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