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

Last change on this file since 861 was 861, checked in by nanardon, 13 years ago
  • reimport missing files from previous svn
  • Property svn:keywords set to Id Rev
File size: 6.0 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 _get_attr_schema {
45    my ($class, $base) = @_;
46    {
47        gidNumber  => { uniq => 1, },
48        description => { },
49        member => {
50            delayed => 1,
51            can_values => sub { $base->list_objects('user') },
52        },
53        memberUID => { delayed => 1, },
54        sAMAccountName => { },
55        managedBy => {
56            delayed => 1,
57            can_values => sub { $base->list_objects('user') },
58        },
59        cn => { ro => 1, },
60        dn => { ro => 1, },
61        objectClass => { ro => 1, },
62        msSFU30NisDomain => { },
63        msSFU30Name => { },
64
65    }
66}
67
68sub _create {
69    my ($class, $base, $id, %data) = @_;
70
71    $data{sAMAccountName} = 'GR-' . $id;
72    my $entry = Net::LDAP::Entry->new();
73
74    $entry->dn(join(',',
75        sprintf('cn=%s', escape_filter_value($id)),
76        $base->object_base_dn($class->type),
77    ));
78    $entry->replace(objectClass => [ $class->_my_ldap_classes ],);
79    my %delayed;
80    foreach (keys %data) {
81        /^(memberUID|member)$/ and do {
82            $delayed{$_} = $data{$_};
83            next;
84        };
85        $class->_populate_entry($entry, $_, $data{$_}, $base);
86    }
87    my $msg = $base->ldap->add($entry);
88    $base->log(LA_ERR, "Cannot create group: %s", $msg->error) if ($msg->code);
89    return if ($msg->code);
90    if (! keys %delayed) { return 1 };
91    my $res = $base->get_object('group', $id)->set_fields(%delayed);
92    return defined($res) ? 1 : 0;
93}
94
95sub _rename {
96    my ($class, $base, $uid, $newuid) = @_;
97
98    $class->SUPER::_rename($base, $uid, $newuid) or return;
99
100    my $obj = $class->new($base, $newuid) or do {
101        $base->log(LA_ERR, "Cannot get newly renamed object %s", $newuid);
102        return;
103    };
104
105    $obj->{entry}->replace('sAMAccountName', 'GR-' . $newuid);
106
107    my $mesg = $obj->{entry}->update($base->ldap);
108
109    if ($mesg->code) {
110        $base->log(LA_ERR, "Cannot update object %s: %s", $newuid, $mesg->error);
111        return;
112    } else {
113        $base->log(LA_INFO, "Object (%s) %s renamed to %s",
114            $class->type, $uid, $newuid
115        );
116        return 1
117    }
118}
119
120sub get_field {
121    my ($self, $field) = @_;
122
123    $field eq 'member' and do {
124        my @res;
125        $self->base->_unlimited_search(
126            base => $self->base->object_base_dn('user'),
127            filter => sprintf(
128                '(&(objectClass=user)(memberOf=%s))',
129                escape_filter_value($self->{entry}->dn),
130            ),
131            callback => sub {
132                my ($mesg, $entry) = @_;
133                ref $entry eq 'Net::LDAP::Entry' or return;
134                push(@res, $entry->get_value('cn'));
135            },
136        );
137        return [ sort(@res) ];
138    };
139    $field eq 'memberUID' and do {
140        my $val = $self->SUPER::get_field($field);
141        return ref $val ? $val : [ grep { $_ } $val ];
142    };
143    $self->SUPER::get_field($field);
144}
145
146sub _populate_entry {
147    my ($self, $entry, $field, $value, $base) = @_;
148    $base ||= $self->base;
149    for ($field) {
150        /managedBy$/ and do {
151            if ($value && (my $user = $base->get_object('user', $value))) {
152                $value = $user->get_field('dn');
153            } else {
154                $value = undef;
155            }
156            next;
157        };
158        /^sAMAccountName$/ and do {
159            # Hack... to avoid clash with user
160            if ($value !~ /^GR-/) {
161                $value = 'GR-' . $value;
162            }
163            next;
164        };
165    }
166    $self->SUPER::_populate_entry($entry, $field, $value, $base);
167}
168
169sub set_fields {
170    my ($self, %data) = @_;
171    my %ndata;
172    while (my ($f, $val) = each(%data)) {
173        $f eq 'memberUID' and do {
174            my %users;
175            $users{$_}{e} = 1 foreach (@{ $self->get_field('memberUID') || []});
176            $users{$_}{n} = 1 foreach (@{ $val || []});
177            foreach (keys %users) {
178                $users{$_}{e} && $users{$_}{n} and next;
179                if ($users{$_}{e}) {
180                    $self->{entry}->delete(memberUID => $_);
181                } elsif ($users{$_}{n} && $self->base->get_object('user', $_)) {
182                    $self->{entry}->add(memberUID => $_);
183                } # else {} # can't happen
184            }
185            next;
186        };
187        $f eq 'member' and do {
188            my %users;
189            $users{$_}{e} = 1 foreach (@{ $self->get_field('member') || []});
190            $users{$_}{n} = 1 foreach (@{ $val || []});
191            foreach (keys %users) {
192                $users{$_}{e} && $users{$_}{n} and next;
193                my $user = $self->base->get_object('user', $_) or next;
194                if ($users{$_}{e}) {
195                    $self->{entry}->delete(member => $user->get_field('dn'));
196                } elsif ($users{$_}{n}) {
197                    $self->{entry}->add(member => $user->get_field('dn'));
198                } # else {} # can't happen
199            }
200            next;
201        };
202        $ndata{$f} = $val;
203    }
204    $self->SUPER::set_fields(%ndata);
205}
206
2071;
208
209__END__
210
211=head1 SEE ALSO
212
213=head1 AUTHOR
214
215Olivier Thauvin, E<lt>olivier.thauvin@aerov.jussieu.frE<gt>
216
217=head1 COPYRIGHT AND LICENSE
218
219Copyright (C) 2008 CNRS SA/CETP/LATMOS
220
221This library is free software; you can redistribute it and/or modify
222it under the same terms as Perl itself, either Perl version 5.10.0 or,
223at your option, any later version of Perl 5 you may have available.
224
225
226=cut
Note: See TracBrowser for help on using the repository browser.