25f4661dce13e5132148532356d979de1f76048c
[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-2010 Jelmer Vernooij <jelmer@samba.org>
9    Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10
11          ** NOTE! The following LGPL license applies to the ldb
12          ** library. This does NOT imply that all of Samba is released
13          ** under the LGPL
14
15    This library is free software; you can redistribute it and/or
16    modify it under the terms of the GNU Lesser General Public
17    License as published by the Free Software Foundation; either
18    version 3 of the License, or (at your option) any later version.
19
20    This library is distributed in the hope that it will be useful,
21    but WITHOUT ANY WARRANTY; without even the implied warranty of
22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23    Lesser General Public License for more details.
24
25    You should have received a copy of the GNU Lesser General Public
26    License along with this library; if not, see <http://www.gnu.org/licenses/>.
27 */
28
29 #include <Python.h>
30 #include "replace.h"
31 #include "ldb_private.h"
32 #include "pyldb.h"
33
34 /* There's no Py_ssize_t in 2.4, apparently */
35 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
36 typedef int Py_ssize_t;
37 typedef inquiry lenfunc;
38 typedef intargfunc ssizeargfunc;
39 #endif
40
41 #ifndef Py_RETURN_NONE
42 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
43 #endif
44
45 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
46 {
47         if (ret == LDB_ERR_PYTHON_EXCEPTION)
48                 return; /* Python exception should already be set, just keep that */
49
50         PyErr_SetObject(error, 
51                                         Py_BuildValue(discard_const_p(char, "(i,s)"), ret, 
52                                   ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
53 }
54
55 static PyObject *PyExc_LdbError;
56
57 PyAPI_DATA(PyTypeObject) PyLdbMessage;
58 PyAPI_DATA(PyTypeObject) PyLdbModule;
59 PyAPI_DATA(PyTypeObject) PyLdbDn;
60 PyAPI_DATA(PyTypeObject) PyLdb;
61 PyAPI_DATA(PyTypeObject) PyLdbMessageElement;
62 PyAPI_DATA(PyTypeObject) PyLdbTree;
63
64 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
65
66 static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx, 
67                                                            struct ldb_message_element *el, 
68                                                            struct ldb_val *val)
69 {
70         struct ldb_val new_val;
71         TALLOC_CTX *mem_ctx = talloc_new(NULL);
72         PyObject *ret;
73
74         new_val = *val;
75
76         ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
77
78         talloc_free(mem_ctx);
79
80         return ret;
81 }
82
83 /**
84  * Create a Python object from a ldb_result.
85  *
86  * @param result LDB result to convert
87  * @return Python object with converted result (a list object)
88  */
89 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
90 {
91         PyObject *ret;
92         int i;
93         if (result == NULL) {
94                 Py_RETURN_NONE;
95         } 
96         ret = PyList_New(result->count);
97         for (i = 0; i < result->count; i++) {
98                 PyList_SetItem(ret, i, PyLdbMessage_FromMessage(result->msgs[i])
99                 );
100         }
101         return ret;
102 }
103
104 /**
105  * Create a LDB Result from a Python object. 
106  * If conversion fails, NULL will be returned and a Python exception set.
107  *
108  * @param mem_ctx Memory context in which to allocate the LDB Result
109  * @param obj Python object to convert
110  * @return a ldb_result, or NULL if the conversion failed
111  */
112 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, 
113                                                                                            PyObject *obj)
114 {
115         struct ldb_result *res;
116         int i;
117
118         if (obj == Py_None)
119                 return NULL;
120
121         res = talloc_zero(mem_ctx, struct ldb_result);
122         res->count = PyList_Size(obj);
123         res->msgs = talloc_array(res, struct ldb_message *, res->count);
124         for (i = 0; i < res->count; i++) {
125                 PyObject *item = PyList_GetItem(obj, i);
126                 res->msgs[i] = PyLdbMessage_AsMessage(item);
127         }
128         return res;
129 }
130
131 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
132 {
133         return PyBool_FromLong(ldb_dn_validate(self->dn));
134 }
135
136 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
137 {
138         return PyBool_FromLong(ldb_dn_is_valid(self->dn));
139 }
140
141 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
142 {
143         return PyBool_FromLong(ldb_dn_is_special(self->dn));
144 }
145
146 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
147 {
148         return PyBool_FromLong(ldb_dn_is_null(self->dn));
149 }
150  
151 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
152 {
153         return PyString_FromString(ldb_dn_get_casefold(self->dn));
154 }
155
156 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
157 {
158         return PyString_FromString(ldb_dn_get_linearized(self->dn));
159 }
160
161 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
162 {
163         return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
164 }
165
166 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
167 {
168         return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
169 }
170
171 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
172 {
173         return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
174 }
175
176 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
177 {
178         char *name;
179
180         if (!PyArg_ParseTuple(args, "s", &name))
181                 return NULL;
182
183         return ldb_dn_check_special(self->dn, name)?Py_True:Py_False;
184 }
185
186 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
187 {
188         int ret;
189         ret = ldb_dn_compare(dn1->dn, dn2->dn);
190         if (ret < 0) ret = -1;
191         if (ret > 0) ret = 1;
192         return ret;
193 }
194
195 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
196 {
197         struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self);
198         struct ldb_dn *parent;
199         PyLdbDnObject *py_ret;
200         TALLOC_CTX *mem_ctx = talloc_new(NULL);
201
202         parent = ldb_dn_get_parent(mem_ctx, dn);
203         if (parent == NULL) {
204                 talloc_free(mem_ctx);
205                 Py_RETURN_NONE;
206         }
207
208         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
209         if (py_ret == NULL) {
210                 PyErr_NoMemory();
211                 talloc_free(mem_ctx);
212                 return NULL;
213         }
214         py_ret->mem_ctx = mem_ctx;
215         py_ret->dn = parent;
216         return (PyObject *)py_ret;
217 }
218
219 #define dn_ldb_ctx(dn) ((struct ldb_context *)dn)
220
221 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
222 {
223         PyObject *py_other;
224         struct ldb_dn *dn, *other;
225         if (!PyArg_ParseTuple(args, "O", &py_other))
226                 return NULL;
227
228         dn = PyLdbDn_AsDn((PyObject *)self);
229
230         if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
231                 return NULL;
232
233         return ldb_dn_add_child(dn, other)?Py_True:Py_False;
234 }
235
236 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
237 {
238         PyObject *py_other;
239         struct ldb_dn *other, *dn;
240         if (!PyArg_ParseTuple(args, "O", &py_other))
241                 return NULL;
242
243         dn = PyLdbDn_AsDn((PyObject *)self);
244
245         if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
246                 return NULL;
247
248         return ldb_dn_add_base(dn, other)?Py_True:Py_False;
249 }
250
251 static PyMethodDef py_ldb_dn_methods[] = {
252         { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS, 
253                 "S.validate() -> bool\n"
254                 "Validate DN is correct." },
255         { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
256                 "S.is_valid() -> bool\n" },
257         { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
258                 "S.is_special() -> bool\n"
259                 "Check whether this is a special LDB DN." },
260         { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
261                 "Check whether this is a null DN." },
262         { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
263                 NULL },
264         { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
265                 NULL },
266         { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
267                 "S.canonical_str() -> string\n"
268                 "Canonical version of this DN (like a posix path)." },
269         { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
270                 "S.canonical_ex_str() -> string\n"
271                 "Canonical version of this DN (like a posix path, with terminating newline)." },
272         { "check_special", (PyCFunction)py_ldb_dn_is_special, METH_VARARGS, 
273                 NULL },
274         { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
275                 "S.parent() -> dn\n"
276                 "Get the parent for this DN." },
277         { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS, 
278                 "S.add_child(dn) -> None\n"
279                 "Add a child DN to this DN." },
280         { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
281                 "S.add_base(dn) -> None\n"
282                 "Add a base DN to this DN." },
283         { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
284                 NULL },
285         { NULL }
286 };
287
288 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
289 {
290         return ldb_dn_get_comp_num(PyLdbDn_AsDn((PyObject *)self));
291 }
292
293 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
294 {
295         struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self), 
296                                   *other;
297         PyLdbDnObject *py_ret;
298         
299         if (!PyObject_AsDn(NULL, py_other, NULL, &other))
300                 return NULL;
301
302         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
303         if (py_ret == NULL) {
304                 PyErr_NoMemory();
305                 return NULL;
306         }
307         py_ret->mem_ctx = talloc_new(NULL);
308         py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
309         ldb_dn_add_child(py_ret->dn, other);
310         return (PyObject *)py_ret;
311 }
312
313 static PySequenceMethods py_ldb_dn_seq = {
314         .sq_length = (lenfunc)py_ldb_dn_len,
315         .sq_concat = (binaryfunc)py_ldb_dn_concat,
316 };
317
318 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
319 {
320         struct ldb_dn *ret;
321         char *str;
322         PyObject *py_ldb;
323         struct ldb_context *ldb_ctx;
324         TALLOC_CTX *mem_ctx;
325         PyLdbDnObject *py_ret;
326         const char * const kwnames[] = { "ldb", "dn", NULL };
327
328         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
329                                          discard_const_p(char *, kwnames),
330                                          &py_ldb, &str))
331                 return NULL;
332
333         ldb_ctx = PyLdb_AsLdbContext(py_ldb);
334
335         mem_ctx = talloc_new(NULL);
336         if (mem_ctx == NULL) {
337                 PyErr_NoMemory();
338                 return NULL;
339         }
340
341         ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
342
343         if (ret == NULL || !ldb_dn_validate(ret)) {
344                 talloc_free(mem_ctx);
345                 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
346                 return NULL;
347         }
348
349         py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
350         if (ret == NULL) {
351                 talloc_free(mem_ctx);
352                 PyErr_NoMemory();
353                 return NULL;
354         }
355         py_ret->mem_ctx = mem_ctx;
356         py_ret->dn = ret;
357         return (PyObject *)py_ret;
358 }
359
360 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
361 {
362         talloc_free(self->mem_ctx);
363         self->ob_type->tp_free(self);
364 }
365
366 PyTypeObject PyLdbDn = {
367         .tp_name = "ldb.Dn",
368         .tp_methods = py_ldb_dn_methods,
369         .tp_str = (reprfunc)py_ldb_dn_get_linearized,
370         .tp_repr = (reprfunc)py_ldb_dn_repr,
371         .tp_compare = (cmpfunc)py_ldb_dn_compare,
372         .tp_as_sequence = &py_ldb_dn_seq,
373         .tp_doc = "A LDB distinguished name.",
374         .tp_new = py_ldb_dn_new,
375         .tp_dealloc = (destructor)py_ldb_dn_dealloc,
376         .tp_basicsize = sizeof(PyLdbObject),
377         .tp_flags = Py_TPFLAGS_DEFAULT,
378 };
379
380 /* Debug */
381 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
382 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
383 {
384         PyObject *fn = (PyObject *)context;
385         PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
386 }
387
388 static PyObject *py_ldb_set_debug(PyLdbObject *self, PyObject *args)
389 {
390         PyObject *cb;
391
392         if (!PyArg_ParseTuple(args, "O", &cb))
393                 return NULL;
394
395         Py_INCREF(cb);
396         /* FIXME: Where do we DECREF cb ? */
397         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_set_debug(self->ldb_ctx, py_ldb_debug, cb), PyLdb_AsLdbContext(self));
398
399         Py_RETURN_NONE;
400 }
401
402 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
403 {
404         unsigned int perms;
405         if (!PyArg_ParseTuple(args, "I", &perms))
406                 return NULL;
407
408         ldb_set_create_perms(PyLdb_AsLdbContext(self), perms);
409
410         Py_RETURN_NONE;
411 }
412
413 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
414 {
415         char *modules_dir;
416         if (!PyArg_ParseTuple(args, "s", &modules_dir))
417                 return NULL;
418
419         ldb_set_modules_dir(PyLdb_AsLdbContext(self), modules_dir);
420
421         Py_RETURN_NONE;
422 }
423
424 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
425 {
426         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_start(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
427         Py_RETURN_NONE;
428 }
429
430 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
431 {
432         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
433         Py_RETURN_NONE;
434 }
435
436 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
437 {
438         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_prepare_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
439         Py_RETURN_NONE;
440 }
441
442 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
443 {
444         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_cancel(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
445         Py_RETURN_NONE;
446 }
447
448 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
449 {
450         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_setup_wellknown_attributes(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
451         Py_RETURN_NONE;
452 }
453
454 static PyObject *py_ldb_repr(PyLdbObject *self)
455 {
456         return PyString_FromFormat("<ldb connection>");
457 }
458
459 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
460 {
461         struct ldb_dn *dn = ldb_get_root_basedn(PyLdb_AsLdbContext(self));
462         if (dn == NULL)
463                 Py_RETURN_NONE;
464         return PyLdbDn_FromDn(dn);
465 }
466
467
468 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
469 {
470         struct ldb_dn *dn = ldb_get_schema_basedn(PyLdb_AsLdbContext(self));
471         if (dn == NULL)
472                 Py_RETURN_NONE;
473         return PyLdbDn_FromDn(dn);
474 }
475
476 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
477 {
478         struct ldb_dn *dn = ldb_get_config_basedn(PyLdb_AsLdbContext(self));
479         if (dn == NULL)
480                 Py_RETURN_NONE;
481         return PyLdbDn_FromDn(dn);
482 }
483
484 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
485 {
486         struct ldb_dn *dn = ldb_get_default_basedn(PyLdb_AsLdbContext(self));
487         if (dn == NULL)
488                 Py_RETURN_NONE;
489         return PyLdbDn_FromDn(dn);
490 }
491
492 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list, 
493                                                                                 const char *paramname)
494 {
495         const char **ret;
496         int i;
497         if (!PyList_Check(list)) {
498                 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
499                 return NULL;
500         }
501         ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
502         for (i = 0; i < PyList_Size(list); i++) {
503                 PyObject *item = PyList_GetItem(list, i);
504                 if (!PyString_Check(item)) {
505                         PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
506                         return NULL;
507                 }
508                 ret[i] = talloc_strndup(ret, PyString_AsString(item),
509                                                            PyString_Size(item));
510         }
511         ret[i] = NULL;
512         return ret;
513 }
514
515 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
516 {
517         const char * const kwnames[] = { "url", "flags", "options", NULL };
518         char *url = NULL;
519         PyObject *py_options = Py_None;
520         const char **options;
521         int flags = 0;
522         int ret;
523         struct ldb_context *ldb;
524
525         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ziO:Ldb.__init__",
526                                          discard_const_p(char *, kwnames),
527                                          &url, &flags, &py_options))
528                 return -1;
529
530         ldb = PyLdb_AsLdbContext(self);
531
532         if (py_options == Py_None) {
533                 options = NULL;
534         } else {
535                 options = PyList_AsStringList(ldb, py_options, "options");
536                 if (options == NULL)
537                         return -1;
538         }
539
540         if (url != NULL) {
541                 ret = ldb_connect(ldb, url, flags, options);
542                 if (ret != LDB_SUCCESS) {
543                         PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
544                         return -1;
545                 }
546         }
547
548         talloc_free(options);
549         return 0;
550 }
551
552 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
553 {
554         PyLdbObject *ret;
555         struct ldb_context *ldb;
556         ret = (PyLdbObject *)type->tp_alloc(type, 0);
557         if (ret == NULL) {
558                 PyErr_NoMemory();
559                 return NULL;
560         }
561         ret->mem_ctx = talloc_new(NULL);
562         ldb = ldb_init(ret->mem_ctx, NULL);
563
564         if (ldb == NULL) {
565                 PyErr_NoMemory();
566                 return NULL;
567         }
568
569         ret->ldb_ctx = ldb;
570         return (PyObject *)ret;
571 }
572
573 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
574 {
575         char *url;
576         int flags = 0;
577         PyObject *py_options = Py_None;
578         int ret;
579         const char **options;
580         const char * const kwnames[] = { "url", "flags", "options", NULL };
581
582         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ziO",
583                                          discard_const_p(char *, kwnames),
584                                          &url, &flags, &py_options))
585                 return NULL;
586
587         if (py_options == Py_None) {
588                 options = NULL;
589         } else {
590                 options = PyList_AsStringList(NULL, py_options, "options");
591                 if (options == NULL)
592                         return NULL;
593         }
594
595         ret = ldb_connect(PyLdb_AsLdbContext(self), url, flags, options);
596         talloc_free(options);
597
598         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
599
600         Py_RETURN_NONE;
601 }
602
603 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args)
604 {
605         PyObject *py_msg;
606         PyObject *py_controls = Py_None;
607         struct ldb_context *ldb_ctx;
608         struct ldb_request *req;
609         struct ldb_control **parsed_controls;
610         struct ldb_message *msg;
611         int ret;
612         TALLOC_CTX *mem_ctx;
613
614         if (!PyArg_ParseTuple(args, "O|O", &py_msg, &py_controls))
615                 return NULL;
616
617         mem_ctx = talloc_new(NULL);
618         if (mem_ctx == NULL) {
619                 PyErr_NoMemory();
620                 return NULL;
621         }
622         ldb_ctx = PyLdb_AsLdbContext(self);
623
624         if (py_controls == Py_None) {
625                 parsed_controls = NULL;
626         } else {
627                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
628                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
629                 talloc_free(controls);
630         }
631
632         if (!PyLdbMessage_Check(py_msg)) {
633                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
634                 talloc_free(mem_ctx);
635                 return NULL;
636         }
637         msg = PyLdbMessage_AsMessage(py_msg);
638
639         ret = ldb_msg_sanity_check(ldb_ctx, msg);
640         if (ret != LDB_SUCCESS) {
641                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
642                 talloc_free(mem_ctx);
643                 return NULL;
644         }
645
646         ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
647                                 NULL, ldb_op_default_callback, NULL);
648         if (ret != LDB_SUCCESS) {
649                 PyErr_SetString(PyExc_TypeError, "failed to build request");
650                 talloc_free(mem_ctx);
651                 return NULL;
652         }
653
654         /* do request and autostart a transaction */
655         /* Then let's LDB handle the message error in case of pb as they are meaningful */
656
657         ret = ldb_transaction_start(ldb_ctx);
658         if (ret != LDB_SUCCESS) {
659                 talloc_free(mem_ctx);
660                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
661         }
662
663         ret = ldb_request(ldb_ctx, req);
664         if (ret == LDB_SUCCESS) {
665                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
666         }
667
668         if (ret == LDB_SUCCESS) {
669                 ret = ldb_transaction_commit(ldb_ctx);
670         } else {
671                 ldb_transaction_cancel(ldb_ctx);
672                 if (ldb_ctx->err_string == NULL) {
673                         /* no error string was setup by the backend */
674                         ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
675                 }
676         }
677
678         talloc_free(mem_ctx);
679         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
680
681         Py_RETURN_NONE;
682 }
683
684
685 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args)
686 {
687         PyObject *py_msg;
688         int ret;
689         Py_ssize_t dict_pos, msg_pos;
690         struct ldb_message_element *msgel;
691         struct ldb_message *msg;
692         struct ldb_context *ldb_ctx;
693         struct ldb_request *req;
694         PyObject *key, *value;
695         PyObject *py_controls = Py_None;
696         TALLOC_CTX *mem_ctx;
697         struct ldb_control **parsed_controls;
698
699         if (!PyArg_ParseTuple(args, "O|O", &py_msg, &py_controls ))
700                 return NULL;
701
702         mem_ctx = talloc_new(NULL);
703         if (mem_ctx == NULL) {
704                 PyErr_NoMemory();
705                 return NULL;
706         }
707         ldb_ctx = PyLdb_AsLdbContext(self);
708
709         if (py_controls == Py_None) {
710                 parsed_controls = NULL;
711         } else {
712                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
713                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
714                 talloc_free(controls);
715         }
716         if (PyDict_Check(py_msg)) {
717                 PyObject *dn_value = PyDict_GetItemString(py_msg, "dn");
718                 msg = ldb_msg_new(mem_ctx);
719                 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_msg));
720                 msg_pos = dict_pos = 0;
721                 if (dn_value) {
722                         if (!PyObject_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
723                                 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
724                                 talloc_free(mem_ctx);
725                                 return NULL;
726                         }
727                         if (msg->dn == NULL) {
728                                 PyErr_SetString(PyExc_TypeError, "dn set but not found");
729                                 talloc_free(mem_ctx);
730                                 return NULL;
731                         }
732                 }
733
734                 while (PyDict_Next(py_msg, &dict_pos, &key, &value)) {
735                         char *key_str = PyString_AsString(key);
736                         if (strcmp(key_str, "dn") != 0) {
737                                 msgel = PyObject_AsMessageElement(msg->elements, value, 0, key_str);
738                                 if (msgel == NULL) {
739                                         PyErr_SetString(PyExc_TypeError, "unable to import element");
740                                         talloc_free(mem_ctx);
741                                         return NULL;
742                                 }
743                                 memcpy(&msg->elements[msg_pos], msgel, sizeof(*msgel));
744                                 msg_pos++;
745                         }
746                 }
747
748                 if (msg->dn == NULL) {
749                         PyErr_SetString(PyExc_TypeError, "no dn set");
750                         talloc_free(mem_ctx);
751                         return NULL;
752                 }
753
754                 msg->num_elements = msg_pos;
755         } else {
756                 msg = PyLdbMessage_AsMessage(py_msg);
757         }
758         
759         ret = ldb_msg_sanity_check(ldb_ctx, msg);
760         if (ret != LDB_SUCCESS) {
761                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
762                 talloc_free(mem_ctx);
763                 return NULL;
764         }
765
766         ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
767                                 NULL, ldb_op_default_callback, NULL);
768         if (ret != LDB_SUCCESS) {
769                 PyErr_SetString(PyExc_TypeError, "failed to build request");
770                 talloc_free(mem_ctx);
771                 return NULL;
772         }
773
774         /* do request and autostart a transaction */
775         /* Then let's LDB handle the message error in case of pb as they are meaningful */
776
777         ret = ldb_transaction_start(ldb_ctx);
778         if (ret != LDB_SUCCESS) {
779                 talloc_free(mem_ctx);
780                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
781         }
782
783         ret = ldb_request(ldb_ctx, req);
784         if (ret == LDB_SUCCESS) {
785                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
786         } 
787
788         if (ret == LDB_SUCCESS) {
789                 ret = ldb_transaction_commit(ldb_ctx);
790         } else {
791                 ldb_transaction_cancel(ldb_ctx);
792                 if (ldb_ctx->err_string == NULL) {
793                         /* no error string was setup by the backend */
794                         ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
795                 }
796         }
797
798         talloc_free(mem_ctx);
799         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
800
801         Py_RETURN_NONE;
802 }
803
804 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args)
805 {
806         PyObject *py_dn;
807         struct ldb_dn *dn;
808         int ret;
809         struct ldb_context *ldb_ctx;
810         struct ldb_request *req;
811         PyObject *py_controls = Py_None;
812         TALLOC_CTX *mem_ctx;
813         struct ldb_control **parsed_controls;
814
815         if (!PyArg_ParseTuple(args, "O|O", &py_dn, &py_controls))
816                 return NULL;
817
818         mem_ctx = talloc_new(NULL);
819         if (mem_ctx == NULL) {
820                 PyErr_NoMemory();
821                 return NULL;
822         }
823         ldb_ctx = PyLdb_AsLdbContext(self);
824
825         if (py_controls == Py_None) {
826                 parsed_controls = NULL;
827         } else {
828                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
829                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
830                 talloc_free(controls);
831         }
832
833         if (!PyObject_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
834                 talloc_free(mem_ctx);
835                 return NULL;
836         }
837
838         ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
839                                 NULL, ldb_op_default_callback, NULL);
840         if (ret != LDB_SUCCESS) {
841                 PyErr_SetString(PyExc_TypeError, "failed to build request");
842                 talloc_free(mem_ctx);
843                 return NULL;
844         }
845
846         /* do request and autostart a transaction */
847         /* Then let's LDB handle the message error in case of pb as they are meaningful */
848
849         ret = ldb_transaction_start(ldb_ctx);
850         if (ret != LDB_SUCCESS) {
851                 talloc_free(mem_ctx);
852                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
853         }
854
855         ret = ldb_request(ldb_ctx, req);
856         if (ret == LDB_SUCCESS) {
857                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
858         }
859
860         if (ret == LDB_SUCCESS) {
861                 ret = ldb_transaction_commit(ldb_ctx);
862         } else {
863                 ldb_transaction_cancel(ldb_ctx);
864                 if (ldb_ctx->err_string == NULL) {
865                         /* no error string was setup by the backend */
866                         ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
867                 }
868         }
869
870         talloc_free(mem_ctx);
871         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
872
873         Py_RETURN_NONE;
874 }
875
876 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args)
877 {
878         PyObject *py_dn1, *py_dn2;
879         struct ldb_dn *dn1, *dn2;
880         int ret;
881         struct ldb_context *ldb;
882         TALLOC_CTX *mem_ctx;
883         PyObject *py_controls = Py_None;
884         struct ldb_control **parsed_controls;
885         struct ldb_context *ldb_ctx;
886         struct ldb_request *req;
887
888         ldb_ctx = PyLdb_AsLdbContext(self);
889
890         if (!PyArg_ParseTuple(args, "OO|O", &py_dn1, &py_dn2, &py_controls))
891                 return NULL;
892
893
894         mem_ctx = talloc_new(NULL);
895         if (mem_ctx == NULL) {
896                 PyErr_NoMemory();
897                 return NULL;
898         }
899         ldb = PyLdb_AsLdbContext(self);
900
901         if (py_controls == Py_None) {
902                 parsed_controls = NULL;
903         } else {
904                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
905                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
906                 talloc_free(controls);
907         }
908
909
910         if (!PyObject_AsDn(mem_ctx, py_dn1, ldb, &dn1)) {
911                 talloc_free(mem_ctx);
912                 return NULL;
913         }
914
915         if (!PyObject_AsDn(mem_ctx, py_dn2, ldb, &dn2)) {
916                 talloc_free(mem_ctx);
917                 return NULL;
918         }
919
920         ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
921                                 NULL, ldb_op_default_callback, NULL);
922         if (ret != LDB_SUCCESS) {
923                 PyErr_SetString(PyExc_TypeError, "failed to build request");
924                 talloc_free(mem_ctx);
925                 return NULL;
926         }
927
928         /* do request and autostart a transaction */
929         /* Then let's LDB handle the message error in case of pb as they are meaningful */
930
931         ret = ldb_transaction_start(ldb_ctx);
932         if (ret != LDB_SUCCESS) {
933                 talloc_free(mem_ctx);
934                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
935         }
936
937         ret = ldb_request(ldb_ctx, req);
938         if (ret == LDB_SUCCESS) {
939                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
940         }
941
942         if (ret == LDB_SUCCESS) {
943                 ret = ldb_transaction_commit(ldb_ctx);
944         } else {
945                 ldb_transaction_cancel(ldb_ctx);
946                 if (ldb_ctx->err_string == NULL) {
947                         /* no error string was setup by the backend */
948                         ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
949                 }
950         }
951
952         talloc_free(mem_ctx);
953         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
954
955         Py_RETURN_NONE;
956 }
957
958 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
959 {
960         char *name;
961         if (!PyArg_ParseTuple(args, "s", &name))
962                 return NULL;
963
964         ldb_schema_attribute_remove(PyLdb_AsLdbContext(self), name);
965
966         Py_RETURN_NONE;
967 }
968
969 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
970 {
971         char *attribute, *syntax;
972         unsigned int flags;
973         int ret;
974         if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
975                 return NULL;
976
977         ret = ldb_schema_attribute_add(PyLdb_AsLdbContext(self), attribute, flags, syntax);
978
979         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
980
981         Py_RETURN_NONE;
982 }
983
984 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
985 {
986         if (ldif == NULL) {
987                 Py_RETURN_NONE;
988         } else {
989         /* We don't want this attached to the 'ldb' any more */
990                 return Py_BuildValue(discard_const_p(char, "(iO)"),
991                                      ldif->changetype,
992                                      PyLdbMessage_FromMessage(ldif->msg));
993         }
994 }
995
996
997 static PyObject *py_ldb_write_ldif(PyLdbMessageObject *self, PyObject *args)
998 {
999         int changetype;
1000         PyObject *py_msg;
1001         struct ldb_ldif ldif;
1002         PyObject *ret;
1003         char *string;
1004         TALLOC_CTX *mem_ctx;
1005
1006         if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1007                 return NULL;
1008
1009         if (!PyLdbMessage_Check(py_msg)) {
1010                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1011                 return NULL;
1012         }
1013
1014         ldif.msg = PyLdbMessage_AsMessage(py_msg);
1015         ldif.changetype = changetype;
1016
1017         mem_ctx = talloc_new(NULL);
1018
1019         string = ldb_ldif_write_string(PyLdb_AsLdbContext(self), mem_ctx, &ldif);
1020         if (!string) {
1021                 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1022                 return NULL;
1023         }
1024
1025         ret = PyString_FromString(string);
1026
1027         talloc_free(mem_ctx);
1028
1029         return ret;
1030 }
1031
1032 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1033 {
1034         PyObject *list;
1035         struct ldb_ldif *ldif;
1036         const char *s;
1037
1038         TALLOC_CTX *mem_ctx;
1039
1040         if (!PyArg_ParseTuple(args, "s", &s))
1041                 return NULL;
1042
1043         mem_ctx = talloc_new(NULL);
1044         if (!mem_ctx) {
1045                 Py_RETURN_NONE;
1046         }
1047
1048         list = PyList_New(0);
1049         while (s && *s != '\0') {
1050                 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1051                 talloc_steal(mem_ctx, ldif);
1052                 if (ldif) {
1053                         PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1054                 } else {
1055                         PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1056                         talloc_free(mem_ctx);
1057                         return NULL;
1058                 }
1059         }
1060         talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1061         return PyObject_GetIter(list);
1062 }
1063
1064 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1065 {
1066         int ldb_ret;
1067         PyObject *py_msg_old;
1068         PyObject *py_msg_new;
1069         struct ldb_message *diff;
1070         struct ldb_context *ldb;
1071         PyObject *py_ret;
1072
1073         if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1074                 return NULL;
1075
1076         if (!PyLdbMessage_Check(py_msg_old)) {
1077                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1078                 return NULL;
1079         }
1080
1081         if (!PyLdbMessage_Check(py_msg_new)) {
1082                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1083                 return NULL;
1084         }
1085
1086         ldb = PyLdb_AsLdbContext(self);
1087         ldb_ret = ldb_msg_difference(ldb, ldb,
1088                                      PyLdbMessage_AsMessage(py_msg_old),
1089                                      PyLdbMessage_AsMessage(py_msg_new),
1090                                      &diff);
1091         if (ldb_ret != LDB_SUCCESS) {
1092                 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1093                 return NULL;
1094         }
1095
1096         py_ret = PyLdbMessage_FromMessage(diff);
1097
1098         talloc_unlink(ldb, diff);
1099
1100         return py_ret;
1101 }
1102
1103 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1104 {
1105         const struct ldb_schema_attribute *a;
1106         struct ldb_val old_val;
1107         struct ldb_val new_val;
1108         TALLOC_CTX *mem_ctx;
1109         PyObject *ret;
1110         char *element_name;
1111         PyObject *val;
1112
1113         if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1114                 return NULL;
1115
1116         mem_ctx = talloc_new(NULL);
1117
1118         old_val.data = (uint8_t *)PyString_AsString(val);
1119         old_val.length = PyString_Size(val);
1120
1121         a = ldb_schema_attribute_by_name(PyLdb_AsLdbContext(self), element_name);
1122
1123         if (a == NULL) {
1124                 Py_RETURN_NONE;
1125         }
1126
1127         if (a->syntax->ldif_write_fn(PyLdb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1128                 talloc_free(mem_ctx);
1129                 Py_RETURN_NONE;
1130         }
1131
1132         ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1133
1134         talloc_free(mem_ctx);
1135
1136         return ret;
1137 }
1138
1139 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1140 {
1141         PyObject *py_base = Py_None;
1142         int scope = LDB_SCOPE_DEFAULT;
1143         char *expr = NULL;
1144         PyObject *py_attrs = Py_None;
1145         PyObject *py_controls = Py_None;
1146         const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1147         int ret;
1148         struct ldb_result *res;
1149         struct ldb_request *req;
1150         const char **attrs;
1151         struct ldb_context *ldb_ctx;
1152         struct ldb_control **parsed_controls;
1153         struct ldb_dn *base;
1154         PyObject *py_ret;
1155         TALLOC_CTX *mem_ctx;
1156
1157         /* type "int" rather than "enum" for "scope" is intentional */
1158         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1159                                          discard_const_p(char *, kwnames),
1160                                          &py_base, &scope, &expr, &py_attrs, &py_controls))
1161                 return NULL;
1162
1163
1164         mem_ctx = talloc_new(NULL);
1165         if (mem_ctx == NULL) {
1166                 PyErr_NoMemory();
1167                 return NULL;
1168         }
1169         ldb_ctx = PyLdb_AsLdbContext(self);
1170
1171         if (py_attrs == Py_None) {
1172                 attrs = NULL;
1173         } else {
1174                 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1175                 if (attrs == NULL) {
1176                         talloc_free(mem_ctx);
1177                         return NULL;
1178                 }
1179         }
1180
1181         if (py_base == Py_None) {
1182                 base = ldb_get_default_basedn(ldb_ctx);
1183         } else {
1184                 if (!PyObject_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1185                         talloc_free(attrs);
1186                         return NULL;
1187                 }
1188         }
1189
1190         if (py_controls == Py_None) {
1191                 parsed_controls = NULL;
1192         } else {
1193                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1194                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1195                 talloc_free(controls);
1196         }
1197
1198         res = talloc_zero(mem_ctx, struct ldb_result);
1199         if (res == NULL) {
1200                 PyErr_NoMemory();
1201                 talloc_free(mem_ctx);
1202                 return NULL;
1203         }
1204
1205         ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1206                                    base,
1207                                    scope,
1208                                    expr,
1209                                    attrs,
1210                                    parsed_controls,
1211                                    res,
1212                                    ldb_search_default_callback,
1213                                    NULL);
1214
1215         if (ret != LDB_SUCCESS) {
1216                 talloc_free(mem_ctx);
1217                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1218                 return NULL;
1219         }
1220
1221         talloc_steal(req, attrs);
1222
1223         ret = ldb_request(ldb_ctx, req);
1224
1225         if (ret == LDB_SUCCESS) {
1226                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1227         }
1228
1229         if (ret != LDB_SUCCESS) {
1230                 talloc_free(mem_ctx);
1231                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1232                 return NULL;
1233         }
1234
1235         py_ret = PyLdbResult_FromResult(res);
1236
1237         talloc_free(mem_ctx);
1238
1239         return py_ret;
1240 }
1241
1242 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1243 {
1244         char *name;
1245         void *data;
1246
1247         if (!PyArg_ParseTuple(args, "s", &name))
1248                 return NULL;
1249
1250         data = ldb_get_opaque(PyLdb_AsLdbContext(self), name);
1251
1252         if (data == NULL)
1253                 Py_RETURN_NONE;
1254
1255         /* FIXME: More interpretation */
1256
1257         return Py_True;
1258 }
1259
1260 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1261 {
1262         char *name;
1263         PyObject *data;
1264
1265         if (!PyArg_ParseTuple(args, "sO", &name, &data))
1266                 return NULL;
1267
1268         /* FIXME: More interpretation */
1269
1270         ldb_set_opaque(PyLdb_AsLdbContext(self), name, data);
1271
1272         Py_RETURN_NONE;
1273 }
1274
1275 static PyObject *py_ldb_modules(PyLdbObject *self)
1276 {
1277         struct ldb_context *ldb = PyLdb_AsLdbContext(self);
1278         PyObject *ret = PyList_New(0);
1279         struct ldb_module *mod;
1280
1281         for (mod = ldb->modules; mod; mod = mod->next) {
1282                 PyList_Append(ret, PyLdbModule_FromModule(mod));
1283         }
1284
1285         return ret;
1286 }
1287
1288 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1289 {
1290         struct ldb_context *ldb = PyLdb_AsLdbContext(self);
1291         int type, ret;
1292         uint64_t value;
1293
1294         /* type "int" rather than "enum" for "scope" is intentional */
1295         if (!PyArg_ParseTuple(args, "i", &type))
1296                 return NULL;
1297
1298         /* FIXME: More interpretation */
1299
1300         ret = ldb_sequence_number(ldb, type, &value);
1301
1302         if (ret != LDB_SUCCESS) {
1303                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1304                 return NULL;
1305         }
1306         return PyLong_FromLongLong(value);
1307 }
1308 static PyMethodDef py_ldb_methods[] = {
1309         { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, 
1310                 "S.set_debug(callback) -> None\n"
1311                 "Set callback for LDB debug messages.\n"
1312                 "The callback should accept a debug level and debug text." },
1313         { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS, 
1314                 "S.set_create_perms(mode) -> None\n"
1315                 "Set mode to use when creating new LDB files." },
1316         { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1317                 "S.set_modules_dir(path) -> None\n"
1318                 "Set path LDB should search for modules" },
1319         { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS, 
1320                 "S.transaction_start() -> None\n"
1321                 "Start a new transaction." },
1322         { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1323                 "S.transaction_prepare_commit() -> None\n"
1324                 "prepare to commit a new transaction (2-stage commit)." },
1325         { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, 
1326                 "S.transaction_commit() -> None\n"
1327                 "commit a new transaction." },
1328         { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS, 
1329                 "S.transaction_cancel() -> None\n"
1330                 "cancel a new transaction." },
1331         { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS, 
1332                 NULL },
1333         { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1334                 NULL },
1335         { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1336                 NULL },
1337         { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1338                 NULL },
1339         { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1340                 NULL },
1341         { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS, 
1342                 "S.connect(url, flags=0, options=None) -> None\n"
1343                 "Connect to a LDB URL." },
1344         { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS, 
1345                 "S.modify(message) -> None\n"
1346                 "Modify an entry." },
1347         { "add", (PyCFunction)py_ldb_add, METH_VARARGS, 
1348                 "S.add(message) -> None\n"
1349                 "Add an entry." },
1350         { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS,
1351                 "S.delete(dn) -> None\n"
1352                 "Remove an entry." },
1353         { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS,
1354                 "S.rename(old_dn, new_dn) -> None\n"
1355                 "Rename an entry." },
1356         { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1357                 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1358                 "Search in a database.\n"
1359                 "\n"
1360                 ":param base: Optional base DN to search\n"
1361                 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1362                 ":param expression: Optional search expression\n"
1363                 ":param attrs: Attributes to return (defaults to all)\n"
1364                 ":param controls: Optional list of controls\n"
1365                 ":return: Iterator over Message objects\n"
1366         },
1367         { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1368                 NULL },
1369         { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1370                 NULL },
1371         { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1372                 NULL },
1373         { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1374                 "S.parse_ldif(ldif) -> iter(messages)\n"
1375                 "Parse a string formatted using LDIF." },
1376         { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1377                 "S.write_ldif(message, changetype) -> ldif\n"
1378                 "Print the message as a string formatted using LDIF." },
1379         { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1380                 "S.msg_diff(Message) -> Message\n"
1381                 "Return an LDB Message of the difference between two Message objects." },
1382         { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1383                 "S.get_opaque(name) -> value\n"
1384                 "Get an opaque value set on this LDB connection. \n"
1385                 ":note: The returned value may not be useful in Python."
1386         },
1387         { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1388                 "S.set_opaque(name, value) -> None\n"
1389                 "Set an opaque value on this LDB connection. \n"
1390                 ":note: Passing incorrect values may cause crashes." },
1391         { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1392                 "S.modules() -> list\n"
1393                 "Return the list of modules on this LDB connection " },
1394         { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1395                 "S.sequence_number(type) -> value\n"
1396                 "Return the value of the sequence according to the requested type" },
1397         { NULL },
1398 };
1399
1400 PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1401 {
1402         PyLdbModuleObject *ret;
1403
1404         ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1405         if (ret == NULL) {
1406                 PyErr_NoMemory();
1407                 return NULL;
1408         }
1409         ret->mem_ctx = talloc_new(NULL);
1410         ret->mod = talloc_reference(ret->mem_ctx, mod);
1411         return (PyObject *)ret;
1412 }
1413
1414 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1415 {
1416         return PyLdbModule_FromModule(PyLdb_AsLdbContext(self)->modules);
1417 }
1418
1419 static PyGetSetDef py_ldb_getset[] = {
1420         { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1421         { NULL }
1422 };
1423
1424 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1425 {
1426         struct ldb_context *ldb_ctx = PyLdb_AsLdbContext(self);
1427         struct ldb_dn *dn;
1428         struct ldb_result *result;
1429         int ret;
1430         int count;
1431
1432         if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn))
1433                 return -1;
1434
1435         ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL, NULL);
1436         if (ret != LDB_SUCCESS) {
1437                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1438                 return -1;
1439         }
1440
1441         count = result->count;
1442
1443         talloc_free(result);
1444
1445         return count;
1446 }
1447
1448 static PySequenceMethods py_ldb_seq = {
1449         .sq_contains = (objobjproc)py_ldb_contains,
1450 };
1451
1452 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1453 {
1454         PyLdbObject *ret;
1455
1456         ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1457         if (ret == NULL) {
1458                 PyErr_NoMemory();
1459                 return NULL;
1460         }
1461         ret->mem_ctx = talloc_new(NULL);
1462         ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1463         return (PyObject *)ret;
1464 }
1465
1466 static void py_ldb_dealloc(PyLdbObject *self)
1467 {
1468         talloc_free(self->mem_ctx);
1469         self->ob_type->tp_free(self);
1470 }
1471
1472 PyTypeObject PyLdb = {
1473         .tp_name = "ldb.Ldb",
1474         .tp_methods = py_ldb_methods,
1475         .tp_repr = (reprfunc)py_ldb_repr,
1476         .tp_new = py_ldb_new,
1477         .tp_init = (initproc)py_ldb_init,
1478         .tp_dealloc = (destructor)py_ldb_dealloc,
1479         .tp_getset = py_ldb_getset,
1480         .tp_getattro = PyObject_GenericGetAttr,
1481         .tp_basicsize = sizeof(PyLdbObject),
1482         .tp_doc = "Connection to a LDB database.",
1483         .tp_as_sequence = &py_ldb_seq,
1484         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1485 };
1486
1487 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
1488 {
1489         return PyString_FromFormat("<ldb module '%s'>", PyLdbModule_AsModule(self)->ops->name);
1490 }
1491
1492 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
1493 {
1494         return PyString_FromString(PyLdbModule_AsModule(self)->ops->name);
1495 }
1496
1497 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
1498 {
1499         PyLdbModule_AsModule(self)->ops->start_transaction(PyLdbModule_AsModule(self));
1500         Py_RETURN_NONE;
1501 }
1502
1503 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
1504 {
1505         PyLdbModule_AsModule(self)->ops->end_transaction(PyLdbModule_AsModule(self));
1506         Py_RETURN_NONE;
1507 }
1508
1509 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
1510 {
1511         PyLdbModule_AsModule(self)->ops->del_transaction(PyLdbModule_AsModule(self));
1512         Py_RETURN_NONE;
1513 }
1514
1515 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
1516 {
1517         PyObject *py_base, *py_tree, *py_attrs, *py_ret;
1518         int ret, scope;
1519         struct ldb_request *req;
1520         const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
1521         struct ldb_module *mod;
1522         const char * const*attrs;
1523
1524         /* type "int" rather than "enum" for "scope" is intentional */
1525         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
1526                                          discard_const_p(char *, kwnames),
1527                                          &py_base, &scope, &py_tree, &py_attrs))
1528                 return NULL;
1529
1530         mod = self->mod;
1531
1532         if (py_attrs == Py_None) {
1533                 attrs = NULL;
1534         } else {
1535                 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
1536                 if (attrs == NULL)
1537                         return NULL;
1538         }
1539
1540         ret = ldb_build_search_req(&req, mod->ldb, NULL, PyLdbDn_AsDn(py_base), 
1541                              scope, NULL /* expr */, attrs,
1542                              NULL /* controls */, NULL, NULL, NULL);
1543
1544         talloc_steal(req, attrs);
1545
1546         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1547
1548         req->op.search.res = NULL;
1549
1550         ret = mod->ops->search(mod, req);
1551
1552         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1553
1554         py_ret = PyLdbResult_FromResult(req->op.search.res);
1555
1556         talloc_free(req);
1557
1558         return py_ret;  
1559 }
1560
1561
1562 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
1563 {
1564         struct ldb_request *req;
1565         PyObject *py_message;
1566         int ret;
1567         struct ldb_module *mod;
1568
1569         if (!PyArg_ParseTuple(args, "O", &py_message))
1570                 return NULL;
1571
1572         req = talloc_zero(NULL, struct ldb_request);
1573         req->operation = LDB_ADD;
1574         req->op.add.message = PyLdbMessage_AsMessage(py_message);
1575
1576         mod = PyLdbModule_AsModule(self);
1577         ret = mod->ops->add(mod, req);
1578
1579         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1580
1581         Py_RETURN_NONE;
1582 }
1583
1584 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args) 
1585 {
1586         int ret;
1587         struct ldb_request *req;
1588         PyObject *py_message;
1589         struct ldb_module *mod;
1590
1591         if (!PyArg_ParseTuple(args, "O", &py_message))
1592                 return NULL;
1593
1594         req = talloc_zero(NULL, struct ldb_request);
1595         req->operation = LDB_MODIFY;
1596         req->op.mod.message = PyLdbMessage_AsMessage(py_message);
1597
1598         mod = PyLdbModule_AsModule(self);
1599         ret = mod->ops->modify(mod, req);
1600
1601         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1602
1603         Py_RETURN_NONE;
1604 }
1605
1606 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args) 
1607 {
1608         int ret;
1609         struct ldb_request *req;
1610         PyObject *py_dn;
1611
1612         if (!PyArg_ParseTuple(args, "O", &py_dn))
1613                 return NULL;
1614
1615         req = talloc_zero(NULL, struct ldb_request);
1616         req->operation = LDB_DELETE;
1617         req->op.del.dn = PyLdbDn_AsDn(py_dn);
1618
1619         ret = PyLdbModule_AsModule(self)->ops->del(PyLdbModule_AsModule(self), req);
1620
1621         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
1622
1623         Py_RETURN_NONE;
1624 }
1625
1626 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
1627 {
1628         int ret;
1629         struct ldb_request *req;
1630         PyObject *py_dn1, *py_dn2;
1631
1632         if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
1633                 return NULL;
1634
1635         req = talloc_zero(NULL, struct ldb_request);
1636
1637         req->operation = LDB_RENAME;
1638         req->op.rename.olddn = PyLdbDn_AsDn(py_dn1);
1639         req->op.rename.newdn = PyLdbDn_AsDn(py_dn2);
1640
1641         ret = PyLdbModule_AsModule(self)->ops->rename(PyLdbModule_AsModule(self), req);
1642
1643         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
1644
1645         Py_RETURN_NONE;
1646 }
1647
1648 static PyMethodDef py_ldb_module_methods[] = {
1649         { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
1650         { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
1651         { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
1652         { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
1653         { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
1654         { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
1655         { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
1656         { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
1657         { NULL },
1658 };
1659
1660 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
1661 {
1662         talloc_free(self->mem_ctx);
1663         self->ob_type->tp_free(self);
1664 }
1665
1666 PyTypeObject PyLdbModule = {
1667         .tp_name = "ldb.LdbModule",
1668         .tp_methods = py_ldb_module_methods,
1669         .tp_repr = (reprfunc)py_ldb_module_repr,
1670         .tp_str = (reprfunc)py_ldb_module_str,
1671         .tp_basicsize = sizeof(PyLdbModuleObject),
1672         .tp_dealloc = (destructor)py_ldb_module_dealloc,
1673         .tp_flags = Py_TPFLAGS_DEFAULT,
1674 };
1675
1676
1677 /**
1678  * Create a ldb_message_element from a Python object.
1679  *
1680  * This will accept any sequence objects that contains strings, or 
1681  * a string object.
1682  *
1683  * A reference to set_obj will be borrowed. 
1684  *
1685  * @param mem_ctx Memory context
1686  * @param set_obj Python object to convert
1687  * @param flags ldb_message_element flags to set
1688  * @param attr_name Name of the attribute
1689  * @return New ldb_message_element, allocated as child of mem_ctx
1690  */
1691 struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx,
1692                                                                                            PyObject *set_obj, int flags,
1693                                                                                            const char *attr_name)
1694 {
1695         struct ldb_message_element *me;
1696
1697         if (PyLdbMessageElement_Check(set_obj)) {
1698                 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
1699                 /* We have to talloc_reference() the memory context, not the pointer which may not actually be it's own context */
1700                 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
1701                         return PyLdbMessageElement_AsMessageElement(set_obj);
1702                 }
1703                 return NULL;
1704         }
1705
1706         me = talloc(mem_ctx, struct ldb_message_element);
1707
1708         me->name = talloc_strdup(me, attr_name);
1709         me->flags = flags;
1710         if (PyString_Check(set_obj)) {
1711                 me->num_values = 1;
1712                 me->values = talloc_array(me, struct ldb_val, me->num_values);
1713                 me->values[0].length = PyString_Size(set_obj);
1714                 me->values[0].data = talloc_memdup(me, 
1715                         (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
1716         } else if (PySequence_Check(set_obj)) {
1717                 int i;
1718                 me->num_values = PySequence_Size(set_obj);
1719                 me->values = talloc_array(me, struct ldb_val, me->num_values);
1720                 for (i = 0; i < me->num_values; i++) {
1721                         PyObject *obj = PySequence_GetItem(set_obj, i);
1722                         if (!PyString_Check(obj)) {
1723                                 PyErr_Format(PyExc_TypeError,
1724                                              "Expected string as element %d in list", i);
1725                                 talloc_free(me);
1726                                 return NULL;
1727                         }
1728
1729                         me->values[i].length = PyString_Size(obj);
1730                         me->values[i].data = talloc_memdup(me, 
1731                                 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
1732                 }
1733         } else {
1734                 talloc_free(me);
1735                 me = NULL;
1736         }
1737
1738         return me;
1739 }
1740
1741
1742 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, 
1743                                                                  struct ldb_message_element *me)
1744 {
1745         int i;
1746         PyObject *result;
1747
1748         /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
1749         result = PyList_New(me->num_values);
1750
1751         for (i = 0; i < me->num_values; i++) {
1752                 PyList_SetItem(result, i,
1753                         PyObject_FromLdbValue(ldb_ctx, me, &me->values[i]));
1754         }
1755
1756         return result;
1757 }
1758
1759 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
1760 {
1761         int i;
1762         if (!PyArg_ParseTuple(args, "i", &i))
1763                 return NULL;
1764         if (i < 0 || i >= PyLdbMessageElement_AsMessageElement(self)->num_values)
1765                 Py_RETURN_NONE;
1766
1767         return PyObject_FromLdbValue(NULL, PyLdbMessageElement_AsMessageElement(self), 
1768                                                                  &(PyLdbMessageElement_AsMessageElement(self)->values[i]));
1769 }
1770
1771 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
1772 {
1773         struct ldb_message_element *el;
1774
1775         el = PyLdbMessageElement_AsMessageElement(self);
1776         return PyInt_FromLong(el->flags);
1777 }
1778
1779 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
1780 {
1781         int flags;
1782         struct ldb_message_element *el;
1783         if (!PyArg_ParseTuple(args, "i", &flags))
1784                 return NULL;
1785
1786         el = PyLdbMessageElement_AsMessageElement(self);
1787         el->flags = flags;
1788         Py_RETURN_NONE;
1789 }
1790
1791 static PyMethodDef py_ldb_msg_element_methods[] = {
1792         { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
1793         { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
1794         { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
1795         { NULL },
1796 };
1797
1798 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
1799 {
1800         return PyLdbMessageElement_AsMessageElement(self)->num_values;
1801 }
1802
1803 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
1804 {
1805         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1806         if (idx < 0 || idx >= el->num_values) {
1807                 PyErr_SetString(PyExc_IndexError, "Out of range");
1808                 return NULL;
1809         }
1810         return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
1811 }
1812
1813 static PySequenceMethods py_ldb_msg_element_seq = {
1814         .sq_length = (lenfunc)py_ldb_msg_element_len,
1815         .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
1816 };
1817
1818 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
1819 {
1820         return ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self), 
1821                                                                    PyLdbMessageElement_AsMessageElement(other));
1822 }
1823
1824 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
1825 {
1826         return PyObject_GetIter(ldb_msg_element_to_set(NULL, PyLdbMessageElement_AsMessageElement(self)));
1827 }
1828
1829 PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
1830 {
1831         PyLdbMessageElementObject *ret;
1832         ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
1833         if (ret == NULL) {
1834                 PyErr_NoMemory();
1835                 return NULL;
1836         }
1837         ret->mem_ctx = talloc_new(NULL);
1838         if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
1839                 PyErr_NoMemory();
1840                 return NULL;
1841         }
1842         ret->el = el;
1843         return (PyObject *)ret;
1844 }
1845
1846 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1847 {
1848         PyObject *py_elements = NULL;
1849         struct ldb_message_element *el;
1850         int flags = 0;
1851         char *name = NULL;
1852         const char * const kwnames[] = { "elements", "flags", "name", NULL };
1853         PyLdbMessageElementObject *ret;
1854         TALLOC_CTX *mem_ctx;
1855
1856         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Ois",
1857                                          discard_const_p(char *, kwnames),
1858                                          &py_elements, &flags, &name))
1859                 return NULL;
1860
1861         mem_ctx = talloc_new(NULL);
1862         if (mem_ctx == NULL) {
1863                 PyErr_NoMemory();
1864                 return NULL;
1865         }
1866
1867         el = talloc_zero(mem_ctx, struct ldb_message_element);
1868
1869         if (py_elements != NULL) {
1870                 int i;
1871                 if (PyString_Check(py_elements)) {
1872                         el->num_values = 1;
1873                         el->values = talloc_array(el, struct ldb_val, 1);
1874                         el->values[0].length = PyString_Size(py_elements);
1875                         el->values[0].data = talloc_memdup(el, 
1876                                 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
1877                 } else if (PySequence_Check(py_elements)) {
1878                         el->num_values = PySequence_Size(py_elements);
1879                         el->values = talloc_array(el, struct ldb_val, el->num_values);
1880                         for (i = 0; i < el->num_values; i++) {
1881                                 PyObject *item = PySequence_GetItem(py_elements, i);
1882                                 if (!PyString_Check(item)) {
1883                                         PyErr_Format(PyExc_TypeError, 
1884                                                         "Expected string as element %d in list", 
1885                                                         i);
1886                                         talloc_free(mem_ctx);
1887                                         return NULL;
1888                                 }
1889                                 el->values[i].length = PyString_Size(item);
1890                                 el->values[i].data = talloc_memdup(el, 
1891                                         (uint8_t *)PyString_AsString(item), el->values[i].length+1);
1892                         }
1893                 } else {
1894                         PyErr_SetString(PyExc_TypeError, 
1895                                         "Expected string or list");
1896                         talloc_free(mem_ctx);
1897                         return NULL;
1898                 }
1899         }
1900
1901         el->flags = flags;
1902         el->name = talloc_strdup(el, name);
1903
1904         ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
1905         if (ret == NULL) {
1906                 PyErr_NoMemory();
1907                 talloc_free(mem_ctx);
1908                 return NULL;
1909         }
1910
1911         ret->mem_ctx = mem_ctx;
1912         ret->el = el;
1913         return (PyObject *)ret;
1914 }
1915
1916 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
1917 {
1918         char *element_str = NULL;
1919         int i;
1920         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1921         PyObject *ret;
1922
1923         for (i = 0; i < el->num_values; i++) {
1924                 PyObject *o = py_ldb_msg_element_find(self, i);
1925                 if (element_str == NULL)
1926                         element_str = talloc_strdup(NULL, PyObject_REPR(o));
1927                 else
1928                         element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
1929         }
1930
1931         if (element_str != NULL) {
1932                 ret = PyString_FromFormat("MessageElement([%s])", element_str);
1933                 talloc_free(element_str);
1934         } else {
1935                 ret = PyString_FromString("MessageElement([])");
1936         }
1937
1938         return ret;
1939 }
1940
1941 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
1942 {
1943         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1944
1945         if (el->num_values == 1)
1946                 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
1947         else 
1948                 Py_RETURN_NONE;
1949 }
1950
1951 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
1952 {
1953         talloc_free(self->mem_ctx);
1954         self->ob_type->tp_free(self);
1955 }
1956
1957 PyTypeObject PyLdbMessageElement = {
1958         .tp_name = "ldb.MessageElement",
1959         .tp_basicsize = sizeof(PyLdbMessageElementObject),
1960         .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
1961         .tp_repr = (reprfunc)py_ldb_msg_element_repr,
1962         .tp_str = (reprfunc)py_ldb_msg_element_str,
1963         .tp_methods = py_ldb_msg_element_methods,
1964         .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
1965         .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
1966         .tp_as_sequence = &py_ldb_msg_element_seq,
1967         .tp_new = py_ldb_msg_element_new,
1968         .tp_flags = Py_TPFLAGS_DEFAULT,
1969 };
1970
1971 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
1972 {
1973         char *name;
1974         if (!PyArg_ParseTuple(args, "s", &name))
1975                 return NULL;
1976
1977         ldb_msg_remove_attr(self->msg, name);
1978
1979         Py_RETURN_NONE;
1980 }
1981
1982 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
1983 {
1984         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1985         int i, j = 0;
1986         PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
1987         if (msg->dn != NULL) {
1988                 PyList_SetItem(obj, j, PyString_FromString("dn"));
1989                 j++;
1990         }
1991         for (i = 0; i < msg->num_elements; i++) {
1992                 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
1993                 j++;
1994         }
1995         return obj;
1996 }
1997
1998 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
1999 {
2000         struct ldb_message_element *el;
2001         char *name;
2002         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2003         if (!PyString_Check(py_name)) {
2004                 PyErr_SetNone(PyExc_TypeError);
2005                 return NULL;
2006         }
2007         name = PyString_AsString(py_name);
2008         if (!strcmp(name, "dn"))
2009                 return PyLdbDn_FromDn(msg->dn);
2010         el = ldb_msg_find_element(msg, name);
2011         if (el == NULL) {
2012                 return NULL;
2013         }
2014         return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2015 }
2016
2017 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2018 {
2019         PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2020         if (ret == NULL) {
2021                 PyErr_SetString(PyExc_KeyError, "No such element");
2022                 return NULL;
2023         }
2024         return ret;
2025 }
2026
2027 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args)
2028 {
2029         PyObject *name, *ret;
2030         if (!PyArg_ParseTuple(args, "O", &name))
2031                 return NULL;
2032
2033         ret = py_ldb_msg_getitem_helper(self, name);
2034         if (ret == NULL) {
2035                 if (PyErr_Occurred())
2036                         return NULL;
2037                 Py_RETURN_NONE;
2038         }
2039         return ret;
2040 }
2041
2042 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2043 {
2044         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2045         int i, j;
2046         PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2047         j = 0;
2048         if (msg->dn != NULL) {
2049                 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", PyLdbDn_FromDn(msg->dn)));
2050                 j++;
2051         }
2052         for (i = 0; i < msg->num_elements; i++, j++) {
2053                 PyList_SetItem(l, j, Py_BuildValue("(sO)", msg->elements[i].name, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements)));
2054         }
2055         return l;
2056 }
2057
2058 static PyMethodDef py_ldb_msg_methods[] = { 
2059         { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, NULL },
2060         { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, NULL },
2061         { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS, NULL },
2062         { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2063         { NULL },
2064 };
2065
2066 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2067 {
2068         PyObject *list, *iter;
2069
2070         list = py_ldb_msg_keys(self);
2071         iter = PyObject_GetIter(list);
2072         Py_DECREF(list);
2073         return iter;
2074 }
2075
2076 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2077 {
2078         char *attr_name;
2079
2080         if (!PyString_Check(name)) {
2081                 PyErr_SetNone(PyExc_TypeError);
2082                 return -1;
2083         }
2084         
2085         attr_name = PyString_AsString(name);
2086         if (value == NULL) {
2087                 /* delitem */
2088                 ldb_msg_remove_attr(self->msg, attr_name);
2089         } else {
2090                 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2091                                                                            value, 0, attr_name);
2092                 if (el == NULL)
2093                         return -1;
2094                 ldb_msg_remove_attr(PyLdbMessage_AsMessage(self), attr_name);
2095                 ldb_msg_add(PyLdbMessage_AsMessage(self), el, el->flags);
2096         }
2097         return 0;
2098 }
2099
2100 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2101 {
2102         return PyLdbMessage_AsMessage(self)->num_elements;
2103 }
2104
2105 static PyMappingMethods py_ldb_msg_mapping = {
2106         .mp_length = (lenfunc)py_ldb_msg_length,
2107         .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2108         .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2109 };
2110
2111 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2112 {
2113         const char * const kwnames[] = { "dn", NULL };
2114         struct ldb_message *ret;
2115         TALLOC_CTX *mem_ctx;
2116         PyObject *pydn = NULL;
2117         PyLdbMessageObject *py_ret;
2118
2119         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2120                                          discard_const_p(char *, kwnames),
2121                                          &pydn))
2122                 return NULL;
2123
2124         mem_ctx = talloc_new(NULL);
2125         if (mem_ctx == NULL) {
2126                 PyErr_NoMemory();
2127                 return NULL;
2128         }
2129
2130         ret = ldb_msg_new(mem_ctx);
2131         if (ret == NULL) {
2132                 talloc_free(mem_ctx);
2133                 PyErr_NoMemory();
2134                 return NULL;
2135         }
2136
2137         if (pydn != NULL) {
2138                 struct ldb_dn *dn;
2139                 if (!PyObject_AsDn(NULL, pydn, NULL, &dn)) {
2140                         talloc_free(mem_ctx);
2141                         return NULL;
2142                 }
2143                 ret->dn = talloc_reference(ret, dn);
2144         }
2145
2146         py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2147         if (py_ret == NULL) {
2148                 PyErr_NoMemory();
2149                 talloc_free(mem_ctx);
2150                 return NULL;
2151         }
2152
2153         py_ret->mem_ctx = mem_ctx;
2154         py_ret->msg = ret;
2155         return (PyObject *)py_ret;
2156 }
2157
2158 PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2159 {
2160         PyLdbMessageObject *ret;
2161
2162         ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2163         if (ret == NULL) {
2164                 PyErr_NoMemory();
2165                 return NULL;
2166         }
2167         ret->mem_ctx = talloc_new(NULL);
2168         ret->msg = talloc_reference(ret->mem_ctx, msg);
2169         return (PyObject *)ret;
2170 }
2171
2172 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2173 {
2174         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2175         return PyLdbDn_FromDn(msg->dn);
2176 }
2177
2178 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2179 {
2180         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2181         if (!PyLdbDn_Check(value)) {
2182                 PyErr_SetNone(PyExc_TypeError);
2183                 return -1;
2184         }
2185
2186         msg->dn = talloc_reference(msg, PyLdbDn_AsDn(value));
2187         return 0;
2188 }
2189
2190 static PyGetSetDef py_ldb_msg_getset[] = {
2191         { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2192         { NULL }
2193 };
2194
2195 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2196 {
2197         PyObject *dict = PyDict_New(), *ret;
2198         if (PyDict_Update(dict, (PyObject *)self) != 0)
2199                 return NULL;
2200         ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2201         Py_DECREF(dict);
2202         return ret;
2203 }
2204
2205 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2206 {
2207         talloc_free(self->mem_ctx);
2208         self->ob_type->tp_free(self);
2209 }
2210
2211 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2212                               PyLdbMessageObject *py_msg2)
2213 {
2214         struct ldb_message *msg1 = PyLdbMessage_AsMessage(py_msg1),
2215                            *msg2 = PyLdbMessage_AsMessage(py_msg2);
2216         unsigned int i;
2217         int ret;
2218
2219         if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
2220                 ret = ldb_dn_compare(msg1->dn, msg2->dn);
2221                 if (ret != 0) {
2222                         return ret;
2223                 }
2224         }
2225
2226         ret = msg1->num_elements - msg2->num_elements;
2227         if (ret != 0) {
2228                 return ret;
2229         }
2230
2231         for (i = 0; i < msg1->num_elements; i++) {
2232                 ret = ldb_msg_element_compare_name(&msg1->elements[i],
2233                                                    &msg2->elements[i]);
2234                 if (ret != 0) {
2235                         return ret;
2236                 }
2237
2238                 ret = ldb_msg_element_compare(&msg1->elements[i],
2239                                               &msg2->elements[i]);
2240                 if (ret != 0) {
2241                         return ret;
2242                 }
2243         }
2244
2245         return 0;
2246 }
2247
2248 PyTypeObject PyLdbMessage = {
2249         .tp_name = "ldb.Message",
2250         .tp_methods = py_ldb_msg_methods,
2251         .tp_getset = py_ldb_msg_getset,
2252         .tp_as_mapping = &py_ldb_msg_mapping,
2253         .tp_basicsize = sizeof(PyLdbMessageObject),
2254         .tp_dealloc = (destructor)py_ldb_msg_dealloc,
2255         .tp_new = py_ldb_msg_new,
2256         .tp_repr = (reprfunc)py_ldb_msg_repr,
2257         .tp_flags = Py_TPFLAGS_DEFAULT,
2258         .tp_iter = (getiterfunc)py_ldb_msg_iter,
2259         .tp_compare = (cmpfunc)py_ldb_msg_compare,
2260 };
2261
2262 PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
2263 {
2264         PyLdbTreeObject *ret;
2265
2266         ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
2267         if (ret == NULL) {
2268                 PyErr_NoMemory();
2269                 return NULL;
2270         }
2271
2272         ret->mem_ctx = talloc_new(NULL);
2273         ret->tree = talloc_reference(ret->mem_ctx, tree);
2274         return (PyObject *)ret;
2275 }
2276
2277 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
2278 {
2279         talloc_free(self->mem_ctx);
2280         self->ob_type->tp_free(self);
2281 }
2282
2283 PyTypeObject PyLdbTree = {
2284         .tp_name = "ldb.Tree",
2285         .tp_basicsize = sizeof(PyLdbTreeObject),
2286         .tp_dealloc = (destructor)py_ldb_tree_dealloc,
2287         .tp_flags = Py_TPFLAGS_DEFAULT,
2288 };
2289
2290 /* Ldb_module */
2291 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
2292 {
2293         PyObject *py_ldb = (PyObject *)mod->private_data;
2294         PyObject *py_result, *py_base, *py_attrs, *py_tree;
2295
2296         py_base = PyLdbDn_FromDn(req->op.search.base);
2297
2298         if (py_base == NULL)
2299                 return LDB_ERR_OPERATIONS_ERROR;
2300
2301         py_tree = PyLdbTree_FromTree(req->op.search.tree);
2302
2303         if (py_tree == NULL)
2304                 return LDB_ERR_OPERATIONS_ERROR;
2305
2306         if (req->op.search.attrs == NULL) {
2307                 py_attrs = Py_None;
2308         } else {
2309                 int i, len;
2310                 for (len = 0; req->op.search.attrs[len]; len++);
2311                 py_attrs = PyList_New(len);
2312                 for (i = 0; i < len; i++)
2313                         PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
2314         }
2315
2316         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
2317                                         discard_const_p(char, "OiOO"),
2318                                         py_base, req->op.search.scope, py_tree, py_attrs);
2319
2320         Py_DECREF(py_attrs);
2321         Py_DECREF(py_tree);
2322         Py_DECREF(py_base);
2323
2324         if (py_result == NULL) {
2325                 return LDB_ERR_PYTHON_EXCEPTION;
2326         }
2327
2328         req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
2329         if (req->op.search.res == NULL) {
2330                 return LDB_ERR_PYTHON_EXCEPTION;
2331         }
2332
2333         Py_DECREF(py_result);
2334
2335         return LDB_SUCCESS;
2336 }
2337
2338 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
2339 {
2340         PyObject *py_ldb = (PyObject *)mod->private_data;
2341         PyObject *py_result, *py_msg;
2342
2343         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
2344
2345         if (py_msg == NULL) {
2346                 return LDB_ERR_OPERATIONS_ERROR;
2347         }
2348
2349         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
2350                                         discard_const_p(char, "O"),
2351                                         py_msg);
2352
2353         Py_DECREF(py_msg);
2354
2355         if (py_result == NULL) {
2356                 return LDB_ERR_PYTHON_EXCEPTION;
2357         }
2358
2359         Py_DECREF(py_result);
2360
2361         return LDB_SUCCESS;
2362 }
2363
2364 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
2365 {
2366         PyObject *py_ldb = (PyObject *)mod->private_data;
2367         PyObject *py_result, *py_msg;
2368
2369         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
2370
2371         if (py_msg == NULL) {
2372                 return LDB_ERR_OPERATIONS_ERROR;
2373         }
2374
2375         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
2376                                         discard_const_p(char, "O"),
2377                                         py_msg);
2378
2379         Py_DECREF(py_msg);
2380
2381         if (py_result == NULL) {
2382                 return LDB_ERR_PYTHON_EXCEPTION;
2383         }
2384
2385         Py_DECREF(py_result);
2386
2387         return LDB_SUCCESS;
2388 }
2389
2390 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
2391 {
2392         PyObject *py_ldb = (PyObject *)mod->private_data;
2393         PyObject *py_result, *py_dn;
2394
2395         py_dn = PyLdbDn_FromDn(req->op.del.dn);
2396
2397         if (py_dn == NULL)
2398                 return LDB_ERR_OPERATIONS_ERROR;
2399
2400         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
2401                                         discard_const_p(char, "O"),
2402                                         py_dn);
2403
2404         if (py_result == NULL) {
2405                 return LDB_ERR_PYTHON_EXCEPTION;
2406         }
2407
2408         Py_DECREF(py_result);
2409
2410         return LDB_SUCCESS;
2411 }
2412
2413 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
2414 {
2415         PyObject *py_ldb = (PyObject *)mod->private_data;
2416         PyObject *py_result, *py_olddn, *py_newdn;
2417
2418         py_olddn = PyLdbDn_FromDn(req->op.rename.olddn);
2419
2420         if (py_olddn == NULL)
2421                 return LDB_ERR_OPERATIONS_ERROR;
2422
2423         py_newdn = PyLdbDn_FromDn(req->op.rename.newdn);
2424
2425         if (py_newdn == NULL)
2426                 return LDB_ERR_OPERATIONS_ERROR;
2427
2428         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
2429                                         discard_const_p(char, "OO"),
2430                                         py_olddn, py_newdn);
2431
2432         Py_DECREF(py_olddn);
2433         Py_DECREF(py_newdn);
2434
2435         if (py_result == NULL) {
2436                 return LDB_ERR_PYTHON_EXCEPTION;
2437         }
2438
2439         Py_DECREF(py_result);
2440
2441         return LDB_SUCCESS;
2442 }
2443
2444 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
2445 {
2446         PyObject *py_ldb = (PyObject *)mod->private_data;
2447         PyObject *py_result;
2448
2449         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
2450                                         discard_const_p(char, ""));
2451
2452         return LDB_ERR_OPERATIONS_ERROR;
2453 }
2454
2455 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
2456 {
2457         PyObject *py_ldb = (PyObject *)mod->private_data;
2458         PyObject *py_result;
2459
2460         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
2461                                         discard_const_p(char, ""));
2462
2463         return LDB_ERR_OPERATIONS_ERROR;
2464 }
2465
2466 static int py_module_start_transaction(struct ldb_module *mod)
2467 {
2468         PyObject *py_ldb = (PyObject *)mod->private_data;
2469         PyObject *py_result;
2470
2471         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
2472                                         discard_const_p(char, ""));
2473
2474         if (py_result == NULL) {
2475                 return LDB_ERR_PYTHON_EXCEPTION;
2476         }
2477
2478         Py_DECREF(py_result);
2479
2480         return LDB_SUCCESS;
2481 }
2482
2483 static int py_module_end_transaction(struct ldb_module *mod)
2484 {
2485         PyObject *py_ldb = (PyObject *)mod->private_data;
2486         PyObject *py_result;
2487
2488         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
2489                                         discard_const_p(char, ""));
2490
2491         if (py_result == NULL) {
2492                 return LDB_ERR_PYTHON_EXCEPTION;
2493         }
2494
2495         Py_DECREF(py_result);
2496
2497         return LDB_SUCCESS;
2498 }
2499
2500 static int py_module_del_transaction(struct ldb_module *mod)
2501 {
2502         PyObject *py_ldb = (PyObject *)mod->private_data;
2503         PyObject *py_result;
2504
2505         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
2506                                         discard_const_p(char, ""));
2507
2508         if (py_result == NULL) {
2509                 return LDB_ERR_PYTHON_EXCEPTION;
2510         }
2511
2512         Py_DECREF(py_result);
2513
2514         return LDB_SUCCESS;
2515 }
2516
2517 static int py_module_destructor(struct ldb_module *mod)
2518 {
2519         Py_DECREF((PyObject *)mod->private_data);
2520         return 0;
2521 }
2522
2523 static int py_module_init(struct ldb_module *mod)
2524 {
2525         PyObject *py_class = (PyObject *)mod->ops->private_data;
2526         PyObject *py_result, *py_next, *py_ldb;
2527
2528         py_ldb = PyLdb_FromLdbContext(mod->ldb);
2529
2530         if (py_ldb == NULL)
2531                 return LDB_ERR_OPERATIONS_ERROR;
2532
2533         py_next = PyLdbModule_FromModule(mod->next);
2534
2535         if (py_next == NULL)
2536                 return LDB_ERR_OPERATIONS_ERROR;
2537
2538         py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
2539                                           py_ldb, py_next);
2540
2541         if (py_result == NULL) {
2542                 return LDB_ERR_PYTHON_EXCEPTION;
2543         }
2544
2545         mod->private_data = py_result;
2546
2547         talloc_set_destructor(mod, py_module_destructor);
2548
2549         return ldb_next_init(mod);
2550 }
2551
2552 static PyObject *py_register_module(PyObject *module, PyObject *args)
2553 {
2554         int ret;
2555         struct ldb_module_ops *ops;
2556         PyObject *input;
2557
2558         if (!PyArg_ParseTuple(args, "O", &input))
2559                 return NULL;
2560
2561         ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
2562         if (ops == NULL) {
2563                 PyErr_NoMemory();
2564                 return NULL;
2565         }
2566
2567         ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
2568
2569         Py_INCREF(input);
2570         ops->private_data = input;
2571         ops->init_context = py_module_init;
2572         ops->search = py_module_search;
2573         ops->add = py_module_add;
2574         ops->modify = py_module_modify;
2575         ops->del = py_module_del;
2576         ops->rename = py_module_rename;
2577         ops->request = py_module_request;
2578         ops->extended = py_module_extended;
2579         ops->start_transaction = py_module_start_transaction;
2580         ops->end_transaction = py_module_end_transaction;
2581         ops->del_transaction = py_module_del_transaction;
2582
2583         ret = ldb_register_module(ops);
2584
2585         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2586
2587         Py_RETURN_NONE;
2588 }
2589
2590 static PyObject *py_timestring(PyObject *module, PyObject *args)
2591 {
2592         time_t t;
2593         unsigned long val;
2594         char *tresult;
2595         PyObject *ret;
2596         if (!PyArg_ParseTuple(args, "l", &val))
2597                 return NULL;
2598         t = (time_t)val;
2599         tresult = ldb_timestring(NULL, t);
2600         ret = PyString_FromString(tresult);
2601         talloc_free(tresult);
2602         return ret;
2603 }
2604
2605 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
2606 {
2607         char *str;
2608         if (!PyArg_ParseTuple(args, "s", &str))
2609                 return NULL;
2610
2611         return PyInt_FromLong(ldb_string_to_time(str));
2612 }
2613
2614 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
2615 {
2616         char *name;
2617         if (!PyArg_ParseTuple(args, "s", &name))
2618                 return NULL;
2619         return PyBool_FromLong(ldb_valid_attr_name(name));
2620 }
2621
2622 static PyMethodDef py_ldb_global_methods[] = {
2623         { "register_module", py_register_module, METH_VARARGS, 
2624                 "S.register_module(module) -> None\n"
2625                 "Register a LDB module."},
2626         { "timestring", py_timestring, METH_VARARGS, 
2627                 "S.timestring(int) -> string\n"
2628                 "Generate a LDAP time string from a UNIX timestamp" },
2629         { "string_to_time", py_string_to_time, METH_VARARGS,
2630                 "S.string_to_time(string) -> int\n"
2631                 "Parse a LDAP time string into a UNIX timestamp." },
2632         { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
2633                 "S.valid_attr_name(name) -> bool\n"
2634                 "Check whether the supplied name is a valid attribute name." },
2635         { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
2636                 NULL },
2637         { NULL }
2638 };
2639
2640 void initldb(void)
2641 {
2642         PyObject *m;
2643
2644         if (PyType_Ready(&PyLdbDn) < 0)
2645                 return;
2646
2647         if (PyType_Ready(&PyLdbMessage) < 0)
2648                 return;
2649
2650         if (PyType_Ready(&PyLdbMessageElement) < 0)
2651                 return;
2652
2653         if (PyType_Ready(&PyLdb) < 0)
2654                 return;
2655
2656         if (PyType_Ready(&PyLdbModule) < 0)
2657                 return;
2658
2659         if (PyType_Ready(&PyLdbTree) < 0)
2660                 return;
2661
2662         m = Py_InitModule3("ldb", py_ldb_global_methods, 
2663                 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
2664         if (m == NULL)
2665                 return;
2666
2667         PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
2668         PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
2669         PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
2670         PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
2671         PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
2672         PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
2673         PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
2674
2675         PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
2676         PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
2677         PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
2678         PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
2679
2680         PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
2681         PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
2682         PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
2683
2684         PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
2685         PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
2686         PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
2687         PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
2688         PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
2689         PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
2690         PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
2691         PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
2692         PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
2693         PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
2694         PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
2695         PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
2696         PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
2697         PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
2698         PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
2699         PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
2700         PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
2701         PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
2702         PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
2703         PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
2704         PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
2705         PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
2706         PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
2707         PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
2708         PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
2709         PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
2710         PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
2711         PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
2712         PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
2713         PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
2714         PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
2715         PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
2716         PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
2717         PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
2718         PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
2719         PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
2720         PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
2721         PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
2722         PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
2723
2724         PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
2725         PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
2726         PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
2727         PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
2728
2729         PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
2730
2731         PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
2732         PyModule_AddObject(m, "LdbError", PyExc_LdbError);
2733
2734         Py_INCREF(&PyLdb);
2735         Py_INCREF(&PyLdbDn);
2736         Py_INCREF(&PyLdbModule);
2737         Py_INCREF(&PyLdbMessage);
2738         Py_INCREF(&PyLdbMessageElement);
2739         Py_INCREF(&PyLdbTree);
2740
2741         PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
2742         PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
2743         PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
2744         PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
2745         PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
2746         PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
2747 }