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