]> git.sur5r.net Git - openldap/blob - servers/slapd/back-perl/SampleLDAP.pm
Resync with HEAD
[openldap] / servers / slapd / back-perl / SampleLDAP.pm
1
2 =head1 Introduction
3
4 This is a sample Perl module for the OpenLDAP server slapd.
5 It also contains the documentation that you will need to
6 get up and going.
7
8 WARNING: the interfaces of this backen to the perl module
9 MAY change.  Any suggestions would greatly be appreciated.
10
11
12 =head1 Overview
13
14 The Perl back end works by embedding a Perl interpreter into
15 the slapd backend. Then when the configuration file indicates
16 that we are going to be using a Perl backend it will get an
17 option that tells it what module to use.  It then creates a 
18 new Perl object that handles all the request for that particular
19 instance of the back end.
20
21
22 =head1 Interface
23
24 You will need to create a method for each one of the
25 following actions that you wish to handle.
26
27    * new        # Creates a new object.
28    * search     # Performs the ldap search
29    * compare    # does a compare
30    * modify     # modify's and entry
31    * add        # adds an entry to back end
32    * modrdn     # modifies a an entries rdn
33    * delete     # deletes an ldap entry
34    * config     # process unknown config file lines
35    * init       # called after backend is initialized
36
37 =head2 new
38
39 This method is called when the config file encounters a 
40 B<perlmod> line. The module in that line is then effectively
41 used into the perl interpreter, then the new method is called
42 to create a new object.  Note that multiple instances of that
43 object may be instantiated, as with any perl object.
44
45 The new method doesn't receive any arguments other than the
46 class name.
47
48 RETURN: 
49
50 =head2 search
51
52 This method is called when a search request comes from a client.
53 It arguments are as follow.
54
55   * obj reference
56   * base DN
57   * scope
58   * alias deferencing policy
59   * size limit
60   * time limit
61   * filter string
62   * attributes only flag ( 1 for yes )
63   * list of attributes that are to be returned. (could be empty)
64
65 RETURN:
66
67 =head2 compare
68
69 This method is called when a compare request comes from a client.
70 Its arguments are as follows.
71
72   * obj reference
73   * dn
74   * attribute assertion string
75
76 RETURN:
77
78 =head2 modify
79
80 This method is called when a modify request comes from a client.
81 Its arguments are as follows.
82
83   * obj reference
84   * dn
85   * lists formatted as follows
86    { ADD | DELETE | REPLACE }, key, value
87
88 RETURN:
89
90 =head2 add
91
92 This method is called when a add request comes from a client.
93 Its arguments are as follows.
94
95   * obj reference
96   * entry in string format.
97
98 RETURN:
99
100 =head2 modrdn
101
102 This method is called when a modrdn request comes from a client.
103 Its arguments are as follows.
104
105   * obj reference
106   * dn
107   * new rdn
108   * delete old dn flage ( 1 means yes )
109
110 RETURN:
111
112 =head2 delete
113
114 This method is called when a delete request comes from a client.
115 Its arguments are as follows.
116
117   * obj reference
118   * dn
119
120 RETURN:
121
122 =head2 config
123
124   * obj reference
125   * arrray of arguments on line
126
127 RETURN: non zero value if this is not a valid option.
128
129 =head2 init
130
131   * obj reference
132
133 RETURN: non zero value if initialization failed.
134
135 =head1 Configuration
136
137 The perl section of the config file recognizes the following 
138 options.  It should also be noted that any option not recoginized
139 will be sent to the B<config> method of the perl module as noted
140 above.
141
142   database perl         # startn section for the perl database
143
144   suffix          "o=AnyOrg, c=US"
145
146   perlModulePath /path/to/libs  # addes the path to @INC variable same
147                              # as "use lib '/path/to/libs'"
148
149   perlModule ModName       # use the module name ModName from ModName.pm
150
151   filterSearchResults      # search results are candidates that need to be
152                            # filtered, rather than search results to be 
153                            # returned directly to the client
154
155 =cut
156
157 package SampleLDAP;
158
159 use POSIX;
160
161 sub new
162 {
163         my $class = shift;
164
165         my $this = {};
166         bless $this, $class;
167         print STDERR "Here in new\n";
168         print STDERR "Posix Var " . BUFSIZ . " and " . FILENAME_MAX . "\n";
169         return $this;
170 }
171
172 sub search
173 {
174         my $this = shift;
175         my($base, $scope, $deref, $sizeLim, $timeLim, $filterStr, $attrOnly, @attrs ) = @_;
176         print STDERR "====$filterStr====\n";
177         $filterStr =~ s/\(|\)//g;
178         $filterStr =~ s/=/: /;
179
180         my @match_dn = ();
181         foreach my $dn ( keys %$this ) {
182                 if ( $this->{ $dn } =~ /$filterStr/im ) {
183                         push @match_dn, $dn;
184                         last if ( scalar @match_dn == $sizeLim );
185
186                 }
187         }
188
189         my @match_entries = ();
190         
191         foreach my $dn ( @match_dn )  {
192                 push @match_entries, $this->{ $dn };
193         }
194
195         return ( 0 , @match_entries );
196
197 }
198
199 sub compare
200 {
201         my $this = shift;
202         my ( $dn, $avaStr ) = @_;
203         my $rc = 5; # LDAP_COMPARE_FALSE
204
205         $avaStr =~ s/=/: /;
206
207         if ( $this->{ $dn } =~ /$avaStr/im ) {
208                 $rc = 6; # LDAP_COMPARE_TRUE
209         }
210
211         return $rc;
212 }
213
214 sub modify
215 {
216         my $this = shift;
217
218         my ( $dn, @list ) = @_;
219
220         while ( @list > 0 ) {
221                 my $action = shift @list;
222                 my $key    = shift @list;
223                 my $value  = shift @list;
224
225                 if( $action eq "ADD" ) {
226                         $this->{ $dn } .= "$key: $value\n";
227
228                 }
229                 elsif( $action eq "DELETE" ) {
230                         $this->{ $dn } =~ s/^$key:\s*$value\n//mi ;
231
232                 }
233                 elsif( $action eq "REPLACE" ) {
234                         $this->{ $dn } =~ s/$key: .*$/$key: $value/im ;
235                 }
236         }
237
238         return 0;
239 }
240
241 sub add
242 {
243         my $this = shift;
244
245         my ( $entryStr ) = @_;
246
247         my ( $dn ) = ( $entryStr =~ /dn:\s(.*)$/m );
248
249         #
250         # This needs to be here untill a normalize dn is
251         # passed to this routine.
252         #
253         $dn = uc( $dn );
254         $dn =~ s/\s*//g;
255
256
257         $this->{$dn} = $entryStr;
258
259         return 0;
260 }
261
262 sub modrdn
263 {
264         my $this = shift;
265
266         my ( $dn, $newdn, $delFlag ) = @_;
267
268         $this->{ $newdn } = $this->{ $dn };
269
270         if( $delFlag ) {
271                 delete $this->{ $dn };
272         }
273         return 0;
274
275 }
276
277 sub delete
278 {
279         my $this = shift;
280
281         my ( $dn ) = @_;
282         
283         print STDERR "XXXXXX $dn XXXXXXX\n";
284         delete $this->{$dn};
285 }
286
287 sub config
288 {
289         my $this = shift;
290
291         my ( @args ) = @_;
292         local $, = " - ";
293         print STDERR @args;
294         print STDERR "\n";
295         return 0;
296 }
297
298 1;
299
300