source: LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Ad/Group.pm @ 821

Last change on this file since 821 was 821, checked in by nanardon, 14 years ago
  • fix initial sAMAccountName when creating group
  • really set groups attributes (eg call parent class function to do the work
  • Property svn:keywords set to Id Rev
File size: 5.8 KB
Line 
1package LATMOS::Accounts::Bases::Ad::Group;
2
3use 5.010000;
4use strict;
5use warnings;
6
7use base qw(LATMOS::Accounts::Bases::Ad::objects);
8use Net::LDAP;
9use Net::LDAP::Entry;
10use Net::LDAP::Control::Paged;
11use Net::LDAP::Constant qw( LDAP_CONTROL_PAGED ); 
12use Net::LDAP::Util     qw( escape_filter_value );
13use LATMOS::Accounts::Log;
14
15our $VERSION = (q$Rev$ =~ /^Rev: (\d+) /)[0];
16
17=head1 NAME
18
19LATMOS::Ad - Perl extension for blah blah blah
20
21=head1 SYNOPSIS
22
23  use LATMOS::Ad;
24  blah blah blah
25
26=head1 DESCRIPTION
27
28Stub documentation for LATMOS::Ad, created by h2xs. It looks like the
29author of the extension was negligent enough to leave the stub
30unedited.
31
32Blah blah blah.
33
34=head1 FUNCTIONS
35
36=cut
37
38sub _class_filter { '(ObjectClass=group)' }
39
40sub _key_attr { 'cn' } 
41
42sub _my_ldap_classes { qw(top group) }
43
44sub _delayed_fields {
45    my ($self)= @_;
46    return qw(memberUID member managedBy);
47}
48
49sub _canonical_fields {
50    my ($self, $base, $mode) = @_;
51    (
52        qw(gidNumber description member memberUID sAMAccountName managedBy),
53        ($mode !~ /w/
54            ? qw(cn dn objectClass)
55            : ()
56        )
57    )
58}
59
60sub _create {
61    my ($class, $base, $id, %data) = @_;
62
63    $data{sAMAccountName} = 'GR-' . $id;
64    my $entry = Net::LDAP::Entry->new();
65
66    $entry->dn(join(',',
67        sprintf('cn=%s', escape_filter_value($id)),
68        $base->object_base_dn($class->type),
69    ));
70    $entry->replace(objectClass => [ $class->_my_ldap_classes ],);
71    my %delayed;
72    foreach (keys %data) {
73        /^(memberUID|member)$/ and do {
74            $delayed{$_} = $data{$_};
75            next;
76        };
77        $class->_populate_entry($entry, $_, $data{$_}, $base);
78    }
79    my $msg = $base->ldap->add($entry);
80    $base->log(LA_ERR, "Cannot create group: %s", $msg->error) if ($msg->code);
81    return if ($msg->code);
82    if (! keys %delayed) { return 1 };
83    my $res = $base->get_object('group', $id)->set_fields(%delayed);
84    return defined($res) ? 1 : 0;
85}
86
87sub _rename {
88    my ($class, $base, $uid, $newuid) = @_;
89
90    $class->SUPER::_rename($base, $uid, $newuid) or return;
91
92    my $obj = $class->new($base, $newuid) or do {
93        $base->log(LA_ERR, "Cannot get newly renamed object %s", $newuid);
94        return;
95    };
96
97    $obj->{entry}->replace('sAMAccountName', 'GR-' . $newuid);
98
99    my $mesg = $obj->{entry}->update($base->ldap);
100
101    if ($mesg->code) {
102        $base->log(LA_ERR, "Cannot update object %s: %s", $newuid, $mesg->error);
103        return;
104    } else {
105        $base->log(LA_INFO, "Object (%s) %s renamed to %s",
106            $class->type, $uid, $newuid
107        );
108        return 1
109    }
110}
111
112sub get_field {
113    my ($self, $field) = @_;
114
115    $field eq 'member' and do {
116        my @res;
117        $self->base->_unlimited_search(
118            base => $self->base->object_base_dn('user'),
119            filter => sprintf(
120                '(&(objectClass=user)(memberOf=%s))',
121                escape_filter_value($self->{entry}->dn),
122            ),
123            callback => sub {
124                my ($mesg, $entry) = @_;
125                ref $entry eq 'Net::LDAP::Entry' or return;
126                push(@res, $entry->get_value('cn'));
127            },
128        );
129        return [ sort(@res) ];
130    };
131    $field eq 'memberUID' and do {
132        my $val = $self->SUPER::get_field($field);
133        return ref $val ? $val : [ grep { $_ } $val ];
134    };
135    $self->SUPER::get_field($field);
136}
137
138sub _populate_entry {
139    my ($self, $entry, $field, $value, $base) = @_;
140    $base ||= $self->base;
141    for ($field) {
142        /managedBy$/ and do {
143            if ($value && (my $user = $base->get_object('user', $value))) {
144                $value = $user->get_field('dn');
145            } else {
146                $value = undef;
147            }
148            next;
149        };
150        /^sAMAccountName$/ and do {
151            # Hack... to avoid clash with user
152            if ($value !~ /^GR-/) {
153                $value = 'GR-' . $value;
154            }
155            next;
156        };
157    }
158    $self->SUPER::_populate_entry($entry, $field, $value, $base);
159}
160
161sub set_fields {
162    my ($self, %data) = @_;
163    my %ndata;
164    while (my ($f, $val) = each(%data)) {
165        $f eq 'memberUID' and do {
166            my %users;
167            $users{$_}{e} = 1 foreach (@{ $self->get_field('memberUID') || []});
168            $users{$_}{n} = 1 foreach (@{ $val || []});
169            foreach (keys %users) {
170                $users{$_}{e} && $users{$_}{n} and next;
171                if ($users{$_}{e}) {
172                    $self->{entry}->delete(memberUID => $_);
173                } elsif ($users{$_}{n} && $self->base->get_object('user', $_)) {
174                    $self->{entry}->add(memberUID => $_);
175                } # else {} # can't happen
176            }
177            next;
178        };
179        $f eq 'member' and do {
180            my %users;
181            $users{$_}{e} = 1 foreach (@{ $self->get_field('member') || []});
182            $users{$_}{n} = 1 foreach (@{ $val || []});
183            foreach (keys %users) {
184                $users{$_}{e} && $users{$_}{n} and next;
185                my $user = $self->base->get_object('user', $_) or next;
186                if ($users{$_}{e}) {
187                    $self->{entry}->delete(member => $user->get_field('dn'));
188                } elsif ($users{$_}{n}) {
189                    $self->{entry}->add(member => $user->get_field('dn'));
190                } # else {} # can't happen
191            }
192            next;
193        };
194        $ndata{$f} = $val;
195    }
196    $self->SUPER::set_fields(%ndata);
197}
198
1991;
200
201__END__
202
203=head1 SEE ALSO
204
205=head1 AUTHOR
206
207Olivier Thauvin, E<lt>olivier.thauvin@aerov.jussieu.frE<gt>
208
209=head1 COPYRIGHT AND LICENSE
210
211Copyright (C) 2008 CNRS SA/CETP/LATMOS
212
213This library is free software; you can redistribute it and/or modify
214it under the same terms as Perl itself, either Perl version 5.10.0 or,
215at your option, any later version of Perl 5 you may have available.
216
217
218=cut
Note: See TracBrowser for help on using the repository browser.