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