1# Copyright (c) 1999-2004 Graham Barr <gbarr@pobox.com>. All rights reserved.
2# This program is free software; you can redistribute it and/or
3# modify it under the same terms as Perl itself.
4
5package Net::LDAP::Control;
6
7use vars qw($VERSION);
8use strict;
9
10use Net::LDAP::Constant qw(
11  LDAP_CONTROL_SORTREQUEST
12  LDAP_CONTROL_SORTRESULT
13  LDAP_CONTROL_VLVREQUEST
14  LDAP_CONTROL_VLVRESPONSE
15  LDAP_CONTROL_PAGED
16  LDAP_CONTROL_PROXYAUTHENTICATION
17  LDAP_CONTROL_MANAGEDSAIT
18  LDAP_CONTROL_PERSISTENTSEARCH
19  LDAP_CONTROL_ENTRYCHANGE
20  LDAP_CONTROL_MATCHEDVALUES
21  LDAP_CONTROL_PASSWORDPOLICY
22);
23
24$VERSION = "0.07";
25
26my %Pkg2Type = (
27
28  'Net::LDAP::Control::Sort'		=> LDAP_CONTROL_SORTREQUEST,
29  'Net::LDAP::Control::SortResult' 	=> LDAP_CONTROL_SORTRESULT,
30
31  'Net::LDAP::Control::VLV'		=> LDAP_CONTROL_VLVREQUEST,
32  'Net::LDAP::Control::VLVResponse'	=> LDAP_CONTROL_VLVRESPONSE,
33
34  'Net::LDAP::Control::Paged'		=> LDAP_CONTROL_PAGED,
35
36  'Net::LDAP::Control::ProxyAuth'	=> LDAP_CONTROL_PROXYAUTHENTICATION,
37
38  'Net::LDAP::Control::ManageDsaIT'	=> LDAP_CONTROL_MANAGEDSAIT,
39
40  'Net::LDAP::Control::PersistentSearch'	=> LDAP_CONTROL_PERSISTENTSEARCH,
41  'Net::LDAP::Control::EntryChange'	=> LDAP_CONTROL_ENTRYCHANGE,
42
43  'Net::LDAP::Control::MatchedValues'	=> LDAP_CONTROL_MATCHEDVALUES,
44
45  'Net::LDAP::Control::PasswordPolicy'	=> LDAP_CONTROL_PASSWORDPOLICY,
46  #
47  #LDAP_CONTROL_PWEXPIRED
48  #LDAP_CONTROL_PWEXPIRING
49  #
50  #LDAP_CONTROL_REFERRALS
51);
52
53my %Type2Pkg = reverse %Pkg2Type;
54
55sub register {
56  my($class,$oid) = @_;
57
58  require Carp and Carp::croak("$oid is already registered to $Type2Pkg{$oid}")
59    if exists $Type2Pkg{$oid} and $Type2Pkg{$oid} ne $class;
60
61  require Carp and Carp::croak("$class is already registered to $Pkg2Type{$class}")
62    if exists $Pkg2Type{$class} and $Pkg2Type{$class} ne $oid;
63
64  $Type2Pkg{$oid} = $class;
65  $Pkg2Type{$class} = $oid;
66}
67
68sub new {
69  my $self = shift;
70  my $pkg  = ref($self) || $self;
71  my $oid  = (@_ & 1) ? shift : undef;
72  my %args = @_;
73
74  $args{'type'} ||= $oid || $Pkg2Type{$pkg} || '';
75
76  unless ($args{type} =~ /^\d+(?:\.\d+)+$/) {
77    $args{error} = 'Invalid OID';
78    return bless \%args;
79  }
80
81  if ($pkg eq __PACKAGE__ and exists $Type2Pkg{$args{type}}) {
82    $pkg = $Type2Pkg{$args{type}};
83    eval "require $pkg" or die $@;
84  }
85
86  delete $args{error};
87
88  bless(\%args, $pkg)->init;
89}
90
91
92sub from_asn {
93  my $self = shift;
94  my $asn = shift;
95  my $class = ref($self) || $self;
96
97  if ($class eq __PACKAGE__ and exists $Type2Pkg{$asn->{type}}) {
98    $class = $Type2Pkg{$asn->{type}};
99    eval "require $class" or die $@;
100  }
101
102  delete $asn->{error};
103
104  bless($asn, $class)->init;
105}
106
107sub to_asn {
108  my $self = shift;
109  $self->value; # Ensure value is there
110  delete $self->{critical} unless $self->{critical};
111  $self;
112}
113
114sub critical {
115  my $self = shift;
116  $self->{critical} = shift if @_;
117  $self->{critical} || 0;
118}
119
120sub value    {
121  my $self = shift;
122  $self->{value} = shift if @_;
123  $self->{value} || undef
124}
125
126sub type  { shift->{type} }
127sub valid { ! exists shift->{error} }
128sub error { shift->{error} }
129sub init  { shift }
130
1311;
132
133__END__
134
135
136=head1 NAME
137
138Net::LDAP::Control - LDAPv3 control object base class
139
140=head1 SYNOPSIS
141
142 use Net::LDAP::Control;
143 use Net::LDAP::Constant qw( LDAP_CONTROL_MATCHEDVALS );
144
145 $ctrl = Net::LDAP::Control->new(
146   type     => "1.2.3.4",
147   value    => "help",
148   critical => 0
149 );
150
151 $mesg = $ldap->search( @args, control => [ $ctrl ]);
152
153 $ctrl = Net::LDAP::Control->new( type => LDAP_CONTROL_MATCHEDVALS );
154
155=head1 DESCRIPTION
156
157C<Net::LDAP::Control> is a base-class for LDAPv3 control objects.
158
159=cut
160
161##
162## Need more blurb in here about controls
163##
164
165=head1 CONSTRUCTORS
166
167=over 4
168
169=item new ( ARGS )
170
171ARGS is a list of name/value pairs, valid arguments are:
172
173=over 4
174
175=item critical
176
177A boolean value, if TRUE and the control is unrecognized by the server or
178is inappropriate for the requested operation then the server will return
179an error and the operation will not be performed.
180
181If FALSE and the control is unrecognized by the server or
182is inappropriate for the requested operation then the server will ignore
183the control and perform the requested operation as if the control was
184not given.
185
186If absent, FALSE is assumed.
187
188=item type
189
190A dotted-decimal representation of an OBJECT IDENTIFIER which
191uniquely identifies the control. This prevents conflicts between
192control names.
193
194This may be ommitted if the contructor is being called on a sub-class of
195Net::LDAP::Control which has registered to be associated with an OID.
196If the contructor is being called on the Net::LDAP::Control
197package, then this argument must be given.  If the given OID has been
198registered by a package, then the returned object will be of the type
199registered to handle that OID.
200
201=item value
202
203Optional information associated with the control. It's format is specific
204to the particular control.
205
206=back
207
208=item from_asn ( ASN )
209
210ASN is a HASH reference, normally extracted from a PDU. It will contain
211a C<type> element and optionally C<critical> and C<value> elements. On
212return ASN will be blessed into a package. If C<type> is a registered
213OID, then ASN will be blessed into the registered package, if not then ASN
214will be blessed into Net::LDAP::Control.
215
216This constructor is used internally by Net::LDAP and assumes that HASH
217passed contains a valid control. It should be used with B<caution>.
218
219=back
220
221=head1 METHODS
222
223In addition to the methods listed below, each of the named parameters
224to C<new> is also avaliable as a method. C<type> will return the OID of
225the control object. C<value> and C<critical> are set/get methods and will
226return the current value for each attribute if called without arguments,
227but may also be called with arguments to set new values.
228
229=over 4
230
231=item error ()
232
233If there has been an error returns a description of the error, otherwise it will
234return C<undef>
235
236=item init ()
237
238C<init> will be called as the last step in both contructors. What it does will depend
239on the sub-class. It must always return the object.
240
241=item register ( OID )
242
243C<register> is provided for sub-class implementors. It should be called as a class method
244on a sub-class of Net::LDAP::Control with the OID that the class will handle. Net::LDAP::Control
245will remember this class and OID pair and use it in the following
246situations.
247
248=over 4
249
250=item *
251
252C<new> is called as a class method on the Net::LDAP::Control package and OID is passed
253as the type. The returned object will be blessed into the package that registered
254the OID.
255
256=item *
257
258C<new> is called as a class method on a registered package and the C<type> is not
259specified. The C<type> will be set to the OID registered by that package.
260
261=item *
262
263C<from_asn> is called to construct an object from ASN. The returned object will be
264blessed into the package which was registered to handle the OID in the ASN.
265
266=back
267
268=item ( to_asn )
269
270Returns a structure suitable for passing to Convert::ASN1 for
271encoding. This method will be called by L<Net::LDAP> when the
272control is used.
273
274The base class implementation of this method will call the C<value> method
275without arguments to allow a sub-class to encode it's value. Sub-classes
276should not need to override this method.
277
278=item valid ()
279
280Returns true if the object is valid and can be encoded. The default implementation
281for this method is to return TRUE if there is no error, but sub-classes may override that.
282
283=back
284
285=head1 SEE ALSO
286
287L<Net::LDAP>
288L<Net::LDAP::Control::EntryChange>
289L<Net::LDAP::Control::ManageDsaIT>
290L<Net::LDAP::Control::Paged>
291L<Net::LDAP::Control::PersistentSearch>
292L<Net::LDAP::Control::ProxyAuth>
293L<Net::LDAP::Control::Sort>
294L<Net::LDAP::Control::SortResult>
295L<Net::LDAP::Control::VLV>
296L<Net::LDAP::Control::VLVResponse>
297
298=head1 AUTHOR
299
300Graham Barr E<lt>gbarr@pobox.comE<gt>
301
302Please report any bugs, or post any suggestions, to the perl-ldap mailing list
303E<lt>perl-ldap@perl.orgE<gt>
304
305=head1 COPYRIGHT
306
307Copyright (c) 1999-2004 Graham Barr. All rights reserved. This program is
308free software; you can redistribute it and/or modify it under the same
309terms as Perl itself.
310
311=cut
312