#!/usr/bin/perl # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # # Copyright (C) 2001-2002 IDEALX # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, # USA. # Purpose of smbldap-usermod : user (posix,shadow,samba) modification use strict; use smbldap_tools; use smbldap_conf; ##################### use Getopt::Std; my %Options; my $nscd_status; my $ok = getopts('A:B:C:D:E:F:H:IJxme:f:u:g:G:d:l:s:c:ok:?', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { print "Usage: $0 [-awmugdsckxABCDEFGHI?] username\n"; print " -c gecos\n"; print " -d home directory\n"; #print " -m move home directory\n"; #print " -e expire date (YYYY-MM-DD)\n"; #print " -f inactive days\n"; print " -u uid\n"; print " -o uid can be non unique\n"; print " -g gid\n"; print " -G supplementary groups (comma separated)\n"; print " -l login name\n"; print " -s shell\n"; print " -x creates rid and primaryGroupID in hex instead of decimal (for Samba 2.2.2 unpatched only)\n"; print " -A can change password ? 0 if no, 1 if yes\n"; print " -B must change password ? 0 if no, 1 if yes\n"; print " -C smbHome (SMB home share, like '\\\\PDC-SRV\\homes')\n"; print " -D homeDrive (letter associated with home share, like 'H:')\n"; print " -E scriptPath (DOS script to execute on login)\n"; print " -F profilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n"; print " -H acctFlags (samba account control bits like '[NDHTUMWSLKI]')\n"; print " -I disable an user. Can't be used with -H or -J\n"; print " -J enable an user. Can't be used with -H or -I\n"; print " -? show this help message\n"; exit (1); } if ($< != 0) { print "You must be root to modify an user\n"; exit (1); } # Read only first @ARGV my $user = $ARGV[0]; # Read user datas my $lines = read_user($user); if (!defined($lines)) { print "$0: user $user doesn't exist\n"; exit (1); } #print "$lines\n"; my $dn_line; if ( $lines =~ /(^dn: .*)/ ) { $dn_line = $1; } chomp($dn_line); my $samba = 0; if ($lines =~ m/objectClass: sambaAccount/) { $samba = 1; } ############ my $tmp; my $mods; # Process options my $changed_uid; my $_userUidNumber; my $_userRid; if (defined($tmp = $Options{'u'})) { if (defined($Options{'o'})) { $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; if ($nscd_status == 0) { system "/etc/init.d/nscd stop > /dev/null 2>&1"; } if (getpwuid($tmp)) { if ($nscd_status == 0) { system "/etc/init.d/nscd start > /dev/null 2>&1"; } print "$0: uid number $tmp exists\n"; exit (6); } if ($nscd_status == 0) { system "/etc/init.d/nscd start > /dev/null 2>&1"; } } $_userUidNumber = $tmp; # as rid we use 2 * uid + 1000 my $_userRid = 2 * $_userUidNumber + 1000; if (defined($Options{'x'})) { $_userRid= sprint("%x", $_userRid); } $mods .= "uidNumber: $_userUidNumber\n"; if ($samba) { $mods .= "rid: $_userRid\n"; } $changed_uid = 1; } my $changed_gid; my $_userGidNumber; my $_userGroupRid; if (defined($tmp = $Options{'g'})) { $_userGidNumber = parse_group($tmp); if ($_userGidNumber < 0) { print "$0: group $tmp doesn't exist\n"; exit (6); } # as grouprid we use 2 * gid + 1001 my $_userGroupRid = 2 * $_userGidNumber + 1001; if (defined($Options{'x'})) { $_userGroupRid = sprint("%x", $_userGroupRid); } $mods .= "gidNumber: $_userGidNumber\n"; if ($samba) { $mods .= "primaryGroupID: $_userGroupRid\n"; } $changed_gid = 1; } my $changed_shell; my $_userLoginShell; if (defined($tmp = $Options{'s'})) { $_userLoginShell = $tmp; $mods .= "loginShell: $_userLoginShell\n"; $changed_shell = 1; } my $changed_gecos; my $_userGecos; if (defined($tmp = $Options{'c'})) { $_userGecos = $tmp; $mods .= "gecos: $_userGecos\n"; $changed_gecos = 1; } my $changed_homedir; my $newhomedir; if (defined($tmp = $Options{'d'})) { $newhomedir = $tmp; $mods .= "homeDirectory: $newhomedir\n"; $changed_homedir = 1; } if (defined($tmp = $Options{'G'})) { # remove user from old groups my $groups = find_groups_of $user; my @grplines = split(/\n/, $groups); my $grp; foreach $grp (@grplines) { my $gname = ""; if ( $grp =~ /dn: cn=([^,]+),/) { $gname = $1; #print "xx $gname\n"; } if ($gname ne "") { group_remove_member($gname, $user); } } # add user to new groups add_grouplist_user($tmp, $user); } # # A : pwdCanChange # B : pwdMustChange # C : smbHome # D : homeDrive # E : scriptPath # F : profilePath # H : acctFlags my $attr; my $winmagic = 2147483647; if (defined($tmp = $Options{'A'})) { $attr = "pwdCanChange"; if ($tmp != 0) { $mods .= "$attr: 0\n"; } else { $mods .= "$attr: $winmagic\n"; } } if (defined($tmp = $Options{'B'})) { $attr = "pwdMustChange"; if ($tmp != 0) { $mods .= "$attr: 0\n"; } else { $mods .= "$attr: $winmagic\n"; } } if (defined($tmp = $Options{'C'})) { $attr = "smbHome"; #$tmp =~ s/\\/\\\\/g; $mods .= "$attr: $tmp\n"; } if (defined($tmp = $Options{'D'})) { $attr = "homeDrive"; $tmp = $tmp.":" unless ($tmp =~ /:/); $mods .= "$attr: $tmp\n"; } if (defined($tmp = $Options{'E'})) { $attr = "scriptPath"; #$tmp =~ s/\\/\\\\/g; $mods .= "$attr: $tmp\n"; } if (defined($tmp = $Options{'F'})) { $attr = "profilePath"; #$tmp =~ s/\\/\\\\/g; $mods .= "$attr: $tmp\n"; } if (defined($tmp = $Options{'H'})) { $attr = "acctFlags"; #$tmp =~ s/\\/\\\\/g; $mods .= "$attr: $tmp\n"; } elsif (defined($tmp = $Options{'I'})) { my $flags; if ( $lines =~ /^acctFlags: (.*)/m ) { $flags = $1; } chomp($flags); if ( !($flags =~ /D/) ) { my $letters; if ($flags =~ /(\w+)/) { $letters = $1; } $mods .= "acctFlags: \[D$letters\]\n"; } } elsif (defined($tmp = $Options{'J'})) { my $flags; if ( $lines =~ /^acctFlags: (.*)/m ) { $flags = $1; } chomp($flags); if ( $flags =~ /D/ ) { my $letters; if ($flags =~ /(\w+)/) { $letters = $1; } $letters =~ s/D//; $mods .= "acctFlags: \[$letters\]\n"; } } if ($mods ne '') { #print "----\n$dn_line\n$mods\n----\n"; my $tmpldif = "$dn_line changetype: modify $mods "; die "$0: error while modifying user $user\n" unless (do_ldapmodify($tmpldif) == 0); undef $tmpldif; } $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; if ($nscd_status == 0) { system "/etc/init.d/nscd restart > /dev/null 2>&1"; } ############################################################ =head1 NAME smbldap-usermod.pl - Modify a user account =head1 SYNOPSIS smbldap-usermod.pl [-c comment] [-d home_dir] [-g initial_group] [-G group[,...]] [-l login_name] [-p passwd] [-s shell] [-u uid [ -o]] [-x] [-A canchange] [-B mustchange] [-C smbhome] [-D homedrive] [-E scriptpath] [-F profilepath] [-H acctflags] login =head1 DESCRIPTION The smbldap-usermod.pl command modifies the system account files to reflect the changes that are specified on the command line. The options which apply to the usermod command are -c comment The new value of the user's comment field (gecos). -d home_dir The user's new login directory. -g initial_group The group name or number of the user's new initial login group. The group name must exist. A group number must refer to an already existing group. The default group number is 1. -G group,[...] A list of supplementary groups which the user is also a member of. Each group is separated from the next by a comma, with no intervening whitespace. The groups are subject to the same restrictions as the group given with the -g option. If the user is currently a member of a group which is not listed, the user will be removed from the group -l login_name The name of the user will be changed from login to login_name. Nothing else is changed. In particular, the user's home direc­ tory name should probably be changed to reflect the new login name. -s shell The name of the user's new login shell. Setting this field to blank causes the system to select the default login shell. -u uid The numerical value of the user's ID. This value must be unique, unless the -o option is used. The value must be non- negative. Any files which the user owns and which are located in the directory tree rooted at the user's home direc­ tory will have the file user ID changed automatically. Files outside of the user's home directory must be altered manually. -x Creates rid and primaryGroupID in hex instead of decimal (for Samba 2.2.2 unpatched only - higher versions always use decimal) -A can change password ? 0 if no, 1 if yes -B must change password ? 0 if no, 1 if yes -C smbHome (SMB home share, like '\\\\PDC-SRV\\homes') -D homeDrive (letter associated with home share, like 'H:') -E scriptPath, relative to the [netlogon] share (DOS script to execute on login, like 'foo.bat') -F profilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo') -H acctFlags, spaces and trailing bracket are ignored (samba account control bits like '[NDHTUMWSLKI]') -I disable user. Can't be used with -H or -J -J enable user. Can't be used with -H or -I =head1 SEE ALSO usermod(1) =cut #'