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