Fix some nonempty blank lines
[kai/samba.git] / source4 / lib / ldb / pyldb.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Python 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-2009 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 #include "replace.h"
29 #include "ldb_private.h"
30 #include <Python.h>
31 #include "pyldb.h"
32
33 /* There's no Py_ssize_t in 2.4, apparently */
34 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
35 typedef int Py_ssize_t;
36 typedef inquiry lenfunc;
37 typedef intargfunc ssizeargfunc;
38 #endif
39
40 #ifndef Py_RETURN_NONE
41 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
42 #endif
43
44 static PyObject *PyExc_LdbError;
45
46 PyAPI_DATA(PyTypeObject) PyLdbMessage;
47 PyAPI_DATA(PyTypeObject) PyLdbModule;
48 PyAPI_DATA(PyTypeObject) PyLdbDn;
49 PyAPI_DATA(PyTypeObject) PyLdb;
50 PyAPI_DATA(PyTypeObject) PyLdbMessageElement;
51 PyAPI_DATA(PyTypeObject) PyLdbTree;
52
53 static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx, 
54                                                            struct ldb_message_element *el, 
55                                                            struct ldb_val *val)
56 {
57         struct ldb_val new_val;
58         TALLOC_CTX *mem_ctx = talloc_new(NULL);
59         PyObject *ret;
60
61         new_val = *val;
62
63         ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
64
65         talloc_free(mem_ctx);
66
67         return ret;
68 }
69
70 /**
71  * Obtain a ldb DN from a Python object.
72  *
73  * @param mem_ctx Memory context
74  * @param object Python object
75  * @param ldb_ctx LDB context
76  * @return Whether or not the conversion succeeded
77  */
78 bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, 
79                    struct ldb_context *ldb_ctx, struct ldb_dn **dn)
80 {
81         struct ldb_dn *odn;
82
83         if (ldb_ctx != NULL && PyString_Check(object)) {
84                 odn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object));
85                 *dn = odn;
86                 return true;
87         }
88
89         if (PyLdbDn_Check(object)) {
90                 *dn = PyLdbDn_AsDn(object);
91                 return true;
92         }
93
94         PyErr_SetString(PyExc_TypeError, "Expected DN");
95         return false;
96 }
97
98 /**
99  * Create a Python object from a ldb_result.
100  *
101  * @param result LDB result to convert
102  * @return Python object with converted result (a list object)
103  */
104 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
105 {
106         PyObject *ret;
107         int i;
108         if (result == NULL) {
109                 Py_RETURN_NONE;
110         } 
111         ret = PyList_New(result->count);
112         for (i = 0; i < result->count; i++) {
113                 PyList_SetItem(ret, i, PyLdbMessage_FromMessage(result->msgs[i])
114                 );
115         }
116         return ret;
117 }
118
119 /**
120  * Create a LDB Result from a Python object. 
121  * If conversion fails, NULL will be returned and a Python exception set.
122  *
123  * @param mem_ctx Memory context in which to allocate the LDB Result
124  * @param obj Python object to convert
125  * @return a ldb_result, or NULL if the conversion failed
126  */
127 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, 
128                                                                                            PyObject *obj)
129 {
130         struct ldb_result *res;
131         int i;
132
133         if (obj == Py_None)
134                 return NULL;
135
136         res = talloc_zero(mem_ctx, struct ldb_result);
137         res->count = PyList_Size(obj);
138         res->msgs = talloc_array(res, struct ldb_message *, res->count);
139         for (i = 0; i < res->count; i++) {
140                 PyObject *item = PyList_GetItem(obj, i);
141                 res->msgs[i] = PyLdbMessage_AsMessage(item);
142         }
143         return res;
144 }
145
146 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
147 {
148         return PyBool_FromLong(ldb_dn_validate(self->dn));
149 }
150
151 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
152 {
153         return PyBool_FromLong(ldb_dn_is_valid(self->dn));
154 }
155
156 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
157 {
158         return PyBool_FromLong(ldb_dn_is_special(self->dn));
159 }
160
161 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
162 {
163         return PyBool_FromLong(ldb_dn_is_null(self->dn));
164 }
165  
166 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
167 {
168         return PyString_FromString(ldb_dn_get_casefold(self->dn));
169 }
170
171 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
172 {
173         return PyString_FromString(ldb_dn_get_linearized(self->dn));
174 }
175
176 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
177 {
178         return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
179 }
180
181 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
182 {
183         return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
184 }
185
186 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
187 {
188         return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
189 }
190
191 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
192 {
193         char *name;
194
195         if (!PyArg_ParseTuple(args, "s", &name))
196                 return NULL;
197
198         return ldb_dn_check_special(self->dn, name)?Py_True:Py_False;
199 }
200
201 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
202 {
203         return ldb_dn_compare(dn1->dn, dn2->dn);
204 }
205
206 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
207 {
208         struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self);
209         return PyLdbDn_FromDn(ldb_dn_get_parent(NULL, dn));
210 }
211
212 #define dn_ldb_ctx(dn) ((struct ldb_context *)dn)
213
214 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
215 {
216         PyObject *py_other;
217         struct ldb_dn *dn, *other;
218         if (!PyArg_ParseTuple(args, "O", &py_other))
219                 return NULL;
220
221         dn = PyLdbDn_AsDn((PyObject *)self);
222
223         if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
224                 return NULL;
225
226         return ldb_dn_add_child(dn, other)?Py_True:Py_False;
227 }
228
229 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
230 {
231         PyObject *py_other;
232         struct ldb_dn *other, *dn;
233         if (!PyArg_ParseTuple(args, "O", &py_other))
234                 return NULL;
235
236         dn = PyLdbDn_AsDn((PyObject *)self);
237
238         if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
239                 return NULL;
240
241         return ldb_dn_add_base(dn, other)?Py_True:Py_False;
242 }
243
244 static PyMethodDef py_ldb_dn_methods[] = {
245         { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS, 
246                 "S.validate() -> bool\n"
247                 "Validate DN is correct." },
248         { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
249                 "S.is_valid() -> bool\n" },
250         { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
251                 "S.is_special() -> bool\n"
252                 "Check whether this is a special LDB DN." },
253         { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
254                 "Check whether this is a null DN." },
255         { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
256                 NULL },
257         { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
258                 NULL },
259         { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
260                 "S.canonical_str() -> string\n"
261                 "Canonical version of this DN (like a posix path)." },
262         { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
263                 "S.canonical_ex_str() -> string\n"
264                 "Canonical version of this DN (like a posix path, with terminating newline)." },
265         { "check_special", (PyCFunction)py_ldb_dn_is_special, METH_VARARGS, 
266                 NULL },
267         { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
268                 "S.parent() -> dn\n"
269                 "Get the parent for this DN." },
270         { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS, 
271                 "S.add_child(dn) -> None\n"
272                 "Add a child DN to this DN." },
273         { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
274                 "S.add_base(dn) -> None\n"
275                 "Add a base DN to this DN." },
276         { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
277                 NULL },
278         { NULL }
279 };
280
281 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
282 {
283         return ldb_dn_get_comp_num(PyLdbDn_AsDn((PyObject *)self));
284 }
285
286 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
287 {
288         struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self), 
289                                   *other;
290         struct ldb_dn *ret = ldb_dn_copy(NULL, dn);
291         if (!PyObject_AsDn(NULL, py_other, NULL, &other))
292                 return NULL;
293         ldb_dn_add_child(ret, other);
294         return PyLdbDn_FromDn(ret);
295 }
296
297 static PySequenceMethods py_ldb_dn_seq = {
298         .sq_length = (lenfunc)py_ldb_dn_len,
299         .sq_concat = (binaryfunc)py_ldb_dn_concat,
300 };
301
302 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
303 {
304         struct ldb_dn *ret;
305         char *str;
306         PyObject *py_ldb;
307         struct ldb_context *ldb_ctx;
308         PyLdbDnObject *py_ret;
309         const char * const kwnames[] = { "ldb", "dn", NULL };
310
311         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
312                                          discard_const_p(char *, kwnames),
313                                          &py_ldb, &str))
314                 return NULL;
315
316         ldb_ctx = PyLdb_AsLdbContext(py_ldb);
317
318         ret = ldb_dn_new(ldb_ctx, ldb_ctx, str);
319         /* ldb_dn_new() doesn't accept NULL as memory context, so 
320            we do it this way... */
321         talloc_steal(NULL, ret);
322
323         if (ret == NULL || !ldb_dn_validate(ret)) {
324                 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
325                 return NULL;
326         }
327
328         py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
329         if (ret == NULL) {
330                 PyErr_NoMemory();
331                 return NULL;
332         }
333         py_ret->dn = ret;
334         return (PyObject *)py_ret;
335 }
336
337 PyObject *PyLdbDn_FromDn(struct ldb_dn *dn)
338 {
339         PyLdbDnObject *py_ret;
340         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
341         if (py_ret == NULL) {
342                 PyErr_NoMemory();
343                 return NULL;
344         }
345         py_ret->mem_ctx = talloc_new(NULL);
346         py_ret->dn = talloc_reference(py_ret->mem_ctx, dn);
347         return (PyObject *)py_ret;
348 }
349
350 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
351 {
352         talloc_free(self->mem_ctx);
353         self->ob_type->tp_free(self);
354 }
355
356 PyTypeObject PyLdbDn = {
357         .tp_name = "Dn",
358         .tp_methods = py_ldb_dn_methods,
359         .tp_str = (reprfunc)py_ldb_dn_get_linearized,
360         .tp_repr = (reprfunc)py_ldb_dn_repr,
361         .tp_compare = (cmpfunc)py_ldb_dn_compare,
362         .tp_as_sequence = &py_ldb_dn_seq,
363         .tp_doc = "A LDB distinguished name.",
364         .tp_new = py_ldb_dn_new,
365         .tp_dealloc = (destructor)py_ldb_dn_dealloc,
366         .tp_basicsize = sizeof(PyLdbObject),
367         .tp_flags = Py_TPFLAGS_DEFAULT,
368 };
369
370 /* Debug */
371 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
372 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
373 {
374         PyObject *fn = (PyObject *)context;
375         PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
376 }
377
378 static PyObject *py_ldb_set_debug(PyLdbObject *self, PyObject *args)
379 {
380         PyObject *cb;
381
382         if (!PyArg_ParseTuple(args, "O", &cb))
383                 return NULL;
384
385         Py_INCREF(cb);
386         /* FIXME: Where do we DECREF cb ? */
387         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_set_debug(self->ldb_ctx, py_ldb_debug, cb), PyLdb_AsLdbContext(self));
388
389         Py_RETURN_NONE;
390 }
391
392 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
393 {
394         unsigned int perms;
395         if (!PyArg_ParseTuple(args, "I", &perms))
396                 return NULL;
397
398         ldb_set_create_perms(PyLdb_AsLdbContext(self), perms);
399
400         Py_RETURN_NONE;
401 }
402
403 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
404 {
405         char *modules_dir;
406         if (!PyArg_ParseTuple(args, "s", &modules_dir))
407                 return NULL;
408
409         ldb_set_modules_dir(PyLdb_AsLdbContext(self), modules_dir);
410
411         Py_RETURN_NONE;
412 }
413
414 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
415 {
416         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_start(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
417         Py_RETURN_NONE;
418 }
419
420 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
421 {
422         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
423         Py_RETURN_NONE;
424 }
425
426 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
427 {
428         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_cancel(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
429         Py_RETURN_NONE;
430 }
431
432 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
433 {
434         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_setup_wellknown_attributes(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
435         Py_RETURN_NONE;
436 }
437
438 static PyObject *py_ldb_repr(PyLdbObject *self)
439 {
440         return PyString_FromFormat("<ldb connection>");
441 }
442
443 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
444 {
445         struct ldb_dn *dn = ldb_get_root_basedn(PyLdb_AsLdbContext(self));
446         if (dn == NULL)
447                 Py_RETURN_NONE;
448         return PyLdbDn_FromDn(dn);
449 }
450
451
452 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
453 {
454         struct ldb_dn *dn = ldb_get_schema_basedn(PyLdb_AsLdbContext(self));
455         if (dn == NULL)
456                 Py_RETURN_NONE;
457         return PyLdbDn_FromDn(dn);
458 }
459
460 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
461 {
462         struct ldb_dn *dn = ldb_get_config_basedn(PyLdb_AsLdbContext(self));
463         if (dn == NULL)
464                 Py_RETURN_NONE;
465         return PyLdbDn_FromDn(dn);
466 }
467
468 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
469 {
470         struct ldb_dn *dn = ldb_get_default_basedn(PyLdb_AsLdbContext(self));
471         if (dn == NULL)
472                 Py_RETURN_NONE;
473         return PyLdbDn_FromDn(dn);
474 }
475
476 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list, 
477                                                                                 const char *paramname)
478 {
479         const char **ret;
480         int i;
481         if (!PyList_Check(list)) {
482                 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
483                 return NULL;
484         }
485         ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
486         for (i = 0; i < PyList_Size(list); i++) {
487                 PyObject *item = PyList_GetItem(list, i);
488                 if (!PyString_Check(item)) {
489                         PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
490                         return NULL;
491                 }
492                 ret[i] = PyString_AsString(item);
493         }
494         ret[i] = NULL;
495         return ret;
496 }
497
498 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
499 {
500         const char * const kwnames[] = { "url", "flags", "options", NULL };
501         char *url = NULL;
502         PyObject *py_options = Py_None;
503         const char **options;
504         int flags = 0;
505         int ret;
506         struct ldb_context *ldb;
507
508         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ziO:Ldb.__init__",
509                                          discard_const_p(char *, kwnames),
510                                          &url, &flags, &py_options))
511                 return -1;
512
513         ldb = PyLdb_AsLdbContext(self);
514
515         if (py_options == Py_None) {
516                 options = NULL;
517         } else {
518                 options = PyList_AsStringList(ldb, py_options, "options");
519                 if (options == NULL)
520                         return -1;
521         }
522
523         if (url != NULL) {
524                 ret = ldb_connect(ldb, url, flags, options);
525                 if (ret != LDB_SUCCESS) {
526                         PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
527                         return -1;
528                 }
529         }
530
531         talloc_free(options);
532         return 0;
533 }
534
535 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
536 {
537         PyLdbObject *ret;
538         struct ldb_context *ldb;
539         ldb = ldb_init(NULL, NULL);
540         if (ldb == NULL) {
541                 PyErr_NoMemory();
542                 return NULL;
543         }
544
545         ret = (PyLdbObject *)type->tp_alloc(type, 0);
546         if (ret == NULL) {
547                 PyErr_NoMemory();
548                 return NULL;
549         }
550         ret->ldb_ctx = ldb;
551         return (PyObject *)ret;
552 }
553
554 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
555 {
556         char *url;
557         int flags = 0;
558         PyObject *py_options = Py_None;
559         int ret;
560         const char **options;
561         const char * const kwnames[] = { "url", "flags", "options", NULL };
562
563         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|iO",
564                                          discard_const_p(char *, kwnames),
565                                          &url, &flags, &py_options))
566                 return NULL;
567
568         if (py_options == Py_None) {
569                 options = NULL;
570         } else {
571                 options = PyList_AsStringList(NULL, py_options, "options");
572                 if (options == NULL)
573                         return NULL;
574         }
575
576         ret = ldb_connect(PyLdb_AsLdbContext(self), url, flags, options);
577         talloc_free(options);
578
579         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
580
581         Py_RETURN_NONE;
582 }
583
584 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args)
585 {
586         PyObject *py_msg;
587         int ret;
588         if (!PyArg_ParseTuple(args, "O", &py_msg))
589                 return NULL;
590
591         if (!PyLdbMessage_Check(py_msg)) {
592                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
593                 return NULL;
594         }
595
596         ret = ldb_modify(PyLdb_AsLdbContext(self), PyLdbMessage_AsMessage(py_msg));
597         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
598
599         Py_RETURN_NONE;
600 }
601
602 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args)
603 {
604         PyObject *py_msg;
605         int ret;
606         Py_ssize_t dict_pos, msg_pos;
607         struct ldb_message_element *msgel;
608         struct ldb_message *msg;
609         PyObject *key, *value;
610
611         if (!PyArg_ParseTuple(args, "O", &py_msg))
612                 return NULL;
613
614         if (PyDict_Check(py_msg)) {
615                 PyObject *dn_value = PyDict_GetItemString(py_msg, "dn");
616                 msg = ldb_msg_new(NULL);
617                 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_msg));
618                 msg_pos = dict_pos = 0;
619                 if (dn_value) {
620                         if (!PyObject_AsDn(msg, dn_value, PyLdb_AsLdbContext(self), &msg->dn)) {
621                                 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
622                                 return NULL;
623                         }
624                         if (msg->dn == NULL) {
625                                 PyErr_SetString(PyExc_TypeError, "dn set but not found");
626                                 return NULL;
627                         }
628                 }
629
630                 while (PyDict_Next(py_msg, &dict_pos, &key, &value)) {
631                         char *key_str = PyString_AsString(key);
632                         if (strcmp(key_str, "dn") != 0) {
633                                 msgel = PyObject_AsMessageElement(msg->elements, value, 0, key_str);
634                                 if (msgel == NULL) {
635                                         PyErr_SetString(PyExc_TypeError, "unable to import element");
636                                         return NULL;
637                                 }
638                                 memcpy(&msg->elements[msg_pos], msgel, sizeof(*msgel));
639                                 msg_pos++;
640                         }
641                 }
642
643                 if (msg->dn == NULL) {
644                         PyErr_SetString(PyExc_TypeError, "no dn set");
645                         return NULL;
646                 }
647
648                 msg->num_elements = msg_pos;
649         } else {
650                 msg = PyLdbMessage_AsMessage(py_msg);
651         }
652
653         ret = ldb_add(PyLdb_AsLdbContext(self), msg);
654         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
655
656         Py_RETURN_NONE;
657 }
658
659 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args)
660 {
661         PyObject *py_dn;
662         struct ldb_dn *dn;
663         int ret;
664         struct ldb_context *ldb;
665         if (!PyArg_ParseTuple(args, "O", &py_dn))
666                 return NULL;
667
668         ldb = PyLdb_AsLdbContext(self);
669
670         if (!PyObject_AsDn(NULL, py_dn, ldb, &dn))
671                 return NULL;
672
673         ret = ldb_delete(ldb, dn);
674         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
675
676         Py_RETURN_NONE;
677 }
678
679 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args)
680 {
681         PyObject *py_dn1, *py_dn2;
682         struct ldb_dn *dn1, *dn2;
683         int ret;
684         struct ldb_context *ldb;
685         if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
686                 return NULL;
687
688         ldb = PyLdb_AsLdbContext(self);
689         if (!PyObject_AsDn(NULL, py_dn1, ldb, &dn1))
690                 return NULL;
691
692         if (!PyObject_AsDn(NULL, py_dn2, ldb, &dn2))
693                 return NULL;
694
695         ret = ldb_rename(ldb, dn1, dn2);
696         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
697
698         Py_RETURN_NONE;
699 }
700
701 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
702 {
703         char *name;
704         if (!PyArg_ParseTuple(args, "s", &name))
705                 return NULL;
706
707         ldb_schema_attribute_remove(PyLdb_AsLdbContext(self), name);
708
709         Py_RETURN_NONE;
710 }
711
712 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
713 {
714         char *attribute, *syntax;
715         unsigned int flags;
716         int ret;
717         if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
718                 return NULL;
719
720         ret = ldb_schema_attribute_add(PyLdb_AsLdbContext(self), attribute, flags, syntax);
721
722         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
723
724         Py_RETURN_NONE;
725 }
726
727 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
728 {
729         if (ldif == NULL) {
730                 Py_RETURN_NONE;
731         } else {
732         /* We don't want this attached to the 'ldb' any more */
733                 talloc_steal(NULL, ldif);
734                 return Py_BuildValue(discard_const_p(char, "(iO)"),
735                                      ldif->changetype,
736                                      PyLdbMessage_FromMessage(ldif->msg));
737         }
738 }
739
740
741 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
742 {
743         PyObject *list;
744         struct ldb_ldif *ldif;
745         const char *s;
746
747         if (!PyArg_ParseTuple(args, "s", &s))
748                 return NULL;
749
750         list = PyList_New(0);
751         while ((ldif = ldb_ldif_read_string(self->ldb_ctx, &s)) != NULL) {
752                 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
753         }
754         return PyObject_GetIter(list);
755 }
756
757 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
758 {
759         const struct ldb_schema_attribute *a;
760         struct ldb_val old_val;
761         struct ldb_val new_val;
762         TALLOC_CTX *mem_ctx;
763         PyObject *ret;
764         char *element_name;
765         PyObject *val;
766
767         if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
768                 return NULL;
769
770         mem_ctx = talloc_new(NULL);
771
772         old_val.data = (uint8_t *)PyString_AsString(val);
773         old_val.length = PyString_Size(val);
774
775         a = ldb_schema_attribute_by_name(PyLdb_AsLdbContext(self), element_name);
776
777         if (a == NULL) {
778                 Py_RETURN_NONE;
779         }
780
781         if (a->syntax->ldif_write_fn(PyLdb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
782                 talloc_free(mem_ctx);
783                 Py_RETURN_NONE;
784         }
785
786         ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
787
788         talloc_free(mem_ctx);
789
790         return ret;
791 }
792
793 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
794 {
795         PyObject *py_base = Py_None;
796         enum ldb_scope scope = LDB_SCOPE_DEFAULT;
797         char *expr = NULL;
798         PyObject *py_attrs = Py_None;
799         PyObject *py_controls = Py_None;
800         const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
801         int ret;
802         struct ldb_result *res;
803         struct ldb_request *req;
804         const char **attrs;
805         struct ldb_context *ldb_ctx;
806         struct ldb_control **parsed_controls;
807         struct ldb_dn *base;
808
809         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
810                                          discard_const_p(char *, kwnames),
811                                          &py_base, &scope, &expr, &py_attrs, &py_controls))
812                 return NULL;
813
814         ldb_ctx = PyLdb_AsLdbContext(self);
815
816         if (py_attrs == Py_None) {
817                 attrs = NULL;
818         } else {
819                 attrs = PyList_AsStringList(ldb_ctx, py_attrs, "attrs");
820                 if (attrs == NULL)
821                         return NULL;
822         }
823
824         if (py_base == Py_None) {
825                 base = ldb_get_default_basedn(ldb_ctx);
826         } else {
827                 if (!PyObject_AsDn(ldb_ctx, py_base, ldb_ctx, &base))
828                         return NULL;
829         }
830
831         if (py_controls == Py_None) {
832                 parsed_controls = NULL;
833         } else {
834                 const char **controls = PyList_AsStringList(ldb_ctx, py_controls, "controls");
835                 parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);
836                 talloc_free(controls);
837         }
838
839         res = talloc_zero(ldb_ctx, struct ldb_result);
840         if (res == NULL) {
841                 PyErr_NoMemory();
842                 return NULL;
843         }
844
845         ret = ldb_build_search_req(&req, ldb_ctx, ldb_ctx,
846                                    base,
847                                    scope,
848                                    expr,
849                                    attrs,
850                                    parsed_controls,
851                                    res,
852                                    ldb_search_default_callback,
853                                    NULL);
854
855         if (ret != LDB_SUCCESS) {
856                 talloc_free(res);
857                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
858                 return NULL;
859         }
860
861         ret = ldb_request(ldb_ctx, req);
862
863         if (ret == LDB_SUCCESS) {
864                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
865         }
866
867         talloc_free(req);
868
869         if (ret != LDB_SUCCESS) {
870                 talloc_free(res);
871                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
872                 return NULL;
873         }
874
875         return PyLdbResult_FromResult(res);
876 }
877
878 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
879 {
880         char *name;
881         void *data;
882
883         if (!PyArg_ParseTuple(args, "s", &name))
884                 return NULL;
885
886         data = ldb_get_opaque(PyLdb_AsLdbContext(self), name);
887
888         if (data == NULL)
889                 Py_RETURN_NONE;
890
891         /* FIXME: More interpretation */
892
893         return Py_True;
894 }
895
896 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
897 {
898         char *name;
899         PyObject *data;
900
901         if (!PyArg_ParseTuple(args, "sO", &name, &data))
902                 return NULL;
903
904         /* FIXME: More interpretation */
905
906         ldb_set_opaque(PyLdb_AsLdbContext(self), name, data);
907
908         Py_RETURN_NONE;
909 }
910
911 static PyObject *py_ldb_modules(PyLdbObject *self)
912 {
913         struct ldb_context *ldb = PyLdb_AsLdbContext(self);
914         PyObject *ret = PyList_New(0);
915         struct ldb_module *mod;
916
917         for (mod = ldb->modules; mod; mod = mod->next) {
918                 PyList_Append(ret, PyLdbModule_FromModule(mod));
919         }
920
921         return ret;
922 }
923
924 static PyMethodDef py_ldb_methods[] = {
925         { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, 
926                 "S.set_debug(callback) -> None\n"
927                 "Set callback for LDB debug messages.\n"
928                 "The callback should accept a debug level and debug text." },
929         { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS, 
930                 "S.set_create_perms(mode) -> None\n"
931                 "Set mode to use when creating new LDB files." },
932         { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
933                 "S.set_modules_dir(path) -> None\n"
934                 "Set path LDB should search for modules" },
935         { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS, 
936                 "S.transaction_start() -> None\n"
937                 "Start a new transaction." },
938         { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, 
939                 "S.transaction_commit() -> None\n"
940                 "commit a new transaction." },
941         { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS, 
942                 "S.transaction_cancel() -> None\n"
943                 "cancel a new transaction." },
944         { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS, 
945                 NULL },
946         { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
947                 NULL },
948         { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
949                 NULL },
950         { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
951                 NULL },
952         { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
953                 NULL },
954         { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS, 
955                 "S.connect(url, flags=0, options=None) -> None\n"
956                 "Connect to a LDB URL." },
957         { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS, 
958                 "S.modify(message) -> None\n"
959                 "Modify an entry." },
960         { "add", (PyCFunction)py_ldb_add, METH_VARARGS, 
961                 "S.add(message) -> None\n"
962                 "Add an entry." },
963         { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS,
964                 "S.delete(dn) -> None\n"
965                 "Remove an entry." },
966         { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS,
967                 "S.rename(old_dn, new_dn) -> None\n"
968                 "Rename an entry." },
969         { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
970                 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
971                 "Search in a database.\n"
972                 "\n"
973                 ":param base: Optional base DN to search\n"
974                 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
975                 ":param expression: Optional search expression\n"
976                 ":param attrs: Attributes to return (defaults to all)\n"
977                 ":param controls: Optional list of controls\n"
978                 ":return: Iterator over Message objects\n"
979         },
980         { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
981                 NULL },
982         { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
983                 NULL },
984         { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
985                 NULL },
986         { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
987                 "S.parse_ldif(ldif) -> iter(messages)\n"
988                 "Parse a string formatted using LDIF." },
989         { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
990                 "S.get_opaque(name) -> value\n"
991                 "Get an opaque value set on this LDB connection. \n"
992                 ":note: The returned value may not be useful in Python."
993         },
994         { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
995                 "S.set_opaque(name, value) -> None\n"
996                 "Set an opaque value on this LDB connection. \n"
997                 ":note: Passing incorrect values may cause crashes." },
998         { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
999                 "S.modules() -> list\n"
1000                 "Return the list of modules on this LDB connection " },
1001         { NULL },
1002 };
1003
1004 PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1005 {
1006         PyLdbModuleObject *ret;
1007
1008         ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1009         if (ret == NULL) {
1010                 PyErr_NoMemory();
1011                 return NULL;
1012         }
1013         ret->mem_ctx = talloc_new(NULL);
1014         ret->mod = talloc_reference(ret->mem_ctx, mod);
1015         return (PyObject *)ret;
1016 }
1017
1018 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1019 {
1020         return PyLdbModule_FromModule(PyLdb_AsLdbContext(self)->modules);
1021 }
1022
1023 static PyGetSetDef py_ldb_getset[] = {
1024         { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1025         { NULL }
1026 };
1027
1028 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1029 {
1030         struct ldb_context *ldb_ctx = PyLdb_AsLdbContext(self);
1031         struct ldb_dn *dn;
1032         struct ldb_result *result;
1033         int ret;
1034         int count;
1035
1036         if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn))
1037                 return -1;
1038
1039         ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL, NULL);
1040         if (ret != LDB_SUCCESS) {
1041                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1042                 return -1;
1043         }
1044
1045         count = result->count;
1046
1047         talloc_free(result);
1048
1049         return count;
1050 }
1051
1052 static PySequenceMethods py_ldb_seq = {
1053         .sq_contains = (objobjproc)py_ldb_contains,
1054 };
1055
1056 PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1057 {
1058         PyLdbObject *ret;
1059
1060         ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1061         if (ret == NULL) {
1062                 PyErr_NoMemory();
1063                 return NULL;
1064         }
1065         ret->mem_ctx = talloc_new(NULL);
1066         ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1067         return (PyObject *)ret;
1068 }
1069
1070 static void py_ldb_dealloc(PyLdbObject *self)
1071 {
1072         talloc_free(self->mem_ctx);
1073         self->ob_type->tp_free(self);
1074 }
1075
1076 PyTypeObject PyLdb = {
1077         .tp_name = "Ldb",
1078         .tp_methods = py_ldb_methods,
1079         .tp_repr = (reprfunc)py_ldb_repr,
1080         .tp_new = py_ldb_new,
1081         .tp_init = (initproc)py_ldb_init,
1082         .tp_dealloc = (destructor)py_ldb_dealloc,
1083         .tp_getset = py_ldb_getset,
1084         .tp_getattro = PyObject_GenericGetAttr,
1085         .tp_basicsize = sizeof(PyLdbObject),
1086         .tp_doc = "Connection to a LDB database.",
1087         .tp_as_sequence = &py_ldb_seq,
1088         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1089 };
1090
1091 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
1092 {
1093         return PyString_FromFormat("<ldb module '%s'>", PyLdbModule_AsModule(self)->ops->name);
1094 }
1095
1096 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
1097 {
1098         return PyString_FromString(PyLdbModule_AsModule(self)->ops->name);
1099 }
1100
1101 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
1102 {
1103         PyLdbModule_AsModule(self)->ops->start_transaction(PyLdbModule_AsModule(self));
1104         Py_RETURN_NONE;
1105 }
1106
1107 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
1108 {
1109         PyLdbModule_AsModule(self)->ops->end_transaction(PyLdbModule_AsModule(self));
1110         Py_RETURN_NONE;
1111 }
1112
1113 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
1114 {
1115         PyLdbModule_AsModule(self)->ops->del_transaction(PyLdbModule_AsModule(self));
1116         Py_RETURN_NONE;
1117 }
1118
1119 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
1120 {
1121         PyObject *py_base, *py_tree, *py_attrs;
1122         int ret, scope;
1123         struct ldb_request *req;
1124         const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
1125         struct ldb_module *mod;
1126
1127         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
1128                                          discard_const_p(char *, kwnames),
1129                                          &py_base, &scope, &py_tree, &py_attrs))
1130                 return NULL;
1131
1132         mod = self->mod;
1133
1134         ret = ldb_build_search_req(&req, mod->ldb, NULL, PyLdbDn_AsDn(py_base), 
1135                              scope, NULL /* expr */, py_attrs == Py_None?NULL:PyList_AsStringList(req, py_attrs, "attrs"),
1136                              NULL /* controls */, NULL, NULL, NULL);
1137         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1138
1139         ret = mod->ops->search(mod, req);
1140         talloc_free(req);
1141
1142         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1143
1144         return PyLdbResult_FromResult(req->op.search.res);
1145 }
1146
1147
1148 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
1149 {
1150         struct ldb_request *req;
1151         PyObject *py_message;
1152         int ret;
1153         struct ldb_module *mod;
1154
1155         if (!PyArg_ParseTuple(args, "O", &py_message))
1156                 return NULL;
1157
1158         req = talloc_zero(NULL, struct ldb_request);
1159         req->operation = LDB_ADD;
1160         req->op.add.message = PyLdbMessage_AsMessage(py_message);
1161
1162         mod = PyLdbModule_AsModule(self);
1163         ret = mod->ops->add(mod, req);
1164
1165         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1166
1167         Py_RETURN_NONE;
1168 }
1169
1170 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args) 
1171 {
1172         int ret;
1173         struct ldb_request *req;
1174         PyObject *py_message;
1175         struct ldb_module *mod;
1176
1177         if (!PyArg_ParseTuple(args, "O", &py_message))
1178                 return NULL;
1179
1180         req = talloc_zero(NULL, struct ldb_request);
1181         req->operation = LDB_MODIFY;
1182         req->op.mod.message = PyLdbMessage_AsMessage(py_message);
1183
1184         mod = PyLdbModule_AsModule(self);
1185         ret = mod->ops->modify(mod, req);
1186
1187         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1188
1189         Py_RETURN_NONE;
1190 }
1191
1192 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args) 
1193 {
1194         int ret;
1195         struct ldb_request *req;
1196         PyObject *py_dn;
1197
1198         if (!PyArg_ParseTuple(args, "O", &py_dn))
1199                 return NULL;
1200
1201         req = talloc_zero(NULL, struct ldb_request);
1202         req->operation = LDB_DELETE;
1203         req->op.del.dn = PyLdbDn_AsDn(py_dn);
1204
1205         ret = PyLdbModule_AsModule(self)->ops->del(PyLdbModule_AsModule(self), req);
1206
1207         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
1208
1209         Py_RETURN_NONE;
1210 }
1211
1212 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
1213 {
1214         int ret;
1215         struct ldb_request *req;
1216         PyObject *py_dn1, *py_dn2;
1217
1218         if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
1219                 return NULL;
1220
1221         req = talloc_zero(NULL, struct ldb_request);
1222
1223         req->operation = LDB_RENAME;
1224         req->op.rename.olddn = PyLdbDn_AsDn(py_dn1);
1225         req->op.rename.newdn = PyLdbDn_AsDn(py_dn2);
1226
1227         ret = PyLdbModule_AsModule(self)->ops->rename(PyLdbModule_AsModule(self), req);
1228
1229         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
1230
1231         Py_RETURN_NONE;
1232 }
1233
1234 static PyMethodDef py_ldb_module_methods[] = {
1235         { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
1236         { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
1237         { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
1238         { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
1239         { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
1240         { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
1241         { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
1242         { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
1243         { NULL },
1244 };
1245
1246 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
1247 {
1248         talloc_free(self->mem_ctx);
1249         self->ob_type->tp_free(self);
1250 }
1251
1252 PyTypeObject PyLdbModule = {
1253         .tp_name = "LdbModule",
1254         .tp_methods = py_ldb_module_methods,
1255         .tp_repr = (reprfunc)py_ldb_module_repr,
1256         .tp_str = (reprfunc)py_ldb_module_str,
1257         .tp_basicsize = sizeof(PyLdbModuleObject),
1258         .tp_dealloc = (destructor)py_ldb_module_dealloc,
1259         .tp_flags = Py_TPFLAGS_DEFAULT,
1260 };
1261
1262
1263 /**
1264  * Create a ldb_message_element from a Python object.
1265  *
1266  * This will accept any sequence objects that contains strings, or 
1267  * a string object.
1268  *
1269  * A reference to set_obj will be borrowed. 
1270  *
1271  * @param mem_ctx Memory context
1272  * @param set_obj Python object to convert
1273  * @param flags ldb_message_element flags to set
1274  * @param attr_name Name of the attribute
1275  * @return New ldb_message_element, allocated as child of mem_ctx
1276  */
1277 struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx,
1278                                                                                            PyObject *set_obj, int flags,
1279                                                                                            const char *attr_name)
1280 {
1281         struct ldb_message_element *me;
1282
1283         if (PyLdbMessageElement_Check(set_obj))
1284                 return PyLdbMessageElement_AsMessageElement(set_obj);
1285
1286         me = talloc(mem_ctx, struct ldb_message_element);
1287
1288         me->name = attr_name;
1289         me->flags = flags;
1290         if (PyString_Check(set_obj)) {
1291                 me->num_values = 1;
1292                 me->values = talloc_array(me, struct ldb_val, me->num_values);
1293                 me->values[0].length = PyString_Size(set_obj);
1294                 me->values[0].data = (uint8_t *)PyString_AsString(set_obj);
1295         } else if (PySequence_Check(set_obj)) {
1296                 int i;
1297                 me->num_values = PySequence_Size(set_obj);
1298                 me->values = talloc_array(me, struct ldb_val, me->num_values);
1299                 for (i = 0; i < me->num_values; i++) {
1300                         PyObject *obj = PySequence_GetItem(set_obj, i);
1301
1302                         me->values[i].length = PyString_Size(obj);
1303                         me->values[i].data = (uint8_t *)PyString_AsString(obj);
1304                 }
1305         } else {
1306                 talloc_free(me);
1307                 me = NULL;
1308         }
1309
1310         return me;
1311 }
1312
1313
1314 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, 
1315                                                                  struct ldb_message_element *me)
1316 {
1317         int i;
1318         PyObject *result;
1319
1320         /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
1321         result = PyList_New(me->num_values);
1322
1323         for (i = 0; i < me->num_values; i++) {
1324                 PyList_SetItem(result, i,
1325                         PyObject_FromLdbValue(ldb_ctx, me, &me->values[i]));
1326         }
1327
1328         return result;
1329 }
1330
1331 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
1332 {
1333         int i;
1334         if (!PyArg_ParseTuple(args, "i", &i))
1335                 return NULL;
1336         if (i < 0 || i >= PyLdbMessageElement_AsMessageElement(self)->num_values)
1337                 Py_RETURN_NONE;
1338
1339         return PyObject_FromLdbValue(NULL, PyLdbMessageElement_AsMessageElement(self), 
1340                                                                  &(PyLdbMessageElement_AsMessageElement(self)->values[i]));
1341 }
1342
1343 static PyMethodDef py_ldb_msg_element_methods[] = {
1344         { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
1345         { NULL },
1346 };
1347
1348 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
1349 {
1350         return PyLdbMessageElement_AsMessageElement(self)->num_values;
1351 }
1352
1353 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
1354 {
1355         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1356         if (idx < 0 || idx >= el->num_values) {
1357                 PyErr_SetString(PyExc_IndexError, "Out of range");
1358                 return NULL;
1359         }
1360         return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
1361 }
1362
1363 static PySequenceMethods py_ldb_msg_element_seq = {
1364         .sq_length = (lenfunc)py_ldb_msg_element_len,
1365         .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
1366 };
1367
1368 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
1369 {
1370         return ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self), 
1371                                                                    PyLdbMessageElement_AsMessageElement(other));
1372 }
1373
1374 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
1375 {
1376         return PyObject_GetIter(ldb_msg_element_to_set(NULL, PyLdbMessageElement_AsMessageElement(self)));
1377 }
1378
1379 PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
1380 {
1381         PyLdbMessageElementObject *ret;
1382         ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
1383         if (ret == NULL) {
1384                 PyErr_NoMemory();
1385                 return NULL;
1386         }
1387         ret->mem_ctx = talloc_new(NULL);
1388         if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
1389                 PyErr_NoMemory();
1390                 return NULL;
1391         }
1392         ret->el = el;
1393         return (PyObject *)ret;
1394 }
1395
1396 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1397 {
1398         PyObject *py_elements = NULL;
1399         struct ldb_message_element *el;
1400         int flags = 0;
1401         char *name = NULL;
1402         const char * const kwnames[] = { "elements", "flags", "name", NULL };
1403         PyLdbMessageElementObject *ret;
1404
1405         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Ois",
1406                                          discard_const_p(char *, kwnames),
1407                                          &py_elements, &flags, &name))
1408                 return NULL;
1409
1410         el = talloc_zero(NULL, struct ldb_message_element);
1411
1412         if (py_elements != NULL) {
1413                 int i;
1414                 if (PyString_Check(py_elements)) {
1415                         el->num_values = 1;
1416                         el->values = talloc_array(el, struct ldb_val, 1);
1417                         el->values[0].data = (uint8_t *)PyString_AsString(py_elements);
1418                         el->values[0].length = PyString_Size(py_elements);
1419                 } else if (PySequence_Check(py_elements)) {
1420                         el->num_values = PySequence_Size(py_elements);
1421                         el->values = talloc_array(el, struct ldb_val, el->num_values);
1422                         for (i = 0; i < el->num_values; i++) {
1423                                 PyObject *item = PySequence_GetItem(py_elements, i);
1424                                 el->values[i].data = (uint8_t *)PyString_AsString(item);
1425                                 el->values[i].length = PyString_Size(item);
1426                         }
1427                 } else {
1428                         PyErr_SetString(PyExc_TypeError, 
1429                                         "Expected string or list");
1430                         talloc_free(el);
1431                         return NULL;
1432                 }
1433         }
1434
1435         el->flags = flags;
1436         el->name = talloc_strdup(el, name);
1437
1438         ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
1439         if (ret == NULL) {
1440                 PyErr_NoMemory();
1441                 talloc_free(el);
1442                 return NULL;
1443         }
1444
1445         ret->mem_ctx = talloc_new(NULL);
1446         ret->el = talloc_reference(ret->mem_ctx, el);
1447         return (PyObject *)ret;
1448 }
1449
1450 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
1451 {
1452         char *element_str = NULL;
1453         int i;
1454         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1455         PyObject *ret;
1456
1457         for (i = 0; i < el->num_values; i++) {
1458                 PyObject *o = py_ldb_msg_element_find(self, i);
1459                 if (element_str == NULL)
1460                         element_str = talloc_strdup(NULL, PyObject_REPR(o));
1461                 else
1462                         element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
1463         }
1464
1465         ret = PyString_FromFormat("MessageElement([%s])", element_str);
1466
1467         talloc_free(element_str);
1468
1469         return ret;
1470 }
1471
1472 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
1473 {
1474         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1475
1476         if (el->num_values == 1)
1477                 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
1478         else 
1479                 Py_RETURN_NONE;
1480 }
1481
1482 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
1483 {
1484         talloc_free(self->mem_ctx);
1485         self->ob_type->tp_free(self);
1486 }
1487
1488 PyTypeObject PyLdbMessageElement = {
1489         .tp_name = "MessageElement",
1490         .tp_basicsize = sizeof(PyLdbMessageElementObject),
1491         .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
1492         .tp_repr = (reprfunc)py_ldb_msg_element_repr,
1493         .tp_str = (reprfunc)py_ldb_msg_element_str,
1494         .tp_methods = py_ldb_msg_element_methods,
1495         .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
1496         .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
1497         .tp_as_sequence = &py_ldb_msg_element_seq,
1498         .tp_new = py_ldb_msg_element_new,
1499         .tp_flags = Py_TPFLAGS_DEFAULT,
1500 };
1501
1502 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
1503 {
1504         char *name;
1505         if (!PyArg_ParseTuple(args, "s", &name))
1506                 return NULL;
1507
1508         ldb_msg_remove_attr(self->msg, name);
1509
1510         Py_RETURN_NONE;
1511 }
1512
1513 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
1514 {
1515         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1516         int i, j = 0;
1517         PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
1518         if (msg->dn != NULL) {
1519                 PyList_SetItem(obj, j, PyString_FromString("dn"));
1520                 j++;
1521         }
1522         for (i = 0; i < msg->num_elements; i++) {
1523                 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
1524                 j++;
1525         }
1526         return obj;
1527 }
1528
1529 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
1530 {
1531         struct ldb_message_element *el;
1532         char *name = PyString_AsString(py_name);
1533         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1534         if (!strcmp(name, "dn"))
1535                 return PyLdbDn_FromDn(msg->dn);
1536         el = ldb_msg_find_element(msg, name);
1537         if (el == NULL) {
1538                 return NULL;
1539         }
1540         return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg);
1541 }
1542
1543 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
1544 {
1545         PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
1546         if (ret == NULL) {
1547                 PyErr_SetString(PyExc_KeyError, "No such element");
1548                 return NULL;
1549         }
1550         return ret;
1551 }
1552
1553 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args)
1554 {
1555         PyObject *name, *ret;
1556         if (!PyArg_ParseTuple(args, "O", &name))
1557                 return NULL;
1558
1559         ret = py_ldb_msg_getitem_helper(self, name);
1560         if (ret == NULL)
1561                 Py_RETURN_NONE;
1562         return ret;
1563 }
1564
1565 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
1566 {
1567         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1568         int i, j;
1569         PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
1570         j = 0;
1571         if (msg->dn != NULL) {
1572                 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", PyLdbDn_FromDn(msg->dn)));
1573                 j++;
1574         }
1575         for (i = 0; i < msg->num_elements; i++, j++) {
1576                 PyList_SetItem(l, j, Py_BuildValue("(sO)", msg->elements[i].name, PyLdbMessageElement_FromMessageElement(&msg->elements[i], self->msg)));
1577         }
1578         return l;
1579 }
1580
1581 static PyMethodDef py_ldb_msg_methods[] = { 
1582         { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, NULL },
1583         { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, NULL },
1584         { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS, NULL },
1585         { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
1586         { NULL },
1587 };
1588
1589 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
1590 {
1591         PyObject *list, *iter;
1592
1593         list = py_ldb_msg_keys(self);
1594         iter = PyObject_GetIter(list);
1595         Py_DECREF(list);
1596         return iter;
1597 }
1598
1599 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
1600 {
1601         char *attr_name = PyString_AsString(name);
1602         if (value == NULL) {
1603                 ldb_msg_remove_attr(self->msg, attr_name);
1604         } else {
1605                 struct ldb_message_element *el = PyObject_AsMessageElement(NULL,
1606                                                                                         value, 0, attr_name);
1607                 if (el == NULL)
1608                         return -1;
1609                 talloc_steal(self->msg, el);
1610                 ldb_msg_remove_attr(PyLdbMessage_AsMessage(self), attr_name);
1611                 ldb_msg_add(PyLdbMessage_AsMessage(self), el, el->flags);
1612         }
1613         return 0;
1614 }
1615
1616 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
1617 {
1618         return PyLdbMessage_AsMessage(self)->num_elements;
1619 }
1620
1621 static PyMappingMethods py_ldb_msg_mapping = {
1622         .mp_length = (lenfunc)py_ldb_msg_length,
1623         .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
1624         .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
1625 };
1626
1627 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1628 {
1629         const char * const kwnames[] = { "dn", NULL };
1630         struct ldb_message *ret;
1631         PyObject *pydn = NULL;
1632         PyLdbMessageObject *py_ret;
1633
1634         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
1635                                          discard_const_p(char *, kwnames),
1636                                          &pydn))
1637                 return NULL;
1638
1639         ret = ldb_msg_new(NULL);
1640         if (ret == NULL) {
1641                 PyErr_NoMemory();
1642                 return NULL;
1643         }
1644
1645         if (pydn != NULL)
1646                 if (!PyObject_AsDn(NULL, pydn, NULL, &ret->dn))
1647                         return NULL;
1648
1649         py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
1650         if (py_ret == NULL) {
1651                 PyErr_NoMemory();
1652                 return NULL;
1653         }
1654
1655         py_ret->mem_ctx = talloc_new(NULL);
1656         py_ret->msg = talloc_reference(py_ret->mem_ctx, ret);
1657         return (PyObject *)py_ret;
1658 }
1659
1660 PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
1661 {
1662         PyLdbMessageObject *ret;
1663
1664         ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
1665         if (ret == NULL) {
1666                 PyErr_NoMemory();
1667                 return NULL;
1668         }
1669         ret->mem_ctx = talloc_new(NULL);
1670         ret->msg = talloc_reference(ret->mem_ctx, msg);
1671         return (PyObject *)ret;
1672 }
1673
1674 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
1675 {
1676         return PyLdbDn_FromDn(PyLdbMessage_AsMessage(self)->dn);
1677 }
1678
1679 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
1680 {
1681         PyLdbMessage_AsMessage(self)->dn = PyLdbDn_AsDn(value);
1682         return 0;
1683 }
1684
1685 static PyGetSetDef py_ldb_msg_getset[] = {
1686         { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
1687         { NULL }
1688 };
1689
1690 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
1691 {
1692         PyObject *dict = PyDict_New(), *ret;
1693         if (PyDict_Update(dict, (PyObject *)self) != 0)
1694                 return NULL;
1695         ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
1696         Py_DECREF(dict);
1697         return ret;
1698 }
1699
1700 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
1701 {
1702         talloc_free(self->mem_ctx);
1703         self->ob_type->tp_free(self);
1704 }
1705
1706 PyTypeObject PyLdbMessage = {
1707         .tp_name = "Message",
1708         .tp_methods = py_ldb_msg_methods,
1709         .tp_getset = py_ldb_msg_getset,
1710         .tp_as_mapping = &py_ldb_msg_mapping,
1711         .tp_basicsize = sizeof(PyLdbMessageObject),
1712         .tp_dealloc = (destructor)py_ldb_msg_dealloc,
1713         .tp_new = py_ldb_msg_new,
1714         .tp_repr = (reprfunc)py_ldb_msg_repr,
1715         .tp_flags = Py_TPFLAGS_DEFAULT,
1716         .tp_iter = (getiterfunc)py_ldb_msg_iter,
1717 };
1718
1719 PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
1720 {
1721         PyLdbTreeObject *ret;
1722
1723         ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
1724         if (ret == NULL) {
1725                 PyErr_NoMemory();
1726                 return NULL;
1727         }
1728
1729         ret->mem_ctx = talloc_new(NULL);
1730         ret->tree = talloc_reference(ret->mem_ctx, tree);
1731         return (PyObject *)ret;
1732 }
1733
1734 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
1735 {
1736         talloc_free(self->mem_ctx);
1737         self->ob_type->tp_free(self);
1738 }
1739
1740 PyTypeObject PyLdbTree = {
1741         .tp_name = "Tree",
1742         .tp_basicsize = sizeof(PyLdbTreeObject),
1743         .tp_dealloc = (destructor)py_ldb_tree_dealloc,
1744         .tp_flags = Py_TPFLAGS_DEFAULT,
1745 };
1746
1747 /* Ldb_module */
1748 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
1749 {
1750         PyObject *py_ldb = (PyObject *)mod->private_data;
1751         PyObject *py_result, *py_base, *py_attrs, *py_tree;
1752
1753         py_base = PyLdbDn_FromDn(req->op.search.base);
1754
1755         if (py_base == NULL)
1756                 return LDB_ERR_OPERATIONS_ERROR;
1757
1758         py_tree = PyLdbTree_FromTree(req->op.search.tree);
1759
1760         if (py_tree == NULL)
1761                 return LDB_ERR_OPERATIONS_ERROR;
1762
1763         if (req->op.search.attrs == NULL) {
1764                 py_attrs = Py_None;
1765         } else {
1766                 int i, len;
1767                 for (len = 0; req->op.search.attrs[len]; len++);
1768                 py_attrs = PyList_New(len);
1769                 for (i = 0; i < len; i++)
1770                         PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
1771         }
1772
1773         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
1774                                         discard_const_p(char, "OiOO"),
1775                                         py_base, req->op.search.scope, py_tree, py_attrs);
1776
1777         Py_DECREF(py_attrs);
1778         Py_DECREF(py_tree);
1779         Py_DECREF(py_base);
1780
1781         if (py_result == NULL) {
1782                 return LDB_ERR_PYTHON_EXCEPTION;
1783         }
1784
1785         req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
1786         if (req->op.search.res == NULL) {
1787                 return LDB_ERR_PYTHON_EXCEPTION;
1788         }
1789
1790         Py_DECREF(py_result);
1791
1792         return LDB_SUCCESS;
1793 }
1794
1795 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
1796 {
1797         PyObject *py_ldb = (PyObject *)mod->private_data;
1798         PyObject *py_result, *py_msg;
1799
1800         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
1801
1802         if (py_msg == NULL) {
1803                 return LDB_ERR_OPERATIONS_ERROR;
1804         }
1805
1806         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
1807                                         discard_const_p(char, "O"),
1808                                         py_msg);
1809
1810         Py_DECREF(py_msg);
1811
1812         if (py_result == NULL) {
1813                 return LDB_ERR_PYTHON_EXCEPTION;
1814         }
1815
1816         Py_DECREF(py_result);
1817
1818         return LDB_SUCCESS;
1819 }
1820
1821 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
1822 {
1823         PyObject *py_ldb = (PyObject *)mod->private_data;
1824         PyObject *py_result, *py_msg;
1825
1826         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
1827
1828         if (py_msg == NULL) {
1829                 return LDB_ERR_OPERATIONS_ERROR;
1830         }
1831
1832         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
1833                                         discard_const_p(char, "O"),
1834                                         py_msg);
1835
1836         Py_DECREF(py_msg);
1837
1838         if (py_result == NULL) {
1839                 return LDB_ERR_PYTHON_EXCEPTION;
1840         }
1841
1842         Py_DECREF(py_result);
1843
1844         return LDB_SUCCESS;
1845 }
1846
1847 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
1848 {
1849         PyObject *py_ldb = (PyObject *)mod->private_data;
1850         PyObject *py_result, *py_dn;
1851
1852         py_dn = PyLdbDn_FromDn(req->op.del.dn);
1853
1854         if (py_dn == NULL)
1855                 return LDB_ERR_OPERATIONS_ERROR;
1856
1857         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
1858                                         discard_const_p(char, "O"),
1859                                         py_dn);
1860
1861         if (py_result == NULL) {
1862                 return LDB_ERR_PYTHON_EXCEPTION;
1863         }
1864
1865         Py_DECREF(py_result);
1866
1867         return LDB_SUCCESS;
1868 }
1869
1870 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
1871 {
1872         PyObject *py_ldb = (PyObject *)mod->private_data;
1873         PyObject *py_result, *py_olddn, *py_newdn;
1874
1875         py_olddn = PyLdbDn_FromDn(req->op.rename.olddn);
1876
1877         if (py_olddn == NULL)
1878                 return LDB_ERR_OPERATIONS_ERROR;
1879
1880         py_newdn = PyLdbDn_FromDn(req->op.rename.newdn);
1881
1882         if (py_newdn == NULL)
1883                 return LDB_ERR_OPERATIONS_ERROR;
1884
1885         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
1886                                         discard_const_p(char, "OO"),
1887                                         py_olddn, py_newdn);
1888
1889         Py_DECREF(py_olddn);
1890         Py_DECREF(py_newdn);
1891
1892         if (py_result == NULL) {
1893                 return LDB_ERR_PYTHON_EXCEPTION;
1894         }
1895
1896         Py_DECREF(py_result);
1897
1898         return LDB_SUCCESS;
1899 }
1900
1901 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
1902 {
1903         PyObject *py_ldb = (PyObject *)mod->private_data;
1904         PyObject *py_result;
1905
1906         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
1907                                         discard_const_p(char, ""));
1908
1909         return LDB_ERR_OPERATIONS_ERROR;
1910 }
1911
1912 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
1913 {
1914         PyObject *py_ldb = (PyObject *)mod->private_data;
1915         PyObject *py_result;
1916
1917         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
1918                                         discard_const_p(char, ""));
1919
1920         return LDB_ERR_OPERATIONS_ERROR;
1921 }
1922
1923 static int py_module_start_transaction(struct ldb_module *mod)
1924 {
1925         PyObject *py_ldb = (PyObject *)mod->private_data;
1926         PyObject *py_result;
1927
1928         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
1929                                         discard_const_p(char, ""));
1930
1931         if (py_result == NULL) {
1932                 return LDB_ERR_PYTHON_EXCEPTION;
1933         }
1934
1935         Py_DECREF(py_result);
1936
1937         return LDB_SUCCESS;
1938 }
1939
1940 static int py_module_end_transaction(struct ldb_module *mod)
1941 {
1942         PyObject *py_ldb = (PyObject *)mod->private_data;
1943         PyObject *py_result;
1944
1945         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
1946                                         discard_const_p(char, ""));
1947
1948         if (py_result == NULL) {
1949                 return LDB_ERR_PYTHON_EXCEPTION;
1950         }
1951
1952         Py_DECREF(py_result);
1953
1954         return LDB_SUCCESS;
1955 }
1956
1957 static int py_module_del_transaction(struct ldb_module *mod)
1958 {
1959         PyObject *py_ldb = (PyObject *)mod->private_data;
1960         PyObject *py_result;
1961
1962         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
1963                                         discard_const_p(char, ""));
1964
1965         if (py_result == NULL) {
1966                 return LDB_ERR_PYTHON_EXCEPTION;
1967         }
1968
1969         Py_DECREF(py_result);
1970
1971         return LDB_SUCCESS;
1972 }
1973
1974 static int py_module_destructor(struct ldb_module *mod)
1975 {
1976         Py_DECREF((PyObject *)mod->private_data);
1977         return 0;
1978 }
1979
1980 static int py_module_init(struct ldb_module *mod)
1981 {
1982         PyObject *py_class = (PyObject *)mod->ops->private_data;
1983         PyObject *py_result, *py_next, *py_ldb;
1984
1985         py_ldb = PyLdb_FromLdbContext(mod->ldb);
1986
1987         if (py_ldb == NULL)
1988                 return LDB_ERR_OPERATIONS_ERROR;
1989
1990         py_next = PyLdbModule_FromModule(mod->next);
1991
1992         if (py_next == NULL)
1993                 return LDB_ERR_OPERATIONS_ERROR;
1994
1995         py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
1996                                           py_ldb, py_next);
1997
1998         if (py_result == NULL) {
1999                 return LDB_ERR_PYTHON_EXCEPTION;
2000         }
2001
2002         mod->private_data = py_result;
2003
2004         talloc_set_destructor(mod, py_module_destructor);
2005
2006         return ldb_next_init(mod);
2007 }
2008
2009 static PyObject *py_register_module(PyObject *module, PyObject *args)
2010 {
2011         int ret;
2012         struct ldb_module_ops *ops;
2013         PyObject *input;
2014
2015         if (!PyArg_ParseTuple(args, "O", &input))
2016                 return NULL;
2017
2018         ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
2019         if (ops == NULL) {
2020                 PyErr_NoMemory();
2021                 return NULL;
2022         }
2023
2024         ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
2025
2026         Py_INCREF(input);
2027         ops->private_data = input;
2028         ops->init_context = py_module_init;
2029         ops->search = py_module_search;
2030         ops->add = py_module_add;
2031         ops->modify = py_module_modify;
2032         ops->del = py_module_del;
2033         ops->rename = py_module_rename;
2034         ops->request = py_module_request;
2035         ops->extended = py_module_extended;
2036         ops->start_transaction = py_module_start_transaction;
2037         ops->end_transaction = py_module_end_transaction;
2038         ops->del_transaction = py_module_del_transaction;
2039
2040         ret = ldb_register_module(ops);
2041
2042         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2043
2044         Py_RETURN_NONE;
2045 }
2046
2047 static PyObject *py_timestring(PyObject *module, PyObject *args)
2048 {
2049         time_t t;
2050         char *tresult;
2051         PyObject *ret;
2052         if (!PyArg_ParseTuple(args, "L", &t))
2053                 return NULL;
2054         tresult = ldb_timestring(NULL, t);
2055         ret = PyString_FromString(tresult);
2056         talloc_free(tresult);
2057         return ret;
2058 }
2059
2060 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
2061 {
2062         char *str;
2063         if (!PyArg_ParseTuple(args, "s", &str))
2064                 return NULL;
2065
2066         return PyInt_FromLong(ldb_string_to_time(str));
2067 }
2068
2069 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
2070 {
2071         char *name;
2072         if (!PyArg_ParseTuple(args, "s", &name))
2073                 return NULL;
2074         return PyBool_FromLong(ldb_valid_attr_name(name));
2075 }
2076
2077 static PyMethodDef py_ldb_global_methods[] = {
2078         { "register_module", py_register_module, METH_VARARGS, 
2079                 "S.register_module(module) -> None\n"
2080                 "Register a LDB module."},
2081         { "timestring", py_timestring, METH_VARARGS, 
2082                 "S.timestring(int) -> string\n"
2083                 "Generate a LDAP time string from a UNIX timestamp" },
2084         { "string_to_time", py_string_to_time, METH_VARARGS,
2085                 "S.string_to_time(string) -> int\n"
2086                 "Parse a LDAP time string into a UNIX timestamp." },
2087         { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
2088                 "S.valid_attr_name(name) -> bool\n"
2089                 "Check whether the supplied name is a valid attribute name." },
2090         { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
2091                 NULL },
2092         { NULL }
2093 };
2094
2095 void initldb(void)
2096 {
2097         PyObject *m;
2098
2099         if (PyType_Ready(&PyLdbDn) < 0)
2100                 return;
2101
2102         if (PyType_Ready(&PyLdbMessage) < 0)
2103                 return;
2104
2105         if (PyType_Ready(&PyLdbMessageElement) < 0)
2106                 return;
2107
2108         if (PyType_Ready(&PyLdb) < 0)
2109                 return;
2110
2111         if (PyType_Ready(&PyLdbModule) < 0)
2112                 return;
2113
2114         if (PyType_Ready(&PyLdbTree) < 0)
2115                 return;
2116
2117         m = Py_InitModule3("ldb", py_ldb_global_methods, 
2118                 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
2119         if (m == NULL)
2120                 return;
2121
2122         PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
2123         PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
2124         PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
2125         PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
2126
2127         PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
2128         PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
2129         PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
2130         PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
2131
2132         PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
2133         PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
2134         PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
2135         PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
2136         PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
2137         PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
2138         PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
2139         PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
2140         PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
2141         PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
2142         PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
2143         PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
2144         PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
2145         PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
2146         PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
2147         PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
2148         PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
2149         PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
2150         PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
2151         PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
2152         PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
2153         PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
2154         PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
2155         PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
2156         PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
2157         PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
2158         PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
2159         PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
2160         PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
2161         PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
2162         PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
2163         PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
2164         PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
2165         PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
2166         PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
2167         PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
2168         PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
2169         PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
2170
2171         PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
2172
2173         PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
2174
2175         PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
2176         PyModule_AddObject(m, "LdbError", PyExc_LdbError);
2177
2178         Py_INCREF(&PyLdb);
2179         Py_INCREF(&PyLdbDn);
2180         Py_INCREF(&PyLdbModule);
2181         Py_INCREF(&PyLdbMessage);
2182         Py_INCREF(&PyLdbMessageElement);
2183         Py_INCREF(&PyLdbTree);
2184
2185         PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
2186         PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
2187         PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
2188         PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
2189         PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
2190         PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
2191 }