From: Gerald Carter Date: Thu, 4 Dec 2003 22:02:05 +0000 (+0000) Subject: updating top 0.8.2-1 of the smbldap tools X-Git-Tag: samba-3.0.1rc1~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=212ddc5baf2116dd189080fec7efa1ed856e9cb8;p=thirdparty%2Fsamba.git updating top 0.8.2-1 of the smbldap tools --- diff --git a/examples/LDAP/smbldap-tools/CONTRIBUTORS b/examples/LDAP/smbldap-tools/CONTRIBUTORS index 59dafcc89ef..d080dd020e8 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: + . Jérôme Tournier . Terry Davis . David Le Corfec . Olivier Lemaire - . Jérôme 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 0994cb49316..e6394d1addf 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 0343c53d609..48ee571b29d 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/INFRA b/examples/LDAP/smbldap-tools/INFRA new file mode 100644 index 00000000000..fe5ce8df2b8 --- /dev/null +++ b/examples/LDAP/smbldap-tools/INFRA @@ -0,0 +1,93 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/Attic/INFRA,v $ +# +## Some notes about the architecture + + +Global Architecture for smbdlap-tools +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +smbldap-tools help you manage users and groups for Unix and Samba, +using LDAP. They may be used in any context, and are kept relatively +simplier enought to let you customize them to you needs. + +They need the following objectClasses to work: + . sambaAccount: from samba.schema for Samba 2.2 branch + . posixAccount and posixGroup : from nis.schema + . organizationalUnit and dcObject: from core.schema + +They will probably use in a near future some additional objectClasses +to support : + . mail features (sendmail/postfix/qmail/courier). + . conform to RFC2307 best practices (and so some maps too like merging + Netbios computers (sambaAccounts) with ipHosts + +For ease of visualization of the LDAP objects by human standards, we +used a DIT like this one : + . dc=IDEALX,dc=org : the company/organization suffix + . ou=Users : to store users accounts + . ou=Computers : to store computers accounts + . ou=Groups : to store system groups +Of course, you're free to use a different naming scheme and DIT (see +smbldap_conf.pm). + + +Built in groups initial population +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +smbldap-populate.pl populate the LDAP directory with some built in groups +using gidNumber according to Well Know RID of Windows NT4 Srv. In fact, As +far a Samba 2.2.x is concerned, only the 'Domain Admins' (gidNumber 512) have +real inpact on the Samba and Windows population. To activate this group as +the Domain Administrators Group, use the following smb.conf directive (see +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. + +Why these specific gidNumbers ? +It's about unix/windows mapping of numerical ids with Samba. Ids below 1024 +are NT special ids. In fact, 512 is the RID (Windows uid/gid) for the +"Domain Administrators" NT group. The magic number is found in Samba sources +and possibly other Samba/Windows documentations. + +The goal is to have a set of Unix users who are Domain Administrators and can +modify Samba datas (eg. LDAP content), with commandline tools or within +Windows via Samba. + +Say you want to add a NT4 ws to an NT domain (controlled by a samba/ldap +server). You give the domain administrator's login and password in the +appropriate ws settings, then the ws contacts the samba server, which checks +the credentials and use them as unix user to run the smbldap-tools (if I +remember). Giving 512 as a RID to a LDAP entry marks it as a domain admin +for Samba (thus Windows). Using nss_ldap, you also have an account with +gid 512. + + +Known BUGS and WORKAROUND used +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +The 2.2.2 has at least a bug : rid/primaryGroupID are read as hex in LDAP, +but written as decimal. Fixed in CVS by reading as decimal. By default +smbldap-useradd.pl writes decimal to LDAP. Use -x to support the odd +behaviour. + +The samba-2.2.4-ldapbindnotuid0.patch is not a perfect solution however +as 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). + +# - The End diff --git a/examples/LDAP/smbldap-tools/INSTALL b/examples/LDAP/smbldap-tools/INSTALL index d5ca07826f4..f4c72751a75 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/README b/examples/LDAP/smbldap-tools/README index 3b4bf2da0dd..add0175c0ce 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 25cc30c6845..71e66952997 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 91cd2dad532..6b02cdd26ca 100755 --- a/examples/LDAP/smbldap-tools/smbldap-groupadd.pl +++ b/examples/LDAP/smbldap-tools/smbldap-groupadd.pl @@ -1,5 +1,7 @@ #!/usr/bin/perl -w +# $Id: smbldap-groupadd.pl,v 1.1.8.3 2003/12/04 22:02:05 jerry Exp $ +# # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -27,33 +29,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 ($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_add($_groupName, $_groupGidNumber, $Options{'o'})) { - print "$0: error adding group $_groupName\n"; - exit (6); +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 89d0d993acf..98b606ddb84 100755 --- a/examples/LDAP/smbldap-tools/smbldap-groupdel.pl +++ b/examples/LDAP/smbldap-tools/smbldap-groupdel.pl @@ -1,5 +1,7 @@ #!/usr/bin/perl -w +# $Id: smbldap-groupdel.pl,v 1.1.8.3 2003/12/04 22:02:05 jerry Exp $ +# # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -30,23 +32,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 +57,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 f8971016027..2eb04c24869 100755 --- a/examples/LDAP/smbldap-tools/smbldap-groupmod.pl +++ b/examples/LDAP/smbldap-tools/smbldap-groupmod.pl @@ -1,4 +1,7 @@ #!/usr/bin/perl -w + +# $Id: smbldap-groupmod.pl,v 1.1.8.5 2003/12/04 22:02:05 jerry Exp $ +# # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -29,29 +32,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 +66,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 +93,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 +112,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 +136,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 +161,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 +236,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 18fe082e665..265c3fd7ba2 100755 --- a/examples/LDAP/smbldap-tools/smbldap-groupshow.pl +++ b/examples/LDAP/smbldap-tools/smbldap-groupshow.pl @@ -1,5 +1,7 @@ #!/usr/bin/perl -w +# $Id: smbldap-groupshow.pl,v 1.1.8.3 2003/12/04 22:02:05 jerry Exp $ +# # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -36,8 +38,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 86f52cb53e1..cb54cae3918 100755 --- a/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl +++ b/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl @@ -1,5 +1,7 @@ #!/usr/bin/perl -w +# $Id: smbldap-migrate-accounts.pl,v 1.1.8.3 2003/12/04 22:02:05 jerry Exp $ +# # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -39,8 +41,8 @@ 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", @@ -54,7 +56,7 @@ sub modify_account $modify->code && die "failed to modify entry: ", $modify->error ; # take down the session $ldap_master->unbind; -} + } ##################### @@ -64,15 +66,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 +92,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 +119,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 +143,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 +189,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 c60be18caf8..3a15485e9f8 100644 --- a/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl +++ b/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl @@ -1,5 +1,7 @@ #!/usr/bin/perl +# $Id: smbldap-migrate-groups.pl,v 1.1.8.3 2003/12/04 22:02:05 jerry Exp $ +# # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -33,52 +35,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 +94,7 @@ sub modify_group my $mbs; foreach $m (@new_mb) { - $mbs .= "memberUid: $m\n"; + $mbs .= "memberUid: $m\n"; } my $mods="$dn_line @@ -105,16 +105,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 +122,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 +166,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 +184,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 7845e5548e2..d96a4537bca 100755 --- a/examples/LDAP/smbldap-tools/smbldap-passwd.pl +++ b/examples/LDAP/smbldap-tools/smbldap-passwd.pl @@ -1,7 +1,8 @@ #!/usr/bin/perl -w # LDAP to unix password sync script for samba -# +# $Id: smbldap-passwd.pl,v 1.1.8.3 2003/12/04 22:02:05 jerry Exp $ + # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -23,7 +24,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 +41,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 +74,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 +105,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 +114,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 +192,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 ce497672a96..c97fa6787fe 100755 --- a/examples/LDAP/smbldap-tools/smbldap-populate.pl +++ b/examples/LDAP/smbldap-tools/smbldap-populate.pl @@ -2,6 +2,8 @@ # Populate a LDAP base for Samba-LDAP usage # +# $Id: smbldap-populate.pl,v 1.1.8.3 2003/12/04 22:02:05 jerry Exp $ + # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -39,66 +41,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 Gérald 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 a84d9f68b21..c3e7c215c43 100755 --- a/examples/LDAP/smbldap-tools/smbldap-useradd.pl +++ b/examples/LDAP/smbldap-tools/smbldap-useradd.pl @@ -1,5 +1,7 @@ #!/usr/bin/perl -w +# $Id: smbldap-useradd.pl,v 1.1.8.3 2003/12/04 22:02:05 jerry Exp $ +# # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -35,102 +37,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 +137,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 +197,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) #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 +224,9 @@ if (defined($tmp = $Options{'w'})) { ] ); $modify->code && warn "failed to modify entry: ", $modify->error ; - } + } - exit 0; + exit 0; } # USER ACCOUNT @@ -237,56 +260,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 => [sambaPwdLastSet => "$valpwdlastset"], add => [sambaLogonTime => '0'], add => [sambaLogoffTime => '2147483647'], add => [sambaKickoffTime => '2147483647'], @@ -300,7 +329,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 +405,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 +414,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 +476,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 1a1a3214b58..fee7739e714 100755 --- a/examples/LDAP/smbldap-tools/smbldap-userdel.pl +++ b/examples/LDAP/smbldap-tools/smbldap-userdel.pl @@ -1,5 +1,7 @@ #!/usr/bin/perl +# $Id: smbldap-userdel.pl,v 1.1.8.3 2003/12/04 22:02:05 jerry Exp $ +# # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -37,9 +39,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 +50,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 +85,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 f25c730fc85..3b9486a7537 100755 --- a/examples/LDAP/smbldap-tools/smbldap-usermod.pl +++ b/examples/LDAP/smbldap-tools/smbldap-usermod.pl @@ -1,5 +1,7 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w +# $Id: smbldap-usermod.pl,v 1.1.8.3 2003/12/04 22:02:05 jerry Exp $ +# # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -29,48 +31,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 +81,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 +95,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 +190,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 +212,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 +244,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 +266,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 +276,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 +342,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 +351,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 +394,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 +406,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 +445,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 555b35ffd81..2fe1190b991 100755 --- a/examples/LDAP/smbldap-tools/smbldap-usershow.pl +++ b/examples/LDAP/smbldap-tools/smbldap-usershow.pl @@ -1,5 +1,7 @@ #!/usr/bin/perl -w +# $Id: smbldap-usershow.pl,v 1.1.8.3 2003/12/04 22:02:05 jerry Exp $ +# # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -34,8 +36,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 c3d5c1732c7..a380e8a56bd 100644 --- a/examples/LDAP/smbldap-tools/smbldap_conf.pm +++ b/examples/LDAP/smbldap-tools/smbldap_conf.pm @@ -2,6 +2,9 @@ use strict; package smbldap_conf; +# $Dource: $ +# $Id: smbldap_conf.pm,v 1.1.8.3 2003/12/04 22:02:05 jerry Exp $ +# # smbldap-tools.conf : Q & D configuration file for smbldap-tools # This code was developped by IDEALX (http://IDEALX.org/) and @@ -28,33 +31,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 +104,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 +159,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 +174,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 +188,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 +206,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 +223,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 8001442fe8f..140f2ce9e7a 100755 --- a/examples/LDAP/smbldap-tools/smbldap_tools.pm +++ b/examples/LDAP/smbldap-tools/smbldap_tools.pm @@ -4,6 +4,8 @@ package smbldap_tools; use smbldap_conf; use Net::LDAP; +# $Id: smbldap_tools.pm,v 1.1.8.3 2003/12/04 22:02:05 jerry Exp $ +# # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -34,36 +36,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 +122,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 +137,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 +223,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,27 +310,27 @@ 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", @@ -330,7 +352,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 +361,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 +389,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 +405,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 +430,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 +445,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 +494,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 +578,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 +706,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 +757,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;