UserDBLDAP.pm 5.46 KB
Newer Older
Yadd's avatar
Yadd committed
1
2
3
4
5
##@file
# LDAP user database backend file

##@class
# LDAP user database backend class
6
7
package Lemonldap::NG::Portal::UserDBLDAP;

8
use strict;
9
use Lemonldap::NG::Portal::Simple;
10
use Lemonldap::NG::Portal::_LDAP 'ldap';    #link protected ldap
11

12
our $VERSION = '0.2';
13

Yadd's avatar
Yadd committed
14
## @method int userDBInit()
Yadd's avatar
Yadd committed
15
# Does nothing.
Yadd's avatar
Yadd committed
16
# @return Lemonldap::NG::Portal constant
17
sub userDBInit {
18
    PE_OK;
19
20
}

21
## @apmethod int getUser()
Yadd's avatar
Yadd committed
22
# 7) Launch formateFilter() and search()
Yadd's avatar
Yadd committed
23
# @return Lemonldap::NG::Portal constant
24
25
26
27
28
sub getUser {
    my $self = shift;
    return $self->_subProcess(qw(formateFilter search));
}

29
## @apmethod protected int formateFilter()
Yadd's avatar
Yadd committed
30
31
# Set the LDAP filter.
# By default, the user is searched in the LDAP server with its UID.
Yadd's avatar
Yadd committed
32
# @return Lemonldap::NG::Portal constant
33
34
sub formateFilter {
    my $self = shift;
35
36
37
38
    $self->{LDAPFilter} =
        $self->{mail}
      ? $self->{mailLDAPFilter}
      : $self->{AuthLDAPFilter}
Yadd's avatar
Yadd committed
39
      || $self->{LDAPFilter};
40
41
    $self->lmLog( "LDAP submitted filter: " . $self->{LDAPFilter}, 'debug' )
      if ( $self->{LDAPFilter} );
Yadd's avatar
Yadd committed
42
    $self->{LDAPFilter} ||= '(&(uid=$user)(objectClass=inetOrgPerson))';
43
    $self->{LDAPFilter} =~ s/\$(user|_?password|mail)/$self->{$1}/g;
Yadd's avatar
Yadd committed
44
    $self->{LDAPFilter} =~ s/\$(\w+)/$self->{sessionInfo}->{$1}/g;
45
    $self->lmLog( "LDAP transformed filter: " . $self->{LDAPFilter}, 'debug' );
46
47
48
    PE_OK;
}

49
## @apmethod protected int search()
Yadd's avatar
Yadd committed
50
# Search the LDAP DN of the user.
Yadd's avatar
Yadd committed
51
# @return Lemonldap::NG::Portal constant
52
53
sub search {
    my $self = shift;
54
55
56
    unless ( $self->ldap ) {
        return PE_LDAPCONNECTFAILED;
    }
57
58
59
    my $mesg = $self->ldap->search(
        base   => $self->{ldapBase},
        scope  => 'sub',
Yadd's avatar
Yadd committed
60
        filter => $self->{LDAPFilter},
61
62
63
64
65
        (
            ref( $self->{exportedVars} )
            ? ( attrs => values( %{ $self->{exportedVars} } ) )
            : ()
        ),
66
    );
67
    $self->lmLog(
68
        'LDAP Search with base: '
69
          . $self->{ldapBase}
70
          . ' and filter: '
71
72
73
          . $self->{LDAPFilter},
        'debug'
    );
74
    if ( $mesg->code() != 0 ) {
75
        $self->lmLog( 'LDAP Search error: ' . $mesg->error, 'error' );
76
77
        return PE_LDAPERROR;
    }
78
    unless ( $self->{entry} = $mesg->entry(0) ) {
79
        my $user = $self->{mail} || $self->{user};
80
        $self->_sub( 'userError', "$user was not found in LDAP directory" );
81
82
        return PE_BADCREDENTIALS;
    }
83
84
85
86
    $self->{dn} = $self->{entry}->dn();
    PE_OK;
}

87
## @apmethod int setSessionInfo()
Yadd's avatar
Yadd committed
88
89
90
# 7) Load all parameters included in exportedVars parameter.
# Multi-value parameters are loaded in a single string with
# '; ' separator
Yadd's avatar
Yadd committed
91
# @return Lemonldap::NG::Portal constant
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
sub setSessionInfo {
    my ($self) = @_;
    $self->{sessionInfo}->{dn} = $self->{dn};
    unless ( $self->{exportedVars} ) {
        foreach (qw(uid cn mail)) {
            $self->{sessionInfo}->{$_} =
              join( '; ', $self->{entry}->get_value($_) ) || "";
        }
    }
    elsif ( ref( $self->{exportedVars} ) eq 'HASH' ) {
        foreach ( keys %{ $self->{exportedVars} } ) {
            if ( my $tmp = $ENV{$_} ) {
                $tmp =~ s/[\r\n]/ /gs;
                $self->{sessionInfo}->{$_} = $tmp;
            }
            else {
                $self->{sessionInfo}->{$_} = join( '; ',
                    $self->{entry}->get_value( $self->{exportedVars}->{$_} ) )
                  || "";
            }
        }
    }
    else {
115
        $self->abort('Only hash reference are supported now in exportedVars');
116
117
118
119
    }
    PE_OK;
}

Clément OUDOT's avatar
Clément OUDOT committed
120
121
122
123
124
## @apmethod int setGroups()
# Load all groups in $groups.
# @return Lemonldap::NG::Portal constant
sub setGroups {
    my ($self) = @_;
125
126
    my $groups = $self->{sessionInfo}->{groups};

127
128
129
130
    $self->{ldapGroupObjectClass}         ||= "groupOfNames";
    $self->{ldapGroupAttributeName}       ||= "member";
    $self->{ldapGroupAttributeNameUser}   ||= "dn";
    $self->{ldapGroupAttributeNameSearch} ||= ["cn"];
131

132
133
    if (   $self->{ldapGroupBase}
        && $self->{sessionInfo}->{ $self->{ldapGroupAttributeNameUser} } )
134
    {
135
136
137
138
        my $searchFilter =
          "(&(objectClass=" . $self->{ldapGroupObjectClass} . ")(|";
        foreach (
            split(
139
                /[;]/,
140
141
142
                $self->{sessionInfo}->{ $self->{ldapGroupAttributeNameUser} }
            )
          )
143
        {
144
145
            $searchFilter .=
              "(" . $self->{ldapGroupAttributeName} . "=" . $_ . ")";
146
147
148
        }
        $searchFilter .= "))";
        my $mesg = $self->{ldap}->search(
149
150
151
152
153
154
155
156
157
158
159
160
            base   => $self->{ldapGroupBase},
            filter => $searchFilter,
            attrs  => $self->{ldapGroupAttributeNameSearch},
        );
        if ( $mesg->code() == 0 ) {
            foreach my $entry ( $mesg->all_entries ) {
                my $nbAttrs = @{ $self->{ldapGroupAttributeNameSearch} };
                for ( my $i = 0 ; $i < $nbAttrs ; $i++ ) {
                    my @data =
                      $entry->get_value(
                        $self->{ldapGroupAttributeNameSearch}[$i] );
                    if (@data) {
161
162
                        $groups .= $data[0];
                        $groups .= "|"
163
164
165
166
167
168
                          if (
                            $i + 1 < $nbAttrs
                            && $entry->get_value(
                                $self->{ldapGroupAttributeNameSearch}[ $i + 1 ]
                            )
                          );
169
170
171
                    }
                }
                $groups .= "; ";
Clément OUDOT's avatar
Clément OUDOT committed
172
            }
173
            $groups =~ s/; $//g;
Clément OUDOT's avatar
Clément OUDOT committed
174
175
        }
    }
176

Clément OUDOT's avatar
Clément OUDOT committed
177
178
179
180
    $self->{sessionInfo}->{groups} = $groups;
    PE_OK;
}

181
182
1;