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