1 | package Epoll::DB::ImportV::Ldap; |
---|
2 | |
---|
3 | use strict; |
---|
4 | use warnings; |
---|
5 | use base qw(Epoll::DB::ImportV); |
---|
6 | use Net::LDAP; |
---|
7 | use Net::LDAP::Control::Paged; |
---|
8 | use Net::LDAP::Constant qw( LDAP_CONTROL_PAGED ); |
---|
9 | |
---|
10 | sub _unlimited_search { |
---|
11 | my $ldap = shift; |
---|
12 | my @args = @_; |
---|
13 | |
---|
14 | my ($page, $cookie) = (Net::LDAP::Control::Paged->new( size => 100 )); |
---|
15 | |
---|
16 | while (1) { |
---|
17 | my $search = $ldap->search( |
---|
18 | @args, |
---|
19 | control => [ $page ], |
---|
20 | ); |
---|
21 | if ($search->code) { |
---|
22 | return $search; |
---|
23 | } |
---|
24 | |
---|
25 | ### After foreach loops ends, client checks LDAP server reponse of how many search results total. |
---|
26 | ### This is a control to end the infinite while loop if there are no search results to go through |
---|
27 | ### If there are search results, this control will always return the total number of results. It is |
---|
28 | ### never decremented |
---|
29 | my ($resp) = $search->control( LDAP_CONTROL_PAGED ) or last; |
---|
30 | |
---|
31 | |
---|
32 | ### Obtaining the cookie from the search result. When no more results, cookie will be NULL |
---|
33 | ### and infinite while loop will terminate. |
---|
34 | $cookie = $resp->cookie or last; |
---|
35 | |
---|
36 | ### Sets cookie so server knows the next search result to send |
---|
37 | $page->cookie($cookie); |
---|
38 | } |
---|
39 | ### This is a control to check for abnormal exit of the while loop. |
---|
40 | ### If this occurs ### we need to tell the LDAP server that remaining |
---|
41 | ### search results are no longer needed ### by sending a search request with a page size of 0 |
---|
42 | if ($cookie) { |
---|
43 | $page->cookie($cookie); |
---|
44 | $page->size(0); |
---|
45 | $ldap->search(@args, control => [ $page ]); |
---|
46 | } |
---|
47 | return 1; |
---|
48 | } |
---|
49 | |
---|
50 | sub fetch_voters { |
---|
51 | my ($self) = @_; |
---|
52 | $self->{params}{uri} or return; |
---|
53 | my $ldap = Net::LDAP->new($self->{params}{uri}) or return; |
---|
54 | |
---|
55 | { |
---|
56 | my $msg = $ldap->bind($self->{params}{login}, |
---|
57 | ($self->{params}{login} |
---|
58 | ? (password => $self->{params}{password}) |
---|
59 | : ()), |
---|
60 | ); |
---|
61 | |
---|
62 | $msg->code and do { |
---|
63 | warn $msg->error; |
---|
64 | return; |
---|
65 | }; |
---|
66 | } |
---|
67 | |
---|
68 | my @list; |
---|
69 | _unlimited_search( |
---|
70 | $ldap, |
---|
71 | base => $self->{params}{basedn}, |
---|
72 | scope => 'sub', |
---|
73 | filter => $self->{params}{filter}, |
---|
74 | attrs => [ grep { $_ } map { $self->{params}{$_} } qw(mail uid displayname) ], |
---|
75 | callback => sub { |
---|
76 | my ($mesg, $entry) = @_; |
---|
77 | $entry or return; |
---|
78 | my @voters = map { |
---|
79 | $self->{params}{$_} |
---|
80 | ? ($self->{params}{$_} eq 'dn' |
---|
81 | ? $entry->dn |
---|
82 | : $entry->get_value($self->{params}{$_}) || undef) |
---|
83 | : undef |
---|
84 | } qw(mail displayname uid); |
---|
85 | $voters[0] or return; |
---|
86 | |
---|
87 | push(@list, \@voters); |
---|
88 | }, |
---|
89 | ); |
---|
90 | |
---|
91 | @list |
---|
92 | } |
---|
93 | |
---|
94 | sub authenticate { |
---|
95 | my ($self, $mail, $uid, $passwd) = @_; |
---|
96 | my $ldap = Net::LDAP->new($self->{params}{uri}) or return; |
---|
97 | |
---|
98 | my $msg = $ldap->bind($uid, password => $passwd); |
---|
99 | $msg->code and return; |
---|
100 | return 1; |
---|
101 | } |
---|
102 | |
---|
103 | 1; |
---|