7 # This code was developped by IDEALX (http://IDEALX.org/) and
8 # contributors (their names can be found in the CONTRIBUTORS file).
10 # Copyright (C) 2001-2002 IDEALX
12 # This program is free software; you can redistribute it and/or
13 # modify it under the terms of the GNU General Public License
14 # as published by the Free Software Foundation; either version 2
15 # of the License, or (at your option) any later version.
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU General Public License for more details.
22 # You should have received a copy of the GNU General Public License
23 # along with this program; if not, write to the Free Software
24 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28 # ugly funcs using global variables and spawning openldap clients
30 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
44 add_samba_machine_mkntpwd
62 # dn_line = get_user_dn($username)
63 # where dn_line is like "dn: a=b,c=d"
67 #my ($local_base,$local_scope,$local_filtre)=@_;
76 my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
78 my $mesg = $ldap->search ( base => $suffix,
80 filter => "(&(objectclass=posixAccount)(uid=$user))"
82 $mesg->code && die $mesg->error;
83 foreach my $entry ($mesg->all_entries) {
95 sub get_user_dn2 ## migré
99 my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
101 my $mesg = $ldap->search ( base => $suffix,
103 filter => "(&(objectclass=posixAccount)(uid=$user))"
105 # $mesg->code && warn $mesg->error;
108 print("Code erreur : ",$mesg->code,"\n");
109 print("Message d'erreur : ",$mesg->error,"\n");
113 foreach my $entry ($mesg->all_entries) {
130 my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
132 my $mesg = $ldap->search ( base => $groupsdn,
134 filter => "(&(objectclass=posixGroup)(|(cn=$group)(gidNumber=$group)))"
136 $mesg->code && die $mesg->error;
137 foreach my $entry ($mesg->all_entries) {
148 # return (success, dn)
149 # bool = is_samba_user($username)
153 my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
155 my $mesg = $ldap->search ( base => $suffix,
157 filter => "(&(objectClass=sambaSamAccount)(uid=$user))"
159 $mesg->code && die $mesg->error;
161 return ($mesg->count ne 0);
165 # try to bind with user dn and password to validate current password
168 my ($user, $dn, $pass) = @_;
169 my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
170 my $mesg= $ldap->bind (dn => $dn, password => $pass );
171 if ($mesg->code eq 0)
182 print ("Le serveur LDAP est indisponible.\nVérifier le serveur, les câblages, ...");
185 } die "Problème : Contacter votre administrateur";
189 # dn = get_dn_from_line ($dn_line)
190 # helper to get "a=b,c=d" from "dn: a=b,c=d"
198 # success = add_posix_machine($user, $uid, $gid)
199 sub add_posix_machine
201 my ($user, $uid, $gid) = @_;
203 "dn: uid=$user,$computersdn
204 objectclass: inetOrgPerson
205 objectclass: posixAccount
211 homeDirectory: /dev/null
212 loginShell: /bin/false
213 description: Computer
217 die "$0: error while adding posix account to machine $user\n"
218 unless (do_ldapadd($tmpldif) == 0);
223 # success = add_samba_machine($computername)
224 sub add_samba_machine
227 system "smbpasswd -a -m $user";
231 sub add_samba_machine_mkntpwd
233 my ($user, $uid) = @_;
234 my $sambaSID = 2 * $uid + 1000;
238 if ($mk_ntpasswd eq '') {
239 print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n";
243 my $ntpwd = `$mk_ntpasswd '$name'`;
244 chomp(my $lmpassword = substr($ntpwd, 0, index($ntpwd, ':')));
245 chomp(my $ntpassword = substr($ntpwd, index($ntpwd, ':')+1));
248 "dn: uid=$user,$computersdn
250 objectclass: inetOrgPerson
251 objectclass: posixAccount
252 objectClass: sambaSamAccount
255 sambaLogoffTime: 2147483647
256 sambaKickoffTime: 2147483647
258 sambaPwdMustChange: 2147483647
260 sambaLMPassword: $lmpassword
261 sambaNTPassword: $ntpassword
262 sambaSID: $smbldap_conf::SID-$sambaSID
263 sambaPrimaryGroupSID: $smbldap_conf::SID-0
267 die "$0: error while adding samba account to $user\n"
268 unless (do_ldapmodify($tmpldif) == 0);
278 my ($group, $userid) = @_;
280 my $dn_line = get_group_dn($group);
281 if (!defined($dn_line)) {
284 my $dn = get_dn_from_line($dn_line);
286 my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
288 my $mesg = $ldap->search ( base =>$dn, scope => "base", filter => "(objectClass=*)" );
289 $mesg->code && die $mesg->error;
290 foreach my $entry ($mesg->all_entries){
291 foreach my $attr ($entry->attributes)
293 if ($attr=~/\bmemberUid\b/){
294 foreach my $ent($entry->get_value($attr)) { $members.= $attr.": ".$ent."\n"; }
300 # user already member ?
301 if ($members =~ m/^memberUid: $userid/) {
305 if ($members ne '') {
326 die "$0: error while modifying group $group\n"
327 unless (do_ldapmodify($tmpldif) == 0);
332 sub add_grouplist_user
334 my ($grouplist, $user) = @_;
335 my @array = split(/,/, $grouplist);
336 foreach my $group (@array) {
337 group_add_user($group, $user);
341 # XXX FIXME : sambaAcctFlags |= D, and not sambaAcctFlags = D
347 if (!defined($dn_line = get_user_dn($user))) {
348 print "$0: user $user doesn't exist\n";
355 replace: userPassword
356 userPassword: {crypt}!x
360 die "$0: error while modifying user $user\n"
361 unless (do_ldapmodify($tmpldif) == 0);
364 if (is_samba_user($user)) {
369 replace: sambaAcctFlags
374 die "$0: error while modifying user $user\n"
375 unless (do_ldapmodify($tmpldif) == 0);
386 if (!defined($dn_line = get_user_dn($user))) {
387 print "$0: user $user doesn't exist\n";
391 my $dn = get_dn_from_line($dn_line);
392 system "$ldapdelete $dn >/dev/null";
395 # $success = group_add($groupname, $group_gid, $force_using_existing_gid)
398 my ($gname, $gid, $force) = @_;
399 my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
400 if ($nscd_status == 0) {
401 system "/etc/init.d/nscd stop > /dev/null 2>&1";
403 if (!defined($gid)) {
404 while (defined(getgrgid($GID_START))) {
409 if (!defined($force)) {
410 if (defined(getgrgid($gid))) {
415 if ($nscd_status == 0) {
416 system "/etc/init.d/nscd start > /dev/null 2>&1";
419 "dn: cn=$gname,$groupsdn
420 objectclass: posixGroup
426 die "$0: error while adding posix group $gname\n"
427 unless (do_ldapadd($tmpldif) == 0);
432 # $homedir = get_homedir ($user)
437 # my $homeDir=`$ldapsearch -b '$suffix' -s '$scope' '(&(objectclass=posixAccount)(uid=$user))' | grep "^homeDirectory:"`;
438 my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
440 my $mesg = $ldap->search ( base =>$suffix, scope => $scope, filter => "(&(objectclass=posixAccount)(uid=$user))" );
441 $mesg->code && die $mesg->error;
442 foreach my $entry ($mesg->all_entries){
443 foreach my $attr ($entry->attributes)
445 if ($attr=~/\bhomeDirectory\b/){
446 foreach my $ent($entry->get_value($attr)) {
447 $homeDir.= $attr.": ".$ent."\n";
454 if ($homeDir eq '') {
457 $homeDir =~ s/^homeDirectory: //;
466 my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
468 my $mesg = $ldap->search ( # perform a search
471 filter => "(&(objectclass=posixAccount)(uid=$user))"
474 $mesg->code && die $mesg->error;
475 foreach my $entry ($mesg->all_entries) {
476 $lines.= "dn: " . $entry->dn."\n";
477 foreach my $attr ($entry->attributes) {
479 $lines.= $attr.": ".join(',', $entry->get_value($attr))."\n";
483 $ldap->unbind; # take down sessio(n
496 my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
498 my $mesg = $ldap->search ( # perform a search
501 filter => "(&(objectclass=posixGroup)(cn=$user))"
504 $mesg->code && die $mesg->error;
505 foreach my $entry ($mesg->all_entries) {
506 $lines.= "dn: " . $entry->dn."\n";
507 foreach my $attr ($entry->attributes) {
509 $lines.= $attr.": ".join(',', $entry->get_value($attr))."\n";
514 $ldap->unbind; # take down sessio(n
522 # find groups of a given user
523 ##### MODIFIE ########
528 my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
530 my $mesg = $ldap->search ( # perform a search
533 filter => "(&(objectclass=posixGroup)(memberuid=$user))"
535 $mesg->code && die $mesg->error;
536 foreach my $entry ($mesg->all_entries) {
537 $lines.= "dn: ".$entry->dn."\n";
541 if ($lines eq '') {return undef; }
545 # return the gidnumber for a group given as name or gid
546 # -1 : bad group name
550 my $userGidNumber = shift;
551 if ($userGidNumber =~ /[^\d]/ ) {
552 my $gname = $userGidNumber;
553 my $gidnum = getgrnam($gname);
554 if ($gidnum !~ /\d+/) {
557 $userGidNumber = $gidnum;
559 } elsif (!defined(getgrgid($userGidNumber))) {
562 return $userGidNumber;
565 # remove $user from $group
566 sub group_remove_member
568 my ($group, $user) = @_;
570 my $grp_line = get_group_dn($group);
571 if (!defined($grp_line)) {
575 my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
577 my $mesg = $ldap->search ( base => $groupsdn,
579 filter => "(&(objectclass=posixgroup)(cn=$group))"
581 $mesg->code && die $mesg->error;
582 foreach my $entry ($mesg->all_entries){
583 foreach my $attr ($entry->attributes)
585 if ($attr=~/\bmemberUid\b/){
586 foreach my $ent($entry->get_value($attr)) {
587 $members.= $attr.": ".$ent."\n";
592 #print "Valeurs de members :\n$members";
594 # my $members = `$ldapsearch -b '$groupsdn' -s '$scope' '(&(objectclass=posixgroup)(cn=$group))' | grep -i "^memberUid:"`;
595 # print "avant ---\n$members\n";
596 $members =~ s/memberUid: $user\n//;
597 #print "après ---\n$members\n";
601 if ($members eq '') {
602 $header = "changetype: modify\n";
603 $header .= "delete: memberUid";
605 $header = "changetype: modify\n";
606 $header .= "replace: memberUid";
615 #print "Valeur du tmpldif : \n$tmpldif";
616 die "$0: error while modifying group $group\n"
617 unless (do_ldapmodify($tmpldif) == 0);
624 sub group_get_members
629 my $grp_line = get_group_dn($group);
630 if (!defined($grp_line)) { return 0; }
632 my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
634 my $mesg = $ldap->search ( base => $groupsdn,
636 filter => "(&(objectclass=posixgroup)(cn=$group))"
638 $mesg->code && die $mesg->error;
639 foreach my $entry ($mesg->all_entries){
640 foreach my $attr ($entry->attributes){
641 if ($attr=~/\bmemberUid\b/){
642 foreach my $ent($entry->get_value($attr)) { push (@resultat,$ent); }
650 my ($filename, $filecontent) = @_;
652 open (FILE, "> $filename") ||
653 die "Cannot open $filename for writing: $!\n";
654 print FILE $filecontent;
658 # wrapper for ldapadd
662 my $tempfile = "/tmp/smbldapadd.$$";
663 file_write($tempfile, $ldif);
665 my $rc = system "$ldapadd < $tempfile >/dev/null";
673 my $FILE = "|$ldapadd >/dev/null";
674 open (FILE, $FILE) || die "$!\n";
684 # wrapper for ldapmodify
688 my $tempfile = "/tmp/smbldapmod.$$";
689 file_write($tempfile, $ldif);
690 my $rc = system "$ldapmodify -r < $tempfile >/dev/null";
698 my $FILE = "|$ldapmodify -r >/dev/null";
699 open (FILE, $FILE) || die "$!\n";