line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Net::LDAP::Express; |
2
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
111771
|
use 5.006; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
84
|
|
4
|
2
|
|
|
2
|
|
13
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
67
|
|
5
|
2
|
|
|
2
|
|
11
|
use warnings; |
|
2
|
|
|
|
|
16
|
|
|
2
|
|
|
|
|
110
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.12'; |
8
|
|
|
|
|
|
|
|
9
|
2
|
|
|
2
|
|
10
|
use Carp ; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
220
|
|
10
|
|
|
|
|
|
|
|
11
|
2
|
|
|
2
|
|
10
|
use base 'Net::LDAP' ; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
2307
|
|
12
|
2
|
|
|
2
|
|
640786
|
use constant DEBUG => 0 ; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
7618
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
# Preloaded methods go here. |
15
|
|
|
|
|
|
|
sub new { |
16
|
0
|
|
|
0
|
1
|
0
|
my $class = shift ; |
17
|
0
|
|
|
|
|
0
|
my %args = @_ ; |
18
|
|
|
|
|
|
|
|
19
|
0
|
0
|
|
|
|
0
|
croak "Not an object method" if ref $class ; |
20
|
|
|
|
|
|
|
|
21
|
0
|
|
|
|
|
0
|
my %myParms = _new_parms() ; |
22
|
0
|
|
|
|
|
0
|
my @myParmNames = keys %myParms ; |
23
|
0
|
|
|
|
|
0
|
foreach my $parm (grep $myParms{$_} eq 'req',@myParmNames) { |
24
|
0
|
0
|
|
|
|
0
|
croak "$parm parameter is required" unless $args{$parm} ; |
25
|
|
|
|
|
|
|
} |
26
|
|
|
|
|
|
|
|
27
|
0
|
|
|
|
|
0
|
my $host = $args{host} ; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# Keep parameters that are local to this class, and pass to |
30
|
|
|
|
|
|
|
# Net::LDAP::new all the rest |
31
|
0
|
|
|
|
|
0
|
my %localparms ; |
32
|
0
|
|
|
|
|
0
|
@localparms{@myParmNames} = |
33
|
|
|
|
|
|
|
delete @args{@myParmNames} ; |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# Test for onlyattrs not overlapping with searchextras; in |
36
|
|
|
|
|
|
|
# case they do, warn |
37
|
0
|
0
|
0
|
|
|
0
|
if (defined $localparms{onlyattrs} and |
38
|
|
|
|
|
|
|
defined $localparms{searchextras}) { |
39
|
0
|
0
|
|
|
|
0
|
carp "Useless use of parameter onlyattrs with searchextras" if $^W ; |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
# try connection |
43
|
0
|
|
|
|
|
0
|
my $ldap = $class->SUPER::new($host,%args) ; |
44
|
0
|
0
|
|
|
|
0
|
croak "Cannot connect to $host: $@" if $@ ; |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
# bind if necessary |
47
|
0
|
0
|
|
|
|
0
|
if ($localparms{bindDN}) { |
48
|
0
|
|
|
|
|
0
|
my @bindArgs = ($localparms{bindDN}) ; |
49
|
0
|
0
|
|
|
|
0
|
push @bindArgs,('password',$localparms{bindpw}) |
50
|
|
|
|
|
|
|
if defined $localparms{bindpw} ; |
51
|
0
|
|
|
|
|
0
|
my $msg = $ldap->bind(@bindArgs) ; |
52
|
0
|
0
|
|
|
|
0
|
if ($msg->is_error) { |
53
|
0
|
|
|
|
|
0
|
$ldap->_seterr($msg) ; |
54
|
0
|
|
|
|
|
0
|
croak "Cannot bind: ".$msg->error ; |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
# Prepare object and return |
59
|
|
|
|
|
|
|
##! I should use accessors here... maybe building a code string |
60
|
|
|
|
|
|
|
##! and then passing it to eval. |
61
|
0
|
|
|
|
|
0
|
while (my ($parm,$value) = each %localparms) { |
62
|
0
|
|
|
|
|
0
|
$ldap->{"net_ldap_express_$parm"} = $value ; |
63
|
|
|
|
|
|
|
} |
64
|
0
|
|
|
|
|
0
|
return $ldap ; |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
{ |
68
|
|
|
|
|
|
|
my @lasterr = (0,'') ; |
69
|
|
|
|
|
|
|
my %errcache = @lasterr ; |
70
|
0
|
|
|
0
|
1
|
0
|
sub error { return $lasterr[1] } |
71
|
0
|
|
|
0
|
1
|
0
|
sub errcode { return $lasterr[0] } |
72
|
|
|
|
|
|
|
sub _seterr { |
73
|
0
|
|
|
0
|
|
0
|
my $ldap = shift ; |
74
|
|
|
|
|
|
|
# _seterr sets error code an name in the error cache |
75
|
|
|
|
|
|
|
# If it is passed one argument, then it should be an object in the |
76
|
|
|
|
|
|
|
# Net::LDAP::Message class |
77
|
|
|
|
|
|
|
# If it is passed two arguments, then they are an error code and |
78
|
|
|
|
|
|
|
# an error name respectively |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
# Redefine @_ if $_[0] is a Net::LDAP::Message |
81
|
0
|
0
|
|
|
|
0
|
if (ref $_[0]) { |
82
|
0
|
|
|
|
|
0
|
my $msg = shift ; |
83
|
0
|
|
|
|
|
0
|
@_ = ($msg->code,$msg->error) ; |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
# Get error code |
86
|
0
|
|
|
|
|
0
|
$lasterr[0] = shift ; |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
# Update cache, if needed |
89
|
0
|
0
|
|
|
|
0
|
$errcache{$lasterr[0]} = shift unless exists $errcache{$lasterr[0]} ; |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
# Get error message from cache |
92
|
0
|
|
|
|
|
0
|
$lasterr[1] = $errcache{$lasterr[0]} ; |
93
|
|
|
|
|
|
|
|
94
|
0
|
0
|
|
|
|
0
|
carp "LDAP ERROR @lasterr" if $^W; |
95
|
|
|
|
|
|
|
|
96
|
0
|
|
|
|
|
0
|
return @lasterr ; |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
sub add_many { |
101
|
0
|
|
|
0
|
1
|
0
|
my $ldap = shift ; |
102
|
0
|
|
|
|
|
0
|
my @parms = @_ ; |
103
|
0
|
|
|
|
|
0
|
my $msg ; |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
# Iterate over the entries, return those that succeeded |
106
|
|
|
|
|
|
|
my @success ; |
107
|
0
|
|
|
|
|
0
|
while (my $e = shift @parms) { |
108
|
0
|
|
|
|
|
0
|
eval { $e->isa('Net::LDAP::Entry') } ; |
|
0
|
|
|
|
|
0
|
|
109
|
0
|
0
|
|
|
|
0
|
if ($@) { |
110
|
0
|
0
|
|
|
|
0
|
carp "Invalid input: $@" if $^W ; |
111
|
0
|
|
|
|
|
0
|
$ldap->_seterr(-1,'Invalid input') ; |
112
|
0
|
|
|
|
|
0
|
return \@success ; |
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
|
115
|
0
|
|
|
|
|
0
|
$msg = $ldap->SUPER::add($e) ; |
116
|
0
|
0
|
|
|
|
0
|
if ($msg->is_error) { |
117
|
0
|
|
|
|
|
0
|
$ldap->_seterr($msg) ; |
118
|
0
|
|
|
|
|
0
|
return \@success ; |
119
|
|
|
|
|
|
|
} |
120
|
0
|
|
|
|
|
0
|
push @success,$e ; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
0
|
|
|
|
|
0
|
$ldap->_seterr(0) ; |
124
|
0
|
|
|
|
|
0
|
return \@success ; |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
sub delete_many { |
128
|
0
|
|
|
0
|
1
|
0
|
my $ldap = shift ; |
129
|
0
|
|
|
|
|
0
|
my @parms = @_ ; |
130
|
0
|
|
|
|
|
0
|
my $msg ; |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
my @success ; |
133
|
0
|
|
|
|
|
0
|
while (my $e = shift @parms) { |
134
|
0
|
|
|
|
|
0
|
eval { $e->isa('Net::LDAP::Entry') } ; |
|
0
|
|
|
|
|
0
|
|
135
|
0
|
0
|
|
|
|
0
|
if ($@) { |
136
|
0
|
0
|
|
|
|
0
|
carp "Invalid input: $@" if $^W ; |
137
|
0
|
|
|
|
|
0
|
$ldap->_seterr(-1,'Invalid input') ; |
138
|
0
|
|
|
|
|
0
|
return \@success ; |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
0
|
|
|
|
|
0
|
$msg = $ldap->SUPER::delete($e) ; |
142
|
0
|
0
|
|
|
|
0
|
if ($msg->is_error) { |
143
|
0
|
|
|
|
|
0
|
$ldap->_seterr($msg) ; |
144
|
0
|
|
|
|
|
0
|
return \@success ; |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
0
|
|
|
|
|
0
|
push @success,$e ; |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
0
|
|
|
|
|
0
|
$ldap->_seterr(0) ; |
151
|
0
|
|
|
|
|
0
|
return \@success ; |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
sub search { |
155
|
0
|
|
|
0
|
1
|
0
|
my $ldap = shift ; |
156
|
0
|
|
|
|
|
0
|
my $query ; |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# If search is passed an odd number of parameters, we assume that |
159
|
|
|
|
|
|
|
# the first is a query string; anyway, we'll override it if a |
160
|
|
|
|
|
|
|
# "filter" parameter is specified |
161
|
0
|
0
|
|
|
|
0
|
if (@_%2) { |
162
|
0
|
|
|
|
|
0
|
$query = shift ; |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
# Load defaults from _makesearchparms, override them with the values |
166
|
|
|
|
|
|
|
# in @_. |
167
|
0
|
|
|
|
|
0
|
my %parms = ($ldap->_makesearchparms,@_) ; |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
# What about filters? |
170
|
0
|
|
0
|
|
|
0
|
$parms{filter} ||= $ldap->_makefilter($query) ; |
171
|
|
|
|
|
|
|
|
172
|
0
|
|
|
|
|
0
|
return $ldap->SUPER::search(%parms) ; |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
sub simplesearch { |
176
|
0
|
|
|
0
|
1
|
0
|
my $ldap = shift ; |
177
|
0
|
|
|
|
|
0
|
my ($query) = @_ ; |
178
|
0
|
|
|
|
|
0
|
my %parms = $ldap->_makesearchparms; |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
# Set filter |
181
|
0
|
|
|
|
|
0
|
$parms{filter} = $ldap->_makefilter($query) ; |
182
|
|
|
|
|
|
|
|
183
|
0
|
|
|
|
|
0
|
my $msg = $ldap->SUPER::search(%parms) ; |
184
|
0
|
0
|
|
|
|
0
|
if ($msg->is_error) { |
185
|
0
|
|
|
|
|
0
|
$ldap->_seterr($msg) ; |
186
|
0
|
|
|
|
|
0
|
return undef ; |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
|
189
|
0
|
|
|
|
|
0
|
$ldap->_seterr(0) ; |
190
|
|
|
|
|
|
|
|
191
|
0
|
|
|
|
|
0
|
return $ldap->_sort_by ? |
192
|
0
|
0
|
|
|
|
0
|
[$msg->sorted(@{$ldap->_sort_by})] : |
193
|
|
|
|
|
|
|
[$msg->entries] ; |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
sub rename { |
198
|
0
|
|
|
0
|
1
|
0
|
my $ldap = shift ; |
199
|
0
|
|
|
|
|
0
|
my ($e,$rdn) = @_ ; |
200
|
|
|
|
|
|
|
|
201
|
0
|
|
|
|
|
0
|
my $msg = $ldap->moddn($e, |
202
|
|
|
|
|
|
|
newrdn => $rdn, |
203
|
|
|
|
|
|
|
deleteoldrdn => 'yes') ; |
204
|
0
|
0
|
|
|
|
0
|
if ($msg->is_error) { |
205
|
0
|
|
|
|
|
0
|
$ldap->_seterr($msg) ; |
206
|
0
|
|
|
|
|
0
|
return undef ; |
207
|
|
|
|
|
|
|
} |
208
|
|
|
|
|
|
|
|
209
|
0
|
|
|
|
|
0
|
return $ldap->_seterr(0) ; |
210
|
0
|
|
|
|
|
0
|
return $e ; |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
sub update { |
215
|
0
|
|
|
0
|
1
|
0
|
my $ldap = shift ; |
216
|
0
|
|
|
|
|
0
|
my @parms = @_ ; |
217
|
0
|
|
|
|
|
0
|
my @success ; |
218
|
|
|
|
|
|
|
my $msg ; |
219
|
|
|
|
|
|
|
|
220
|
0
|
|
|
|
|
0
|
while (my $e = shift @parms) { |
221
|
0
|
|
|
|
|
0
|
eval { $e->isa('Net::LDAP::Entry') } ; |
|
0
|
|
|
|
|
0
|
|
222
|
0
|
0
|
|
|
|
0
|
if ($@) { |
223
|
0
|
0
|
|
|
|
0
|
carp "Invalid input: $@" if $^W ; |
224
|
0
|
|
|
|
|
0
|
$ldap->_seterr(-1,'Invalid input') ; |
225
|
0
|
|
|
|
|
0
|
return \@success ; |
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
|
228
|
0
|
|
|
|
|
0
|
$msg = $e->update($ldap) ; |
229
|
|
|
|
|
|
|
|
230
|
0
|
0
|
|
|
|
0
|
if ($msg->is_error) { |
231
|
|
|
|
|
|
|
# Don't complain if error code is 82 |
232
|
|
|
|
|
|
|
# (that means: the entry hasn't been modified) |
233
|
0
|
0
|
|
|
|
0
|
unless ($msg->code == 82) { |
234
|
0
|
|
|
|
|
0
|
$ldap->_seterr($msg) ; |
235
|
0
|
|
|
|
|
0
|
return \@success ; |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
} |
238
|
|
|
|
|
|
|
|
239
|
0
|
|
|
|
|
0
|
push @success,$e ; |
240
|
|
|
|
|
|
|
} |
241
|
|
|
|
|
|
|
|
242
|
0
|
|
|
|
|
0
|
$ldap->_seterr(0) ; |
243
|
0
|
|
|
|
|
0
|
return \@success ; |
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
######################################################################## |
248
|
|
|
|
|
|
|
# These methods should be considered PRIVATE! |
249
|
|
|
|
|
|
|
BEGIN { |
250
|
|
|
|
|
|
|
sub _new_parms { |
251
|
|
|
|
|
|
|
return ( |
252
|
2
|
|
|
2
|
|
29
|
host => 'req', |
253
|
|
|
|
|
|
|
base => 'req', |
254
|
|
|
|
|
|
|
searchattrs => 'req', |
255
|
|
|
|
|
|
|
bindDN => 'opt', |
256
|
|
|
|
|
|
|
bindpw => 'opt', |
257
|
|
|
|
|
|
|
searchbool => 'opt', |
258
|
|
|
|
|
|
|
searchmatch => 'opt', |
259
|
|
|
|
|
|
|
searchextras => 'opt', |
260
|
|
|
|
|
|
|
onlyattrs => 'opt', |
261
|
|
|
|
|
|
|
sort_by => 'opt', |
262
|
|
|
|
|
|
|
) |
263
|
|
|
|
|
|
|
} |
264
|
|
|
|
|
|
|
|
265
|
2
|
50
|
50
|
2
|
|
19
|
carp __PACKAGE__.": Dynamically building accessors at compile time" |
266
|
|
|
|
|
|
|
if $^W and DEBUG ; |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
{ |
269
|
2
|
|
|
2
|
|
360
|
no strict 'refs' ; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
299
|
|
|
2
|
|
|
|
|
4
|
|
270
|
2
|
|
|
|
|
7
|
my %myParms = _new_parms() ; |
271
|
2
|
|
|
|
|
11
|
foreach my $attr (keys %myParms) { |
272
|
20
|
|
|
|
|
42
|
my $subname = "_$attr" ; |
273
|
20
|
|
|
|
|
53
|
my $parm = "net_ldap_express_$attr" ; |
274
|
|
|
|
|
|
|
*$subname = sub { |
275
|
0
|
|
|
0
|
|
0
|
my $ldap = shift ; |
276
|
0
|
0
|
|
|
|
0
|
return $ldap->{$parm} if @_ == 0 ; |
277
|
0
|
|
|
|
|
0
|
return $ldap->{$parm} = shift ; |
278
|
20
|
|
|
|
|
1535
|
} ; |
279
|
|
|
|
|
|
|
} |
280
|
|
|
|
|
|
|
} |
281
|
|
|
|
|
|
|
} |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
sub _makefilter { |
284
|
0
|
|
|
0
|
|
|
my $ldap = shift ; |
285
|
0
|
|
|
|
|
|
my ($query) = @_ ; |
286
|
|
|
|
|
|
|
|
287
|
0
|
0
|
|
|
|
|
my $bool = $ldap->_searchbool ? $ldap->_searchbool : '|' ; |
288
|
0
|
|
|
|
|
|
my $match = $ldap->_searchmatch ; |
289
|
|
|
|
|
|
|
|
290
|
0
|
|
|
|
|
|
my $op = '~=' ; |
291
|
|
|
|
|
|
|
|
292
|
0
|
0
|
|
|
|
|
if ($match) { |
293
|
0
|
0
|
0
|
|
|
|
$op = '=' if $match eq 'substr' or $match eq 'exact' ; |
294
|
0
|
0
|
|
|
|
|
$query = qq/*$query*/ if $match eq 'substr'; |
295
|
|
|
|
|
|
|
} |
296
|
|
|
|
|
|
|
|
297
|
0
|
|
|
|
|
|
my @attrs = @{$ldap->_searchattrs} ; |
|
0
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
|
299
|
0
|
|
|
|
|
|
my $filter ; |
300
|
0
|
0
|
|
|
|
|
if (@attrs == 1) { |
301
|
0
|
|
|
|
|
|
$filter = qq/($attrs[0]$op$query)/ ; |
302
|
|
|
|
|
|
|
} else { |
303
|
0
|
|
|
|
|
|
$filter = "($bool". |
304
|
|
|
|
|
|
|
join("",map("($_$op$query)",@attrs)). |
305
|
|
|
|
|
|
|
")" ; |
306
|
|
|
|
|
|
|
} |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
#carp "Search filter is $filter" if DEBUG ; |
309
|
0
|
|
|
|
|
|
return $filter ; |
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
sub _makesearchparms { |
313
|
0
|
|
|
0
|
|
|
my $ldap = shift ; |
314
|
|
|
|
|
|
|
|
315
|
0
|
0
|
|
|
|
|
unless (exists $ldap->{net_ldap_express_searchparms}) { |
316
|
0
|
|
|
|
|
|
my %parms ; |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
# Set search base |
319
|
0
|
|
|
|
|
|
$parms{base} = $ldap->_base ; |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
# Retrieve onlyattrs, or all; add searchextras if needed |
322
|
0
|
0
|
|
|
|
|
my $attrs = $ldap->_onlyattrs ? $ldap->_onlyattrs : ['*'] ; |
323
|
|
|
|
|
|
|
|
324
|
0
|
0
|
|
|
|
|
if (my $extras = $ldap->_searchextras) { |
325
|
0
|
|
|
|
|
|
push @$attrs,@$extras ; |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
# Now what if one specifies also sort_by, and the attributes are not |
329
|
|
|
|
|
|
|
# in $attrs? The sorting would fail... First, let's see if the |
330
|
|
|
|
|
|
|
# first element of @$attrs is a '*', in that case just skip |
331
|
0
|
0
|
|
|
|
|
if (my $sortattrs = $ldap->_sort_by) { |
332
|
0
|
0
|
|
|
|
|
unless ($attrs->[0] eq '*') { |
333
|
|
|
|
|
|
|
# We have to compare each @$sortattrs element with the elements |
334
|
|
|
|
|
|
|
# of @$attrs; better to have some precompiled patterns handy. |
335
|
0
|
|
|
|
|
|
my @qrattrs = map qr/^$_$/i,@$attrs ; |
336
|
0
|
|
|
|
|
|
foreach my $attr (@$sortattrs) { |
337
|
0
|
0
|
|
|
|
|
push @$attrs,$attr unless grep $attr =~ $_ ,@qrattrs ; |
338
|
|
|
|
|
|
|
} |
339
|
|
|
|
|
|
|
} |
340
|
|
|
|
|
|
|
} |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
# Now we can assign the resulting $attrs to $parms{attrs}... |
343
|
0
|
|
|
|
|
|
$parms{attrs} = $attrs ; |
344
|
|
|
|
|
|
|
|
345
|
0
|
|
|
|
|
|
$ldap->{net_ldap_express_searchparms} = \%parms ; |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
|
348
|
0
|
|
|
|
|
|
return %{$ldap->{net_ldap_express_searchparms}} ; |
|
0
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
} |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
1; |
353
|
|
|
|
|
|
|
__END__ |