From 077d5b2f69f2b32dd6b58c8931909a222401ceaf Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 6 Jan 2004 14:45:56 +0000 Subject: merging from 3.0 (This used to be commit 694052f8a9cc703d4e4ec8075c623ab7122a169b) --- examples/LDAP/smbldap-tools/CONTRIBUTORS | 10 +- examples/LDAP/smbldap-tools/ChangeLog | 105 ++++- examples/LDAP/smbldap-tools/FILES | 2 + examples/LDAP/smbldap-tools/INFRASTRUCTURE | 11 + examples/LDAP/smbldap-tools/INSTALL | 2 + examples/LDAP/smbldap-tools/Makefile | 2 +- examples/LDAP/smbldap-tools/README | 3 + examples/LDAP/smbldap-tools/TODO | 2 + examples/LDAP/smbldap-tools/smbldap-groupadd.pl | 95 +++- examples/LDAP/smbldap-tools/smbldap-groupdel.pl | 13 +- examples/LDAP/smbldap-tools/smbldap-groupmod.pl | 155 +++++-- examples/LDAP/smbldap-tools/smbldap-groupshow.pl | 4 +- .../LDAP/smbldap-tools/smbldap-migrate-accounts.pl | 46 +- .../LDAP/smbldap-tools/smbldap-migrate-groups.pl | 88 ++-- examples/LDAP/smbldap-tools/smbldap-passwd.pl | 117 ++--- examples/LDAP/smbldap-tools/smbldap-populate.pl | 138 ++++-- examples/LDAP/smbldap-tools/smbldap-tools.spec | 70 +-- examples/LDAP/smbldap-tools/smbldap-useradd.pl | 360 ++++++++------- examples/LDAP/smbldap-tools/smbldap-userdel.pl | 32 +- examples/LDAP/smbldap-tools/smbldap-usermod.pl | 270 +++++++----- examples/LDAP/smbldap-tools/smbldap-usershow.pl | 4 +- examples/LDAP/smbldap-tools/smbldap_conf.pm | 63 +-- examples/LDAP/smbldap-tools/smbldap_tools.pm | 482 ++++++++++++--------- 23 files changed, 1253 insertions(+), 821 deletions(-) (limited to 'examples/LDAP') diff --git a/examples/LDAP/smbldap-tools/CONTRIBUTORS b/examples/LDAP/smbldap-tools/CONTRIBUTORS index 59dafcc89e..d080dd020e 100644 --- a/examples/LDAP/smbldap-tools/CONTRIBUTORS +++ b/examples/LDAP/smbldap-tools/CONTRIBUTORS @@ -1,13 +1,19 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/CONTRIBUTORS,v $ +# ## Authors and actives contributors to SMBLDAP-TOOLS Have contributed directly to this tools, or are always in charge of -some aspects of it developments (alphabetical order): +some aspects of it developments: + . Jrme Tournier . Terry Davis . David Le Corfec . Olivier Lemaire - . Jrme Tournier Many thanks to contributors for bug report and patches: + . Marc Schoechlin + load the perl-modules without setting environment-variables or making symlinks + . Alexander Bergolth + more Net::LDAP support . Gert-Jan Braas bug report for 2.2.3 samba.schema . Jody Haynes diff --git a/examples/LDAP/smbldap-tools/ChangeLog b/examples/LDAP/smbldap-tools/ChangeLog index 0994cb4931..e4e3768385 100644 --- a/examples/LDAP/smbldap-tools/ChangeLog +++ b/examples/LDAP/smbldap-tools/ChangeLog @@ -1,28 +1,89 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/ChangeLog,v $ +# $id: $ +# ## ChangeLog for SMBLDAP-TOOLS -* 2002-07-24: top and account objectclasses replaced with inetorgperson -* 2002-06-03: notes to webmin.idealx.org (idxldapaccounts) -* 2002-06-01: release 0.7. tested with 2.2.4 -* 2002-05-31: fixed smbldap-populate compliance to smbldap_conf - cleaned up smbldap_conf to be more readable - some more documentation - bugfixes on smbldap-passwd and smbldap-populate -* 2002-05-16: modified default mode on homes: now 700 -* 2002-05-13: fixed spec (relocation and reqs) -* 2002-03-02: fixed 2.2.3 sambaAccount bug with smbldap-useradd.pl +2003-11-18: + . new option '-a' to smbldap-usermod.pl that allow adding the sambaSamAccount + objectclass to an existing posixAccount +2003-11-07: + . patch that allow adding user to a group when the group is in a higher level depth + then ou=Groups (for example, ou=grp1,ou=Groups,...) + . check the unicity of a group when adding/removing a user to this group +2003-10-28: + . new option '-p' in smbldap-groupadd.pl to 'print' the gidNumber + of the group to STDOUT. This is needed by samba (see the man page) +2003-10-19: + . new function does_sid_exist that check if samaSID sttribute is already + defined for another use or another group +2003-10-13: + . smbldap-populate.pl now also add the group mapping +2003-10-01: + . one can now comment the two directives '$_userSmbHome' and '$_userProfile' + if you want to use the smb.conf directives instead ('logon home' and + 'logon path' respectively), or if you want to desable roaming profiles + . Patch from Alexander Bergolth : the sambaPrimaryGroupSID + of a user is now set to the sambaSID of his primary group +2003-09-29: + . added new option '$_defaultMaxPasswordAge' in smbldap_conf.pm to specifie + how long a password is valid + . The '-B' option was not always valid: to force a user to change his password: + . the attribut sambaPwdLastSet must be != 0 + . the attribut sambaAcctFlags must not match the 'X' flag + . logon script is set (for every one) to the default '_userScript' value if it is defined + . Patch from Alexander Bergolth : + gid-sid group mapping to smbldap-groupadd.pl and smbldap-groupmod.pl +2003-09-19: Patch from Marc Schoechlin + . load the perl-modules without setting environment-variables or making symlinks +2003-09-18: Patch from Alexander Bergolth + . options "-u", "-g", "-s" and "-c" are now functionnal + . the existence of samba account was made on sambaAccount and + not sambaSamAccount as it should be for samba3 + . new function read_user_entry to smbldap_tools.pm that returns + a Net::LDAP:Entry object of the user + . Use this object to get the dn and user attributes instead of + producing an ldif and searching for attributes within that ldif +2003-09-15: + . change machine account creation to not add the sambaSamAccount objectclass. + It is now added directly by samba when joigning the domain + . new option in smbldap-usermod.pl: '-e' to set an expire date + . Start_tls support activated when ldapSSL is set to 1 + . Net::LDAP support more scripts + . bugs correction +2003-09-02: + . sambaPwdLastSet is updated when smbldap-passwd.pl is used + . add a function is_group_member to test the existence of a + user in a particular group + . add a function is_unix_user to test if a particular user exist + . Net::LDAP support more scripts +2003-08-15: + . Samba3.0 support +2003-08-01: + . Final version for samba 2.2.8a (cvs tag SAMBA-2-2-8a-FINAL) + . OpenLDAP 2.1 support (only one structural objectclass allowed) +2002-07-24: top and account objectclasses replaced with inetorgperson +2002-06-03: notes to webmin.idealx.org (idxldapaccounts) +2002-06-01: release 0.7. tested with 2.2.4 +2002-05-31: fixed smbldap-populate compliance to smbldap_conf + cleaned up smbldap_conf to be more readable + some more documentation + bugfixes on smbldap-passwd and smbldap-populate +2002-05-16: modified default mode on homes: now 700 +2002-05-13: fixed spec (relocation and reqs) +2002-03-02: fixed 2.2.3 sambaAccount bug with smbldap-useradd.pl (rid is now mandatory in the sambaAccount objectClass) -* 2002-02-14: just modified default populate for Administrator -* 2002-02-05: release 0.6. enable/disable user in usermod -* 2002-02-04: release 0.5. added smbldap-migrate-groups to migrate NT groups - from a net group dump. added samba parameters to smbldap-useradd - and smbldap-usermod. -* 2002-01-12: added smbldap-migrate-accounts to migrate users/machines - accounts from a PWDUMP dump -* 2001-12-13: added smbldap-populate to create the initial base -* 2001-12-13: initial release 0.1 -* 2001-12-12: fixed the SPEC file for RedHat -* 2001-12-03: cleaned the code and use strict; -* 2001-11-20: initial needs (for testing purpose on Samba-2.2.2 an Samba-TNG) +2002-02-14: just modified default populate for Administrator +2002-02-05: release 0.6. enable/disable user in usermod +2002-02-04: release 0.5. added smbldap-migrate-groups to migrate NT groups + from a net group dump. added samba parameters to smbldap-useradd + and smbldap-usermod. +2002-01-12: added smbldap-migrate-accounts to migrate users/machines + accounts from a PWDUMP dump +2001-12-13: added smbldap-populate to create the initial base +2001-12-13: initial release 0.1 +2001-12-12: fixed the SPEC file for RedHat +2001-12-03: cleaned the code and use strict; +2001-11-20: initial needs (for testing purpose on Samba-2.2.2 an Samba-TNG) # - The End diff --git a/examples/LDAP/smbldap-tools/FILES b/examples/LDAP/smbldap-tools/FILES index 0343c53d60..48ee571b29 100644 --- a/examples/LDAP/smbldap-tools/FILES +++ b/examples/LDAP/smbldap-tools/FILES @@ -1,3 +1,5 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/FILES,v $ +# ## File listing for SMBLDAP-TOOLS CONTRIBUTORS : authors and contributors diff --git a/examples/LDAP/smbldap-tools/INFRASTRUCTURE b/examples/LDAP/smbldap-tools/INFRASTRUCTURE index 25fbda8599..e14ec70e02 100644 --- a/examples/LDAP/smbldap-tools/INFRASTRUCTURE +++ b/examples/LDAP/smbldap-tools/INFRASTRUCTURE @@ -1,3 +1,5 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/INFRASTRUCTURE,v $ +# ## Some notes about the architecture @@ -41,6 +43,15 @@ man smb.conf for more): domain admin group = " @"Domain Admins" " +However, to make pdb_ldap accept bind without being uid=0, a quick and +dirty patch must be applied to 2.2.4 (see samba-2.2.4-ldapbindnotuid0.patch). +This patch is Q&D because the check is there because Samba store admin +credentials to establish the LDAP connection. The uid == 0 check was to +ensure that a normal user could not get write access to the LDAP backend. +A more logical situation should be done for 2.2.5 by checking if the user +is a member of the domain admin group (reported to Jerremy and Gerald +2002-05-28). + Other built in groups are really cosmetic ones with Samba 2.2.x. We did not removed them because one of these days, we whish to use Samba 3.0 where Windows Group Support should be operational. diff --git a/examples/LDAP/smbldap-tools/INSTALL b/examples/LDAP/smbldap-tools/INSTALL index d5ca07826f..f4c72751a7 100644 --- a/examples/LDAP/smbldap-tools/INSTALL +++ b/examples/LDAP/smbldap-tools/INSTALL @@ -1,3 +1,5 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/INSTALL,v $ +# ## How To Install SMBLDAP-TOOLS Quick & Dirty: diff --git a/examples/LDAP/smbldap-tools/Makefile b/examples/LDAP/smbldap-tools/Makefile index 3e5eac427d..783a3571a9 100644 --- a/examples/LDAP/smbldap-tools/Makefile +++ b/examples/LDAP/smbldap-tools/Makefile @@ -1,5 +1,5 @@ PACKAGE=smbldap-tools -RELEASE=0.7 +RELEASE=0.8.2-1 DESTDIR = $(PACKAGE)-$(RELEASE) dist: distclean $(DESTDIR).tgz diff --git a/examples/LDAP/smbldap-tools/README b/examples/LDAP/smbldap-tools/README index 3b4bf2da0d..add0175c0c 100644 --- a/examples/LDAP/smbldap-tools/README +++ b/examples/LDAP/smbldap-tools/README @@ -1,3 +1,6 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/README,v $ +# + Latest version may be found at http://samba.idealx.org/ diff --git a/examples/LDAP/smbldap-tools/TODO b/examples/LDAP/smbldap-tools/TODO index 25cc30c684..71e6695299 100644 --- a/examples/LDAP/smbldap-tools/TODO +++ b/examples/LDAP/smbldap-tools/TODO @@ -1,3 +1,5 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/TODO,v $ +# ## TODO list - First In, Last in the list... ## (BF: Bug Report / FR: Feature Request) diff --git a/examples/LDAP/smbldap-tools/smbldap-groupadd.pl b/examples/LDAP/smbldap-tools/smbldap-groupadd.pl index 91cd2dad53..e242d6e223 100755 --- a/examples/LDAP/smbldap-tools/smbldap-groupadd.pl +++ b/examples/LDAP/smbldap-tools/smbldap-groupadd.pl @@ -27,33 +27,104 @@ use FindBin; use FindBin qw($RealBin); use lib "$RealBin/"; use smbldap_tools; - +use smbldap_conf; use Getopt::Std; my %Options; -my $ok = getopts('og:?', \%Options); +my $ok = getopts('ag:or:s:t:p?', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { - print "Usage: $0 [-go?] groupname\n"; - print " -g gid\n"; - print " -o gid is not unique\n"; - print " -? show this help message\n"; - exit (1); + print "Usage: $0 [-agorst?] groupname\n"; + print " -a add automatic group mapping entry\n"; + print " -g gid\n"; + print " -o gid is not unique\n"; + print " -r group-rid\n"; + print " -s group-sid\n"; + print " -t group-type\n"; + print " -p print the gidNumber to stdout\n"; + print " -? show this help message\n"; + exit (1); } my $_groupName = $ARGV[0]; if (defined(get_group_dn($_groupName))) { - print "$0: group $_groupName exists\n"; - exit (6); + warn "$0: group $_groupName exists\n"; + exit (6); } my $_groupGidNumber = $Options{'g'}; +if (! defined ($_groupGidNumber = group_add($_groupName, $_groupGidNumber, $Options{'o'}))) { + warn "$0: error adding group $_groupName\n"; + exit (6); +} + +my $group_sid; +my $tmp; +if ($tmp= $Options{'s'}) { + if ($tmp =~ /^S-(?:\d+-)+\d+$/) { + $group_sid = $tmp; + } else { + warn "$0: illegal group-rid $tmp\n"; + exit(7); + } +} elsif ($Options{'r'} || $Options{'a'}) { + my $group_rid; + if ($tmp= $Options{'r'}) { + if ($tmp =~ /^\d+$/) { + $group_rid = $tmp; + } else { + warn "$0: illegal group-rid $tmp\n"; + exit(7); + } + } else { + # algorithmic mapping + $group_rid = 2*$_groupGidNumber+1001; + } + $group_sid = $SID.'-'.$group_rid; +} -if (!group_add($_groupName, $_groupGidNumber, $Options{'o'})) { - print "$0: error adding group $_groupName\n"; - exit (6); +if ($Options{'r'} || $Options{'a'} || $Options{'s'}) { + # let's test if this SID already exist + my $test_exist_sid=does_sid_exist($group_sid,$groupsdn); + if ($test_exist_sid->count == 1) { + warn "Group SID already owned by\n"; + # there should not exist more than one entry, but ... + foreach my $entry ($test_exist_sid->all_entries) { + my $dn= $entry->dn; + chomp($dn); + warn "$dn\n"; + } + exit(7); + } } +if ($group_sid) { + my $group_type; + my $tmp; + if ($tmp= $Options{'t'}) { + unless (defined($group_type = &group_type_by_name($tmp))) { + warn "$0: unknown group type $tmp\n"; + exit(8); + } + } else { + $group_type = group_type_by_name('domain'); + } + my $ldap_master=connect_ldap_master(); + my $modify = $ldap_master->modify ( "cn=$_groupName,$groupsdn", + add => { + 'objectClass' => 'sambaGroupMapping', + 'sambaSID' => $group_sid, + 'sambaGroupType' => $group_type + } + ); + $modify->code && warn "failed to delete entry: ", $modify->error ; + # take down session + $ldap_master->unbind +} + +if ($Options{'p'}) { + print STDOUT "$_groupGidNumber"; +} exit(0); ######################################## diff --git a/examples/LDAP/smbldap-tools/smbldap-groupdel.pl b/examples/LDAP/smbldap-tools/smbldap-groupdel.pl index 89d0d993ac..4f6839ebe5 100755 --- a/examples/LDAP/smbldap-tools/smbldap-groupdel.pl +++ b/examples/LDAP/smbldap-tools/smbldap-groupdel.pl @@ -30,23 +30,22 @@ use smbldap_tools; use smbldap_conf; ##################### - use Getopt::Std; my %Options; my $ok = getopts('?', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { - print "Usage: $0 groupname\n"; - print " -? show this help message\n"; - exit (1); + print "Usage: $0 groupname\n"; + print " -? show this help message\n"; + exit (1); } my $_groupName = $ARGV[0]; my $dn_line; if (!defined($dn_line = get_group_dn($_groupName))) { - print "$0: group $_groupName doesn't exist\n"; - exit (6); + print "$0: group $_groupName doesn't exist\n"; + exit (6); } my $dn = get_dn_from_line($dn_line); @@ -56,7 +55,7 @@ group_del($dn); my $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"; + system "/etc/init.d/nscd restart > /dev/null 2>&1"; } #if (defined($dn_line = get_group_dn($_groupName))) { diff --git a/examples/LDAP/smbldap-tools/smbldap-groupmod.pl b/examples/LDAP/smbldap-tools/smbldap-groupmod.pl index f897101602..3f9741e015 100755 --- a/examples/LDAP/smbldap-tools/smbldap-groupmod.pl +++ b/examples/LDAP/smbldap-tools/smbldap-groupmod.pl @@ -1,4 +1,5 @@ #!/usr/bin/perl -w + # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -29,29 +30,33 @@ use lib "$RealBin/"; use smbldap_tools; use smbldap_conf; - ##################### use Getopt::Std; my %Options; -my $ok = getopts('og:n:m:x:?', \%Options); +my $ok = getopts('ag:n:m:or:s:t:x:?', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { - print "Usage: $0 [-g gid [-o]] [-n name] [-m members(,)] [-x members (,)] groupname\n"; - print " -g new gid\n"; - print " -o gid is not unique\n"; - print " -n new group name\n"; - print " -m add members (comma delimited)\n"; - print " -x delete members (comma delimted)\n"; - print " -? show this help message\n"; - exit (1); + print "Usage: $0 [-a] [-g gid [-o]] [-n name] [-m members(,)] [-x members (,)] [-r rid] [-s sid] [-t type] groupname\n"; + print " -a add automatic group mapping entry\n"; + print " -g new gid\n"; + print " -o gid is not unique\n"; + print " -n new group name\n"; + print " -m add members (comma delimited)\n"; + print " -r group-rid\n"; + print " -s group-sid\n"; + print " -t group-type\n"; + print " -x delete members (comma delimted)\n"; + print " -? show this help message\n"; + exit (1); } my $groupName = $ARGV[0]; +my $group_entry; -if (!defined(get_group_dn($groupName))) { - print "$0: group $groupName doesn't exist\n"; - exit (6); +if (! ($group_entry = read_group_entry($groupName))) { + print "$0: group $groupName doesn't exist\n"; + exit (6); } my $newname = $Options{'n'}; @@ -59,20 +64,24 @@ my $newname = $Options{'n'}; my $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"; + system "/etc/init.d/nscd restart > /dev/null 2>&1"; } my $gid = getgrnam($groupName); +unless (defined ($gid)) { + print "$0: group $groupName not found!\n"; + exit(6); +} my $tmp; if (defined($tmp = $Options{'g'}) and $tmp =~ /\d+/) { - if (!defined($Options{'o'})) { + if (!defined($Options{'o'})) { if (defined(getgrgid($tmp))) { - print "$0: gid $tmp exists\n"; - exit (6); + print "$0: gid $tmp exists\n"; + exit (6); } - } - if (!($gid == $tmp)) { + } + if (!($gid == $tmp)) { my $ldap_master=connect_ldap_master(); my $modify = $ldap_master->modify ( "cn=$groupName,$groupsdn", changes => [ @@ -82,7 +91,7 @@ if (defined($tmp = $Options{'g'}) and $tmp =~ /\d+/) { $modify->code && die "failed to modify entry: ", $modify->error ; # take down session $ldap_master->unbind - } + } } @@ -101,17 +110,19 @@ if (defined($newname)) { # Add members if (defined($Options{'m'})) { - my $members = $Options{'m'}; - my @members = split( /,/, $members ); - my $member; - foreach $member ( @members ) { + my $members = $Options{'m'}; + my @members = split( /,/, $members ); + my $member; + foreach $member ( @members ) { + my $group_entry=read_group_entry($groupName); + $groupsdn=$group_entry->dn; if (is_unix_user($member)) { - if (is_group_member("cn=$groupName,$groupsdn",$member)) { + if (is_group_member($groupsdn,$member)) { print "User $member already in the group\n"; } else { print "adding user $member to group $groupName\n"; my $ldap_master=connect_ldap_master(); - my $modify = $ldap_master->modify ( "cn=$groupName,$groupsdn", + my $modify = $ldap_master->modify ($groupsdn, changes => [ add => [memberUid => $member] ] @@ -123,19 +134,21 @@ if (defined($Options{'m'})) { } else { print "User $member does not exist: create it first !\n"; } - } + } } # Delete members if (defined($Options{'x'})) { - my $members = $Options{'x'}; - my @members = split( /,/, $members ); - my $member; - foreach $member ( @members ) { - if (is_group_member("cn=$groupName,$groupsdn",$member)) { + my $members = $Options{'x'}; + my @members = split( /,/, $members ); + my $member; + foreach $member ( @members ) { + my $group_entry=read_group_entry($groupName); + $groupsdn=$group_entry->dn; + if (is_group_member("$groupsdn",$member)) { print "deleting user $member from group $groupName\n"; my $ldap_master=connect_ldap_master(); - my $modify = $ldap_master->modify ( "cn=$groupName,$groupsdn", + my $modify = $ldap_master->modify ($groupsdn, changes => [ delete => [memberUid => $member] ] @@ -146,13 +159,73 @@ if (defined($Options{'x'})) { } else { print "User $member is not in the group $groupName!\n"; } - } + } +} + +my $group_sid; +if ($tmp= $Options{'s'}) { + if ($tmp =~ /^S-(?:\d+-)+\d+$/) { + $group_sid = $tmp; + } else { + print "$0: illegal group-rid $tmp\n"; + exit(7); + } +} elsif ($Options{'r'} || $Options{'a'}) { + my $group_rid; + if ($tmp= $Options{'r'}) { + if ($tmp =~ /^\d+$/) { + $group_rid = $tmp; + } else { + print "$0: illegal group-rid $tmp\n"; + exit(7); + } + } else { + # algorithmic mapping + $group_rid = 2*$gid+1001; + } + $group_sid = $SID.'-'.$group_rid; +} + +if ($group_sid) { + my @adds; + my @mods; + push(@mods, 'sambaSID' => $group_sid); + + if ($tmp= $Options{'t'}) { + my $group_type; + if (defined($group_type = &group_type_by_name($tmp))) { + push(@mods, 'sambaGroupType' => $group_type); + } else { + print "$0: unknown group type $tmp\n"; + exit(8); + } + } else { + if (! defined($group_entry->get_value('sambaGroupType'))) { + push(@mods, 'sambaGroupType' => group_type_by_name('domain')); + } + } + + my @oc = $group_entry->get_value('objectClass'); + unless (grep($_ =~ /^sambaGroupMapping$/i, @oc)) { + push (@adds, 'objectClass' => 'sambaGroupMapping'); + } + + my $ldap_master=connect_ldap_master(); + my $modify = $ldap_master->modify ( "cn=$groupName,$groupsdn", + changes => [ + 'add' => [ @adds ], + 'replace' => [ @mods ] + ] + ); + $modify->code && warn "failed to delete entry: ", $modify->error ; + # take down session + $ldap_master->unbind } $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"; + system "/etc/init.d/nscd restart > /dev/null 2>&1"; } exit (0); @@ -161,19 +234,19 @@ exit (0); =head1 NAME - smbldap-groupmod.pl - Modify a group +smbldap-groupmod.pl - Modify a group =head1 SYNOPSIS - smbldap-groupmod.pl [-g gid [-o]] [-n group_name ] group +smbldap-groupmod.pl [-g gid [-o]] [-n group_name ] group =head1 DESCRIPTION - The smbldap-groupmod.pl command modifies the system account files to - reflect the changes that are specified on the command line. - The options which apply to the smbldap-groupmod command are +The smbldap-groupmod.pl command modifies the system account files to + reflect the changes that are specified on the command line. + The options which apply to the smbldap-groupmod command are - -g gid The numerical value of the group's ID. This value must be + -g gid The numerical value of the group's ID. This value must be unique, unless the -o option is used. The value must be non- negative. Any files which the old group ID is the file group ID must have the file group ID changed manually. diff --git a/examples/LDAP/smbldap-tools/smbldap-groupshow.pl b/examples/LDAP/smbldap-tools/smbldap-groupshow.pl index 18fe082e66..a9d368763e 100755 --- a/examples/LDAP/smbldap-tools/smbldap-groupshow.pl +++ b/examples/LDAP/smbldap-tools/smbldap-groupshow.pl @@ -36,8 +36,8 @@ my %Options; my $ok = getopts('?', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { - print "Usage: $0 [-?] group\n"; - print " -? show this help message\n"; + print "Usage: $0 [-?] group\n"; + print " -? show this help message\n"; exit (1); } diff --git a/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl b/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl index 86f52cb53e..54e4d7f7e3 100755 --- a/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl +++ b/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl @@ -39,14 +39,14 @@ use smbldap_conf; # Errors, debug and stats are output to stderr. sub modify_account -{ - my ($login, $basedn, $lmpwd, $ntpwd, $gecos, $homedir) = @_; + { + my ($login, $basedn, $lmpwd, $ntpwd, $gecos, $homedir) = @_; # bind to a directory with dn and password my $ldap_master=connect_ldap_master(); my $modify = $ldap_master->modify ("uid=$login,$basedn", changes => [ - replace => [lmpassword => "$lmpwd"], - replace => [ntpassword => "$ntpwd"], + replace => [sambaLMPassword => "$lmpwd"], + replace => [sambaNTpassword => "$ntpwd"], replace => [gecos => "$gecos"], replace => [sambaHomePath => "$homedir"] ] @@ -54,7 +54,7 @@ sub modify_account $modify->code && die "failed to modify entry: ", $modify->error ; # take down the session $ldap_master->unbind; -} + } ##################### @@ -64,15 +64,15 @@ my %Options; my $ok = getopts('awA:CUW:?h', \%Options); if ( (!$ok) || ($Options{'?'}) || ($Options{'h'}) ) { - print "Usage: $0 [-awAWCU?]\n"; - print " -a process only people, ignore computers\n"; - print " -w process only computers, ignore persons\n"; - print " -A option string passed verbatim to smbldap-useradd for persons\n"; - print " -W option string passed verbatim to smbldap-useradd for computers\n"; - print " -C if entry not found, don't create it and log it to stdout (default: create it)\n"; - print " -U if entry found, don't update it and log it to stdout (default: update it)\n"; + print "Usage: $0 [-awAWCU?]\n"; + print " -a process only people, ignore computers\n"; + print " -w process only computers, ignore persons\n"; + print " -A option string passed verbatim to smbldap-useradd for persons\n"; + print " -W option string passed verbatim to smbldap-useradd for computers\n"; + print " -C if entry not found, don't create it and log it to stdout (default: create it)\n"; + print " -U if entry found, don't update it and log it to stdout (default: update it)\n"; print " -?|-h show this help message\n"; - exit (1); + exit (1); } my %processed = ( 'user' => 0, 'machine' => 0); @@ -90,7 +90,7 @@ while (<>) { my $entry_type = 'user'; - if ($login =~ m/.*\$$/ ) { # computer + if ($login =~ m/.*\$$/ ) { # computer $processed{'machine'}++; $entry_type = 'machine'; if (defined($Options{'a'})) { @@ -117,14 +117,14 @@ while (<>) { } # normalize homedir -# uncomment to replace configured share with share from pwdump -# if ($homedir eq "") { - $homedir = $_userSmbHome; -# } + # uncomment to replace configured share with share from pwdump + # if ($homedir eq "") { + $homedir = $_userSmbHome; + # } # normalize gecos if (!($gecos eq "")) { - $gecos =~ tr/ÁÀÂÄáàâäÇçÉÈÊËÆéèêëæÍÌÏÎíìîÏÑñÓÒÔÖóòôöÚÙÜÛúùüûÝýÿ/AAAAaaaaCcEEEEEeeeeeIIIIiiiiNnOOOOooooUUUUuuuuYyy/; + $gecos =~ tr//AAAAaaaaCcEEEEEeeeeeIIIIiiiiNnOOOOooooUUUUuuuuYyy/; } else { $gecos = $_userGecos; } @@ -141,12 +141,12 @@ while (<>) { print STDERR "error adding $login, skipping\n"; next; } - # lem modif... a retirer si pb + # lem modif... a retirer si pb if ($entry_type eq "user") { modify_account($login, $userbasedn, $lmpwd, $ntpwd, $gecos, $homedir); - } + } - $created{$entry_type}++; + $created{$entry_type}++; } else { # uid doesn't exist and no create => log print "$_"; $logged{$entry_type}++; @@ -187,7 +187,7 @@ print STDERR "special users skipped: $specialskipped\n"; =head1 NAME - smbldap-migrate.pl - Migrate NT accounts to LDAP +smbldap-migrate.pl - Migrate NT accounts to LDAP =head1 SYNOPSIS diff --git a/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl b/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl index c60be18caf..a2b07bf817 100644 --- a/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl +++ b/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl @@ -33,52 +33,50 @@ use smbldap_tools; use smbldap_conf; use Getopt::Std; - - sub process_rec_group -{ + { my ($group, $mb) = @_; my @members; if (!(@members = group_get_members($group))) { - return 0; + return 0; } foreach my $m (@members) { - if ( !($m =~ m/^\*/) ) { + if ( !($m =~ m/^\*/) ) { push @{$mb}, $m; - } else { + } else { my $gname = $m; $gname =~ s/^.//; if (!process_rec_group($gname, $mb)) { - print "recursive group not added : $gname\n"; + print "recursive group not added : $gname\n"; } - } + } } -} + } # given a group dn and a list of members, update the group sub modify_group -{ + { my ($group, $dn_line, @members, $recgroup) = @_; my $m; my @new_mb; foreach $m (@members) { - if ( ($m =~ m/^\*/) ) { + if ( ($m =~ m/^\*/) ) { my $gname = $m; $gname =~ s/^.//; if (!$recgroup) { - print "recursive group not added : $gname\n"; + print "recursive group not added : $gname\n"; } else { - if (!process_rec_group($gname, \@new_mb)) { + if (!process_rec_group($gname, \@new_mb)) { print "recursive group not added : $gname\n"; - } + } } - } else { + } else { push @new_mb, $m; - } + } } # new_mb contains flat members from group dump @@ -94,7 +92,7 @@ sub modify_group my $mbs; foreach $m (@new_mb) { - $mbs .= "memberUid: $m\n"; + $mbs .= "memberUid: $m\n"; } my $mods="$dn_line @@ -105,16 +103,16 @@ $mbs #print "$mods\n"; my $tmpldif = -"$mods + "$mods "; die "$0: error while modifying group $group\n" - unless (do_ldapmodify($tmpldif) == 0); + unless (do_ldapmodify($tmpldif) == 0); undef $tmpldif; -} + } sub display_group -{ + { my ($group, @members) = @_; print "Group name $group\n"; @@ -122,43 +120,43 @@ sub display_group my $m; my $i = 0; foreach $m (@members) { - print "$m "; - if ($i % 5 == 0) { + print "$m "; + if ($i % 5 == 0) { print "\n"; - } - $i++; + } + $i++; } -} + } sub process_group -{ + { my ($group, @members, $nocreate, $noupdate, $recgroup) = @_; my $dn_line; if (!defined($dn_line = get_group_dn($group))) { - # group not found, create it ? - if (!$nocreate) { + # group not found, create it ? + if (!$nocreate) { system "/usr/local/sbin/smbldap-groupadd.pl \"$group\"; sleep 5"; if (!defined($dn_line = get_group_dn($group))) { - return 1; + return 1; } modify_group($group, $dn_line, @members, $recgroup); - } else { + } else { # don't create print "not created:\n"; display_group($group, @members); - } + } } else { - # group found, update it ? - if (!$noupdate) { + # group found, update it ? + if (!$noupdate) { modify_group($group, $dn_line, @members, $recgroup); - } else { + } else { # don't update print "not updated:\n"; display_group($group, @members); - } + } } -} + } ################################################### @@ -166,11 +164,11 @@ my %Options; my $ok = getopts('CUr?', \%Options); if ( (!$ok) || ($Options{'?'}) ) { - print "Usage: $0 [-CUr?] < group_dump\n"; - print " -C don't create group if it doesn't exist\n"; - print " -U don't update group if it exists\n"; - print " -r recursively process groups\n"; - exit(1); + print "Usage: $0 [-CUr?] < group_dump\n"; + print " -C don't create group if it doesn't exist\n"; + print " -U don't update group if it exists\n"; + print " -r recursively process groups\n"; + exit(1); } my $group_name; @@ -184,13 +182,13 @@ while (<>) { next if ( $line =~ m/^\s*$/ ); if ($group_name eq "") { - if ( $line =~ m/^Group name\s+(.+).$/ ) { + if ( $line =~ m/^Group name\s+(.+).$/ ) { $group_name = $1; next; - } + } } if ($group_desc eq "") { - if ( $line =~ m/^Comment\s+(.*)$/ ) { + if ( $line =~ m/^Comment\s+(.*)$/ ) { $group_desc = $1; next; } diff --git a/examples/LDAP/smbldap-tools/smbldap-passwd.pl b/examples/LDAP/smbldap-tools/smbldap-passwd.pl index 7845e5548e..afbc87a058 100755 --- a/examples/LDAP/smbldap-tools/smbldap-passwd.pl +++ b/examples/LDAP/smbldap-tools/smbldap-passwd.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl -w # LDAP to unix password sync script for samba -# + # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -23,7 +23,7 @@ # USA. # Purpose : -# . ldap-unix passwd sync for SAMBA-2.2.2 + LDAP +# . ldap-unix passwd sync for SAMBA>2.2.2 + LDAP # . may also replace /bin/passwd use strict; @@ -40,29 +40,29 @@ my $ret; my $arg; foreach $arg (@ARGV) { - if ($< != 0) { - die "Only root can specify parameters\n"; - } else { - if ( ($arg eq '-?') || ($arg eq '--help') ) { - print "Usage: $0 [username]\n"; - print " -?, --help show this help message\n"; - exit (6); - } elsif (substr($arg,0) ne '-') { - $user = $arg; - } - $oldpass = 1; + if ($< != 0) { + die "Only root can specify parameters\n"; + } else { + if ( ($arg eq '-?') || ($arg eq '--help') ) { + print "Usage: $0 [username]\n"; + print " -?, --help show this help message\n"; + exit (6); + } elsif (substr($arg,0) ne '-') { + $user = $arg; } + $oldpass = 1; + } } if (!defined($user)) { - $user=$ENV{"USER"}; + $user=$ENV{"USER"}; } # test existence of user in LDAP my $dn_line; if (!defined($dn_line = get_user_dn($user))) { - print "$0: user $user doesn't exist\n"; - exit (10); + print "$0: user $user doesn't exist\n"; + exit (10); } my $dn = get_dn_from_line($dn_line); @@ -73,17 +73,17 @@ print "Changing password for $user\n"; # non-root user if (!defined($oldpass)) { - # prompt for current password - system "stty -echo"; - print "(current) UNIX password: "; - chomp($oldpass=); - print "\n"; - system "stty echo"; - - if (!is_user_valid($user, $dn, $oldpass)) { - print "Authentication failure\n"; - exit (10); - } + # prompt for current password + system "stty -echo"; + print "(current) UNIX password: "; + chomp($oldpass=); + print "\n"; + system "stty echo"; + + if (!is_user_valid($user, $dn, $oldpass)) { + print "Authentication failure\n"; + exit (10); + } } # prompt for new password @@ -104,8 +104,8 @@ print "\n"; system "stty echo"; if ($pass ne $pass2) { - print "New passwords don't match!\n"; - exit (10); + print "New passwords don't match!\n"; + exit (10); } # First, connecting to the directory @@ -113,59 +113,64 @@ my $ldap_master=connect_ldap_master(); # only modify smb passwords if smb user if ($samba == 1) { - if (!$with_smbpasswd) { -# generate LanManager and NT clear text passwords + if (!$with_smbpasswd) { + # generate LanManager and NT clear text passwords if ($mk_ntpasswd eq '') { - print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n"; - exit(1); + print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n"; + exit(1); } my $ntpwd = `$mk_ntpasswd '$pass'`; - chomp(my $sambaLMPassword = substr($ntpwd, 0, index($ntpwd, ':'))); - chomp(my $sambaNTPassword = substr($ntpwd, index($ntpwd, ':')+1)); + chomp(my $sambaLMPassword = substr($ntpwd, 0, index($ntpwd, ':'))); + chomp(my $sambaNTPassword = substr($ntpwd, index($ntpwd, ':')+1)); # the sambaPwdLastSet must be updating my $date=time; + my @mods; + push(@mods, 'sambaLMPassword' => $sambaLMPassword); + push(@mods, 'sambaNTPassword' => $sambaNTPassword); + push(@mods, 'sambaPwdLastSet' => $date); + if (defined $_defaultMaxPasswordAge) { + my $new_sambaPwdMustChange=$date+$_defaultMaxPasswordAge*24*60*60; + push(@mods, 'sambaPwdMustChange' => $new_sambaPwdMustChange); + push(@mods, 'sambaAcctFlags' => '[U]'); + } # Let's change nt/lm passwords my $modify = $ldap_master->modify ( "$dn", - changes => [ - replace => [sambaLMPassword => "$sambaLMPassword"], - replace => [sambaNTPassword => "$sambaNTPassword"], - replace => [sambaPwdLastSet => "$date"] - ] + 'replace' => { @mods } ); $modify->code && warn "failed to modify entry: ", $modify->error ; } else { if ($< != 0) { - my $FILE="|$smbpasswd -s >/dev/null"; - open (FILE, $FILE) || die "$!\n"; - print FILE <modify ( "$dn", - changes => [ - replace => [userPassword => "$hash_password"] - ] - ); + changes => [ + replace => [userPassword => "$hash_password"] + ] + ); $modify->code && warn "Unable to change password : ", $modify->error ; # take down session @@ -186,7 +191,7 @@ smbldap-passwd.pl - change user password =head1 DESCRIPTION - smbldap-passwd.pl changes passwords for user accounts. A normal user +smbldap-passwd.pl changes passwords for user accounts. A normal user may only change the password for their own account, the super user may change the password for any account. diff --git a/examples/LDAP/smbldap-tools/smbldap-populate.pl b/examples/LDAP/smbldap-tools/smbldap-populate.pl index ce497672a9..b691a84850 100755 --- a/examples/LDAP/smbldap-tools/smbldap-populate.pl +++ b/examples/LDAP/smbldap-tools/smbldap-populate.pl @@ -2,6 +2,7 @@ # Populate a LDAP base for Samba-LDAP usage # + # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -39,66 +40,66 @@ use vars qw(%oc); # objectclass of the suffix %oc = ( - "ou" => "organizationalUnit", - "o" => "organization", - "dc" => "dcObject", -); + "ou" => "organizationalUnit", + "o" => "organization", + "dc" => "dcObject", + ); my %Options; my $ok = getopts('a:b:?', \%Options); if ( (!$ok) || ($Options{'?'}) ) { - print "Usage: $0 [-ab?] [ldif]\n"; - print " -a administrator login name (default: Administrator)\n"; - print " -b guest login name (default: nobody)\n"; - print " -? show this help message\n"; - print " ldif file to add to ldap (default: suffix, Groups,"; - print " Users, Computers and builtin users )\n"; - exit (1); + print "Usage: $0 [-ab?] [ldif]\n"; + print " -a administrator login name (default: Administrator)\n"; + print " -b guest login name (default: nobody)\n"; + print " -? show this help message\n"; + print " ldif file to add to ldap (default: suffix, Groups,"; + print " Users, Computers and builtin users )\n"; + exit (1); } my $_ldifName; my $tmp_ldif_file="/tmp/$$.ldif"; if (@ARGV >= 1) { - $_ldifName = $ARGV[0]; + $_ldifName = $ARGV[0]; } my $adminName = $Options{'a'}; if (!defined($adminName)) { - $adminName = "Administrator"; + $adminName = "Administrator"; } my $guestName = $Options{'b'}; if (!defined($guestName)) { - $guestName = "nobody"; + $guestName = "nobody"; } if (!defined($_ldifName)) { - my $attr; - my $val; - my $objcl; + my $attr; + my $val; + my $objcl; print "Using builtin directory structure\n"; - if ($suffix =~ m/([^=]+)=([^,]+)/) { + if ($suffix =~ m/([^=]+)=([^,]+)/) { $attr = $1; $val = $2; $objcl = $oc{$attr} if (exists $oc{$attr}); if (!defined($objcl)) { - $objcl = "myhardcodedobjectclass"; + $objcl = "myhardcodedobjectclass"; } - } else { + } else { die "can't extract first attr and value from suffix $suffix"; - } - #print "$attr=$val\n"; - my ($organisation,$ext) = ($suffix =~ m/dc=(\w+),dc=(\w+)$/); + } + #print "$attr=$val\n"; + my ($organisation,$ext) = ($suffix =~ m/dc=(.*),dc=(.*)$/); - #my $FILE="|cat"; + #my $FILE="|cat"; my $FILE=$tmp_ldif_file; open (FILE, ">$FILE") || die "Can't open file $FILE: $!\n"; - print FILE <= 5.6 @@ -86,13 +88,21 @@ install -m 644 %{SOURCE14} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/FILES install -m 644 %{SOURCE15} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/README install -m 644 %{SOURCE16} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/TODO install -m 644 %{SOURCE21} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/INFRA +install -m 644 %{SOURCE22} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/smb.conf %clean rm -rf $RPM_BUILD_ROOT %post -ln -sf %{prefix}/sbin/smbldap_tools.pm /usr/lib/perl5/site_perl/smbldap_tools.pm -ln -sf %{prefix}/sbin/smbldap_conf.pm /usr/lib/perl5/site_perl/smbldap_conf.pm +# from smbldap-tools-0.8-2, librairies are loaded with the FindBin perl package +if [ -f /usr/lib/perl5/site_perl/smbldap_tools.pm ]; +then + rm -f /usr/lib/perl5/site_perl/smbldap_tools.pm +fi +if [ -f /usr/lib/perl5/site_perl/smbldap_conf.pm ]; +then + rm -f /usr/lib/perl5/site_perl/smbldap_conf.pm +fi chgrp 512 %{prefix}/sbin/smbldap-useradd.pl %{prefix}/sbin/smbldap_conf.pm || echo "An error occured while changing groups of smbldap-useradd.pl and smbldap_conf.pm in /usr/local/sbin. For proper operations, please ensure that they have the same posix group as the Samba domain administrator if there's a local Samba PDC." perl -i -pe 's/_SLAVELDAP_/localhost/' %{prefix}/sbin/smbldap_conf.pm perl -i -pe 's/_MASTERLDAP_/localhost/' %{prefix}/sbin/smbldap_conf.pm @@ -101,11 +111,11 @@ perl -i -pe 's/_USERS_/Users/' %{prefix}/sbin/smbldap_conf.pm perl -i -pe 's/_COMPUTERS_/Computers/' %{prefix}/sbin/smbldap_conf.pm perl -i -pe 's/_GROUPS_/Groups/' %{prefix}/sbin/smbldap_conf.pm perl -i -pe 's/_LOGINSHELL_/\/bin\/bash/' %{prefix}/sbin/smbldap_conf.pm -perl -i -pe 's/_HOMEPREFIX_/\/home\//' %{prefix}/sbin/smbldap_conf.pm +perl -i -pe 's/_HOMEPREFIX_/\/home/' %{prefix}/sbin/smbldap_conf.pm perl -i -pe 's/_BINDDN_/cn=Manager,\$suffix/' %{prefix}/sbin/smbldap_conf.pm perl -i -pe 's/_BINDPW_/secret/' %{prefix}/sbin/smbldap_conf.pm perl -i -pe 's/_PDCNAME_/PDC-SRV/' %{prefix}/sbin/smbldap_conf.pm -perl -i -pe 's/_HOMEDRIVE_/H/' %{prefix}/sbin/smbldap_conf.pm +perl -i -pe 's/_HOMEDRIVE_/H:/' %{prefix}/sbin/smbldap_conf.pm # FIXME: links should not be removed on upgrade #%postun @@ -118,53 +128,13 @@ perl -i -pe 's/_HOMEDRIVE_/H/' %{prefix}/sbin/smbldap_conf.pm %defattr(-,root,root) %{prefix}/sbin/*.pl %{prefix}/sbin/smbldap_tools.pm -%config %{prefix}/sbin/smbldap_conf.pm +%config(noreplace) %{prefix}/sbin/smbldap_conf.pm %{prefix}/sbin/mkntpwd %doc /usr/share/doc/%{name}/ %changelog -* Fri Aug 22 2003 Jerome Tournier 0.8-1 -- support for Samba3.0 +* Fri Nov 28 2003 Jerome Tournier 0.8.2-1 +- new smb.conf file as example configuration file +- see Changelog file for updates in scripts -* Thu Sep 26 2002 Grald Macinenti 0.7-2 -- top and account objectclasses replaced by InetOrgPerson - -* Sat Jun 1 2002 Olivier Lemaire 0.7-1 -- some bugfixes about smbldap-populate -- bugfixed the smbpasswd call in smbldap-useradd -- cleaned up the smbldap_conf -- more documentation - -* Tue Apr 30 2002 Brad Langhorst 0.6-2 -- changed requires samba-common to samba -- replaced /usr/local with %{prefix} to allow relocation - -* Tue Feb 5 2002 David Le Corfec 0.6-1 -- v0.6 - -* Mon Feb 4 2002 David Le Corfec 0.5-1 -- v0.5 - -* Mon Jan 14 2002 David Le Corfec 0.3-4 -- internal changes -- should upgrade smoothly from now on - -* Mon Jan 14 2002 David Le Corfec 0.2-1 -- added migration scripts - -* Fri Dec 28 2001 David Le Corfec 0.1-5 -- numeric group for chmod - -* Thu Dec 27 2001 David Le Corfec 0.1-4 -- misc bugfixes - -* Mon Dec 18 2001 David Le Corfec 0.1-3 -- changed files attrs for domain admins to add users -- added smbldap-populate.pl - -* Fri Dec 14 2001 David Le Corfec -- added mkntpwd - -* Wed Dec 12 2001 Olivier Lemaire -- Spec file was generated, and tested atomically. diff --git a/examples/LDAP/smbldap-tools/smbldap-useradd.pl b/examples/LDAP/smbldap-tools/smbldap-useradd.pl index a84d9f68b2..918bd4a4f6 100755 --- a/examples/LDAP/smbldap-tools/smbldap-useradd.pl +++ b/examples/LDAP/smbldap-tools/smbldap-useradd.pl @@ -35,102 +35,92 @@ use smbldap_conf; use Getopt::Std; my %Options; -my $ok = getopts('axnmwPG:u:g:d:s:c:k:A:B:C:D:E:F:H:N:S:?', \%Options); +my $ok = getopts('anmwPG:u:g:d:s:c:k:A:B:C:D:E:F:H:N:S:?', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { - print "Usage: $0 [-awmugdsckGPABCDEFH?] username\n"; - print " -a is a Windows User (otherwise, Posix stuff only)\n"; - print " -w is a Windows Workstation (otherwise, Posix stuff only)\n"; - print " -x creates rid and primaryGroupID in hex instead of decimal\n"; - print " -u uid\n"; - print " -g gid\n"; - print " -G supplementary comma-separated groups\n"; - print " -n do not create a group\n"; - print " -d home\n"; - print " -s shell\n"; - print " -c gecos\n"; - print " -m creates home directory and copies /etc/skel\n"; - print " -k skeleton dir (with -m)\n"; - print " -P ends by invoking smbldap-passwd.pl\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 sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')\n"; - print " -D sambaHomeDrive (letter associated with home share, like 'H:')\n"; - print " -E sambaLogonScript (DOS script to execute on login)\n"; - print " -F sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n"; - print " -H sambaAcctFlags (samba account control bits like '[NDHTUMWSLKI]')\n"; - print " -N canonical name\n"; - print " -S surname\n"; - print " -? show this help message\n"; - exit (1); + print "Usage: $0 [-awmugdsckGPABCDEFH?] username\n"; + print " -a is a Windows User (otherwise, Posix stuff only)\n"; + print " -w is a Windows Workstation (otherwise, Posix stuff only)\n"; + print " -u uid\n"; + print " -g gid\n"; + print " -G supplementary comma-separated groups\n"; + print " -n do not create a group\n"; + print " -d home\n"; + print " -s shell\n"; + print " -c gecos\n"; + print " -m creates home directory and copies /etc/skel\n"; + print " -k skeleton dir (with -m)\n"; + print " -P ends by invoking smbldap-passwd.pl\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 sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')\n"; + print " -D sambaHomeDrive (letter associated with home share, like 'H:')\n"; + print " -E sambaLogonScript (DOS script to execute on login)\n"; + print " -F sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n"; + print " -H sambaAcctFlags (samba account control bits like '[NDHTUMWSLKI]')\n"; + print " -N canonical name\n"; + print " -S surname\n"; + print " -? show this help message\n"; + exit (1); } + # cause problems when dealing with getpwuid because of the # negative ttl and ldap modification my $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"; + system "/etc/init.d/nscd stop > /dev/null 2>&1"; } + # Read options my $userUidNumber = $Options{'u'}; if (!defined($userUidNumber)) { - # find first unused uid starting from $UID_START - while (defined(getpwuid($UID_START))) { - $UID_START++; - } - $userUidNumber = $UID_START; + # find first unused uid starting from $UID_START + while (defined(getpwuid($UID_START))) { + $UID_START++; + } + $userUidNumber = $UID_START; } elsif (getpwuid($userUidNumber)) { die "Uid already exists.\n"; } if ($nscd_status == 0) { - system "/etc/init.d/nscd start > /dev/null 2>&1"; + system "/etc/init.d/nscd start > /dev/null 2>&1"; } -# as rid we use 2 * uid + 1000 -my $userRid = 2 * $userUidNumber + 1000; -if (defined($Options{'x'})) { - $userRid= sprint("%x", $userRid); -} - my $createGroup = 0; my $userGidNumber = $Options{'g'}; # gid not specified ? if (!defined($userGidNumber)) { - # windows machine => $_defaultComputerGid - if (defined($Options{'w'})) { + # windows machine => $_defaultComputerGid + if (defined($Options{'w'})) { $userGidNumber = $_defaultComputerGid; -# } elsif (!defined($Options{'n'})) { + # } elsif (!defined($Options{'n'})) { # create new group (redhat style) # find first unused gid starting from $GID_START -# while (defined(getgrgid($GID_START))) { -# $GID_START++; -# } -# $userGidNumber = $GID_START; + # while (defined(getgrgid($GID_START))) { + # $GID_START++; + # } + # $userGidNumber = $GID_START; -# $createGroup = 1; + # $createGroup = 1; - } else { + } else { # user will have gid = $_defaultUserGid $userGidNumber = $_defaultUserGid; - } + } } else { - my $gid; - if (($gid = parse_group($userGidNumber)) < 0) { + my $gid; + if (($gid = parse_group($userGidNumber)) < 0) { print "$0: unknown group $userGidNumber\n"; exit (6); - } - $userGidNumber = $gid; + } + $userGidNumber = $gid; } -# as grouprid we use 2 * gid + 1001 -my $userGroupRid = 2 * $userGidNumber + 1001; -if (defined($Options{'x'})) { - $userGroupRid = sprint("%x", $userGroupRid); -} # Read only first @ARGV my $userName = $ARGV[0]; @@ -145,18 +135,49 @@ if ($userName =~ /^([\w -]+\$?)$/) { # user must not exist in LDAP (should it be nss-wide ?) my ($rc, $dn) = get_user_dn2($userName); if ($rc and defined($dn)) { - print "$0: user $userName exists\n"; - exit (9); + print "$0: user $userName exists\n"; + exit (9); } elsif (!$rc) { - print "$0: error in get_user_dn2\n"; - exit(10); + print "$0: error in get_user_dn2\n"; + exit(10); +} + +my $group_entry; +my $userGroupSID; +my $userRid; +if ($Options{'a'}) { + # as grouprid we use the value of the sambaSID attribute for + # group of gidNumber=$userGidNumber + $group_entry = read_group_entry_gid($userGidNumber); + $userGroupSID = $group_entry->get_value('sambaSID'); + unless ($userGroupSID) { + print "$0: unknown group SID not set for unix group $userGidNumber\n"; + print "check if your unix group is mapped to an NT group\n"; + exit (7); + } + + # as rid we use 2 * uid + 1000 + $userRid = 2 * $userUidNumber + 1000; + # let's test if this SID already exist + my $user_sid="$SID-$userRid"; + my $test_exist_sid=does_sid_exist($user_sid,$usersdn); + if ($test_exist_sid->count == 1) { + print "User SID already owned by\n"; + # there should not exist more than one entry, but ... + foreach my $entry ($test_exist_sid->all_entries) { + my $dn= $entry->dn; + chomp($dn); + print "$dn\n"; + } + exit(7); + } } my $userHomeDirectory; my ($userCN, $userSN); my $tmp; if (!defined($userHomeDirectory = $Options{'d'})) { - $userHomeDirectory = $_userHomePrefix."/".$userName; + $userHomeDirectory = $_userHomePrefix."/".$userName; } $_userLoginShell = $tmp if (defined($tmp = $Options{'s'})); $_userGecos = $tmp if (defined($tmp = $Options{'c'})); @@ -174,26 +195,26 @@ my $ldap_master=connect_ldap_master(); # MACHINE ACCOUNT if (defined($tmp = $Options{'w'})) { - # add a trailing dollar if missing - if ($userName =~ /[^\$]$/s) { + # add a trailing dollar if missing + if ($userName =~ /[^\$]$/s) { $userName .= "\$"; - } + } - #print "About to create machine $userName:\n"; + #print "About to create machine $userName:\n"; - if (!add_posix_machine ($userName, $userUidNumber, $userGidNumber)) { + if (!add_posix_machine ($userName, $userUidNumber, $userGidNumber)) { die "$0: error while adding posix account\n"; - } + } - if (!$with_smbpasswd) { + if (!$with_smbpasswd) { # (jtournier) - # Objectclass sambaSAMAccount is now added directly by samba when joigning the domain (for samba3) + # Objectclass sambaSamAccount is now added directly by samba when joigning the domain (for samba3) #if (!add_samba_machine_mkntpwd($userName, $userUidNumber)) { # die "$0: error while adding samba account\n"; #} - } else { + } else { if (!add_samba_machine($userName)) { - die "$0: error while adding samba account\n"; + die "$0: error while adding samba account\n"; } my $modify = $ldap_master->modify ( "$dn", changes => [ @@ -201,9 +222,9 @@ if (defined($tmp = $Options{'w'})) { ] ); $modify->code && warn "failed to modify entry: ", $modify->error ; - } + } - exit 0; + exit 0; } # USER ACCOUNT @@ -237,56 +258,62 @@ group_add_user($userGidNumber, $userName); my $grouplist; # adds to supplementary groups if (defined($grouplist = $Options{'G'})) { - add_grouplist_user($grouplist, $userName); + add_grouplist_user($grouplist, $userName); } # If user was created successfully then we should create his/her home dir if (defined($tmp = $Options{'m'})) { - unless ( $userName =~ /\$$/ ) { + unless ( $userName =~ /\$$/ ) { if ( !(-e $userHomeDirectory) ) { - system "mkdir $userHomeDirectory 2>/dev/null"; - system "cp -a $_skeletonDir/.[a-z,A-Z]* $_skeletonDir/* $userHomeDirectory 2>/dev/null"; - system "chown -R $userUidNumber:$userGidNumber $userHomeDirectory 2>/dev/null"; - system "chmod 700 $userHomeDirectory 2>/dev/null"; + system "mkdir $userHomeDirectory 2>/dev/null"; + system "cp -a $_skeletonDir/.[a-z,A-Z]* $_skeletonDir/* $userHomeDirectory 2>/dev/null"; + system "chown -R $userUidNumber:$userGidNumber $userHomeDirectory 2>/dev/null"; + system "chmod 700 $userHomeDirectory 2>/dev/null"; } - } + } } # Add Samba user infos if (defined($Options{'a'})) { - if (!$with_smbpasswd) { + if (!$with_smbpasswd) { my $winmagic = 2147483647; my $valpwdcanchange = 0; my $valpwdmustchange = $winmagic; + my $valpwdlastset = 0; my $valacctflags = "[UX]"; if (defined($tmp = $Options{'A'})) { - if ($tmp != 0) { + if ($tmp != 0) { $valpwdcanchange = "0"; - } else { + } else { $valpwdcanchange = "$winmagic"; - } + } } if (defined($tmp = $Options{'B'})) { - if ($tmp != 0) { + if ($tmp != 0) { $valpwdmustchange = "0"; - } else { + # To force a user to change his password: + # . the attribut sambaPwdLastSet must be != 0 + # . the attribut sambaAcctFlags must not match the 'X' flag + $valpwdlastset=$winmagic; + $valacctflags = "[U]"; + } else { $valpwdmustchange = "$winmagic"; - } + } } if (defined($tmp = $Options{'H'})) { - $valacctflags = "$tmp"; + $valacctflags = "$tmp"; } my $modify = $ldap_master->modify ( "uid=$userName,$usersdn", changes => [ - add => [objectClass => 'sambaSAMAccount'], - add => [sambaPwdLastSet => '0'], + add => [objectClass => 'sambaSamAccount'], + add => [sambaPwdLastSet => "$valpwdlastset"], add => [sambaLogonTime => '0'], add => [sambaLogoffTime => '2147483647'], add => [sambaKickoffTime => '2147483647'], @@ -300,7 +327,7 @@ if (defined($Options{'a'})) { $modify->code && die "failed to add entry: ", $modify->error ; - } else { + } else { my $FILE="|smbpasswd -s -a $userName >/dev/null" ; open (FILE, $FILE) || die "$!\n"; print FILE <modify ( "uid=$userName,$usersdn", changes => [ - add => [sambaPrimaryGroupSID => "$SID-$userGroupRid"], + add => [sambaPrimaryGroupSID => "$userGroupSID"], add => [sambaHomeDrive => "$valhomedrive"], - add => [sambaHomePath => "$valsmbhome"], - add => [sambaProfilePath => "$valprofilepath"], add => [sambaLogonScript => "$valscriptpath"], add => [sambaLMPassword => 'XXX'], add => [sambaNTPassword => 'XXX'] ] ); + $modify = $ldap_master->modify ( "uid=$userName,$usersdn", + 'replace' => { @mods } + ); + $modify->code && die "failed to add entry: ", $modify->error ; @@ -357,7 +403,7 @@ $ldap_master->unbind; # take down session if (defined($Options{'P'})) { - exec "/usr/local/sbin/smbldap-passwd.pl $userName" + exec "/usr/local/sbin/smbldap-passwd.pl $userName" } exit 0; @@ -366,57 +412,57 @@ exit 0; =head1 NAME - smbldap-useradd.pl - Create a new user or update default new - user information +smbldap-useradd.pl - Create a new user or update default new + user information =head1 SYNOPSIS - smbldap-useradd.pl [-c comment] [-d home_dir] - [-g initial_group] [-G group[,...]] - [-m [-k skeleton_dir]] - [-s shell] [-u uid [ -o]] [-P] - [-A canchange] [-B mustchange] [-C smbhome] - [-D homedrive] [-E scriptpath] [-F profilepath] - [-H acctflags] login +smbldap-useradd.pl [-c comment] [-d home_dir] + [-g initial_group] [-G group[,...]] + [-m [-k skeleton_dir]] + [-s shell] [-u uid [ -o]] [-P] + [-A canchange] [-B mustchange] [-C smbhome] + [-D homedrive] [-E scriptpath] [-F profilepath] + [-H acctflags] login =head1 DESCRIPTION - Creating New Users - The smbldap-useradd.pl command creates a new user account using - the values specified on the command line and the default - values from the system. - The new user account will be entered into the system - files as needed, the home directory will be created, and - initial files copied, depending on the command line options. +Creating New Users + The smbldap-useradd.pl command creates a new user account using + the values specified on the command line and the default + values from the system. + The new user account will be entered into the system + files as needed, the home directory will be created, and + initial files copied, depending on the command line options. - You have to use smbldap-passwd to set the user password. - For Samba users, rid is 2*uidNumber+1000, and primaryGroupID - is 2*gidNumber+1001. Thus you may want to use - smbldap-useradd.pl -a -g "Domain Admins" -u 500 Administrator - to create a sambaDomainName administrator (admin rid is 0x1F4 = 500 and - grouprid is 0x200 = 512) + You have to use smbldap-passwd to set the user password. + For Samba users, rid is 2*uidNumber+1000, and primaryGroupID + is 2*gidNumber+1001. Thus you may want to use + smbldap-useradd.pl -a -g "Domain Admins" -u 500 Administrator + to create a sambaDomainName administrator (admin rid is 0x1F4 = 500 and + grouprid is 0x200 = 512) - Without any option, the account created will be an Unix (Posix) - account. The following options may be used to add information: + Without any option, the account created will be an Unix (Posix) + account. The following options may be used to add information: - -a The user will have a Samba account (and Unix). +-a The user will have a Samba account (and Unix). - -w Creates an account for a Samba machine (Workstation), so that - it can join a sambaDomainName. + -w Creates an account for a Samba machine (Workstation), so that + it can join a sambaDomainName. - -x Creates rid and primaryGroupID in hex (for Samba 2.2.2 bug). Else - decimal (2.2.2 patched from cvs or 2.2.x, x > 2) + -x Creates rid and primaryGroupID in hex (for Samba 2.2.2 bug). Else + decimal (2.2.2 patched from cvs or 2.2.x, x > 2) - -c comment - The new user's comment field (gecos). + -c comment + The new user's comment field (gecos). -d home_dir The new user will be created using home_dir as the value for the user's login directory. The default is to append the login name - to default_home and use that as the login directory name. + to default_home and use that as the login directory name. - -g initial_group - The group name or number of the user's initial login group. The + -g initial_group + The group name or number of the user's initial login group. The group name must exist. A group number must refer to an already existing group. The default group number is 1. @@ -428,20 +474,20 @@ exit 0; is for the user to belong only to the initial group. -m The user's home directory will be created if it does not exist. - The files contained in skeleton_dir will be copied to the home - directory if the -k option is used, otherwise the files con­ - tained in /etc/skel will be used instead. Any directories con­ - tained in skeleton_dir or /etc/skel will be created in the - user's home directory as well. The -k option is only valid in + The files contained in skeleton_dir will be copied to the home + directory if the -k option is used, otherwise the files con + tained in /etc/skel will be used instead. Any directories con + tained in skeleton_dir or /etc/skel will be created in the + user's home directory as well. The -k option is only valid in conjunction with the -m option. The default is to not create the directory and to not copy any files. -s shell The name of the user's login shell. The default is to leave - this field blank, which causes the system to select the default - login shell. + this field blank, which causes the system to select the default + login shell. - -u uid The numerical value of the user's ID. This value must be + -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. The default is to use the smallest ID value greater than 1000 and greater than every other user. diff --git a/examples/LDAP/smbldap-tools/smbldap-userdel.pl b/examples/LDAP/smbldap-tools/smbldap-userdel.pl index 1a1a3214b5..f1e69e209c 100755 --- a/examples/LDAP/smbldap-tools/smbldap-userdel.pl +++ b/examples/LDAP/smbldap-tools/smbldap-userdel.pl @@ -37,9 +37,9 @@ my %Options; my $ok = getopts('r?', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { - print "Usage: $0 [-r?] username\n"; - print " -r remove home directory\n"; - exit (1); + print "Usage: $0 [-r?] username\n"; + print " -r remove home directory\n"; + exit (1); } # Read only first @ARGV @@ -48,34 +48,34 @@ my $user = $ARGV[0]; my $dn; # user must not exist in LDAP if (!defined($dn=get_user_dn($user))) { - print "$0: user $user does not exist\n"; - exit (6); + print "$0: user $user does not exist\n"; + exit (6); } if ($< != 0) { - print "You must be root to delete an user\n"; - exit (1); + print "You must be root to delete an user\n"; + exit (1); } my $homedir; if (defined($Options{'r'})) { - $homedir=get_homedir($user); + $homedir=get_homedir($user); } # remove user from groups my $groups = find_groups_of $user; -my @grplines = split(/\n/, $groups); +my @grplines = split(/\n/,$groups); my $grp; foreach $grp (@grplines) { - my $gname = ""; - if ( $grp =~ /dn: cn=([^,]+),/) { + my $gname = ""; + if ( $grp =~ /dn: cn=([^,]+),/) { $gname = $1; #print "xx $gname\n"; - } - if ($gname ne "") { + } + if ($gname ne "") { group_remove_member($gname, $user); - } + } } # XXX @@ -83,9 +83,9 @@ delete_user($user); # delete dir -- be sure that homeDir is not a strange value if (defined($Options{'r'})) { - if ($homedir !~ /^\/dev/ and $homedir !~ /^\/$/) { + if ($homedir !~ /^\/dev/ and $homedir !~ /^\/$/) { system "rm -rf $homedir"; - } + } } my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; diff --git a/examples/LDAP/smbldap-tools/smbldap-usermod.pl b/examples/LDAP/smbldap-tools/smbldap-usermod.pl index f25c730fc8..70151b7412 100755 --- a/examples/LDAP/smbldap-tools/smbldap-usermod.pl +++ b/examples/LDAP/smbldap-tools/smbldap-usermod.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). @@ -29,48 +29,48 @@ use lib "$RealBin/"; use smbldap_tools; use smbldap_conf; - ##################### use Getopt::Std; my %Options; my $nscd_status; -my $ok = getopts('A:B:C:D:E:F:H:IJN:S:xme:f:u:g:G:d:l:s:c:ok:?h', \%Options); +my $ok = getopts('A:B:C:D:E:F:H:IJN:S:Pame:f:u:g:G:d:l:s:c:ok:?h', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) || ($Options{'h'}) ) { print "Usage: $0 [-awmugdsckxABCDEFGHI?h] username\n"; print "Available options are:\n"; - print " -c gecos\n"; - print " -d home directory\n"; - #print " -m move home directory\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 " -c gecos\n"; + print " -d home directory\n"; + #print " -m move home directory\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 " -N canonical name\n"; print " -S surname\n"; + print " -P ends by invoking smbldap-passwd.pl\n"; print " For samba users:\n"; + print " -a add sambaSamAccount objectclass\n"; print " -e expire date (\"YYYY-MM-DD HH:MM:SS\")\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 sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')\n"; - print " -D sambaHomeDrive (letter associated with home share, like 'H:')\n"; - print " -E sambaLogonScript (DOS script to execute on login)\n"; - print " -F sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n"; - print " -H sambaAcctFlags (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 " -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 sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')\n"; + print " -D sambaHomeDrive (letter associated with home share, like 'H:')\n"; + print " -E sambaLogonScript (DOS script to execute on login)\n"; + print " -F sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n"; + print " -H sambaAcctFlags (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 " -?|-h show this help message\n"; - exit (1); + exit (1); } if ($< != 0) { - print "You must be root to modify an user\n"; - exit (1); + print "You must be root to modify an user\n"; + exit (1); } # Read only first @ARGV @@ -79,13 +79,13 @@ my $user = $ARGV[0]; # Read user data my $user_entry = read_user_entry($user); if (!defined($user_entry)) { - print "$0: user $user doesn't exist\n"; - exit (1); + print "$0: user $user doesn't exist\n"; + exit (1); } my $samba = 0; if (grep ($_ =~ /^sambaSamAccount$/i, $user_entry->get_value('objectClass'))) { - $samba = 1; + $samba = 1; } # get the dn of the user @@ -93,64 +93,94 @@ my $dn= $user_entry->dn(); my $tmp; my @mods; +if (defined($tmp = $Options{'a'})) { + # Let's connect to the directory first + my $ldap_master=connect_ldap_master(); + my $winmagic = 2147483647; + my $valpwdcanchange = 0; + my $valpwdmustchange = $winmagic; + my $valpwdlastset = 0; + my $valacctflags = "[UX]"; + my $user_entry=read_user_entry($user); + my $uidNumber = $user_entry->get_value('uidNumber'); + my $userRid = 2 * $uidNumber + 1000; + # apply changes + my $modify = $ldap_master->modify ( "$dn", + changes => [ + add => [objectClass => 'sambaSamAccount'], + add => [sambaPwdLastSet => "$valpwdlastset"], + add => [sambaLogonTime => '0'], + add => [sambaLogoffTime => '2147483647'], + add => [sambaKickoffTime => '2147483647'], + add => [sambaPwdCanChange => "$valpwdcanchange"], + add => [sambaPwdMustChange => "$valpwdmustchange"], + add => [displayName => "$_userGecos"], + add => [sambaSID=> "$SID-$userRid"], + add => [sambaAcctFlags => "$valacctflags"], + ] + ); + $modify->code && warn "failed to modify entry: ", $modify->error ; +} # Process options my $changed_uid; my $_userUidNumber; my $_userRid; if (defined($tmp = $Options{'u'})) { - if (defined($Options{'o'})) { + 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"; + system "/etc/init.d/nscd stop > /dev/null 2>&1"; } if (getpwuid($tmp)) { - if ($nscd_status == 0) { + if ($nscd_status == 0) { system "/etc/init.d/nscd start > /dev/null 2>&1"; - } + } - print "$0: uid number $tmp exists\n"; - exit (6); + print "$0: uid number $tmp exists\n"; + exit (6); } if ($nscd_status == 0) { - system "/etc/init.d/nscd start > /dev/null 2>&1"; + system "/etc/init.d/nscd start > /dev/null 2>&1"; } - } + } push(@mods, 'uidNumber', $tmp); - $_userUidNumber = $tmp; + $_userUidNumber = $tmp; if ($samba) { # as rid we use 2 * uid + 1000 my $_userRid = 2 * $_userUidNumber + 1000; if (defined($Options{'x'})) { - $_userRid= sprint("%x", $_userRid); + $_userRid= sprint("%x", $_userRid); } push(@mods, 'sambaSID', $SID.'-'.$_userRid); - } - $changed_uid = 1; + } + $changed_uid = 1; } my $changed_gid; my $_userGidNumber; -my $_userGroupRid; +my $_userGroupSID; if (defined($tmp = $Options{'g'})) { - $_userGidNumber = parse_group($tmp); - if ($_userGidNumber < 0) { + $_userGidNumber = parse_group($tmp); + if ($_userGidNumber < 0) { print "$0: group $tmp doesn't exist\n"; exit (6); - } + } push(@mods, 'gidNumber', $_userGidNumber); if ($samba) { -# as grouprid we use 2 * gid + 1001 - my $_userGroupRid = 2 * $_userGidNumber + 1001; - if (defined($Options{'x'})) { - $_userGroupRid = sprint("%x", $_userGroupRid); - } - push(@mods, 'sambaPrimaryGroupSid', $SID.'-'.$_userGroupRid); + # as grouprid we use the sambaSID attribute's value of the group + my $group_entry = read_group_entry_gid($_userGidNumber); + my $_userGroupSID = $group_entry->get_value('sambaSID'); + unless ($_userGroupSID) { + print "$0: unknown group SID not set for unix group $_userGidNumber\n"; + exit (7); } - $changed_gid = 1; + push(@mods, 'sambaPrimaryGroupSid', $_userGroupSID); + } + $changed_gid = 1; } if (defined($tmp = $Options{'s'})) { @@ -158,7 +188,7 @@ if (defined($tmp = $Options{'s'})) { } -if (defined($tmp = $Options{'c'})) { +if (defined($tmp = $Options{'c'})) { push(@mods, 'gecos' => $tmp, 'description' => $tmp); if ($samba == 1) { @@ -180,24 +210,24 @@ if (defined($tmp = $Options{'S'})) { if (defined($tmp = $Options{'G'})) { - # remove user from old groups - my $groups = find_groups_of $user; - my @grplines = split(/\n/, $groups); + # remove user from old groups + my $groups = find_groups_of $user; + my @grplines = split(/\n/,$groups); - my $grp; - foreach $grp (@grplines) { + my $grp; + foreach $grp (@grplines) { my $gname = ""; if ( $grp =~ /dn: cn=([^,]+),/) { - $gname = $1; - #print "xx $gname\n"; + $gname = $1; + #print "xx $gname\n"; } if ($gname ne "") { - group_remove_member($gname, $user); + group_remove_member($gname, $user); } - } + } - # add user to new groups - add_grouplist_user($tmp, $user); + # add user to new groups + add_grouplist_user($tmp, $user); } # @@ -212,7 +242,7 @@ if (defined($tmp = $Options{'G'})) { my $attr; my $winmagic = 2147483647; -my $samba = is_samba_user($user); +$samba = is_samba_user($user); if (defined($tmp = $Options{'e'})) { if ($samba == 1) { @@ -234,9 +264,9 @@ if (defined($tmp = $Options{'A'})) { $_sambaPwdCanChange=$winmagic; } push(@mods, 'sambaPwdCanChange' => $_sambaPwdCanChange); - } else { + } else { print "User $user is not a samba user\n"; - } + } } my $_sambaPwdMustChange; @@ -244,13 +274,31 @@ if (defined($tmp = $Options{'B'})) { if ($samba == 1) { if ($tmp != 0) { $_sambaPwdMustChange=0; + # To force a user to change his password: + # . the attribut sambaPwdLastSet must be != 0 + # . the attribut sambaAcctFlags must not match the 'X' flag + my $_sambaAcctFlags; + my $flags = $user_entry->get_value('sambaAcctFlags'); + if ( $flags =~ /X/ ) { + my $letters; + if ($flags =~ /(\w+)/) { + $letters = $1; + } + $letters =~ s/X//; + $_sambaAcctFlags="\[$letters\]"; + push(@mods, 'sambaAcctFlags' => $_sambaAcctFlags); + } + my $_sambaPwdLastSet = $user_entry->get_value('sambaPwdLastSet'); + if ($_sambaPwdLastSet == 0) { + push(@mods, 'sambaPwdLastSet' => $winmagic); + } } else { $_sambaPwdMustChange=$winmagic; } push(@mods, 'sambaPwdMustChange' => $_sambaPwdMustChange); - } else { + } else { print "User $user is not a samba user\n"; - } + } } if (defined($tmp = $Options{'C'})) { @@ -292,7 +340,7 @@ if (defined($tmp = $Options{'F'})) { if ($samba == 1 and (defined $Options{'H'} or defined $Options{'I'} or defined $Options{'J'})) { my $_sambaAcctFlags; -if (defined($tmp = $Options{'H'})) { + if (defined($tmp = $Options{'H'})) { #$tmp =~ s/\\/\\\\/g; $_sambaAcctFlags=$tmp; } else { @@ -301,24 +349,24 @@ if (defined($tmp = $Options{'H'})) { $flags = $user_entry->get_value('sambaAcctFlags'); if (defined($tmp = $Options{'I'})) { - if ( !($flags =~ /D/) ) { - my $letters; - if ($flags =~ /(\w+)/) { - $letters = $1; - } + if ( !($flags =~ /D/) ) { + my $letters; + if ($flags =~ /(\w+)/) { + $letters = $1; + } $_sambaAcctFlags="\[D$letters\]"; - } -} elsif (defined($tmp = $Options{'J'})) { - if ( $flags =~ /D/ ) { - my $letters; - if ($flags =~ /(\w+)/) { - $letters = $1; - } - $letters =~ s/D//; + } + } elsif (defined($tmp = $Options{'J'})) { + if ( $flags =~ /D/ ) { + my $letters; + if ($flags =~ /(\w+)/) { + $letters = $1; + } + $letters =~ s/D//; $_sambaAcctFlags="\[$letters\]"; } - } -} + } + } if ("$_sambaAcctFlags" ne '') { @@ -344,7 +392,11 @@ $ldap_master->unbind; $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"; + system "/etc/init.d/nscd restart > /dev/null 2>&1"; +} + +if (defined($Options{'P'})) { + exec "/usr/local/sbin/smbldap-passwd.pl $user" } @@ -352,32 +404,32 @@ if ($nscd_status == 0) { =head1 NAME - smbldap-usermod.pl - Modify a user account +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 +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 +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). + -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. + -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. @@ -391,18 +443,18 @@ if ($nscd_status == 0) { -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. + 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 + -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­ + 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. diff --git a/examples/LDAP/smbldap-tools/smbldap-usershow.pl b/examples/LDAP/smbldap-tools/smbldap-usershow.pl index 555b35ffd8..173480d76c 100755 --- a/examples/LDAP/smbldap-tools/smbldap-usershow.pl +++ b/examples/LDAP/smbldap-tools/smbldap-usershow.pl @@ -34,8 +34,8 @@ my %Options; my $ok = getopts('?', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { - print "Usage: $0 [-?] username\n"; - print " -? show this help message\n"; + print "Usage: $0 [-?] username\n"; + print " -? show this help message\n"; exit (1); } diff --git a/examples/LDAP/smbldap-tools/smbldap_conf.pm b/examples/LDAP/smbldap-tools/smbldap_conf.pm index c3d5c1732c..257c205a2c 100644 --- a/examples/LDAP/smbldap-tools/smbldap_conf.pm +++ b/examples/LDAP/smbldap-tools/smbldap_conf.pm @@ -28,33 +28,33 @@ package smbldap_conf; # . be the configuration file for all smbldap-tools scripts use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS -$UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP -$slavePort $masterPort $ldapSSL $slaveURI $masterURI $with_smbpasswd $mk_ntpasswd -$ldap_path $ldap_opts $ldapmodify $suffix $usersdn $computersdn -$groupsdn $scope $binddn $bindpasswd -$slaveDN $slavePw $masterDN $masterPw -$_userLoginShell $_userHomePrefix $_userGecos -$_defaultUserGid $_defaultComputerGid -$_skeletonDir $_userSmbHome -$_userProfile $_userHomeDrive -$_userScript $usersou $computersou $groupsou $SID $hash_encrypt -); + $UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP + $slavePort $masterPort $ldapSSL $slaveURI $masterURI $with_smbpasswd $mk_ntpasswd + $ldap_path $ldap_opts $ldapmodify $suffix $usersdn $computersdn + $groupsdn $scope $binddn $bindpasswd + $slaveDN $slavePw $masterDN $masterPw + $_userLoginShell $_userHomePrefix $_userGecos + $_defaultUserGid $_defaultComputerGid + $_skeletonDir $_userSmbHome + $_userProfile $_userHomeDrive + $_userScript $usersou $computersou $groupsou $SID $hash_encrypt $_defaultMaxPasswordAge + ); use Exporter; $VERSION = 1.00; @ISA = qw(Exporter); @EXPORT = qw( -$UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP -$slavePort $masterPort $ldapSSL $slaveURI $masterURI $with_smbpasswd $mk_ntpasswd -$ldap_path $ldap_opts $ldapmodify $suffix $usersdn -$computersdn $groupsdn $scope $binddn $bindpasswd -$slaveDN $slavePw $masterDN $masterPw -$_userLoginShell $_userHomePrefix $_userGecos -$_defaultUserGid $_defaultComputerGid $_skeletonDir -$_userSmbHome $_userProfile $_userHomeDrive $_userScript -$usersou $computersou $groupsou $SID $hash_encrypt -); + $UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP + $slavePort $masterPort $ldapSSL $slaveURI $masterURI $with_smbpasswd $mk_ntpasswd + $ldap_path $ldap_opts $ldapmodify $suffix $usersdn + $computersdn $groupsdn $scope $binddn $bindpasswd + $slaveDN $slavePw $masterDN $masterPw + $_userLoginShell $_userHomePrefix $_userGecos + $_defaultUserGid $_defaultComputerGid $_skeletonDir + $_userSmbHome $_userProfile $_userHomeDrive $_userScript + $usersou $computersou $groupsou $SID $hash_encrypt $_defaultMaxPasswordAge + ); ############################################################################## @@ -101,7 +101,7 @@ $ldapSSL = "0"; # LDAP Suffix # Ex: $suffix = "dc=IDEALX,dc=ORG"; -$suffix = "dc=IDEALX,dc=ORG"; +$suffix = "dc=IDEALX,dc=COM"; # Where are stored Users @@ -156,7 +156,7 @@ $masterPw = $bindpasswd; $_userLoginShell = q(_LOGINSHELL_); # Home directory prefix (without username) -#Ex: $_userHomePrefix = q(/home/); +# Ex: $_userHomePrefix = q(/home/); $_userHomePrefix = q(_HOMEPREFIX_); # Gecos @@ -171,6 +171,11 @@ $_defaultComputerGid = 553; # Skel dir $_skeletonDir = q(/etc/skel); +# Default password validation time (time in days) Comment the next line if +# you don't want password to be enable for $_defaultMaxPasswordAge days (be +# careful to the sambaPwdMustChange attribute's value) +$_defaultMaxPasswordAge = 45; + ############################################################################## # # SAMBA Configuration @@ -180,11 +185,15 @@ $_skeletonDir = q(/etc/skel); # The UNC path to home drives location without the username last extension # (will be dynamically prepended) # Ex: q(\\\\My-PDC-netbios-name\\homes) for \\My-PDC-netbios-name\homes +# Just comment this if you want to use the smb.conf 'logon home' directive +# and/or desabling roaming profiles $_userSmbHome = q(\\\\_PDCNAME_\\homes); # The UNC path to profiles locations without the username last extension # (will be dynamically prepended) # Ex: q(\\\\My-PDC-netbios-name\\profiles\\) for \\My-PDC-netbios-name\profiles +# Just comment this if you want to use the smb.conf 'logon path' directive +# and/or desabling roaming profiles $_userProfile = q(\\\\_PDCNAME_\\profiles\\); # The default Home Drive Letter mapping @@ -194,7 +203,7 @@ $_userHomeDrive = q(_HOMEDRIVE_); # The default user netlogon script name # if not used, will be automatically username.cmd -#$_userScript = q(startup.cmd); # make sure script file is edited under dos +# $_userScript = q(startup.cmd); # make sure script file is edited under dos ############################################################################## @@ -211,13 +220,13 @@ $mk_ntpasswd = "/usr/local/sbin/mkntpwd"; # those next externals commands are kept fot the migration scripts and # for the populate script: this will be updated as soon as possible - $slaveURI = "ldap://$slaveLDAP:$slavePort"; - $masterURI = "ldap://$masterLDAP:$masterPort"; +$slaveURI = "ldap://$slaveLDAP:$slavePort"; +$masterURI = "ldap://$masterLDAP:$masterPort"; $ldap_path = "/usr/bin"; if ( $ldapSSL eq "0" ) { -$ldap_opts = "-x"; + $ldap_opts = "-x"; } elsif ( $ldapSSL eq "1" ) { $ldap_opts = "-x -Z"; } else { diff --git a/examples/LDAP/smbldap-tools/smbldap_tools.pm b/examples/LDAP/smbldap-tools/smbldap_tools.pm index 8001442fe8..d33a65b7d1 100755 --- a/examples/LDAP/smbldap-tools/smbldap_tools.pm +++ b/examples/LDAP/smbldap-tools/smbldap_tools.pm @@ -34,36 +34,40 @@ $VERSION = 1.00; @ISA = qw(Exporter); @EXPORT = qw( -get_user_dn -get_group_dn + get_user_dn + get_group_dn is_group_member -is_samba_user + is_samba_user is_unix_user -is_user_valid -get_dn_from_line -add_posix_machine -add_samba_machine -add_samba_machine_mkntpwd -group_add_user -add_grouplist_user -disable_user -delete_user -group_add + is_user_valid + does_sid_exist + get_dn_from_line + add_posix_machine + add_samba_machine + add_samba_machine_mkntpwd + group_add_user + add_grouplist_user + disable_user + delete_user + group_add group_del -get_homedir -read_user + get_homedir + read_user read_user_entry -read_group -find_groups_of -parse_group -group_remove_member -group_get_members -do_ldapadd -do_ldapmodify -get_user_dn2 + read_group + read_group_entry + read_group_entry_gid + find_groups_of + parse_group + group_remove_member + group_get_members + do_ldapadd + do_ldapmodify + get_user_dn2 connect_ldap_master connect_ldap_slave -); + group_type_by_name + ); sub connect_ldap_master { @@ -116,14 +120,14 @@ sub connect_ldap_slave } sub get_user_dn -{ + { my $user = shift; my $dn=''; my $ldap_slave=connect_ldap_slave(); my $mesg = $ldap_slave->search ( base => $suffix, - scope => $scope, - filter => "(&(objectclass=posixAccount)(uid=$user))" - ); + scope => $scope, + filter => "(&(objectclass=posixAccount)(uid=$user))" + ); $mesg->code && die $mesg->error; foreach my $entry ($mesg->all_entries) { $dn= $entry->dn; @@ -131,70 +135,70 @@ sub get_user_dn $ldap_slave->unbind; chomp($dn); if ($dn eq '') { - return undef; + return undef; } $dn="dn: ".$dn; return $dn; -} + } sub get_user_dn2 -{ + { my $user = shift; my $dn=''; my $ldap_slave=connect_ldap_slave(); my $mesg = $ldap_slave->search ( base => $suffix, - scope => $scope, - filter => "(&(objectclass=posixAccount)(uid=$user))" - ); + scope => $scope, + filter => "(&(objectclass=posixAccount)(uid=$user))" + ); $mesg->code && warn "failed to perform search; ", $mesg->error; foreach my $entry ($mesg->all_entries) { - $dn= $entry->dn; + $dn= $entry->dn; } $ldap_slave->unbind; chomp($dn); if ($dn eq '') { - return (1,undef); + return (1,undef); } $dn="dn: ".$dn; return (1,$dn); -} + } sub get_group_dn { - my $group = shift; - my $dn=''; + my $group = shift; + my $dn=''; my $ldap_slave=connect_ldap_slave(); my $mesg = $ldap_slave->search ( base => $groupsdn, - scope => $scope, - filter => "(&(objectclass=posixGroup)(|(cn=$group)(gidNumber=$group)))" - ); - $mesg->code && die $mesg->error; - foreach my $entry ($mesg->all_entries) { + scope => $scope, + filter => "(&(objectclass=posixGroup)(|(cn=$group)(gidNumber=$group)))" + ); + $mesg->code && die $mesg->error; + foreach my $entry ($mesg->all_entries) { $dn= $entry->dn; } $ldap_slave->unbind; - chomp($dn); - if ($dn eq '') { + chomp($dn); + if ($dn eq '') { return undef; - } - $dn="dn: ".$dn; - return $dn; + } + $dn="dn: ".$dn; + return $dn; } # return (success, dn) # bool = is_samba_user($username) sub is_samba_user { - my $user = shift; + my $user = shift; my $ldap_slave=connect_ldap_slave(); my $mesg = $ldap_slave->search ( base => $suffix, - scope => $scope, - filter => "(&(objectClass=sambaSamAccount)(uid=$user))" - ); - $mesg->code && die $mesg->error; + scope => $scope, + filter => "(&(objectClass=sambaSamAccount)(uid=$user))" + ); + $mesg->code && die $mesg->error; $ldap_slave->unbind; return ($mesg->count ne 0); } @@ -217,52 +221,68 @@ sub is_group_member my $dn_group = shift; my $user = shift; my $ldap_slave=connect_ldap_slave(); - my $mesg = $ldap_slave->search ( - base => "$dn_group", + my $mesg = $ldap_slave->search ( base => $dn_group, scope => 'base', filter => "(&(memberUid=$user))" ); $mesg->code && die $mesg->error; $ldap_slave->unbind; - return ($mesg->count ne 0); + return ($mesg->count ne 0); } +# all entries = does_sid_exist($sid,$scope) +sub does_sid_exist + { + my $sid = shift; + my $dn_group=shift; + my $ldap_slave=connect_ldap_slave(); + my $mesg = $ldap_slave->search ( base => $dn_group, + scope => $scope, + filter => "(sambaSID=$sid)" + #filter => "(&(objectClass=sambaSamAccount|objectClass=sambaGroupMapping)(sambaSID=$sid))" + ); + $mesg->code && die $mesg->error; + $ldap_slave->unbind; + return ($mesg); + } # try to bind with user dn and password to validate current password sub is_user_valid { - my ($user, $dn, $pass) = @_; - my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; - my $mesg= $ldap->bind (dn => $dn, password => $pass ); + my ($user, $dn, $pass) = @_; + my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; + my $mesg= $ldap->bind (dn => $dn, password => $pass ); if ($mesg->code eq 0) { - $ldap->unbind; - return 1; + $ldap->unbind; + return 1; } else { - if($ldap->bind()) { + if ($ldap->bind()) { $ldap->unbind; return 0; - } else { + } else { print ("The LDAP directory is not available.\n Check the server, cables ..."); $ldap->unbind; return 0; } die "Problem : contact your administrator"; } -} + } + # dn = get_dn_from_line ($dn_line) # helper to get "a=b,c=d" from "dn: a=b,c=d" sub get_dn_from_line { - my $dn = shift; - $dn =~ s/^dn: //; - return $dn; + my $dn = shift; + $dn =~ s/^dn: //; + return $dn; } + # success = add_posix_machine($user, $uid, $gid) sub add_posix_machine { - my ($user, $uid, $gid) = @_; + my ($user, $uid, $gid) = @_; # bind to a directory with dn and password my $ldap_master=connect_ldap_master(); my $add = $ldap_master->add ( "uid=$user,$computersdn", @@ -288,32 +308,32 @@ sub add_posix_machine # success = add_samba_machine($computername) sub add_samba_machine -{ + { my $user = shift; system "smbpasswd -a -m $user"; return 1; -} + } sub add_samba_machine_mkntpwd { - my ($user, $uid) = @_; - my $sambaSID = 2 * $uid + 1000; - my $name = $user; - $name =~ s/.$//s; + my ($user, $uid) = @_; + my $sambaSID = 2 * $uid + 1000; + my $name = $user; + $name =~ s/.$//s; - if ($mk_ntpasswd eq '') { + if ($mk_ntpasswd eq '') { print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n"; return 0; - } + } - my $ntpwd = `$mk_ntpasswd '$name'`; - chomp(my $lmpassword = substr($ntpwd, 0, index($ntpwd, ':'))); - chomp(my $ntpassword = substr($ntpwd, index($ntpwd, ':')+1)); + my $ntpwd = `$mk_ntpasswd '$name'`; + chomp(my $lmpassword = substr($ntpwd, 0, index($ntpwd, ':'))); + chomp(my $ntpassword = substr($ntpwd, index($ntpwd, ':')+1)); my $ldap_master=connect_ldap_master(); my $modify = $ldap_master->modify ( "uid=$user,$computersdn", changes => [ - replace => [objectClass => ['inetOrgPerson', 'posixAccount', 'sambaSAMAccount']], + replace => [objectClass => ['inetOrgPerson', 'posixAccount', 'sambaSamAccount']], add => [sambaPwdLastSet => '0'], add => [sambaLogonTime => '0'], add => [sambaLogoffTime => '2147483647'], @@ -330,7 +350,7 @@ sub add_samba_machine_mkntpwd $modify->code && die "failed to add entry: ", $modify->error ; - return 1; + return 1; # take down the session $ldap_master->unbind; @@ -339,16 +359,16 @@ sub add_samba_machine_mkntpwd sub group_add_user { - my ($group, $userid) = @_; - my $members=''; - my $dn_line = get_group_dn($group); + my ($group, $userid) = @_; + my $members=''; + my $dn_line = get_group_dn($group); if (!defined(get_group_dn($group))) { print "$0: group \"$group\" doesn't exist\n"; exit (6); } - if (!defined($dn_line)) { + if (!defined($dn_line)) { return 1; - } + } my $dn = get_dn_from_line("$dn_line"); # on look if the user is already present in the group my $is_member=is_group_member($dn,$userid); @@ -367,8 +387,8 @@ sub group_add_user $modify->code && die "failed to modify entry: ", $modify->error ; # take down session $ldap_master->unbind; - } - } + } + } sub group_del { @@ -383,23 +403,23 @@ sub group_del sub add_grouplist_user { - my ($grouplist, $user) = @_; - my @array = split(/,/, $grouplist); - foreach my $group (@array) { + my ($grouplist, $user) = @_; + my @array = split(/,/, $grouplist); + foreach my $group (@array) { group_add_user($group, $user); - } + } } sub disable_user { - my $user = shift; - my $dn_line; + my $user = shift; + my $dn_line; my $dn = get_dn_from_line($dn_line); - - if (!defined($dn_line = get_user_dn($user))) { + + if (!defined($dn_line = get_user_dn($user))) { print "$0: user $user doesn't exist\n"; exit (10); - } + } my $ldap_master=connect_ldap_master(); my $modify = $ldap_master->modify ( "$dn", changes => [ @@ -408,14 +428,14 @@ sub disable_user ); $modify->code && die "failed to modify entry: ", $modify->error ; - if (is_samba_user($user)) { + if (is_samba_user($user)) { my $modify = $ldap_master->modify ( "$dn", changes => [ replace => [sambaAcctFlags => '[D ]'] ] ); $modify->code && die "failed to modify entry: ", $modify->error ; - } + } # take down session $ldap_master->unbind; } @@ -423,43 +443,43 @@ sub disable_user # delete_user($user) sub delete_user { - my $user = shift; - my $dn_line; + my $user = shift; + my $dn_line; - if (!defined($dn_line = get_user_dn($user))) { + if (!defined($dn_line = get_user_dn($user))) { print "$0: user $user doesn't exist\n"; exit (10); - } + } - my $dn = get_dn_from_line($dn_line); + my $dn = get_dn_from_line($dn_line); my $ldap_master=connect_ldap_master(); my $modify = $ldap_master->delete($dn); $ldap_master->unbind; } -# $success = group_add($groupname, $group_gid, $force_using_existing_gid) +# $gid = group_add($groupname, $group_gid, $force_using_existing_gid) sub group_add { - my ($gname, $gid, $force) = @_; - my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; - if ($nscd_status == 0) { + my ($gname, $gid, $force) = @_; + my $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 (!defined($gid)) { + } + if (!defined($gid)) { while (defined(getgrgid($GID_START))) { - $GID_START++; + $GID_START++; } $gid = $GID_START; - } else { + } else { if (!defined($force)) { - if (defined(getgrgid($gid))) { - return 0; - } + if (defined(getgrgid($gid))) { + return undef; + } } - } - if ($nscd_status == 0) { + } + if ($nscd_status == 0) { system "/etc/init.d/nscd start > /dev/null 2>&1"; - } + } my $ldap_master=connect_ldap_master(); my $modify = $ldap_master->add ( "cn=$gname,$groupsdn", attrs => [ @@ -472,67 +492,67 @@ sub group_add $modify->code && die "failed to add entry: ", $modify->error ; # take down session $ldap_master->unbind; - return 1; + return $gid; } # $homedir = get_homedir ($user) sub get_homedir { - my $user = shift; - my $homeDir=''; + my $user = shift; + my $homeDir=''; my $ldap_slave=connect_ldap_slave(); my $mesg = $ldap_slave->search ( base =>$suffix, scope => $scope, filter => "(&(objectclass=posixAccount)(uid=$user))" ); - $mesg->code && die $mesg->error; - foreach my $entry ($mesg->all_entries){ + $mesg->code && die $mesg->error; + foreach my $entry ($mesg->all_entries) { foreach my $attr ($entry->attributes) { - if ($attr=~/\bhomeDirectory\b/){ - foreach my $ent($entry->get_value($attr)) { + if ($attr=~/\bhomeDirectory\b/) { + foreach my $ent ($entry->get_value($attr)) { $homeDir.= $attr.": ".$ent."\n"; - } + } } - } - } + } + } $ldap_slave->unbind; - chomp $homeDir; - if ($homeDir eq '') { + chomp $homeDir; + if ($homeDir eq '') { return undef; - } - $homeDir =~ s/^homeDirectory: //; - return $homeDir; + } + $homeDir =~ s/^homeDirectory: //; + return $homeDir; } # search for an user sub read_user { - my $user = shift; - my $lines =''; + my $user = shift; + my $lines =''; my $ldap_slave=connect_ldap_slave(); my $mesg = $ldap_slave->search ( # perform a search - base => $suffix, - scope => $scope, - filter => "(&(objectclass=posixAccount)(uid=$user))" - ); + base => $suffix, + scope => $scope, + filter => "(&(objectclass=posixAccount)(uid=$user))" + ); - $mesg->code && die $mesg->error; - foreach my $entry ($mesg->all_entries) { + $mesg->code && die $mesg->error; + foreach my $entry ($mesg->all_entries) { $lines.= "dn: " . $entry->dn."\n"; foreach my $attr ($entry->attributes) { - { + { $lines.= $attr.": ".join(',', $entry->get_value($attr))."\n"; - } + } } - } + } # take down session $ldap_slave->unbind; - chomp $lines; - if ($lines eq '') { + chomp $lines; + if ($lines eq '') { return undef; - } - return $lines; + } + return $lines; } # search for a user @@ -556,86 +576,124 @@ sub read_user_entry # search for a group sub read_group { - my $user = shift; - my $lines =''; + my $user = shift; + my $lines =''; my $ldap_slave=connect_ldap_slave(); my $mesg = $ldap_slave->search ( # perform a search - base => $groupsdn, - scope => $scope, - filter => "(&(objectclass=posixGroup)(cn=$user))" - ); + base => $groupsdn, + scope => $scope, + filter => "(&(objectclass=posixGroup)(cn=$user))" + ); - $mesg->code && die $mesg->error; - foreach my $entry ($mesg->all_entries) { + $mesg->code && die $mesg->error; + foreach my $entry ($mesg->all_entries) { $lines.= "dn: " . $entry->dn."\n"; foreach my $attr ($entry->attributes) { - { + { $lines.= $attr.": ".join(',', $entry->get_value($attr))."\n"; - } + } } - } + } # take down session $ldap_slave->unbind; - chomp $lines; - if ($lines eq '') { + chomp $lines; + if ($lines eq '') { return undef; - } - return $lines; + } + return $lines; } # find groups of a given user ##### MODIFIE ######## sub find_groups_of { - my $user = shift; - my $lines =''; + my $user = shift; + my $lines =''; my $ldap_slave=connect_ldap_slave; my $mesg = $ldap_slave->search ( # perform a search - base => $groupsdn, - scope => $scope, - filter => "(&(objectclass=posixGroup)(memberuid=$user))" - ); - $mesg->code && die $mesg->error; - foreach my $entry ($mesg->all_entries) { + base => $groupsdn, + scope => $scope, + filter => "(&(objectclass=posixGroup)(memberuid=$user))" + ); + $mesg->code && die $mesg->error; + foreach my $entry ($mesg->all_entries) { $lines.= "dn: ".$entry->dn."\n"; - } + } $ldap_slave->unbind; - chomp($lines); + chomp($lines); if ($lines eq '') { return undef; } - return $lines; + return $lines; + } + +sub read_group_entry { + my $group = shift; + my $entry; + my %res; + my $ldap_slave=connect_ldap_slave(); + my $mesg = $ldap_slave->search ( # perform a search + base => $groupsdn, + scope => $scope, + filter => "(&(objectclass=posixGroup)(cn=$group))" + ); + + $mesg->code && die $mesg->error; + my $nb=$mesg->count; + if ($nb > 1) { + print "Error: $nb groups exist \"cn=$group\"\n"; + foreach $entry ($mesg->all_entries) { my $dn=$entry->dn; print " $dn\n"; } + exit 11; + } else { + $entry = $mesg->shift_entry(); } + return $entry; +} + +sub read_group_entry_gid { + my $group = shift; + my %res; + my $ldap_slave=connect_ldap_slave(); + my $mesg = $ldap_slave->search ( # perform a search + base => $groupsdn, + scope => $scope, + filter => "(&(objectclass=posixGroup)(gidNumber=$group))" + ); + + $mesg->code && die $mesg->error; + my $entry = $mesg->shift_entry(); + return $entry; +} # return the gidnumber for a group given as name or gid # -1 : bad group name # -2 : bad gidnumber sub parse_group { - my $userGidNumber = shift; - if ($userGidNumber =~ /[^\d]/ ) { + my $userGidNumber = shift; + if ($userGidNumber =~ /[^\d]/ ) { my $gname = $userGidNumber; my $gidnum = getgrnam($gname); if ($gidnum !~ /\d+/) { - return -1; + return -1; } else { - $userGidNumber = $gidnum; + $userGidNumber = $gidnum; } - } elsif (!defined(getgrgid($userGidNumber))) { + } elsif (!defined(getgrgid($userGidNumber))) { return -2; - } - return $userGidNumber; + } + return $userGidNumber; } # remove $user from $group sub group_remove_member { - my ($group, $user) = @_; - my $members=''; - my $grp_line = get_group_dn($group); - if (!defined($grp_line)) { + my ($group, $user) = @_; + my $members=''; + my $grp_line = get_group_dn($group); + if (!defined($grp_line)) { return 0; - } + } my $dn = get_dn_from_line($grp_line); # we test if the user exist in the group my $is_member=is_group_member($dn,$user); @@ -646,40 +704,40 @@ sub group_remove_member changes => [ delete => [memberUid => ["$user"]] ] - ); + ); $modify->code && die "failed to delete entry: ", $modify->error ; $ldap_master->unbind; - } - return 1; + } + return 1; } sub group_get_members { - my ($group) = @_; - my $members; - my @resultat; - my $grp_line = get_group_dn($group); + my ($group) = @_; + my $members; + my @resultat; + my $grp_line = get_group_dn($group); if (!defined($grp_line)) { return 0; } - my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; - $ldap->bind ; + my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; + $ldap->bind ; my $mesg = $ldap->search ( base => $groupsdn, - scope => $scope, - filter => "(&(objectclass=posixgroup)(cn=$group))" - ); - $mesg->code && die $mesg->error; - foreach my $entry ($mesg->all_entries){ - foreach my $attr ($entry->attributes){ - if ($attr=~/\bmemberUid\b/){ + scope => $scope, + filter => "(&(objectclass=posixgroup)(cn=$group))" + ); + $mesg->code && die $mesg->error; + foreach my $entry ($mesg->all_entries) { + foreach my $attr ($entry->attributes) { + if ($attr=~/\bmemberUid\b/) { foreach my $ent ($entry->get_value($attr)) { push (@resultat,$ent); - } + } + } } - } -} + } return @resultat; } @@ -697,5 +755,17 @@ EOF return $rc; } +sub group_type_by_name { + my $type_name = shift; + my %groupmap = ( + 'domain' => 2, + 'local' => 4, + 'builtin' => 5 + ); + return $groupmap{$type_name}; +} + + + 1; -- cgit