merging from 3.0
authorGerald Carter <jerry@samba.org>
Tue, 6 Jan 2004 14:45:56 +0000 (14:45 +0000)
committerGerald Carter <jerry@samba.org>
Tue, 6 Jan 2004 14:45:56 +0000 (14:45 +0000)
(This used to be commit 694052f8a9cc703d4e4ec8075c623ab7122a169b)

23 files changed:
examples/LDAP/smbldap-tools/CONTRIBUTORS
examples/LDAP/smbldap-tools/ChangeLog
examples/LDAP/smbldap-tools/FILES
examples/LDAP/smbldap-tools/INFRASTRUCTURE
examples/LDAP/smbldap-tools/INSTALL
examples/LDAP/smbldap-tools/Makefile
examples/LDAP/smbldap-tools/README
examples/LDAP/smbldap-tools/TODO
examples/LDAP/smbldap-tools/smbldap-groupadd.pl
examples/LDAP/smbldap-tools/smbldap-groupdel.pl
examples/LDAP/smbldap-tools/smbldap-groupmod.pl
examples/LDAP/smbldap-tools/smbldap-groupshow.pl
examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl
examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl
examples/LDAP/smbldap-tools/smbldap-passwd.pl
examples/LDAP/smbldap-tools/smbldap-populate.pl
examples/LDAP/smbldap-tools/smbldap-tools.spec
examples/LDAP/smbldap-tools/smbldap-useradd.pl
examples/LDAP/smbldap-tools/smbldap-userdel.pl
examples/LDAP/smbldap-tools/smbldap-usermod.pl
examples/LDAP/smbldap-tools/smbldap-usershow.pl
examples/LDAP/smbldap-tools/smbldap_conf.pm
examples/LDAP/smbldap-tools/smbldap_tools.pm

index 59dafcc89ef9d3930bc7ae91be5d83f8a2606c58..d080dd020e8ea3f370952fd73f8ad66b4c4e7398 100644 (file)
@@ -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 <jerome.tournier@IDEALX.com>
  . Terry Davis <terry@terryd.net>
  . David Le Corfec <dlc@freesurf.fr>
  . Olivier Lemaire <olivier.lemaire@IDEALX.com>
- . Jérôme Tournier <jerome.tournier@IDEALX.com>
 
 Many thanks to contributors for bug report and patches:
+ . Marc Schoechlin <ms@LF.net>
+       load the perl-modules without setting environment-variables or making symlinks
+ . Alexander Bergolth <leo@strike.wu-wien.ac.at>
+       more Net::LDAP support
  . Gert-Jan Braas <braas@wyldebeast-wunderliebe.com>
        bug report for 2.2.3 samba.schema
  . Jody Haynes <Jody.Haynes@isunnetworks.com>
index 0994cb493162780f273f27c910ecad47bd07b43e..e4e376838586a6088a9c4ce873dde14ca4c6a194 100644 (file)
@@ -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 <leo@strike.wu-wien.ac.at>: 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 <leo@strike.wu-wien.ac.at>:
+         gid-sid group mapping to smbldap-groupadd.pl and smbldap-groupmod.pl
+2003-09-19: Patch from Marc Schoechlin <ms@LF.net>
+       . load the perl-modules without setting environment-variables or making symlinks
+2003-09-18: Patch from Alexander Bergolth <leo@strike.wu-wien.ac.at>
+       . 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
index 0343c53d609aeec265e43c95952ec8acec90b8f8..48ee571b29d3c0b8a44646b17c2d949bdd336136 100644 (file)
@@ -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
index 25fbda859993de598d38da69bf2378fb20e1fccd..e14ec70e0274c1133fc9fda799323af87031c2f6 100644 (file)
@@ -1,3 +1,5 @@
+# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/INFRASTRUCTURE,v $
+#
 ## Some notes about the architecture
 
 
@@ -41,6 +43,15 @@ man smb.conf for more):
 
        domain admin group = " @"Domain Admins" "
 
+However, to make pdb_ldap accept bind without being uid=0, a quick and
+dirty patch must be applied to 2.2.4 (see samba-2.2.4-ldapbindnotuid0.patch).
+This patch is Q&D because the check is there because Samba store admin 
+credentials to establish the LDAP connection. The uid == 0 check was to 
+ensure that a normal user could not get write access to the LDAP backend.
+A more logical situation should be done for 2.2.5 by checking if the user
+is a member of the domain admin group (reported to Jerremy and Gerald 
+2002-05-28).
+
 Other built in groups are really cosmetic ones with Samba 2.2.x. We did not
 removed them because one of these days, we whish to use Samba 3.0 where 
 Windows Group Support should be operational.
index d5ca07826f4fc3d5bf2c816a0eb2ec131555be6f..f4c72751a75784c0a558d68ce0f8399914261085 100644 (file)
@@ -1,3 +1,5 @@
+# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/INSTALL,v $
+#
 ## How To Install SMBLDAP-TOOLS
 
 Quick & Dirty:
index 3e5eac427d790b4d8bd703100122018cd262edcc..783a3571a99edca52c1018c418bf0e138bd33e52 100644 (file)
@@ -1,5 +1,5 @@
 PACKAGE=smbldap-tools
-RELEASE=0.7
+RELEASE=0.8.2-1
 DESTDIR = $(PACKAGE)-$(RELEASE)
 
 dist:  distclean $(DESTDIR).tgz 
index 3b4bf2da0dd805aa089aa356ac29cc190e26c7c0..add0175c0cee0b8b2e8db652603f390d236bbcab 100644 (file)
@@ -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/
 
 
index 25cc30c68456c36fe85d0cfa45f0a05642d00723..71e66952997f93f45f2b5e1b2dd63470949b08b5 100644 (file)
@@ -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)
 
index 91cd2dad532b428ba4490801808a9293491df65c..e242d6e223f72d38c4e6f0aa12203f83e7d232e8 100755 (executable)
@@ -27,33 +27,104 @@ use FindBin;
 use FindBin qw($RealBin);
 use lib "$RealBin/";
 use smbldap_tools;
-
+use smbldap_conf;
 use Getopt::Std;
 my %Options;
 
-my $ok = getopts('og:?', \%Options);
+my $ok = getopts('ag:or:s:t:p?', \%Options);
 if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
-       print "Usage: $0 [-go?] groupname\n";
-       print "  -g     gid\n";
-       print "  -o     gid is not unique\n";
-       print "  -?     show this help message\n";
-       exit (1);
+  print "Usage: $0 [-agorst?] groupname\n";
+  print "  -a   add automatic group mapping entry\n";
+  print "  -g   gid\n";
+  print "  -o   gid is not unique\n";
+  print "  -r   group-rid\n";
+  print "  -s   group-sid\n";
+  print "  -t   group-type\n";
+  print "  -p   print the gidNumber to stdout\n";
+  print "  -?   show this help message\n";
+  exit (1);
 }
 
 my $_groupName = $ARGV[0];
 
 if (defined(get_group_dn($_groupName))) {
-    print "$0: group $_groupName exists\n";
-    exit (6);
+  warn "$0: group $_groupName exists\n";
+  exit (6);
 }
 
 my $_groupGidNumber = $Options{'g'};
+if (! defined ($_groupGidNumber = group_add($_groupName, $_groupGidNumber, $Options{'o'}))) {
+  warn "$0: error adding group $_groupName\n";
+  exit (6);
+}
+
+my $group_sid;
+my $tmp;
+if ($tmp= $Options{'s'}) {
+  if ($tmp =~ /^S-(?:\d+-)+\d+$/) {
+    $group_sid = $tmp;
+  } else {
+    warn "$0: illegal group-rid $tmp\n";
+    exit(7);
+  }
+} elsif ($Options{'r'} || $Options{'a'}) {
+  my $group_rid;
+  if ($tmp= $Options{'r'}) {
+    if ($tmp =~ /^\d+$/) {
+      $group_rid = $tmp;
+    } else {
+      warn "$0: illegal group-rid $tmp\n";
+      exit(7);
+    }
+  } else {
+    # algorithmic mapping
+    $group_rid = 2*$_groupGidNumber+1001;
+  }
+  $group_sid = $SID.'-'.$group_rid;
+}
 
-if (!group_add($_groupName, $_groupGidNumber, $Options{'o'})) {
-    print "$0: error adding group $_groupName\n";
-    exit (6);
+if ($Options{'r'} || $Options{'a'} || $Options{'s'}) {
+  # let's test if this SID already exist
+  my $test_exist_sid=does_sid_exist($group_sid,$groupsdn);
+  if ($test_exist_sid->count == 1) {
+       warn "Group SID already owned by\n";
+       # there should not exist more than one entry, but ...
+       foreach my $entry ($test_exist_sid->all_entries) {
+         my $dn= $entry->dn;
+         chomp($dn);
+         warn "$dn\n";
+       }
+       exit(7);
+  }
 }
 
+if ($group_sid) {
+  my $group_type;
+  my $tmp;
+  if ($tmp= $Options{'t'}) {
+    unless (defined($group_type = &group_type_by_name($tmp))) {
+      warn "$0: unknown group type $tmp\n";
+      exit(8);
+    }
+  } else {
+    $group_type = group_type_by_name('domain');
+  }
+  my $ldap_master=connect_ldap_master();
+  my $modify = $ldap_master->modify ( "cn=$_groupName,$groupsdn",
+                                                                         add => {
+                                                                                         'objectClass' => 'sambaGroupMapping',
+                                                                                         'sambaSID' => $group_sid,
+                                                                                         'sambaGroupType' => $group_type
+                                                                                        }
+                                                                       );
+  $modify->code && warn "failed to delete entry: ", $modify->error ;
+  # take down session
+  $ldap_master->unbind
+}
+
+if ($Options{'p'}) {
+  print STDOUT "$_groupGidNumber";
+}
 exit(0);
 
 ########################################
index 89d0d993acfb78d3612ef1fe84f2100648b70e8f..4f6839ebe5905ddd15b9f73301f2336adb1e19a7 100755 (executable)
@@ -30,23 +30,22 @@ use smbldap_tools;
 use smbldap_conf;
 
 #####################
-
 use Getopt::Std;
 my %Options;
 
 my $ok = getopts('?', \%Options);
 if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
-       print "Usage: $0 groupname\n";
-       print "  -?     show this help message\n";
-       exit (1);
+  print "Usage: $0 groupname\n";
+  print "  -?  show this help message\n";
+  exit (1);
 }
 
 my $_groupName = $ARGV[0];
 
 my $dn_line;
 if (!defined($dn_line = get_group_dn($_groupName))) {
-    print "$0: group $_groupName doesn't exist\n";
-    exit (6);
+  print "$0: group $_groupName doesn't exist\n";
+  exit (6);
 }
 
 my $dn = get_dn_from_line($dn_line);
@@ -56,7 +55,7 @@ group_del($dn);
 my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
 
 if ($nscd_status == 0) {
-   system "/etc/init.d/nscd restart > /dev/null 2>&1";
+  system "/etc/init.d/nscd restart > /dev/null 2>&1";
 }
 
 #if (defined($dn_line = get_group_dn($_groupName))) {
index f8971016027f84fc70b052b95295d8031599fca8..3f9741e0152f623a93af5f80c4989bd3f6e1f32e 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/perl -w
+
 #  This code was developped by IDEALX (http://IDEALX.org/) and
 #  contributors (their names can be found in the CONTRIBUTORS file).
 #
@@ -29,29 +30,33 @@ use lib "$RealBin/";
 use smbldap_tools;
 use smbldap_conf;
 
-
 #####################
 
 use Getopt::Std;
 my %Options;
 
-my $ok = getopts('og:n:m:x:?', \%Options);
+my $ok = getopts('ag:n:m:or:s:t:x:?', \%Options);
 if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
-       print "Usage: $0 [-g gid [-o]] [-n name] [-m members(,)] [-x members (,)] groupname\n";
-       print "  -g     new gid\n";
-       print "  -o     gid is not unique\n";
-       print "  -n     new group name\n";
-       print "  -m     add members (comma delimited)\n";
-       print "  -x     delete members (comma delimted)\n";
-       print "  -?     show this help message\n";
-       exit (1);
+  print "Usage: $0 [-a] [-g gid [-o]] [-n name] [-m members(,)] [-x members (,)] [-r rid] [-s sid] [-t type] groupname\n";
+  print "  -a   add automatic group mapping entry\n";
+  print "  -g   new gid\n";
+  print "  -o   gid is not unique\n";
+  print "  -n   new group name\n";
+  print "  -m   add members (comma delimited)\n";
+  print "  -r   group-rid\n";
+  print "  -s   group-sid\n";
+  print "  -t   group-type\n"; 
+  print "  -x   delete members (comma delimted)\n";
+  print "  -?   show this help message\n";
+  exit (1);
 }
 
 my $groupName = $ARGV[0];
+my $group_entry;
 
-if (!defined(get_group_dn($groupName))) {
-    print "$0: group $groupName doesn't exist\n";
-    exit (6);
+if (! ($group_entry = read_group_entry($groupName))) {
+  print "$0: group $groupName doesn't exist\n";
+  exit (6);
 }
 
 my $newname = $Options{'n'};
@@ -59,20 +64,24 @@ my $newname = $Options{'n'};
 my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
 
 if ($nscd_status == 0) {
-   system "/etc/init.d/nscd restart > /dev/null 2>&1";
+  system "/etc/init.d/nscd restart > /dev/null 2>&1";
 }
 
 my $gid = getgrnam($groupName);
+unless (defined ($gid)) {
+  print "$0: group $groupName not found!\n";
+  exit(6);
+}
 
 my $tmp;
 if (defined($tmp = $Options{'g'}) and $tmp =~ /\d+/) {
-    if (!defined($Options{'o'})) {
+  if (!defined($Options{'o'})) {
        if (defined(getgrgid($tmp))) {
-           print "$0: gid $tmp exists\n";
-           exit (6);
+         print "$0: gid $tmp exists\n";
+         exit (6);
        }
-    }
-    if (!($gid == $tmp)) {
+  }
+  if (!($gid == $tmp)) {
        my $ldap_master=connect_ldap_master();
        my $modify = $ldap_master->modify ( "cn=$groupName,$groupsdn",
                                                                                changes => [
@@ -82,7 +91,7 @@ if (defined($tmp = $Options{'g'}) and $tmp =~ /\d+/) {
        $modify->code && die "failed to modify entry: ", $modify->error ;
        # take down session
        $ldap_master->unbind
-    }
+  }
 }
 
 
@@ -101,17 +110,19 @@ if (defined($newname)) {
 
 # Add members
 if (defined($Options{'m'})) {
-       my $members = $Options{'m'};
-       my @members = split( /,/, $members );
-       my $member;
-       foreach $member ( @members ) {
+  my $members = $Options{'m'};
+  my @members = split( /,/, $members );
+  my $member;
+  foreach $member ( @members ) {
+       my $group_entry=read_group_entry($groupName);
+       $groupsdn=$group_entry->dn;
        if (is_unix_user($member)) {
-         if (is_group_member("cn=$groupName,$groupsdn",$member)) {
+         if (is_group_member($groupsdn,$member)) {
                print "User $member already in the group\n";
          } else {
                print "adding user $member to group $groupName\n";
                my $ldap_master=connect_ldap_master();
-               my $modify = $ldap_master->modify ( "cn=$groupName,$groupsdn",
+               my $modify = $ldap_master->modify ($groupsdn,
                                                                                        changes => [
                                                                                                                add => [memberUid => $member]
                                                                                                           ]
@@ -123,19 +134,21 @@ if (defined($Options{'m'})) {
        } else {
          print "User $member does not exist: create it first !\n";
        }
-       }
+  }
 }
 
 # Delete members
 if (defined($Options{'x'})) {
-        my $members = $Options{'x'};
-        my @members = split( /,/, $members );
-        my $member;
-        foreach $member ( @members ) {
-       if (is_group_member("cn=$groupName,$groupsdn",$member)) {
+  my $members = $Options{'x'};
+  my @members = split( /,/, $members );
+  my $member;
+  foreach $member ( @members ) {
+        my $group_entry=read_group_entry($groupName);
+        $groupsdn=$group_entry->dn;
+       if (is_group_member("$groupsdn",$member)) {
          print "deleting user $member from group $groupName\n";
          my $ldap_master=connect_ldap_master();
-         my $modify = $ldap_master->modify ( "cn=$groupName,$groupsdn",
+         my $modify = $ldap_master->modify ($groupsdn,
                                                                                  changes => [
                                                                                                          delete => [memberUid => $member]
                                                                                                         ]
@@ -146,13 +159,73 @@ if (defined($Options{'x'})) {
        } else {
          print "User $member is not in the group $groupName!\n";
        }
-        }
+  }
+}
+
+my $group_sid;
+if ($tmp= $Options{'s'}) {
+  if ($tmp =~ /^S-(?:\d+-)+\d+$/) {
+    $group_sid = $tmp;
+  } else {
+    print "$0: illegal group-rid $tmp\n";
+    exit(7);
+  }
+} elsif ($Options{'r'} || $Options{'a'}) {
+  my $group_rid;
+  if ($tmp= $Options{'r'}) {
+    if ($tmp =~ /^\d+$/) {
+      $group_rid = $tmp;
+    } else {
+      print "$0: illegal group-rid $tmp\n";
+      exit(7);
+    }
+  } else {
+    # algorithmic mapping
+    $group_rid = 2*$gid+1001;
+  }
+  $group_sid = $SID.'-'.$group_rid;
+}
+
+if ($group_sid) {
+  my @adds;
+  my @mods;
+  push(@mods, 'sambaSID' => $group_sid);
+
+  if ($tmp= $Options{'t'}) {
+    my $group_type;
+    if (defined($group_type = &group_type_by_name($tmp))) {
+      push(@mods, 'sambaGroupType' => $group_type);
+    } else {
+      print "$0: unknown group type $tmp\n";
+      exit(8);
+    }
+  } else {
+    if (! defined($group_entry->get_value('sambaGroupType'))) {
+      push(@mods, 'sambaGroupType' => group_type_by_name('domain'));
+    }
+  }
+
+  my @oc = $group_entry->get_value('objectClass');
+  unless (grep($_ =~ /^sambaGroupMapping$/i, @oc)) {
+    push (@adds, 'objectClass' => 'sambaGroupMapping');
+  }
+
+  my $ldap_master=connect_ldap_master();
+  my $modify = $ldap_master->modify ( "cn=$groupName,$groupsdn",
+                                                                         changes => [
+                                                                                                 'add' => [ @adds ],
+                                                                                                 'replace' => [ @mods ]
+                                                                                                ]
+                                                                       );
+  $modify->code && warn "failed to delete entry: ", $modify->error ;
+  # take down session
+  $ldap_master->unbind
 }
 
 $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
 
 if ($nscd_status == 0) {
-   system "/etc/init.d/nscd restart > /dev/null 2>&1";
+  system "/etc/init.d/nscd restart > /dev/null 2>&1";
 }
 
 exit (0);
@@ -161,19 +234,19 @@ exit (0);
 
 =head1 NAME
 
-       smbldap-groupmod.pl - Modify a group
+smbldap-groupmod.pl - Modify a group
 
 =head1 SYNOPSIS
 
-       smbldap-groupmod.pl [-g gid [-o]] [-n group_name ] group
+smbldap-groupmod.pl [-g gid [-o]] [-n group_name ] group
 
 =head1 DESCRIPTION
 
-       The smbldap-groupmod.pl command modifies the system account files to
-       reflect the changes that are specified on the command line.
-       The options which apply to the smbldap-groupmod command are
+The smbldap-groupmod.pl command modifies the system account files to
+  reflect the changes that are specified on the command line.
+  The options which apply to the smbldap-groupmod command are
 
-       -g gid The numerical value of the group's ID. This value must be
+  -g gid The numerical value of the group's ID. This value must be
               unique, unless the -o option is used. The value must be non-
               negative. Any files which the old group ID is the file
               group ID must have the file group ID changed manually.
index 18fe082e665835b0d2cfc62aa2316248ab1a16fc..a9d368763ee82c5278fb6d87ff87d01f4a01ba65 100755 (executable)
@@ -36,8 +36,8 @@ my %Options;
 my $ok = getopts('?', \%Options);
 
 if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
-       print "Usage: $0 [-?] group\n";
-       print "  -?     show this help message\n";
+  print "Usage: $0 [-?] group\n";
+  print "  -?  show this help message\n";
        exit (1);
 }
 
index 86f52cb53e1b753ac94aac051ff4be8e6637dc84..54e4d7f7e3f14768e2aec0ceedef42af52915233 100755 (executable)
@@ -39,14 +39,14 @@ use smbldap_conf;
 # Errors, debug and stats are output to stderr.
 
 sub modify_account
-{
-  my ($login, $basedn, $lmpwd, $ntpwd, $gecos, $homedir) = @_;
+  {
+       my ($login, $basedn, $lmpwd, $ntpwd, $gecos, $homedir) = @_;
        # bind to a directory with dn and password
        my $ldap_master=connect_ldap_master();
        my $modify = $ldap_master->modify ("uid=$login,$basedn",
                changes => [
-                       replace => [lmpassword => "$lmpwd"],
-                       replace => [ntpassword => "$ntpwd"],
+                       replace => [sambaLMPassword => "$lmpwd"],
+                       replace => [sambaNTpassword => "$ntpwd"],
                        replace => [gecos => "$gecos"],
                        replace => [sambaHomePath => "$homedir"]
                ]
@@ -54,7 +54,7 @@ sub modify_account
        $modify->code && die "failed to modify entry: ", $modify->error ;
        # take down the session
        $ldap_master->unbind;
-}
+  }
 
 #####################
 
@@ -64,15 +64,15 @@ my %Options;
 my $ok = getopts('awA:CUW:?h', \%Options);
 
 if ( (!$ok) || ($Options{'?'}) || ($Options{'h'}) ) {
-        print "Usage: $0 [-awAWCU?]\n";
-        print "  -a         process only people, ignore computers\n";
-        print "  -w         process only computers, ignore persons\n";
-        print "  -A <opts>  option string passed verbatim to smbldap-useradd for persons\n";
-        print "  -W <opts>  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 <opts>  option string passed verbatim to smbldap-useradd for persons\n";
+  print "  -W <opts>  option string passed verbatim to smbldap-useradd for computers\n";
+  print "  -C         if entry not found, don't create it and log it to stdout (default: create it)\n";
+  print "  -U         if entry found, don't update it and log it to stdout (default: update it)\n";
   print "  -?|-h      show this help message\n";
-        exit (1);
+  exit (1);
 }
 
 my %processed = ( 'user' => 0, 'machine' => 0);
@@ -90,7 +90,7 @@ while (<>) {
 
   my $entry_type = 'user';
 
-  if ($login =~ m/.*\$$/ ) { # computer
+  if ($login =~ m/.*\$$/ ) {   # computer
     $processed{'machine'}++;
     $entry_type = 'machine';
     if (defined($Options{'a'})) {
@@ -117,14 +117,14 @@ while (<>) {
   }
 
   # normalize homedir
-# uncomment to replace configured share with share from pwdump
-#  if ($homedir eq "") {
-    $homedir = $_userSmbHome;
-#  }
+  # uncomment to replace configured share with share from pwdump
+  #  if ($homedir eq "") {
+  $homedir = $_userSmbHome;
+  #  }
 
   # normalize gecos
   if (!($gecos eq "")) {
-    $gecos =~ tr/ÁÀÂÄáàâäÇçÉÈÊËÆéèêëæÍÌÏÎíìîÏÑñÓÒÔÖóòôöÚÙÜÛúùüûÝýÿ/AAAAaaaaCcEEEEEeeeeeIIIIiiiiNnOOOOooooUUUUuuuuYyy/;
+    $gecos =~ tr/ÁÀÂÄáàâäÇçÉÈÊËÆéèêëæÍÌÏÎíìîÏÑñÓÒÔÖóòôöÚÙÜÛúùüûÝýÿ/AAAAaaaaCcEEEEEeeeeeIIIIiiiiNnOOOOooooUUUUuuuuYyy/;
   } else {
     $gecos = $_userGecos;
   }
@@ -141,12 +141,12 @@ while (<>) {
         print STDERR "error adding $login, skipping\n";
         next;
       }
-       # lem modif... a retirer si pb
+         # lem modif... a retirer si pb
          if ($entry_type eq "user") {
        modify_account($login, $userbasedn, $lmpwd, $ntpwd, $gecos, $homedir);
-       }
+         }
 
-       $created{$entry_type}++;
+         $created{$entry_type}++;
     } else {                                   # uid doesn't exist and no create => log
       print "$_";
       $logged{$entry_type}++;
@@ -187,7 +187,7 @@ print STDERR "special users skipped: $specialskipped\n";
 
 =head1 NAME
 
-       smbldap-migrate.pl - Migrate NT accounts to LDAP
+smbldap-migrate.pl - Migrate NT accounts to LDAP
 
 =head1 SYNOPSIS
 
index c60be18caf8f80c03cd3803c8c4df7a48e6ba87a..a2b07bf817cf708c59988e852f95063e0a72c06b 100644 (file)
@@ -33,52 +33,50 @@ use smbldap_tools;
 use smbldap_conf;
 use Getopt::Std;
 
-
-
 sub process_rec_group
-{
+  {
     my ($group, $mb) = @_;
     my @members;
     
     if (!(@members = group_get_members($group))) {
-       return 0;
+         return 0;
     }
 
     foreach my $m (@members) {
-       if ( !($m =~ m/^\*/) ) {
+         if ( !($m =~ m/^\*/) ) {
            push @{$mb}, $m;
-       } else {
+         } else {
            my $gname = $m;
            $gname =~ s/^.//;
            if (!process_rec_group($gname, $mb)) {
-               print "recursive group not added : $gname\n";
+                 print "recursive group not added : $gname\n";
            }
-       }
+         }
     }
-}
+  }
 
 
 # given a group dn and a list of members, update the group
 sub modify_group
-{
+  {
     my ($group, $dn_line, @members, $recgroup) = @_;
     my $m;
     my @new_mb;
 
     foreach $m (@members) {
-       if ( ($m =~ m/^\*/) ) {
+         if ( ($m =~ m/^\*/) ) {
            my $gname = $m;
            $gname =~ s/^.//;
            if (!$recgroup) {
-               print "recursive group not added : $gname\n";
+                 print "recursive group not added : $gname\n";
            } else {
-               if (!process_rec_group($gname, \@new_mb)) {
+                 if (!process_rec_group($gname, \@new_mb)) {
                    print "recursive group not added : $gname\n";
-               }
+                 }
            }
-       } else {
+         } else {
            push @new_mb, $m;
-       }
+         }
     }
 
     # new_mb contains flat members from group dump
@@ -94,7 +92,7 @@ sub modify_group
     
     my $mbs;
     foreach $m (@new_mb) {
-           $mbs .= "memberUid: $m\n";
+         $mbs .= "memberUid: $m\n";
     }
 
     my $mods="$dn_line
@@ -105,16 +103,16 @@ $mbs
 
     #print "$mods\n";
     my $tmpldif =
-"$mods
+         "$mods
 ";
 
     die "$0: error while modifying group $group\n"
-       unless (do_ldapmodify($tmpldif) == 0);
+         unless (do_ldapmodify($tmpldif) == 0);
     undef $tmpldif;
-}
+  }
 
 sub display_group
-{
+  {
     my ($group, @members) = @_;
 
     print "Group name $group\n";
@@ -122,43 +120,43 @@ sub display_group
     my $m;
     my $i = 0;
     foreach $m (@members) {
-       print "$m ";
-       if ($i % 5 == 0) {
+         print "$m ";
+         if ($i % 5 == 0) {
            print "\n";
-       }
-       $i++;
+         }
+         $i++;
     }
-}
+  }
 
 sub process_group
-{
+  {
     my ($group, @members, $nocreate, $noupdate, $recgroup) = @_;
 
     my $dn_line;
     if (!defined($dn_line = get_group_dn($group))) {
-       # group not found, create it ?
-       if (!$nocreate) {
+         # group not found, create it ?
+         if (!$nocreate) {
            system "/usr/local/sbin/smbldap-groupadd.pl \"$group\"; sleep 5";
            if (!defined($dn_line = get_group_dn($group))) {
-               return 1;
+                 return 1;
            }
            modify_group($group, $dn_line, @members, $recgroup);
-       } else {
+         } else {
            # don't create
            print "not created:\n";
            display_group($group, @members);
-       }
+         }
     } else {
-       # group found, update it ?
-       if (!$noupdate) {
+         # group found, update it ?
+         if (!$noupdate) {
            modify_group($group, $dn_line, @members, $recgroup);
-       } else {
+         } else {
            # don't update
            print "not updated:\n";
            display_group($group, @members);    
-       }
+         }
     }
-}
+  }
 
 ###################################################
 
@@ -166,11 +164,11 @@ my %Options;
 
 my $ok = getopts('CUr?', \%Options);
 if ( (!$ok) || ($Options{'?'}) ) {
-    print "Usage: $0 [-CUr?] < group_dump\n";
-    print "  -C            don't create group if it doesn't exist\n";
-    print "  -U            don't update group if it exists\n";
-    print "  -r            recursively process groups\n";
-    exit(1);
+  print "Usage: $0 [-CUr?] < group_dump\n";
+  print "  -C      don't create group if it doesn't exist\n";
+  print "  -U      don't update group if it exists\n";
+  print "  -r      recursively process groups\n";
+  exit(1);
 }
 
 my $group_name;
@@ -184,13 +182,13 @@ while (<>) {
   next if ( $line =~ m/^\s*$/ );
 
   if ($group_name eq "") {
-      if ( $line =~ m/^Group name\s+(.+).$/ ) {
+       if ( $line =~ m/^Group name\s+(.+).$/ ) {
          $group_name = $1;
          next;
-      }
+       }
   }
   if ($group_desc eq "") {
-      if ( $line =~ m/^Comment\s+(.*)$/ ) {
+       if ( $line =~ m/^Comment\s+(.*)$/ ) {
          $group_desc = $1;
          next;
       }
index 7845e5548e23e0e5bcb4c3f7a52381284904d838..afbc87a058d1603d548b0aef8011d300ed689c23 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/perl -w
 
 # LDAP to unix password sync script for samba
-#
+
 #  This code was developped by IDEALX (http://IDEALX.org/) and
 #  contributors (their names can be found in the CONTRIBUTORS file).
 #
@@ -23,7 +23,7 @@
 #  USA.
 
 #  Purpose :
-#       . ldap-unix passwd sync for SAMBA-2.2.2 + LDAP
+#       . ldap-unix passwd sync for SAMBA>2.2.2 + LDAP
 #       . may also replace /bin/passwd
 
 use strict;
@@ -40,29 +40,29 @@ my $ret;
 my $arg;
 
 foreach $arg (@ARGV) {
-       if ($< != 0) {
-               die "Only root can specify parameters\n";
-       } else {
-               if ( ($arg eq '-?') || ($arg eq '--help') ) {
-                       print "Usage: $0 [username]\n";
-                       print "  -?, --help                     show this help message\n";
-                       exit (6);
-               } elsif (substr($arg,0) ne '-')  {
-                       $user = $arg;
-               }
-               $oldpass = 1;
+  if ($< != 0) {
+       die "Only root can specify parameters\n";
+  } else {
+       if ( ($arg eq '-?') || ($arg eq '--help') ) {
+         print "Usage: $0 [username]\n";
+         print "  -?, --help                   show this help message\n";
+         exit (6);
+       } elsif (substr($arg,0) ne '-') {
+         $user = $arg;
        }
+       $oldpass = 1;
+  }
 }
 
 if (!defined($user)) {
-       $user=$ENV{"USER"};
+  $user=$ENV{"USER"};
 }
 
 # test existence of user in LDAP
 my $dn_line;
 if (!defined($dn_line = get_user_dn($user))) {
-    print "$0: user $user doesn't exist\n";
-    exit (10);
+  print "$0: user $user doesn't exist\n";
+  exit (10);
 }
 
 my $dn = get_dn_from_line($dn_line);
@@ -73,17 +73,17 @@ print "Changing password for $user\n";
 
 # non-root user
 if (!defined($oldpass)) {
-    # prompt for current password
-       system "stty -echo";
-       print "(current) UNIX password: ";
-       chomp($oldpass=<STDIN>);
-       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=<STDIN>);
+  print "\n";
+  system "stty echo";
+
+  if (!is_user_valid($user, $dn, $oldpass)) {
+       print "Authentication failure\n";
+       exit (10);
+  }
 }
 
 # prompt for new password
@@ -104,8 +104,8 @@ print "\n";
 system "stty echo";
 
 if ($pass ne $pass2) {
-    print "New passwords don't match!\n";
-    exit (10);
+  print "New passwords don't match!\n";
+  exit (10);
 }
 
 # First, connecting to the directory
@@ -113,59 +113,64 @@ my $ldap_master=connect_ldap_master();
 
 # only modify smb passwords if smb user
 if ($samba == 1) {
-    if (!$with_smbpasswd) {
-# generate LanManager and NT clear text passwords
+  if (!$with_smbpasswd) {
+       # generate LanManager and NT clear text passwords
        if ($mk_ntpasswd eq '') {
-           print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n";
-           exit(1);
+         print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n";
+         exit(1);
        }
        my $ntpwd = `$mk_ntpasswd '$pass'`;
-        chomp(my $sambaLMPassword = substr($ntpwd, 0, index($ntpwd, ':')));
-        chomp(my $sambaNTPassword = substr($ntpwd, index($ntpwd, ':')+1));
+       chomp(my $sambaLMPassword = substr($ntpwd, 0, index($ntpwd, ':')));
+       chomp(my $sambaNTPassword = substr($ntpwd, index($ntpwd, ':')+1));
        # the sambaPwdLastSet must be updating
        my $date=time;
+       my @mods;
+       push(@mods, 'sambaLMPassword' => $sambaLMPassword);
+       push(@mods, 'sambaNTPassword' => $sambaNTPassword);
+       push(@mods, 'sambaPwdLastSet' => $date);
+       if (defined $_defaultMaxPasswordAge) {
+         my $new_sambaPwdMustChange=$date+$_defaultMaxPasswordAge*24*60*60;
+         push(@mods, 'sambaPwdMustChange' => $new_sambaPwdMustChange);
+         push(@mods, 'sambaAcctFlags' => '[U]');
+       }
        # Let's change nt/lm passwords
        my $modify = $ldap_master->modify ( "$dn",
-                                                                               changes => [
-                                                                                                       replace => [sambaLMPassword => "$sambaLMPassword"],
-                                                                                                       replace => [sambaNTPassword => "$sambaNTPassword"],
-                                                                                                       replace => [sambaPwdLastSet => "$date"]
-                                                                                                  ]
+                                                                               'replace' => { @mods }
                                                                          );
        $modify->code && warn "failed to modify entry: ", $modify->error ;
 
   } else {
        if ($< != 0) {
-           my $FILE="|$smbpasswd -s >/dev/null";
-           open (FILE, $FILE) || die "$!\n";
-           print FILE <<EOF;
+         my $FILE="|$smbpasswd -s >/dev/null";
+         open (FILE, $FILE) || die "$!\n";
+         print FILE <<EOF;
 '$oldpass'
 '$pass'
 '$pass'
 EOF
-    ;
-           close FILE;
+         ;
+         close FILE;
        } else {
-           my $FILE="|$smbpasswd $user -s >/dev/null";
-           open (FILE, $FILE) || die "$!\n";
-           print FILE <<EOF;
+         my $FILE="|$smbpasswd $user -s >/dev/null";
+         open (FILE, $FILE) || die "$!\n";
+         print FILE <<EOF;
 '$pass'
 '$pass'
 EOF
-    ;
-           close FILE;
+         ;
+         close FILE;
        }
-    }
+  }
 }
 
 # change unix password
 my $hash_password = `slappasswd -h {$hash_encrypt} -s '$pass'`;
 chomp($hash_password);
 my $modify = $ldap_master->modify ( "$dn",
-       changes => [
-                       replace => [userPassword => "$hash_password"]
-                  ]
-         );
+                                                                       changes => [
+                                                                                               replace => [userPassword => "$hash_password"]
+                                                                                          ]
+                                                                 );
 $modify->code && warn "Unable to change password : ", $modify->error ;
 
 # take down session
@@ -186,7 +191,7 @@ smbldap-passwd.pl - change user password
 
 =head1 DESCRIPTION
 
-       smbldap-passwd.pl changes passwords for user accounts. A normal user
+smbldap-passwd.pl changes passwords for user accounts. A normal user
        may only change the password for their own account, the super user may
        change the password for any account.
 
index ce497672a96c55e4fbd0a08be27e9f301516e3df..b691a84850089358530c01a3e1baa87dbf8bd152 100755 (executable)
@@ -2,6 +2,7 @@
 
 # Populate a LDAP base for Samba-LDAP usage
 #
+
 #  This code was developped by IDEALX (http://IDEALX.org/) and
 #  contributors (their names can be found in the CONTRIBUTORS file).
 #
@@ -39,66 +40,66 @@ use vars qw(%oc);
 
 # objectclass of the suffix
 %oc = (
-    "ou" => "organizationalUnit",
-    "o" => "organization",
-    "dc" => "dcObject",
-);
+          "ou" => "organizationalUnit",
+          "o" => "organization",
+          "dc" => "dcObject",
+         );
 
 
 my %Options;
 
 my $ok = getopts('a:b:?', \%Options);
 if ( (!$ok) || ($Options{'?'}) ) {
-       print "Usage: $0 [-ab?] [ldif]\n";
-       print "  -a     administrator login name (default: Administrator)\n";
-       print "  -b     guest login name (default: nobody)\n";
-       print "  -?     show this help message\n";
-       print "  ldif   file to add to ldap (default: suffix, Groups,";
-       print " Users, Computers and builtin users )\n";
-       exit (1);
+  print "Usage: $0 [-ab?] [ldif]\n";
+  print "  -a  administrator login name (default: Administrator)\n";
+  print "  -b  guest login name (default: nobody)\n";
+  print "  -?  show this help message\n";
+  print "  ldif        file to add to ldap (default: suffix, Groups,";
+  print " Users, Computers and builtin users )\n";
+  exit (1);
 }
 
 my $_ldifName;
 my $tmp_ldif_file="/tmp/$$.ldif";
 
 if (@ARGV >= 1) {
-    $_ldifName = $ARGV[0];
+  $_ldifName = $ARGV[0];
 }
 
 my $adminName = $Options{'a'};
 if (!defined($adminName)) {
-    $adminName = "Administrator";
+  $adminName = "Administrator";
 }
 
 my $guestName = $Options{'b'};
 if (!defined($guestName)) {
-    $guestName = "nobody";
+  $guestName = "nobody";
 }
 
 if (!defined($_ldifName)) {
-    my $attr;
-    my $val;
-    my $objcl;
+  my $attr;
+  my $val;
+  my $objcl;
 
   print "Using builtin directory structure\n";
-    if ($suffix =~ m/([^=]+)=([^,]+)/) {
+  if ($suffix =~ m/([^=]+)=([^,]+)/) {
        $attr = $1;
        $val = $2;
        $objcl = $oc{$attr} if (exists $oc{$attr});
        if (!defined($objcl)) {
-           $objcl = "myhardcodedobjectclass";
+         $objcl = "myhardcodedobjectclass";
        }
-    } else {
+  } else {
        die "can't extract first attr and value from suffix $suffix";
-    }
-    #print "$attr=$val\n";
-    my ($organisation,$ext) = ($suffix =~ m/dc=(\w+),dc=(\w+)$/);
+  }
+  #print "$attr=$val\n";
+  my ($organisation,$ext) = ($suffix =~ m/dc=(.*),dc=(.*)$/);
 
-    #my $FILE="|cat";
+  #my $FILE="|cat";
   my $FILE=$tmp_ldif_file;
   open (FILE, ">$FILE") || die "Can't open file $FILE: $!\n";
 
-    print FILE <<EOF;
+  print FILE <<EOF;
 dn: $suffix
 objectClass: $objcl
 objectclass: organization
@@ -121,7 +122,7 @@ dn: uid=$adminName,$usersdn
 cn: $adminName
 sn: $adminName
 objectClass: inetOrgPerson
-objectClass: sambaSAMAccount
+objectClass: sambaSamAccount
 objectClass: posixAccount
 gidNumber: 512
 uid: $adminName
@@ -148,7 +149,7 @@ dn: uid=$guestName,$usersdn
 cn: $guestName
 sn: $guestName
 objectClass: inetOrgPerson
-objectClass: sambaSAMAccount
+objectClass: sambaSamAccount
 objectClass: posixAccount
 gidNumber: 514
 uid: $guestName
@@ -172,87 +173,138 @@ loginShell: /bin/false
 
 dn: cn=Domain Admins,$groupsdn
 objectClass: posixGroup
+objectClass: sambaGroupMapping
 gidNumber: 512
 cn: Domain Admins
 memberUid: $adminName
-description: Netbios Domain Administrators (need smb.conf configuration)
+description: Netbios Domain Administrators
+sambaSID: $SID-512
+sambaGroupType: 2
+displayName: Domain Admins
 
 dn: cn=Domain Users,$groupsdn
 objectClass: posixGroup
+objectClass: sambaGroupMapping
 gidNumber: 513
 cn: Domain Users
-description: Netbios Domain Users (not implemented yet)
+description: Netbios Domain Users
+sambaSID: $SID-513
+sambaGroupType: 2
+displayName: Domain Users
 
 dn: cn=Domain Guests,$groupsdn
 objectClass: posixGroup
+objectClass: sambaGroupMapping
 gidNumber: 514
 cn: Domain Guests
-description: Netbios Domain Guests Users (not implemented yet)
+description: Netbios Domain Guests Users
+sambaSID: $SID-514
+sambaGroupType: 2
+displayName: Domain Guests
 
 dn: cn=Administrators,$groupsdn
 objectClass: posixGroup
+objectClass: sambaGroupMapping
 gidNumber: 544
 cn: Administrators
-description: Netbios Domain Members can fully administer the computer/sambaDomainName (not implemented yet)
+description: Netbios Domain Members can fully administer the computer/sambaDomainName
+sambaSID: $SID-544
+sambaGroupType: 2
+displayName: Administrators
 
 dn: cn=Users,$groupsdn
 objectClass: posixGroup
+objectClass: sambaGroupMapping
 gidNumber: 545
 cn: Users
-description: Netbios Domain Ordinary users (not implemented yet)
+description: Netbios Domain Ordinary users
+sambaSID: $SID-545
+sambaGroupType: 2
+displayName: users
 
 dn: cn=Guests,$groupsdn
 objectClass: posixGroup
+objectClass: sambaGroupMapping
 gidNumber: 546
 cn: Guests
 memberUid: $guestName
-description: Netbios Domain Users granted guest access to the computer/sambaDomainName (not implemented yet)
-
+description: Netbios Domain Users granted guest access to the computer/sambaDomainName
+sambaSID: $SID-546
+sambaGroupType: 2
+displayName: Guests
 
 dn: cn=Power Users,$groupsdn
 objectClass: posixGroup
+objectClass: sambaGroupMapping
 gidNumber: 547
 cn: Power Users
-description: Netbios Domain Members can share directories and printers (not implemented yet)
+description: Netbios Domain Members can share directories and printers
+sambaSID: $SID-547
+sambaGroupType: 2
+displayName: Power Users
 
 dn: cn=Account Operators,$groupsdn
 objectClass: posixGroup
+objectClass: sambaGroupMapping
 gidNumber: 548
 cn: Account Operators
-description: Netbios Domain Users to manipulate users accounts (not implemented yet)
+description: Netbios Domain Users to manipulate users accounts
+sambaSID: $SID-548
+sambaGroupType: 2
+displayName: Account Operators
 
 dn: cn=Server Operators,$groupsdn
 objectClass: posixGroup
+objectClass: sambaGroupMapping
 gidNumber: 549
 cn: Server Operators
-description: Netbios Domain Server Operators (need smb.conf configuration)
+description: Netbios Domain Server Operators
+sambaSID: $SID-549
+sambaGroupType: 2
+displayName: Server Operators
 
 dn: cn=Print Operators,$groupsdn
 objectClass: posixGroup
+objectClass: sambaGroupMapping
 gidNumber: 550
 cn: Print Operators
-description: Netbios Domain Print Operators (need smb.conf configuration)
+description: Netbios Domain Print Operators
+sambaSID: $SID-550
+sambaGroupType: 2
+displayName: Print Operators
 
 dn: cn=Backup Operators,$groupsdn
 objectClass: posixGroup
+objectClass: sambaGroupMapping
 gidNumber: 551
 cn: Backup Operators
-description: Netbios Domain Members can bypass file security to back up files (not implemented yet)
+description: Netbios Domain Members can bypass file security to back up files
+sambaSID: $SID-551
+sambaGroupType: 2
+displayName: Backup Operators
 
 dn: cn=Replicator,$groupsdn
 objectClass: posixGroup
+objectClass: sambaGroupMapping
 gidNumber: 552
 cn: Replicator
-description: Netbios Domain Supports file replication in a sambaDomainName (not implemented yet)
+description: Netbios Domain Supports file replication in a sambaDomainName
+sambaSID: $SID-552
+sambaGroupType: 2
+displayName: Replicator
 
 dn: cn=Domain Computers,$groupsdn
 objectClass: posixGroup
+objectClass: sambaGroupMapping
 gidNumber: 553
 cn: Domain Computers
 description: Netbios Domain Computers accounts
+sambaSID: $SID-553
+sambaGroupType: 2
+displayName: Domain Computers
 
 EOF
-    close FILE;
+  close FILE;
 } else {
   $tmp_ldif_file=$_ldifName;
 }
@@ -280,11 +332,11 @@ exit(0);
 
 =head1 NAME
 
-       smbldap-populate.pl - Populate your LDAP database
+smbldap-populate.pl - Populate your LDAP database
 
 =head1 SYNOPSIS
 
-       smbldap-populate.pl [ldif-file]
+  smbldap-populate.pl [ldif-file]
 
 =head1 DESCRIPTION
 
index 7924ae20e27ae5739ca03bf495ac2ea912b38699..0275c8096fc6356d4e9a8d4b07577c8a5bc09841 100755 (executable)
@@ -1,5 +1,6 @@
-%define version        0.8
-%define release        1
+# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/smbldap-tools.spec,v $
+%define version        0.8.2
+%define release 1
 %define name   smbldap-tools
 %define realname  smbldap-tools
 
@@ -35,6 +36,7 @@ Source18:     smbldap-populate.pl
 Source19:      smbldap-migrate-accounts.pl
 Source20:      smbldap-migrate-groups.pl
 Source21:      INFRA
+Source22:      smb.conf
 BuildRoot:     /%{_tmppath}/%{name}
 Prefix: /usr/local
 BuildRequires: perl >= 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 <jerome.tournier@idealx.com> 0.8-1
-- support for Samba3.0
+* Fri Nov 28 2003 Jerome Tournier <jerome.tournier@idealx.com> 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 <gmacinenti@IDEALX.com> 0.7-2
-- top and account objectclasses replaced by InetOrgPerson
-
-* Sat Jun  1 2002 Olivier Lemaire <olem@IDEALX.com> 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 <brad@langhorst.com> 0.6-2
-- changed requires samba-common to samba
-- replaced /usr/local with %{prefix} to allow relocation
-
-* Tue Feb 5 2002 David Le Corfec <dlc@IDEALX.com> 0.6-1
-- v0.6
-
-* Mon Feb 4 2002 David Le Corfec <dlc@IDEALX.com> 0.5-1
-- v0.5
-
-* Mon Jan 14 2002 David Le Corfec <dlc@IDEALX.com> 0.3-4
-- internal changes
-- should upgrade smoothly from now on
-
-* Mon Jan 14 2002 David Le Corfec <dlc@IDEALX.com> 0.2-1
-- added migration scripts
-
-* Fri Dec 28 2001 David Le Corfec <dlc@IDEALX.com> 0.1-5
-- numeric group for chmod
-
-* Thu Dec 27 2001 David Le Corfec <dlc@IDEALX.com> 0.1-4
-- misc bugfixes
-
-* Mon Dec 18 2001 David Le Corfec <dlc@IDEALX.com> 0.1-3
-- changed files attrs for domain admins to add users
-- added smbldap-populate.pl
-
-* Fri Dec 14 2001 David Le Corfec <dlc@IDEALX.com>
-- added mkntpwd
-
-* Wed Dec 12 2001 Olivier Lemaire <olivier.lemaire@IDEALX.com>
-- Spec file was generated, and tested atomically.
index a84d9f68b217eeca5c978f6dcd54c7a26ebec780..918bd4a4f66f545c3cb63782b9cc0e01412bf211 100755 (executable)
@@ -35,102 +35,92 @@ use smbldap_conf;
 use Getopt::Std;
 my %Options;
 
-my $ok = getopts('axnmwPG:u:g:d:s:c:k:A:B:C:D:E:F:H:N:S:?', \%Options);
+my $ok = getopts('anmwPG:u:g:d:s:c:k:A:B:C:D:E:F:H:N:S:?', \%Options);
 
 if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
-       print "Usage: $0 [-awmugdsckGPABCDEFH?] username\n";
-       print "  -a     is a Windows User (otherwise, Posix stuff only)\n";
-       print "  -w     is a Windows Workstation (otherwise, Posix stuff only)\n";
-       print "  -x     creates rid and primaryGroupID in hex instead of decimal\n";
-       print "  -u     uid\n";
-       print "  -g     gid\n";
-       print "  -G     supplementary comma-separated groups\n";
-       print "  -n     do not create a group\n";
-       print "  -d     home\n";
-       print "  -s     shell\n";
-       print "  -c     gecos\n";
-       print "  -m     creates home directory and copies /etc/skel\n";
-       print "  -k     skeleton dir (with -m)\n";
-       print "  -P     ends by invoking smbldap-passwd.pl\n";
-       print "  -A     can change password ? 0 if no, 1 if yes\n";
-       print "  -B     must change password ? 0 if no, 1 if yes\n";
-       print "  -C     sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')\n";
-       print "  -D     sambaHomeDrive (letter associated with home share, like 'H:')\n";
-       print "  -E     sambaLogonScript (DOS script to execute on login)\n";
-       print "  -F     sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n";
-       print "  -H     sambaAcctFlags (samba account control bits like '[NDHTUMWSLKI]')\n";
-  print "  -N   canonical name\n";
-  print "  -S   surname\n";
-       print "  -?     show this help message\n";
-       exit (1);
+  print "Usage: $0 [-awmugdsckGPABCDEFH?] username\n";
+  print "  -a  is a Windows User (otherwise, Posix stuff only)\n";
+  print "  -w  is a Windows Workstation (otherwise, Posix stuff only)\n";
+  print "  -u  uid\n";
+  print "  -g  gid\n";
+  print "  -G  supplementary comma-separated groups\n";
+  print "  -n  do not create a group\n";
+  print "  -d  home\n";
+  print "  -s  shell\n";
+  print "  -c  gecos\n";
+  print "  -m  creates home directory and copies /etc/skel\n";
+  print "  -k  skeleton dir (with -m)\n";
+  print "  -P  ends by invoking smbldap-passwd.pl\n";
+  print "  -A  can change password ? 0 if no, 1 if yes\n";
+  print "  -B  must change password ? 0 if no, 1 if yes\n";
+  print "  -C  sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')\n";
+  print "  -D  sambaHomeDrive (letter associated with home share, like 'H:')\n";
+  print "  -E  sambaLogonScript (DOS script to execute on login)\n";
+  print "  -F  sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n";
+  print "  -H  sambaAcctFlags (samba account control bits like '[NDHTUMWSLKI]')\n";
+  print "  -N  canonical name\n";
+  print "  -S  surname\n";
+  print "  -?  show this help message\n";
+  exit (1);
 }
 
+
 # cause problems when dealing with getpwuid because of the
 # negative ttl and ldap modification
 my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
 
 if ($nscd_status == 0) {
-   system "/etc/init.d/nscd stop > /dev/null 2>&1";
+  system "/etc/init.d/nscd stop > /dev/null 2>&1";
 }
 
+
 # Read options
 my $userUidNumber = $Options{'u'};
 if (!defined($userUidNumber)) { 
-       # find first unused uid starting from $UID_START
-       while (defined(getpwuid($UID_START))) {
-               $UID_START++;
-       }
-       $userUidNumber = $UID_START;
+  # find first unused uid starting from $UID_START
+  while (defined(getpwuid($UID_START))) {
+       $UID_START++;
+  }
+  $userUidNumber = $UID_START;
 } elsif (getpwuid($userUidNumber)) {
   die "Uid already exists.\n";
 }
 
 if ($nscd_status == 0) {
-   system "/etc/init.d/nscd start > /dev/null 2>&1";
+  system "/etc/init.d/nscd start > /dev/null 2>&1";
 }
 
 
-# as rid we use 2 * uid + 1000
-my $userRid = 2 * $userUidNumber + 1000;
-if (defined($Options{'x'})) {
-    $userRid= sprint("%x", $userRid);
-}
-
 my $createGroup = 0;
 my $userGidNumber = $Options{'g'};
 # gid not specified ? 
 if (!defined($userGidNumber)) {
-    # windows machine => $_defaultComputerGid
-    if (defined($Options{'w'})) {
+  # windows machine => $_defaultComputerGid
+  if (defined($Options{'w'})) {
        $userGidNumber = $_defaultComputerGid;
-#    } elsif (!defined($Options{'n'})) {
+       #    } elsif (!defined($Options{'n'})) {
        # create new group (redhat style)
        # find first unused gid starting from $GID_START
-#      while (defined(getgrgid($GID_START))) {
-#              $GID_START++;
-#      }
-#      $userGidNumber = $GID_START;
+       #       while (defined(getgrgid($GID_START))) {
+       #               $GID_START++;
+       #       }
+       #       $userGidNumber = $GID_START;
 
-#      $createGroup = 1;
+       #       $createGroup = 1;
 
-    } else {
+  } else {
        # user will have gid = $_defaultUserGid
        $userGidNumber = $_defaultUserGid;
-    }
+  }
 } else {
-    my $gid;
-    if (($gid = parse_group($userGidNumber)) < 0) {
+  my $gid;
+  if (($gid = parse_group($userGidNumber)) < 0) {
        print "$0: unknown group $userGidNumber\n";
        exit (6);
-    }
-    $userGidNumber = $gid;
+  }
+  $userGidNumber = $gid;
 }
 
-# as grouprid we use 2 * gid + 1001
-my $userGroupRid = 2 * $userGidNumber + 1001;
-if (defined($Options{'x'})) {
-    $userGroupRid = sprint("%x", $userGroupRid);
-}
 # Read only first @ARGV
 my $userName = $ARGV[0];
 
@@ -145,18 +135,49 @@ if ($userName =~ /^([\w -]+\$?)$/) {
 # user must not exist in LDAP (should it be nss-wide ?)
 my ($rc, $dn) = get_user_dn2($userName);
 if ($rc and defined($dn)) {
-    print "$0: user $userName exists\n";
-    exit (9);
+  print "$0: user $userName exists\n";
+  exit (9);
 } elsif (!$rc) {
-    print "$0: error in get_user_dn2\n";
-    exit(10);
+  print "$0: error in get_user_dn2\n";
+  exit(10);
+}
+
+my $group_entry;
+my $userGroupSID;
+my $userRid;
+if ($Options{'a'}) {
+       # as grouprid we use the value of the sambaSID attribute for
+       # group of gidNumber=$userGidNumber
+       $group_entry = read_group_entry_gid($userGidNumber);
+       $userGroupSID = $group_entry->get_value('sambaSID');
+       unless ($userGroupSID) {
+         print "$0: unknown group SID not set for unix group $userGidNumber\n";
+         print "check if your unix group is mapped to an NT group\n";
+         exit (7);
+       }
+
+       # as rid we use 2 * uid + 1000
+       $userRid = 2 * $userUidNumber + 1000;
+        # let's test if this SID already exist
+       my $user_sid="$SID-$userRid";
+        my $test_exist_sid=does_sid_exist($user_sid,$usersdn);
+        if ($test_exist_sid->count == 1) {
+                print "User SID already owned by\n";
+                # there should not exist more than one entry, but ...
+                foreach my $entry ($test_exist_sid->all_entries) {
+                        my $dn= $entry->dn;
+                        chomp($dn);
+                        print "$dn\n";
+                }
+                exit(7);
+        }
 }
 
 my $userHomeDirectory;
 my ($userCN, $userSN);
 my $tmp;
 if (!defined($userHomeDirectory = $Options{'d'})) {
-    $userHomeDirectory = $_userHomePrefix."/".$userName;
+  $userHomeDirectory = $_userHomePrefix."/".$userName;
 }
 $_userLoginShell = $tmp if (defined($tmp = $Options{'s'}));
 $_userGecos = $tmp if (defined($tmp = $Options{'c'}));
@@ -174,26 +195,26 @@ my $ldap_master=connect_ldap_master();
 # MACHINE ACCOUNT
 if (defined($tmp = $Options{'w'})) {
    
-    # add a trailing dollar if missing
-    if ($userName =~ /[^\$]$/s) {
+  # add a trailing dollar if missing
+  if ($userName =~ /[^\$]$/s) {
        $userName .= "\$";
-    }
+  }
 
-    #print "About to create machine $userName:\n";
+  #print "About to create machine $userName:\n";
 
-    if (!add_posix_machine ($userName, $userUidNumber, $userGidNumber)) {
+  if (!add_posix_machine ($userName, $userUidNumber, $userGidNumber)) {
        die "$0: error while adding posix account\n";
-    }
+  }
 
-    if (!$with_smbpasswd) {
+  if (!$with_smbpasswd) {
        # (jtournier)
-       # Objectclass sambaSAMAccount is now added directly by samba when joigning the domain (for samba3)
+       # Objectclass sambaSamAccount is now added directly by samba when joigning the domain (for samba3)
        #if (!add_samba_machine_mkntpwd($userName, $userUidNumber)) {
        #  die "$0: error while adding samba account\n";
        #}
-    } else {
+  } else {
        if (!add_samba_machine($userName)) {
-           die "$0: error while adding samba account\n";
+         die "$0: error while adding samba account\n";
        }
        my $modify = $ldap_master->modify ( "$dn",
                                                                                changes => [
@@ -201,9 +222,9 @@ if (defined($tmp = $Options{'w'})) {
                                                                                                   ]
                                                                          );
        $modify->code && warn "failed to modify entry: ", $modify->error ;
-    }
+  }
 
-    exit 0;
+  exit 0;
 }
 
 # USER ACCOUNT
@@ -237,56 +258,62 @@ group_add_user($userGidNumber, $userName);
 my $grouplist;
 # adds to supplementary groups
 if (defined($grouplist = $Options{'G'})) {
-    add_grouplist_user($grouplist, $userName);
+  add_grouplist_user($grouplist, $userName);
 }
 
 # If user was created successfully then we should create his/her home dir
 if (defined($tmp = $Options{'m'})) {
-   unless ( $userName =~ /\$$/ ) {
+  unless ( $userName =~ /\$$/ ) {
     if ( !(-e $userHomeDirectory) ) {
-       system "mkdir $userHomeDirectory 2>/dev/null";
-       system "cp -a $_skeletonDir/.[a-z,A-Z]* $_skeletonDir/* $userHomeDirectory 2>/dev/null";
-       system "chown -R $userUidNumber:$userGidNumber $userHomeDirectory 2>/dev/null";
-       system "chmod 700 $userHomeDirectory 2>/dev/null"; 
+         system "mkdir $userHomeDirectory 2>/dev/null";
+         system "cp -a $_skeletonDir/.[a-z,A-Z]* $_skeletonDir/* $userHomeDirectory 2>/dev/null";
+         system "chown -R $userUidNumber:$userGidNumber $userHomeDirectory 2>/dev/null";
+         system "chmod 700 $userHomeDirectory 2>/dev/null"; 
     }
-   }
+  }
 }
 
 
 # Add Samba user infos
 if (defined($Options{'a'})) {
-    if (!$with_smbpasswd) {
+  if (!$with_smbpasswd) {
 
        my $winmagic = 2147483647;
        my $valpwdcanchange = 0;
        my $valpwdmustchange = $winmagic;
+       my $valpwdlastset = 0;
        my $valacctflags = "[UX]";
 
        if (defined($tmp = $Options{'A'})) {
-           if ($tmp != 0) {
+         if ($tmp != 0) {
                $valpwdcanchange = "0";
-           } else {
+         } else {
                $valpwdcanchange = "$winmagic";
-           }
+         }
        }
 
        if (defined($tmp = $Options{'B'})) {
-           if ($tmp != 0) {
+         if ($tmp != 0) {
                $valpwdmustchange = "0";
-           } else {
+               # To force a user to change his password:
+               # . the attribut sambaPwdLastSet must be != 0
+               # . the attribut sambaAcctFlags must not match the 'X' flag
+               $valpwdlastset=$winmagic;
+               $valacctflags = "[U]";
+         } else {
                $valpwdmustchange = "$winmagic";
-           }
+         }
        }
 
        if (defined($tmp = $Options{'H'})) {
-           $valacctflags = "$tmp";
+         $valacctflags = "$tmp";
        }
 
 
        my $modify = $ldap_master->modify ( "uid=$userName,$usersdn",
                                                                                changes => [
-                                                                                                       add => [objectClass => 'sambaSAMAccount'],
-                                                                                                       add => [sambaPwdLastSet => '0'],
+                                                                                                       add => [objectClass => 'sambaSamAccount'],
+                                                                                                       add => [sambaPwdLastSet => "$valpwdlastset"],
                                                                                                        add => [sambaLogonTime => '0'],
                                                                                                        add => [sambaLogoffTime => '2147483647'],
                                                                                                        add => [sambaKickoffTime => '2147483647'],
@@ -300,7 +327,7 @@ if (defined($Options{'a'})) {
        
        $modify->code && die "failed to add entry: ", $modify->error ;
 
-    } else {
+  } else {
        my $FILE="|smbpasswd -s -a $userName >/dev/null" ;
        open (FILE, $FILE) || die "$!\n";
        print FILE <<EOF;
@@ -310,45 +337,64 @@ EOF
     ;
        close FILE;
        if ($?) {
-           print "$0: error adding samba account\n";
-           exit (10);
+         print "$0: error adding samba account\n";
+         exit (10);
        }
-    } # with_smbpasswd
-
-    my $valscriptpath = "$userName.cmd";
-    my $valprofilepath = "$_userProfile$userName";
-    my $valsmbhome = "$_userSmbHome";
-    my $valhomedrive = "$_userHomeDrive";
+  }                                                            # with_smbpasswd
+
+  my @mods;
+  my $valscriptpath;
+  if (defined $_userScript) {
+        $valscriptpath="$_userScript";
+  } else {
+        $valscriptpath = "$userName.cmd";
+  }
+  if (defined($tmp = $Options{'E'})) {
+    $valscriptpath = "$tmp";
+  }
 
-if (defined($tmp = $Options{'C'})) {
+  my $valsmbhome;
+  if (defined $_userSmbHome) {
+       $valsmbhome = "$_userSmbHome";
+  }
+  if (defined($tmp = $Options{'C'})) {
     $valsmbhome = "$tmp";
-}
+  }
+  if (defined $valsmbhome) {
+       push(@mods, 'sambaHomePath', $valsmbhome);
+  }
 
-if (defined($tmp = $Options{'D'})) {
+  my $valhomedrive = "$_userHomeDrive";
+  if (defined($tmp = $Options{'D'})) {
     $tmp = $tmp.":" unless ($tmp =~ /:/);
     $valhomedrive = "$tmp";
-}
+  }
 
-if (defined($tmp = $Options{'E'})) {
-    $valscriptpath = "$tmp";
-}
+  my $valprofilepath;
+  if (defined $_userProfile) {
+       $valprofilepath = "$_userProfile$userName";
+  }
 
-if (defined($tmp = $Options{'F'})) {
+  if (defined($tmp = $Options{'F'})) {
     $valprofilepath = "$tmp";
-}
+  }
+  if (defined $valprofilepath) {
+       push(@mods, 'sambaProfilePath', $valprofilepath);
+  }
 
-       
   my $modify = $ldap_master->modify ( "uid=$userName,$usersdn",
                                                                          changes => [
-                                                                                                 add => [sambaPrimaryGroupSID => "$SID-$userGroupRid"],
+                                                                                                 add => [sambaPrimaryGroupSID => "$userGroupSID"],
                                                                                                  add => [sambaHomeDrive => "$valhomedrive"],
-                                                                                                 add => [sambaHomePath => "$valsmbhome"],
-                                                                                                 add => [sambaProfilePath => "$valprofilepath"],
                                                                                                  add => [sambaLogonScript => "$valscriptpath"],
                                                                                                  add => [sambaLMPassword => 'XXX'],
                                                                                                  add => [sambaNTPassword => 'XXX']
                                                                                                 ]
                                                                        );
+  $modify = $ldap_master->modify ( "uid=$userName,$usersdn",
+                                                                       'replace' => { @mods }
+                                                                       );
+
 
   $modify->code && die "failed to add entry: ", $modify->error ;
 
@@ -357,7 +403,7 @@ $ldap_master->unbind;                       # take down session
 
 
 if (defined($Options{'P'})) {
-    exec "/usr/local/sbin/smbldap-passwd.pl $userName"
+  exec "/usr/local/sbin/smbldap-passwd.pl $userName"
 }
 
 exit 0;
@@ -366,57 +412,57 @@ exit 0;
 
 =head1 NAME
 
-       smbldap-useradd.pl - Create a new user or update default new 
-                            user information
+smbldap-useradd.pl - Create a new user or update default new 
+  user information
 
 =head1 SYNOPSIS
 
-       smbldap-useradd.pl [-c comment] [-d home_dir]
-               [-g initial_group] [-G group[,...]]
-               [-m [-k skeleton_dir]]
-               [-s shell] [-u uid [ -o]] [-P]
-               [-A canchange] [-B mustchange] [-C smbhome]
-               [-D homedrive] [-E scriptpath] [-F profilepath]
-               [-H acctflags] login
+smbldap-useradd.pl [-c comment] [-d home_dir]
+  [-g initial_group] [-G group[,...]]
+  [-m [-k skeleton_dir]]
+  [-s shell] [-u uid [ -o]] [-P]
+  [-A canchange] [-B mustchange] [-C smbhome]
+  [-D homedrive] [-E scriptpath] [-F profilepath]
+  [-H acctflags] login
 
 =head1 DESCRIPTION
 
-   Creating New Users
-       The smbldap-useradd.pl command creates a new user account using
-       the values specified on the  command  line  and  the default
-       values from the system.
-       The new user account will be entered into the system
-       files as needed, the home directory  will  be  created, and 
-       initial  files copied, depending on the command line options.
+Creating New Users
+  The smbldap-useradd.pl command creates a new user account using
+  the values specified on the  command  line  and  the default
+  values from the system.
+  The new user account will be entered into the system
+  files as needed, the home directory  will  be  created, and 
+  initial  files copied, depending on the command line options.
 
-       You have to use smbldap-passwd to set the user password.
-       For Samba users, rid is 2*uidNumber+1000, and primaryGroupID
-       is 2*gidNumber+1001. Thus you may want to use
-       smbldap-useradd.pl -a -g "Domain Admins" -u 500 Administrator
-       to create a sambaDomainName administrator (admin rid is 0x1F4 = 500 and
-       grouprid is 0x200 = 512)
+  You have to use smbldap-passwd to set the user password.
+  For Samba users, rid is 2*uidNumber+1000, and primaryGroupID
+  is 2*gidNumber+1001. Thus you may want to use
+  smbldap-useradd.pl -a -g "Domain Admins" -u 500 Administrator
+  to create a sambaDomainName administrator (admin rid is 0x1F4 = 500 and
+                                                                                        grouprid is 0x200 = 512)
 
-       Without any option, the account created will be an Unix (Posix)
-       account. The following options may be used to add information:
+  Without any option, the account created will be an Unix (Posix)
+  account. The following options may be used to add information:
 
-       -a     The user will have a Samba account (and Unix).
+-a     The user will have a Samba account (and Unix).
 
-       -w     Creates an account for a Samba machine (Workstation), so that 
-              it can join a sambaDomainName.
+  -w     Creates an account for a Samba machine (Workstation), so that 
+  it can join a sambaDomainName.
 
-       -x     Creates rid and primaryGroupID in hex (for Samba 2.2.2 bug). Else
-              decimal (2.2.2 patched from cvs or 2.2.x, x > 2)
+  -x     Creates rid and primaryGroupID in hex (for Samba 2.2.2 bug). Else
+  decimal (2.2.2 patched from cvs or 2.2.x, x > 2)
 
-       -c comment
-              The new user's comment field (gecos).
+  -c comment
+  The new user's comment field (gecos).
 
        -d home_dir
               The new user will be created using home_dir as the value for the
               user's login directory.  The default is to append the login name
-              to default_home and use that as the login directory name.
+  to default_home and use that as the login directory name.
 
-       -g initial_group
-              The group name or number of the user's initial login group.  The
+  -g initial_group
+  The group name or number of the user's initial login group.  The
               group  name must exist.  A group number must refer to an already
               existing group.  The default group number is 1.
 
@@ -428,20 +474,20 @@ exit 0;
               is for the user to belong only to the initial group.
 
        -m     The user's home directory will be created if it does not  exist.
-              The  files  contained in skeleton_dir will be copied to the home
-              directory if the -k option is used,  otherwise  the  files  con­
-              tained  in /etc/skel will be used instead.  Any directories con­
-              tained in skeleton_dir or  /etc/skel  will  be  created  in  the
-              user's  home  directory as well.  The -k option is only valid in
+  The  files  contained in skeleton_dir will be copied to the home
+  directory if the -k option is used,  otherwise  the  files  con­
+  tained  in /etc/skel will be used instead.  Any directories con­
+  tained in skeleton_dir or  /etc/skel  will  be  created  in  the
+  user's  home  directory as well.  The -k option is only valid in
               conjunction with the -m option.  The default is  to  not  create
               the directory and to not copy any files.
 
        -s shell
               The name of the user's login shell.  The  default  is  to  leave
-              this  field blank, which causes the system to select the default
-              login shell.
+  this  field blank, which causes the system to select the default
+  login shell.
 
-       -u uid The numerical value of  the  user's  ID.   This  value  must  be
+  -u uid The numerical value of  the  user's  ID.   This  value  must  be
               unique,  unless  the  -o option is used.  The value must be non-
               negative.  The default is to use the smallest ID  value  greater
               than 1000 and greater than every other user.
index 1a1a3214b589d99f0f2a6e4b2cb31373b6201e72..f1e69e209c561589b0faa341a01d7fd56ec53114 100755 (executable)
@@ -37,9 +37,9 @@ my %Options;
 my $ok = getopts('r?', \%Options);
 
 if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
-       print "Usage: $0 [-r?] username\n";
-       print "  -r     remove home directory\n";
-       exit (1);
+  print "Usage: $0 [-r?] username\n";
+  print "  -r  remove home directory\n";
+  exit (1);
 }
 
 # Read only first @ARGV
@@ -48,34 +48,34 @@ my $user = $ARGV[0];
 my $dn;
 # user must not exist in LDAP
 if (!defined($dn=get_user_dn($user))) {
-    print "$0: user $user does not exist\n";
-    exit (6);
+  print "$0: user $user does not exist\n";
+  exit (6);
 }
 
 if ($< != 0) {
-    print "You must be root to delete an user\n";
-    exit (1);
+  print "You must be root to delete an user\n";
+  exit (1);
 }
 
 my $homedir;
 if (defined($Options{'r'})) {
-    $homedir=get_homedir($user);
+  $homedir=get_homedir($user);
 }
 
 # remove user from groups
 my $groups = find_groups_of $user;
-my @grplines = split(/\n/, $groups);
+my @grplines = split(/\n/,$groups);
 
 my $grp;
 foreach $grp (@grplines) {
-    my $gname = "";
-    if ( $grp =~ /dn: cn=([^,]+),/) {
+  my $gname = "";
+  if ( $grp =~ /dn: cn=([^,]+),/) {
        $gname = $1;
        #print "xx $gname\n";
-    }
-    if ($gname ne "") {
+  }
+  if ($gname ne "") {
        group_remove_member($gname, $user);
-    }
+  }
 }
 
 # XXX
@@ -83,9 +83,9 @@ delete_user($user);
 
 # delete dir -- be sure that homeDir is not a strange value
 if (defined($Options{'r'})) {
-    if ($homedir !~ /^\/dev/ and $homedir !~ /^\/$/) {
+  if ($homedir !~ /^\/dev/ and $homedir !~ /^\/$/) {
        system "rm -rf $homedir";
-    }
+  }
 }
 
 my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
index f25c730fc851172d2033e031c0e51d3dbcd72883..70151b74122fe531e5dcaa82072e690f73ecb86c 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl 
+#!/usr/bin/perl -w
 
 #  This code was developped by IDEALX (http://IDEALX.org/) and
 #  contributors (their names can be found in the CONTRIBUTORS file).
@@ -29,48 +29,48 @@ use lib "$RealBin/";
 use smbldap_tools;
 use smbldap_conf;
 
-
 #####################
 
 use Getopt::Std;
 my %Options;
 my $nscd_status;
 
-my $ok = getopts('A:B:C:D:E:F:H:IJN:S:xme:f:u:g:G:d:l:s:c:ok:?h', \%Options);
+my $ok = getopts('A:B:C:D:E:F:H:IJN:S:Pame:f:u:g:G:d:l:s:c:ok:?h', \%Options);
 if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) || ($Options{'h'}) ) {
   print "Usage: $0 [-awmugdsckxABCDEFGHI?h] username\n";
   print "Available options are:\n";
-       print "  -c     gecos\n";
-       print "  -d     home directory\n";
-       #print "  -m    move home directory\n";
-       #print "  -f    inactive days\n";
-       print "  -u     uid\n";
-       print "  -o     uid can be non unique\n";
-       print "  -g     gid\n";
-       print "  -G     supplementary groups (comma separated)\n";
-       print "  -l     login name\n";
-       print "  -s     shell\n";
+  print "  -c    gecos\n";
+  print "  -d    home directory\n";
+  #print "  -m    move home directory\n";
+  #print "  -f    inactive days\n";
+  print "  -u    uid\n";
+  print "  -o    uid can be non unique\n";
+  print "  -g    gid\n";
+  print "  -G    supplementary groups (comma separated)\n";
+  print "  -l    login name\n";
+  print "  -s    shell\n";
   print "  -N    canonical name\n";
   print "  -S    surname\n";
+  print "  -P    ends by invoking smbldap-passwd.pl\n";
   print " For samba users:\n";
+  print "  -a    add sambaSamAccount objectclass\n";
   print "  -e    expire date (\"YYYY-MM-DD HH:MM:SS\")\n";
-       print "  -x     creates rid and primaryGroupID in hex instead of decimal (for Samba 2.2.2 unpatched only)\n";
-       print "  -A     can change password ? 0 if no, 1 if yes\n";
-       print "  -B     must change password ? 0 if no, 1 if yes\n";
-       print "  -C     sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')\n";
-       print "  -D     sambaHomeDrive (letter associated with home share, like 'H:')\n";
-       print "  -E     sambaLogonScript (DOS script to execute on login)\n";
-       print "  -F     sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n";
-       print "  -H     sambaAcctFlags (samba account control bits like '[NDHTUMWSLKI]')\n";
-       print "  -I     disable an user. Can't be used with -H or -J\n";
-       print "  -J     enable an user. Can't be used with -H or -I\n";
+  print "  -A    can change password ? 0 if no, 1 if yes\n";
+  print "  -B    must change password ? 0 if no, 1 if yes\n";
+  print "  -C    sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')\n";
+  print "  -D    sambaHomeDrive (letter associated with home share, like 'H:')\n";
+  print "  -E    sambaLogonScript (DOS script to execute on login)\n";
+  print "  -F    sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n";
+  print "  -H    sambaAcctFlags (samba account control bits like '[NDHTUMWSLKI]')\n";
+  print "  -I    disable an user. Can't be used with -H or -J\n";
+  print "  -J    enable an user. Can't be used with -H or -I\n";
   print "  -?|-h show this help message\n";
-       exit (1);
+  exit (1);
 }
 
 if ($< != 0) {
-    print "You must be root to modify an user\n";
-    exit (1);
+  print "You must be root to modify an user\n";
+  exit (1);
 }
 
 # Read only first @ARGV
@@ -79,13 +79,13 @@ my $user = $ARGV[0];
 # Read user data
 my $user_entry = read_user_entry($user);
 if (!defined($user_entry)) {
-    print "$0: user $user doesn't exist\n";
-    exit (1);
+  print "$0: user $user doesn't exist\n";
+  exit (1);
 }
 
 my $samba = 0;
 if (grep ($_ =~ /^sambaSamAccount$/i, $user_entry->get_value('objectClass'))) {
-    $samba = 1;
+  $samba = 1;
 }
 
 # get the dn of the user
@@ -93,64 +93,94 @@ my $dn= $user_entry->dn();
 
 my $tmp;
 my @mods;
+if (defined($tmp = $Options{'a'})) {
+       # Let's connect to the directory first
+       my $ldap_master=connect_ldap_master();
+        my $winmagic = 2147483647;
+        my $valpwdcanchange = 0;
+        my $valpwdmustchange = $winmagic;
+        my $valpwdlastset = 0; 
+        my $valacctflags = "[UX]";
+       my $user_entry=read_user_entry($user);
+       my $uidNumber = $user_entry->get_value('uidNumber');
+       my $userRid = 2 * $uidNumber + 1000;
+       # apply changes
+       my $modify = $ldap_master->modify ( "$dn",
+                                                                                changes => [
+                                                                                                        add => [objectClass => 'sambaSamAccount'],
+                                                                                                        add => [sambaPwdLastSet => "$valpwdlastset"],
+                                                                                                        add => [sambaLogonTime => '0'],
+                                                                                                        add => [sambaLogoffTime => '2147483647'],
+                                                                                                        add => [sambaKickoffTime => '2147483647'],
+                                                                                                        add => [sambaPwdCanChange => "$valpwdcanchange"],
+                                                                                                        add => [sambaPwdMustChange => "$valpwdmustchange"],
+                                                                                                        add => [displayName => "$_userGecos"],
+                                                                                                        add => [sambaSID=> "$SID-$userRid"],
+                                                                                                        add => [sambaAcctFlags => "$valacctflags"],
+                                                                                                   ]
+                                                                 );
+       $modify->code && warn "failed to modify entry: ", $modify->error ;
+}
 
 # Process options
 my $changed_uid;
 my $_userUidNumber;
 my $_userRid;
 if (defined($tmp = $Options{'u'})) {
-    if (defined($Options{'o'})) {
+  if (defined($Options{'o'})) {
        $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
        
        if ($nscd_status == 0) {
-           system "/etc/init.d/nscd stop > /dev/null 2>&1";
+         system "/etc/init.d/nscd stop > /dev/null 2>&1";
        }
 
        if (getpwuid($tmp)) {
-           if ($nscd_status == 0) {
+         if ($nscd_status == 0) {
                system "/etc/init.d/nscd start > /dev/null 2>&1";
-           }
+         }
 
-           print "$0: uid number $tmp exists\n";
-           exit (6);
+         print "$0: uid number $tmp exists\n";
+         exit (6);
        }
        if ($nscd_status == 0) {
-           system "/etc/init.d/nscd start > /dev/null 2>&1";
+         system "/etc/init.d/nscd start > /dev/null 2>&1";
        }
 
-    }
+  }
   push(@mods, 'uidNumber', $tmp);
-    $_userUidNumber = $tmp;
+  $_userUidNumber = $tmp;
   if ($samba) {
     # as rid we use 2 * uid + 1000
     my $_userRid = 2 * $_userUidNumber + 1000;
     if (defined($Options{'x'})) {
-       $_userRid= sprint("%x", $_userRid);
+      $_userRid= sprint("%x", $_userRid);
     }
     push(@mods, 'sambaSID', $SID.'-'.$_userRid);
-    }
-    $changed_uid = 1;
+  }
+  $changed_uid = 1;
 }
 
 my $changed_gid;
 my $_userGidNumber;
-my $_userGroupRid;
+my $_userGroupSID;
 if (defined($tmp = $Options{'g'})) {
-    $_userGidNumber = parse_group($tmp);
-    if ($_userGidNumber < 0) {
+  $_userGidNumber = parse_group($tmp);
+  if ($_userGidNumber < 0) {
        print "$0: group $tmp doesn't exist\n";
        exit (6);
-    }
+  }
   push(@mods, 'gidNumber', $_userGidNumber);
   if ($samba) {
-# as grouprid we use 2 * gid + 1001
-    my $_userGroupRid = 2 * $_userGidNumber + 1001;
-    if (defined($Options{'x'})) {
-       $_userGroupRid = sprint("%x", $_userGroupRid);
-    }
-    push(@mods, 'sambaPrimaryGroupSid', $SID.'-'.$_userGroupRid);
+    # as grouprid we use the sambaSID attribute's value of the group
+    my $group_entry = read_group_entry_gid($_userGidNumber);
+    my $_userGroupSID = $group_entry->get_value('sambaSID');
+    unless ($_userGroupSID) {
+      print "$0: unknown group SID not set for unix group $_userGidNumber\n";
+      exit (7);
     }
-    $changed_gid = 1;
+    push(@mods, 'sambaPrimaryGroupSid', $_userGroupSID);
+  }
+  $changed_gid = 1;
 }
 
 if (defined($tmp = $Options{'s'})) {
@@ -158,7 +188,7 @@ if (defined($tmp = $Options{'s'})) {
 }
 
 
-if (defined($tmp = $Options{'c'})) { 
+if (defined($tmp = $Options{'c'})) {
   push(@mods, 'gecos' => $tmp,
           'description' => $tmp);
   if ($samba == 1) {
@@ -180,24 +210,24 @@ if (defined($tmp = $Options{'S'})) {
 
 if (defined($tmp = $Options{'G'})) {
 
-    # remove user from old groups
-    my $groups = find_groups_of $user;
-    my @grplines = split(/\n/, $groups);
+  # remove user from old groups
+  my $groups = find_groups_of $user;
+  my @grplines = split(/\n/,$groups);
 
-    my $grp;
-    foreach $grp (@grplines) {
+  my $grp;
+  foreach $grp (@grplines) {
        my $gname = "";
        if ( $grp =~ /dn: cn=([^,]+),/) {
-           $gname = $1;
-           #print "xx $gname\n";
+         $gname = $1;
+         #print "xx $gname\n";
        }
        if ($gname ne "") {
-           group_remove_member($gname, $user);
+         group_remove_member($gname, $user);
        }
-    }
+  }
 
-    # add user to new groups
-    add_grouplist_user($tmp, $user);
+  # add user to new groups
+  add_grouplist_user($tmp, $user);
 }
 
 #
@@ -212,7 +242,7 @@ if (defined($tmp = $Options{'G'})) {
 my $attr;
 my $winmagic = 2147483647;
 
-my $samba = is_samba_user($user);
+$samba = is_samba_user($user);
 
 if (defined($tmp = $Options{'e'})) {
   if ($samba == 1) {
@@ -234,9 +264,9 @@ if (defined($tmp = $Options{'A'})) {
       $_sambaPwdCanChange=$winmagic;
     }
     push(@mods, 'sambaPwdCanChange' => $_sambaPwdCanChange);
-    } else {
+  } else {
        print "User $user is not a samba user\n";
-    }
+  }
 }
 
 my $_sambaPwdMustChange;
@@ -244,13 +274,31 @@ if (defined($tmp = $Options{'B'})) {
   if ($samba == 1) {
     if ($tmp != 0) {
       $_sambaPwdMustChange=0;
+      # To force a user to change his password:
+      # . the attribut sambaPwdLastSet must be != 0
+      # . the attribut sambaAcctFlags must not match the 'X' flag
+      my $_sambaAcctFlags;
+      my $flags = $user_entry->get_value('sambaAcctFlags');
+      if ( $flags =~ /X/ ) {
+       my $letters;
+       if ($flags =~ /(\w+)/) {
+               $letters = $1;
+       }
+       $letters =~ s/X//;
+       $_sambaAcctFlags="\[$letters\]";
+       push(@mods, 'sambaAcctFlags' => $_sambaAcctFlags);
+      }
+      my $_sambaPwdLastSet = $user_entry->get_value('sambaPwdLastSet');
+      if ($_sambaPwdLastSet == 0) {
+       push(@mods, 'sambaPwdLastSet' => $winmagic);
+      }
     } else {
       $_sambaPwdMustChange=$winmagic;
     }
     push(@mods, 'sambaPwdMustChange' => $_sambaPwdMustChange);
-    } else {
+  } else {
        print "User $user is not a samba user\n";
-    }
+  }
 }
 
 if (defined($tmp = $Options{'C'})) {
@@ -292,7 +340,7 @@ if (defined($tmp = $Options{'F'})) {
 
 if ($samba == 1 and (defined $Options{'H'} or defined $Options{'I'} or defined $Options{'J'})) {
   my $_sambaAcctFlags;
-if (defined($tmp = $Options{'H'})) {
+  if (defined($tmp = $Options{'H'})) {
     #$tmp =~ s/\\/\\\\/g;
     $_sambaAcctFlags=$tmp;
   } else {
@@ -301,24 +349,24 @@ if (defined($tmp = $Options{'H'})) {
     $flags = $user_entry->get_value('sambaAcctFlags');
 
     if (defined($tmp = $Options{'I'})) {
-    if ( !($flags =~ /D/) ) {
-       my $letters;
-       if ($flags =~ /(\w+)/) {
-           $letters = $1;
-       }
+      if ( !($flags =~ /D/) ) {
+               my $letters;
+               if ($flags =~ /(\w+)/) {
+                 $letters = $1;
+               }
                $_sambaAcctFlags="\[D$letters\]";
-    }
-} elsif (defined($tmp = $Options{'J'})) {
-    if ( $flags =~ /D/ ) {
-       my $letters;
-       if ($flags =~ /(\w+)/) {
-           $letters = $1;
-       }
-       $letters =~ s/D//;
+      }
+    } elsif (defined($tmp = $Options{'J'})) {
+         if ( $flags =~ /D/ ) {
+               my $letters;
+               if ($flags =~ /(\w+)/) {
+                 $letters = $1;
+               }
+               $letters =~ s/D//;
                $_sambaAcctFlags="\[$letters\]";
          }
-    }
-}
+       }
+  }
 
 
   if ("$_sambaAcctFlags" ne '') {
@@ -344,7 +392,11 @@ $ldap_master->unbind;
 $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
 
 if ($nscd_status == 0) {
-   system "/etc/init.d/nscd restart > /dev/null 2>&1";
+  system "/etc/init.d/nscd restart > /dev/null 2>&1";
+}
+
+if (defined($Options{'P'})) {
+  exec "/usr/local/sbin/smbldap-passwd.pl $user"
 }
 
 
@@ -352,32 +404,32 @@ if ($nscd_status == 0) {
 
 =head1 NAME
 
-       smbldap-usermod.pl - Modify a user account
+smbldap-usermod.pl - Modify a user account
 
 =head1 SYNOPSIS
 
-       smbldap-usermod.pl [-c comment] [-d home_dir]
-               [-g initial_group] [-G group[,...]]
-               [-l login_name] [-p passwd]
-               [-s shell] [-u uid [ -o]] [-x]
-               [-A canchange] [-B mustchange] [-C smbhome]
-               [-D homedrive] [-E scriptpath] [-F profilepath]
-               [-H acctflags] login
+smbldap-usermod.pl [-c comment] [-d home_dir]
+  [-g initial_group] [-G group[,...]]
+  [-l login_name] [-p passwd]
+  [-s shell] [-u uid [ -o]] [-x]
+  [-A canchange] [-B mustchange] [-C smbhome]
+  [-D homedrive] [-E scriptpath] [-F profilepath]
+  [-H acctflags] login
 
 =head1 DESCRIPTION
 
-       The  smbldap-usermod.pl  command  modifies the system account files
-       to reflect the changes that are specified on the  command  line.
-       The  options  which apply to the usermod command are
+The  smbldap-usermod.pl  command  modifies the system account files
+  to reflect the changes that are specified on the  command  line.
+  The  options  which apply to the usermod command are
 
-       -c comment
-              The new value of the user's comment field (gecos).
+  -c comment
+  The new value of the user's comment field (gecos).
 
        -d home_dir
               The user's new login directory.
 
-       -g initial_group
-              The group name or number of the user's new initial login  group.
+  -g initial_group
+  The group name or number of the user's new initial login  group.
               The  group  name  must  exist.   A group number must refer to an
               already existing group.  The default group number is 1.
 
@@ -391,18 +443,18 @@ if ($nscd_status == 0) {
 
        -l login_name
               The  name  of the user will be changed from login to login_name.
-              Nothing else is changed.  In particular, the user's home  direc­
-              tory  name  should  probably be changed to reflect the new login
-              name.
+              Nothing else is changed.  In particular, the user's home  direc­
+  tory  name  should  probably be changed to reflect the new login
+  name.
 
-       -s shell
-              The name of the user's new login shell.  Setting this  field  to
+  -s shell
+  The name of the user's new login shell.  Setting this  field  to
               blank causes the system to select the default login shell.
 
        -u uid The  numerical  value  of  the  user's  ID.   This value must be
-              unique, unless the -o option is used.  The value  must  be  non-
-              negative.  Any files which the user owns  and  which  are
-              located  in  the directory tree rooted at the user's home direc­
+  unique, unless the -o option is used.  The value  must  be  non-
+  negative.  Any files which the user owns  and  which  are
+  located  in  the directory tree rooted at the user's home direc­
               tory will have the file user ID  changed  automatically.   Files
               outside of the user's home directory must be altered manually.
 
index 555b35ffd817d2232628caea336d91c86234917e..173480d76c2742c5eaa59536bec0bf5107e12ee9 100755 (executable)
@@ -34,8 +34,8 @@ my %Options;
 my $ok = getopts('?', \%Options);
 
 if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
-       print "Usage: $0 [-?] username\n";
-       print "  -?     show this help message\n";
+  print "Usage: $0 [-?] username\n";
+  print "  -?  show this help message\n";
        exit (1);
 }
 
index c3d5c1732c731b2539a458af8a9502abac2e2c84..257c205a2cd3c8bbe60d2dfe46e50ccb0f21654a 100644 (file)
@@ -28,33 +28,33 @@ package smbldap_conf;
 #       . be the configuration file for all smbldap-tools scripts
 
 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS
-$UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP
-$slavePort $masterPort $ldapSSL $slaveURI $masterURI $with_smbpasswd $mk_ntpasswd
-$ldap_path $ldap_opts $ldapmodify $suffix $usersdn $computersdn
-$groupsdn $scope $binddn $bindpasswd
-$slaveDN $slavePw $masterDN $masterPw
-$_userLoginShell $_userHomePrefix $_userGecos
-$_defaultUserGid $_defaultComputerGid
-$_skeletonDir $_userSmbHome
-$_userProfile $_userHomeDrive
-$_userScript $usersou $computersou $groupsou $SID $hash_encrypt
-);
+                       $UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP
+                       $slavePort $masterPort $ldapSSL $slaveURI $masterURI $with_smbpasswd $mk_ntpasswd
+                       $ldap_path $ldap_opts $ldapmodify $suffix $usersdn $computersdn
+                       $groupsdn $scope $binddn $bindpasswd
+                       $slaveDN $slavePw $masterDN $masterPw
+                       $_userLoginShell $_userHomePrefix $_userGecos
+                       $_defaultUserGid $_defaultComputerGid
+                       $_skeletonDir $_userSmbHome
+                       $_userProfile $_userHomeDrive
+                       $_userScript $usersou $computersou $groupsou $SID $hash_encrypt $_defaultMaxPasswordAge
+                  );
 
 use Exporter;
 $VERSION = 1.00;
 @ISA = qw(Exporter);
 
 @EXPORT = qw(
-$UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP
-$slavePort $masterPort $ldapSSL $slaveURI $masterURI $with_smbpasswd $mk_ntpasswd
-$ldap_path $ldap_opts $ldapmodify $suffix $usersdn
-$computersdn $groupsdn $scope $binddn $bindpasswd
-$slaveDN $slavePw $masterDN $masterPw
-$_userLoginShell $_userHomePrefix $_userGecos
-$_defaultUserGid $_defaultComputerGid $_skeletonDir 
-$_userSmbHome $_userProfile $_userHomeDrive $_userScript
-$usersou $computersou $groupsou $SID $hash_encrypt
-);
+                        $UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP
+                        $slavePort $masterPort $ldapSSL $slaveURI $masterURI $with_smbpasswd $mk_ntpasswd
+                        $ldap_path $ldap_opts $ldapmodify $suffix $usersdn
+                        $computersdn $groupsdn $scope $binddn $bindpasswd
+                        $slaveDN $slavePw $masterDN $masterPw
+                        $_userLoginShell $_userHomePrefix $_userGecos
+                        $_defaultUserGid $_defaultComputerGid $_skeletonDir 
+                        $_userSmbHome $_userProfile $_userHomeDrive $_userScript
+                        $usersou $computersou $groupsou $SID $hash_encrypt $_defaultMaxPasswordAge
+                       );
 
 
 ##############################################################################
@@ -101,7 +101,7 @@ $ldapSSL = "0";
 
 # LDAP Suffix
 # Ex: $suffix = "dc=IDEALX,dc=ORG";
-$suffix = "dc=IDEALX,dc=ORG";
+$suffix = "dc=IDEALX,dc=COM";
 
 
 # Where are stored Users
@@ -156,7 +156,7 @@ $masterPw = $bindpasswd;
 $_userLoginShell = q(_LOGINSHELL_);
 
 # Home directory prefix (without username)
-#Ex: $_userHomePrefix = q(/home/);
+# Ex: $_userHomePrefix = q(/home/);
 $_userHomePrefix = q(_HOMEPREFIX_);
 
 # Gecos
@@ -171,6 +171,11 @@ $_defaultComputerGid = 553;
 # Skel dir
 $_skeletonDir = q(/etc/skel);
 
+# Default password validation time (time in days) Comment the next line if
+# you don't want password to be enable for $_defaultMaxPasswordAge days (be
+# careful to the sambaPwdMustChange attribute's value)
+$_defaultMaxPasswordAge = 45;
+
 ##############################################################################
 #
 # SAMBA Configuration
@@ -180,11 +185,15 @@ $_skeletonDir = q(/etc/skel);
 # The UNC path to home drives location without the username last extension
 # (will be dynamically prepended)
 # Ex: q(\\\\My-PDC-netbios-name\\homes) for \\My-PDC-netbios-name\homes
+# Just comment this if you want to use the smb.conf 'logon home' directive
+# and/or desabling roaming profiles
 $_userSmbHome = q(\\\\_PDCNAME_\\homes);
 
 # The UNC path to profiles locations without the username last extension
 # (will be dynamically prepended)
 # Ex: q(\\\\My-PDC-netbios-name\\profiles\\) for \\My-PDC-netbios-name\profiles
+# Just comment this if you want to use the smb.conf 'logon path' directive
+# and/or desabling roaming profiles
 $_userProfile = q(\\\\_PDCNAME_\\profiles\\);
 
 # The default Home Drive Letter mapping
@@ -194,7 +203,7 @@ $_userHomeDrive = q(_HOMEDRIVE_);
 
 # The default user netlogon script name
 # if not used, will be automatically username.cmd
-#$_userScript = q(startup.cmd); # make sure script file is edited under dos
+# $_userScript = q(startup.cmd); # make sure script file is edited under dos
 
 
 ##############################################################################
@@ -211,13 +220,13 @@ $mk_ntpasswd = "/usr/local/sbin/mkntpwd";
 
 # those next externals commands are kept fot the migration scripts and
 # for the populate script: this will be updated as soon as possible
-       $slaveURI = "ldap://$slaveLDAP:$slavePort";
-       $masterURI = "ldap://$masterLDAP:$masterPort";
+$slaveURI = "ldap://$slaveLDAP:$slavePort";
+$masterURI = "ldap://$masterLDAP:$masterPort";
 
 $ldap_path = "/usr/bin";
 
 if ( $ldapSSL eq "0" ) {
-$ldap_opts = "-x";
+       $ldap_opts = "-x";
 } elsif ( $ldapSSL eq "1" ) {
        $ldap_opts = "-x -Z";
 } else {
index 8001442fe8ff6962381e6f5851832efbf34a5e2a..d33a65b7d17355d1367ad8dbf550c5658fadb149 100755 (executable)
@@ -34,36 +34,40 @@ $VERSION = 1.00;
 @ISA = qw(Exporter);
 
 @EXPORT = qw(
-get_user_dn
-get_group_dn
+                        get_user_dn
+                        get_group_dn
                         is_group_member
-is_samba_user
+                        is_samba_user
                         is_unix_user
-is_user_valid
-get_dn_from_line
-add_posix_machine
-add_samba_machine
-add_samba_machine_mkntpwd
-group_add_user
-add_grouplist_user
-disable_user
-delete_user
-group_add
+                        is_user_valid
+                        does_sid_exist
+                        get_dn_from_line
+                        add_posix_machine
+                        add_samba_machine
+                        add_samba_machine_mkntpwd
+                        group_add_user
+                        add_grouplist_user
+                        disable_user
+                        delete_user
+                        group_add
                         group_del
-get_homedir
-read_user
+                        get_homedir
+                        read_user
                         read_user_entry
-read_group
-find_groups_of
-parse_group
-group_remove_member
-group_get_members
-do_ldapadd
-do_ldapmodify
-get_user_dn2
+                        read_group
+                        read_group_entry
+                        read_group_entry_gid
+                        find_groups_of
+                        parse_group
+                        group_remove_member
+                        group_get_members
+                        do_ldapadd
+                        do_ldapmodify
+                        get_user_dn2
                         connect_ldap_master
                         connect_ldap_slave
-);
+                        group_type_by_name
+                       );
 
 sub connect_ldap_master
   {
@@ -116,14 +120,14 @@ sub connect_ldap_slave
   }
 
 sub get_user_dn
-{
+  {
     my $user = shift;
     my $dn='';
     my $ldap_slave=connect_ldap_slave();
     my  $mesg = $ldap_slave->search (    base   => $suffix,
-                                  scope => $scope,
-                                  filter => "(&(objectclass=posixAccount)(uid=$user))"
-                              );
+                                                                                scope => $scope,
+                                                                                filter => "(&(objectclass=posixAccount)(uid=$user))"
+                                                                       );
     $mesg->code && die $mesg->error;
     foreach my $entry ($mesg->all_entries) {
          $dn= $entry->dn;
@@ -131,70 +135,70 @@ sub get_user_dn
     $ldap_slave->unbind;
     chomp($dn);
     if ($dn eq '') {
-       return undef;
+         return undef;
     }
     $dn="dn: ".$dn;
     return $dn;
-}
+  }
 
 
 sub get_user_dn2
-{
+  {
     my $user = shift;
     my $dn='';
     my $ldap_slave=connect_ldap_slave();
     my  $mesg = $ldap_slave->search (    base   => $suffix,
-                                  scope => $scope,
-                               filter => "(&(objectclass=posixAccount)(uid=$user))"
-                              );
+                                                                                scope => $scope,
+                                                                                filter => "(&(objectclass=posixAccount)(uid=$user))"
+                                                                       );
     $mesg->code && warn "failed to perform search; ", $mesg->error;
 
     foreach my $entry ($mesg->all_entries) {
-       $dn= $entry->dn;
+         $dn= $entry->dn;
     }
     $ldap_slave->unbind;
     chomp($dn);
     if ($dn eq '') {
-       return (1,undef);
+         return (1,undef);
     }
     $dn="dn: ".$dn;
     return (1,$dn);
-}
+  }
 
 
 sub get_group_dn
   {
-      my $group = shift;
-      my $dn='';
+       my $group = shift;
+       my $dn='';
        my $ldap_slave=connect_ldap_slave();
        my  $mesg = $ldap_slave->search (    base   => $groupsdn,
-                                    scope => $scope,
-                                    filter => "(&(objectclass=posixGroup)(|(cn=$group)(gidNumber=$group)))"
-                               );
-      $mesg->code && die $mesg->error;
-      foreach my $entry ($mesg->all_entries) {
+                                                                                scope => $scope,
+                                                                                filter => "(&(objectclass=posixGroup)(|(cn=$group)(gidNumber=$group)))"
+                                                                       );
+       $mesg->code && die $mesg->error;
+       foreach my $entry ($mesg->all_entries) {
          $dn= $entry->dn;
        }
        $ldap_slave->unbind;
-      chomp($dn);
-      if ($dn eq '') {
+       chomp($dn);
+       if ($dn eq '') {
          return undef;
-      }
-      $dn="dn: ".$dn;
-      return $dn;
+       }
+       $dn="dn: ".$dn;
+       return $dn;
   }
 
 # return (success, dn)
 # bool = is_samba_user($username)
 sub is_samba_user
   {
-      my $user = shift;
+       my $user = shift;
        my $ldap_slave=connect_ldap_slave();
        my $mesg = $ldap_slave->search (    base   => $suffix,
-                                   scope => $scope,
-                                   filter => "(&(objectClass=sambaSamAccount)(uid=$user))"
-                              );
-      $mesg->code && die $mesg->error;
+                                                                               scope => $scope,
+                                                                               filter => "(&(objectClass=sambaSamAccount)(uid=$user))"
+                                                                  );
+       $mesg->code && die $mesg->error;
        $ldap_slave->unbind;
        return ($mesg->count ne 0);
   }
@@ -217,52 +221,68 @@ sub is_group_member
        my $dn_group = shift;
        my $user = shift;
        my $ldap_slave=connect_ldap_slave();
-       my $mesg = $ldap_slave->search (
-                                                                       base   => "$dn_group",
+       my $mesg = $ldap_slave->search (   base   => $dn_group,
                                                                        scope => 'base',
                                                                        filter => "(&(memberUid=$user))"
                                                                   );
        $mesg->code && die $mesg->error;
        $ldap_slave->unbind;
-      return ($mesg->count ne 0);
+       return ($mesg->count ne 0);
   }
 
+# all entries = does_sid_exist($sid,$scope)
+sub does_sid_exist
+  {
+       my $sid = shift;
+       my $dn_group=shift;
+       my $ldap_slave=connect_ldap_slave();
+       my $mesg = $ldap_slave->search (    base   => $dn_group,
+                                                                               scope => $scope,
+                                                                               filter => "(sambaSID=$sid)"
+                                                                               #filter => "(&(objectClass=sambaSamAccount|objectClass=sambaGroupMapping)(sambaSID=$sid))"
+                                                                  );
+       $mesg->code && die $mesg->error;
+       $ldap_slave->unbind;
+       return ($mesg);
+  }
 
 # try to bind with user dn and password to validate current password
 sub is_user_valid
   {
-      my ($user, $dn, $pass) = @_;
-      my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
-      my $mesg= $ldap->bind (dn => $dn, password => $pass );
+       my ($user, $dn, $pass) = @_;
+       my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
+       my $mesg= $ldap->bind (dn => $dn, password => $pass );
        if ($mesg->code eq 0) {
-           $ldap->unbind;
-           return 1;
+         $ldap->unbind;
+         return 1;
        } else {
-           if($ldap->bind()) {
+         if ($ldap->bind()) {
                $ldap->unbind;
                return 0;
-           } else {
+         } else {
                print ("The LDAP directory is not available.\n Check the server, cables ...");
                $ldap->unbind;
                return 0;
          }
          die "Problem : contact your administrator";
        }
-}
+  }
+
 
 # dn = get_dn_from_line ($dn_line)
 # helper to get "a=b,c=d" from "dn: a=b,c=d"
 sub get_dn_from_line
   {
-      my $dn = shift;
-      $dn =~ s/^dn: //;
-      return $dn;
+       my $dn = shift;
+       $dn =~ s/^dn: //;
+       return $dn;
   }
 
+
 # success = add_posix_machine($user, $uid, $gid)
 sub add_posix_machine
   {
-      my ($user, $uid, $gid) = @_;
+       my ($user, $uid, $gid) = @_;
        # bind to a directory with dn and password
        my $ldap_master=connect_ldap_master();
        my $add = $ldap_master->add ( "uid=$user,$computersdn",
@@ -288,32 +308,32 @@ sub add_posix_machine
 
 # success = add_samba_machine($computername)
 sub add_samba_machine
-{
+  {
     my $user = shift;
     system "smbpasswd -a -m $user";
     return 1;
-}
+  }
 
 sub add_samba_machine_mkntpwd
   {
-      my ($user, $uid) = @_;
-      my $sambaSID = 2 * $uid + 1000;
-      my $name = $user;
-      $name =~ s/.$//s;
+       my ($user, $uid) = @_;
+       my $sambaSID = 2 * $uid + 1000;
+       my $name = $user;
+       $name =~ s/.$//s;
 
-      if ($mk_ntpasswd eq '') {
+       if ($mk_ntpasswd eq '') {
          print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n";
          return 0;
-      }
+       }
 
-      my $ntpwd = `$mk_ntpasswd '$name'`;
-      chomp(my $lmpassword = substr($ntpwd, 0, index($ntpwd, ':')));
-      chomp(my $ntpassword = substr($ntpwd, index($ntpwd, ':')+1));
+       my $ntpwd = `$mk_ntpasswd '$name'`;
+       chomp(my $lmpassword = substr($ntpwd, 0, index($ntpwd, ':')));
+       chomp(my $ntpassword = substr($ntpwd, index($ntpwd, ':')+1));
 
        my $ldap_master=connect_ldap_master();
        my $modify = $ldap_master->modify ( "uid=$user,$computersdn",
                                                                                changes => [
-                                                                                                       replace => [objectClass => ['inetOrgPerson', 'posixAccount', 'sambaSAMAccount']],
+                                                                                                       replace => [objectClass => ['inetOrgPerson', 'posixAccount', 'sambaSamAccount']],
                                                                                                        add => [sambaPwdLastSet => '0'],
                                                                                                        add => [sambaLogonTime => '0'],
                                                                                                        add => [sambaLogoffTime => '2147483647'],
@@ -330,7 +350,7 @@ sub add_samba_machine_mkntpwd
        
        $modify->code && die "failed to add entry: ", $modify->error ;
 
-      return 1;
+       return 1;
        # take down the session
        $ldap_master->unbind;
 
@@ -339,16 +359,16 @@ sub add_samba_machine_mkntpwd
 
 sub group_add_user
   {
-      my ($group, $userid) = @_;
-      my $members='';
-      my $dn_line = get_group_dn($group);
+       my ($group, $userid) = @_;
+       my $members='';
+       my $dn_line = get_group_dn($group);
        if (!defined(get_group_dn($group))) {
          print "$0: group \"$group\" doesn't exist\n";
          exit (6); 
        }
-      if (!defined($dn_line)) {
+       if (!defined($dn_line)) {
          return 1;
-      }
+       }
        my $dn = get_dn_from_line("$dn_line");
        # on look if the user is already present in the group
        my $is_member=is_group_member($dn,$userid);
@@ -367,8 +387,8 @@ sub group_add_user
          $modify->code && die "failed to modify entry: ", $modify->error ;
          # take down session
          $ldap_master->unbind;
-           }
-      }
+       }
+  }
 
 sub group_del
   {
@@ -383,23 +403,23 @@ sub group_del
 
 sub add_grouplist_user
   {
-      my ($grouplist, $user) = @_;
-      my @array = split(/,/, $grouplist);
-      foreach my $group (@array) {
+       my ($grouplist, $user) = @_;
+       my @array = split(/,/, $grouplist);
+       foreach my $group (@array) {
          group_add_user($group, $user);
-      }
+       }
   }
 
 sub disable_user
   {
-      my $user = shift;
-      my $dn_line;
+       my $user = shift;
+       my $dn_line;
        my $dn = get_dn_from_line($dn_line);
-
-      if (!defined($dn_line = get_user_dn($user))) {
+       
+       if (!defined($dn_line = get_user_dn($user))) {
          print "$0: user $user doesn't exist\n";
          exit (10);
-      }
+       }
        my $ldap_master=connect_ldap_master();
        my $modify = $ldap_master->modify ( "$dn",
                                                                                changes => [
@@ -408,14 +428,14 @@ sub disable_user
                                                                          );
        $modify->code && die "failed to modify entry: ", $modify->error ;
 
-      if (is_samba_user($user)) {
+       if (is_samba_user($user)) {
          my $modify = $ldap_master->modify ( "$dn",
                                                                                  changes => [
                                                                                                          replace => [sambaAcctFlags => '[D       ]']
                                                                                                         ]
                                                                                );
          $modify->code && die "failed to modify entry: ", $modify->error ;
-      }
+       }
        # take down session
        $ldap_master->unbind;
   }
@@ -423,43 +443,43 @@ sub disable_user
 # delete_user($user)
 sub delete_user
   {
-      my $user = shift;
-      my $dn_line;
+       my $user = shift;
+       my $dn_line;
 
-      if (!defined($dn_line = get_user_dn($user))) {
+       if (!defined($dn_line = get_user_dn($user))) {
          print "$0: user $user doesn't exist\n";
          exit (10);
-      }
+       }
 
-      my $dn = get_dn_from_line($dn_line);
+       my $dn = get_dn_from_line($dn_line);
        my $ldap_master=connect_ldap_master();
        my $modify = $ldap_master->delete($dn);
        $ldap_master->unbind;
   }
 
-# $success = group_add($groupname, $group_gid, $force_using_existing_gid)
+# $gid = group_add($groupname, $group_gid, $force_using_existing_gid)
 sub group_add
   {
-      my ($gname, $gid, $force) = @_;
-      my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
-      if ($nscd_status == 0) {
+       my ($gname, $gid, $force) = @_;
+       my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
+       if ($nscd_status == 0) {
          system "/etc/init.d/nscd stop > /dev/null 2>&1";
-      }
-      if (!defined($gid)) {
+       }
+       if (!defined($gid)) {
          while (defined(getgrgid($GID_START))) {
-             $GID_START++;
+               $GID_START++;
          }
          $gid = $GID_START;
-      } else {
+       } else {
          if (!defined($force)) {
-             if (defined(getgrgid($gid))) {
-                 return 0;
-             }
+               if (defined(getgrgid($gid))) {
+                 return undef;
+               }
          }
-      }
-      if ($nscd_status == 0) {
+       }
+       if ($nscd_status == 0) {
          system "/etc/init.d/nscd start > /dev/null 2>&1";
-      }
+       }
        my $ldap_master=connect_ldap_master();
        my $modify = $ldap_master->add ( "cn=$gname,$groupsdn",
                                                                         attrs => [
@@ -472,67 +492,67 @@ sub group_add
        $modify->code && die "failed to add entry: ", $modify->error ;
        # take down session
        $ldap_master->unbind;
-      return 1;
+       return $gid;
   }
 
 # $homedir = get_homedir ($user)
 sub get_homedir
   {
-      my $user = shift;
-      my $homeDir='';
+       my $user = shift;
+       my $homeDir='';
        my $ldap_slave=connect_ldap_slave();
        my  $mesg = $ldap_slave->search (
                                                                         base   =>$suffix,
                                                                         scope => $scope,
                                                                         filter => "(&(objectclass=posixAccount)(uid=$user))"
                                                                        );
-      $mesg->code && die $mesg->error;
-      foreach my $entry ($mesg->all_entries){
+       $mesg->code && die $mesg->error;
+       foreach my $entry ($mesg->all_entries) {
          foreach my $attr ($entry->attributes) {
-               if ($attr=~/\bhomeDirectory\b/){
-                   foreach my $ent($entry->get_value($attr)) {
+               if ($attr=~/\bhomeDirectory\b/) {
+                 foreach my $ent ($entry->get_value($attr)) {
                        $homeDir.= $attr.": ".$ent."\n";
-                   }
+                 }
                }
-           }
-      }
+         }
+       }
        $ldap_slave->unbind;
-      chomp $homeDir;
-      if ($homeDir eq '') {
+       chomp $homeDir;
+       if ($homeDir eq '') {
          return undef;
-      }
-      $homeDir =~ s/^homeDirectory: //;
-      return $homeDir;
+       }
+       $homeDir =~ s/^homeDirectory: //;
+       return $homeDir;
   }
 
 # search for an user
 sub read_user
   {
-      my $user = shift;
-      my $lines ='';
+       my $user = shift;
+       my $lines ='';
        my $ldap_slave=connect_ldap_slave();
        my $mesg = $ldap_slave->search ( # perform a search
-                                base   => $suffix,
-                                scope => $scope,
-                                filter => "(&(objectclass=posixAccount)(uid=$user))"
-                               );
+                                                                       base   => $suffix,
+                                                                       scope => $scope,
+                                                                       filter => "(&(objectclass=posixAccount)(uid=$user))"
+                                                                  );
 
-      $mesg->code && die $mesg->error;
-      foreach my $entry ($mesg->all_entries) {
+       $mesg->code && die $mesg->error;
+       foreach my $entry ($mesg->all_entries) {
          $lines.= "dn: " . $entry->dn."\n";
          foreach my $attr ($entry->attributes) {
-             {
+               {
                  $lines.= $attr.": ".join(',', $entry->get_value($attr))."\n";
-             }
+               }
          }
-      }
+       }
        # take down session
        $ldap_slave->unbind;
-      chomp $lines;
-      if ($lines eq '') {
+       chomp $lines;
+       if ($lines eq '') {
          return undef;
-      }
-      return $lines;
+       }
+       return $lines;
   }
 
 # search for a user
@@ -556,86 +576,124 @@ sub read_user_entry
 # search for a group
 sub read_group
   {
-      my $user = shift;
-      my $lines ='';
+       my $user = shift;
+       my $lines ='';
        my $ldap_slave=connect_ldap_slave();
        my  $mesg = $ldap_slave->search ( # perform a search
-                                base   => $groupsdn,
-                                scope => $scope,
-                                filter => "(&(objectclass=posixGroup)(cn=$user))"
-                               );
+                                                                        base   => $groupsdn,
+                                                                        scope => $scope,
+                                                                        filter => "(&(objectclass=posixGroup)(cn=$user))"
+                                                                       );
 
-      $mesg->code && die $mesg->error;
-      foreach my $entry ($mesg->all_entries) {
+       $mesg->code && die $mesg->error;
+       foreach my $entry ($mesg->all_entries) {
          $lines.= "dn: " . $entry->dn."\n";
          foreach my $attr ($entry->attributes) {
-             {
+               {
                  $lines.= $attr.": ".join(',', $entry->get_value($attr))."\n";
-             }
+               }
          }
-      }
+       }
        # take down session
        $ldap_slave->unbind;
-      chomp $lines;
-      if ($lines eq '') {
+       chomp $lines;
+       if ($lines eq '') {
          return undef;
-      }
-      return $lines;
+       }
+       return $lines;
   }
 
 # find groups of a given user
 ##### MODIFIE ########
 sub find_groups_of
   {
-      my $user = shift;
-      my $lines ='';
+       my $user = shift;
+       my $lines ='';
        my $ldap_slave=connect_ldap_slave;
        my  $mesg = $ldap_slave->search ( # perform a search
-                                base   => $groupsdn,
-                                scope => $scope,
-                                filter => "(&(objectclass=posixGroup)(memberuid=$user))"
-                               );
-      $mesg->code && die $mesg->error;
-      foreach my $entry ($mesg->all_entries) {
+                                                                        base   => $groupsdn,
+                                                                        scope => $scope,
+                                                                        filter => "(&(objectclass=posixGroup)(memberuid=$user))"
+                                                                       );
+       $mesg->code && die $mesg->error;
+       foreach my $entry ($mesg->all_entries) {
          $lines.= "dn: ".$entry->dn."\n";
-      }
+       }
        $ldap_slave->unbind;
-      chomp($lines);
+       chomp($lines);
        if ($lines eq '') {
          return undef;
        }
-      return $lines;
+       return $lines;
+  }
+
+sub read_group_entry {
+  my $group = shift;
+  my $entry;
+  my %res;
+  my $ldap_slave=connect_ldap_slave();
+  my  $mesg = $ldap_slave->search ( # perform a search
+                                                                  base   => $groupsdn,
+                                                                  scope => $scope,
+                                                                  filter => "(&(objectclass=posixGroup)(cn=$group))"
+                                                                 );
+
+  $mesg->code && die $mesg->error;
+  my $nb=$mesg->count;
+  if ($nb > 1) {
+    print "Error: $nb groups exist \"cn=$group\"\n";
+    foreach $entry ($mesg->all_entries) { my $dn=$entry->dn; print "  $dn\n"; }
+    exit 11;
+  } else {
+    $entry = $mesg->shift_entry();
   }
+  return $entry;
+}
+
+sub read_group_entry_gid {
+  my $group = shift;
+  my %res;
+  my $ldap_slave=connect_ldap_slave();
+  my  $mesg = $ldap_slave->search ( # perform a search
+                                  base   => $groupsdn,
+                                  scope => $scope,
+                                  filter => "(&(objectclass=posixGroup)(gidNumber=$group))"
+                                 );
+
+  $mesg->code && die $mesg->error;
+  my $entry = $mesg->shift_entry();
+  return $entry;
+}
 
 # return the gidnumber for a group given as name or gid
 # -1 : bad group name
 # -2 : bad gidnumber
 sub parse_group
   {
-      my $userGidNumber = shift;
-      if ($userGidNumber =~ /[^\d]/ ) {
+       my $userGidNumber = shift;
+       if ($userGidNumber =~ /[^\d]/ ) {
          my $gname = $userGidNumber;
          my $gidnum = getgrnam($gname);
          if ($gidnum !~ /\d+/) {
-             return -1;
+               return -1;
          } else {
-             $userGidNumber = $gidnum;
+               $userGidNumber = $gidnum;
          }
-      } elsif (!defined(getgrgid($userGidNumber))) {
+       } elsif (!defined(getgrgid($userGidNumber))) {
          return -2;
-      }
-      return $userGidNumber;
+       }
+       return $userGidNumber;
   }
 
 # remove $user from $group
 sub group_remove_member
   {
-      my ($group, $user) = @_;
-      my $members='';
-      my $grp_line = get_group_dn($group);
-      if (!defined($grp_line)) {
+       my ($group, $user) = @_;
+       my $members='';
+       my $grp_line = get_group_dn($group);
+       if (!defined($grp_line)) {
          return 0;
-      }
+       }
        my $dn = get_dn_from_line($grp_line);
        # we test if the user exist in the group
        my $is_member=is_group_member($dn,$user);
@@ -646,40 +704,40 @@ sub group_remove_member
                                                                                  changes => [
                                                                                                          delete => [memberUid => ["$user"]]
                                                                                                         ]
-                               );
+                                                                               );
          $modify->code && die "failed to delete entry: ", $modify->error ;
          $ldap_master->unbind;
-               }
-      return 1;
+       }
+       return 1;
   }
 
 sub group_get_members
   {
-      my ($group) = @_;
-      my $members;
-      my @resultat;
-      my $grp_line = get_group_dn($group);
+       my ($group) = @_;
+       my $members;
+       my @resultat;
+       my $grp_line = get_group_dn($group);
        if (!defined($grp_line)) {
          return 0;
        }
 
-      my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
-      $ldap->bind ;
+       my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
+       $ldap->bind ;
        my  $mesg = $ldap->search (
                                                           base   => $groupsdn,
-                                    scope => $scope,
-                                    filter => "(&(objectclass=posixgroup)(cn=$group))"
-                               );
-      $mesg->code && die $mesg->error;
-      foreach my $entry ($mesg->all_entries){
-         foreach my $attr ($entry->attributes){
-             if ($attr=~/\bmemberUid\b/){
+                                                          scope => $scope,
+                                                          filter => "(&(objectclass=posixgroup)(cn=$group))"
+                                                         );
+       $mesg->code && die $mesg->error;
+       foreach my $entry ($mesg->all_entries) {
+         foreach my $attr ($entry->attributes) {
+               if ($attr=~/\bmemberUid\b/) {
                  foreach my $ent ($entry->get_value($attr)) {
                        push (@resultat,$ent);
-             }
+                 }
+               }
          }
-      }
-}
+       }
        return @resultat;
   }
 
@@ -697,5 +755,17 @@ EOF
       return $rc;
   }
 
+sub group_type_by_name {
+  my $type_name = shift;
+  my %groupmap = (
+    'domain' => 2,
+    'local' => 4,
+    'builtin' => 5
+  );
+  return $groupmap{$type_name};
+}
+
+
+
 1;