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