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