Add support for implementing LDB modules in Python.
[ira/wip.git] / source4 / lib / ldb / ldb.i
1 /*
2    Unix SMB/CIFS implementation.
3
4    Swig interface to ldb.
5
6    Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7    Copyright (C) 2006 Simo Sorce <idra@samba.org>
8    Copyright (C) 2007-2008 Jelmer Vernooij <jelmer@samba.org>
9
10      ** NOTE! The following LGPL license applies to the ldb
11      ** library. This does NOT imply that all of Samba is released
12      ** under the LGPL
13    
14    This library is free software; you can redistribute it and/or
15    modify it under the terms of the GNU Lesser General Public
16    License as published by the Free Software Foundation; either
17    version 3 of the License, or (at your option) any later version.
18
19    This library is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22    Lesser General Public License for more details.
23
24    You should have received a copy of the GNU Lesser General Public
25    License along with this library; if not, see <http://www.gnu.org/licenses/>.
26 */
27
28 %define DOCSTRING
29 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server."
30 %enddef
31
32 %module(docstring=DOCSTRING) ldb
33
34 %{
35
36 #include <stdint.h>
37 #include <stdbool.h>
38 #include "talloc.h"
39 #include "events.h"
40 #include "ldb.h"
41 #include "ldb_errors.h"
42 #include "ldb_private.h"
43
44 typedef struct ldb_message ldb_msg;
45 typedef struct ldb_context ldb;
46 typedef struct ldb_dn ldb_dn;
47 typedef struct ldb_ldif ldb_ldif;
48 typedef struct ldb_message_element ldb_message_element;
49 typedef struct ldb_module ldb_module;
50 typedef int ldb_error;
51 typedef int ldb_int_error;
52
53 %}
54
55 %import "carrays.i"
56 %import "typemaps.i"
57 %include "exception.i"
58 %import "stdint.i"
59
60 /* Don't expose talloc contexts in Python code. Python does reference 
61    counting for us, so just create a new top-level talloc context.
62  */
63 %typemap(in, numinputs=0, noblock=1) TALLOC_CTX * {
64     $1 = NULL;
65 }
66
67
68
69 %constant int SCOPE_DEFAULT = LDB_SCOPE_DEFAULT;
70 %constant int SCOPE_BASE = LDB_SCOPE_BASE;
71 %constant int SCOPE_ONELEVEL = LDB_SCOPE_ONELEVEL;
72 %constant int SCOPE_SUBTREE = LDB_SCOPE_SUBTREE;
73
74 %constant int CHANGETYPE_NONE = LDB_CHANGETYPE_NONE;
75 %constant int CHANGETYPE_ADD = LDB_CHANGETYPE_ADD;
76 %constant int CHANGETYPE_DELETE = LDB_CHANGETYPE_DELETE;
77 %constant int CHANGETYPE_MODIFY = LDB_CHANGETYPE_MODIFY;
78
79 /* 
80  * Wrap struct ldb_context
81  */
82
83 /* The ldb functions will crash if a NULL ldb context is passed so
84    catch this before it happens. */
85
86 %typemap(check,noblock=1) struct ldb_context* {
87         if ($1 == NULL)
88                 SWIG_exception(SWIG_ValueError, 
89                         "ldb context must be non-NULL");
90 }
91
92 %typemap(check,noblock=1) ldb_msg * {
93         if ($1 == NULL)
94                 SWIG_exception(SWIG_ValueError, 
95                         "Message can not be None");
96 }
97
98 /*
99  * Wrap struct ldb_val
100  */
101
102 %typemap(in,noblock=1) struct ldb_val *INPUT (struct ldb_val temp) {
103         $1 = &temp;
104         if (!PyString_Check($input)) {
105                 PyErr_SetString(PyExc_TypeError, "string arg expected");
106                 return NULL;
107         }
108         $1->length = PyString_Size($input);
109         $1->data = PyString_AsString($input);
110 }
111
112 %inline %{
113 PyObject *ldb_val_to_py_object(struct ldb_context *ldb_ctx, 
114                                struct ldb_message_element *el, 
115                                struct ldb_val *val)
116 {
117         const struct ldb_schema_attribute *a;
118         struct ldb_val new_val;
119         TALLOC_CTX *mem_ctx = talloc_new(NULL);
120         PyObject *ret;
121         
122         new_val = *val;
123         
124         if (ldb_ctx != NULL) {        
125                 a = ldb_schema_attribute_by_name(ldb_ctx, el->name);
126         
127                 if (a != NULL) {
128                         if (a->syntax->ldif_write_fn(ldb_ctx, mem_ctx, val, &new_val) != 0) {
129                                 talloc_free(mem_ctx);
130                                 return NULL;
131                         }
132                 }
133         } 
134         
135         ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
136         
137         talloc_free(mem_ctx);
138         
139         return ret;
140 }
141
142 %}
143
144 %typemap(out,noblock=1) struct ldb_val * {
145         $result = PyString_FromStringAndSize((const char *)$1->data, $1->length)
146 }
147
148 %typemap(out,noblock=1) struct ldb_val {
149         $result = PyString_FromStringAndSize((const char *)$1.data, $1.length)
150 }
151
152 /*
153  * Wrap struct ldb_result
154  */
155
156 %typemap(in,noblock=1,numinputs=0) struct ldb_result **OUT (struct ldb_result *temp_ldb_result) {
157         $1 = &temp_ldb_result;
158 }
159
160 #ifdef SWIGPYTHON
161 %typemap(argout,noblock=1) struct ldb_result ** (int i) {
162         $result = PyList_New((*$1)->count);
163     for (i = 0; i < (*$1)->count; i++) {
164         PyList_SetItem($result, i, 
165             SWIG_NewPointerObj((*$1)->msgs[i], SWIGTYPE_p_ldb_message, 0)
166         );
167     }
168 }
169
170 %typemap(in,noblock=1,numinputs=1) const char * const *NULL_STR_LIST {
171     if ($input == Py_None) {
172         $1 = NULL;
173     } else if (PySequence_Check($input)) {
174         int i;
175         $1 = talloc_array(NULL, char *, PySequence_Size($input)+1);
176         for(i = 0; i < PySequence_Size($input); i++)
177             $1[i] = PyString_AsString(PySequence_GetItem($input, i));
178         $1[i] = NULL;
179     } else {
180         SWIG_exception(SWIG_TypeError, "expected sequence");
181     }
182 }
183
184 %typemap(freearg,noblock=1) const char * const *NULL_STR_LIST {
185     talloc_free($1);
186 }
187
188 %apply const char * const *NULL_STR_LIST { const char * const *attrs }
189 %apply const char * const *NULL_STR_LIST { const char * const *control_strings }
190
191 #endif
192
193 %types(struct ldb_result *, struct ldb_parse_tree *);
194
195 /*
196  * Wrap struct ldb_dn
197  */
198
199 %rename(__str__) ldb_dn::get_linearized;
200 %rename(__cmp__) ldb_dn::compare;
201 %rename(__len__) ldb_dn::get_comp_num;
202 %rename(Dn) ldb_dn;
203 %feature("docstring") ldb_dn "A LDB distinguished name.";
204 typedef struct ldb_dn {
205     %extend {
206         %feature("docstring") ldb_dn "S.__init__(ldb, string)\n" \
207                  "Create a new DN.";
208         ldb_dn(ldb *ldb_ctx, const char *str)
209         {
210             ldb_dn *ret = ldb_dn_new(ldb_ctx, ldb_ctx, str);
211             /* ldb_dn_new() doesn't accept NULL as memory context, so 
212                we do it this way... */
213             talloc_steal(NULL, ret);
214
215             if (ret == NULL)
216                 SWIG_exception(SWIG_ValueError, 
217                                 "unable to parse dn string");
218 fail:
219             return ret;
220         }
221         ~ldb_dn() { talloc_free($self); }
222         %feature("docstring") validate "S.validate() -> bool\n" \
223                                        "Validate DN is correct.";
224         bool validate();
225         const char *get_casefold();
226         const char *get_linearized();
227         %feature("docstring") parent "S.parent() -> dn\n" \
228                                      "Get the parent for this DN.";
229         ldb_dn *parent() { return ldb_dn_get_parent(NULL, $self); }
230         int compare(ldb_dn *other);
231         bool is_valid();
232         %feature("docstring") is_special "S.is_special() -> bool\n" \
233                                          "Check whether this is a special LDB DN.";
234         bool is_special();
235         %feature("docstring") is_null "S.is_null() -> bool\n" \
236                                          "Check whether this is a null DN.";
237         bool is_null();
238         bool check_special(const char *name);
239         int get_comp_num();
240         %feature("docstring") add_child "S.add_child(dn) -> None\n" \
241                                          "Add a child DN to this DN.";
242         bool add_child(ldb_dn *child);
243         %feature("docstring") add_base "S.add_base(dn) -> None\n" \
244                                          "Add a base DN to this DN.";
245         bool add_base(ldb_dn *base);
246         %feature("docstring") canonical_str "S.canonical_str() -> string\n" \
247                                          "Canonical version of this DN (like a posix path).";
248         const char *canonical_str() {
249             return ldb_dn_canonical_string($self, $self);
250         }
251         %feature("docstring") canonical_ex_str "S.canonical_ex_str() -> string\n" \
252                                                "Canonical version of this DN (like a posix path, with terminating newline).";
253         const char *canonical_ex_str() {
254             return ldb_dn_canonical_ex_string($self, $self);
255         }
256 #ifdef SWIGPYTHON
257         char *__repr__(void)
258         {
259             char *dn = ldb_dn_get_linearized($self), *ret;
260             asprintf(&ret, "Dn('%s')", dn);
261             talloc_free(dn);
262             return ret;
263         }
264
265         ldb_dn *__add__(ldb_dn *other)
266         {
267             ldb_dn *ret = ldb_dn_copy(NULL, $self);
268             ldb_dn_add_child(ret, other);
269             return ret;
270         }
271
272         /* FIXME: implement __getslice__ */
273 #endif
274     %pythoncode {
275         def __eq__(self, other):
276             if isinstance(other, self.__class__):
277                 return self.__cmp__(other) == 0
278             if isinstance(other, str):
279                 return str(self) == other
280             return False
281     }
282     }
283 } ldb_dn;
284
285 #ifdef SWIGPYTHON
286 %{
287 struct ldb_context *ldb_context_from_py_object(PyObject *py_obj)
288 {
289         struct ldb_context *ldb_ctx;
290     if (SWIG_ConvertPtr(py_obj, (void *)&ldb_ctx, SWIGTYPE_p_ldb_context, 0 |  0 ) < 0)
291         return NULL;
292     return ldb_ctx;
293 }
294
295 int ldb_dn_from_pyobject(TALLOC_CTX *mem_ctx, PyObject *object, 
296                          struct ldb_context *ldb_ctx, ldb_dn **dn)
297 {
298     int ret;
299     struct ldb_dn *odn;
300     if (ldb_ctx != NULL && PyString_Check(object)) {
301         odn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object));
302         if (!odn) {
303                 return SWIG_ERROR;
304         }
305         *dn = odn;
306         return 0;
307     }
308     ret = SWIG_ConvertPtr(object, (void **)&odn, SWIGTYPE_p_ldb_dn, 
309                            SWIG_POINTER_EXCEPTION);
310     *dn = ldb_dn_copy(mem_ctx, odn);
311     if (odn && !*dn) {
312         return SWIG_ERROR;
313     }
314     return ret;
315 }
316
317 ldb_message_element *ldb_msg_element_from_pyobject(TALLOC_CTX *mem_ctx,
318                                                PyObject *set_obj, int flags,
319                                                const char *attr_name)
320 {
321     struct ldb_message_element *me = talloc(mem_ctx, struct ldb_message_element);
322     me->name = attr_name;
323     me->flags = flags;
324     if (PyString_Check(set_obj)) {
325         me->num_values = 1;
326         me->values = talloc_array(me, struct ldb_val, me->num_values);
327         me->values[0].length = PyString_Size(set_obj);
328         me->values[0].data = (uint8_t *)talloc_strdup(me->values, 
329                                            PyString_AsString(set_obj));
330     } else if (PySequence_Check(set_obj)) {
331         int i;
332         me->num_values = PySequence_Size(set_obj);
333         me->values = talloc_array(me, struct ldb_val, me->num_values);
334         for (i = 0; i < me->num_values; i++) {
335             PyObject *obj = PySequence_GetItem(set_obj, i);
336             me->values[i].length = PyString_Size(obj);
337             me->values[i].data = (uint8_t *)PyString_AsString(obj);
338         }
339     } else {
340         talloc_free(me);
341         me = NULL;
342     }
343
344     return me;
345 }
346
347 PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, 
348                                  ldb_message_element *me)
349 {
350     int i;
351     PyObject *result;
352
353     /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
354     result = PyList_New(me->num_values);
355
356     for (i = 0; i < me->num_values; i++) {
357         PyList_SetItem(result, i,
358             ldb_val_to_py_object(ldb_ctx, me, &me->values[i]));
359     }
360
361     return result;
362 }
363
364 %}
365 #endif
366
367 /* ldb_message_element */
368 %rename(MessageElement) ldb_message_element;
369 %feature("docstring") ldb_message_element "Message element.";
370 typedef struct ldb_message_element {
371     %extend {
372 #ifdef SWIGPYTHON
373         int __cmp__(ldb_message_element *other)
374         {
375             return ldb_msg_element_compare($self, other);
376         }
377
378         PyObject *__iter__(void)
379         {
380             return PyObject_GetIter(ldb_msg_element_to_set(NULL, $self));
381         }
382
383         PyObject *__set__(void)
384         {
385             return ldb_msg_element_to_set(NULL, $self);
386         }
387
388         ldb_message_element(PyObject *set_obj, int flags=0, const char *name = NULL)
389         {
390             return ldb_msg_element_from_pyobject(NULL, set_obj, flags, name);
391         }
392
393         int __len__()
394         {
395             return $self->num_values;
396         }
397 #endif
398
399         PyObject *get(int i)
400         {
401             if (i < 0 || i >= $self->num_values)
402                 return Py_None;
403
404             return ldb_val_to_py_object(NULL, $self, &$self->values[i]);
405         }
406
407         ~ldb_message_element() { talloc_free($self); }
408     }
409     %pythoncode {
410         def __getitem__(self, i):
411             ret = self.get(i)
412             if ret is None:
413                 raise KeyError("no such value")
414             return ret
415
416         def __repr__(self):
417             return "MessageElement([%s])" % (",".join(repr(x) for x in self.__set__()))
418
419         def __eq__(self, other):
420             if (len(self) == 1 and self.get(0) == other):
421                 return True
422             if isinstance(other, self.__class__):
423                 return self.__cmp__(other) == 0
424             o = iter(other)
425             for i in range(len(self)):
426                 if self.get(i) != o.next():
427                     return False
428             return True
429     }
430 } ldb_message_element;
431
432 /* ldb_message */
433
434 %feature("docstring") ldb_message "Message.";
435 %rename(Message) ldb_message;
436 #ifdef SWIGPYTHON
437 %rename(__delitem__) ldb_message::remove_attr;
438 %typemap(out) ldb_message_element * {
439         if ($1 == NULL)
440                 PyErr_SetString(PyExc_KeyError, "no such element");
441     else
442         $result = SWIG_NewPointerObj($1, SWIGTYPE_p_ldb_message_element, 0);
443 }
444
445 %inline {
446     PyObject *ldb_msg_list_elements(ldb_msg *msg)
447     {
448         int i, j = 0;
449         PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
450         if (msg->dn != NULL) {
451             PyList_SetItem(obj, j, PyString_FromString("dn"));
452             j++;
453         }
454         for (i = 0; i < msg->num_elements; i++) {
455             PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
456             j++;
457         }
458         return obj;
459     }
460 }
461
462 #endif
463
464 typedef struct ldb_message {
465         ldb_dn *dn;
466
467     %extend {
468         ldb_msg(ldb_dn *dn = NULL) { 
469             ldb_msg *ret = ldb_msg_new(NULL); 
470             ret->dn = talloc_reference(ret, dn);
471             return ret;
472         }
473         ~ldb_msg() { talloc_free($self); }
474         ldb_message_element *find_element(const char *name);
475         
476 #ifdef SWIGPYTHON
477         void __setitem__(const char *attr_name, ldb_message_element *val)
478         {
479             struct ldb_message_element *el;
480             
481             ldb_msg_remove_attr($self, attr_name);
482
483             el = talloc($self, struct ldb_message_element);
484             el->name = talloc_strdup(el, attr_name);
485             el->num_values = val->num_values;
486             el->values = talloc_reference(el, val->values);
487
488             ldb_msg_add($self, el, val->flags);
489         }
490
491         void __setitem__(const char *attr_name, PyObject *val)
492         {
493             struct ldb_message_element *el = ldb_msg_element_from_pyobject(NULL,
494                                                 val, 0, attr_name);
495             talloc_steal($self, el);
496             ldb_msg_remove_attr($self, attr_name);
497             ldb_msg_add($self, el, el->flags);
498         }
499
500         unsigned int __len__() { return $self->num_elements; }
501
502         PyObject *keys(void)
503         {
504             return ldb_msg_list_elements($self);
505         }
506
507         PyObject *__iter__(void)
508         {
509             return PyObject_GetIter(ldb_msg_list_elements($self));
510         }
511 #endif
512         void remove_attr(const char *name);
513 %pythoncode {
514     def get(self, key, default=None):
515         if key == "dn":
516             return self.dn
517         return self.find_element(key)
518
519     def __getitem__(self, key):
520         ret = self.get(key, None)
521         if ret is None:
522             raise KeyError("No such element")
523         return ret
524
525     def iteritems(self):
526         for k in self.keys():
527             yield k, self[k]
528     
529     def items(self):
530         return list(self.iteritems())
531
532     def __repr__(self):
533         return "Message(%s)" % repr(dict(self.iteritems()))
534 }
535     }
536 } ldb_msg;
537
538 /* FIXME: Convert ldb_result to 3-tuple:
539    (msgs, refs, controls)
540  */
541
542 typedef struct ldb_ldif ldb_ldif;
543
544 #ifdef SWIGPYTHON
545 %{
546 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
547
548 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
549 {
550     char *text;
551     PyObject *fn = context;
552
553     vasprintf(&text, fmt, ap);
554     PyObject_CallFunction(fn, (char *)"(i,s)", level, text);
555     free(text);
556 }
557 %}
558
559 %typemap(in,numinputs=1,noblock=1) (void (*debug)(void *context, enum ldb_debug_level level, const char *fmt, va_list ap), void *context) {
560     $1 = py_ldb_debug;
561     /* FIXME: Should be decreased somewhere as well. Perhaps register a 
562        destructor and tie it to the ldb context ? */
563     Py_INCREF($input);
564     $2 = $input;
565 }
566 #endif
567
568 %inline {
569     static PyObject *ldb_ldif_to_pyobject(ldb_ldif *ldif)
570     {
571         if (ldif == NULL) {
572             return Py_None;
573         } else {
574             return Py_BuildValue((char *)"(iO)", ldif->changetype, 
575                    SWIG_NewPointerObj(ldif->msg, SWIGTYPE_p_ldb_message, 0));
576         }
577     }
578 }
579
580 /*
581  * Wrap ldb errors
582  */
583
584 %{
585 PyObject *PyExc_LdbError;
586 %}
587
588 %pythoncode %{
589     LdbError = _ldb.LdbError
590 %}
591
592 %init %{
593     PyExc_LdbError = PyErr_NewException((char *)"_ldb.LdbError", NULL, NULL);
594     PyDict_SetItemString(d, "LdbError", PyExc_LdbError);
595 %}
596
597 %ignore _LDB_ERRORS_H_;
598 %ignore LDB_SUCCESS;
599 %include "include/ldb_errors.h"
600
601 /*
602  * Wrap ldb functions 
603  */
604
605
606 %typemap(out,noblock=1) ldb_error {
607     if ($1 != LDB_SUCCESS) {
608         PyErr_SetObject(PyExc_LdbError, Py_BuildValue((char *)"(i,s)", $1, ldb_errstring(arg1)));
609         SWIG_fail;
610     }
611     $result = Py_None;
612 };
613
614 %typemap(out,noblock=1) ldb_int_error {
615     if ($1 != LDB_SUCCESS) {
616         PyErr_SetObject(PyExc_LdbError, Py_BuildValue((char *)"(i,s)", $1, ldb_strerror($1)));
617         SWIG_fail;
618     }
619     $result = Py_None;
620 };
621
622 %typemap(out,noblock=1) struct ldb_control ** {
623     if ($1 == NULL) {
624         PyErr_SetObject(PyExc_LdbError, Py_BuildValue((char *)"(s)", ldb_errstring(arg1)));
625         SWIG_fail;
626     }
627     $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
628 }
629
630 %rename(Ldb) ldb_context;
631 %feature("docstring") ldb_context "Connection to a LDB database.";
632
633 %typemap(in,noblock=1) struct ldb_dn * {
634     if (ldb_dn_from_pyobject(NULL, $input, arg1, &$1) != 0) {
635         SWIG_fail;
636     }
637 };
638
639 %typemap(freearg,noblock=1) struct ldb_dn * {
640     talloc_free($1);
641 };
642
643 %typemap(in,numinputs=1) ldb_msg *add_msg {
644     Py_ssize_t dict_pos, msg_pos;
645     ldb_message_element *msgel;
646     PyObject *key, *value;
647
648     if (PyDict_Check($input)) {
649         PyObject *dn_value = PyDict_GetItemString($input, "dn");
650         $1 = ldb_msg_new(NULL);
651         $1->elements = talloc_zero_array($1, struct ldb_message_element, PyDict_Size($input));
652         msg_pos = dict_pos = 0;
653         if (dn_value) {
654                 /* using argp1 (magic SWIG value) here is a hack */
655                 if (ldb_dn_from_pyobject($1, dn_value, argp1, &$1->dn) != 0) {
656                     SWIG_exception(SWIG_TypeError, "unable to import dn object");
657                 }
658                 if ($1->dn == NULL) {
659                     SWIG_exception(SWIG_TypeError, "dn set but not found");
660                 }
661         }
662
663         while (PyDict_Next($input, &dict_pos, &key, &value)) {
664             char *key_str = PyString_AsString(key);
665             if (strcmp(key_str, "dn") != 0) {
666                 msgel = ldb_msg_element_from_pyobject($1->elements, value, 0, key_str);
667                 if (msgel == NULL) {
668                     SWIG_exception(SWIG_TypeError, "unable to import element");
669                 }
670                 memcpy(&$1->elements[msg_pos], msgel, sizeof(*msgel));
671                 msg_pos++;
672             }
673         }
674
675         if ($1->dn == NULL) {
676             SWIG_exception(SWIG_TypeError, "no dn set");
677         }
678
679         $1->num_elements = msg_pos;
680     } else {
681         if (SWIG_ConvertPtr($input, (void **)&$1, SWIGTYPE_p_ldb_message, 0) != 0) {
682             SWIG_exception(SWIG_TypeError, "unable to convert ldb message");
683         }
684     }
685 }
686
687 /* Top-level ldb operations */
688 typedef struct ldb_context {
689     %rename(firstmodule) modules;
690     struct ldb_module *modules;
691
692     %pythoncode {
693         def itermodules(self):
694             m = self.firstmodule
695             while m is not None:
696                 yield m
697                 m = m.next
698
699         def modules(self):
700             return list(self.itermodules())
701     }
702
703     %extend {
704         ldb(void) { 
705             return ldb_init(NULL, event_context_init(NULL)); 
706         }
707
708         %feature("docstring") connect "S.connect(url,flags=0,options=None) -> None\n" \
709                                       "Connect to a LDB URL.";
710         ldb_error connect(const char *url, unsigned int flags = 0, 
711             const char *options[] = NULL);
712
713         ~ldb() { talloc_free($self); }
714         ldb_error search_ex(TALLOC_CTX *mem_ctx,
715                    ldb_dn *base = NULL, 
716                    enum ldb_scope scope = LDB_SCOPE_DEFAULT, 
717                    const char *expression = NULL, 
718                    const char *const *attrs = NULL, 
719                    struct ldb_control **controls = NULL,
720                    struct ldb_result **OUT) {
721             int ret;
722             struct ldb_result *res;
723             struct ldb_request *req;
724             res = talloc_zero(mem_ctx, struct ldb_result);
725             if (!res) {
726                 return LDB_ERR_OPERATIONS_ERROR;
727             }
728
729             ret = ldb_build_search_req(&req, $self, mem_ctx,
730                            base?base:ldb_get_default_basedn($self),
731                            scope,
732                            expression,
733                            attrs,
734                            controls,
735                            res,
736                            ldb_search_default_callback);
737
738             if (ret != LDB_SUCCESS) {
739                 talloc_free(res);
740                 return ret;
741             }
742
743             ldb_set_timeout($self, req, 0); /* use default timeout */
744                 
745             ret = ldb_request($self, req);
746                 
747             if (ret == LDB_SUCCESS) {
748                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
749             }
750
751             talloc_free(req);
752
753             *OUT = res;
754             return ret;
755         }
756
757         %feature("docstring") delete "S.delete(dn) -> None\n" \
758                                      "Remove an entry.";
759         ldb_error delete(ldb_dn *dn);
760         %feature("docstring") rename "S.rename(old_dn, new_dn) -> None\n" \
761                                      "Rename an entry.";
762         ldb_error rename(ldb_dn *olddn, ldb_dn *newdn);
763         struct ldb_control **parse_control_strings(TALLOC_CTX *mem_ctx, 
764                                                    const char * const*control_strings);
765         %feature("docstring") add "S.add(message) -> None\n" \
766                                   "Add an entry.";
767         ldb_error add(ldb_msg *add_msg);
768         %feature("docstring") modify "S.modify(message) -> None\n" \
769                                   "Modify an entry.";
770         ldb_error modify(ldb_msg *message);
771         ldb_dn *get_config_basedn();
772         ldb_dn *get_root_basedn();
773         ldb_dn *get_schema_basedn();
774         ldb_dn *get_default_basedn();
775         PyObject *schema_format_value(const char *element_name, PyObject *val)
776         {
777                 const struct ldb_schema_attribute *a;
778                 struct ldb_val old_val;
779                 struct ldb_val new_val;
780                 TALLOC_CTX *mem_ctx = talloc_new(NULL);
781                 PyObject *ret;
782                 
783                 old_val.data = PyString_AsString(val);
784                 old_val.length = PyString_Size(val);
785                 
786                 a = ldb_schema_attribute_by_name($self, element_name);
787         
788                 if (a == NULL) {
789                         return Py_None;
790                 }
791                 
792                 if (a->syntax->ldif_write_fn($self, mem_ctx, &old_val, &new_val) != 0) {
793                         talloc_free(mem_ctx);
794                         return Py_None;
795                  }
796         
797                 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
798                 
799                 talloc_free(mem_ctx);
800                 
801                 return ret;
802         }
803
804         const char *errstring();
805         %feature("docstring") set_create_perms "S.set_create_perms(mode) -> None\n" \
806                                                "Set mode to use when creating new LDB files.";
807         void set_create_perms(unsigned int perms);
808         %feature("docstring") set_modules_dir "S.set_modules_dir(path) -> None\n" \
809                                               "Set path LDB should search for modules";
810         void set_modules_dir(const char *path);
811         %feature("docstring") set_debug "S.set_debug(callback) -> None\n" \
812                                         "Set callback for LDB debug messages.\n" \
813                                         "The callback should accept a debug level and debug text.";
814         ldb_error set_debug(void (*debug)(void *context, enum ldb_debug_level level, 
815                                           const char *fmt, va_list ap),
816                             void *context);
817         %feature("docstring") set_opaque "S.set_opaque(name, value) -> None\n" \
818             "Set an opaque value on this LDB connection. \n"
819             ":note: Passing incorrect values may cause crashes.";
820         ldb_error set_opaque(const char *name, void *value);
821         %feature("docstring") get_opaque "S.get_opaque(name) -> value\n" \
822             "Get an opaque value set on this LDB connection. \n"
823             ":note: The returned value may not be useful in Python.";
824         void *get_opaque(const char *name);
825         %feature("docstring") transaction_start "S.transaction_start() -> None\n" \
826                                                 "Start a new transaction.";
827         ldb_error transaction_start();
828         %feature("docstring") transaction_commit "S.transaction_commit() -> None\n" \
829                                                  "Commit currently active transaction.";
830         ldb_error transaction_commit();
831         %feature("docstring") transaction_cancel "S.transaction_cancel() -> None\n" \
832                                                  "Cancel currently active transaction.";
833         ldb_error transaction_cancel();
834         void schema_attribute_remove(const char *name);
835         ldb_error schema_attribute_add(const char *attribute, unsigned flags, const char *syntax);
836         ldb_error setup_wellknown_attributes(void);
837  
838 #ifdef SWIGPYTHON
839         %typemap(in,numinputs=0,noblock=1) struct ldb_result **result_as_bool (struct ldb_result *tmp) { $1 = &tmp; }
840         %typemap(argout,noblock=1) struct ldb_result **result_as_bool { $result = ((*$1)->count > 0)?Py_True:Py_False; }
841         %typemap(freearg,noblock=1) struct ldb_result **result_as_bool { talloc_free(*$1); }
842         ldb_error __contains__(ldb_dn *dn, struct ldb_result **result_as_bool)
843         {
844             return ldb_search($self, dn, LDB_SCOPE_BASE, NULL, NULL, 
845                              result_as_bool);
846         }
847
848         %feature("docstring") parse_ldif "S.parse_ldif(ldif) -> iter(messages)\n" \
849             "Parse a string formatted using LDIF.";
850
851         PyObject *parse_ldif(const char *s)
852         {
853             PyObject *list = PyList_New(0);
854             struct ldb_ldif *ldif;
855             while ((ldif = ldb_ldif_read_string($self, &s)) != NULL) {
856                 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
857             }
858             return PyObject_GetIter(list);
859         }
860
861         char *__repr__(void)
862         {
863             char *ret;
864             asprintf(&ret, "<ldb connection at 0x%x>", ret); 
865             return ret;
866         }
867 #endif
868     }
869     %pythoncode {
870         def __init__(self, url=None, flags=0, options=None):
871             """Create a new LDB object.
872
873             Will also connect to the specified URL if one was given.
874             """
875             _ldb.Ldb_swiginit(self,_ldb.new_Ldb())
876             if url is not None:
877                 self.connect(url, flags, options)
878
879         def search(self, base=None, scope=SCOPE_DEFAULT, expression=None, 
880                    attrs=None, controls=None):
881             """Search in a database.
882
883             :param base: Optional base DN to search
884             :param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)
885             :param expression: Optional search expression
886             :param attrs: Attributes to return (defaults to all)
887             :param controls: Optional list of controls
888             :return: Iterator over Message objects
889             """
890             if not (attrs is None or isinstance(attrs, list)):
891                 raise TypeError("attributes not a list")
892             parsed_controls = None
893             if controls is not None:
894                 parsed_controls = self.parse_control_strings(controls)
895             return self.search_ex(base, scope, expression, attrs, 
896                                   parsed_controls)
897     }
898
899 } ldb;
900
901 %typemap(in,noblock=1) struct ldb_dn *;
902 %typemap(freearg,noblock=1) struct ldb_dn *;
903
904 %nodefault ldb_message;
905 %nodefault ldb_context;
906 %nodefault Dn;
907
908 %rename(valid_attr_name) ldb_valid_attr_name;
909 %feature("docstring") ldb_valid_attr_name "S.valid_attr_name(name) -> bool\n"
910                                           "Check whether the supplied name is a valid attribute name.";
911 int ldb_valid_attr_name(const char *s);
912
913 typedef unsigned long time_t;
914
915 %feature("docstring") timestring "S.timestring(int) -> string\n"
916                                  "Generate a LDAP time string from a UNIX timestamp";
917
918 %inline %{
919 static char *timestring(time_t t)
920 {
921     char *tresult = ldb_timestring(NULL, t);
922     char *result = strdup(tresult);
923     talloc_free(tresult);
924     return result; 
925 }
926 %}
927
928 %rename(string_to_time) ldb_string_to_time;
929 %feature("docstring") ldb_string_to_time "S.string_to_time(string) -> int\n"
930                                      "Parse a LDAP time string into a UNIX timestamp.";
931 time_t ldb_string_to_time(const char *s);
932
933 typedef struct ldb_module {
934     struct ldb_module *prev, *next;
935
936     %extend {
937 #ifdef SWIGPYTHON
938         const char *__str__() {
939             return $self->ops->name;
940         }
941         char *__repr__() {
942             char *ret;
943             asprintf(&ret, "<ldb module '%s'>", $self->ops->name);
944             return ret;
945         }
946 #endif
947         int search(struct ldb_request *req) {
948             return $self->ops->search($self, req);
949         }
950         ldb_error add(struct ldb_request *req) {
951             return $self->ops->add($self, req);
952         }
953         ldb_error modify(struct ldb_request *req) {
954             return $self->ops->modify($self, req);
955         }
956         ldb_error delete(struct ldb_request *req) {
957             return $self->ops->del($self, req);
958         }
959         ldb_error rename(struct ldb_request *req) {
960             return $self->ops->rename($self, req);
961         }
962         ldb_error start_transaction() {
963             return $self->ops->start_transaction($self);
964         }
965         ldb_error end_transaction() {
966             return $self->ops->end_transaction($self);
967         }
968         ldb_error del_transaction() {
969             return $self->ops->del_transaction($self);
970         }
971     }
972 } ldb_module;
973
974 %{
975 int py_module_search(struct ldb_module *mod, struct ldb_request *req)
976 {
977     PyObject *py_ldb = mod->private_data;
978     PyObject *py_result, *py_base, *py_attrs, *py_tree;
979
980     py_base = SWIG_NewPointerObj(req->op.search.base, SWIGTYPE_p_ldb_dn, 0);
981
982     if (py_base == NULL)
983         return LDB_ERR_OPERATIONS_ERROR;
984
985     py_tree = SWIG_NewPointerObj(req->op.search.tree, SWIGTYPE_p_ldb_parse_tree, 0);
986
987     if (py_tree == NULL)
988         return LDB_ERR_OPERATIONS_ERROR;
989
990     if (req->op.search.attrs == NULL) {
991         py_attrs = Py_None;
992     } else {
993         int i, len;
994         for (len = 0; req->op.search.attrs[len]; len++);
995         py_attrs = PyList_New(len);
996         for (i = 0; i < len; i++)
997             PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
998     }
999
1000     py_result = PyObject_CallMethod(py_ldb, "search", "OiOO", py_base, req->op.search.scope, py_tree, py_attrs);
1001
1002     Py_DECREF(py_attrs);
1003     Py_DECREF(py_tree);
1004     Py_DECREF(py_base);
1005
1006     if (py_result == NULL) {
1007         return LDB_ERR_OPERATIONS_ERROR;
1008     }
1009
1010     if (SWIG_ConvertPtr(py_result, &req->op.search.res, SWIGTYPE_p_ldb_result, 0) != 0) {
1011         return LDB_ERR_OPERATIONS_ERROR;
1012     }
1013
1014     Py_DECREF(py_result);
1015
1016     return LDB_SUCCESS;
1017 }
1018
1019 int py_module_add(struct ldb_module *mod, struct ldb_request *req)
1020 {
1021     PyObject *py_ldb = mod->private_data;
1022     PyObject *py_result, *py_msg;
1023
1024     py_msg = SWIG_NewPointerObj(req->op.add.message, SWIGTYPE_p_ldb_message, 0);
1025
1026     if (py_msg == NULL) {
1027         return LDB_ERR_OPERATIONS_ERROR;
1028     }
1029
1030     py_result = PyObject_CallMethod(py_ldb, "add", "O", py_msg);
1031
1032     Py_DECREF(py_msg);
1033
1034     if (py_result == NULL) {
1035         return LDB_ERR_OPERATIONS_ERROR;
1036     }
1037
1038     Py_DECREF(py_result);
1039
1040     return LDB_SUCCESS;
1041 }
1042
1043 int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
1044 {
1045     PyObject *py_ldb = mod->private_data;
1046     PyObject *py_result, *py_msg;
1047
1048     py_msg = SWIG_NewPointerObj(req->op.mod.message, SWIGTYPE_p_ldb_message, 0);
1049
1050     if (py_msg == NULL) {
1051         return LDB_ERR_OPERATIONS_ERROR;
1052     }
1053
1054     py_result = PyObject_CallMethod(py_ldb, "modify", "O", py_msg);
1055
1056     Py_DECREF(py_msg);
1057
1058     if (py_result == NULL) {
1059         return LDB_ERR_OPERATIONS_ERROR;
1060     }
1061
1062     Py_DECREF(py_result);
1063
1064     return LDB_SUCCESS;
1065 }
1066
1067 int py_module_del(struct ldb_module *mod, struct ldb_request *req)
1068 {
1069     PyObject *py_ldb = mod->private_data;
1070     PyObject *py_result, *py_dn;
1071
1072     py_dn = SWIG_NewPointerObj(req->op.del.dn, SWIGTYPE_p_ldb_dn, 0);
1073
1074     if (py_dn == NULL)
1075         return LDB_ERR_OPERATIONS_ERROR;
1076
1077     py_result = PyObject_CallMethod(py_ldb, "delete", "O", py_dn);
1078
1079     if (py_result == NULL) {
1080         return LDB_ERR_OPERATIONS_ERROR;
1081     }
1082
1083     Py_DECREF(py_result);
1084
1085     return LDB_SUCCESS;
1086 }
1087
1088 int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
1089 {
1090     PyObject *py_ldb = mod->private_data;
1091     PyObject *py_result, *py_olddn, *py_newdn;
1092
1093     py_olddn = SWIG_NewPointerObj(req->op.rename.olddn, SWIGTYPE_p_ldb_dn, 0);
1094
1095     if (py_olddn == NULL)
1096         return LDB_ERR_OPERATIONS_ERROR;
1097
1098     py_newdn = SWIG_NewPointerObj(req->op.rename.newdn, SWIGTYPE_p_ldb_dn, 0);
1099
1100     if (py_newdn == NULL)
1101         return LDB_ERR_OPERATIONS_ERROR;
1102
1103     py_result = PyObject_CallMethod(py_ldb, "rename", "OO", py_olddn, py_newdn);
1104
1105     Py_DECREF(py_olddn);
1106     Py_DECREF(py_newdn);
1107
1108     if (py_result == NULL) {
1109         return LDB_ERR_OPERATIONS_ERROR;
1110     }
1111
1112     Py_DECREF(py_result);
1113
1114     return LDB_SUCCESS;
1115 }
1116
1117 int py_module_request(struct ldb_module *mod, struct ldb_request *req)
1118 {
1119     PyObject *py_ldb = mod->private_data;
1120     PyObject *py_result;
1121
1122     py_result = PyObject_CallMethod(py_ldb, "request", "");
1123
1124     return LDB_ERR_OPERATIONS_ERROR;
1125 }
1126
1127 int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
1128 {
1129     PyObject *py_ldb = mod->private_data;
1130     PyObject *py_result;
1131
1132     py_result = PyObject_CallMethod(py_ldb, "extended", "");
1133
1134     return LDB_ERR_OPERATIONS_ERROR;
1135 }
1136
1137 int py_module_start_transaction(struct ldb_module *mod)
1138 {
1139     PyObject *py_ldb = mod->private_data;
1140     PyObject *py_result;
1141
1142     py_result = PyObject_CallMethod(py_ldb, "start_transaction", "");
1143
1144     if (py_result == NULL) {
1145         return LDB_ERR_OPERATIONS_ERROR;
1146     }
1147
1148     Py_DECREF(py_result);
1149
1150     return LDB_SUCCESS;
1151 }
1152
1153 int py_module_end_transaction(struct ldb_module *mod)
1154 {
1155     PyObject *py_ldb = mod->private_data;
1156     PyObject *py_result;
1157
1158     py_result = PyObject_CallMethod(py_ldb, "end_transaction", "");
1159
1160     if (py_result == NULL) {
1161         return LDB_ERR_OPERATIONS_ERROR;
1162     }
1163
1164     Py_DECREF(py_result);
1165
1166     return LDB_SUCCESS;
1167 }
1168
1169 int py_module_del_transaction(struct ldb_module *mod)
1170 {
1171     PyObject *py_ldb = mod->private_data;
1172     PyObject *py_result;
1173
1174     py_result = PyObject_CallMethod(py_ldb, "del_transaction", "");
1175
1176     if (py_result == NULL) {
1177         return LDB_ERR_OPERATIONS_ERROR;
1178     }
1179
1180     Py_DECREF(py_result);
1181
1182     return LDB_SUCCESS;
1183 }
1184
1185 int py_module_wait(struct ldb_handle *mod, enum ldb_wait_type wait_type)
1186 {
1187     PyObject *py_ldb = mod->private_data;
1188     PyObject *py_result;
1189
1190     py_result = PyObject_CallMethod(py_ldb, "wait", "i", wait_type);
1191
1192     if (py_result == NULL) {
1193         return LDB_ERR_OPERATIONS_ERROR;
1194     }
1195
1196     Py_DECREF(py_result);
1197
1198     return LDB_SUCCESS;
1199 }
1200
1201 int py_module_sequence_number(struct ldb_module *mod, struct ldb_request *req)
1202 {
1203     PyObject *py_ldb = mod->private_data;
1204     PyObject *py_result;
1205     int ret;
1206
1207     py_result = PyObject_CallMethod(py_ldb, "sequence_number", "ili", req->op.seq_num.type, req->op.seq_num.seq_num, req->op.seq_num.flags);
1208
1209     if (py_result == NULL) {
1210         return LDB_ERR_OPERATIONS_ERROR;
1211     }
1212
1213     ret = PyInt_AsLong(py_result);
1214
1215     Py_DECREF(py_result);
1216
1217     return ret;
1218 }
1219
1220 static int py_module_destructor(void *_mod)
1221 {
1222     struct ldb_module *mod = _mod;
1223     Py_DECREF((PyObject *)mod->private_data);
1224     return 0;
1225 }
1226
1227 int py_module_init (struct ldb_module *mod)
1228 {
1229     PyObject *py_class = mod->ops->private_data;
1230     PyObject *py_result, *py_next, *py_ldb;
1231
1232     py_ldb = SWIG_NewPointerObj(mod->ldb, SWIGTYPE_p_ldb_context, 0);
1233
1234     if (py_ldb == NULL)
1235         return LDB_ERR_OPERATIONS_ERROR;
1236
1237     py_next = SWIG_NewPointerObj(mod->next, SWIGTYPE_p_ldb_module, 0);
1238
1239     if (py_next == NULL)
1240         return LDB_ERR_OPERATIONS_ERROR;
1241
1242     py_result = PyObject_CallFunction(py_class, "OO", py_ldb, py_next);
1243
1244     if (py_result == NULL) {
1245         return LDB_ERR_OPERATIONS_ERROR;
1246     }
1247
1248     mod->private_data = py_result;
1249
1250     talloc_set_destructor (mod, py_module_destructor);
1251
1252     return ldb_next_init(mod);
1253 }
1254 %}
1255
1256 %typemap(in,noblock=1) const struct ldb_module_ops * {
1257     $1 = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
1258
1259     $1->name = talloc_strdup($1, PyString_AsString(PyObject_GetAttrString($input, (char *)"name")));
1260
1261     Py_INCREF($input);
1262     $1->private_data = $input;
1263     $1->init_context = py_module_init;
1264     $1->search = py_module_search;
1265     $1->add = py_module_add;
1266     $1->modify = py_module_modify;
1267     $1->del = py_module_del;
1268     $1->rename = py_module_rename;
1269     $1->request = py_module_request;
1270     $1->extended = py_module_extended;
1271     $1->start_transaction = py_module_start_transaction;
1272     $1->end_transaction = py_module_end_transaction;
1273     $1->del_transaction = py_module_del_transaction;
1274     $1->wait = py_module_wait;
1275     $1->sequence_number = py_module_sequence_number;
1276 }
1277
1278 %feature("docstring") ldb_register_module "S.register_module(module) -> None\n"
1279                                           "Register a LDB module.";
1280 %rename(register_module) ldb_register_module;
1281 ldb_int_error ldb_register_module(const struct ldb_module_ops *);
1282
1283 %pythoncode {
1284 __docformat__ = "restructuredText"
1285 open = Ldb
1286 }