File: | /home/mik/work/module/Tivoli/AccessManager/Admin/User.pm |
Coverage: | 99.2% |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package Tivoli::AccessManager::Admin::User; | ||||||
2 | 15 15 15 | 165 78 235 | use strict; | ||||
3 | 15 15 15 | 238 61 218 | use warnings; | ||||
4 | 15 15 15 | 212 59 409 | use Data::Dumper; | ||||
5 | 15 15 15 | 221 61 293 | use Carp; | ||||
6 | 15 15 15 | 229 62 262 | use Tivoli::AccessManager::Admin::Response; | ||||
7 | 15 15 15 | 210 65 276 | use Tivoli::AccessManager::Admin::Group; | ||||
8 | |||||||
9 | #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | ||||||
10 | # $Id: User.pm 334 2006-11-20 19:09:35Z mik $ | ||||||
11 | #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | ||||||
12 | $Tivoli::AccessManager::Admin::User::VERSION = '0.04'; | ||||||
13 | 15 | 232 | use Inline(C => 'DATA', | ||||
14 | INC => '-I/opt/PolicyDirector/include', | ||||||
15 | LIBS => ' -lpthread -lpdadminapi -lstdc++', | ||||||
16 | CCFLAGS => '-Wall', | ||||||
17 | # VERSION => '0.04', | ||||||
18 | NAME => 'Tivoli::AccessManager::Admin::User', | ||||||
19 | 15 15 | 192 82 | ); | ||||
20 | |||||||
21 | my %tod = ( 1 => 'sun', | ||||||
22 | 2 => 'mon', | ||||||
23 | 4 => 'tue', | ||||||
24 | 8 => 'wed', | ||||||
25 | 16 => 'thu', | ||||||
26 | 32 => 'fri', | ||||||
27 | 64 => 'sat', | ||||||
28 | ); | ||||||
29 | |||||||
30 | my %revtod = map { $tod{$_} => $_ } keys %tod; | ||||||
31 | |||||||
32 | sub _todtolist { | ||||||
33 | 5 | 35 | my $vector = shift; | ||||
34 | 5 | 21 | my @list; | ||||
35 | |||||||
36 | 5 | 63 | return qw/any/ unless $vector; | ||||
37 | |||||||
38 | 4 48 | 54 385 | for my $mask ( sort { $a <=> $b } keys %tod ) { | ||||
39 | 28 | 286 | push @list, $tod{$mask} if ( ($vector & $mask) == $mask ); | ||||
40 | } | ||||||
41 | 4 | 93 | return @list; | ||||
42 | } | ||||||
43 | |||||||
44 | sub _listtotod { | ||||||
45 | 5 | 25 | my $list = shift; | ||||
46 | 5 | 23 | my $vector = 0; | ||||
47 | |||||||
48 | 5 5 | 22 40 | for my $day ( @{$list} ) { | ||||
49 | 11 | 53 | $day = lc($day); | ||||
50 | 11 | 79 | if ( $day eq 'any' ) { | ||||
51 | 2 | 15 | $vector = 0; | ||||
52 | 2 | 12 | last; | ||||
53 | } | ||||||
54 | 9 | 58 | $vector += $revtod{$day}; | ||||
55 | } | ||||||
56 | 5 | 42 | return $vector; | ||||
57 | } | ||||||
58 | |||||||
59 | sub _miltomin { | ||||||
60 | 12 | 74 | my $miltime = shift; | ||||
61 | 12 | 127 | return ( $miltime - $miltime % 100 ) * .6 + $miltime % 100; | ||||
62 | } | ||||||
63 | |||||||
64 | sub _mintomil { | ||||||
65 | 10 | 49 | my $mins = shift; | ||||
66 | |||||||
67 | 10 | 175 | return sprintf("%04d", ($mins - $mins % 60)/.6 + $mins % 60); | ||||
68 | } | ||||||
69 | |||||||
70 | sub new { | ||||||
71 | 38 | 1 | 551 | my $class = shift; | |||
72 | 38 | 176 | my $cont = shift; | ||||
73 | 38 | 970 | unless ( defined($cont) and UNIVERSAL::isa($cont,'Tivoli::AccessManager::Admin::Context' ) ) { | ||||
74 | 2 | 69 | warn "Incorrect syntax -- did you forget the context?\n"; | ||||
75 | 2 | 20 | return undef; | ||||
76 | } | ||||||
77 | |||||||
78 | 36 | 297 | if ( @_ % 2 ) { | ||||
79 | 2 | 49 | warn "Incorrect syntax -- new() requires a hash\n"; | ||||
80 | 2 | 32 | return undef; | ||||
81 | } | ||||||
82 | |||||||
83 | 34 | 587 | my %opts = @_; | ||||
84 | 34 | 513 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
85 | |||||||
86 | 34 | 368 | my $self = bless {}, $class; | ||||
87 | |||||||
88 | 34 | 440 | $self->{name} = $opts{name} || ''; | ||||
89 | 34 | 368 | $self->{dn} = $opts{dn} || ''; | ||||
90 | 34 | 368 | $self->{cn} = $opts{cn} || ''; | ||||
91 | 34 | 360 | $self->{sn} = $opts{sn} || ''; | ||||
92 | 34 | 211 | $self->{exist} = 0; | ||||
93 | 34 | 581 | $self->_userstore(); | ||||
94 | 34 | 241 | $self->{context} = $cont; | ||||
95 | |||||||
96 | 34 | 863 | unless ( $self->{cn} ) { | ||||
97 | 11 | 293 | $self->{cn} = $1 if $self->{dn} =~ /^cn=(.+?),/; | ||||
98 | } | ||||||
99 | |||||||
100 | # If the name was provided, call getuser to see if the user exists. | ||||||
101 | 34 | 321 | if ( $self->{name} ) { | ||||
102 | 29 | 1635991 | my $rc = $self->user_get( $resp ); | ||||
103 | |||||||
104 | 29 | 579 | if ( $rc ) { | ||||
105 | 8 | 256 | $self->{dn} = $self->user_getdn(); | ||||
106 | 8 | 153 | $self->{cn} = $self->user_getcn(); | ||||
107 | 8 | 132 | $self->{sn} = $self->user_getsn(); | ||||
108 | 8 | 134 | $self->{exist} = 1; | ||||
109 | } | ||||||
110 | } | ||||||
111 | elsif ( $self->{dn} ) { | ||||||
112 | 4 | 273983 | my $rc = $self->user_getbydn( $resp ); | ||||
113 | 4 | 125 | if ( $rc ) { | ||||
114 | 3 | 99 | $self->{name} = $self->user_getid(); | ||||
115 | 3 | 53 | $self->{cn} = $self->user_getcn(); | ||||
116 | 3 | 54 | $self->{sn} = $self->user_getsn(); | ||||
117 | # It is possible for getbydn to return a user in the LDAP who is | ||||||
118 | # not TAMified. This makes sure the discovered user is TAMified | ||||||
119 | 3 | 171613 | $self->{exist} = $self->user_get($resp); | ||||
120 | } | ||||||
121 | } | ||||||
122 | |||||||
123 | 34 | 562 | return $self; | ||||
124 | } | ||||||
125 | |||||||
126 | sub create { | ||||||
127 | 33 | 1 | 471 | my $self = shift; | |||
128 | 33 | 512 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
129 | 33 | 239 | my $gref = []; | ||||
130 | |||||||
131 | 33 | 328 | unless ( ref $self ) { | ||||
132 | 19 | 112 | my $pd = shift; | ||||
133 | 19 | 455 | unless ( defined($pd) and UNIVERSAL::isa($pd,'Tivoli::AccessManager::Admin::Context' ) ) { | ||||
134 | 3 | 35 | $resp->set_message("Incorrect syntax -- did you forget the context?"); | ||||
135 | 3 | 38 | $resp->set_isok(0); | ||||
136 | 3 | 33 | return $resp; | ||||
137 | } | ||||||
138 | 16 | 161 | $self = new( $self, $pd, @_ ); | ||||
139 | } | ||||||
140 | |||||||
141 | 30 | 828 | if ( @_ % 2 ) { | ||||
142 | 1 | 15 | $resp->set_message("Incorrect syntax -- create() requires a hash"); | ||||
143 | 1 | 15 | $resp->set_isok(0); | ||||
144 | 1 | 8 | return $resp; | ||||
145 | } | ||||||
146 | |||||||
147 | 29 | 449 | my %opts = @_; | ||||
148 | |||||||
149 | 29 | 321 | if ( $self->{exist} ) { | ||||
150 | 7 | 106 | $resp->set_message( $self->{name} . " already exists" ); | ||||
151 | 7 | 75 | $resp->set_iswarning(1); | ||||
152 | 7 | 67 | $resp->set_value( $self ); | ||||
153 | |||||||
154 | 7 | 103 | return $resp; | ||||
155 | } | ||||||
156 | |||||||
157 | 22 | 176 | unless ( $self->{name} ) { | ||||
158 | 3 | 81 | $self->{name} = $opts{name} || ''; | ||||
159 | } | ||||||
160 | |||||||
161 | 22 | 167 | unless ( $self->{dn} ) { | ||||
162 | 3 | 63 | $self->{dn} = $opts{dn} || ''; | ||||
163 | } | ||||||
164 | |||||||
165 | 22 | 170 | unless ( $self->{cn} ) { | ||||
166 | 3 | 101 | $self->{cn} = $opts{cn} || ''; | ||||
167 | } | ||||||
168 | |||||||
169 | 22 | 949 | unless ( $self->{sn} ) { | ||||
170 | 3 | 49 | $self->{sn} = $opts{sn} || ''; | ||||
171 | } | ||||||
172 | |||||||
173 | |||||||
174 | 22 | 200 | $opts{password} ||= ''; | ||||
175 | 22 | 272 | $opts{sso} = defined( $opts{sso} ) ? $opts{sso} : 0; | ||||
176 | 22 | 218 | $opts{nopwdpolicy} = defined( $opts{nopwdpolicy} ) ? $opts{nopwdpolicy} : 0; | ||||
177 | 22 | 162 | if ( defined( $opts{groups} ) ) { | ||||
178 | 3 | 63 | if (ref($opts{groups}) eq 'ARRAY') { | ||||
179 | 1 | 24 | $gref = $opts{groups}; | ||||
180 | } | ||||||
181 | elsif ( ref($opts{groups}) ) { | ||||||
182 | 1 | 16 | $resp->set_message("Invalid group syntax -- it must be a string or an array ref"); | ||||
183 | 1 | 14 | $resp->set_isok(0); | ||||
184 | 1 | 6 | return $resp; | ||||
185 | } | ||||||
186 | else { | ||||||
187 | 1 | 10 | push @$gref, $opts{groups}; | ||||
188 | } | ||||||
189 | } | ||||||
190 | 21 | 347 | $opts{groups} = [] unless defined( $opts{groups} ); | ||||
191 | |||||||
192 | 21 | 555 | if ( $self->{name} and $self->{dn} and $self->{sn} and $self->{cn} ) { | ||||
193 | 17 | 1604033 | my $rc = $self->user_create( $resp, $opts{password}, $gref, | ||||
194 | $opts{sso}, $opts{nopwdpolicy}); | ||||||
195 | 17 | 578 | if ( $resp->isok ) { | ||||
196 | 15 | 147 | $self->{exist} = 1; | ||||
197 | 15 | 200 | $resp->set_value($self); | ||||
198 | } | ||||||
199 | } | ||||||
200 | else { | ||||||
201 | 4 | 68 | $resp->set_message("create: you must defined the userid, the DN, the CN and the SN"); | ||||
202 | 4 | 52 | $resp->set_isok(0); | ||||
203 | } | ||||||
204 | |||||||
205 | 21 | 658 | return $resp; | ||||
206 | } | ||||||
207 | |||||||
208 | sub delete { | ||||||
209 | 25 | 1 | 230 | my $self = shift; | |||
210 | 25 | 350 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
211 | 25 | 149 | my $registry = 0; | ||||
212 | |||||||
213 | |||||||
214 | 25 | 260 | if ( @_ == 1 ) { | ||||
215 | 4 | 21 | $registry = shift; | ||||
216 | } | ||||||
217 | elsif ( @_ % 2 ) { | ||||||
218 | 1 | 14 | $resp->set_message("Incorrect syntax -- delete needs a hash or just one parameter"); | ||||
219 | 1 | 13 | $resp->set_isok(0); | ||||
220 | 1 | 11 | return $resp; | ||||
221 | } | ||||||
222 | else { | ||||||
223 | 20 | 181 | my %opts = @_; | ||||
224 | 20 | 232 | $registry = $opts{registry} || 0; | ||||
225 | } | ||||||
226 | |||||||
227 | 24 | 171 | unless ( $self->{exist} ) { | ||||
228 | 2 | 38 | $resp->set_message( "delete: " . $self->{name} . " doesn't exist" ); | ||||
229 | 2 | 27 | $resp->set_isok(0); | ||||
230 | |||||||
231 | 2 | 18 | return $resp; | ||||
232 | } | ||||||
233 | |||||||
234 | 22 | 2117286 | my $rc = $self->user_delete($resp,$registry); | ||||
235 | 22 | 1111 | if ( $resp->isok ) { | ||||
236 | 21 | 279 | $resp->set_value( $rc ); | ||||
237 | 21 | 284 | $self->{exist} = 0; | ||||
238 | } | ||||||
239 | |||||||
240 | 22 | 276 | return $resp; | ||||
241 | } | ||||||
242 | |||||||
243 | sub description { | ||||||
244 | 8 | 1 | 53 | my $self = shift; | |||
245 | 8 | 104 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
246 | |||||||
247 | 8 | 72 | if ( $self->{exist} ) { | ||||
248 | 7 | 27 | my $desc; | ||||
249 | |||||||
250 | 7 | 89 | if ( @_ == 1 ) { | ||||
251 | 2 | 13 | $desc = shift; | ||||
252 | } | ||||||
253 | elsif ( @_ % 2 ) { | ||||||
254 | 1 | 10 | $resp->set_message("Invalid syntax"); | ||||
255 | 1 | 11 | $resp->set_isok(0); | ||||
256 | 1 | 9 | return $resp; | ||||
257 | } | ||||||
258 | elsif (@_) { | ||||||
259 | 2 | 15 | my %opts = @_; | ||||
260 | 2 | 34 | $desc = $opts{description} || ''; | ||||
261 | } | ||||||
262 | |||||||
263 | 6 | 34 | if ( defined $desc ) { | ||||
264 | 4 | 183585 | my $rc = $self->user_setdescription($resp, $desc); | ||||
265 | 4 | 102 | $resp->isok && $self->user_get($resp); | ||||
266 | } | ||||||
267 | 6 | 100 | if ( $resp->isok ) { | ||||
268 | 5 | 143 | my $rc = $self->user_getdescription; | ||||
269 | 5 | 82 | if ( defined $rc ) { | ||||
270 | 4 | 54 | $resp->set_value($rc); | ||||
271 | } | ||||||
272 | else { | ||||||
273 | 1 | 14 | $resp->set_message("Could not retrieve user's description"); | ||||
274 | 1 | 13 | $resp->set_isok(0); | ||||
275 | } | ||||||
276 | } | ||||||
277 | } | ||||||
278 | else { | ||||||
279 | 1 | 14 | $resp->set_message( "The user does not yet exist" ); | ||||
280 | 1 | 14 | $resp->set_isok(0); | ||||
281 | } | ||||||
282 | |||||||
283 | 7 | 64 | return $resp; | ||||
284 | } | ||||||
285 | |||||||
286 | sub accexpdate { | ||||||
287 | 8 | 1 | 93 | my $self = shift; | |||
288 | 8 | 53 | my $lifetime = 0; | ||||
289 | 8 | 130 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
290 | |||||||
291 | 8 | 47 | my ($seconds,$unlimited,$unset,$rc); | ||||
292 | 8 | 84 | if ( @_ == 1 ) { | ||||
293 | 4 | 28 | $lifetime = shift; | ||||
294 | } | ||||||
295 | elsif ( @_ % 2 ) { | ||||||
296 | 1 | 13 | $resp->set_message("Invalid syntax"); | ||||
297 | 1 | 14 | $resp->set_isok(0); | ||||
298 | 1 | 13 | return $resp; | ||||
299 | } | ||||||
300 | elsif ( @_ ) { | ||||||
301 | 2 | 20 | my %opts = @_; | ||||
302 | 2 | 35 | $lifetime = $opts{lifetime} || 0; | ||||
303 | } | ||||||
304 | else { | ||||||
305 | 1 | 7 | $lifetime = 0; | ||||
306 | } | ||||||
307 | |||||||
308 | 7 | 54 | if ( $lifetime ) { | ||||
309 | 5 | 94 | if ( $lifetime =~ /^\d+$/ ) { | ||||
310 | 1 | 3 | $unlimited = 0; | ||||
311 | 1 | 6 | $unset = 0; | ||||
312 | } | ||||||
313 | elsif ( $lifetime eq 'unlimited' ) { | ||||||
314 | 2 | 14 | ($unlimited,$unset,$lifetime) = (1,0,0); | ||||
315 | } | ||||||
316 | elsif ( $lifetime eq 'unset' ) { | ||||||
317 | 1 | 8 | ($unlimited,$unset,$lifetime) = (0,1,0); | ||||
318 | } | ||||||
319 | else { | ||||||
320 | 1 | 12 | $resp->set_message("The parameter must either be an integer, 'unset' or 'unlimited'"); | ||||
321 | 1 | 10 | $resp->set_isok(0); | ||||
322 | 1 | 10 | return $resp; | ||||
323 | } | ||||||
324 | 4 | 240453 | $rc = $self->user_setaccexpdate( $resp, | ||||
325 | $lifetime, | ||||||
326 | $unlimited, | ||||||
327 | $unset ); | ||||||
328 | 4 | 139 | $resp->isok && $self->user_get($resp); | ||||
329 | } | ||||||
330 | 6 | 116 | if ( $resp->isok ) { | ||||
331 | 5 | 258825 | ($seconds,$unlimited,$unset) = $self->user_getaccexpdate($resp); | ||||
332 | 5 | 197 | $resp->set_value( $unlimited ? "unlimited" : $unset ? "unset" : $seconds); | ||||
333 | } | ||||||
334 | |||||||
335 | 6 | 79 | return $resp; | ||||
336 | } | ||||||
337 | |||||||
338 | sub disabletimeint { | ||||||
339 | 8 | 1 | 75 | my $self = shift; | |||
340 | 8 | 128 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
341 | 8 | 49 | my ($seconds,$disable,$unset,$rc); | ||||
342 | |||||||
343 | 8 | 135 | if ( @_ == 1 ) { | ||||
344 | 4 | 29 | $seconds = shift; | ||||
345 | } | ||||||
346 | elsif ( @_ % 2 ) { | ||||||
347 | 1 | 15 | $resp->set_message("Invalid syntax"); | ||||
348 | 1 | 14 | $resp->set_isok(0); | ||||
349 | 1 | 13 | return $resp; | ||||
350 | } | ||||||
351 | elsif ( @_ ) { | ||||||
352 | 2 | 22 | my %opts = @_; | ||||
353 | 2 | 41 | $seconds = $opts{seconds} || ''; | ||||
354 | } | ||||||
355 | else { | ||||||
356 | 1 | 7 | $seconds = ''; | ||||
357 | } | ||||||
358 | |||||||
359 | 7 | 47 | if ( $seconds ) { | ||||
360 | 5 | 102 | if ( $seconds =~ /^\d+$/ ) { | ||||
361 | 1 | 4 | $disable = 0; | ||||
362 | 1 | 6 | $unset = 0; | ||||
363 | } | ||||||
364 | elsif ($seconds eq 'disable') { | ||||||
365 | 1 | 10 | ($disable,$unset,$seconds) = (1,0,0); | ||||
366 | } | ||||||
367 | elsif ($seconds eq 'unset') { | ||||||
368 | 2 | 16 | ($disable,$unset,$seconds) = (0,1,0); | ||||
369 | } | ||||||
370 | else { | ||||||
371 | 1 | 19 | $resp->set_message("The parameter must either be an integer, 'disable' or 'unset'"); | ||||
372 | 1 | 20 | $resp->set_isok(0); | ||||
373 | 1 | 17 | return $resp; | ||||
374 | } | ||||||
375 | |||||||
376 | 4 | 248225 | $rc = $self->user_setdisabletimeint( $resp, | ||||
377 | $seconds, | ||||||
378 | $disable, | ||||||
379 | $unset); | ||||||
380 | 4 | 125 | $resp->isok && $self->user_get($resp); | ||||
381 | } | ||||||
382 | 6 | 122 | if ( $resp->isok ) { | ||||
383 | 5 | 288731 | ($seconds,$disable,$unset) = $self->user_getdisabletimeint( $resp ); | ||||
384 | 5 | 210 | $resp->set_value( $disable ? "disable" : $unset ? "unset" : $seconds ); | ||||
385 | } | ||||||
386 | |||||||
387 | 6 | 86 | return $resp; | ||||
388 | } | ||||||
389 | |||||||
390 | sub maxlgnfails { | ||||||
391 | 7 | 1 | 574 | my $self = shift; | |||
392 | 7 | 122 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
393 | 7 | 38 | my ($failures,$unset,$rc); | ||||
394 | |||||||
395 | 7 | 97 | if ( @_ == 1 ) { | ||||
396 | 3 | 23 | $failures = shift; | ||||
397 | } | ||||||
398 | elsif ( @_ % 2 ) { | ||||||
399 | 1 | 19 | $resp->set_message("Invalid syntax"); | ||||
400 | 1 | 15 | $resp->set_isok(0); | ||||
401 | 1 | 13 | return $resp; | ||||
402 | } | ||||||
403 | elsif ( @_ ) { | ||||||
404 | 2 | 32 | my %opts = @_; | ||||
405 | 2 | 42 | $failures = $opts{failures} || ''; | ||||
406 | } | ||||||
407 | else { | ||||||
408 | 1 | 11 | $failures = ''; | ||||
409 | } | ||||||
410 | |||||||
411 | 6 | 48 | if ( $failures ) { | ||||
412 | 4 | 75 | if ( $failures =~ /^\d+$/ ) { | ||||
413 | 1 | 8 | $unset = 0; | ||||
414 | } | ||||||
415 | elsif ($failures eq 'unset') { | ||||||
416 | 2 | 12 | $failures = 0; | ||||
417 | 2 | 11 | $unset = 1; | ||||
418 | } | ||||||
419 | else { | ||||||
420 | 1 | 13 | $resp->set_message("The parameter must either be an integer or 'unset'"); | ||||
421 | 1 | 13 | $resp->set_isok(0); | ||||
422 | 1 | 9 | return $resp; | ||||
423 | } | ||||||
424 | |||||||
425 | 3 | 195663 | $rc = $self->user_setmaxlgnfails( $resp, | ||||
426 | $failures, | ||||||
427 | $unset); | ||||||
428 | 3 | 99 | $resp->isok && $self->user_get($resp); | ||||
429 | } | ||||||
430 | 5 | 113 | if ( $resp->isok ) { | ||||
431 | 4 | 237487 | ($failures,$unset) = $self->user_getmaxlgnfails( $resp ); | ||||
432 | 4 | 150 | $resp->set_value($unset ? "unset" : $failures); | ||||
433 | } | ||||||
434 | |||||||
435 | 5 | 71 | return $resp; | ||||
436 | } | ||||||
437 | |||||||
438 | sub maxpwdage { | ||||||
439 | 7 | 1 | 41 | my $self = shift; | |||
440 | 7 | 80 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
441 | 7 | 29 | my ($seconds,$unset,$rc); | ||||
442 | |||||||
443 | 7 | 67 | if ( @_ == 1 ) { | ||||
444 | 3 | 15 | $seconds = shift; | ||||
445 | } | ||||||
446 | elsif ( @_ % 2 ) { | ||||||
447 | 1 | 16 | $resp->set_message("Invalid syntax"); | ||||
448 | 1 | 14 | $resp->set_isok(0); | ||||
449 | 1 | 8 | return $resp; | ||||
450 | } | ||||||
451 | elsif ( @_ ) { | ||||||
452 | 2 | 11 | my %opts = @_; | ||||
453 | 2 | 24 | $seconds = $opts{seconds} || ''; | ||||
454 | } | ||||||
455 | else { | ||||||
456 | 1 | 9 | $seconds = ''; | ||||
457 | } | ||||||
458 | |||||||
459 | 6 | 38 | if ( $seconds ) { | ||||
460 | 4 | 53 | if ( $seconds =~ /^\d+$/ ) { | ||||
461 | 1 | 4 | $unset = 0; | ||||
462 | } | ||||||
463 | elsif ($seconds eq 'unset') { | ||||||
464 | 2 | 9 | $seconds = 0; | ||||
465 | 2 | 7 | $unset = 1; | ||||
466 | } | ||||||
467 | else { | ||||||
468 | 1 | 11 | $resp->set_message("The parameter must either be an integer or 'unset'"); | ||||
469 | 1 | 8 | $resp->set_isok(0); | ||||
470 | 1 | 7 | return $resp; | ||||
471 | } | ||||||
472 | |||||||
473 | 3 | 197361 | $rc = $self->user_setmaxpwdage( $resp, | ||||
474 | $seconds, | ||||||
475 | $unset ); | ||||||
476 | 3 | 71 | $resp->isok && $self->user_get($resp); | ||||
477 | } | ||||||
478 | 5 | 64 | if ( $resp->isok ) { | ||||
479 | 4 | 228369 | ($seconds,$unset) = $self->user_getmaxpwdage( $resp ); | ||||
480 | 4 | 123 | $resp->set_value($unset ? "unset" : $seconds); | ||||
481 | } | ||||||
482 | |||||||
483 | 5 | 50 | return $resp; | ||||
484 | } | ||||||
485 | |||||||
486 | sub maxpwdrepchars { | ||||||
487 | 7 | 1 | 44 | my $self = shift; | |||
488 | 7 | 109 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
489 | 7 | 25 | my ($chars,$unset,$rc); | ||||
490 | |||||||
491 | 7 | 67 | if ( @_ == 1 ) { | ||||
492 | 3 | 17 | $chars = shift; | ||||
493 | } | ||||||
494 | elsif ( @_ % 2 ) { | ||||||
495 | 1 | 26 | $resp->set_message("Invalid syntax"); | ||||
496 | 1 | 8 | $resp->set_isok(0); | ||||
497 | 1 | 11 | return $resp; | ||||
498 | } | ||||||
499 | elsif ( @_ ) { | ||||||
500 | 2 | 17 | my %opts = @_; | ||||
501 | 2 | 28 | $chars = $opts{chars} || ''; | ||||
502 | } | ||||||
503 | else { | ||||||
504 | 1 | 5 | $chars = ''; | ||||
505 | } | ||||||
506 | |||||||
507 | 6 | 36 | if ( $chars ) { | ||||
508 | 4 | 53 | if ( $chars =~ /^\d+$/ ) { | ||||
509 | 1 | 7 | $unset = 0; | ||||
510 | } | ||||||
511 | elsif ($chars eq 'unset') { | ||||||
512 | 2 | 12 | $chars = 0; | ||||
513 | 2 | 6 | $unset = 1; | ||||
514 | } | ||||||
515 | else { | ||||||
516 | 1 | 12 | $resp->set_message("The parameter must either be an integer or 'unset'"); | ||||
517 | 1 | 14 | $resp->set_isok(0); | ||||
518 | 1 | 10 | return $resp; | ||||
519 | } | ||||||
520 | 3 | 378107 | $rc = $self->user_setmaxpwdrepchars( $resp, | ||||
521 | $chars, | ||||||
522 | $unset ); | ||||||
523 | 3 | 78 | $resp->isok && $self->user_get($resp); | ||||
524 | } | ||||||
525 | 5 | 72 | if ( $resp->isok ) { | ||||
526 | 4 | 199544 | ($chars,$unset) = $self->user_getmaxpwdrepchars( $resp ); | ||||
527 | 4 | 103 | $resp->set_value($unset ? "unset" : $chars); | ||||
528 | } | ||||||
529 | |||||||
530 | 5 | 50 | return $resp; | ||||
531 | } | ||||||
532 | |||||||
533 | sub minpwdalphas { | ||||||
534 | 7 | 1 | 40 | my $self = shift; | |||
535 | 7 | 71 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
536 | 7 | 24 | my ($chars,$unset,$rc); | ||||
537 | |||||||
538 | 7 | 63 | if ( @_ == 1 ) { | ||||
539 | 3 | 16 | $chars = shift; | ||||
540 | } | ||||||
541 | elsif ( @_ % 2 ) { | ||||||
542 | 1 | 6 | $resp->set_message("Invalid syntax"); | ||||
543 | 1 | 10 | $resp->set_isok(0); | ||||
544 | 1 | 5 | return $resp; | ||||
545 | } | ||||||
546 | elsif ( @_ ) { | ||||||
547 | 2 | 13 | my %opts = @_; | ||||
548 | 2 | 23 | $chars = $opts{chars} || ''; | ||||
549 | } | ||||||
550 | else { | ||||||
551 | 1 | 5 | $chars = ''; | ||||
552 | } | ||||||
553 | |||||||
554 | 6 | 32 | if ( $chars ) { | ||||
555 | 4 | 47 | if ( $chars =~ /^\d+$/ ) { | ||||
556 | 1 | 6 | $unset = 0; | ||||
557 | } | ||||||
558 | elsif ($chars eq 'unset') { | ||||||
559 | 2 | 7 | $chars = 0; | ||||
560 | 2 | 10 | $unset = 1; | ||||
561 | } | ||||||
562 | else { | ||||||
563 | 1 | 13 | $resp->set_message("The parameter must either be an integer or 'unset'"); | ||||
564 | 1 | 12 | $resp->set_isok(0); | ||||
565 | 1 | 8 | return $resp; | ||||
566 | } | ||||||
567 | 3 | 222870 | $rc = $self->user_setminpwdalphas( $resp, | ||||
568 | $chars, | ||||||
569 | $unset ); | ||||||
570 | 3 | 62 | $resp->isok && $self->user_get($resp); | ||||
571 | } | ||||||
572 | 5 | 55 | if ( $resp->isok ) { | ||||
573 | 4 | 214760 | ($chars,$unset) = $self->user_getminpwdalphas( $resp ); | ||||
574 | 4 | 97 | $resp->set_value( $unset ? "unset" : $chars ); | ||||
575 | } | ||||||
576 | |||||||
577 | 5 | 50 | return $resp; | ||||
578 | } | ||||||
579 | |||||||
580 | sub minpwdnonalphas { | ||||||
581 | 7 | 1 | 44 | my $self = shift; | |||
582 | 7 | 82 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
583 | 7 | 29 | my ($chars,$unset,$rc); | ||||
584 | |||||||
585 | 7 | 69 | if ( @_ == 1 ) { | ||||
586 | 3 | 16 | $chars = shift; | ||||
587 | } | ||||||
588 | elsif ( @_ % 2 ) { | ||||||
589 | 1 | 7 | $resp->set_message("Invalid syntax"); | ||||
590 | 1 | 7 | $resp->set_isok(0); | ||||
591 | 1 | 6 | return $resp; | ||||
592 | } | ||||||
593 | elsif ( @_ ) { | ||||||
594 | 2 | 17 | my %opts = @_; | ||||
595 | 2 | 30 | $chars = $opts{chars} || ''; | ||||
596 | } | ||||||
597 | else { | ||||||
598 | 1 | 8 | $chars = ''; | ||||
599 | } | ||||||
600 | |||||||
601 | 6 | 35 | if ( $chars ) { | ||||
602 | 4 | 55 | if ( $chars =~ /^\d+$/ ) { | ||||
603 | 1 | 6 | $unset = 0; | ||||
604 | } | ||||||
605 | elsif ($chars eq 'unset') { | ||||||
606 | 2 | 7 | $chars = 0; | ||||
607 | 2 | 12 | $unset = 1; | ||||
608 | } | ||||||
609 | else { | ||||||
610 | 1 | 12 | $resp->set_message("The parameter must either be an integer or 'unset'"); | ||||
611 | 1 | 10 | $resp->set_isok(0); | ||||
612 | 1 | 10 | return $resp; | ||||
613 | } | ||||||
614 | 3 | 153836 | $rc = $self->user_setminpwdnonalphas( $resp, | ||||
615 | $chars, | ||||||
616 | $unset ); | ||||||
617 | 3 | 67 | $resp->isok && $self->user_get($resp); | ||||
618 | |||||||
619 | } | ||||||
620 | 5 | 62 | if ( $resp->isok ) { | ||||
621 | 4 | 204391 | ($chars,$unset) = $self->user_getminpwdnonalphas( $resp ); | ||||
622 | 4 | 101 | $resp->set_value($unset ? "unset" : $chars); | ||||
623 | } | ||||||
624 | |||||||
625 | 5 | 43 | return $resp; | ||||
626 | } | ||||||
627 | |||||||
628 | sub minpwdlen { | ||||||
629 | 7 | 1 | 42 | my $self = shift; | |||
630 | 7 | 86 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
631 | 7 | 30 | my ($chars,$unset,$rc); | ||||
632 | |||||||
633 | 7 | 67 | if ( @_ == 1 ) { | ||||
634 | 3 | 18 | $chars = shift; | ||||
635 | } | ||||||
636 | elsif ( @_ % 2 ) { | ||||||
637 | 1 | 16 | $resp->set_message("Invalid syntax"); | ||||
638 | 1 | 14 | $resp->set_isok(0); | ||||
639 | 1 | 12 | return $resp; | ||||
640 | } | ||||||
641 | elsif ( @_ ) { | ||||||
642 | 2 | 16 | my %opts = @_; | ||||
643 | 2 | 28 | $chars = $opts{chars} || ''; | ||||
644 | } | ||||||
645 | else { | ||||||
646 | 1 | 5 | $chars = ''; | ||||
647 | } | ||||||
648 | |||||||
649 | 6 | 33 | if ( $chars ) { | ||||
650 | 4 | 50 | if ( $chars =~ /^\d+$/ ) { | ||||
651 | 1 | 5 | $unset = 0; | ||||
652 | } | ||||||
653 | elsif ($chars eq 'unset') { | ||||||
654 | 2 | 9 | $chars = 8; | ||||
655 | 2 | 8 | $unset = 1; | ||||
656 | } | ||||||
657 | else { | ||||||
658 | 1 | 10 | $resp->set_message("The parameter must either be an integer or 'unset'"); | ||||
659 | 1 | 8 | $resp->set_isok(0); | ||||
660 | 1 | 6 | return $resp; | ||||
661 | } | ||||||
662 | 3 | 163495 | $rc = $self->user_setminpwdlen( $resp, | ||||
663 | $chars, | ||||||
664 | $unset ); | ||||||
665 | 3 | 68 | $resp->isok && $self->user_get($resp); | ||||
666 | } | ||||||
667 | 5 | 76 | if ( $resp->isok ) { | ||||
668 | 4 | 242340 | ($chars,$unset) = $self->user_getminpwdlen( $resp ); | ||||
669 | 4 | 111 | $resp->set_value($unset ? "unset" : $chars); | ||||
670 | } | ||||||
671 | |||||||
672 | 5 | 54 | return $resp; | ||||
673 | } | ||||||
674 | |||||||
675 | sub max_concur_session { | ||||||
676 | 10 | 1 | 62 | my $self = shift; | |||
677 | 10 | 125 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
678 | 10 | 45 | my ($session,$unset,$unlimited,$displace,$rc); | ||||
679 | |||||||
680 | 10 | 83 | if ( @_ == 1 ) { | ||||
681 | 6 | 32 | $session = shift; | ||||
682 | } | ||||||
683 | elsif ( @_ % 2 ) { | ||||||
684 | 1 | 11 | $resp->set_message("Invalid syntax"); | ||||
685 | 1 | 7 | $resp->set_isok(0); | ||||
686 | 1 | 6 | return $resp; | ||||
687 | } | ||||||
688 | elsif ( @_ ) { | ||||||
689 | 2 | 17 | my %opts = @_; | ||||
690 | 2 | 30 | $session = $opts{session} || ''; | ||||
691 | } | ||||||
692 | else { | ||||||
693 | 1 | 6 | $session = ''; | ||||
694 | } | ||||||
695 | |||||||
696 | 9 | 51 | if ( $session ) { | ||||
697 | 7 | 103 | if ( $session =~ /^\d+$/ ) { | ||||
698 | 1 | 8 | ($unset,$unlimited,$displace) = (0,0,0); | ||||
699 | } | ||||||
700 | elsif ($session eq 'displace') { | ||||||
701 | 1 | 4 | ($session,$unset,$unlimited,$displace) = (0,0,0,1); | ||||
702 | } | ||||||
703 | elsif ($session eq 'unlimited') { | ||||||
704 | 1 | 7 | ($session,$unset,$unlimited,$displace) = (0,0,1,0); | ||||
705 | } | ||||||
706 | elsif ($session eq 'unset') { | ||||||
707 | 3 | 18 | ($session,$unset,$unlimited,$displace) = (0,1,0,0); | ||||
708 | } | ||||||
709 | else { | ||||||
710 | 1 | 12 | $resp->set_message("The parameter must be either an integers, 'displace', 'unlimited' or 'unset'"); | ||||
711 | 1 | 10 | $resp->set_isok(0); | ||||
712 | 1 | 9 | return $resp; | ||||
713 | } | ||||||
714 | |||||||
715 | 6 | 302247 | $rc = $self->user_setmaxconcurwebsess( $resp, | ||||
716 | $session, | ||||||
717 | $displace, | ||||||
718 | $unlimited, | ||||||
719 | $unset, | ||||||
720 | ); | ||||||
721 | 6 | 145 | $resp->set_value($rc); | ||||
722 | |||||||
723 | } | ||||||
724 | 8 | 84 | if ( $resp->isok ) { | ||||
725 | 7 | 38 | my $retval; | ||||
726 | 7 | 344903 | ($session,$displace,$unlimited,$unset) = $self->user_getmaxconcurwebsess( $resp ); | ||||
727 | |||||||
728 | 7 | 105 | if ($unset) { | ||||
729 | 4 | 29 | $retval = 'unset'; | ||||
730 | } | ||||||
731 | elsif ($displace) { | ||||||
732 | 1 | 10 | $retval = 'displace'; | ||||
733 | } | ||||||
734 | elsif ($unlimited) { | ||||||
735 | 1 | 7 | $retval = 'unlimited'; | ||||
736 | } | ||||||
737 | else { | ||||||
738 | 1 | 10 | $retval = $session; | ||||
739 | } | ||||||
740 | 7 | 107 | $resp->set_value($retval); | ||||
741 | } | ||||||
742 | |||||||
743 | 8 | 92 | return $resp; | ||||
744 | } | ||||||
745 | |||||||
746 | sub pwdspaces { | ||||||
747 | 7 | 1 | 43 | my $self = shift; | |||
748 | 7 | 80 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
749 | 7 | 33 | my ($allowed,$unset,$rc); | ||||
750 | |||||||
751 | 7 | 59 | if ( @_ == 1 ) { | ||||
752 | 3 | 15 | $allowed = shift; | ||||
753 | } | ||||||
754 | elsif ( @_ % 2 ) { | ||||||
755 | 1 | 11 | $resp->set_message("Invalid syntax"); | ||||
756 | 1 | 10 | $resp->set_isok(0); | ||||
757 | 1 | 9 | return $resp; | ||||
758 | } | ||||||
759 | elsif ( @_ ) { | ||||||
760 | 2 | 16 | my %opts = @_; | ||||
761 | 2 | 26 | $allowed = $opts{allowed} || ''; | ||||
762 | } | ||||||
763 | else { | ||||||
764 | 1 | 5 | $allowed = ''; | ||||
765 | } | ||||||
766 | |||||||
767 | 6 | 35 | if ( $allowed ) { | ||||
768 | 4 | 53 | if ($allowed =~ /^\d+$/) { | ||||
769 | 1 | 5 | $unset = 0; | ||||
770 | } | ||||||
771 | elsif ( $allowed eq 'unset' ) { | ||||||
772 | 2 | 8 | $allowed = 0; | ||||
773 | 2 | 9 | $unset = 1; | ||||
774 | } | ||||||
775 | else { | ||||||
776 | 1 | 13 | $resp->set_message("The parameter must either be an integer or 'unset'"); | ||||
777 | 1 | 14 | $resp->set_isok(0); | ||||
778 | 1 | 8 | return $resp; | ||||
779 | } | ||||||
780 | 3 | 146552 | $rc = $self->user_setpwdspaces( $resp, | ||||
781 | $allowed, | ||||||
782 | $unset ); | ||||||
783 | 3 | 67 | $resp->isok && $self->user_get($resp); | ||||
784 | } | ||||||
785 | 5 | 64 | if ( $resp->isok ) { | ||||
786 | 4 | 199744 | ($allowed,$unset) = $self->user_getpwdspaces( $resp ); | ||||
787 | 4 | 100 | $resp->set_value($unset ? "unset" : $allowed ); | ||||
788 | } | ||||||
789 | |||||||
790 | 5 | 48 | return $resp; | ||||
791 | } | ||||||
792 | |||||||
793 | sub tod { | ||||||
794 | 10 | 1 | 103 | my $self = shift; | |||
795 | 10 | 144 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
796 | 10 | 51 | my ( $days, $start, $end, $reference, $unset, $rc ); | ||||
797 | 10 | 43 | my (@list, %rc ); | ||||
798 | |||||||
799 | 10 | 84 | if ( @_ % 2 ) { | ||||
800 | 1 | 11 | $resp->set_message("Invalid syntax"); | ||||
801 | 1 | 10 | $resp->set_isok(0); | ||||
802 | 1 | 9 | return $resp; | ||||
803 | } | ||||||
804 | 9 | 134 | my %opts = @_; | ||||
805 | |||||||
806 | 9 | 86 | $reference = $opts{reference} || ''; | ||||
807 | |||||||
808 | 9 | 180 | if ( $opts{days} ) { | ||||
809 | 8 | 51 | $reference = $reference eq 'UTC'; | ||||
810 | |||||||
811 | 8 | 118 | if ( $opts{days} ne 'unset' ) { | ||||
812 | 7 | 79 | if ( ref($opts{days}) ) { | ||||
813 | 5 | 48 | $days = _listtotod( $opts{days} ) | ||||
814 | } | ||||||
815 | else { | ||||||
816 | 2 | 23 | if ( $opts{days} > 127 ) { | ||||
817 | 1 | 10 | $resp->set_message( "days bitmask > 127"); | ||||
818 | 1 | 5 | $resp->set_isok(0); | ||||
819 | 1 | 11 | return $resp; | ||||
820 | } | ||||||
821 | 1 | 10 | $days = $opts{days}; | ||||
822 | } | ||||||
823 | 6 | 56 | $start = _miltomin( $opts{start} ); | ||||
824 | 6 | 44 | $end = _miltomin( $opts{end} ); | ||||
825 | 6 | 33 | $unset = 0; | ||||
826 | } | ||||||
827 | else { | ||||||
828 | 1 | 9 | $days = $start = $end = 0; | ||||
829 | 1 | 5 | $unset = 1; | ||||
830 | } | ||||||
831 | |||||||
832 | 7 | 389263 | $self->user_settodaccess( $resp, | ||||
833 | $days, | ||||||
834 | $start, | ||||||
835 | $end, | ||||||
836 | $reference, | ||||||
837 | $unset ); | ||||||
838 | 7 | 220 | $resp->isok && $self->user_get($resp); | ||||
839 | } | ||||||
840 | 8 | 192 | if ( $resp->isok ) { | ||||
841 | 7 | 410697 | @list = $self->user_gettodaccess( $resp ); | ||||
842 | 7 | 137 | if ( $list[-1] ) { | ||||
843 | 2 | 20 | $rc{days} = 0; | ||||
844 | 2 | 14 | $rc{start} = 0; | ||||
845 | 2 | 14 | $rc{end} = 0; | ||||
846 | 2 | 22 | $rc{reference} = 'local'; | ||||
847 | 2 | 11 | $rc{unset} = 1; | ||||
848 | } | ||||||
849 | else { | ||||||
850 | 5 | 76 | $rc{days} = [ _todtolist($list[0]) ]; | ||||
851 | 5 | 60 | $rc{start} = _mintomil( $list[1]); | ||||
852 | 5 | 50 | $rc{end} = _mintomil( $list[2]); | ||||
853 | 5 | 60 | $rc{reference} = $list[3] ? 'UTC' : 'local'; | ||||
854 | } | ||||||
855 | |||||||
856 | 7 | 135 | $resp->set_value( \%rc ); | ||||
857 | } | ||||||
858 | 8 | 164 | return $resp; | ||||
859 | } | ||||||
860 | |||||||
861 | sub list { | ||||||
862 | 8 | 1 | 55 | my $class = shift; | |||
863 | 8 | 33 | my $pd; | ||||
864 | 8 | 99 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
865 | |||||||
866 | # I want this to be called as either Tivoli::AccessManager::Admin::User->list or | ||||||
867 | # $self->list | ||||||
868 | 8 | 52 | if ( ref($class) ) { | ||||
869 | 1 | 7 | $pd = $class->{context}; | ||||
870 | } | ||||||
871 | else { | ||||||
872 | 7 | 31 | $pd = shift; | ||||
873 | 7 | 148 | unless ( defined($pd) and UNIVERSAL::isa($pd,'Tivoli::AccessManager::Admin::Context' ) ) { | ||||
874 | 2 | 17 | $resp->set_message("Incorrect syntax -- did you forget the context?"); | ||||
875 | 2 | 18 | $resp->set_isok(0); | ||||
876 | 2 | 9 | return $resp; | ||||
877 | } | ||||||
878 | } | ||||||
879 | |||||||
880 | 6 | 60 | if ( @_ % 2 ) { | ||||
881 | 1 | 13 | $resp->set_message("Invalid syntax"); | ||||
882 | 1 | 9 | $resp->set_isok(0); | ||||
883 | 1 | 9 | return $resp; | ||||
884 | } | ||||||
885 | 5 | 57 | my %opts = @_; | ||||
886 | |||||||
887 | 5 | 54 | $opts{maxreturn} = 0 unless defined( $opts{maxreturn} ); | ||||
888 | 5 | 53 | $opts{pattern} = '*' unless defined( $opts{pattern} ); | ||||
889 | 5 | 51 | $opts{bydn} = 0 unless defined( $opts{bydn} ); | ||||
890 | |||||||
891 | |||||||
892 | 5 | 262851 | my @rc = sort $opts{bydn} ? user_listbydn( $pd, $resp, | ||||
893 | $opts{pattern}, | ||||||
894 | $opts{maxreturn} ) : | ||||||
895 | user_list( $pd, $resp, | ||||||
896 | $opts{pattern}, | ||||||
897 | $opts{maxreturn} ); | ||||||
898 | 5 | 163 | $resp->isok() && $resp->set_value( \@rc ); | ||||
899 | 5 | 107 | return $resp; | ||||
900 | } | ||||||
901 | |||||||
902 | sub groups { | ||||||
903 | 14 | 1 | 277 | my $self = shift; | |||
904 | 14 | 72 | my (@groups, $group); | ||||
905 | 14 | 202 | my $resp = Tivoli::AccessManager::Admin::Response->new; | ||||
906 | 14 | 91 | my @dne = (); | ||||
907 | |||||||
908 | 14 | 115 | if ( @_ % 2 ) { | ||||
909 | 1 | 11 | $resp->set_message("Invalid syntax"); | ||||
910 | 1 | 10 | $resp->set_isok(0); | ||||
911 | 1 | 10 | return $resp; | ||||
912 | } | ||||||
913 | 13 | 105 | my %opts = @_; | ||||
914 | 13 | 108 | if ( defined( $opts{remove} ) ) { | ||||
915 | 4 4 | 16 34 | for my $grp ( @{$opts{remove}} ) { | ||||
916 | 12 | 101 | if ( ref $grp ) { | ||||
917 | 5 | 29 | $group = $grp; | ||||
918 | } | ||||||
919 | else { | ||||||
920 | 7 | 107 | $group = Tivoli::AccessManager::Admin::Group->new( $self->{context}, name => $grp ); | ||||
921 | } | ||||||
922 | 12 | 174 | my $gname = $group->name; | ||||
923 | |||||||
924 | 12 | 130 | if ( $group->exist ) { | ||||
925 | 11 | 187 | $resp = $group->members( remove => [ $self->{name} ] ); | ||||
926 | 11 | 105 | return $resp unless $resp->isok; | ||||
927 | } | ||||||
928 | else { | ||||||
929 | 1 | 35 | push @dne, $gname; | ||||
930 | } | ||||||
931 | } | ||||||
932 | } | ||||||
933 | |||||||
934 | 12 | 107 | if ( defined( $opts{add} ) ) { | ||||
935 | 4 4 | 19 23 | for my $grp ( @{$opts{add}} ) { | ||||
936 | 12 | 120 | if ( ref $grp ) { | ||||
937 | 5 | 35 | $group = $grp; | ||||
938 | } | ||||||
939 | else { | ||||||
940 | 7 | 112 | $group = Tivoli::AccessManager::Admin::Group->new( $self->{context}, name => $grp ); | ||||
941 | } | ||||||
942 | 12 | 208 | my $gname = $group->name; | ||||
943 | |||||||
944 | 12 | 143 | if ( $group->exist ) { | ||||
945 | 11 | 228 | $resp = $group->members( add => [ $self->{name} ] ); | ||||
946 | 11 | 168 | return $resp unless $resp->isok; | ||||
947 | } | ||||||
948 | else { | ||||||
949 | 1 | 34 | push @dne, $gname; | ||||
950 | } | ||||||
951 | } | ||||||
952 | } | ||||||
953 | |||||||
954 | 12 | 970870 | @groups = $self->user_getmemberships( $resp ); | ||||
955 | 12 | 431 | $resp->isok and $resp->set_value(\@groups); | ||||
956 | 12 | 118 | if ( @dne ) { | ||||
957 | 2 | 64 | $resp->set_message("The following groups did not exist: " . join(",",@dne)); | ||||
958 | 2 | 916 | $resp->set_iswarning(1); | ||||
959 | } | ||||||
960 | |||||||
961 | 12 | 195 | return $resp; | ||||
962 | } | ||||||
963 | |||||||
964 | sub userimport { | ||||||
965 | 16 | 1 | 226 | my $self = shift; | |||
966 | 16 | 214 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
967 | |||||||
968 | 16 | 144 | unless ( ref $self ) { | ||||
969 | 8 | 48 | my $pd = shift; | ||||
970 | 8 | 199 | unless ( defined($pd) and UNIVERSAL::isa($pd,'Tivoli::AccessManager::Admin::Context' ) ) { | ||||
971 | 2 | 28 | $resp->set_message("Incorrect syntax -- did you forget the context?"); | ||||
972 | 2 | 21 | $resp->set_isok(0); | ||||
973 | 2 | 22 | return $resp; | ||||
974 | } | ||||||
975 | |||||||
976 | 6 | 71 | if ( @_ % 2 ) { | ||||
977 | 1 | 15 | $resp->set_message("Invalid syntax"); | ||||
978 | 1 | 13 | $resp->set_isok(0); | ||||
979 | 1 | 11 | return $resp; | ||||
980 | } | ||||||
981 | 5 | 43 | $self = new( $self, $pd, @_ ); | ||||
982 | } | ||||||
983 | |||||||
984 | 13 | 286 | if ( @_ % 2 ) { | ||||
985 | 1 | 7 | $resp->set_message("Invalid syntax"); | ||||
986 | 1 | 7 | $resp->set_isok(0); | ||||
987 | 1 | 6 | return $resp; | ||||
988 | } | ||||||
989 | 12 | 128 | my %opts = @_; | ||||
990 | |||||||
991 | 12 | 109 | if ( $self->{exist} ) { | ||||
992 | 2 | 23 | $resp->set_message("Cannot create a user that already exists"); | ||||
993 | 2 | 21 | $resp->set_isok(0); | ||||
994 | 2 | 16 | return $resp; | ||||
995 | } | ||||||
996 | |||||||
997 | 10 | 86 | unless ( $self->{name} ) { | ||||
998 | 3 | 68 | $self->{name} = $opts{name} || ""; | ||||
999 | } | ||||||
1000 | |||||||
1001 | 10 | 82 | unless ( $self->{dn} ) { | ||||
1002 | 3 | 56 | $self->{dn} = $opts{dn} || ""; | ||||
1003 | } | ||||||
1004 | |||||||
1005 | 10 | 132 | $opts{sso} = 0 unless defined($opts{sso}); | ||||
1006 | |||||||
1007 | 10 | 146 | if ( $self->{name} and $self->{dn} ) { | ||||
1008 | 6 | 425470 | my $rc = $self->user_import( $resp, "", $opts{sso} ); | ||||
1009 | 6 | 167 | if ( $resp->isok() ) { | ||||
1010 | 6 | 414928 | my $user = $self->user_get( $resp ); | ||||
1011 | 6 | 213 | $self->{dn} = $self->user_getdn(); | ||||
1012 | 6 | 130 | $self->{name} = $self->user_getid(); | ||||
1013 | 6 | 75 | $self->{cn} = $self->user_getcn(); | ||||
1014 | 6 | 71 | $self->{sn} = $self->user_getsn(); | ||||
1015 | |||||||
1016 | 6 | 45 | $self->{exist} = 1; | ||||
1017 | 6 | 65 | if ( defined($opts{groups}) ) { | ||||
1018 | 1 | 12 | $resp = $self->groups( add => $opts{groups} ); | ||||
1019 | 1 | 16 | return $resp unless $resp->isok; | ||||
1020 | } | ||||||
1021 | 6 | 113 | $resp->isok and $resp->set_value( $self ); | ||||
1022 | } | ||||||
1023 | } | ||||||
1024 | elsif ( $self->{dn} ) { | ||||||
1025 | 2 | 37 | $resp->set_message("You must specify the user's name"); | ||||
1026 | 2 | 31 | $resp->set_isok(0); | ||||
1027 | } | ||||||
1028 | else { | ||||||
1029 | 2 | 27 | $resp->set_message("You must specify the user's dn"); | ||||
1030 | 2 | 23 | $resp->set_isok(0); | ||||
1031 | } | ||||||
1032 | |||||||
1033 | 10 | 159 | return $resp; | ||||
1034 | } | ||||||
1035 | |||||||
1036 | sub accountvalid { | ||||||
1037 | 6 | 1 | 42 | my $self = shift; | |||
1038 | 6 | 73 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
1039 | 6 | 22 | my ($rc,$valid); | ||||
1040 | |||||||
1041 | 6 | 70 | if ( @_ == 1 ) { | ||||
1042 | 2 | 12 | $valid = shift; | ||||
1043 | } | ||||||
1044 | elsif ( @_ % 2 ) { | ||||||
1045 | 1 | 11 | $resp->set_message("Invalid syntax"); | ||||
1046 | 1 | 10 | $resp->set_isok(0); | ||||
1047 | 1 | 9 | return $resp; | ||||
1048 | } | ||||||
1049 | elsif ( @_ ) { | ||||||
1050 | 2 | 21 | my %opts = @_; | ||||
1051 | 2 | 23 | $valid = $opts{valid}; | ||||
1052 | } | ||||||
1053 | |||||||
1054 | # Set | ||||||
1055 | 5 | 29 | if ( defined($valid) ) { | ||||
1056 | 3 | 147688 | $rc = $self->user_setaccountvalid( $resp, $valid ); | ||||
1057 | 3 | 95 | $resp->isok && $self->user_get($resp); | ||||
1058 | } | ||||||
1059 | |||||||
1060 | 5 | 82 | if ( $resp->isok ) { | ||||
1061 | 4 | 130 | $rc = $self->user_getaccountvalid(); | ||||
1062 | 4 | 38 | $resp->set_value( $rc ); | ||||
1063 | } | ||||||
1064 | |||||||
1065 | 5 | 51 | return $resp; | ||||
1066 | } | ||||||
1067 | |||||||
1068 | sub passwordvalid { | ||||||
1069 | 5 | 1 | 30 | my $self = shift; | |||
1070 | 5 | 56 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
1071 | 5 | 17 | my ($rc,$valid); | ||||
1072 | |||||||
1073 | 5 | 84 | if ( @_ == 1 ) { | ||||
1074 | 1 | 5 | $valid = shift; | ||||
1075 | } | ||||||
1076 | elsif ( @_ % 2 ) { | ||||||
1077 | 1 | 28 | $resp->set_message("Invalid syntax"); | ||||
1078 | 1 | 6 | $resp->set_isok(0); | ||||
1079 | 1 | 11 | return $resp; | ||||
1080 | } | ||||||
1081 | elsif ( @_ ) { | ||||||
1082 | 2 | 20 | my %opts = @_; | ||||
1083 | 2 | 20 | $valid = $opts{valid}; | ||||
1084 | } | ||||||
1085 | |||||||
1086 | |||||||
1087 | # 0 is a valid input value. I need to test for definedness | ||||||
1088 | 4 | 29 | if ( defined($valid) ) { | ||||
1089 | 2 | 101535 | $rc = $self->user_setpasswordvalid( $resp, $valid ); | ||||
1090 | 2 | 61 | $resp->isok && $self->user_get($resp); | ||||
1091 | } | ||||||
1092 | 4 | 64 | if ( $resp->isok ) { | ||||
1093 | 4 | 125 | $rc = $self->user_getpasswordvalid(); | ||||
1094 | 4 | 44 | $resp->set_value( $rc ); | ||||
1095 | } | ||||||
1096 | |||||||
1097 | 4 | 22 | return $resp; | ||||
1098 | } | ||||||
1099 | |||||||
1100 | sub ssouser { | ||||||
1101 | 5 | 1 | 43 | my $self = shift; | |||
1102 | 5 | 77 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
1103 | 5 | 25 | my ($rc,$sso); | ||||
1104 | |||||||
1105 | 5 | 79 | if ( @_ == 1 ) { | ||||
1106 | 1 | 11 | $sso = shift; | ||||
1107 | } | ||||||
1108 | elsif ( @_ % 2 ) { | ||||||
1109 | 1 | 7 | $resp->set_message("Invalid ssouser syntax"); | ||||
1110 | 1 | 7 | $resp->set_isok(0); | ||||
1111 | 1 | 5 | return $resp; | ||||
1112 | } | ||||||
1113 | elsif ( @_ ) { | ||||||
1114 | 2 | 15 | my %opts = @_; | ||||
1115 | 2 | 44 | $sso = $opts{sso} || 0; | ||||
1116 | } | ||||||
1117 | |||||||
1118 | # Set | ||||||
1119 | 4 | 35 | if ( defined($sso) ) { | ||||
1120 | 3 | 167028 | $rc = $self->user_setssouser( $resp, $sso ); | ||||
1121 | 3 | 93 | $resp->isok && $self->user_get($resp); | ||||
1122 | } | ||||||
1123 | 4 | 98 | if ( $resp->isok ) { | ||||
1124 | 4 | 160 | $rc = $self->user_getssouser(); | ||||
1125 | 4 | 54 | $resp->set_value( $rc ); | ||||
1126 | } | ||||||
1127 | |||||||
1128 | 4 | 50 | return $resp; | ||||
1129 | } | ||||||
1130 | |||||||
1131 | sub password { | ||||||
1132 | 5 | 1 | 37 | my $self = shift; | |||
1133 | 5 | 66 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
1134 | 5 | 27 | my ($password,$rc); | ||||
1135 | |||||||
1136 | 5 | 62 | if ( @_ == 1 ) { | ||||
1137 | 2 | 15 | $password = shift; | ||||
1138 | } | ||||||
1139 | elsif ( @_ % 2 ) { | ||||||
1140 | 1 | 8 | $resp->set_message("Invalid password syntax"); | ||||
1141 | 1 | 11 | $resp->set_isok(0); | ||||
1142 | 1 | 8 | return $resp; | ||||
1143 | } | ||||||
1144 | elsif ( @_ ) { | ||||||
1145 | 1 | 9 | my %opts = @_; | ||||
1146 | 1 | 13 | $password = $opts{password}; | ||||
1147 | } | ||||||
1148 | |||||||
1149 | # Set | ||||||
1150 | 4 | 22 | if ( defined($password)) { | ||||
1151 | 3 | 224701 | $rc = $self->user_setpassword( $resp, $password ); | ||||
1152 | 3 | 109 | $resp->set_value( $rc ); | ||||
1153 | } | ||||||
1154 | else { | ||||||
1155 | 1 | 10 | $resp->set_message("There is no passwordget!"); | ||||
1156 | 1 | 11 | $resp->set_isok(0); | ||||
1157 | } | ||||||
1158 | |||||||
1159 | 4 | 42 | return $resp; | ||||
1160 | } | ||||||
1161 | |||||||
1162 | sub DESTROY { | ||||||
1163 | 34 | 333 | my $self = shift; | ||||
1164 | |||||||
1165 | 34 | 919 | $self->_userfree; | ||||
1166 | } | ||||||
1167 | |||||||
1168 | 4 | 1 | 140 | sub exist { $_[0]->{exist} } | |||
1169 | 5 | 1 | 84 | sub name { $_[0]->{name} } | |||
1170 | 1 | 1 | 26 | sub cn { $_[0]->{cn} } | |||
1171 | 1 | 1 | 23 | sub dn { $_[0]->{dn} } | |||
1172 | 1; | ||||||
1173 | |||||||
1174 - 1618 | =head1 NAME Tivoli::AccessManager::Admin::User =head1 SYNOPSIS use Tivoli::AccessManager::Admin my $pd = Tivoli::AccessManager::Admin->new( password => 'N3ew0nk' ); my (@users,$resp); # Lets see who is there $resp = Tivoli::AccessManager::Admin::User->list( $pd, pattern => "luser*", maxreturn => 0 ); print join("\n", $resp->value); # Lets search by DN instead $resp = Tivoli::AccessManager::Admin::User->list( $pd, pattern => "luser*", maxreturn => 0, bydn => 1 ); print join("\n", $resp->value); # Lets create three new users, the easy way for my $i ( 0 .. 2 ) { my $name = sprintf "luser%02d", $i; $resp = Tivoli::AccessManager::Admin::User->create( $pd, name => $name, dn => "cn=$name,ou=people,o=rox,c=us", sn => "Luser", cn => "$name", password => 'neeWonk'); $users[$i] = $resp->value if $resp->isok; # Mark the account valid $resp = $users[$i]->accountvalid(1); # But force them to change the password on login $resp = $users[$i]->passwordvalid(0); } # A slightly different way to create a user push @users, Tivoli::AccessManager::Admin::User->new( $pd, name => 'luser03', dn => 'cn=luser03,ou=people,o=rox,c=us', sn => 'Luser', cn => 'luser03' ); $resp = $users[-1]->create( password => 'Wonknee' ); # Oops. That last one was a mistake $resp = $users[-1]->delete; # Oops. Deleting luser03 was a mistake. Good thing we didn't remove her # from the registry $resp = $users[-1]->userimport; $resp = $users[-1]->password("Fjord!"); # Nah. Delete luser03 completely. $resp = $users[-1]->delete(1); # Hmm, lets put luser00 in a few groups $resp = $users[0]->groups( groups => [qw/sheep coworker/] ); =head1 DESCRIPTION L<Tivoli::AccessManager::Admin::User> implements the User portion of the TAM API. There is a fair amount of overlap between L<Tivoli::AccessManager::Admin::User> and L<Tivoli::AccessManager::Admin::Context>. Since I am a lazy POD writer, I will refer you to that FM when appropriate. =head1 CONSTRUCTOR =head2 new( PDADMIN[, name =E<gt> NAME, dn =E<gt> DN, cn =E<gt> CN, sn =E<gt> SN] ) Creates a blessed L<Tivoli::AccessManager::Admin::User> object. As with everything else, you will need to destroy the object if you want to change the context. =head3 Parameters =over 4 =item PDADMIN An initialized L<Tivoli::AccessManager::Admin::Context> object. This is the only required parameter. =item name =E<gt> NAME The user's name, aka, the userid. If this parameter is provided, L</"new"> will try to determine if the user is already known to TAM. If the user is, all the fields ( cn, sn and dn ) will be retrieved from TAM. =item dn =E<gt> DN The user's DN. If this value is provided (but L</"name"> is not), L</"new"> will look to see if the user is already defined. If the user is, the other fields (name, cn and sn) will be retrieved from TAM. =item cn =E<gt> CN The user's common name. Nothing special happens if you provide the cn. =item sn =E<gt> SN The user's surname. There is nothing special about this parameter either. =back =head3 Returns A fully blessed L<Tivoli::AccessManager::Admin::User> object, with an embedded context. =head1 CLASS METHODS Class methods behave like instance methods -- they return L<Tivoli::AccessManager::Admin::Response> objects. =head2 list(PDADMIN [,maxreturn =E<gt> N, pattern =E<gt> STRING, bydn => 1]) Lists some subset of the TAM users. There is no export available -- it would quickly become gruesome with all the other module's lists. =head3 Parameters =over 4 =item PDADMIN A fully blessed L<Tivoli::AccessManager::Admin::Context> object. Since this is a class method, and L<Tivoli::AccessManager::Admin::Context> objects are stored in the instances, you must provide it. =item maxreturn =E<gt> N The number of users to return from the query. This will default to 0, which means all users matching the pattern. Depending on how your LDAP is configured, this may cause issues. =item pattern =E<gt> STRING The pattern to search on. The standard rules for TAM searches apply -- * and ? are legal wild cards. If not specified, it will default to *, which may cause issues with your LDAP. =item bydn => 1 Changes the search from UID to DN. Do be aware that this will return all the inetOrgPerson objects in the LDAP, not just the TAMified users. =back =head3 Returns The resulting list of users. =head1 METHODS All of the methods return a L<Tivoli::AccessManager::Admin::Response> object. See the documentation for that module on how to coax the values out. The methods, for the most part, follow the same pattern. If the optional parameters are sent, it has the effect of setting the attributes. All methods calls will embed the results of a 'get' in the L<Tivoli::AccessManager::Admin::Response> object. =head2 create( password =E<gt> 'password'[, sso =E<gt> 0|1, nopwdpolicy =E<gt> 0|1, groups =E<gt> [qw/list of groups/][, name =E<gt> NAME, dn =E<gt> DN, cn =E<gt> CN, sn =E<gt> SN] ) Crikey. That's an awful number of options, isn't it? L</"create">, as you might suspect, creates a user in TAM. You can call L</"create"> instead of L</"new"> and retrieve the L<Tivoli::AccessManager::Admin::User> object out of the Response object. =head3 Parameters =over 4 =item password =E<gt> 'password' The new user's password. This is the only required parameter. =item sso =E<gt> 0|1 Controls if the user is created as a GSO user. It defaults to false. =item nopwdpolicy =E<gt> 0|1 Determines if the password policy is ignored when the user is created. Defaults to false -- which is to say the default password policy will be enforced. =item groups =E<gt> [qw/list of a groups/] A reference to an array containing the list of groups to which the user will be added upon creation. Defaults to the empty list. =item name =E<gt> NAME =item dn =E<gt> DN =item cn =E<gt> CN =item sn =E<gt> SN These are the same as defined in L</"new"> and each one is required only if you did not provide it to L</"new"> or if you are calling L</"create"> instead of L</"new">. =back =head3 Returns The success or failure of the operation if L</"new"> was used, the new L<Tivoli::AccessManager::Admin::User> object if not. If the name, the DN, the CN and the SN are not present, you will get an error message. =head2 userimport([name =E<gt> NAME, dn =E<gt> DN, groups =E<gt> [qw/list of groups], sso =E<gt> 0|1) "TAMifies" an existing user in the LDAP. I would have loved to simply name this import, but that had some very unfortunate side affects. As with L</"create">, you can call this method to initialize the L<Tivoli::AccessManager::Admin::User> object. =head3 Parameters =over 4 =item name =E<gt> NAME The user's ID. This is optional if you provided it to L</"new">. =item dn =E<gt> DN The user's DN. This too is optional if you provided it to L</"new">. =item groups =E<gt> [ qw/ list of groups/ ] The groups the imported user is to be granted membership. =item sso =E<gt> 0 | 1 Import the user as a GSO user or not. Defaults to "not". =back =head3 Returns The success of the operation. If you called L</"userimport"> instead of L</"new">, you will get the L<Tivoli::AccessManager::Admin::User> object. =head2 delete(0|1) Deletes the user from TAM. =head3 Parameters =over 4 =item 0 | 1 Controls deleting the user from the registry. This is an optional parameter and will default to 0. =back =head3 Returns The result of the operation =head2 groups([ remove =E<gt> [qw/list of groups/], add =E<gt> [qw/list of groups/] ] ) Adds the user to the listed groups, removes them from another list or simply returns the user's groups. =head3 Parameters =over 4 =item add =E<gt> [ qw/ list of groups/ ] The list of groups to which the user will be added. =item remove =E<gt> [ qw/ list of groups/ ] The list of groups from which the user will be removed. If both the add and the remove tag are provided, the removes are processed first. =back =head3 Returns The user's group memberships after the removes and adds are processed. If some of the specified groups do not exist, they will be listed in the error message from the L<Tivoli::AccessManager::Admin::Response> object and the iswarning flag will be set. I wish I had a better way of returning interesting error info. =head2 accountvalid( 0|1 ) Marks the user's account valid or not =head3 Parameters =over 4 =item 0|1 0 sets the account invalid, 1 sets it valid. =back =head3 Returns 1 if the account is valid, 0 if not. =head2 password( STR ) Changes the user's password to the specified value =head3 Parameters =over 4 =item STR The new password =back =head3 Returns The success of the operation. Kindly note that there is no get password function =head2 description( STR ) Changes the user's description to the specified value =head3 Parameters =over 4 =item STR The new description =back =head3 Returns The user's description. =head2 passwordvalid( 0|1 ) Marks the user's password valid or not =head3 Parameters =over 4 =item 0|1 0 sets the password invalid, 1 sets it valid. =back =head3 Returns 1 if the password is valid, 0 if not. =head2 ssouser( 0|1 ) Marks the user as a GSO enabled user. =head3 Parameters =over 4 =item 0|1 Disable or enable GSO for the user, respectively. =back =head3 Returns 1 if the user is GSO enabled, 0 otherwise. =head2 exist Returns true if the user is known to TAM. =head2 name Returns the user's ID, if known. =head2 accexpdate =head2 disabletimeint =head2 maxlgnfails =head2 tod =head2 maxpwdage =head2 maxpwdrepchars =head2 minpwdalphas =head2 minpwdnonalphas =head2 minpwdlen =head2 pwdspaces =head2 max_concur_session These are identical to the same named functions in L<Tivoli::AccessManager::Admin::Context>. See that very fine manual for documentation. I will repeat one caveat here. If you perform a get on a non-existent user, the functions will not return an error. No idea why not. =head1 TODO The interface to accexpdate blows chunketh. It needs to become significantly smarter -- I want it to be able to accept: 10 days from now ( which would be 11/27/2004 as of this note ) 11/27/2004-12:00:00 86400 * 10 1101588906 and each one of those should do the same thing. =head1 ACKNOWLEDGEMENTS See L<Tivoli::AccessManager::Admin> for the list. This was not possible without the help of a bunch of people smarter than I. =head1 BUGS Should L</"list"> return a list of names, or a list of L<Tivoli::AccessManager::Admin::User> objects? =head1 AUTHOR Mik Firestone E<lt>mikfire@gmail.comE<gt> =head1 COPYRIGHT Copyright (c) 2004-2011 Mik Firestone. All rights reserved. This program is free software; you can redistibute it and/or modify it under the same terms as Perl itself. All references to TAM, Tivoli Access Manager, etc are copyrighted, trademarked and otherwise patented by IBM. =cut | ||||||
1619 |