Fix the mess with ldb includes.
[metze/samba/wip.git] / source4 / lib / ldb / ldb_ldap / ldb_ldap.c
1 /* 
2    ldb database library
3
4    Copyright (C) Andrew Tridgell  2004
5    Copyright (C) Simo Sorce       2006
6
7      ** NOTE! The following LGPL license applies to the ldb
8      ** library. This does NOT imply that all of Samba is released
9      ** under the LGPL
10    
11    This library is free software; you can redistribute it and/or
12    modify it under the terms of the GNU Lesser General Public
13    License as published by the Free Software Foundation; either
14    version 3 of the License, or (at your option) any later version.
15
16    This library is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    Lesser General Public License for more details.
20
21    You should have received a copy of the GNU Lesser General Public
22    License along with this library; if not, see <http://www.gnu.org/licenses/>.
23 */
24
25 /*
26  *  Name: ldb_ldap
27  *
28  *  Component: ldb ldap backend
29  *
30  *  Description: core files for LDAP backend
31  *
32  *  Author: Andrew Tridgell
33  *
34  *  Modifications:
35  *
36  *  - description: make the module use asyncronous calls
37  *    date: Feb 2006
38  *    author: Simo Sorce
39  */
40
41 #include "ldb_module.h"
42
43 #define LDAP_DEPRECATED 1
44 #include <ldap.h>
45
46 struct lldb_private {
47         LDAP *ldap;
48 };
49
50 struct lldb_context {
51         struct ldb_module *module;
52         struct ldb_request *req;
53
54         struct lldb_private *lldb;
55
56         struct ldb_control **controls;
57         int msgid;
58 };
59
60 static int lldb_ldap_to_ldb(int err) {
61         /* Ldap errors and ldb errors are defined to the same values */
62         return err;
63 }
64
65 /*
66   convert a ldb_message structure to a list of LDAPMod structures
67   ready for ldap_add() or ldap_modify()
68 */
69 static LDAPMod **lldb_msg_to_mods(void *mem_ctx, const struct ldb_message *msg, int use_flags)
70 {
71         LDAPMod **mods;
72         unsigned int i, j;
73         int num_mods = 0;
74
75         /* allocate maximum number of elements needed */
76         mods = talloc_array(mem_ctx, LDAPMod *, msg->num_elements+1);
77         if (!mods) {
78                 errno = ENOMEM;
79                 return NULL;
80         }
81         mods[0] = NULL;
82
83         for (i=0;i<msg->num_elements;i++) {
84                 const struct ldb_message_element *el = &msg->elements[i];
85
86                 mods[num_mods] = talloc(mods, LDAPMod);
87                 if (!mods[num_mods]) {
88                         goto failed;
89                 }
90                 mods[num_mods+1] = NULL;
91                 mods[num_mods]->mod_op = LDAP_MOD_BVALUES;
92                 if (use_flags) {
93                         switch (el->flags & LDB_FLAG_MOD_MASK) {
94                         case LDB_FLAG_MOD_ADD:
95                                 mods[num_mods]->mod_op |= LDAP_MOD_ADD;
96                                 break;
97                         case LDB_FLAG_MOD_DELETE:
98                                 mods[num_mods]->mod_op |= LDAP_MOD_DELETE;
99                                 break;
100                         case LDB_FLAG_MOD_REPLACE:
101                                 mods[num_mods]->mod_op |= LDAP_MOD_REPLACE;
102                                 break;
103                         }
104                 }
105                 mods[num_mods]->mod_type = discard_const_p(char, el->name);
106                 mods[num_mods]->mod_vals.modv_bvals = talloc_array(mods[num_mods], 
107                                                                    struct berval *,
108                                                                    1+el->num_values);
109                 if (!mods[num_mods]->mod_vals.modv_bvals) {
110                         goto failed;
111                 }
112
113                 for (j=0;j<el->num_values;j++) {
114                         mods[num_mods]->mod_vals.modv_bvals[j] = talloc(mods[num_mods]->mod_vals.modv_bvals,
115                                                                         struct berval);
116                         if (!mods[num_mods]->mod_vals.modv_bvals[j]) {
117                                 goto failed;
118                         }
119                         mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = el->values[j].data;
120                         mods[num_mods]->mod_vals.modv_bvals[j]->bv_len = el->values[j].length;
121                 }
122                 mods[num_mods]->mod_vals.modv_bvals[j] = NULL;
123                 num_mods++;
124         }
125
126         return mods;
127
128 failed:
129         talloc_free(mods);
130         return NULL;
131 }
132
133 /*
134   add a single set of ldap message values to a ldb_message
135 */
136 static int lldb_add_msg_attr(struct ldb_context *ldb,
137                              struct ldb_message *msg, 
138                              const char *attr, struct berval **bval)
139 {
140         int count, i;
141         struct ldb_message_element *el;
142
143         count = ldap_count_values_len(bval);
144
145         if (count <= 0) {
146                 return -1;
147         }
148
149         el = talloc_realloc(msg, msg->elements, struct ldb_message_element, 
150                               msg->num_elements + 1);
151         if (!el) {
152                 errno = ENOMEM;
153                 return -1;
154         }
155
156         msg->elements = el;
157
158         el = &msg->elements[msg->num_elements];
159
160         el->name = talloc_strdup(msg->elements, attr);
161         if (!el->name) {
162                 errno = ENOMEM;
163                 return -1;
164         }
165         el->flags = 0;
166
167         el->num_values = 0;
168         el->values = talloc_array(msg->elements, struct ldb_val, count);
169         if (!el->values) {
170                 errno = ENOMEM;
171                 return -1;
172         }
173
174         for (i=0;i<count;i++) {
175                 /* we have to ensure this is null terminated so that
176                    ldb_msg_find_attr_as_string() can work */
177                 el->values[i].data = talloc_size(el->values, bval[i]->bv_len+1);
178                 if (!el->values[i].data) {
179                         errno = ENOMEM;
180                         return -1;
181                 }
182                 memcpy(el->values[i].data, bval[i]->bv_val, bval[i]->bv_len);
183                 el->values[i].data[bval[i]->bv_len] = 0;
184                 el->values[i].length = bval[i]->bv_len;
185                 el->num_values++;
186         }
187
188         msg->num_elements++;
189
190         return 0;
191 }
192
193 /*
194   search for matching records
195 */
196 static int lldb_search(struct lldb_context *lldb_ac)
197 {
198         struct ldb_context *ldb;
199         struct lldb_private *lldb = lldb_ac->lldb;
200         struct ldb_module *module = lldb_ac->module;
201         struct ldb_request *req = lldb_ac->req;
202         struct timeval tv;
203         int ldap_scope;
204         char *search_base;
205         char *expression;
206         int ret;
207
208         ldb = ldb_module_get_ctx(module);
209
210         if (!req->callback || !req->context) {
211                 ldb_set_errstring(ldb, "Async interface called with NULL callback function or NULL context");
212                 return LDB_ERR_OPERATIONS_ERROR;
213         }
214
215         if (req->op.search.tree == NULL) {
216                 ldb_set_errstring(ldb, "Invalid expression parse tree");
217                 return LDB_ERR_OPERATIONS_ERROR;
218         }
219
220         if (req->controls != NULL) {
221                 ldb_debug(ldb, LDB_DEBUG_WARNING, "Controls are not yet supported by ldb_ldap backend!\n");
222         }
223
224         ldb_request_set_state(req, LDB_ASYNC_PENDING);
225
226         search_base = ldb_dn_alloc_linearized(lldb_ac, req->op.search.base);
227         if (req->op.search.base == NULL) {
228                 search_base = talloc_strdup(lldb_ac, "");
229         }
230         if (search_base == NULL) {
231                 return LDB_ERR_OPERATIONS_ERROR;
232         }
233
234         expression = ldb_filter_from_tree(lldb_ac, req->op.search.tree);
235         if (expression == NULL) {
236                 return LDB_ERR_OPERATIONS_ERROR;
237         }
238
239         switch (req->op.search.scope) {
240         case LDB_SCOPE_BASE:
241                 ldap_scope = LDAP_SCOPE_BASE;
242                 break;
243         case LDB_SCOPE_ONELEVEL:
244                 ldap_scope = LDAP_SCOPE_ONELEVEL;
245                 break;
246         default:
247                 ldap_scope = LDAP_SCOPE_SUBTREE;
248                 break;
249         }
250
251         tv.tv_sec = req->timeout;
252         tv.tv_usec = 0;
253
254         ret = ldap_search_ext(lldb->ldap, search_base, ldap_scope, 
255                             expression, 
256                             discard_const_p(char *, req->op.search.attrs), 
257                             0,
258                             NULL,
259                             NULL,
260                             &tv,
261                             LDAP_NO_LIMIT,
262                             &lldb_ac->msgid);
263
264         if (ret != LDAP_SUCCESS) {
265                 ldb_set_errstring(ldb, ldap_err2string(ret));
266         }
267
268         return lldb_ldap_to_ldb(ret);
269 }
270
271 /*
272   add a record
273 */
274 static int lldb_add(struct lldb_context *lldb_ac)
275 {
276         struct ldb_context *ldb;
277         struct lldb_private *lldb = lldb_ac->lldb;
278         struct ldb_module *module = lldb_ac->module;
279         struct ldb_request *req = lldb_ac->req;
280         LDAPMod **mods;
281         char *dn;
282         int ret;
283
284         ldb_module_get_ctx(module);
285
286         ldb_request_set_state(req, LDB_ASYNC_PENDING);
287
288         mods = lldb_msg_to_mods(lldb_ac, req->op.add.message, 0);
289         if (mods == NULL) {
290                 return LDB_ERR_OPERATIONS_ERROR;
291         }
292
293         dn = ldb_dn_alloc_linearized(lldb_ac, req->op.add.message->dn);
294         if (dn == NULL) {
295                 return LDB_ERR_OPERATIONS_ERROR;
296         }
297
298         ret = ldap_add_ext(lldb->ldap, dn, mods,
299                            NULL,
300                            NULL,
301                            &lldb_ac->msgid);
302
303         if (ret != LDAP_SUCCESS) {
304                 ldb_set_errstring(ldb, ldap_err2string(ret));
305         }
306
307         return lldb_ldap_to_ldb(ret);
308 }
309
310 /*
311   modify a record
312 */
313 static int lldb_modify(struct lldb_context *lldb_ac)
314 {
315         struct ldb_context *ldb;
316         struct lldb_private *lldb = lldb_ac->lldb;
317         struct ldb_module *module = lldb_ac->module;
318         struct ldb_request *req = lldb_ac->req;
319         LDAPMod **mods;
320         char *dn;
321         int ret;
322
323         ldb_module_get_ctx(module);
324
325         ldb_request_set_state(req, LDB_ASYNC_PENDING);
326
327         mods = lldb_msg_to_mods(lldb_ac, req->op.mod.message, 1);
328         if (mods == NULL) {
329                 return LDB_ERR_OPERATIONS_ERROR;
330         }
331
332         dn = ldb_dn_alloc_linearized(lldb_ac, req->op.mod.message->dn);
333         if (dn == NULL) {
334                 return LDB_ERR_OPERATIONS_ERROR;
335         }
336
337         ret = ldap_modify_ext(lldb->ldap, dn, mods,
338                               NULL,
339                               NULL,
340                               &lldb_ac->msgid);
341
342         if (ret != LDAP_SUCCESS) {
343                 ldb_set_errstring(ldb, ldap_err2string(ret));
344         }
345
346         return lldb_ldap_to_ldb(ret);
347 }
348
349 /*
350   delete a record
351 */
352 static int lldb_delete(struct lldb_context *lldb_ac)
353 {
354         struct ldb_context *ldb;
355         struct lldb_private *lldb = lldb_ac->lldb;
356         struct ldb_module *module = lldb_ac->module;
357         struct ldb_request *req = lldb_ac->req;
358         char *dnstr;
359         int ret;
360
361         ldb_module_get_ctx(module);
362
363         ldb_request_set_state(req, LDB_ASYNC_PENDING);
364
365         dnstr = ldb_dn_alloc_linearized(lldb_ac, req->op.del.dn);
366
367         ret = ldap_delete_ext(lldb->ldap, dnstr,
368                               NULL,
369                               NULL,
370                               &lldb_ac->msgid);
371
372         if (ret != LDAP_SUCCESS) {
373                 ldb_set_errstring(ldb, ldap_err2string(ret));
374         }
375
376         return lldb_ldap_to_ldb(ret);
377 }
378
379 /*
380   rename a record
381 */
382 static int lldb_rename(struct lldb_context *lldb_ac)
383 {
384         struct ldb_context *ldb;
385         struct lldb_private *lldb = lldb_ac->lldb;
386         struct ldb_module *module = lldb_ac->module;
387         struct ldb_request *req = lldb_ac->req;
388         char *old_dn;
389         char *newrdn;
390         char *parentdn;
391         int ret;
392
393         ldb_module_get_ctx(module);
394
395         ldb_request_set_state(req, LDB_ASYNC_PENDING);
396
397         old_dn = ldb_dn_alloc_linearized(lldb_ac, req->op.rename.olddn);
398         if (old_dn == NULL) {
399                 return LDB_ERR_OPERATIONS_ERROR;
400         }
401
402         newrdn = talloc_asprintf(lldb_ac, "%s=%s",
403                                  ldb_dn_get_rdn_name(req->op.rename.newdn),
404                                  ldb_dn_escape_value(lldb, *(ldb_dn_get_rdn_val(req->op.rename.newdn))));
405         if (!newrdn) {
406                 return LDB_ERR_OPERATIONS_ERROR;
407         }
408
409         parentdn = ldb_dn_alloc_linearized(lldb_ac, ldb_dn_get_parent(lldb_ac, req->op.rename.newdn));
410         if (!parentdn) {
411                 return LDB_ERR_OPERATIONS_ERROR;
412         }
413
414         ret = ldap_rename(lldb->ldap, old_dn, newrdn, parentdn,
415                           1, NULL, NULL,
416                           &lldb_ac->msgid);
417
418         if (ret != LDAP_SUCCESS) {
419                 ldb_set_errstring(ldb, ldap_err2string(ret));
420         }
421
422         return lldb_ldap_to_ldb(ret);
423 }
424
425 static int lldb_start_trans(struct ldb_module *module)
426 {
427         /* TODO implement a local transaction mechanism here */
428
429         return LDB_SUCCESS;
430 }
431
432 static int lldb_end_trans(struct ldb_module *module)
433 {
434         /* TODO implement a local transaction mechanism here */
435
436         return LDB_SUCCESS;
437 }
438
439 static int lldb_del_trans(struct ldb_module *module)
440 {
441         /* TODO implement a local transaction mechanism here */
442
443         return LDB_SUCCESS;
444 }
445
446 void lldb_request_done(struct lldb_context *ac,
447                         struct ldb_control **ctrls, int error)
448 {
449         struct ldb_request *req;
450         struct ldb_reply *ares;
451
452         req = ac->req;
453
454         ares = talloc_zero(req, struct ldb_reply);
455         if (!ares) {
456                 ldb_oom(ldb_module_get_ctx(ac->module));
457                 req->callback(req, NULL);
458                 return;
459         }
460         ares->type = LDB_REPLY_DONE;
461         ares->controls = talloc_steal(ares, ctrls);
462         ares->error = error;
463
464         req->callback(req, ares);
465 }
466
467 /* return false if the request is still in progress
468  * return true if the request is completed
469  */
470 static bool lldb_parse_result(struct lldb_context *ac, LDAPMessage *result)
471 {
472         struct ldb_context *ldb;
473         struct lldb_private *lldb = ac->lldb;
474         LDAPControl **serverctrlsp = NULL;
475         char **referralsp = NULL;
476         char *matcheddnp = NULL;
477         char *errmsgp = NULL;
478         LDAPMessage *msg;
479         int type;
480         struct ldb_message *ldbmsg;
481         char *referral;
482         bool callback_failed;
483         bool request_done;
484         bool lret;
485         int ret;
486         int i;
487
488         ldb = ldb_module_get_ctx(ac->module);
489
490         type = ldap_msgtype(result);
491         callback_failed = false;
492         request_done = false;
493
494         switch (type) {
495         case LDAP_RES_SEARCH_ENTRY:
496
497                 msg = ldap_first_entry(lldb->ldap, result);
498                 if (msg != NULL) {
499                         BerElement *berptr = NULL;
500                         char *attr, *dn;
501
502                         ldbmsg = ldb_msg_new(ac);
503                         if (!ldbmsg) {
504                                 ret = LDB_ERR_OPERATIONS_ERROR;
505                                 break;
506                         }
507
508                         dn = ldap_get_dn(lldb->ldap, msg);
509                         if (!dn) {
510                                 talloc_free(ldbmsg);
511                                 ret = LDB_ERR_OPERATIONS_ERROR;
512                                 break;
513                         }
514                         ldbmsg->dn = ldb_dn_new(ldbmsg, ldb, dn);
515                         if ( ! ldb_dn_validate(ldbmsg->dn)) {
516                                 talloc_free(ldbmsg);
517                                 ret = LDB_ERR_OPERATIONS_ERROR;
518                                 break;
519                         }
520                         ldap_memfree(dn);
521
522                         ldbmsg->num_elements = 0;
523                         ldbmsg->elements = NULL;
524
525                         /* loop over all attributes */
526                         for (attr=ldap_first_attribute(lldb->ldap, msg, &berptr);
527                              attr;
528                              attr=ldap_next_attribute(lldb->ldap, msg, berptr)) {
529                                 struct berval **bval;
530                                 bval = ldap_get_values_len(lldb->ldap, msg, attr);
531
532                                 if (bval) {
533                                         lldb_add_msg_attr(ldb, ldbmsg, attr, bval);
534                                         ldap_value_free_len(bval);
535                                 }
536                         }
537                         if (berptr) ber_free(berptr, 0);
538
539                         ret = ldb_module_send_entry(ac->req, ldbmsg, NULL /* controls not yet supported */);
540                         if (ret != LDB_SUCCESS) {
541
542                                 callback_failed = true;
543                         }
544                 } else {
545                         ret = LDB_ERR_OPERATIONS_ERROR;
546                 }
547                 break;
548
549         case LDAP_RES_SEARCH_REFERENCE:
550
551                 if (ldap_parse_result(lldb->ldap, result, &ret,
552                                         &matcheddnp, &errmsgp,
553                                         &referralsp, &serverctrlsp, 0) != LDAP_SUCCESS) {
554                         ret = LDB_ERR_OPERATIONS_ERROR;
555                 }
556                 if (ret != LDB_SUCCESS) {
557                         break;
558                 }
559                 if (referralsp == NULL) {
560                         ret = LDB_ERR_PROTOCOL_ERROR;
561                         break;
562                 }
563
564                 for (i = 0; referralsp[i]; i++) {
565                         referral = talloc_strdup(ac, referralsp[i]);
566
567                         ret = ldb_module_send_referral(ac->req, referral);
568                         if (ret != LDB_SUCCESS) {
569                                 callback_failed = true;
570                                 break;
571                         }
572                 }
573                 break;
574
575         case LDAP_RES_SEARCH_RESULT:
576         case LDAP_RES_MODIFY:
577         case LDAP_RES_ADD:
578         case LDAP_RES_DELETE:
579         case LDAP_RES_MODDN:
580
581                 if (ldap_parse_result(lldb->ldap, result, &ret,
582                                         &matcheddnp, &errmsgp,
583                                         &referralsp, &serverctrlsp, 0) != LDAP_SUCCESS) {
584                         ret = LDB_ERR_OPERATIONS_ERROR;
585                 }
586                 if (ret != LDB_SUCCESS) {
587                         break;
588                 }
589
590                 if (serverctrlsp != NULL) {
591                         /* FIXME: transform the LDAPControl list into an ldb_control one */
592                         ac->controls = NULL;
593                 }
594
595                 request_done = true;
596                 break;
597
598         default:
599                 ret = LDB_ERR_PROTOCOL_ERROR;
600                 break;
601         }
602
603         if (ret != LDB_SUCCESS) {
604
605                 /* if the callback failed the caller will have freed the
606                  * request. Just return and don't try to use it */
607                 if (callback_failed) {
608
609                         /* tell lldb_wait to remove the request from the
610                          *  queue */
611                         lret = true;
612                         goto free_and_return;
613                 }
614
615                 request_done = true;
616         }
617
618         if (request_done) {
619                 lldb_request_done(ac, ac->controls, ret);
620                 lret = true;
621                 goto free_and_return;
622         }
623
624         lret = false;
625
626 free_and_return:
627
628         if (matcheddnp) ldap_memfree(matcheddnp);
629         if (errmsgp && *errmsgp) {
630                 ldb_set_errstring(ldb, errmsgp);
631         }
632         if (errmsgp) {
633                 ldap_memfree(errmsgp);
634         }
635         if (referralsp) ldap_value_free(referralsp);
636         if (serverctrlsp) ldap_controls_free(serverctrlsp);
637
638         ldap_msgfree(result);
639
640         return lret;
641 }
642
643 static void lldb_timeout(struct tevent_context *ev,
644                          struct tevent_timer *te,
645                          struct timeval t,
646                          void *private_data)
647 {
648         struct lldb_context *ac;
649         ac = talloc_get_type(private_data, struct lldb_context);
650
651         lldb_request_done(ac, NULL, LDB_ERR_TIME_LIMIT_EXCEEDED);
652 }
653
654 static void lldb_callback(struct tevent_context *ev,
655                           struct tevent_timer *te,
656                           struct timeval t,
657                           void *private_data)
658 {
659         struct lldb_context *ac;
660         struct tevent_timer *lte;
661         struct timeval tv;
662         LDAPMessage *result;
663         int lret;
664
665         ac = talloc_get_type(private_data, struct lldb_context);
666
667         if (!ac->msgid) {
668                 lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR);
669                 return;
670         }
671
672         tv.tv_sec = 0;
673         tv.tv_usec = 0;
674         lret = ldap_result(ac->lldb->ldap, ac->msgid, 0, &tv, &result);
675         if (lret == 0) {
676                 goto respin;
677         }
678         if (lret == -1) {
679                 lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR);
680                 return;
681         }
682
683         if ( ! lldb_parse_result(ac, result)) {
684                 goto respin;
685         }
686
687         return;
688
689 respin:
690         tv.tv_sec = 0;
691         tv.tv_usec = 100;
692         lte = tevent_add_timer(ev, ac, tv, lldb_callback, ac);
693         if (NULL == lte) {
694                 lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR);
695         }
696 }
697
698 static bool lldb_dn_is_special(struct ldb_request *req)
699 {
700         struct ldb_dn *dn = NULL;
701
702         switch (req->operation) {
703         case LDB_ADD:
704                 dn = req->op.add.message->dn;
705                 break;
706         case LDB_MODIFY:
707                 dn = req->op.mod.message->dn;
708                 break;
709         case LDB_DELETE:
710                 dn = req->op.del.dn;
711                 break;
712         case LDB_RENAME:
713                 dn = req->op.rename.olddn;
714                 break;
715         default:
716                 break;
717         }
718
719         if (dn && ldb_dn_is_special(dn)) {
720                 return true;
721         }
722         return false;
723 }
724
725 static void lldb_auto_done_callback(struct tevent_context *ev,
726                                     struct tevent_timer *te,
727                                     struct timeval t,
728                                     void *private_data)
729 {
730         struct lldb_context *ac;
731
732         ac = talloc_get_type(private_data, struct lldb_context);
733         lldb_request_done(ac, NULL, LDB_SUCCESS);
734 }
735
736 static int lldb_handle_request(struct ldb_module *module, struct ldb_request *req)
737 {
738         struct ldb_context *ldb;
739         struct lldb_private *lldb;
740         struct lldb_context *ac;
741         struct tevent_context *ev;
742         struct tevent_timer *te;
743         struct timeval tv;
744         int ret;
745
746         lldb = talloc_get_type(ldb_module_get_private(module), struct lldb_private);
747         ldb = ldb_module_get_ctx(module);
748
749         if (req->starttime == 0 || req->timeout == 0) {
750                 ldb_set_errstring(ldb, "Invalid timeout settings");
751                 return LDB_ERR_TIME_LIMIT_EXCEEDED;
752         }
753
754         ev = ldb_get_event_context(ldb);
755         if (NULL == ev) {
756                 return LDB_ERR_OPERATIONS_ERROR;
757         }
758
759         ac = talloc_zero(ldb, struct lldb_context);
760         if (ac == NULL) {
761                 ldb_set_errstring(ldb, "Out of Memory");
762                 return LDB_ERR_OPERATIONS_ERROR;
763         }
764
765         ac->module = module;
766         ac->req = req;
767         ac->lldb = lldb;
768         ac->msgid = 0;
769
770         if (lldb_dn_is_special(req)) {
771                 tv.tv_sec = 0;
772                 tv.tv_usec = 0;
773                 te = tevent_add_timer(ev, ac, tv,
774                                      lldb_auto_done_callback, ac);
775                 if (NULL == te) {
776                         return LDB_ERR_OPERATIONS_ERROR;
777                 }
778
779                 return LDB_SUCCESS;
780         }
781
782         switch (ac->req->operation) {
783         case LDB_SEARCH:
784                 ret = lldb_search(ac);
785                 break;
786         case LDB_ADD:
787                 ret = lldb_add(ac);
788                 break;
789         case LDB_MODIFY:
790                 ret = lldb_modify(ac);
791                 break;
792         case LDB_DELETE:
793                 ret = lldb_delete(ac);
794                 break;
795         case LDB_RENAME:
796                 ret = lldb_rename(ac);
797                 break;
798         default:
799                 /* no other op supported */
800                 ret = LDB_ERR_OPERATIONS_ERROR;
801                 break;
802         }
803
804         if (ret != LDB_SUCCESS) {
805                 lldb_request_done(ac, NULL, ret);
806                 return ret;
807         }
808
809         tv.tv_sec = 0;
810         tv.tv_usec = 0;
811         te = tevent_add_timer(ev, ac, tv, lldb_callback, ac);
812         if (NULL == te) {
813                 return LDB_ERR_OPERATIONS_ERROR;
814         }
815
816
817         tv.tv_sec = req->starttime + req->timeout;
818         tv.tv_usec = 0;
819         te = tevent_add_timer(ev, ac, tv, lldb_timeout, ac);
820         if (NULL == te) {
821                 return LDB_ERR_OPERATIONS_ERROR;
822         }
823
824         return LDB_SUCCESS;
825 }
826
827 static const struct ldb_module_ops lldb_ops = {
828         .name              = "ldap",
829         .search            = lldb_handle_request,
830         .add               = lldb_handle_request,
831         .modify            = lldb_handle_request,
832         .del               = lldb_handle_request,
833         .rename            = lldb_handle_request,
834         .request           = lldb_handle_request,
835         .start_transaction = lldb_start_trans,
836         .end_transaction   = lldb_end_trans,
837         .del_transaction   = lldb_del_trans,
838 };
839
840
841 static int lldb_destructor(struct lldb_private *lldb)
842 {
843         ldap_unbind(lldb->ldap);
844         return 0;
845 }
846
847 /*
848   connect to the database
849 */
850 static int lldb_connect(struct ldb_context *ldb,
851                         const char *url,
852                         unsigned int flags,
853                         const char *options[],
854                         struct ldb_module **_module)
855 {
856         struct ldb_module *module;
857         struct lldb_private *lldb;
858         int version = 3;
859         int ret;
860
861         module = ldb_module_new(ldb, ldb, "ldb_ldap backend", &lldb_ops);
862         if (!module) return -1;
863
864         lldb = talloc_zero(module, struct lldb_private);
865         if (!lldb) {
866                 ldb_oom(ldb);
867                 goto failed;
868         }
869         ldb_module_set_private(module, lldb);
870
871         ret = ldap_initialize(&lldb->ldap, url);
872         if (ret != LDAP_SUCCESS) {
873                 ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s\n",
874                           url, ldap_err2string(ret));
875                 goto failed;
876         }
877
878         talloc_set_destructor(lldb, lldb_destructor);
879
880         ret = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
881         if (ret != LDAP_SUCCESS) {
882                 ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s\n",
883                           ldap_err2string(ret));
884                 goto failed;
885         }
886
887         *_module = module;
888         return 0;
889
890 failed:
891         talloc_free(module);
892         return -1;
893 }
894
895 const struct ldb_backend_ops ldb_ldap_backend_ops = {
896         .name = "ldap",
897         .connect_fn = lldb_connect
898 };
899
900 const struct ldb_backend_ops ldb_ldapi_backend_ops = {
901         .name = "ldapi",
902         .connect_fn = lldb_connect
903 };
904
905 const struct ldb_backend_ops ldb_ldaps_backend_ops = {
906         .name = "ldaps",
907         .connect_fn = lldb_connect
908 };