source: trunk/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Unix/User.pm @ 2075

Last change on this file since 2075 was 1975, checked in by nanardon, 7 years ago

Fix internal attribute name discovery for Unix db

  • Property svn:keywords set to Id
File size: 5.0 KB
Line 
1package LATMOS::Accounts::Bases::Unix::User;
2
3use 5.010000;
4use strict;
5use warnings;
6
7use base qw(LATMOS::Accounts::Bases::Objects);
8use LATMOS::Accounts::Log;
9
10our $VERSION = (q$Rev: 205 $ =~ /^Rev: (\d+) /)[0];
11
12=head1 NAME
13
14LATMOS::Ad - Perl extension for blah blah blah
15
16=head1 SYNOPSIS
17
18  use LATMOS::Accounts::Bases;
19  my $base = LATMOS::Accounts::Bases->new('unix');
20  ...
21
22=head1 DESCRIPTION
23
24Account base access over standard unix file format.
25
26=head1 FUNCTIONS
27
28=cut
29
30sub _get_attr_schema {
31    my ($class, $base) = @_;
32    {
33        uidNumber       => { iname => 'uid', uniq => 1, },
34        gidNumber       => { iname => 'gid',
35            can_values => sub {
36                map { $_->get_attributes('gidNumber') }
37                map { $base->get_object('group', $_) }
38                $base->list_objects('group')
39            },
40            reference => 'group',
41            mandatory => 1,
42        },
43        gecos           => { },
44        homeDirectory   => { iname => 'home' },
45        loginShell      => { iname => 'shell' },
46        userPassword    => {
47            iname => ($base->{use_shadow} ? 'spassword' : 'password'),
48        },
49        memberOf        => {
50            delayed => 1,
51            multiple => 1,
52        },
53        locked          => {},
54        givenName       => { ro => 1 },
55        sn              => { ro => 1 },
56        sAMAccountName  => { iname => 'login', ro => 1 },
57        $base->{use_shadow} ?
58        (
59            shadowLastChange => { iname => 'last_changed' },
60            shadowMin        => { iname => 'before_ch' },
61            shadowMax        => { iname => 'after_ch' },
62            shadowWarning    => { iname => 'exp_warn' },
63            shadowInactive   => { iname => 'exp_disable' },
64            shadowExpire     => { iname => 'disable' },
65            shadowFlag       => { iname => 'res' },
66        ) : (),
67    };
68}
69
70=head2 new(%config)
71
72=cut
73
74sub new {
75    my ($class, $base, $id, @args) = @_;
76    # we profit of ref, quite easy
77    if (exists($base->{users}{$id}) && $base->{users}{$id}) {
78        if ($base->{users}{$id}{uid} < ($base->{min_uid} || 0)) {
79            return;
80        }
81        return bless($base->{users}{$id}, $class);
82    } else { return }
83}
84
85sub get_field {
86    my ($self, $field) = @_;
87    for ($field) {
88        /^login$/ and return $self->id;
89        /^(sn|givenName)$/ and do {
90            my $gecos = $self->{gecos} || '';
91            my ($given, $sn) = $gecos =~ /^([^, ]+) +([^, ]+)/;
92            return $field eq 'sn' ? $sn : $given;
93        };
94        /^memberOf$/ and do {
95            my @res;
96            foreach (sort keys %{ $self->base->{groups} || {}}) {
97                push(@res, $_)
98                    if(exists($self->base->{groups}{$_}{'users'}{$self->id}));
99            }
100            return \@res;
101        };
102    }
103    $self->{$field}
104}
105
106sub set_fields {
107    my ($self, %gdata) = @_;
108
109    my %data;
110
111    foreach my $attr (keys %gdata) {
112        if (my $oattr = $self->attribute($attr)) {
113            $data{ $oattr->iname } = $gdata{$attr};
114        } else {
115            $data{$attr} = $gdata{$attr};
116        }
117    }
118
119    foreach my $field (keys %data) {
120        $field =~ /^(uid|gid)$/ and do {
121            if(!(defined($data{$field}) && $data{$field} =~ /^\d+$/)) {
122                $self->base->log(LA_ERR,
123                    "Invalid data for $field: " . (defined($data{$field}) ? $data{$field} : '(none)'));
124                return;
125            }
126        }
127    }
128    foreach my $field (keys %data) {
129        # TODO check fields exists !
130        $field =~ /^(sn|givenName)$/ and next;
131        $field eq 'memberOf' and do {
132            my %set;
133            $data{$field} = [ $data{$field} ] unless(ref $data{$field});
134            foreach(grep { defined($_) }  @{ $data{$field} || []}) {
135                $set{$_} = 1;
136            }
137            foreach (sort keys %{ $self->base->{groups} || {}}) {
138                if ($set{$_}) {
139                    $self->base->{groups}{$_}{'users'}{$self->id} = 1;
140                } else {
141                    delete($self->base->{groups}{$_}{'users'}{$self->id});
142                }
143            }
144        };
145        $self->{$field} = $data{$field};
146    }
147    1;
148}
149
150=head2 _InjectCryptPasswd($cryptpasswd)
151
152Inject a password encrypted using standard UNIX method.
153
154=cut
155
156sub _InjectCryptPasswd {
157    my ($self, $cryptpasswd) = @_;
158
159    my $res = $self->set_c_fields(
160        userPassword => $cryptpasswd,
161    );
162
163    if ($res) {
164        $self->base->log(LA_NOTICE, 'Crypted password injected for %s', $self->id);
165        return 1;
166    } else {
167        $self->base->log(LA_ERR, 'Cannot inject crypted password for %s', $self->id);
168        return 0;
169    }
170}
171
1721;
173
174__END__
175
176=head1 SEE ALSO
177
178L<LATMOS::Accounts::Bases::Unix>
179
180=head1 AUTHOR
181
182Olivier Thauvin, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>
183
184=head1 COPYRIGHT AND LICENSE
185
186Copyright (C) 2008, 2009 CNRS SA/CETP/LATMOS
187
188This library is free software; you can redistribute it and/or modify
189it under the same terms as Perl itself, either Perl version 5.10.0 or,
190at your option, any later version of Perl 5 you may have available.
191
192
193=cut
Note: See TracBrowser for help on using the repository browser.