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