diff options
Diffstat (limited to 'examples/LDAP/smbldap-tools')
-rwxr-xr-x | examples/LDAP/smbldap-tools/smbldap-groupadd.pl | 5 | ||||
-rwxr-xr-x | examples/LDAP/smbldap-tools/smbldap-groupdel.pl | 9 | ||||
-rwxr-xr-x | examples/LDAP/smbldap-tools/smbldap-groupshow.pl | 6 | ||||
-rwxr-xr-x | examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl | 60 | ||||
-rw-r--r-- | examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl | 6 | ||||
-rwxr-xr-x | examples/LDAP/smbldap-tools/smbldap-passwd.pl | 58 | ||||
-rwxr-xr-x | examples/LDAP/smbldap-tools/smbldap-populate.pl | 45 | ||||
-rwxr-xr-x | examples/LDAP/smbldap-tools/smbldap-useradd.pl | 176 | ||||
-rwxr-xr-x | examples/LDAP/smbldap-tools/smbldap-userdel.pl | 3 | ||||
-rwxr-xr-x | examples/LDAP/smbldap-tools/smbldap-usermod.pl | 203 | ||||
-rwxr-xr-x | examples/LDAP/smbldap-tools/smbldap-usershow.pl | 5 | ||||
-rw-r--r-- | examples/LDAP/smbldap-tools/smbldap_conf.pm | 118 | ||||
-rwxr-xr-x | examples/LDAP/smbldap-tools/smbldap_tools.pm | 551 |
13 files changed, 638 insertions, 607 deletions
diff --git a/examples/LDAP/smbldap-tools/smbldap-groupadd.pl b/examples/LDAP/smbldap-tools/smbldap-groupadd.pl index ee804b34d3..91cd2dad53 100755 --- a/examples/LDAP/smbldap-tools/smbldap-groupadd.pl +++ b/examples/LDAP/smbldap-tools/smbldap-groupadd.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). @@ -23,6 +23,9 @@ # Purpose of smbldap-groupadd : group (posix) add use strict; +use FindBin; +use FindBin qw($RealBin); +use lib "$RealBin/"; use smbldap_tools; use Getopt::Std; diff --git a/examples/LDAP/smbldap-tools/smbldap-groupdel.pl b/examples/LDAP/smbldap-tools/smbldap-groupdel.pl index 3d072585b2..89d0d993ac 100755 --- a/examples/LDAP/smbldap-tools/smbldap-groupdel.pl +++ b/examples/LDAP/smbldap-tools/smbldap-groupdel.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). @@ -23,6 +23,9 @@ # Purpose of smbldap-groupdel : group (posix) deletion use strict; +use FindBin; +use FindBin qw($RealBin); +use lib "$RealBin/"; use smbldap_tools; use smbldap_conf; @@ -48,9 +51,7 @@ if (!defined($dn_line = get_group_dn($_groupName))) { my $dn = get_dn_from_line($dn_line); -my $rc = system "$ldapdelete $dn >/dev/null"; -die "$0: error while deleting group $_groupName\n" - unless ($rc == 0); +group_del($dn); my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; diff --git a/examples/LDAP/smbldap-tools/smbldap-groupshow.pl b/examples/LDAP/smbldap-tools/smbldap-groupshow.pl index bc5b4d98fb..18fe082e66 100755 --- a/examples/LDAP/smbldap-tools/smbldap-groupshow.pl +++ b/examples/LDAP/smbldap-tools/smbldap-groupshow.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). @@ -26,8 +26,10 @@ # . originally by David Le Corfec <david.le-corfec@IDEALX.com> use strict; +use FindBin; +use FindBin qw($RealBin); +use lib "$RealBin/"; use smbldap_tools; - use Getopt::Std; my %Options; diff --git a/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl b/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl index 0d0efa384c..86f52cb53e 100755 --- a/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl +++ b/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). @@ -25,10 +25,13 @@ use strict; use Getopt::Std; +use FindBin; +use FindBin qw($RealBin); +use lib "$RealBin/"; use smbldap_tools; use smbldap_conf; -# smbldap-migrate.pl (-? for help) +# smbldap-migrate.pl (-? or -h for help) # # Read pwdump entries on stdin, and add them to the ldap server. # Output uncreated/unmodified entries (see parameters -C -U) @@ -38,20 +41,19 @@ use smbldap_conf; sub modify_account { my ($login, $basedn, $lmpwd, $ntpwd, $gecos, $homedir) = @_; - - my $tmpldif = -"dn: uid=$login,$basedn -changetype: modify -lmpassword: $lmpwd -ntpassword: $ntpwd -gecos: $gecos -sambaHomePath: $homedir - -"; - - die "$0: error while modifying user $login\n" - unless (do_ldapmodify($tmpldif) == 0); - undef $tmpldif; + # 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 => [gecos => "$gecos"], + replace => [sambaHomePath => "$homedir"] + ] + ); + $modify->code && die "failed to modify entry: ", $modify->error ; + # take down the session + $ldap_master->unbind; } ##################### @@ -59,9 +61,9 @@ sambaHomePath: $homedir my %Options; -my $ok = getopts('awA:CUW:?', \%Options); +my $ok = getopts('awA:CUW:?h', \%Options); -if ( (!$ok) || ($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"; @@ -69,7 +71,7 @@ if ( (!$ok) || ($Options{'?'}) ) { 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 " -? show this help message\n"; + print " -?|-h show this help message\n"; exit (1); } @@ -81,8 +83,7 @@ my %errors = ( 'user' => 0, 'machine' => 0); my %existing = ( 'user' => 0, 'machine' => 0); my $specialskipped = 0; -while (<>) -{ +while (<>) { my ($login, $rid, $lmpwd, $ntpwd, $gecos, $homedir, $b) = split(/:/, $_); my $usertype; my $userbasedn; @@ -99,8 +100,7 @@ while (<>) $usertype = "-w $Options{'W'}"; $userbasedn = $computersdn; - } - else { # people + } else { # people $processed{'user'}++; if (defined($Options{'w'})) { print STDERR "ignoring $login\n"; @@ -124,7 +124,7 @@ while (<>) # normalize gecos if (!($gecos eq "")) { - $gecos =~ tr//AAAAaaaaCcEEEEEeeeeeIIIIiiiiNnOOOOooooUUUUuuuuYyy/; + $gecos =~ tr/ÁÀÂÄáàâäÇçÉÈÊËÆéèêëæÍÌÏÎíìîÏÑñÓÒÔÖóòôöÚÙÜÛúùüûÝýÿ/AAAAaaaaCcEEEEEeeeeeIIIIiiiiNnOOOOooooUUUUuuuuYyy/; } else { $gecos = $_userGecos; } @@ -142,25 +142,21 @@ while (<>) next; } # lem modif... a retirer si pb - if ($entry_type eq "user") - { + if ($entry_type eq "user") { modify_account($login, $userbasedn, $lmpwd, $ntpwd, $gecos, $homedir); } $created{$entry_type}++; - } - else { # uid doesn't exist and no create => log + } else { # uid doesn't exist and no create => log print "$_"; $logged{$entry_type}++; } - } - else { # account exists + } else { # account exists $existing{$entry_type}++; if (!defined($Options{'U'})) { # exists and modify modify_account($login, $userbasedn, $lmpwd, $ntpwd, $gecos, $homedir); $updated{$entry_type}++; - } - else { # exists and log + } else { # exists and log print "$_"; $logged{$entry_type}++; } diff --git a/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl b/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl index 0d3dd07d50..c60be18caf 100644 --- a/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl +++ b/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl @@ -26,6 +26,9 @@ use strict; +use FindBin; +use FindBin qw($RealBin); +use lib "$RealBin/"; use smbldap_tools; use smbldap_conf; use Getopt::Std; @@ -175,8 +178,7 @@ my $group_desc; my $has_members = 0; my @members = (); -while (<>) -{ +while (<>) { my $line = $_; chomp($line); next if ( $line =~ m/^\s*$/ ); diff --git a/examples/LDAP/smbldap-tools/smbldap-passwd.pl b/examples/LDAP/smbldap-tools/smbldap-passwd.pl index 29aee97c50..7845e5548e 100755 --- a/examples/LDAP/smbldap-tools/smbldap-passwd.pl +++ b/examples/LDAP/smbldap-tools/smbldap-passwd.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w # LDAP to unix password sync script for samba # @@ -27,6 +27,9 @@ # . may also replace /bin/passwd use strict; +use FindBin; +use FindBin qw($RealBin); +use lib "$RealBin/"; use smbldap_tools; use smbldap_conf; @@ -105,6 +108,9 @@ if ($pass ne $pass2) { exit (10); } +# First, connecting to the directory +my $ldap_master=connect_ldap_master(); + # only modify smb passwords if smb user if ($samba == 1) { if (!$with_smbpasswd) { @@ -116,25 +122,19 @@ if ($samba == 1) { my $ntpwd = `$mk_ntpasswd '$pass'`; chomp(my $sambaLMPassword = substr($ntpwd, 0, index($ntpwd, ':'))); chomp(my $sambaNTPassword = substr($ntpwd, index($ntpwd, ':')+1)); - -# change nt/lm passwords - my $tmpldif = -"$dn_line -changetype: modify -replace: sambaLMPassword -sambaLMPassword: $sambaLMPassword -- -changetype: modify -replace: sambaNTPassword -sambaNTPassword: $sambaNTPassword -- - -"; - die "$0: error while modifying password for $user\n" - unless (do_ldapmodify($tmpldif) == 0); - undef $tmpldif; - } - else { + # the sambaPwdLastSet must be updating + my $date=time; + # Let's change nt/lm passwords + my $modify = $ldap_master->modify ( "$dn", + changes => [ + replace => [sambaLMPassword => "$sambaLMPassword"], + replace => [sambaNTPassword => "$sambaNTPassword"], + replace => [sambaPwdLastSet => "$date"] + ] + ); + $modify->code && warn "failed to modify entry: ", $modify->error ; + + } else { if ($< != 0) { my $FILE="|$smbpasswd -s >/dev/null"; open (FILE, $FILE) || die "$!\n"; @@ -157,13 +157,19 @@ EOF } } } + # change unix password -$ret = system "$ldappasswd $dn -s '$pass' > /dev/null"; -if ($ret == 0) { - print "all authentication tokens updated successfully\n"; -} else { - return $ret; -} +my $hash_password = `slappasswd -h {$hash_encrypt} -s '$pass'`; +chomp($hash_password); +my $modify = $ldap_master->modify ( "$dn", + changes => [ + replace => [userPassword => "$hash_password"] + ] + ); +$modify->code && warn "Unable to change password : ", $modify->error ; + +# take down session +$ldap_master->unbind; exit 0; diff --git a/examples/LDAP/smbldap-tools/smbldap-populate.pl b/examples/LDAP/smbldap-tools/smbldap-populate.pl index 1676017c67..ce497672a9 100755 --- a/examples/LDAP/smbldap-tools/smbldap-populate.pl +++ b/examples/LDAP/smbldap-tools/smbldap-populate.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w # Populate a LDAP base for Samba-LDAP usage # @@ -27,10 +27,13 @@ # . For lazy people, replace ldapadd (with only an ldif parameter) use strict; +use FindBin; +use FindBin qw($RealBin); +use lib "$RealBin/"; use smbldap_tools; use smbldap_conf; - use Getopt::Std; +use Net::LDAP::LDIF; use vars qw(%oc); @@ -56,6 +59,7 @@ if ( (!$ok) || ($Options{'?'}) ) { } my $_ldifName; +my $tmp_ldif_file="/tmp/$$.ldif"; if (@ARGV >= 1) { $_ldifName = $ARGV[0]; @@ -76,6 +80,7 @@ if (!defined($_ldifName)) { my $val; my $objcl; + print "Using builtin directory structure\n"; if ($suffix =~ m/([^=]+)=([^,]+)/) { $attr = $1; $val = $2; @@ -90,8 +95,8 @@ if (!defined($_ldifName)) { my ($organisation,$ext) = ($suffix =~ m/dc=(\w+),dc=(\w+)$/); #my $FILE="|cat"; - my $FILE="|$ldapadd -c"; - open (FILE, $FILE) || die "$!\n"; + my $FILE=$tmp_ldif_file; + open (FILE, ">$FILE") || die "Can't open file $FILE: $!\n"; print FILE <<EOF; dn: $suffix @@ -131,11 +136,11 @@ sambaPwdMustChange: 2147483647 sambaHomePath: $_userSmbHome sambaHomeDrive: $_userHomeDrive sambaProfilePath: $_userProfile -sambaPrimaryGroupSID: 512 +sambaPrimaryGroupSID: $SID-512 sambaLMPassword: XXX sambaNTPassword: XXX sambaAcctFlags: [U ] -sambaSID: $smbldap_conf::SID-2996 +sambaSID: $SID-2996 loginShell: /bin/false gecos: Netbios Domain Administrator @@ -158,11 +163,11 @@ sambaPwdMustChange: 2147483647 sambaHomePath: $_userSmbHome sambaHomeDrive: $_userHomeDrive sambaProfilePath: $_userProfile -sambaPrimaryGroupSID: $smbldap_conf::SID-514 +sambaPrimaryGroupSID: $SID-514 sambaLMPassword: NO PASSWORDXXXXXXXXXXXXXXXXXXXXX sambaNTPassword: NO PASSWORDXXXXXXXXXXXXXXXXXXXXX sambaAcctFlags: [NU ] -sambaSID: $smbldap_conf::SID-2998 +sambaSID: $SID-2998 loginShell: /bin/false dn: cn=Domain Admins,$groupsdn @@ -248,12 +253,26 @@ description: Netbios Domain Computers accounts EOF close FILE; - exit($?) - } else { - exec "$ldapadd < $_ldifName"; + $tmp_ldif_file=$_ldifName; } +my $ldap_master=connect_ldap_master(); +my $ldif = Net::LDAP::LDIF->new($tmp_ldif_file, "r", onerror => 'undef' ); +while( not $ldif->eof() ) { + my $entry = $ldif->read_entry(); + if ( $ldif->error() ) { + print "Error msg: ",$ldif->error(),"\n"; + print "Error lines:\n",$ldif->error_lines(),"\n"; + } else { + my $dn = $entry->dn; + print "adding new entry: $dn\n"; + my $result=$ldap_master->add($entry); + $result->code && warn "failed to add entry: ", $result->error ; + } +} +$ldap_master->unbind; +system "rm -f $tmp_ldif_file"; exit(0); @@ -280,9 +299,7 @@ exit(0); If you give an extra parameter, it is assumed to be the ldif file to use instead of the builtin one. Options -a and -b - will be ignored. This usage mode makes the command behave - like ldapadd(1) with extra parameters taken from the smbldap-tools - config (smbldap_conf.pm). + will be ignored. =head1 FILES diff --git a/examples/LDAP/smbldap-tools/smbldap-useradd.pl b/examples/LDAP/smbldap-tools/smbldap-useradd.pl index 99c9525e82..a84d9f68b2 100755 --- a/examples/LDAP/smbldap-tools/smbldap-useradd.pl +++ b/examples/LDAP/smbldap-tools/smbldap-useradd.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). @@ -23,6 +23,10 @@ # Purpose of smbldap-useradd : user (posix,shadow,samba) add use strict; + +use FindBin; +use FindBin qw($RealBin); +use lib "$RealBin/"; use smbldap_tools; use smbldap_conf; @@ -31,7 +35,7 @@ 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:?', \%Options); +my $ok = getopts('axnmwPG: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"; @@ -55,6 +59,8 @@ if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { 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); } @@ -75,7 +81,9 @@ if (!defined($userUidNumber)) { $UID_START++; } $userUidNumber = $UID_START; -} elsif (getpwuid($userUidNumber)) { die "Uid already exists.\n"; } +} elsif (getpwuid($userUidNumber)) { + die "Uid already exists.\n"; +} if ($nscd_status == 0) { system "/etc/init.d/nscd start > /dev/null 2>&1"; @@ -126,6 +134,14 @@ if (defined($Options{'x'})) { # Read only first @ARGV my $userName = $ARGV[0]; +# untaint $userName (can finish with one or two $) +if ($userName =~ /^([\w -]+\$?)$/) { + $userName = $1; +} else { + print "$0: illegal username\n"; + exit (1); +} + # user must not exist in LDAP (should it be nss-wide ?) my ($rc, $dn) = get_user_dn2($userName); if ($rc and defined($dn)) { @@ -137,17 +153,24 @@ if ($rc and defined($dn)) { } my $userHomeDirectory; +my ($userCN, $userSN); my $tmp; -if (!defined($userHomeDirectory = $Options{'d'})) -{ +if (!defined($userHomeDirectory = $Options{'d'})) { $userHomeDirectory = $_userHomePrefix."/".$userName; } $_userLoginShell = $tmp if (defined($tmp = $Options{'s'})); $_userGecos = $tmp if (defined($tmp = $Options{'c'})); $_skeletonDir = $tmp if (defined($tmp = $Options{'k'})); +$userCN = ($Options{'c'} || $userName); +$userCN = $tmp if (defined($tmp = $Options{'N'})); +$userSN = $userName; +$userSN = $tmp if (defined($tmp = $Options{'S'})); + ######################## +my $ldap_master=connect_ldap_master(); + # MACHINE ACCOUNT if (defined($tmp = $Options{'w'})) { @@ -163,55 +186,47 @@ if (defined($tmp = $Options{'w'})) { } if (!$with_smbpasswd) { - if (!add_samba_machine_mkntpwd($userName, $userUidNumber)) { - die "$0: error while adding samba account\n"; - } + # (jtournier) + # Objectclass sambaSAMAccount is now added directly by samba when joigning the domain (for samba3) + #if (!add_samba_machine_mkntpwd($userName, $userUidNumber)) { + # die "$0: error while adding samba account\n"; + #} } else { if (!add_samba_machine($userName)) { die "$0: error while adding samba account\n"; } - - my $tmpldif = -"dn: uid=$userName,$computersdn -changetype: modify -sambaAcctFlags: [W ] - -"; - die "$0: error while modifying accountflags of $userName\n" - unless (do_ldapmodify($tmpldif) == 0); - undef $tmpldif; + my $modify = $ldap_master->modify ( "$dn", + changes => [ + replace => [sambaAcctFlags => '[W ]'] + ] + ); + $modify->code && warn "failed to modify entry: ", $modify->error ; } exit 0; } -####################### - # USER ACCOUNT - # add posix account first -my $tmpldif = -"dn: uid=$userName,$usersdn -objectclass: inetOrgPerson -objectclass: posixAccount -cn: $userName -sn: $userName -uid: $userName -uidNumber: $userUidNumber -gidNumber: $userGidNumber -homeDirectory: $userHomeDirectory -loginShell: $_userLoginShell -gecos: $_userGecos -description: $_userGecos -userPassword: {crypt}x - -"; +my $add = $ldap_master->add ("uid=$userName,$usersdn", + attr => [ + 'objectclass' => ['top','inetOrgPerson', 'posixAccount'], + 'cn' => "$userCN", + 'sn' => "$userSN", + 'uid' => "$userName", + 'uidNumber' => "$userUidNumber", + 'gidNumber' => "$userGidNumber", + 'homeDirectory' => "$userHomeDirectory", + 'loginShell' => "$_userLoginShell", + 'gecos' => "$_userGecos", + 'description' => "$_userGecos", + 'userPassword' => "{crypt}x" + ] + ); + +$add->code && warn "failed to add entry: ", $add->error ; -die "$0: error while adding posix user $userName\n" - unless (do_ldapadd($tmpldif) == 0); - -undef $tmpldif; #if ($createGroup) { # group_add($userName, $userGidNumber); @@ -267,28 +282,24 @@ if (defined($Options{'a'})) { $valacctflags = "$tmp"; } - my $tmpldif = -"dn: uid=$userName,$usersdn -changetype: modify -objectClass: inetOrgPerson -objectclass: posixAccount -objectClass: sambaSAMAccount -sambaPwdLastSet: 0 -sambaLogonTime: 0 -sambaLogoffTime: 2147483647 -sambaKickoffTime: 2147483647 -sambaPwdCanChange: $valpwdcanchange -sambaPwdMustChange: $valpwdmustchange -displayName: $_userGecos -sambaAcctFlags: $valacctflags -sambaSID: $smbldap_conf::SID-$userRid - -"; + + my $modify = $ldap_master->modify ( "uid=$userName,$usersdn", + changes => [ + add => [objectClass => 'sambaSAMAccount'], + add => [sambaPwdLastSet => '0'], + add => [sambaLogonTime => '0'], + add => [sambaLogoffTime => '2147483647'], + add => [sambaKickoffTime => '2147483647'], + add => [sambaPwdCanChange => "$valpwdcanchange"], + add => [sambaPwdMustChange => "$valpwdmustchange"], + add => [displayName => "$_userGecos"], + add => [sambaAcctFlags => "$valacctflags"], + add => [sambaSID => "$SID-$userRid"] + ] + ); - die "$0: error while adding samba account to posix user $userName\n" - unless (do_ldapmodify($tmpldif) == 0); + $modify->code && die "failed to add entry: ", $modify->error ; - undef $tmpldif; } else { my $FILE="|smbpasswd -s -a $userName >/dev/null" ; open (FILE, $FILE) || die "$!\n"; @@ -326,24 +337,24 @@ if (defined($tmp = $Options{'F'})) { $valprofilepath = "$tmp"; } - my $tmpldif = -"dn: uid=$userName,$usersdn -changetype: modify -sambaSID: $smbldap_conf::SID-$userRid -sambaPrimaryGroupSID: $smbldap_conf::SID-$userGroupRid -sambaHomeDrive: $valhomedrive -sambaHomePath: $valsmbhome -sambaProfilePath: $valprofilepath -sambaLogonScript: $valscriptpath -sambaLMPassword: XXX -sambaNTPassword: XXX - -"; - - die "$0: error while modifying samba account of user $userName\n" - unless (do_ldapmodify($tmpldif) == 0); - undef $tmpldif; + + my $modify = $ldap_master->modify ( "uid=$userName,$usersdn", + changes => [ + add => [sambaPrimaryGroupSID => "$SID-$userGroupRid"], + add => [sambaHomeDrive => "$valhomedrive"], + add => [sambaHomePath => "$valsmbhome"], + add => [sambaProfilePath => "$valprofilepath"], + add => [sambaLogonScript => "$valscriptpath"], + add => [sambaLMPassword => 'XXX'], + add => [sambaNTPassword => 'XXX'] + ] + ); + + $modify->code && die "failed to add entry: ", $modify->error ; + } +$ldap_master->unbind; # take down session + if (defined($Options{'P'})) { exec "/usr/local/sbin/smbldap-passwd.pl $userName" @@ -418,8 +429,8 @@ exit 0; -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 + 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 @@ -451,6 +462,11 @@ exit 0; -H sambaAcctFlags, spaces and trailing bracket are ignored (samba account control bits like '[NDHTUMWSLKI]') + -N canonical name (defaults to gecos or username, if gecos not set) + + -S surname (defaults to username) + + =head1 SEE ALSO useradd(1) diff --git a/examples/LDAP/smbldap-tools/smbldap-userdel.pl b/examples/LDAP/smbldap-tools/smbldap-userdel.pl index 435be4fdd0..1a1a3214b5 100755 --- a/examples/LDAP/smbldap-tools/smbldap-userdel.pl +++ b/examples/LDAP/smbldap-tools/smbldap-userdel.pl @@ -23,6 +23,9 @@ # Purpose of smbldap-userdel : user (posix,shadow,samba) deletion use strict; +use FindBin; +use FindBin qw($RealBin); +use lib "$RealBin/"; use smbldap_tools; diff --git a/examples/LDAP/smbldap-tools/smbldap-usermod.pl b/examples/LDAP/smbldap-tools/smbldap-usermod.pl index dffb95bace..f25c730fc8 100755 --- a/examples/LDAP/smbldap-tools/smbldap-usermod.pl +++ b/examples/LDAP/smbldap-tools/smbldap-usermod.pl @@ -23,6 +23,9 @@ # Purpose of smbldap-usermod : user (posix,shadow,samba) modification use strict; +use FindBin; +use FindBin qw($RealBin); +use lib "$RealBin/"; use smbldap_tools; use smbldap_conf; @@ -33,13 +36,13 @@ use Getopt::Std; my %Options; my $nscd_status; -my $ok = getopts('A:B:C:D:E:F:H:IJxme:f:u:g:G:d:l:s:c:ok:?', \%Options); -if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { - print "Usage: $0 [-awmugdsckxABCDEFGHI?] username\n"; +my $ok = getopts('A:B:C:D:E:F:H:IJN:S:xme: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 " -e expire date (YYYY-MM-DD)\n"; #print " -f inactive days\n"; print " -u uid\n"; print " -o uid can be non unique\n"; @@ -47,6 +50,10 @@ if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { 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 " For samba users:\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"; @@ -57,7 +64,7 @@ if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { 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 " -? show this help message\n"; + print " -?|-h show this help message\n"; exit (1); } @@ -69,30 +76,23 @@ if ($< != 0) { # Read only first @ARGV my $user = $ARGV[0]; -# Read user datas -my $lines = read_user($user); -if (!defined($lines)) { +# 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 "$lines\n"; -my $dn_line; -if ( $lines =~ /(^dn: .*)/ ) { - $dn_line = $1; -} - -chomp($dn_line); - my $samba = 0; -if ($lines =~ m/objectClass: sambaAccount/) { +if (grep ($_ =~ /^sambaSamAccount$/i, $user_entry->get_value('objectClass'))) { $samba = 1; } -############ +# get the dn of the user +my $dn= $user_entry->dn(); my $tmp; -my $mods; +my @mods; # Process options my $changed_uid; @@ -119,15 +119,15 @@ if (defined($tmp = $Options{'u'})) { } } + push(@mods, 'uidNumber', $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); } - $mods .= "uidNumber: $_userUidNumber\n"; - if ($samba) { - $mods .= "rid: $_userRid\n"; + push(@mods, 'sambaSID', $SID.'-'.$_userRid); } $changed_uid = 1; } @@ -141,42 +141,42 @@ if (defined($tmp = $Options{'g'})) { 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); } - $mods .= "gidNumber: $_userGidNumber\n"; - if ($samba) { - $mods .= "primaryGroupID: $_userGroupRid\n"; + push(@mods, 'sambaPrimaryGroupSid', $SID.'-'.$_userGroupRid); } $changed_gid = 1; } -my $changed_shell; -my $_userLoginShell; if (defined($tmp = $Options{'s'})) { - $_userLoginShell = $tmp; - $mods .= "loginShell: $_userLoginShell\n"; - $changed_shell = 1; + push(@mods, 'loginShell' => $tmp); } -my $changed_gecos; -my $_userGecos; + if (defined($tmp = $Options{'c'})) { - $_userGecos = $tmp; - $mods .= "gecos: $_userGecos\n"; - $changed_gecos = 1; + push(@mods, 'gecos' => $tmp, + 'description' => $tmp); + if ($samba == 1) { + push(@mods, 'displayName' => $tmp); + } } -my $changed_homedir; -my $newhomedir; if (defined($tmp = $Options{'d'})) { - $newhomedir = $tmp; - $mods .= "homeDirectory: $newhomedir\n"; - $changed_homedir = 1; + push(@mods, 'homeDirectory' => $tmp); } +if (defined($tmp = $Options{'N'})) { + push(@mods, 'cn' => $tmp); +} + +if (defined($tmp = $Options{'S'})) { + push(@mods, 'sn' => $tmp); +} if (defined($tmp = $Options{'G'})) { @@ -212,102 +212,135 @@ if (defined($tmp = $Options{'G'})) { my $attr; my $winmagic = 2147483647; +my $samba = is_samba_user($user); + +if (defined($tmp = $Options{'e'})) { + if ($samba == 1) { + my $kickoffTime=`date --date='$tmp' +%s`; + chomp($kickoffTime); + push(@mods, 'sambakickoffTime' => $kickoffTime); + } else { + print "User $user is not a samba user\n"; + } +} + +my $_sambaPwdCanChange; if (defined($tmp = $Options{'A'})) { + if ($samba == 1) { $attr = "sambaPwdCanChange"; if ($tmp != 0) { - $mods .= "$attr: 0\n"; + $_sambaPwdCanChange=0; } else { - $mods .= "$attr: $winmagic\n"; + $_sambaPwdCanChange=$winmagic; + } + push(@mods, 'sambaPwdCanChange' => $_sambaPwdCanChange); + } else { + print "User $user is not a samba user\n"; } } +my $_sambaPwdMustChange; if (defined($tmp = $Options{'B'})) { - $attr = "sambaPwdMustChange"; + if ($samba == 1) { if ($tmp != 0) { - $mods .= "$attr: 0\n"; + $_sambaPwdMustChange=0; + } else { + $_sambaPwdMustChange=$winmagic; + } + push(@mods, 'sambaPwdMustChange' => $_sambaPwdMustChange); } else { - $mods .= "$attr: $winmagic\n"; + print "User $user is not a samba user\n"; } } if (defined($tmp = $Options{'C'})) { - $attr = "sambaHomePath"; + if ($samba == 1) { #$tmp =~ s/\\/\\\\/g; - $mods .= "$attr: $tmp\n"; + push(@mods, 'sambaHomePath' => $tmp); + } else { + print "User $user is not a samba user\n"; + } } +my $_sambaHomeDrive; if (defined($tmp = $Options{'D'})) { - $attr = "sambaHomeDrive"; + if ($samba == 1) { $tmp = $tmp.":" unless ($tmp =~ /:/); - $mods .= "$attr: $tmp\n"; + push(@mods, 'sambaHomeDrive' => $tmp); + } else { + print "User $user is not a samba user\n"; + } } if (defined($tmp = $Options{'E'})) { - $attr = "sambaLogonScript"; + if ($samba == 1) { #$tmp =~ s/\\/\\\\/g; - $mods .= "$attr: $tmp\n"; + push(@mods, 'sambaLogonScript' => $tmp); + } else { + print "User $user is not a samba user\n"; + } } if (defined($tmp = $Options{'F'})) { - $attr = "sambaProfilePath"; + if ($samba == 1) { #$tmp =~ s/\\/\\\\/g; - $mods .= "$attr: $tmp\n"; + push(@mods, 'sambaProfilePath' => $tmp); + } else { + print "User $user is not a samba user\n"; + } } +if ($samba == 1 and (defined $Options{'H'} or defined $Options{'I'} or defined $Options{'J'})) { + my $_sambaAcctFlags; if (defined($tmp = $Options{'H'})) { - $attr = "sambaAcctFlags"; #$tmp =~ s/\\/\\\\/g; - $mods .= "$attr: $tmp\n"; -} elsif (defined($tmp = $Options{'I'})) { + $_sambaAcctFlags=$tmp; + } else { + # I or J my $flags; + $flags = $user_entry->get_value('sambaAcctFlags'); - if ( $lines =~ /^sambaAcctFlags: (.*)/m ) { - $flags = $1; - } - - chomp($flags); - + if (defined($tmp = $Options{'I'})) { if ( !($flags =~ /D/) ) { my $letters; if ($flags =~ /(\w+)/) { $letters = $1; } - $mods .= "sambaAcctFlags: \[D$letters\]\n"; + $_sambaAcctFlags="\[D$letters\]"; } } elsif (defined($tmp = $Options{'J'})) { - my $flags; - - if ( $lines =~ /^sambaAcctFlags: (.*)/m ) { - $flags = $1; - } - - chomp($flags); - if ( $flags =~ /D/ ) { my $letters; if ($flags =~ /(\w+)/) { $letters = $1; } $letters =~ s/D//; - $mods .= "sambaAcctFlags: \[$letters\]\n"; + $_sambaAcctFlags="\[$letters\]"; + } } } -if ($mods ne '') { - #print "----\n$dn_line\n$mods\n----\n"; - - my $tmpldif = -"$dn_line -changetype: modify -$mods -"; - die "$0: error while modifying user $user\n" - unless (do_ldapmodify($tmpldif) == 0); + if ("$_sambaAcctFlags" ne '') { + push(@mods, 'sambaAcctFlags' => $_sambaAcctFlags); + } - undef $tmpldif; +} elsif (!$samba == 1 and (defined $Options{'H'} or defined $Options{'I'} or defined $Options{'J'})) { + print "User $user is not a samba user\n"; } +# Let's connect to the directory first +my $ldap_master=connect_ldap_master(); + +# apply changes +my $modify = $ldap_master->modify ( "$dn", + 'replace' => { @mods } + ); +$modify->code && warn "failed to modify 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) { @@ -358,7 +391,7 @@ 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 + Nothing else is changed. In particular, the user's home direc tory name should probably be changed to reflect the new login name. @@ -369,7 +402,7 @@ if ($nscd_status == 0) { -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 + located in the directory tree rooted at the user's home direc tory will have the file user ID changed automatically. Files outside of the user's home directory must be altered manually. diff --git a/examples/LDAP/smbldap-tools/smbldap-usershow.pl b/examples/LDAP/smbldap-tools/smbldap-usershow.pl index b05f087620..555b35ffd8 100755 --- a/examples/LDAP/smbldap-tools/smbldap-usershow.pl +++ b/examples/LDAP/smbldap-tools/smbldap-usershow.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). @@ -23,6 +23,9 @@ # Purpose of smbldap-userdisplay : user (posix,shadow,samba) display use strict; +use FindBin; +use FindBin qw($RealBin); +use lib "$RealBin/"; use smbldap_tools; use Getopt::Std; diff --git a/examples/LDAP/smbldap-tools/smbldap_conf.pm b/examples/LDAP/smbldap-tools/smbldap_conf.pm index dd1d772ea7..c3d5c1732c 100644 --- a/examples/LDAP/smbldap-tools/smbldap_conf.pm +++ b/examples/LDAP/smbldap-tools/smbldap_conf.pm @@ -30,16 +30,14 @@ package smbldap_conf; 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 $ldapsearch $ldapsearchnobind -$ldapmodify $ldappasswd $ldapadd $ldapdelete $ldapmodrdn -$suffix $usersdn $computersdn +$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 +$_userScript $usersou $computersou $groupsou $SID $hash_encrypt ); use Exporter; @@ -49,14 +47,13 @@ $VERSION = 1.00; @EXPORT = qw( $UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP $slavePort $masterPort $ldapSSL $slaveURI $masterURI $with_smbpasswd $mk_ntpasswd -$ldap_path $ldap_opts $ldapsearch $ldapsearchnobind $ldapmodify $ldappasswd -$ldapadd $ldapdelete $ldapmodrdn $suffix $usersdn +$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 +$usersou $computersou $groupsou $SID $hash_encrypt ); @@ -66,16 +63,13 @@ $usersou $computersou $groupsou # ############################################################################## -# # UID and GID starting at... -# - $UID_START = 1000; $GID_START = 1000; # Put your own SID -# to obtain this number do: # net getlocalsid -our $SID='S-1-5-21-636805976-1992644568-3666589737'; +# to obtain this number do: "net getlocalsid" +$SID='S-1-5-21-3516781642-1962875130-3438800523'; ############################################################################## # @@ -86,84 +80,65 @@ our $SID='S-1-5-21-636805976-1992644568-3666589737'; # Notes: to use to dual ldap servers backend for Samba, you must patch # Samba with the dual-head patch from IDEALX. If not using this patch # just use the same server for slaveLDAP and masterLDAP. -# -# Slave LDAP : needed for read operations -# +# Those two servers declarations can also be used when you have +# . one master LDAP server where all writing operations must be done +# . one slave LDAP server where all reading operations must be done +# (typically a replication directory) + # Ex: $slaveLDAP = "127.0.0.1"; $slaveLDAP = "127.0.0.1"; - $slavePort = "389"; -# # Master LDAP : needed for write operations -# # Ex: $masterLDAP = "127.0.0.1"; $masterLDAP = "127.0.0.1"; - - -# -# Master Port -# 389 636 -# Ex: $masterPort = " $masterPort = "389"; -# # Use SSL for LDAP -# +# If set to "1", this option will use start_tls for connection +# (you should also used the port 389) $ldapSSL = "0"; -# # LDAP Suffix -# # Ex: $suffix = "dc=IDEALX,dc=ORG"; $suffix = "dc=IDEALX,dc=ORG"; -# # Where are stored Users -# # Ex: $usersdn = "ou=Users,$suffix"; for ou=Users,dc=IDEALX,dc=ORG $usersou = q(_USERS_); - $usersdn = "ou=$usersou,$suffix"; -# # Where are stored Computers -# # Ex: $computersdn = "ou=Computers,$suffix"; for ou=Computers,dc=IDEALX,dc=ORG $computersou = q(_COMPUTERS_); - $computersdn = "ou=$computersou,$suffix"; -# # Where are stored Groups -# # Ex $groupsdn = "ou=Groups,$suffix"; for ou=Groups,dc=IDEALX,dc=ORG $groupsou = q(_GROUPS_); - $groupsdn = "ou=$groupsou,$suffix"; -# # Default scope Used -# $scope = "sub"; -# -# Credential Configuration -# +# Unix password encryption (CRYPT, MD5, SMD5, SSHA, SHA) +$hash_encrypt="SSHA"; + +############################ +# Credential Configuration # +############################ # Bind DN used # Ex: $binddn = "cn=Manager,$suffix"; for cn=Manager,dc=IDEALX,dc=org $binddn = "cn=Manager,$suffix"; -# + # Bind DN passwd used # Ex: $bindpasswd = 'secret'; for 'secret' $bindpasswd = "secret"; -# # Notes: if using dual ldap patch, you can specify to different configuration # By default, we will use the same DN (so it will work for standard Samba # release) -# $slaveDN = $binddn; $slavePw = $bindpasswd; $masterDN = $binddn; @@ -176,36 +151,24 @@ $masterPw = $bindpasswd; ############################################################################## # Login defs -# # Default Login Shell -# # Ex: $_userLoginShell = q(/bin/bash); $_userLoginShell = q(_LOGINSHELL_); -# # Home directory prefix (without username) -# #Ex: $_userHomePrefix = q(/home/); $_userHomePrefix = q(_HOMEPREFIX_); -# # Gecos -# $_userGecos = q(System User); -# # Default User (POSIX and Samba) GID -# -$_defaultUserGid = 100; +$_defaultUserGid = 513; -# # Default Computer (Samba) GID -# $_defaultComputerGid = 553; -# # Skel dir -# $_skeletonDir = q(/etc/skel); ############################################################################## @@ -214,28 +177,23 @@ $_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 $_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 +# Ex: q(\\\\My-PDC-netbios-name\\profiles\\) for \\My-PDC-netbios-name\profiles $_userProfile = q(\\\\_PDCNAME_\\profiles\\); -# # The default Home Drive Letter mapping # (will be automatically mapped at logon time if home directory exist) # Ex: q(U:) for U: $_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 @@ -251,28 +209,28 @@ $with_smbpasswd = 0; $smbpasswd = "/usr/bin/smbpasswd"; $mk_ntpasswd = "/usr/local/sbin/mkntpwd"; -if ( $ldapSSL eq "0" ) { +# 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"; -} -elsif ( $ldapSSL eq "1" ) { - $slaveURI = "ldaps://$slaveLDAP:$slavePort"; - $masterURI = "ldaps://$masterLDAP:$masterPort"; -} -else { - die "ldapSSL option must be either 0 or 1.\n"; -} - $ldap_path = "/usr/bin"; + +if ( $ldapSSL eq "0" ) { $ldap_opts = "-x"; -$ldapsearch = "$ldap_path/ldapsearch $ldap_opts -H $slaveURI -D '$slaveDN' -w '$slavePw'"; -$ldapsearchnobind = "$ldap_path/ldapsearch $ldap_opts -H $slaveURI"; +} elsif ( $ldapSSL eq "1" ) { + $ldap_opts = "-x -Z"; +} else { + die "ldapSSL option must be either 0 or 1.\n"; +} + +#$ldapsearch = "$ldap_path/ldapsearch $ldap_opts -H $slaveURI -D '$slaveDN' -w '$slavePw'"; +#$ldapsearchnobind = "$ldap_path/ldapsearch $ldap_opts -H $slaveURI"; $ldapmodify = "$ldap_path/ldapmodify $ldap_opts -H $masterURI -D '$masterDN' -w '$masterPw'"; -$ldappasswd = "$ldap_path/ldappasswd $ldap_opts -H $masterURI -D '$masterDN' -w '$masterPw'"; -$ldapadd = "$ldap_path/ldapadd $ldap_opts -H $masterURI -D '$masterDN' -w '$masterPw'"; -$ldapdelete = "$ldap_path/ldapdelete $ldap_opts -H $masterURI -D '$masterDN' -w '$masterPw'"; -$ldapmodrdn = "$ldap_path/ldapmodrdn $ldap_opts -H $masterURI -D '$masterDN' -w '$masterPw'"; +#$ldappasswd = "$ldap_path/ldappasswd $ldap_opts -H $masterURI -D '$masterDN' -w '$masterPw'"; +#$ldapadd = "$ldap_path/ldapadd $ldap_opts -H $masterURI -D '$masterDN' -w '$masterPw'"; +#$ldapdelete = "$ldap_path/ldapdelete $ldap_opts -H $masterURI -D '$masterDN' -w '$masterPw'"; +#$ldapmodrdn = "$ldap_path/ldapmodrdn $ldap_opts -H $masterURI -D '$masterDN' -w '$masterPw'"; diff --git a/examples/LDAP/smbldap-tools/smbldap_tools.pm b/examples/LDAP/smbldap-tools/smbldap_tools.pm index ad6ef74eb6..8001442fe8 100755 --- a/examples/LDAP/smbldap-tools/smbldap_tools.pm +++ b/examples/LDAP/smbldap-tools/smbldap_tools.pm @@ -1,4 +1,4 @@ -#! /usr/bin/perl +#! /usr/bin/perl -w use strict; package smbldap_tools; use smbldap_conf; @@ -36,7 +36,9 @@ $VERSION = 1.00; @EXPORT = qw( get_user_dn get_group_dn + is_group_member is_samba_user + is_unix_user is_user_valid get_dn_from_line add_posix_machine @@ -47,8 +49,10 @@ add_grouplist_user disable_user delete_user group_add + group_del get_homedir read_user + read_user_entry read_group find_groups_of parse_group @@ -57,32 +61,74 @@ group_get_members do_ldapadd do_ldapmodify get_user_dn2 + connect_ldap_master + connect_ldap_slave ); -# dn_line = get_user_dn($username) -# where dn_line is like "dn: a=b,c=d" - -#sub ldap_search -#{ -#my ($local_base,$local_scope,$local_filtre)=@_; -#} - +sub connect_ldap_master + { + # bind to a directory with dn and password + my $ldap_master = Net::LDAP->new( + "$masterLDAP", + port => "$masterPort", + version => 3, + # debug => 0xffff, + ) + or die "erreur LDAP: Can't contact master ldap server ($@)"; + if ($ldapSSL == 1) { + $ldap_master->start_tls( + # verify => 'require', + # clientcert => 'mycert.pem', + # clientkey => 'mykey.pem', + # decryptkey => sub { 'secret'; }, + # capath => '/usr/local/cacerts/' + ); + } + $ldap_master->bind ( "$binddn", + password => "$masterPw" + ); + return($ldap_master); + } +sub connect_ldap_slave + { + # bind to a directory with dn and password + my $ldap_slave = Net::LDAP->new( + "$slaveLDAP", + port => "$slavePort", + version => 3, + # debug => 0xffff, + ) + or die "erreur LDAP: Can't contact slave ldap server ($@)"; + if ($ldapSSL == 1) { + $ldap_slave->start_tls( + # verify => 'require', + # clientcert => 'mycert.pem', + # clientkey => 'mykey.pem', + # decryptkey => sub { 'secret'; }, + # capath => '/usr/local/cacerts/' + ); + } + $ldap_slave->bind ( "$binddn", + password => "$slavePw" + ); + return($ldap_slave); + } sub get_user_dn { my $user = shift; my $dn=''; - my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; - $ldap->bind ; - my $mesg = $ldap->search ( base => $suffix, + 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) { - $dn= $entry->dn;} - $ldap->unbind; + $dn= $entry->dn; + } + $ldap_slave->unbind; chomp($dn); if ($dn eq '') { return undef; @@ -92,28 +138,21 @@ sub get_user_dn } -sub get_user_dn2 ## migr +sub get_user_dn2 { my $user = shift; my $dn=''; - my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; - $ldap->bind ; - my $mesg = $ldap->search ( base => $suffix, + my $ldap_slave=connect_ldap_slave(); + my $mesg = $ldap_slave->search ( base => $suffix, scope => $scope, filter => "(&(objectclass=posixAccount)(uid=$user))" ); - # $mesg->code && warn $mesg->error; - if ($mesg->code) - { - print("Code erreur : ",$mesg->code,"\n"); - print("Message d'erreur : ",$mesg->error,"\n"); - return (0,undef); - } + $mesg->code && warn "failed to perform search; ", $mesg->error; foreach my $entry ($mesg->all_entries) { $dn= $entry->dn; } - $ldap->unbind; + $ldap_slave->unbind; chomp($dn); if ($dn eq '') { return (1,undef); @@ -127,16 +166,16 @@ sub get_group_dn { my $group = shift; my $dn=''; - my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; - $ldap->bind ; - my $mesg = $ldap->search ( base => $groupsdn, + 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) { - $dn= $entry->dn;} - $ldap->unbind; + $dn= $entry->dn; + } + $ldap_slave->unbind; chomp($dn); if ($dn eq '') { return undef; @@ -150,14 +189,41 @@ sub get_group_dn sub is_samba_user { my $user = shift; - my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; - $ldap->bind ; - my $mesg = $ldap->search ( base => $suffix, + 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; - $ldap->unbind; + $ldap_slave->unbind; + return ($mesg->count ne 0); + } + +sub is_unix_user + { + my $user = shift; + 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; + $ldap_slave->unbind; + return ($mesg->count ne 0); + } + +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", + scope => 'base', + filter => "(&(memberUid=$user))" + ); + $mesg->code && die $mesg->error; + $ldap_slave->unbind; return ($mesg->count ne 0); } @@ -168,21 +234,19 @@ 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 ); - if ($mesg->code eq 0) - { + if ($mesg->code eq 0) { $ldap->unbind; return 1; - } - else - { + } else { if($ldap->bind()) { $ldap->unbind; return 0; } else { - print ("Le serveur LDAP est indisponible.\nVrifier le serveur, les cblages, ..."); + print ("The LDAP directory is not available.\n Check the server, cables ..."); $ldap->unbind; return 0; - } die "Problme : Contacter votre administrateur"; + } + die "Problem : contact your administrator"; } } @@ -199,27 +263,29 @@ sub get_dn_from_line sub add_posix_machine { my ($user, $uid, $gid) = @_; - my $tmpldif = - "dn: uid=$user,$computersdn -objectclass: inetOrgPerson -objectclass: posixAccount -sn: $user -cn: $user -uid: $user -uidNumber: $uid -gidNumber: $gid -homeDirectory: /dev/null -loginShell: /bin/false -description: Computer - -"; - - die "$0: error while adding posix account to machine $user\n" - unless (do_ldapadd($tmpldif) == 0); - undef $tmpldif; - return 1; + # bind to a directory with dn and password + my $ldap_master=connect_ldap_master(); + my $add = $ldap_master->add ( "uid=$user,$computersdn", + attr => [ + 'objectclass' => ['top','inetOrgPerson', 'posixAccount'], + 'cn' => "$user", + 'sn' => "$user", + 'uid' => "$user", + 'uidNumber' => "$uid", + 'gidNumber' => "$gid", + 'homeDirectory' => '/dev/null', + 'loginShell' => '/bin/false', + 'description' => 'Computer', + ] + ); + + $add->code && warn "failed to add entry: ", $add->error ; + # take down the session + $ldap_master->unbind; + } + # success = add_samba_machine($computername) sub add_samba_machine { @@ -244,33 +310,31 @@ sub add_samba_machine_mkntpwd chomp(my $lmpassword = substr($ntpwd, 0, index($ntpwd, ':'))); chomp(my $ntpassword = substr($ntpwd, index($ntpwd, ':')+1)); - my $tmpldif = - "dn: uid=$user,$computersdn -changetype: modify -objectclass: inetOrgPerson -objectclass: posixAccount -objectClass: sambaSamAccount -sambaPwdLastSet: 0 -sambaLogonTime: 0 -sambaLogoffTime: 2147483647 -sambaKickoffTime: 2147483647 -sambaPwdCanChange: 0 -sambaPwdMustChange: 2147483647 -sambaAcctFlags: [W ] -sambaLMPassword: $lmpassword -sambaNTPassword: $ntpassword -sambaSID: $smbldap_conf::SID-$sambaSID -sambaPrimaryGroupSID: $smbldap_conf::SID-0 - -"; - - die "$0: error while adding samba account to $user\n" - unless (do_ldapmodify($tmpldif) == 0); - undef $tmpldif; + my $ldap_master=connect_ldap_master(); + my $modify = $ldap_master->modify ( "uid=$user,$computersdn", + changes => [ + replace => [objectClass => ['inetOrgPerson', 'posixAccount', 'sambaSAMAccount']], + add => [sambaPwdLastSet => '0'], + add => [sambaLogonTime => '0'], + add => [sambaLogoffTime => '2147483647'], + add => [sambaKickoffTime => '2147483647'], + add => [sambaPwdCanChange => '0'], + add => [sambaPwdMustChange => '0'], + add => [sambaAcctFlags => '[W ]'], + add => [sambaLMPassword => "$lmpassword"], + add => [sambaNTPassword => "$ntpassword"], + add => [sambaSID => "$SID-$sambaSID"], + add => [sambaPrimaryGroupSID => "$SID-0"] + ] + ); + + $modify->code && die "failed to add entry: ", $modify->error ; return 1; - } + # take down the session + $ldap_master->unbind; + } sub group_add_user @@ -278,55 +342,43 @@ sub group_add_user 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)) { return 1; } - my $dn = get_dn_from_line($dn_line); - - my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; - $ldap->bind ; - my $mesg = $ldap->search ( base =>$dn, scope => "base", filter => "(objectClass=*)" ); - $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)) { $members.= $attr.": ".$ent."\n"; } - } + 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); + if ($is_member == 1) { + print "User \"$userid\" already member of the group \"$group\".\n"; + } else { + # bind to a directory with dn and password + my $ldap_master=connect_ldap_master(); + # It does not matter if the user already exist, Net::LDAP will add the user + # if he does not exist, and ignore him if his already in the directory. + my $modify = $ldap_master->modify ( "$dn", + changes => [ + add => [memberUid => $userid] + ] + ); + $modify->code && die "failed to modify entry: ", $modify->error ; + # take down session + $ldap_master->unbind; } } - $ldap->unbind; - chomp($members); - # user already member ? - if ($members =~ m/^memberUid: $userid/) { - return 2; - } - my $mods = ""; - if ($members ne '') { - $mods="$dn_line -changetype: modify -replace: memberUid -$members -memberUid: $userid - -"; - } else { - $mods="$dn_line -changetype: modify -add: memberUid -memberUid: $userid -"; - } - #print "$mods\n"; - my $tmpldif = - "$mods -"; - - die "$0: error while modifying group $group\n" - unless (do_ldapmodify($tmpldif) == 0); - undef $tmpldif; - return 0; +sub group_del + { + my $group_dn=shift; + # bind to a directory with dn and password + my $ldap_master=connect_ldap_master(); + my $modify = $ldap_master->delete ($group_dn); + $modify->code && die "failed to delete group : ", $modify->error ; + # take down session + $ldap_master->unbind; } sub add_grouplist_user @@ -338,43 +390,34 @@ sub add_grouplist_user } } -# XXX FIXME : sambaAcctFlags |= D, and not sambaAcctFlags = D sub disable_user { my $user = shift; my $dn_line; + my $dn = get_dn_from_line($dn_line); if (!defined($dn_line = get_user_dn($user))) { print "$0: user $user doesn't exist\n"; exit (10); } - - my $tmpldif = - "dn: $dn_line -changetype: modify -replace: userPassword -userPassword: {crypt}!x - -"; - - die "$0: error while modifying user $user\n" - unless (do_ldapmodify($tmpldif) == 0); - undef $tmpldif; + my $ldap_master=connect_ldap_master(); + my $modify = $ldap_master->modify ( "$dn", + changes => [ + replace => [userPassword => '{crypt}!x'] + ] + ); + $modify->code && die "failed to modify entry: ", $modify->error ; if (is_samba_user($user)) { - - my $tmpldif = - "dn: $dn_line -changetype: modify -replace: sambaAcctFlags -sambaAcctFlags: [D ] - -"; - - die "$0: error while modifying user $user\n" - unless (do_ldapmodify($tmpldif) == 0); - undef $tmpldif; + 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; } # delete_user($user) @@ -389,7 +432,9 @@ sub delete_user } my $dn = get_dn_from_line($dn_line); - system "$ldapdelete $dn >/dev/null"; + 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) @@ -415,17 +460,18 @@ sub group_add if ($nscd_status == 0) { system "/etc/init.d/nscd start > /dev/null 2>&1"; } - my $tmpldif = - "dn: cn=$gname,$groupsdn -objectclass: posixGroup -cn: $gname -gidNumber: $gid - -"; - - die "$0: error while adding posix group $gname\n" - unless (do_ldapadd($tmpldif) == 0); - undef $tmpldif; + my $ldap_master=connect_ldap_master(); + my $modify = $ldap_master->add ( "cn=$gname,$groupsdn", + attrs => [ + objectClass => 'posixGroup', + cn => "$gname", + gidNumber => "$gid" + ] + ); + + $modify->code && die "failed to add entry: ", $modify->error ; + # take down session + $ldap_master->unbind; return 1; } @@ -434,14 +480,15 @@ sub get_homedir { my $user = shift; my $homeDir=''; - # my $homeDir=`$ldapsearch -b '$suffix' -s '$scope' '(&(objectclass=posixAccount)(uid=$user))' | grep "^homeDirectory:"`; - my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; - $ldap->bind ; - my $mesg = $ldap->search ( base =>$suffix, scope => $scope, filter => "(&(objectclass=posixAccount)(uid=$user))" ); + 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){ - foreach my $attr ($entry->attributes) - { + foreach my $attr ($entry->attributes) { if ($attr=~/\bhomeDirectory\b/){ foreach my $ent($entry->get_value($attr)) { $homeDir.= $attr.": ".$ent."\n"; @@ -449,7 +496,7 @@ sub get_homedir } } } - $ldap->unbind; + $ldap_slave->unbind; chomp $homeDir; if ($homeDir eq '') { return undef; @@ -463,9 +510,8 @@ sub read_user { my $user = shift; my $lines =''; - my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; - $ldap->bind ; - my $mesg = $ldap->search ( # perform a search + my $ldap_slave=connect_ldap_slave(); + my $mesg = $ldap_slave->search ( # perform a search base => $suffix, scope => $scope, filter => "(&(objectclass=posixAccount)(uid=$user))" @@ -480,7 +526,8 @@ sub read_user } } } - $ldap->unbind; # take down sessio(n + # take down session + $ldap_slave->unbind; chomp $lines; if ($lines eq '') { return undef; @@ -488,14 +535,31 @@ sub read_user return $lines; } +# search for a user +# return the attributes in an array +sub read_user_entry + { + my $user = shift; + my $ldap_slave=connect_ldap_slave(); + my $mesg = $ldap_slave->search ( # perform a search + base => $suffix, + scope => $scope, + filter => "(&(objectclass=posixAccount)(uid=$user))" + ); + + $mesg->code && die $mesg->error; + my $entry = $mesg->entry(); + $ldap_slave->unbind; + return $entry; + } + # search for a group sub read_group { my $user = shift; my $lines =''; - my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; - $ldap->bind ; - my $mesg = $ldap->search ( # perform a search + my $ldap_slave=connect_ldap_slave(); + my $mesg = $ldap_slave->search ( # perform a search base => $groupsdn, scope => $scope, filter => "(&(objectclass=posixGroup)(cn=$user))" @@ -510,8 +574,8 @@ sub read_group } } } - - $ldap->unbind; # take down sessio(n + # take down session + $ldap_slave->unbind; chomp $lines; if ($lines eq '') { return undef; @@ -525,9 +589,8 @@ sub find_groups_of { my $user = shift; my $lines =''; - my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; - $ldap->bind ; - my $mesg = $ldap->search ( # perform a search + my $ldap_slave=connect_ldap_slave; + my $mesg = $ldap_slave->search ( # perform a search base => $groupsdn, scope => $scope, filter => "(&(objectclass=posixGroup)(memberuid=$user))" @@ -536,9 +599,11 @@ sub find_groups_of foreach my $entry ($mesg->all_entries) { $lines.= "dn: ".$entry->dn."\n"; } - $ldap->unbind; + $ldap_slave->unbind; chomp($lines); - if ($lines eq '') {return undef; } + if ($lines eq '') { + return undef; + } return $lines; } @@ -571,53 +636,20 @@ sub group_remove_member if (!defined($grp_line)) { return 0; } - - 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))" + 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); + if ($is_member == 1) { + my $ldap_master=connect_ldap_master(); + # delete only the user from the group + my $modify = $ldap_master->modify ( "$dn", + changes => [ + delete => [memberUid => ["$user"]] + ] ); - $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)) { - $members.= $attr.": ".$ent."\n"; - } + $modify->code && die "failed to delete entry: ", $modify->error ; + $ldap_master->unbind; } - } - } - #print "Valeurs de members :\n$members"; - $ldap->unbind; - # my $members = `$ldapsearch -b '$groupsdn' -s '$scope' '(&(objectclass=posixgroup)(cn=$group))' | grep -i "^memberUid:"`; - # print "avant ---\n$members\n"; - $members =~ s/memberUid: $user\n//; - #print "aprs ---\n$members\n"; - chomp($members); - - my $header; - if ($members eq '') { - $header = "changetype: modify\n"; - $header .= "delete: memberUid"; - } else { - $header = "changetype: modify\n"; - $header .= "replace: memberUid"; - } - - my $tmpldif = -"$grp_line -$header -$members -"; - - #print "Valeur du tmpldif : \n$tmpldif"; - die "$0: error while modifying group $group\n" - unless (do_ldapmodify($tmpldif) == 0); - undef $tmpldif; - - $ldap->unbind; return 1; } @@ -627,11 +659,14 @@ sub group_get_members my $members; my @resultat; my $grp_line = get_group_dn($group); - if (!defined($grp_line)) { return 0; } + if (!defined($grp_line)) { + return 0; + } my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; $ldap->bind ; - my $mesg = $ldap->search ( base => $groupsdn, + my $mesg = $ldap->search ( + base => $groupsdn, scope => $scope, filter => "(&(objectclass=posixgroup)(cn=$group))" ); @@ -639,57 +674,13 @@ sub group_get_members 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); } + foreach my $ent ($entry->get_value($attr)) { + push (@resultat,$ent); } } } - return @resultat; - } - -sub file_write { - my ($filename, $filecontent) = @_; - local *FILE; - open (FILE, "> $filename") || - die "Cannot open $filename for writing: $!\n"; - print FILE $filecontent; - close FILE; } - -# wrapper for ldapadd -sub do_ldapadd2 - { - my $ldif = shift; - my $tempfile = "/tmp/smbldapadd.$$"; - file_write($tempfile, $ldif); - - my $rc = system "$ldapadd < $tempfile >/dev/null"; - unlink($tempfile); - return $rc; - } - -sub do_ldapadd - { - my $ldif = shift; - my $FILE = "|$ldapadd >/dev/null"; - open (FILE, $FILE) || die "$!\n"; - print FILE <<EOF; -$ldif -EOF - ; - close FILE; - my $rc = $?; - return $rc; - } - -# wrapper for ldapmodify -sub do_ldapmodify2 - { - my $ldif = shift; - my $tempfile = "/tmp/smbldapmod.$$"; - file_write($tempfile, $ldif); - my $rc = system "$ldapmodify -r < $tempfile >/dev/null"; - unlink($tempfile); - return $rc; + return @resultat; } sub do_ldapmodify |