#!/usr/bin/perl use Getopt::Std; $ldapmodify = "/usr/bin/ldapmodify"; $ldapsearch = "/usr/bin/ldapsearch"; $basedn = "dc=parkland,dc=cc,dc=il,dc=us"; $rootdn = "cn=manager,$basedn"; $rootpasswd = "secret"; $skeldir = "/etc/skel"; #skeleton files should be here ################################################################################ # parse args ################################################################################ showusage() unless(@ARGV > 1); # I need a username *and* something to change... $username = $ARGV[-1] || die "no username!"; getopts("u:og:G:d:ms:c:l:f:e:p:M:", \%options); $uid = $options{'u'}; $allow2uid = 0; $allow2uid++ if($options{'o'}); $group = $options{'g'}; $options{'G'} && (@othergroups = split(/,/, $options{'G'})); $homedirectory = $options{'d'}; $createhome = 0; $createhome++ if($options{'m'}); $shell = $options{'s'}; $fullname = $options{'c'}; $newusername = $options{'l'}; $inactive = $options{'f'}; $expire = $options{'e'}; $password = $options{'p'}; $newmail = $options{'M'}; ################################################################################ # done with arguments, now modify the user... ################################################################################ $userdn = finddn($username); die "\"$username\" does not exist in LDAP!" unless($userdn); chomp($userdn); # open ldap modify pipe (replace this with Net::LDAP) #open(LDAPMODIFY, "|$ldapmodify -r -D $binddn -w $rootpasswd"); #select(LDAPMODIFY); print "dn: $userdn\n"; print "changetype: modify\n"; # user ID if(defined($uid)){ # allow for $uid = 0 # check for duplicate uidnumbers if(!$allow2uid && ($dupuid = findattr("uidnumber", $uid, "uid")) ){ die "UID $uid already exists in LDAP (user $dupid)\ntry '-o'\t"; } print "replace: uidnumber\n"; print "uidnumber: $uid\n"; print "-\n"; }else{ # I need the UID later on in the program $uid = findattr("uid", $uid, "uidnumber"); } # primary group if(defined($group)){ # allow for a GID of 0 $group = makeGID($group); print "replace: gidnumber\n"; print "gidnumber: $group\n"; print "-\n"; }else{ # I also need the GID later on in the program $group = findattr("uid", $username, "gidnumber"); } # home directory if($homedirectory){ $oldhome = findattr("uid", $username, "homedirectory"); if($oldhome){ # rename($oldhome $homedirectory); print "oldhome = $oldhome\n"; print "replace: homedirectory\n"; print "homedirectory: $homedirectory\n"; print "-\n"; } # if($createhome){ # use File::Copy; # foreach $file (@files_in_etc){ # copy("$skeldir/$file", "$homedirectory/$file"); # chown($uid, $group, $file); # } # } } # login shell if($shell){ print "replace: loginshell\n"; print "loginshell: $shell\n"; print "-\n"; } # full name if($fullname){ ($firstname, $lastname) = split(" ", $fullname, 2); die "You need to give me 'Firstname Lastname'" unless(defined($lastname)); print "replace: givenname\n"; print "givenname: $firstname\n"; print "-\n"; print "replace: sn\n"; print "sn: $lastname\n"; print "-\n"; print "replace: cn\n"; print "cn: $fullname\n"; print "-\n"; } # inactive doesn't actually do anything... if($inactive){ } # expire also doesn't actually do anything for me... :) if($expire){ } # password if($password){ print "replace: password\n"; print "password: {crypt}$password\n"; print "-\n"; } # email if($newmail){ print "replace: mail\n"; print "mail: $newmail\n"; print "-\n"; } # if you use uid in the dn (which you do), make sure this updates the # dn as well as the uid properly... (I think) It needs to be last, just # before the alternate groups modification because of the dn modification if($newusername && $newusername ne $username){ if($dupusername = finddn($newusername)){ die "\"$newusername\" already exists in LDAP ($dupusername)" } print "replace: uid\n"; print "uid: $newusername\n"; print "\n\n"; print "dn: $userdn\n"; print "changetype: modrdn\n"; print "newrdn: uid=$newusername,ou=People,$basedn\n"; print "\n\n"; $username = $newusername; # I need this for the secondary groups later... } # secondary groups if($options{'G'}){ foreach $auxgroup (@othergroups){ $auxgroup = makeGID($auxgroup); $auxgroupname = getgrgid($auxgroup); print "dn: cn=$auxgroupname,ou=Group,$basedn\n"; print "changetype: add\n"; print "add: memberuid\n"; print "memberuid: $username\n\n"; } } close(LDAPMODIFY); exit(0); sub showusage{ $usage = "usage: usermod [-u uid [-o]] [-g group] [-G group,...] [-d home [-m]] [-s shell] [-c comment] [-l new_name] [-f inactive] [-e expire ] [-p passwd] [-M email] name "; print $usage; exit(1); } ################################################################################ # finddn(uid) # find and return the distinguished name (dn) for a given uid (username in LDAP) # convenience funciton that uses findattr ################################################################################ sub finddn{ $finduid = shift; $found = findattr("uid", $finduid, "dn"); return $found; } ################################################################################ # findattr(attr, value, search_attr) # find and return the specificed attr (such as dn, uid, etc) for the given uid ################################################################################ sub findattr{ $findattr = shift; $findval = shift; $returnattr = shift; $query = "$findattr=$findval $returnattr"; if($returnattr eq "userpassword"){ #bind as root open(LDAPSEARCH, "$ldapsearch -D'$binddn' -w$rootpasswd $query|"); }else{ #bind anonymously most of the time open(LDAPSEARCH, "$ldapsearch $query|"); } $found = ; #there's better only be one of them... if($found && $returnattr ne "dn"){ # it's on line 2 $found = ; $found && ($found = (split(/=/, $found, 2))[1]); } close(LDAPSEARCH); chomp($found) unless(!$found); # there *was* a trailing newline on there return $found; } ################################################################################ # makeGID(group) # return the GID of a group name, pass a GID staright through # cool if you don't know if $group is a GID or a string ################################################################################ sub makeGID{ local $group; $group = shift; if ($group !~ /^\d+$/){ if($group != getgrgid(0)){ $group = getgrnam($group) or die "Crappy group \"$group\": $!"; }else{ $group = getgrnam($group); } } findattr("'(&(gidnumber=$group)(objectclass", "posixGroup))'", "cn") or die "Crappy GID $group"; return $group; }