File: | /home/mik/work/module/Tivoli/AccessManager/Admin/Group.pm |
Coverage: | 99.6% |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package Tivoli::AccessManager::Admin::Group; | ||||||
2 | 15 15 15 | 260 54 428 | use strict; | ||||
3 | 15 15 15 | 198 58 211 | use warnings; | ||||
4 | 15 15 15 | 186 51 279 | use Carp; | ||||
5 | |||||||
6 | #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | ||||||
7 | # $Id: Group.pm 329 2006-11-20 19:01:01Z mik $ | ||||||
8 | #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | ||||||
9 | $Tivoli::AccessManager::Admin::Group::VERSION = '0.04'; | ||||||
10 | 15 | 205 | use Inline( C => 'DATA', | ||||
11 | INC => '-I/opt/PolicyDirector/include', | ||||||
12 | LIBS => ' -lpthread -lpdadminapi -lstdc++', | ||||||
13 | CCFLAGS => '-Wall', | ||||||
14 | # VERSION => '0.04', | ||||||
15 | NAME => 'Tivoli::AccessManager::Admin::Group', | ||||||
16 | 15 15 | 181 45 | ); | ||||
17 | 15 15 15 | 192 55 230 | use Tivoli::AccessManager::Admin::Response; | ||||
18 | |||||||
19 | sub new { | ||||||
20 | 48 | 1 | 411 | my $class = shift; | |||
21 | 48 | 4062 | my $cont = shift; | ||||
22 | 48 | 530 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
23 | |||||||
24 | 48 | 1025 | unless (defined($cont) and UNIVERSAL::isa($cont,'Tivoli::AccessManager::Admin::Context')) { | ||||
25 | 2 | 58 | warn "Incorrect syntax -- did you forget the context?\n"; | ||||
26 | 2 | 18 | return undef; | ||||
27 | } | ||||||
28 | |||||||
29 | 46 | 707 | if (@_ % 2) { | ||||
30 | 3 | 92 | warn "Invalid syntax -- you did not send a hash\n"; | ||||
31 | 3 | 31 | return undef; | ||||
32 | } | ||||||
33 | 43 | 458 | my %opts = @_; | ||||
34 | |||||||
35 | 43 | 344 | my $self = bless {}, $class; | ||||
36 | |||||||
37 | 43 | 533 | $self->{name} = $opts{name} || ''; | ||||
38 | 43 | 477 | $self->{cn} = $opts{cn} || ''; | ||||
39 | 43 | 368 | $self->{dn} = $opts{dn} || ''; | ||||
40 | 43 | 206 | $self->{exist} = 0; | ||||
41 | 43 | 501 | $self->_groupstore(); | ||||
42 | 43 | 247 | $self->{context} = $cont; | ||||
43 | |||||||
44 | 43 | 276 | if ($self->{dn}) { | ||||
45 | 19 | 917731 | my $rc = $self->group_getbydn($resp); | ||||
46 | |||||||
47 | # The group already exists | ||||||
48 | 19 | 530 | if ($resp->isok()) { | ||||
49 | 3 | 78 | $self->{dn} = $self->group_getdn(); | ||||
50 | 3 | 55 | $self->{cn} = $self->group_getcn(); | ||||
51 | 3 | 50 | $self->{name} = $self->group_getname(); | ||||
52 | 3 | 158100 | $self->{exist} = $self->group_get($resp); | ||||
53 | } | ||||||
54 | } | ||||||
55 | |||||||
56 | 43 | 706 | if ($self->{name} and not $self->{exist}) { | ||||
57 | 36 | 2010087 | my $rc = $self->group_get($resp); | ||||
58 | 36 | 982 | if ($resp->isok) { | ||||
59 | 15 | 337 | $self->{dn} = $self->group_getdn(); | ||||
60 | 15 | 241 | $self->{cn} = $self->group_getcn(); | ||||
61 | 15 | 241 | $self->{exist} = 1; | ||||
62 | } | ||||||
63 | } | ||||||
64 | |||||||
65 | 43 | 505 | return $self; | ||||
66 | } | ||||||
67 | |||||||
68 | sub create { | ||||||
69 | 24 | 1 | 230 | my $self = shift; | |||
70 | 24 | 315 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
71 | 24 | 87 | my $rc; | ||||
72 | |||||||
73 | 24 | 184 | unless (ref $self) { | ||||
74 | 13 | 50 | my $pd = shift; | ||||
75 | 13 | 114 | $self = new($self, $pd, @_); | ||||
76 | } | ||||||
77 | |||||||
78 | 24 | 481 | if (@_ % 2) { | ||||
79 | 1 | 12 | $resp->set_message("Invalid syntax"); | ||||
80 | 1 | 10 | $resp->set_isok(0); | ||||
81 | 1 | 10 | return $resp; | ||||
82 | } | ||||||
83 | 23 | 302 | my %opts = @_; | ||||
84 | |||||||
85 | 23 | 169 | if ($self->{exist}) { | ||||
86 | 1 | 12 | $resp->set_message("The group $self->{name} already exists"); | ||||
87 | 1 | 9 | $resp->set_iswarning(1); | ||||
88 | 1 | 6 | $resp->set_value($self); | ||||
89 | |||||||
90 | 1 | 10 | return $resp; | ||||
91 | } | ||||||
92 | |||||||
93 | 22 | 322 | $self->{name} = $opts{name} || $self->{name} || ''; | ||||
94 | 22 | 271 | $self->{dn} = $opts{dn} || $self->{dn} || ''; | ||||
95 | 22 | 324 | $self->{cn} = $opts{cn} || $self->{cn} || ''; | ||||
96 | |||||||
97 | 22 | 243 | $self->{cn} = $self->{name} unless $opts{cn}; | ||||
98 | |||||||
99 | 22 | 374 | if ($self->{cn} and $self->{dn} and $self->{name}) { | ||||
100 | 17 | 1255893 | $rc = $self->group_create($resp, $opts{container} || ""); | ||||
101 | 17 | 509 | if ($resp->isok) { | ||||
102 | 16 | 118 | $self->{exist} = 1; | ||||
103 | 16 | 179 | $resp->set_value($self); | ||||
104 | } | ||||||
105 | } | ||||||
106 | else { | ||||||
107 | 5 | 67 | $resp->set_message("Syntax error in creating group -- the cn, dn and name must be defined"); | ||||
108 | 5 | 51 | $resp->set_isok(0); | ||||
109 | 5 | 37 | $resp->set_value('undef'); | ||||
110 | } | ||||||
111 | |||||||
112 | 22 | 338 | return $resp; | ||||
113 | } | ||||||
114 | |||||||
115 | sub delete { | ||||||
116 | 24 | 1 | 199 | my $self = shift; | |||
117 | |||||||
118 | 24 | 347 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
119 | |||||||
120 | 24 | 204 | if ($self->{exist}) { | ||||
121 | 23 | 79 | my $rc; | ||||
122 | 23 | 90 | my $reg = 0; | ||||
123 | |||||||
124 | 23 | 249 | if (@_ == 1) { | ||||
125 | 9 | 32 | $reg = shift; | ||||
126 | } | ||||||
127 | elsif (@_ % 2) { | ||||||
128 | 1 | 18 | $resp->set_message("Invalid syntax"); | ||||
129 | 1 | 17 | $resp->set_isok(0); | ||||
130 | 1 | 20 | return $resp; | ||||
131 | } | ||||||
132 | elsif (@_) { | ||||||
133 | 8 | 80 | my %opts = @_; | ||||
134 | 8 | 125 | $reg = $opts{registry} || 0; | ||||
135 | } | ||||||
136 | |||||||
137 | 22 | 1825443 | $rc = $self->group_delete($resp,$reg); | ||||
138 | 22 | 697 | if ($resp->isok) { | ||||
139 | 21 | 644 | $resp->set_value($rc); | ||||
140 | 21 | 350 | $self->_groupfree; | ||||
141 | 21 | 269 | $self->{exist} = 0; | ||||
142 | } | ||||||
143 | } | ||||||
144 | else { | ||||||
145 | 1 | 15 | $resp->set_message("The specified group does not exist"); | ||||
146 | 1 | 10 | $resp->set_isok(0); | ||||
147 | } | ||||||
148 | |||||||
149 | 23 | 261 | return $resp; | ||||
150 | } | ||||||
151 | |||||||
152 | sub description { | ||||||
153 | 8 | 1 | 60 | my $self = shift; | |||
154 | 8 | 118 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
155 | |||||||
156 | 8 | 66 | if ($self->{exist}) { | ||||
157 | 7 | 32 | my $desc = ''; | ||||
158 | |||||||
159 | 7 | 72 | if (@_ == 1) { | ||||
160 | 2 | 15 | $desc = shift; | ||||
161 | } | ||||||
162 | elsif (@_ % 2) { | ||||||
163 | 1 | 12 | $resp->set_message("Invalid syntax"); | ||||
164 | 1 | 18 | $resp->set_isok(0); | ||||
165 | 1 | 12 | return $resp; | ||||
166 | } | ||||||
167 | elsif (@_) { | ||||||
168 | 2 | 18 | my %opts = @_; | ||||
169 | 2 | 42 | $desc = $opts{description} || ''; | ||||
170 | } | ||||||
171 | |||||||
172 | 6 | 35 | if ($desc) { | ||||
173 | 3 | 175666 | my $rc = $self->group_setdescription($resp, $desc); | ||||
174 | 3 | 94 | $resp->isok && $self->group_get($resp); | ||||
175 | } | ||||||
176 | 6 | 88 | if ($resp->isok) { | ||||
177 | 5 | 150 | $resp->set_value($self->group_getdescription || ''); | ||||
178 | } | ||||||
179 | } | ||||||
180 | else { | ||||||
181 | 1 | 11 | $resp->set_message("The group does not yet exist"); | ||||
182 | 1 | 10 | $resp->set_isok(0); | ||||
183 | } | ||||||
184 | |||||||
185 | 7 | 65 | return $resp; | ||||
186 | } | ||||||
187 | |||||||
188 | sub cn { | ||||||
189 | 2 | 1 | 32 | my $self = shift; | |||
190 | |||||||
191 | 2 | 21 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
192 | |||||||
193 | 2 | 20 | if ($self->{cn}) { | ||||
194 | 1 | 10 | $resp->set_value($self->{cn}); | ||||
195 | } | ||||||
196 | else { | ||||||
197 | 1 | 15 | $resp->set_message("The cn for this group is not defined"); | ||||
198 | 1 | 37 | $resp->set_isok(0); | ||||
199 | } | ||||||
200 | 2 | 17 | return $resp; | ||||
201 | } | ||||||
202 | |||||||
203 | sub dn { | ||||||
204 | 6 | 1 | 60 | my $self = shift; | |||
205 | |||||||
206 | 6 | 71 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
207 | |||||||
208 | 6 | 52 | if ($self->{dn}) { | ||||
209 | 4 | 39 | $resp->set_value($self->{dn}); | ||||
210 | } | ||||||
211 | else { | ||||||
212 | 2 | 20 | $resp->set_message("The dn for this group is not defined"); | ||||
213 | 2 | 16 | $resp->set_isok(0); | ||||
214 | } | ||||||
215 | 6 | 40 | return $resp; | ||||
216 | } | ||||||
217 | |||||||
218 | sub _addmembers { | ||||||
219 | 16 | 98 | my $self = shift; | ||||
220 | 16 | 207 | my %opts = @_; | ||||
221 | |||||||
222 | 16 | 89 | my (%hash, @junc,@add); | ||||
223 | |||||||
224 | 16 | 255 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
225 | # This is suckage. I need to make sure there are no duplicates in the add | ||||||
226 | # list. | ||||||
227 | 16 33 16 | 95 340 128 | %hash = map { $_ => 1 } @{$opts{add}}; | ||||
228 | 16 | 207 | @add = keys %hash; | ||||
229 | |||||||
230 | # We need to translate the existing users into a hash for the next step. | ||||||
231 | # This also forces the names to lower case. | ||||||
232 | 16 14 14 16 | 117 72 90 120 | %hash = map { my $f = lc $_; $f => 1 } @{$opts{existing}}; | ||||
233 | |||||||
234 | # Finally. Create a list of all the users in the add list that are not in | ||||||
235 | # the existing list. | ||||||
236 | 16 33 | 107 283 | @junc = grep { not $hash{lc($_)} } @add; | ||||
237 | |||||||
238 | # In theory, the two lists (those we are adding and those who are not in | ||||||
239 | # the list) should be the same. | ||||||
240 | 16 | 258 | if (@junc != @add and $opts{force}) { | ||||
241 | 2 | 17 | @add = @junc; | ||||
242 | 2 | 35 | unless (@add) { | ||||
243 | 1 | 20 | $resp->set_message("All of the users are already members in $self->{name}"); | ||||
244 | 1 | 15 | $resp->set_iswarning(1); | ||||
245 | 1 | 16 | return $resp; | ||||
246 | } | ||||||
247 | } | ||||||
248 | elsif (@junc != @add) { | ||||||
249 | 1 | 14 | my $message = "The following users are already in $self->{name}: "; | ||||
250 | 1 1 | 7 20 | $resp->set_message($message . join(", ", @{$opts{existing}})); | ||||
251 | 1 | 16 | $resp->set_value([@junc]); | ||||
252 | 1 | 11 | $resp->set_iswarning(1); | ||||
253 | 1 | 16 | return $resp; | ||||
254 | } | ||||||
255 | |||||||
256 | 14 | 1026814 | my $rc = $self->group_addmembers($resp,\@add); | ||||
257 | |||||||
258 | 14 | 666 | return $resp; | ||||
259 | } | ||||||
260 | |||||||
261 | sub _removemembers { | ||||||
262 | 16 | 94 | my $self = shift; | ||||
263 | 16 | 163 | my %opts = @_; | ||||
264 | |||||||
265 | 16 | 88 | my (%hash, @intersect, @rem); | ||||
266 | |||||||
267 | 16 | 208 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
268 | 16 21 21 16 | 70 98 213 114 | %hash = map { my $f = lc $_; $f => 1 } @{$opts{remove}}; | ||||
269 | 16 | 167 | @rem = keys %hash; | ||||
270 | |||||||
271 | 16 27 27 16 | 76 101 211 95 | %hash = map { my $f = lc $_; $f => 1 } @{$opts{existing}}; | ||||
272 | 16 21 | 104 141 | @intersect = grep { $hash{$_} } @rem; | ||||
273 | |||||||
274 | 16 | 229 | if (@intersect != @rem and $opts{force}) { | ||||
275 | 2 | 18 | unless (@intersect) { | ||||
276 | 1 | 12 | $resp->set_message("There are no members to remove"); | ||||
277 | 1 | 10 | $resp->set_iswarning(1); | ||||
278 | 1 | 17 | return $resp; | ||||
279 | } | ||||||
280 | 1 | 19 | @rem = @intersect; | ||||
281 | } | ||||||
282 | elsif (@intersect != @rem) { | ||||||
283 | 2 3 | 10 37 | %hash = map {$_ => 1} @rem; | ||||
284 | 2 2 | 8 24 | delete $hash{lc($_)} for @intersect; | ||||
285 | |||||||
286 | 2 | 32 | my $message = "The following are not in $self->{name}: "; | ||||
287 | 2 | 32 | $resp->set_message($message, join(", ", keys %hash)); | ||||
288 | 2 | 26 | $resp->set_isok(0); | ||||
289 | 2 | 22 | return $resp; | ||||
290 | } | ||||||
291 | |||||||
292 | 13 | 823419 | my $rc = $self->group_removemembers($resp, \@rem); | ||||
293 | |||||||
294 | 13 | 478 | return $resp; | ||||
295 | } | ||||||
296 | |||||||
297 | sub members { | ||||||
298 | 41 | 1 | 263 | my $self = shift; | |||
299 | 41 | 574 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
300 | 41 | 636 | my %job = (add => \&_addmembers, | ||||
301 | remove => \&_removemembers); | ||||||
302 | |||||||
303 | 41 | 389 | if (@_ % 2) { | ||||
304 | 1 | 12 | $resp->set_message("Invalid syntax"); | ||||
305 | 1 | 12 | $resp->set_isok(0); | ||||
306 | 1 | 12 | return $resp; | ||||
307 | } | ||||||
308 | 40 | 270 | my %opts = @_; | ||||
309 | |||||||
310 | 40 | 356 | $opts{force} = defined($opts{force}) ? $opts{force} : 0; | ||||
311 | 40 | 290 | unless ($self->{exist}) { | ||||
312 | 1 | 14 | $resp->set_message("The group does not exist"); | ||||
313 | 1 | 10 | $resp->set_isok(0); | ||||
314 | 1 | 11 | return $resp; | ||||
315 | } | ||||||
316 | |||||||
317 | # Get the list of users, | ||||||
318 | 39 | 2633754 | my @rc = sort $self->group_getmembers($resp); | ||||
319 | 39 | 1167 | return $resp unless ($resp->isok); | ||||
320 | |||||||
321 | 36 | 592 | unless (defined($opts{add}) or defined($opts{remove})) { | ||||
322 | 3 | 53 | $resp->set_value(\@rc); | ||||
323 | 3 | 78 | return $resp; | ||||
324 | } | ||||||
325 | |||||||
326 | 33 | 241 | for my $action (qw/remove add/) { | ||||
327 | 63 | 1022 | if (defined($opts{$action}) and ref($opts{$action}) eq 'ARRAY') { | ||||
328 | 32 | 628 | $resp = $job{$action}-> ($self, %opts, existing => \@rc) ; | ||||
329 | 32 | 496 | return $resp unless $resp->isok; | ||||
330 | } | ||||||
331 | elsif (defined($opts{$action})) { | ||||||
332 | 2 | 30 | $resp->set_message("Invalid syntax: $action => array ref"); | ||||
333 | 2 | 15 | $resp->set_isok(0); | ||||
334 | 2 | 47 | return $resp; | ||||
335 | } | ||||||
336 | 59 | 4078727 | @rc = sort $self->group_getmembers($resp); | ||||
337 | 59 | 1796 | return $resp unless $resp->isok; | ||||
338 | } | ||||||
339 | 29 | 546 | $resp->set_value(\@rc); | ||||
340 | 29 | 743 | return $resp; | ||||
341 | } | ||||||
342 | |||||||
343 | sub list { | ||||||
344 | 7 | 1 | 50 | my $class = shift; | |||
345 | 7 | 115 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
346 | 7 | 28 | my $pd; | ||||
347 | |||||||
348 | # I want this to be called as either Tivoli::AccessManager::Admin::Group->list of | ||||||
349 | # $self->list | ||||||
350 | 7 | 44 | if (ref $class) { | ||||
351 | 4 | 29 | $pd = $class->{context}; | ||||
352 | } | ||||||
353 | else { | ||||||
354 | 3 | 18 | $pd = shift; | ||||
355 | } | ||||||
356 | |||||||
357 | 7 | 50 | if (@_ % 2) { | ||||
358 | 1 | 19 | $resp->set_message("Invalid syntax"); | ||||
359 | 1 | 16 | $resp->set_isok(0); | ||||
360 | 1 | 16 | return $resp; | ||||
361 | } | ||||||
362 | 6 | 62 | my %opts = @_; | ||||
363 | 6 | 68 | $opts{bydn} ||= 0; | ||||
364 | |||||||
365 | 6 | 72 | $opts{maxreturn} = 0 unless defined($opts{maxreturn}); | ||||
366 | 6 | 46 | $opts{pattern} = '*' unless defined($opts{pattern}); | ||||
367 | |||||||
368 | |||||||
369 | 6 | 501116 | my @rc = $opts{bydn} ? group_listbydn($pd, $resp, $opts{pattern}, | ||||
370 | $opts{maxreturn}) : | ||||||
371 | group_list($pd, $resp, $opts{pattern}, | ||||||
372 | $opts{maxreturn}); | ||||||
373 | 6 | 201 | $resp->isok() && $resp->set_value(\@rc); | ||||
374 | 6 | 125 | return $resp; | ||||
375 | } | ||||||
376 | |||||||
377 | sub groupimport { | ||||||
378 | 10 | 1 | 130 | my $self = shift; | |||
379 | 10 | 153 | my $resp = Tivoli::AccessManager::Admin::Response->new(); | ||||
380 | |||||||
381 | 10 | 93 | unless (ref $self) { | ||||
382 | 1 | 10 | my $pd = shift; | ||||
383 | 1 | 16 | $self = new($self, $pd, @_); | ||||
384 | } | ||||||
385 | |||||||
386 | 10 | 144 | if (@_ % 2) { | ||||
387 | 1 | 18 | $resp->set_message("Invalid syntax"); | ||||
388 | 1 | 16 | $resp->set_isok(0); | ||||
389 | 1 | 14 | return $resp; | ||||
390 | } | ||||||
391 | 9 | 88 | my %opts = @_; | ||||
392 | |||||||
393 | 9 | 114 | if ($self->{exist}) { | ||||
394 | 1 | 18 | $resp->set_message("Cannot import a group that already exists"); | ||||
395 | 1 | 17 | $resp->set_isok(0); | ||||
396 | 1 | 11 | return $resp; | ||||
397 | } | ||||||
398 | |||||||
399 | 8 | 58 | unless ($self->{name}) { | ||||
400 | 2 | 45 | $self->{name} = $opts{name} || ""; | ||||
401 | } | ||||||
402 | |||||||
403 | 8 | 56 | unless ($self->{dn}) { | ||||
404 | 3 | 51 | $self->{dn} = $opts{dn} || ""; | ||||
405 | } | ||||||
406 | |||||||
407 | 8 | 99 | if ($self->{name} and $self->{dn}) { | ||||
408 | 6 | 373165 | my $rc = $self->group_import($resp, $opts{container} || ""); | ||||
409 | 6 | 172 | if ($resp->isok()) { | ||||
410 | 5 | 324537 | $self->group_get($resp); | ||||
411 | 5 | 193 | $self->{cn} = $self->group_getcn(); | ||||
412 | 5 | 103 | $self->{exist} = 1; | ||||
413 | } | ||||||
414 | } | ||||||
415 | else { | ||||||
416 | 2 | 27 | $resp->set_message("groupimport needs the name and the DN"); | ||||
417 | 2 | 22 | $resp->set_isok(0); | ||||
418 | } | ||||||
419 | 8 | 171 | return $resp; | ||||
420 | } | ||||||
421 | |||||||
422 | sub DESTROY { | ||||||
423 | 43 | 312 | my $self = shift; | ||||
424 | |||||||
425 | 43 | 587 | $self->_groupfree(); | ||||
426 | } | ||||||
427 | |||||||
428 | 29 | 1 | 542 | sub name { $_[0]->{name} } | |||
429 | 26 | 1 | 294 | sub exist { $_[0]->{exist} } | |||
430 | |||||||
431 | 1; | ||||||
432 | |||||||
433 - 775 | =head1 NAME Tivoli::AccessManager::Admin::Group =head1 SYNOPSIS use Tivoli::AccessManager::Admin; my ($resp, @groups); my $pd = Tivoli::AccessManager::Admin->new(password => 'N3ew0nk'); # Lets see who is there $resp = Tivoli::AccessManager::Admin::Group->list($pd, pattern => "lgroup*"); print join("\n", @{$resp->value}); # Alternately, search by DN. $resp = Tivoli::AccessManager::Admin::Group->list($pd, pattern => "lgroup*", bydn => 1); print join("\n", @{$resp->value}); # Create a new group the easy way $resp = Tivoli::AccessManager::Admin::Group->create($pd, name => 'lgroup', dn => 'cn=lgroup,ou=groups,o=rox,c=us', cn => 'lgroup' ); $groups[0] = $resp->value if $resp->is_ok; # Create a few more groups in a different way for my $i (1 .. 3) { my $name = sprintf "lgroup%02d", $i; $groups[$i] = Tivoli::AccessManager::Admin::Group->new($pd, name => $name); # Don't attempt to create something that already exists next if $groups[$i]->exist; $resp = $groups[$i]->create(dn => "cn=$name,ou=groups,o=rox,c=us"); } # Add members to the group, skipping those users already in the group $resp = $groups[0]->members(add => [qw/luser01 luser02 luser03 luser04 luser05/ ], force => 1); # List the members $resp = $groups[0]->members(); print "\t$_\n" for (@{$resp->value()}); # Remove members $resp = $groups[0]->members(remove => [qw/luser02 luser03/]); # Add and remove members at the same time $resp = $groups[0]->members(remove => [qw/luser01 luser04/], add => [qw/luser02 luser03/ ] ); # Delete the group $resp = $groups[0]->delete(); # We didn't remove it from the registry. Import it and delete it again $resp = $groups[0]->groupimport(); $resp = $groups[0]->delete(1); =head1 DESCRIPTION B<Tivoli::AccessManager::Admin::Group> provides the interface to the group portion of the TAM API. =head1 CONSTRUCTOR =head2 new(PDADMIN[, name=E<gt> NAME, dn =E<gt> DN, cn =E<gt> CN]) Creates a blessed B<Tivoli::AccessManager::Admin::Group> object and returns it. =head3 Parameters =over 4 =item PDADMIN An initialized L<Tivoli::AccessManager::Admin::Context> object. Please note that, after the L<Tivoli::AccessManager::Admin::Group> object is created, you cannot change the context w/o destroying the object and recreating it. =item name =E<gt> NAME The name of the group to which the object refers. B<new> will query TAM to determine if the group exists or not, retrieving the other values (cn and dn) if it does. =item dn =E<gt> DN The group's DN. If this value is provided (but L</"name"> is not), B<new> will look to see if the group is already defined. If the group is, the other fields (name and cn) will be retrieved from TAM. =item cn =E<gt> CN The group's common name. Nothing special happens if you provide the cn. If this parameter is not provided, I will assume it is the same as the group's name. =back =head3 Returns A fully blessed L<Tivoli::AccessManager::Admin::Group> object. =head1 CLASS METHODS Class methods behave like instance methods -- they return L<Tivoli::AccessManager::Adming::Response> objects. =head2 list(PDADMIN [,maxreturn =E<gt> N, pattern =E<gt> STRING, bydn => 1]) Lists some subset of TAM groups. =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 =E<gt> 1 Search by DN instead of group name. This changes the semantics of the search in an interesting fashion. By default, you will only get tamified groups. Searching by dn will return any LDAP object that TAM recognizes as a group, irrespective of the TAMification. This parameters defaults to 0. =back =head3 Returns The resulting list of users. =head1 METHODS This verse is the same as all the rest. Methods called with optional parameters will attempt to set. Methods called with no options will perform a get. Given that all return values are cleverly hidden in the returned L<Tivoli::AccessManager::Admin::Response> object, I am not going to worry about documenting that part. I will only say what will be in the object. =head2 create(name =E<gt> NAME, dn =E<gt> DN, cn =E<gt> CN, container =E<gt> 'CONTAINER NAME') L</"create"> a new group in TAM. At the bare minimum, both the name and the DN must be defined. See L</"Parameters"> below for a full discussion. B<create> can be called instead of B<new>. The new object can be retrieved from the L<Tivoli::AccessManager::Admin::Response> object. =head3 Parameters =over 4 =item container =E<gt> 'CONTAINER NAME' The group container, if there is one. This parameter is optional. If you don't understand it, don't provide it. =item name =E<gt> NAME =item dn =E<gt> DN =item cn =E<gt> CN These are the same as defined for L</"new"> and are only required if you either did not provide them when you created the instance or if you are calling L</"create"> to create a new object. =back =head3 Returns The success of the ooerstion if B<new> was used, the new L<Tivoli::AccessManager::Admin::Group> object otherwise. =head2 delete([1]) Deletes the group from TAM. =head3 Parameters =over 4 =item 1 If anything is provided that perl will interpret as "true", the group will be deleted from the registry. Defaults to false. =back =head3 Returns The success of the operation =head2 description([STRING]) Gets or sets the description of the group. =head3 Parameters =over 4 =item STRING The new description for the group. This is an optional parameter. =back =head3 Returns The description for the group for either the set or the get. =head2 exist A flag indicating if the group exists or not. =head2 cn Returns the CN for the group. This is a read-only function. No sets are allowed via the TAM API (go see L<Net::LDAP> if you really want to do this). =head2 dn Returns the DN for the group. This is a read-only function. No sets are allowed via the TAM API. =head2 name Returns the name for the group. This is a read-only function. No sets are allowed via the TAM API. =head2 members(add =E<gt> [qw/list of users/], remove =E<gt> [qw/list of users/], force =E<gt> 1) Adds, removes and retrieves the members of a group. The add and remove option can be used at the same time -- removes are processed first. If the removal fails, no adds will be attempted. =head3 Parameters =over 4 =item add =E<gt> [qw/list of users/] An array reference to the list of users to be added to the group. =item remove =E<gt> [qw/list of users/] An array reference to the list of users to be removed from the group. =item force =E<gt> 1 Under normal circumstances, TAM will get unhappy if you try to either add members that are already in the group or delete members that don't exist. Using the force option will cause B<members> to only add those members that are not in the group or delete those that are. If no members will be added/deleted, you will get a warning in the response. =back =head3 Returns Unless there is an error, you will get the new membership list for the group. =head2 list(maxreturn =E<gt> NUMBER, pattern =E<gt> STRING) Gets a list of groups defined in TAM. If the pattern contains an '=', list will search by DNs. Otherwise, it will search by name. Yes, this is the same as the class method. I like being able to call this way as well, although it rather breaks the metaphor. =head3 Parameters =over 4 =item maxreturn =E<gt> NUMBER The maximum number of groups to return. It will default to 0, which means return all matching groups. That could cause problems with the LDAP. =item pattern =E<gt> STRING The pattern to search for. You can use the * and ? wildcards, but that is about it. This will default to *. It too could cause issues with the LDAP. =back =head3 Returns The list of groups that matched the search criteria. =head2 groupimport([name =E<gt> NAME, dn =E<gt> DN, container =E<gt> 'CONTAINER') Imports an already existing LDAP group into TAM. This can also be used to create a new L<Tivoli::AccessManager::Admin::Group> object. =head3 Parameters See L<create> for the full explanation. Have I mentioned I am a lazy POD writer yet? =head3 Returns The success or failure of the import if called as an instance method, the new L<Tivoli::AccessManager::Admin::Group> object otherwise. =head1 ACKNOWLEDGEMENTS See L<Tivoli::AccessManager::Admin>. I stand upon the shoulders of giants. =head1 BUGS None known yet. =head1 AUTHOR Mik Firestone <mikfire@gmail.com> =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. Standard IBM copyright, trademark, patent and ownership statement. =cut | ||||||
776 |