1 |
slords |
1.1 |
diff -up e-smith-ldap-5.2.0/root/etc/e-smith/events/actions/ldap-update.code_cleanup e-smith-ldap-5.2.0/root/etc/e-smith/events/actions/ldap-update |
2 |
slords |
1.3 |
--- e-smith-ldap-5.2.0/root/etc/e-smith/events/actions/ldap-update.code_cleanup 2010-09-25 12:07:10.000000000 -0600 |
3 |
|
|
+++ e-smith-ldap-5.2.0/root/etc/e-smith/events/actions/ldap-update 2010-09-25 12:07:30.000000000 -0600 |
4 |
slords |
1.1 |
@@ -30,6 +30,7 @@ use esmith::ConfigDB; |
5 |
|
|
use esmith::AccountsDB; |
6 |
|
|
use esmith::util; |
7 |
|
|
use Net::LDAP; |
8 |
|
|
+use Date::Parse; |
9 |
|
|
|
10 |
|
|
my $c = esmith::ConfigDB->open_ro; |
11 |
|
|
my $a = esmith::AccountsDB->open_ro; |
12 |
|
|
@@ -44,11 +45,21 @@ unless ($status eq "enabled" ) |
13 |
|
|
|
14 |
|
|
my $hostname = $c->get('SystemName') |
15 |
|
|
|| die("Couldn't determine system name"); |
16 |
|
|
- $hostname = $hostname->value; |
17 |
|
|
+$hostname = $hostname->value; |
18 |
|
|
|
19 |
|
|
my $domain = $c->get('DomainName') |
20 |
|
|
|| die("Couldn't determine domain name"); |
21 |
|
|
- $domain = $domain->value; |
22 |
|
|
+$domain = $domain->value; |
23 |
|
|
+ |
24 |
|
|
+my $schema = '/etc/openldap/schema/samba.schema'; |
25 |
|
|
+my $map = { 'FirstName' => 'givenName', |
26 |
|
|
+ 'LastName' => 'sn', |
27 |
|
|
+ 'Phone' => 'telephoneNumber', |
28 |
|
|
+ 'Company' => 'o', |
29 |
|
|
+ 'Department' => 'ou', |
30 |
|
|
+ 'City' => 'l', |
31 |
|
|
+ 'Street' => 'street', |
32 |
|
|
+ }; |
33 |
|
|
|
34 |
|
|
my @accounts; |
35 |
|
|
my $account; |
36 |
|
|
@@ -69,73 +80,32 @@ else |
37 |
|
|
|
38 |
|
|
exit (0) if ($type eq 'ibay'); |
39 |
|
|
|
40 |
|
|
- die "Account $userName is not a user or group account; " . |
41 |
|
|
- "update LDAP entry failed.\n" |
42 |
|
|
+ die "Account $userName is not a user or group account; update LDAP entry failed.\n" |
43 |
|
|
unless (($type eq 'user') || ($type eq 'group') || ($userName eq 'admin')); |
44 |
|
|
@accounts = ($account); |
45 |
|
|
} |
46 |
|
|
|
47 |
|
|
#------------------------------------------------------------ |
48 |
|
|
-# Update LDAP directory entry. First read LDAP password |
49 |
|
|
+# Read all samba groups (can't do individual lookups) |
50 |
|
|
#------------------------------------------------------------ |
51 |
|
|
-my $pw = esmith::util::LdapPassword(); |
52 |
|
|
-my %passwd; |
53 |
|
|
-my %uid; |
54 |
|
|
-my %gid; |
55 |
|
|
-my %home; |
56 |
|
|
-my %shell; |
57 |
|
|
- |
58 |
|
|
-while(my ($key,$pwd,$uid,$gid, |
59 |
|
|
- undef,undef,undef, |
60 |
|
|
- $home,$shell) = getpwent()) { |
61 |
|
|
- |
62 |
|
|
- $passwd{$key} = "{CRYPT}$pwd"; |
63 |
|
|
- $uid{$key} = $uid; |
64 |
|
|
- $gid{$key} = $gid; |
65 |
|
|
- $home{$key} = $home; |
66 |
|
|
- $shell{$key} = $shell; |
67 |
|
|
-} |
68 |
|
|
-endpwent(); |
69 |
|
|
|
70 |
|
|
-# Now parse samba info |
71 |
|
|
-# We want to copy all this into LDAP |
72 |
|
|
-# so it'll be easier to switch to real LDAP auth later |
73 |
|
|
-my %lmpass; |
74 |
|
|
-my %ntpass; |
75 |
|
|
-my %smbflag; |
76 |
|
|
-my %smblct; |
77 |
|
|
-my %smbsid; |
78 |
|
|
-my %smbpgsid; |
79 |
|
|
- |
80 |
|
|
-# First, parse users data |
81 |
|
|
-foreach my $line (`/usr/bin/pdbedit -Lw`){ |
82 |
|
|
- my ($key,undef,$lmpass,$ntpass,$smbflag,$smblct) = split(/:/,$line); |
83 |
|
|
- $lmpass{$key} = $lmpass; |
84 |
|
|
- $ntpass{$key} = $ntpass; |
85 |
|
|
- $smbflag{$key} = $smbflag; |
86 |
|
|
- $smblct =~ s/LCT\-//; |
87 |
|
|
- $smblct{$key} = hex($smblct); |
88 |
|
|
- foreach my $info (`/usr/bin/pdbedit -v $key`){ |
89 |
|
|
- $smbsid{$key} = $1 if ($info =~ m/User SID:\s+(S-.*)/); |
90 |
|
|
- $smbpgsid{$key} = $1 if ($info =~ m/Primary Group SID:\s+(S-.*)/); |
91 |
|
|
- } |
92 |
|
|
-} |
93 |
|
|
+my $groupmap = (); |
94 |
|
|
|
95 |
|
|
-# Now, parse groupmaps data |
96 |
|
|
-foreach (`/usr/bin/net groupmap list`){ |
97 |
|
|
- chomp; |
98 |
|
|
- next unless (/^(.*?) \((S-.*-\d+)\) -> (.*)$/); |
99 |
|
|
- my ($desc, $smbsid, $key) = ($1, $2, $3); |
100 |
|
|
- # We only want group sid |
101 |
|
|
- my $account = $a->get($key) || next; |
102 |
|
|
- next unless ($account->prop('type') eq 'group'); |
103 |
|
|
- $smbsid{$key} = $smbsid; |
104 |
|
|
+# Only do if schema is found |
105 |
|
|
+if ( -f "$schema" and -x '/usr/bin/net' ) |
106 |
|
|
+{ |
107 |
|
|
+ foreach (`/usr/bin/net groupmap list 2> /dev/null`){ |
108 |
|
|
+ chomp; |
109 |
|
|
+ next if m{\(S-1-5-32-\d+\)}; |
110 |
|
|
+ $groupmap->{$3} = { name => "$1", sid => "$2" } if (/^(.*) \((S-.*-\d+)\) -> (.*)$/); |
111 |
|
|
+ } |
112 |
|
|
} |
113 |
|
|
|
114 |
|
|
#------------------------------------------------------------ |
115 |
|
|
# Update LDAP database entry. |
116 |
|
|
#------------------------------------------------------------ |
117 |
|
|
my $base = esmith::util::ldapBase ($domain); |
118 |
|
|
+my $pw = esmith::util::LdapPassword(); |
119 |
|
|
|
120 |
|
|
my $ldap = Net::LDAP->new('localhost') |
121 |
|
|
or die "$@"; |
122 |
slords |
1.3 |
@@ -145,109 +115,169 @@ $ldap->bind( |
123 |
slords |
1.1 |
password => $pw |
124 |
|
|
); |
125 |
|
|
|
126 |
|
|
-my $phone = $l->prop('defaultTelephoneNumber') || ''; |
127 |
|
|
-my $company = $l->prop('defaultCompany') || ''; |
128 |
|
|
-my $dept = $l->prop('defaultDepartment') || ''; |
129 |
|
|
-my $city = $l->prop('defaultCity') || ''; |
130 |
|
|
-my $street = $l->prop('defaultStreet') || ''; |
131 |
slords |
1.3 |
+#------------------------------------------------------------ |
132 |
|
|
+# Create a list of updates that need to happen |
133 |
|
|
+#------------------------------------------------------------ |
134 |
slords |
1.1 |
+my $updates; |
135 |
|
|
foreach my $acct (@accounts) |
136 |
|
|
{ |
137 |
|
|
my $key = $acct->key; |
138 |
|
|
my $type = $acct->prop('type'); |
139 |
|
|
- next unless ($type eq 'user' || $key eq 'admin' || $type eq 'group'); |
140 |
|
|
- my @attrs = (); |
141 |
|
|
- my $dn = $base; |
142 |
|
|
- if (($type eq 'user') || ($key eq 'admin')) |
143 |
|
|
- { |
144 |
|
|
- $dn = "uid=$key,ou=Users,$base"; |
145 |
|
|
- my $name = $acct->prop('FirstName') . " " . $acct->prop('LastName'); |
146 |
|
|
- utf8::upgrade($name); |
147 |
|
|
- my $first = $acct->prop('FirstName') || ''; |
148 |
|
|
- utf8::upgrade($first); |
149 |
|
|
- my $last = $acct->prop('LastName') || ''; |
150 |
|
|
- utf8::upgrade($last); |
151 |
|
|
- my $phone = $acct->prop('Phone') || ''; |
152 |
|
|
- my $company = $acct->prop('Company') || ''; |
153 |
|
|
- utf8::upgrade($company); |
154 |
|
|
- my $dept = $acct->prop('Dept') || ''; |
155 |
|
|
- utf8::upgrade($dept); |
156 |
|
|
- my $city = $acct->prop('City') || ''; |
157 |
|
|
- utf8::upgrade($city); |
158 |
|
|
- my $street = $acct->prop('Street') || ''; |
159 |
|
|
- utf8::upgrade($street); |
160 |
|
|
- my $password = $passwd{$key} || ''; |
161 |
|
|
- utf8::upgrade($password); |
162 |
|
|
- my $uid = $uid{$key} || ''; |
163 |
|
|
- my $gid = $gid{$key} || ''; |
164 |
|
|
- my $home = $home{$key} || ''; |
165 |
|
|
- my $shell = $shell{$key} || ''; |
166 |
|
|
- my $lmpass = $lmpass{$key} || ''; |
167 |
|
|
- my $ntpass = $ntpass{$key} || ''; |
168 |
|
|
- my $smbflag = $smbflag{$key} || ''; |
169 |
|
|
- my $smblct = $smblct{$key} || ''; |
170 |
|
|
- my $smbsid = $smbsid{$key} || ''; |
171 |
|
|
- my $smbpgsid = $smbpgsid{$key} || ''; |
172 |
|
|
- |
173 |
|
|
- push @attrs, (objectClass => ['inetOrgPerson', 'posixAccount', 'sambaSamAccount']); |
174 |
|
|
- push @attrs, (uid => $key); |
175 |
|
|
- |
176 |
|
|
- push @attrs, (cn => $name) unless ($name =~ /^\s*$/); |
177 |
|
|
- push @attrs, (givenName => $first) unless $first =~ /^\s*$/; |
178 |
|
|
- push @attrs, (sn => $last) unless $last =~ /^\s*$/; |
179 |
|
|
- push @attrs, (mail => "$key\@$domain"); |
180 |
|
|
- push @attrs, (telephoneNumber => $phone) unless $phone =~ /^\s*$/; |
181 |
|
|
- push @attrs, (o => $company) unless $company =~ /^\s*$/; |
182 |
|
|
- push @attrs, (ou => $dept) unless $dept =~ /^\s*$/; |
183 |
|
|
- push @attrs, (l => $city) unless $city =~ /^\s*$/; |
184 |
|
|
- push @attrs, (street => $street) unless $street =~ /^\s*$/; |
185 |
|
|
- push @attrs, (userPassword => $password) unless $password =~ /^\s*$/; |
186 |
|
|
- push @attrs, (uidNumber => $uid) unless $uid =~ /^\s*$/; |
187 |
|
|
- push @attrs, (gidNumber => $gid) unless $gid =~ /^\s*$/; |
188 |
|
|
- push @attrs, (homeDirectory => $home) unless $home =~ /^\s*$/; |
189 |
|
|
- push @attrs, (loginShell => $shell) unless $shell =~ /^\s*$/; |
190 |
|
|
- push @attrs, (sambaLMPassword => $lmpass) unless $lmpass =~ /^\s*$/; |
191 |
|
|
- push @attrs, (sambaNTPassword => $ntpass) unless $ntpass =~ /^\s*$/; |
192 |
|
|
- push @attrs, (sambaAcctFlags => $smbflag) unless $smbflag =~ /^\s*$/; |
193 |
|
|
- push @attrs, (sambaPwdLastSet => $smblct) unless $smblct =~ /^\s*$/; |
194 |
|
|
- push @attrs, (sambaSID => $smbsid) unless $smbsid =~ /^\s*$/; |
195 |
|
|
- push @attrs, (sambaPrimaryGroupSID => $smbpgsid) unless $smbpgsid =~ /^\s*$/; |
196 |
|
|
- } |
197 |
|
|
- elsif ($type eq 'group') |
198 |
|
|
+ my $desc = undef; |
199 |
|
|
+ |
200 |
|
|
+ if ($type =~ m{^(?:user|group)$} or $key eq 'admin') |
201 |
|
|
{ |
202 |
|
|
+ #------------------------------------------------------------ |
203 |
|
|
+ # Do the user portion |
204 |
|
|
+ #------------------------------------------------------------ |
205 |
|
|
+ my $dn = "uid=$key,ou=Users,$base"; |
206 |
slords |
1.3 |
+ $updates->{$dn}->{objectClass} = ['posixAccount', 'shadowAccount']; |
207 |
slords |
1.1 |
+ |
208 |
|
|
+ # Read information from getent passwd |
209 |
|
|
+ @{$updates->{$dn}}{'uid','userPassword','uidNumber','gidNumber','junk','junk','gecos','homeDirectory','loginShell'} = getpwnam($key); |
210 |
slords |
1.3 |
+ unless ($updates->{$dn}->{uid}) |
211 |
|
|
+ { |
212 |
|
|
+ delete $updates->{$dn}; |
213 |
|
|
+ next; |
214 |
|
|
+ } |
215 |
slords |
1.1 |
+ $updates->{$dn}->{userPassword} =~ s/^/{CRYPT}/ unless $updates->{$dn}->{userPassword} =~ m/^{/; |
216 |
|
|
+ $desc = $updates->{$dn}->{cn} = $updates->{$dn}->{gecos}; |
217 |
|
|
+ |
218 |
|
|
+ # Load values from db record |
219 |
|
|
+ foreach my $attr ( keys %$map ) |
220 |
|
|
+ { |
221 |
|
|
+ my $val = $acct->prop($attr); |
222 |
|
|
+ $updates->{$dn}->{$map->{$attr}} = $val if defined $val; |
223 |
|
|
+ } |
224 |
|
|
+ |
225 |
|
|
+ # Ensure users have the needed properties |
226 |
slords |
1.3 |
+ if ($type eq 'user' or $key eq 'admin') |
227 |
slords |
1.1 |
+ { |
228 |
|
|
+ push @{$updates->{$dn}->{objectClass}}, 'inetOrgPerson'; |
229 |
|
|
+ $updates->{$dn}->{mail} = "$key\@$domain"; |
230 |
slords |
1.3 |
+ } |
231 |
|
|
+ else |
232 |
|
|
+ { |
233 |
|
|
+ push @{$updates->{$dn}->{objectClass}}, 'account'; |
234 |
|
|
+ } |
235 |
slords |
1.1 |
+ |
236 |
slords |
1.3 |
+ # Samba parameters if we find the samba.schema |
237 |
|
|
+ if ( -f "$schema" and -x '/usr/bin/pdbedit' ) |
238 |
|
|
+ { |
239 |
|
|
+ my $line = `/usr/bin/pdbedit -wu '$key' 2> /dev/null`; |
240 |
|
|
+ chomp($line); |
241 |
|
|
+ if ($line) |
242 |
slords |
1.1 |
+ { |
243 |
slords |
1.3 |
+ @{$updates->{$dn}}{'junk','junk','sambaLMPassword','sambaNTPassword'} = split(/:/,$line); |
244 |
|
|
+ foreach $line (`/usr/bin/pdbedit -vu '$key' 2> /dev/null`) |
245 |
slords |
1.1 |
+ { |
246 |
slords |
1.3 |
+ chomp($line); |
247 |
|
|
+ $updates->{$dn}->{sambaSID} = $1 if $line =~ m{User SID:\s+(S-.*)$}; |
248 |
|
|
+ $updates->{$dn}->{displayName} = $1 if $line =~ m{Full Name:\s+(.*)$}; |
249 |
|
|
+ $updates->{$dn}->{sambaPrimaryGroupSID} = $1 if $line =~ m{Primary Group SID:\s+(S-.*)$}; |
250 |
|
|
+ $updates->{$dn}->{sambaAcctFlags} = $1 if $line =~ m{Account Flags:\s+(.*)$}; |
251 |
|
|
+ $updates->{$dn}->{sambaPwdLastSet} = str2time($1) if $line =~ m{Password last set:\s+(.*)$}; |
252 |
slords |
1.1 |
+ } |
253 |
slords |
1.3 |
+ push @{$updates->{$dn}->{objectClass}}, 'sambaSamAccount'; |
254 |
slords |
1.1 |
+ } |
255 |
|
|
+ } |
256 |
slords |
1.3 |
+ |
257 |
slords |
1.1 |
+ #------------------------------------------------------------ |
258 |
|
|
+ # Do the group portion |
259 |
|
|
+ #------------------------------------------------------------ |
260 |
|
|
$dn = "cn=$key,ou=Groups,$base"; |
261 |
|
|
- my $key = $acct->key; |
262 |
|
|
- my $desc = $acct->prop('Description') || ''; |
263 |
|
|
- utf8::upgrade($desc); |
264 |
|
|
- my @members = split(/,/,($acct->prop('Members') || '')); |
265 |
|
|
- my $gid = $acct->prop('Gid'); |
266 |
|
|
- my $smbsid = $smbsid{$key}; |
267 |
|
|
- |
268 |
|
|
- push @attrs, (objectClass => ['posixGroup','mailboxRelatedObject','sambaGroupMapping']); |
269 |
|
|
- push @attrs, (cn => $key); |
270 |
|
|
- push @attrs, (mail => "$key\@$domain"); |
271 |
|
|
- push @attrs, (gidNumber => $gid); |
272 |
|
|
- push @attrs, (description => $desc) unless $desc =~ /^\s*$/; |
273 |
|
|
- push @attrs, (memberUid => \@members) |
274 |
|
|
- unless ((scalar @members == 0) && ($event eq 'group-create')); |
275 |
|
|
- # Samba requires the displayName attribute |
276 |
|
|
- push @attrs, (displayName => $desc) unless $desc =~ /^\s*$/; |
277 |
|
|
- push @attrs, (sambaGroupType => '2'); |
278 |
|
|
- push @attrs, (sambaSID => $smbsid); |
279 |
|
|
+ $updates->{$dn}->{objectClass} = ['posixGroup']; |
280 |
|
|
+ |
281 |
|
|
+ # Read information from getent group |
282 |
|
|
+ @{$updates->{$dn}}{'cn','userPassword','gidNumber','memberUid'} = getgrnam($key); |
283 |
|
|
+ $updates->{$dn}->{userPassword} =~ s/^/{CRYPT}/ unless $updates->{$dn}->{userPassword} =~ m/^{/; |
284 |
|
|
+ $updates->{$dn}->{description} = $desc if $desc; |
285 |
|
|
+ $updates->{$dn}->{memberUid} = [ split /\s+/, $updates->{$dn}->{memberUid} ]; |
286 |
|
|
+ |
287 |
|
|
+ # Ensure groups have the needed properties |
288 |
|
|
+ if ($type eq 'group') |
289 |
|
|
+ { |
290 |
|
|
+ push @{$updates->{$dn}->{objectClass}}, 'mailboxRelatedObject'; |
291 |
|
|
+ $updates->{$dn}->{mail} = "$key\@$domain"; |
292 |
|
|
+ } |
293 |
|
|
+ |
294 |
|
|
+ # Samba parameters if we find the samba.schema |
295 |
|
|
+ if ( -f "$schema" and exists $groupmap->{$key} ) |
296 |
|
|
+ { |
297 |
|
|
+ push @{$updates->{$dn}->{objectClass}}, 'sambaGroupMapping'; |
298 |
|
|
+ $updates->{$dn}->{displayName} = $groupmap->{$key}->{name}; |
299 |
|
|
+ $updates->{$dn}->{sambaSID} = $groupmap->{$key}->{sid}; |
300 |
|
|
+ $updates->{$dn}->{sambaGroupType} = '2'; |
301 |
|
|
+ } |
302 |
|
|
+ |
303 |
slords |
1.3 |
} |
304 |
|
|
- if (($event eq 'user-create') || ($event eq 'group-create')) |
305 |
slords |
1.1 |
+} |
306 |
|
|
+endpwent(); |
307 |
|
|
+ |
308 |
slords |
1.3 |
+#------------------------------------------------------------ |
309 |
|
|
+# Update LDAP database entry. |
310 |
|
|
+#------------------------------------------------------------ |
311 |
slords |
1.1 |
+foreach my $dn (keys %$updates) |
312 |
|
|
+{ |
313 |
|
|
+ # Try and find record |
314 |
|
|
+ my ($filter, $searchbase) = split /,/, $dn, 2; |
315 |
|
|
+ my $result = $ldap->search( base => $searchbase, filter => "($filter)" ); |
316 |
|
|
+ if ( $result->code ) |
317 |
slords |
1.3 |
{ |
318 |
|
|
- my $result = $ldap->add ($dn, attr => \@attrs); |
319 |
|
|
+ warn "failed looking up entry $dn: ", $result->error; |
320 |
slords |
1.1 |
+ next; |
321 |
slords |
1.3 |
+ } |
322 |
|
|
+ my $cnt = $result->count; |
323 |
|
|
+ |
324 |
slords |
1.1 |
+ # Clean up attributes and convert to utf8 |
325 |
|
|
+ delete $updates->{$dn}->{'junk'}; |
326 |
|
|
+ foreach my $attr ( keys %{$updates->{$dn}} ) |
327 |
slords |
1.3 |
+ { |
328 |
slords |
1.1 |
+ if ( ref($updates->{$dn}->{$attr}) eq 'ARRAY' ) |
329 |
|
|
+ { |
330 |
|
|
+ if ( $cnt == 0 and scalar(@{$updates->{$dn}->{$attr}}) == 0 ) |
331 |
|
|
+ { |
332 |
|
|
+ delete $updates->{$dn}->{$attr}; |
333 |
|
|
+ } |
334 |
|
|
+ else |
335 |
|
|
+ { |
336 |
|
|
+ for (my $c = 0; $c < scalar(@{$updates->{$dn}->{$attr}}); $c++) |
337 |
|
|
+ { |
338 |
|
|
+ utf8::upgrade($updates->{$dn}->{$attr}[$c]); |
339 |
|
|
+ } |
340 |
|
|
+ } |
341 |
|
|
+ } |
342 |
|
|
+ else |
343 |
|
|
+ { |
344 |
|
|
+ if ($updates->{$dn}->{$attr} !~ /^\s*$/) |
345 |
|
|
+ { |
346 |
|
|
+ utf8::upgrade($updates->{$dn}->{$attr}); |
347 |
|
|
+ } |
348 |
|
|
+ elsif ( $cnt == 0 ) |
349 |
|
|
+ { |
350 |
|
|
+ delete $updates->{$dn}->{$attr}; |
351 |
|
|
+ } |
352 |
|
|
+ else |
353 |
|
|
+ { |
354 |
|
|
+ $updates->{$dn}->{$attr} = []; |
355 |
|
|
+ } |
356 |
|
|
+ } |
357 |
|
|
+ } |
358 |
|
|
|
359 |
|
|
- $result->code && |
360 |
|
|
- warn "failed to add entry for $dn: ", $result->error ; |
361 |
|
|
+ # Perform insert or update |
362 |
|
|
+ if ( $cnt == 0 ) |
363 |
|
|
+ { |
364 |
slords |
1.3 |
+ $result = $ldap->add( $dn, attrs => [ %{$updates->{$dn}} ] ); |
365 |
|
|
+ $result->code && warn "failed to add entry $dn: ", $result->error; |
366 |
slords |
1.1 |
+ } |
367 |
|
|
+ elsif ( $cnt == 1 ) |
368 |
|
|
+ { |
369 |
slords |
1.3 |
+ $result = $ldap->modify( $dn, replace => $updates->{$dn}); |
370 |
|
|
+ $result->code && warn "failed to modify entry $dn: ", $result->error; |
371 |
slords |
1.1 |
} |
372 |
|
|
else |
373 |
|
|
{ |
374 |
|
|
- my %attrs = @attrs; |
375 |
|
|
- my $result = $ldap->modify ($dn, replace => \%attrs); |
376 |
|
|
- |
377 |
|
|
- $result->code && |
378 |
|
|
- warn "failed to modify entry for $dn: ", $result->error ; |
379 |
slords |
1.3 |
+ warn "failed looking up entry $dn: found $cnt results"; |
380 |
slords |
1.1 |
} |
381 |
|
|
} |
382 |
|
|
$ldap->unbind; |