1bcdaabe13efc7dcf92014a739133e8ccfed17c9
[metze/samba/wip.git] / source4 / lib / ldb / pyldb.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Python 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-2010 Jelmer Vernooij <jelmer@samba.org>
9    Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10
11     ** NOTE! The following LGPL license applies to the ldb
12     ** library. This does NOT imply that all of Samba is released
13     ** under the LGPL
14
15    This library is free software; you can redistribute it and/or
16    modify it under the terms of the GNU Lesser General Public
17    License as published by the Free Software Foundation; either
18    version 3 of the License, or (at your option) any later version.
19
20    This library is distributed in the hope that it will be useful,
21    but WITHOUT ANY WARRANTY; without even the implied warranty of
22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23    Lesser General Public License for more details.
24
25    You should have received a copy of the GNU Lesser General Public
26    License along with this library; if not, see <http://www.gnu.org/licenses/>.
27 */
28
29 #include <Python.h>
30 #include <pytalloc.h>
31 #include "ldb_private.h"
32 #include "pyldb.h"
33
34 void initldb(void);
35 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
36 static PyObject *PyExc_LdbError;
37
38 staticforward PyTypeObject PyLdbControl;
39 staticforward PyTypeObject PyLdbResult;
40 staticforward PyTypeObject PyLdbMessage;
41 staticforward PyTypeObject PyLdbModule;
42 staticforward PyTypeObject PyLdbDn;
43 staticforward PyTypeObject PyLdb;
44 staticforward PyTypeObject PyLdbMessageElement;
45 staticforward PyTypeObject PyLdbTree;
46 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
47 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
48 static struct ldb_message_element *PyObject_AsMessageElement(
49                                                       TALLOC_CTX *mem_ctx,
50                                                       PyObject *set_obj,
51                                                       unsigned int flags,
52                                                       const char *attr_name);
53
54 /* There's no Py_ssize_t in 2.4, apparently */
55 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
56 typedef int Py_ssize_t;
57 typedef inquiry lenfunc;
58 typedef intargfunc ssizeargfunc;
59 #endif
60
61 #ifndef Py_RETURN_NONE
62 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
63 #endif
64
65 #define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1))
66
67
68
69 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
70 {
71         if (self->data != NULL) {
72                 char* control = ldb_control_to_string(self->mem_ctx, self->data);
73                 if (control == NULL) {
74                         PyErr_NoMemory();
75                         return NULL;
76                 }
77                 return PyString_FromString(control);
78         } else {
79                 return PyString_FromFormat("ldb control");
80         }
81 }
82
83 static void py_ldb_control_dealloc(PyLdbControlObject *self)
84 {
85         if (self->mem_ctx != NULL) {
86                 talloc_free(self->mem_ctx);
87         }
88         self->data = NULL;
89         self->ob_type->tp_free(self);
90 }
91
92 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
93 {
94         return PyString_FromString(self->data->oid);
95 }
96
97 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
98 {
99         return PyBool_FromLong(self->data->critical);
100 }
101
102 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
103 {
104         if (PyObject_IsTrue(value)) {
105                 self->data->critical = true;
106         } else {
107                 self->data->critical = false;
108         }
109         return 0;
110 }
111
112 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
113 {
114         char *data = NULL;
115         const char * const kwnames[] = { "ldb", "data", NULL };
116         struct ldb_control *parsed_controls;
117         PyLdbControlObject *ret;
118         PyObject *py_ldb;
119         TALLOC_CTX *mem_ctx;
120         struct ldb_context *ldb_ctx;
121
122         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
123                                          discard_const_p(char *, kwnames),
124                                          &py_ldb, &data))
125                 return NULL;
126
127         mem_ctx = talloc_new(NULL);
128         if (mem_ctx == NULL) {
129                 PyErr_NoMemory();
130                 return NULL;
131         }
132
133         ldb_ctx = PyLdb_AsLdbContext(py_ldb);
134         parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
135
136         if (!parsed_controls) {
137                 talloc_free(mem_ctx);
138                 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
139                 return NULL;
140         }
141
142         ret = PyObject_New(PyLdbControlObject, type);
143         if (ret == NULL) {
144                 PyErr_NoMemory();
145                 talloc_free(mem_ctx);
146                 return NULL;
147         }
148
149         ret->mem_ctx = mem_ctx;
150
151         ret->data = talloc_move(mem_ctx, &parsed_controls);
152         if (ret->data == NULL) {
153                 Py_DECREF(ret);
154                 PyErr_NoMemory();
155                 talloc_free(mem_ctx);
156                 return NULL;
157         }
158
159         return (PyObject *)ret;
160 }
161
162 static PyGetSetDef py_ldb_control_getset[] = {
163         { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
164         { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
165         { NULL }
166 };
167
168 static PyTypeObject PyLdbControl = {
169         .tp_name = "ldb.control",
170         .tp_dealloc = (destructor)py_ldb_control_dealloc,
171         .tp_getattro = PyObject_GenericGetAttr,
172         .tp_basicsize = sizeof(PyLdbControlObject),
173         .tp_getset = py_ldb_control_getset,
174         .tp_doc = "LDB control.",
175         .tp_str = (reprfunc)py_ldb_control_str,
176         .tp_new = py_ldb_control_new,
177         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
178 };
179
180 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
181 {
182         if (ret == LDB_ERR_PYTHON_EXCEPTION)
183                 return; /* Python exception should already be set, just keep that */
184
185         PyErr_SetObject(error, 
186                         Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
187                                       ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
188 }
189
190 static PyObject *PyObject_FromLdbValue(struct ldb_val *val)
191 {
192         return PyString_FromStringAndSize((const char *)val->data, val->length);
193 }
194
195 /**
196  * Create a Python object from a ldb_result.
197  *
198  * @param result LDB result to convert
199  * @return Python object with converted result (a list object)
200  */
201 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
202 {
203         TALLOC_CTX *ctl_ctx = talloc_new(NULL);
204         PyLdbControlObject *ctrl;
205         if (ctl_ctx == NULL) {
206                 PyErr_NoMemory();
207                 return NULL;
208         }
209
210         ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
211         if (ctrl == NULL) {
212                 talloc_free(ctl_ctx);
213                 PyErr_NoMemory();
214                 return NULL;
215         }
216         ctrl->mem_ctx = ctl_ctx;
217         ctrl->data = talloc_steal(ctrl->mem_ctx, control);
218         if (ctrl->data == NULL) {
219                 Py_DECREF(ctrl);
220                 PyErr_NoMemory();
221                 return NULL;
222         }
223         return (PyObject*) ctrl;
224 }
225
226 /**
227  * Create a Python object from a ldb_result.
228  *
229  * @param result LDB result to convert
230  * @return Python object with converted result (a list object)
231  */
232 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
233 {
234         PyLdbResultObject *ret;
235         PyObject *list, *controls, *referals;
236         Py_ssize_t i;
237
238         if (result == NULL) {
239                 Py_RETURN_NONE;
240         }
241
242         ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
243         if (ret == NULL) {
244                 PyErr_NoMemory();
245                 return NULL;
246         }
247
248         list = PyList_New(result->count);
249         if (list == NULL) {
250                 PyErr_NoMemory();
251                 Py_DECREF(ret);
252                 return NULL;
253         }
254
255         for (i = 0; i < result->count; i++) {
256                 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
257         }
258
259         ret->mem_ctx = talloc_new(NULL);
260         if (ret->mem_ctx == NULL) {
261                 Py_DECREF(list);
262                 Py_DECREF(ret);
263                 PyErr_NoMemory();
264                 return NULL;
265         }
266
267         ret->msgs = list;
268
269         if (result->controls) {
270                 controls = PyList_New(1);
271                 if (controls == NULL) {
272                         Py_DECREF(ret);
273                         PyErr_NoMemory();
274                         return NULL;
275                 }
276                 for (i=0; result->controls[i]; i++) {
277                         PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
278                         if (ctrl == NULL) {
279                                 Py_DECREF(ret);
280                                 Py_DECREF(controls);
281                                 PyErr_NoMemory();
282                                 return NULL;
283                         }
284                         PyList_SetItem(controls, i, ctrl);
285                 }
286         } else {
287                 /*
288                  * No controls so we keep an empty list
289                  */
290                 controls = PyList_New(0);
291                 if (controls == NULL) {
292                         Py_DECREF(ret);
293                         PyErr_NoMemory();
294                         return NULL;
295                 }
296         }
297
298         ret->controls = controls;
299
300         i = 0;
301
302         while (result->refs && result->refs[i]) {
303                 i++;
304         }
305
306         referals = PyList_New(i);
307         if (referals == NULL) {
308                 Py_DECREF(ret);
309                 PyErr_NoMemory();
310                 return NULL;
311         }
312
313         for (i = 0;result->refs && result->refs[i]; i++) {
314                 PyList_SetItem(referals, i, PyString_FromString(result->refs[i]));
315         }
316         ret->referals = referals;
317         return (PyObject *)ret;
318 }
319
320 /**
321  * Create a LDB Result from a Python object. 
322  * If conversion fails, NULL will be returned and a Python exception set.
323  *
324  * @param mem_ctx Memory context in which to allocate the LDB Result
325  * @param obj Python object to convert
326  * @return a ldb_result, or NULL if the conversion failed
327  */
328 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, 
329                                                PyObject *obj)
330 {
331         struct ldb_result *res;
332         Py_ssize_t i;
333
334         if (obj == Py_None)
335                 return NULL;
336
337         res = talloc_zero(mem_ctx, struct ldb_result);
338         res->count = PyList_Size(obj);
339         res->msgs = talloc_array(res, struct ldb_message *, res->count);
340         for (i = 0; i < res->count; i++) {
341                 PyObject *item = PyList_GetItem(obj, i);
342                 res->msgs[i] = PyLdbMessage_AsMessage(item);
343         }
344         return res;
345 }
346
347 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
348 {
349         return PyBool_FromLong(ldb_dn_validate(self->dn));
350 }
351
352 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
353 {
354         return PyBool_FromLong(ldb_dn_is_valid(self->dn));
355 }
356
357 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
358 {
359         return PyBool_FromLong(ldb_dn_is_special(self->dn));
360 }
361
362 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
363 {
364         return PyBool_FromLong(ldb_dn_is_null(self->dn));
365 }
366  
367 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
368 {
369         return PyString_FromString(ldb_dn_get_casefold(self->dn));
370 }
371
372 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
373 {
374         return PyString_FromString(ldb_dn_get_linearized(self->dn));
375 }
376
377 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
378 {
379         return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
380 }
381
382 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
383 {
384         return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
385 }
386
387 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
388 {
389         return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
390 }
391
392 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
393 {
394         char *name;
395
396         if (!PyArg_ParseTuple(args, "s", &name))
397                 return NULL;
398
399         return ldb_dn_check_special(self->dn, name)?Py_True:Py_False;
400 }
401
402 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
403 {
404         int ret;
405         ret = ldb_dn_compare(dn1->dn, dn2->dn);
406         if (ret < 0) ret = -1;
407         if (ret > 0) ret = 1;
408         return ret;
409 }
410
411 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
412 {
413         struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self);
414         struct ldb_dn *parent;
415         PyLdbDnObject *py_ret;
416         TALLOC_CTX *mem_ctx = talloc_new(NULL);
417
418         parent = ldb_dn_get_parent(mem_ctx, dn);
419         if (parent == NULL) {
420                 talloc_free(mem_ctx);
421                 Py_RETURN_NONE;
422         }
423
424         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
425         if (py_ret == NULL) {
426                 PyErr_NoMemory();
427                 talloc_free(mem_ctx);
428                 return NULL;
429         }
430         py_ret->mem_ctx = mem_ctx;
431         py_ret->dn = parent;
432         return (PyObject *)py_ret;
433 }
434
435 #define dn_ldb_ctx(dn) ((struct ldb_context *)dn)
436
437 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
438 {
439         PyObject *py_other;
440         struct ldb_dn *dn, *other;
441         if (!PyArg_ParseTuple(args, "O", &py_other))
442                 return NULL;
443
444         dn = PyLdbDn_AsDn((PyObject *)self);
445
446         if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
447                 return NULL;
448
449         return ldb_dn_add_child(dn, other)?Py_True:Py_False;
450 }
451
452 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
453 {
454         PyObject *py_other;
455         struct ldb_dn *other, *dn;
456         if (!PyArg_ParseTuple(args, "O", &py_other))
457                 return NULL;
458
459         dn = PyLdbDn_AsDn((PyObject *)self);
460
461         if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
462                 return NULL;
463
464         return ldb_dn_add_base(dn, other)?Py_True:Py_False;
465 }
466
467 static PyMethodDef py_ldb_dn_methods[] = {
468         { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS, 
469                 "S.validate() -> bool\n"
470                 "Validate DN is correct." },
471         { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
472                 "S.is_valid() -> bool\n" },
473         { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
474                 "S.is_special() -> bool\n"
475                 "Check whether this is a special LDB DN." },
476         { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
477                 "Check whether this is a null DN." },
478         { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
479                 NULL },
480         { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
481                 NULL },
482         { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
483                 "S.canonical_str() -> string\n"
484                 "Canonical version of this DN (like a posix path)." },
485         { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
486                 "S.canonical_ex_str() -> string\n"
487                 "Canonical version of this DN (like a posix path, with terminating newline)." },
488         { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
489                 "S.parent() -> dn\n"
490                 "Get the parent for this DN." },
491         { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS, 
492                 "S.add_child(dn) -> None\n"
493                 "Add a child DN to this DN." },
494         { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
495                 "S.add_base(dn) -> None\n"
496                 "Add a base DN to this DN." },
497         { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
498                 "S.check_special(name) -> bool\n\n"
499                 "Check if name is a special DN name"},
500         { NULL }
501 };
502
503 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
504 {
505         return ldb_dn_get_comp_num(PyLdbDn_AsDn((PyObject *)self));
506 }
507
508 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
509 {
510         struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self), 
511                                   *other;
512         PyLdbDnObject *py_ret;
513         
514         if (!PyObject_AsDn(NULL, py_other, NULL, &other))
515                 return NULL;
516
517         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
518         if (py_ret == NULL) {
519                 PyErr_NoMemory();
520                 return NULL;
521         }
522         py_ret->mem_ctx = talloc_new(NULL);
523         py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
524         ldb_dn_add_child(py_ret->dn, other);
525         return (PyObject *)py_ret;
526 }
527
528 static PySequenceMethods py_ldb_dn_seq = {
529         .sq_length = (lenfunc)py_ldb_dn_len,
530         .sq_concat = (binaryfunc)py_ldb_dn_concat,
531 };
532
533 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
534 {
535         struct ldb_dn *ret;
536         char *str;
537         PyObject *py_ldb;
538         struct ldb_context *ldb_ctx;
539         TALLOC_CTX *mem_ctx;
540         PyLdbDnObject *py_ret;
541         const char * const kwnames[] = { "ldb", "dn", NULL };
542
543         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
544                                          discard_const_p(char *, kwnames),
545                                          &py_ldb, &str))
546                 return NULL;
547
548         ldb_ctx = PyLdb_AsLdbContext(py_ldb);
549
550         mem_ctx = talloc_new(NULL);
551         if (mem_ctx == NULL) {
552                 PyErr_NoMemory();
553                 return NULL;
554         }
555
556         ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
557         if (!ldb_dn_validate(ret)) {
558                 talloc_free(mem_ctx);
559                 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
560                 return NULL;
561         }
562
563         py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
564         if (ret == NULL) {
565                 talloc_free(mem_ctx);
566                 PyErr_NoMemory();
567                 return NULL;
568         }
569         py_ret->mem_ctx = mem_ctx;
570         py_ret->dn = ret;
571         return (PyObject *)py_ret;
572 }
573
574 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
575 {
576         talloc_free(self->mem_ctx);
577         PyObject_Del(self);
578 }
579
580 static PyTypeObject PyLdbDn = {
581         .tp_name = "ldb.Dn",
582         .tp_methods = py_ldb_dn_methods,
583         .tp_str = (reprfunc)py_ldb_dn_get_linearized,
584         .tp_repr = (reprfunc)py_ldb_dn_repr,
585         .tp_compare = (cmpfunc)py_ldb_dn_compare,
586         .tp_as_sequence = &py_ldb_dn_seq,
587         .tp_doc = "A LDB distinguished name.",
588         .tp_new = py_ldb_dn_new,
589         .tp_dealloc = (destructor)py_ldb_dn_dealloc,
590         .tp_basicsize = sizeof(PyLdbDnObject),
591         .tp_flags = Py_TPFLAGS_DEFAULT,
592 };
593
594 /* Debug */
595 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
596 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
597 {
598         PyObject *fn = (PyObject *)context;
599         PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
600 }
601
602 static PyObject *py_ldb_set_debug(PyLdbObject *self, PyObject *args)
603 {
604         PyObject *cb;
605
606         if (!PyArg_ParseTuple(args, "O", &cb))
607                 return NULL;
608
609         Py_INCREF(cb);
610         /* FIXME: Where do we DECREF cb ? */
611         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_set_debug(self->ldb_ctx, py_ldb_debug, cb), PyLdb_AsLdbContext(self));
612
613         Py_RETURN_NONE;
614 }
615
616 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
617 {
618         unsigned int perms;
619         if (!PyArg_ParseTuple(args, "I", &perms))
620                 return NULL;
621
622         ldb_set_create_perms(PyLdb_AsLdbContext(self), perms);
623
624         Py_RETURN_NONE;
625 }
626
627 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
628 {
629         char *modules_dir;
630         if (!PyArg_ParseTuple(args, "s", &modules_dir))
631                 return NULL;
632
633         ldb_set_modules_dir(PyLdb_AsLdbContext(self), modules_dir);
634
635         Py_RETURN_NONE;
636 }
637
638 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
639 {
640         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_start(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
641         Py_RETURN_NONE;
642 }
643
644 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
645 {
646         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
647         Py_RETURN_NONE;
648 }
649
650 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
651 {
652         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_prepare_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
653         Py_RETURN_NONE;
654 }
655
656 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
657 {
658         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_cancel(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
659         Py_RETURN_NONE;
660 }
661
662 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
663 {
664         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_setup_wellknown_attributes(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
665         Py_RETURN_NONE;
666 }
667
668 static PyObject *py_ldb_repr(PyLdbObject *self)
669 {
670         return PyString_FromFormat("<ldb connection>");
671 }
672
673 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
674 {
675         struct ldb_dn *dn = ldb_get_root_basedn(PyLdb_AsLdbContext(self));
676         if (dn == NULL)
677                 Py_RETURN_NONE;
678         return PyLdbDn_FromDn(dn);
679 }
680
681
682 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
683 {
684         struct ldb_dn *dn = ldb_get_schema_basedn(PyLdb_AsLdbContext(self));
685         if (dn == NULL)
686                 Py_RETURN_NONE;
687         return PyLdbDn_FromDn(dn);
688 }
689
690 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
691 {
692         struct ldb_dn *dn = ldb_get_config_basedn(PyLdb_AsLdbContext(self));
693         if (dn == NULL)
694                 Py_RETURN_NONE;
695         return PyLdbDn_FromDn(dn);
696 }
697
698 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
699 {
700         struct ldb_dn *dn = ldb_get_default_basedn(PyLdb_AsLdbContext(self));
701         if (dn == NULL)
702                 Py_RETURN_NONE;
703         return PyLdbDn_FromDn(dn);
704 }
705
706 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list, 
707                                         const char *paramname)
708 {
709         const char **ret;
710         Py_ssize_t i;
711         if (!PyList_Check(list)) {
712                 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
713                 return NULL;
714         }
715         ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
716         if (ret == NULL) {
717                 PyErr_NoMemory();
718                 return NULL;
719         }
720
721         for (i = 0; i < PyList_Size(list); i++) {
722                 PyObject *item = PyList_GetItem(list, i);
723                 if (!PyString_Check(item)) {
724                         PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
725                         return NULL;
726                 }
727                 ret[i] = talloc_strndup(ret, PyString_AsString(item),
728                                         PyString_Size(item));
729         }
730         ret[i] = NULL;
731         return ret;
732 }
733
734 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
735 {
736         const char * const kwnames[] = { "url", "flags", "options", NULL };
737         char *url = NULL;
738         PyObject *py_options = Py_None;
739         const char **options;
740         unsigned int flags = 0;
741         int ret;
742         struct ldb_context *ldb;
743
744         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
745                                          discard_const_p(char *, kwnames),
746                                          &url, &flags, &py_options))
747                 return -1;
748
749         ldb = PyLdb_AsLdbContext(self);
750
751         if (py_options == Py_None) {
752                 options = NULL;
753         } else {
754                 options = PyList_AsStringList(ldb, py_options, "options");
755                 if (options == NULL)
756                         return -1;
757         }
758
759         if (url != NULL) {
760                 ret = ldb_connect(ldb, url, flags, options);
761                 if (ret != LDB_SUCCESS) {
762                         PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
763                         return -1;
764                 }
765         }
766
767         talloc_free(options);
768         return 0;
769 }
770
771 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
772 {
773         PyLdbObject *ret;
774         struct ldb_context *ldb;
775         ret = (PyLdbObject *)type->tp_alloc(type, 0);
776         if (ret == NULL) {
777                 PyErr_NoMemory();
778                 return NULL;
779         }
780         ret->mem_ctx = talloc_new(NULL);
781         ldb = ldb_init(ret->mem_ctx, NULL);
782
783         if (ldb == NULL) {
784                 PyErr_NoMemory();
785                 return NULL;
786         }
787
788         ret->ldb_ctx = ldb;
789         return (PyObject *)ret;
790 }
791
792 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
793 {
794         char *url;
795         unsigned int flags = 0;
796         PyObject *py_options = Py_None;
797         int ret;
798         const char **options;
799         const char * const kwnames[] = { "url", "flags", "options", NULL };
800
801         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
802                                          discard_const_p(char *, kwnames),
803                                          &url, &flags, &py_options))
804                 return NULL;
805
806         if (py_options == Py_None) {
807                 options = NULL;
808         } else {
809                 options = PyList_AsStringList(NULL, py_options, "options");
810                 if (options == NULL)
811                         return NULL;
812         }
813
814         ret = ldb_connect(PyLdb_AsLdbContext(self), url, flags, options);
815         talloc_free(options);
816
817         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
818
819         Py_RETURN_NONE;
820 }
821
822 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
823 {
824         PyObject *py_msg;
825         PyObject *py_controls = Py_None;
826         struct ldb_context *ldb_ctx;
827         struct ldb_request *req;
828         struct ldb_control **parsed_controls;
829         struct ldb_message *msg;
830         int ret;
831         TALLOC_CTX *mem_ctx;
832         bool validate=true;
833         const char * const kwnames[] = { "message", "controls", "validate", NULL };
834
835         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
836                                          discard_const_p(char *, kwnames),
837                                          &py_msg, &py_controls, &validate))
838                 return NULL;
839
840         mem_ctx = talloc_new(NULL);
841         if (mem_ctx == NULL) {
842                 PyErr_NoMemory();
843                 return NULL;
844         }
845         ldb_ctx = PyLdb_AsLdbContext(self);
846
847         if (py_controls == Py_None) {
848                 parsed_controls = NULL;
849         } else {
850                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
851                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
852                 talloc_free(controls);
853         }
854
855         if (!PyLdbMessage_Check(py_msg)) {
856                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
857                 talloc_free(mem_ctx);
858                 return NULL;
859         }
860         msg = PyLdbMessage_AsMessage(py_msg);
861
862         if (validate) {
863                 ret = ldb_msg_sanity_check(ldb_ctx, msg);
864                 if (ret != LDB_SUCCESS) {
865                         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
866                         talloc_free(mem_ctx);
867                         return NULL;
868                 }
869         }
870
871         ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
872                                 NULL, ldb_op_default_callback, NULL);
873         if (ret != LDB_SUCCESS) {
874                 PyErr_SetString(PyExc_TypeError, "failed to build request");
875                 talloc_free(mem_ctx);
876                 return NULL;
877         }
878
879         /* do request and autostart a transaction */
880         /* Then let's LDB handle the message error in case of pb as they are meaningful */
881
882         ret = ldb_transaction_start(ldb_ctx);
883         if (ret != LDB_SUCCESS) {
884                 talloc_free(mem_ctx);
885                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
886         }
887
888         ret = ldb_request(ldb_ctx, req);
889         if (ret == LDB_SUCCESS) {
890                         ret = ldb_wait(req->handle, LDB_WAIT_ALL);
891         }
892
893         if (ret == LDB_SUCCESS) {
894                 ret = ldb_transaction_commit(ldb_ctx);
895         } else {
896                 ldb_transaction_cancel(ldb_ctx);
897                 if (ldb_ctx->err_string == NULL) {
898                         /* no error string was setup by the backend */
899                         ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
900                 }
901         }
902
903         talloc_free(mem_ctx);
904         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
905
906         Py_RETURN_NONE;
907 }
908
909
910 /**
911  * Obtain a ldb message from a Python Dictionary object.
912  *
913  * @param mem_ctx Memory context
914  * @param py_obj Python Dictionary object
915  * @param ldb_ctx LDB context
916  * @param mod_flags Flags to be set on every message element
917  * @return ldb_message on success or NULL on failure
918  */
919 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
920                                             PyObject *py_obj,
921                                             struct ldb_context *ldb_ctx,
922                                             unsigned int mod_flags)
923 {
924         struct ldb_message *msg;
925         unsigned int msg_pos = 0;
926         Py_ssize_t dict_pos = 0;
927         PyObject *key, *value;
928         struct ldb_message_element *msg_el;
929         PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
930
931         msg = ldb_msg_new(mem_ctx);
932         msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
933
934         if (dn_value) {
935                 if (!PyObject_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
936                         PyErr_SetString(PyExc_TypeError, "unable to import dn object");
937                         return NULL;
938                 }
939                 if (msg->dn == NULL) {
940                         PyErr_SetString(PyExc_TypeError, "dn set but not found");
941                         return NULL;
942                 }
943         } else {
944                 PyErr_SetString(PyExc_TypeError, "no dn set");
945                 return NULL;
946         }
947
948         while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
949                 char *key_str = PyString_AsString(key);
950                 if (strcmp(key_str, "dn") != 0) {
951                         msg_el = PyObject_AsMessageElement(msg->elements, value,
952                                                            mod_flags, key_str);
953                         if (msg_el == NULL) {
954                                 PyErr_SetString(PyExc_TypeError, "unable to import element");
955                                 return NULL;
956                         }
957                         memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
958                         msg_pos++;
959                 }
960         }
961
962         msg->num_elements = msg_pos;
963
964         return msg;
965 }
966
967 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
968 {
969         PyObject *py_obj;
970         int ret;
971         struct ldb_context *ldb_ctx;
972         struct ldb_request *req;
973         struct ldb_message *msg = NULL;
974         PyObject *py_controls = Py_None;
975         TALLOC_CTX *mem_ctx;
976         struct ldb_control **parsed_controls;
977         const char * const kwnames[] = { "message", "controls", NULL };
978
979         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
980                                          discard_const_p(char *, kwnames),
981                                          &py_obj, &py_controls))
982                 return NULL;
983
984         mem_ctx = talloc_new(NULL);
985         if (mem_ctx == NULL) {
986                 PyErr_NoMemory();
987                 return NULL;
988         }
989         ldb_ctx = PyLdb_AsLdbContext(self);
990
991         if (py_controls == Py_None) {
992                 parsed_controls = NULL;
993         } else {
994                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
995                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
996                 talloc_free(controls);
997         }
998
999         if (PyLdbMessage_Check(py_obj)) {
1000                 msg = PyLdbMessage_AsMessage(py_obj);
1001         } else if (PyDict_Check(py_obj)) {
1002                 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1003         } else {
1004                 PyErr_SetString(PyExc_TypeError,
1005                                 "Dictionary or LdbMessage object expected!");
1006         }
1007
1008         if (!msg) {
1009                 /* we should have a PyErr already set */
1010                 talloc_free(mem_ctx);
1011                 return NULL;
1012         }
1013
1014         ret = ldb_msg_sanity_check(ldb_ctx, msg);
1015         if (ret != LDB_SUCCESS) {
1016                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1017                 talloc_free(mem_ctx);
1018                 return NULL;
1019         }
1020
1021         ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1022                                 NULL, ldb_op_default_callback, NULL);
1023         if (ret != LDB_SUCCESS) {
1024                 PyErr_SetString(PyExc_TypeError, "failed to build request");
1025                 talloc_free(mem_ctx);
1026                 return NULL;
1027         }
1028
1029         /* do request and autostart a transaction */
1030         /* Then let's LDB handle the message error in case of pb as they are meaningful */
1031
1032         ret = ldb_transaction_start(ldb_ctx);
1033         if (ret != LDB_SUCCESS) {
1034                 talloc_free(mem_ctx);
1035                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1036         }
1037
1038         ret = ldb_request(ldb_ctx, req);
1039         if (ret == LDB_SUCCESS) {
1040                         ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1041         } 
1042
1043         if (ret == LDB_SUCCESS) {
1044                         ret = ldb_transaction_commit(ldb_ctx);
1045         } else {
1046                 ldb_transaction_cancel(ldb_ctx);
1047                 if (ldb_ctx->err_string == NULL) {
1048                         /* no error string was setup by the backend */
1049                         ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
1050                 }
1051         }
1052
1053         talloc_free(mem_ctx);
1054         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1055
1056         Py_RETURN_NONE;
1057 }
1058
1059 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1060 {
1061         PyObject *py_dn;
1062         struct ldb_dn *dn;
1063         int ret;
1064         struct ldb_context *ldb_ctx;
1065         struct ldb_request *req;
1066         PyObject *py_controls = Py_None;
1067         TALLOC_CTX *mem_ctx;
1068         struct ldb_control **parsed_controls;
1069         const char * const kwnames[] = { "dn", "controls", NULL };
1070
1071         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1072                                          discard_const_p(char *, kwnames),
1073                                          &py_dn, &py_controls))
1074                 return NULL;
1075
1076         mem_ctx = talloc_new(NULL);
1077         if (mem_ctx == NULL) {
1078                 PyErr_NoMemory();
1079                 return NULL;
1080         }
1081         ldb_ctx = PyLdb_AsLdbContext(self);
1082
1083         if (py_controls == Py_None) {
1084                 parsed_controls = NULL;
1085         } else {
1086                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1087                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1088                 talloc_free(controls);
1089         }
1090
1091         if (!PyObject_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1092                 talloc_free(mem_ctx);
1093                 return NULL;
1094         }
1095
1096         ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1097                                 NULL, ldb_op_default_callback, NULL);
1098         if (ret != LDB_SUCCESS) {
1099                 PyErr_SetString(PyExc_TypeError, "failed to build request");
1100                 talloc_free(mem_ctx);
1101                 return NULL;
1102         }
1103
1104         /* do request and autostart a transaction */
1105         /* Then let's LDB handle the message error in case of pb as they are meaningful */
1106
1107         ret = ldb_transaction_start(ldb_ctx);
1108         if (ret != LDB_SUCCESS) {
1109                 talloc_free(mem_ctx);
1110                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1111         }
1112
1113         ret = ldb_request(ldb_ctx, req);
1114         if (ret == LDB_SUCCESS) {
1115                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1116         }
1117
1118         if (ret == LDB_SUCCESS) {
1119                 ret = ldb_transaction_commit(ldb_ctx);
1120         } else {
1121                 ldb_transaction_cancel(ldb_ctx);
1122                 if (ldb_ctx->err_string == NULL) {
1123                         /* no error string was setup by the backend */
1124                         ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
1125                 }
1126         }
1127
1128         talloc_free(mem_ctx);
1129         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1130
1131         Py_RETURN_NONE;
1132 }
1133
1134 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1135 {
1136         PyObject *py_dn1, *py_dn2;
1137         struct ldb_dn *dn1, *dn2;
1138         int ret;
1139         struct ldb_context *ldb;
1140         TALLOC_CTX *mem_ctx;
1141         PyObject *py_controls = Py_None;
1142         struct ldb_control **parsed_controls;
1143         struct ldb_context *ldb_ctx;
1144         struct ldb_request *req;
1145         const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1146
1147         ldb_ctx = PyLdb_AsLdbContext(self);
1148
1149         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1150                                          discard_const_p(char *, kwnames),
1151                                          &py_dn1, &py_dn2, &py_controls))
1152                 return NULL;
1153
1154
1155         mem_ctx = talloc_new(NULL);
1156         if (mem_ctx == NULL) {
1157                 PyErr_NoMemory();
1158                 return NULL;
1159         }
1160         ldb = PyLdb_AsLdbContext(self);
1161
1162         if (py_controls == Py_None) {
1163                 parsed_controls = NULL;
1164         } else {
1165                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1166                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1167                 talloc_free(controls);
1168         }
1169
1170
1171         if (!PyObject_AsDn(mem_ctx, py_dn1, ldb, &dn1)) {
1172                 talloc_free(mem_ctx);
1173                 return NULL;
1174         }
1175
1176         if (!PyObject_AsDn(mem_ctx, py_dn2, ldb, &dn2)) {
1177                 talloc_free(mem_ctx);
1178                 return NULL;
1179         }
1180
1181         ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1182                                 NULL, ldb_op_default_callback, NULL);
1183         if (ret != LDB_SUCCESS) {
1184                 PyErr_SetString(PyExc_TypeError, "failed to build request");
1185                 talloc_free(mem_ctx);
1186                 return NULL;
1187         }
1188
1189         /* do request and autostart a transaction */
1190         /* Then let's LDB handle the message error in case of pb as they are meaningful */
1191
1192         ret = ldb_transaction_start(ldb_ctx);
1193         if (ret != LDB_SUCCESS) {
1194                 talloc_free(mem_ctx);
1195                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1196         }
1197
1198         ret = ldb_request(ldb_ctx, req);
1199         if (ret == LDB_SUCCESS) {
1200                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1201         }
1202
1203         if (ret == LDB_SUCCESS) {
1204                 ret = ldb_transaction_commit(ldb_ctx);
1205         } else {
1206                 ldb_transaction_cancel(ldb_ctx);
1207                 if (ldb_ctx->err_string == NULL) {
1208                         /* no error string was setup by the backend */
1209                         ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
1210                 }
1211         }
1212
1213         talloc_free(mem_ctx);
1214         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1215
1216         Py_RETURN_NONE;
1217 }
1218
1219 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1220 {
1221         char *name;
1222         if (!PyArg_ParseTuple(args, "s", &name))
1223                 return NULL;
1224
1225         ldb_schema_attribute_remove(PyLdb_AsLdbContext(self), name);
1226
1227         Py_RETURN_NONE;
1228 }
1229
1230 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1231 {
1232         char *attribute, *syntax;
1233         unsigned int flags;
1234         int ret;
1235         if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1236                 return NULL;
1237
1238         ret = ldb_schema_attribute_add(PyLdb_AsLdbContext(self), attribute, flags, syntax);
1239
1240         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
1241
1242         Py_RETURN_NONE;
1243 }
1244
1245 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1246 {
1247         if (ldif == NULL) {
1248                 Py_RETURN_NONE;
1249         } else {
1250         /* We don't want this attached to the 'ldb' any more */
1251                 return Py_BuildValue(discard_const_p(char, "(iO)"),
1252                                      ldif->changetype,
1253                                      PyLdbMessage_FromMessage(ldif->msg));
1254         }
1255 }
1256
1257
1258 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1259 {
1260         int changetype;
1261         PyObject *py_msg;
1262         struct ldb_ldif ldif;
1263         PyObject *ret;
1264         char *string;
1265         TALLOC_CTX *mem_ctx;
1266
1267         if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1268                 return NULL;
1269
1270         if (!PyLdbMessage_Check(py_msg)) {
1271                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1272                 return NULL;
1273         }
1274
1275         ldif.msg = PyLdbMessage_AsMessage(py_msg);
1276         ldif.changetype = changetype;
1277
1278         mem_ctx = talloc_new(NULL);
1279
1280         string = ldb_ldif_write_string(PyLdb_AsLdbContext(self), mem_ctx, &ldif);
1281         if (!string) {
1282                 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1283                 return NULL;
1284         }
1285
1286         ret = PyString_FromString(string);
1287
1288         talloc_free(mem_ctx);
1289
1290         return ret;
1291 }
1292
1293 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1294 {
1295         PyObject *list;
1296         struct ldb_ldif *ldif;
1297         const char *s;
1298
1299         TALLOC_CTX *mem_ctx;
1300
1301         if (!PyArg_ParseTuple(args, "s", &s))
1302                 return NULL;
1303
1304         mem_ctx = talloc_new(NULL);
1305         if (!mem_ctx) {
1306                 Py_RETURN_NONE;
1307         }
1308
1309         list = PyList_New(0);
1310         while (s && *s != '\0') {
1311                 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1312                 talloc_steal(mem_ctx, ldif);
1313                 if (ldif) {
1314                         PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1315                 } else {
1316                         PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1317                         talloc_free(mem_ctx);
1318                         return NULL;
1319                 }
1320         }
1321         talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1322         return PyObject_GetIter(list);
1323 }
1324
1325 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1326 {
1327         int ldb_ret;
1328         PyObject *py_msg_old;
1329         PyObject *py_msg_new;
1330         struct ldb_message *diff;
1331         struct ldb_context *ldb;
1332         PyObject *py_ret;
1333
1334         if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1335                 return NULL;
1336
1337         if (!PyLdbMessage_Check(py_msg_old)) {
1338                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1339                 return NULL;
1340         }
1341
1342         if (!PyLdbMessage_Check(py_msg_new)) {
1343                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1344                 return NULL;
1345         }
1346
1347         ldb = PyLdb_AsLdbContext(self);
1348         ldb_ret = ldb_msg_difference(ldb, ldb,
1349                                      PyLdbMessage_AsMessage(py_msg_old),
1350                                      PyLdbMessage_AsMessage(py_msg_new),
1351                                      &diff);
1352         if (ldb_ret != LDB_SUCCESS) {
1353                 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1354                 return NULL;
1355         }
1356
1357         py_ret = PyLdbMessage_FromMessage(diff);
1358
1359         talloc_unlink(ldb, diff);
1360
1361         return py_ret;
1362 }
1363
1364 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1365 {
1366         const struct ldb_schema_attribute *a;
1367         struct ldb_val old_val;
1368         struct ldb_val new_val;
1369         TALLOC_CTX *mem_ctx;
1370         PyObject *ret;
1371         char *element_name;
1372         PyObject *val;
1373
1374         if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1375                 return NULL;
1376
1377         mem_ctx = talloc_new(NULL);
1378
1379         old_val.data = (uint8_t *)PyString_AsString(val);
1380         old_val.length = PyString_Size(val);
1381
1382         a = ldb_schema_attribute_by_name(PyLdb_AsLdbContext(self), element_name);
1383
1384         if (a == NULL) {
1385                 Py_RETURN_NONE;
1386         }
1387
1388         if (a->syntax->ldif_write_fn(PyLdb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1389                 talloc_free(mem_ctx);
1390                 Py_RETURN_NONE;
1391         }
1392
1393         ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1394
1395         talloc_free(mem_ctx);
1396
1397         return ret;
1398 }
1399
1400 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1401 {
1402         PyObject *py_base = Py_None;
1403         int scope = LDB_SCOPE_DEFAULT;
1404         char *expr = NULL;
1405         PyObject *py_attrs = Py_None;
1406         PyObject *py_controls = Py_None;
1407         const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1408         int ret;
1409         struct ldb_result *res;
1410         struct ldb_request *req;
1411         const char **attrs;
1412         struct ldb_context *ldb_ctx;
1413         struct ldb_control **parsed_controls;
1414         struct ldb_dn *base;
1415         PyObject *py_ret;
1416         TALLOC_CTX *mem_ctx;
1417
1418         /* type "int" rather than "enum" for "scope" is intentional */
1419         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1420                                          discard_const_p(char *, kwnames),
1421                                          &py_base, &scope, &expr, &py_attrs, &py_controls))
1422                 return NULL;
1423
1424
1425         mem_ctx = talloc_new(NULL);
1426         if (mem_ctx == NULL) {
1427                 PyErr_NoMemory();
1428                 return NULL;
1429         }
1430         ldb_ctx = PyLdb_AsLdbContext(self);
1431
1432         if (py_attrs == Py_None) {
1433                 attrs = NULL;
1434         } else {
1435                 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1436                 if (attrs == NULL) {
1437                         talloc_free(mem_ctx);
1438                         return NULL;
1439                 }
1440         }
1441
1442         if (py_base == Py_None) {
1443                 base = ldb_get_default_basedn(ldb_ctx);
1444         } else {
1445                 if (!PyObject_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1446                         talloc_free(attrs);
1447                         return NULL;
1448                 }
1449         }
1450
1451         if (py_controls == Py_None) {
1452                 parsed_controls = NULL;
1453         } else {
1454                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1455                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1456                 talloc_free(controls);
1457         }
1458
1459         res = talloc_zero(mem_ctx, struct ldb_result);
1460         if (res == NULL) {
1461                 PyErr_NoMemory();
1462                 talloc_free(mem_ctx);
1463                 return NULL;
1464         }
1465
1466         ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1467                                    base,
1468                                    scope,
1469                                    expr,
1470                                    attrs,
1471                                    parsed_controls,
1472                                    res,
1473                                    ldb_search_default_callback,
1474                                    NULL);
1475
1476         if (ret != LDB_SUCCESS) {
1477                 talloc_free(mem_ctx);
1478                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1479                 return NULL;
1480         }
1481
1482         talloc_steal(req, attrs);
1483
1484         ret = ldb_request(ldb_ctx, req);
1485
1486         if (ret == LDB_SUCCESS) {
1487                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1488         }
1489
1490         if (ret != LDB_SUCCESS) {
1491                 talloc_free(mem_ctx);
1492                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1493                 return NULL;
1494         }
1495
1496         py_ret = PyLdbResult_FromResult(res);
1497
1498         talloc_free(mem_ctx);
1499
1500         return py_ret;
1501 }
1502
1503 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1504 {
1505         char *name;
1506         void *data;
1507
1508         if (!PyArg_ParseTuple(args, "s", &name))
1509                 return NULL;
1510
1511         data = ldb_get_opaque(PyLdb_AsLdbContext(self), name);
1512
1513         if (data == NULL)
1514                 Py_RETURN_NONE;
1515
1516         /* FIXME: More interpretation */
1517
1518         return Py_True;
1519 }
1520
1521 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1522 {
1523         char *name;
1524         PyObject *data;
1525
1526         if (!PyArg_ParseTuple(args, "sO", &name, &data))
1527                 return NULL;
1528
1529         /* FIXME: More interpretation */
1530
1531         ldb_set_opaque(PyLdb_AsLdbContext(self), name, data);
1532
1533         Py_RETURN_NONE;
1534 }
1535
1536 static PyObject *py_ldb_modules(PyLdbObject *self)
1537 {
1538         struct ldb_context *ldb = PyLdb_AsLdbContext(self);
1539         PyObject *ret = PyList_New(0);
1540         struct ldb_module *mod;
1541
1542         for (mod = ldb->modules; mod; mod = mod->next) {
1543                 PyList_Append(ret, PyLdbModule_FromModule(mod));
1544         }
1545
1546         return ret;
1547 }
1548
1549 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1550 {
1551         struct ldb_context *ldb = PyLdb_AsLdbContext(self);
1552         int type, ret;
1553         uint64_t value;
1554
1555         if (!PyArg_ParseTuple(args, "i", &type))
1556                 return NULL;
1557
1558         /* FIXME: More interpretation */
1559
1560         ret = ldb_sequence_number(ldb, type, &value);
1561
1562         if (ret != LDB_SUCCESS) {
1563                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1564                 return NULL;
1565         }
1566         return PyLong_FromLongLong(value);
1567 }
1568 static PyMethodDef py_ldb_methods[] = {
1569         { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, 
1570                 "S.set_debug(callback) -> None\n"
1571                 "Set callback for LDB debug messages.\n"
1572                 "The callback should accept a debug level and debug text." },
1573         { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS, 
1574                 "S.set_create_perms(mode) -> None\n"
1575                 "Set mode to use when creating new LDB files." },
1576         { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1577                 "S.set_modules_dir(path) -> None\n"
1578                 "Set path LDB should search for modules" },
1579         { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS, 
1580                 "S.transaction_start() -> None\n"
1581                 "Start a new transaction." },
1582         { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1583                 "S.transaction_prepare_commit() -> None\n"
1584                 "prepare to commit a new transaction (2-stage commit)." },
1585         { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, 
1586                 "S.transaction_commit() -> None\n"
1587                 "commit a new transaction." },
1588         { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS, 
1589                 "S.transaction_cancel() -> None\n"
1590                 "cancel a new transaction." },
1591         { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS, 
1592                 NULL },
1593         { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1594                 NULL },
1595         { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1596                 NULL },
1597         { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1598                 NULL },
1599         { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1600                 NULL },
1601         { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS, 
1602                 "S.connect(url, flags=0, options=None) -> None\n"
1603                 "Connect to a LDB URL." },
1604         { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
1605                 "S.modify(message, controls=None, validate=False) -> None\n"
1606                 "Modify an entry." },
1607         { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
1608                 "S.add(message, controls=None) -> None\n"
1609                 "Add an entry." },
1610         { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
1611                 "S.delete(dn, controls=None) -> None\n"
1612                 "Remove an entry." },
1613         { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
1614                 "S.rename(old_dn, new_dn, controls=None) -> None\n"
1615                 "Rename an entry." },
1616         { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1617                 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1618                 "Search in a database.\n"
1619                 "\n"
1620                 ":param base: Optional base DN to search\n"
1621                 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1622                 ":param expression: Optional search expression\n"
1623                 ":param attrs: Attributes to return (defaults to all)\n"
1624                 ":param controls: Optional list of controls\n"
1625                 ":return: Iterator over Message objects\n"
1626         },
1627         { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1628                 NULL },
1629         { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1630                 NULL },
1631         { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1632                 NULL },
1633         { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1634                 "S.parse_ldif(ldif) -> iter(messages)\n"
1635                 "Parse a string formatted using LDIF." },
1636         { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1637                 "S.write_ldif(message, changetype) -> ldif\n"
1638                 "Print the message as a string formatted using LDIF." },
1639         { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1640                 "S.msg_diff(Message) -> Message\n"
1641                 "Return an LDB Message of the difference between two Message objects." },
1642         { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1643                 "S.get_opaque(name) -> value\n"
1644                 "Get an opaque value set on this LDB connection. \n"
1645                 ":note: The returned value may not be useful in Python."
1646         },
1647         { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1648                 "S.set_opaque(name, value) -> None\n"
1649                 "Set an opaque value on this LDB connection. \n"
1650                 ":note: Passing incorrect values may cause crashes." },
1651         { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1652                 "S.modules() -> list\n"
1653                 "Return the list of modules on this LDB connection " },
1654         { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1655                 "S.sequence_number(type) -> value\n"
1656                 "Return the value of the sequence according to the requested type" },
1657         { NULL },
1658 };
1659
1660 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1661 {
1662         PyLdbModuleObject *ret;
1663
1664         ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1665         if (ret == NULL) {
1666                 PyErr_NoMemory();
1667                 return NULL;
1668         }
1669         ret->mem_ctx = talloc_new(NULL);
1670         ret->mod = talloc_reference(ret->mem_ctx, mod);
1671         return (PyObject *)ret;
1672 }
1673
1674 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1675 {
1676         return PyLdbModule_FromModule(PyLdb_AsLdbContext(self)->modules);
1677 }
1678
1679 static PyGetSetDef py_ldb_getset[] = {
1680         { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1681         { NULL }
1682 };
1683
1684 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1685 {
1686         struct ldb_context *ldb_ctx = PyLdb_AsLdbContext(self);
1687         struct ldb_dn *dn;
1688         struct ldb_result *result;
1689         unsigned int count;
1690         int ret;
1691
1692         if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
1693                 return -1;
1694         }
1695
1696         ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
1697                          NULL);
1698         if (ret != LDB_SUCCESS) {
1699                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1700                 return -1;
1701         }
1702
1703         count = result->count;
1704
1705         talloc_free(result);
1706
1707         if (count > 1) {
1708                 PyErr_Format(PyExc_RuntimeError,
1709                              "Searching for [%s] dn gave %u results!",
1710                              ldb_dn_get_linearized(dn),
1711                              count);
1712                 return -1;
1713         }
1714
1715         return count;
1716 }
1717
1718 static PySequenceMethods py_ldb_seq = {
1719         .sq_contains = (objobjproc)py_ldb_contains,
1720 };
1721
1722 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1723 {
1724         PyLdbObject *ret;
1725
1726         ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1727         if (ret == NULL) {
1728                 PyErr_NoMemory();
1729                 return NULL;
1730         }
1731         ret->mem_ctx = talloc_new(NULL);
1732         ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1733         return (PyObject *)ret;
1734 }
1735
1736 static void py_ldb_dealloc(PyLdbObject *self)
1737 {
1738         talloc_free(self->mem_ctx);
1739         self->ob_type->tp_free(self);
1740 }
1741
1742 static PyTypeObject PyLdb = {
1743         .tp_name = "ldb.Ldb",
1744         .tp_methods = py_ldb_methods,
1745         .tp_repr = (reprfunc)py_ldb_repr,
1746         .tp_new = py_ldb_new,
1747         .tp_init = (initproc)py_ldb_init,
1748         .tp_dealloc = (destructor)py_ldb_dealloc,
1749         .tp_getset = py_ldb_getset,
1750         .tp_getattro = PyObject_GenericGetAttr,
1751         .tp_basicsize = sizeof(PyLdbObject),
1752         .tp_doc = "Connection to a LDB database.",
1753         .tp_as_sequence = &py_ldb_seq,
1754         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1755 };
1756
1757 static void py_ldb_result_dealloc(PyLdbResultObject *self)
1758 {
1759         talloc_free(self->mem_ctx);
1760         Py_DECREF(self->msgs);
1761         Py_DECREF(self->referals);
1762         Py_DECREF(self->controls);
1763         self->ob_type->tp_free(self);
1764 }
1765
1766 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
1767 {
1768         Py_INCREF(self->msgs);
1769         return self->msgs;
1770 }
1771
1772 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
1773 {
1774         Py_INCREF(self->controls);
1775         return self->controls;
1776 }
1777
1778 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
1779 {
1780         Py_INCREF(self->referals);
1781         return self->referals;
1782 }
1783
1784 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
1785 {
1786         Py_ssize_t size;
1787         if (self->msgs == NULL) {
1788                 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
1789                 return NULL;
1790         }
1791         size = PyList_Size(self->msgs);
1792         return PyInt_FromLong(size);
1793 }
1794
1795 static PyGetSetDef py_ldb_result_getset[] = {
1796         { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
1797         { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
1798         { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
1799         { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
1800         { NULL }
1801 };
1802
1803 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
1804 {
1805         return PyObject_GetIter(self->msgs);
1806 }
1807
1808 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
1809 {
1810         return PySequence_Size(self->msgs);
1811 }
1812
1813 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
1814 {
1815         return PySequence_GetItem(self->msgs, idx);
1816 }
1817
1818 static PySequenceMethods py_ldb_result_seq = {
1819         .sq_length = (lenfunc)py_ldb_result_len,
1820         .sq_item = (ssizeargfunc)py_ldb_result_find,
1821 };
1822
1823 static PyObject *py_ldb_result_repr(PyLdbObject *self)
1824 {
1825         return PyString_FromFormat("<ldb result>");
1826 }
1827
1828
1829 static PyTypeObject PyLdbResult = {
1830         .tp_name = "ldb.Result",
1831         .tp_repr = (reprfunc)py_ldb_result_repr,
1832         .tp_dealloc = (destructor)py_ldb_result_dealloc,
1833         .tp_iter = (getiterfunc)py_ldb_result_iter,
1834         .tp_getset = py_ldb_result_getset,
1835         .tp_getattro = PyObject_GenericGetAttr,
1836         .tp_basicsize = sizeof(PyLdbResultObject),
1837         .tp_as_sequence = &py_ldb_result_seq,
1838         .tp_doc = "LDB result.",
1839         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1840 };
1841
1842 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
1843 {
1844         return PyString_FromFormat("<ldb module '%s'>", PyLdbModule_AsModule(self)->ops->name);
1845 }
1846
1847 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
1848 {
1849         return PyString_FromString(PyLdbModule_AsModule(self)->ops->name);
1850 }
1851
1852 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
1853 {
1854         PyLdbModule_AsModule(self)->ops->start_transaction(PyLdbModule_AsModule(self));
1855         Py_RETURN_NONE;
1856 }
1857
1858 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
1859 {
1860         PyLdbModule_AsModule(self)->ops->end_transaction(PyLdbModule_AsModule(self));
1861         Py_RETURN_NONE;
1862 }
1863
1864 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
1865 {
1866         PyLdbModule_AsModule(self)->ops->del_transaction(PyLdbModule_AsModule(self));
1867         Py_RETURN_NONE;
1868 }
1869
1870 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
1871 {
1872         PyObject *py_base, *py_tree, *py_attrs, *py_ret;
1873         int ret, scope;
1874         struct ldb_request *req;
1875         const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
1876         struct ldb_module *mod;
1877         const char * const*attrs;
1878
1879         /* type "int" rather than "enum" for "scope" is intentional */
1880         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
1881                                          discard_const_p(char *, kwnames),
1882                                          &py_base, &scope, &py_tree, &py_attrs))
1883                 return NULL;
1884
1885         mod = self->mod;
1886
1887         if (py_attrs == Py_None) {
1888                 attrs = NULL;
1889         } else {
1890                 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
1891                 if (attrs == NULL)
1892                         return NULL;
1893         }
1894
1895         ret = ldb_build_search_req(&req, mod->ldb, NULL, PyLdbDn_AsDn(py_base), 
1896                              scope, NULL /* expr */, attrs,
1897                              NULL /* controls */, NULL, NULL, NULL);
1898
1899         talloc_steal(req, attrs);
1900
1901         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1902
1903         req->op.search.res = NULL;
1904
1905         ret = mod->ops->search(mod, req);
1906
1907         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1908
1909         py_ret = PyLdbResult_FromResult(req->op.search.res);
1910
1911         talloc_free(req);
1912
1913         return py_ret;  
1914 }
1915
1916
1917 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
1918 {
1919         struct ldb_request *req;
1920         PyObject *py_message;
1921         int ret;
1922         struct ldb_module *mod;
1923
1924         if (!PyArg_ParseTuple(args, "O", &py_message))
1925                 return NULL;
1926
1927         req = talloc_zero(NULL, struct ldb_request);
1928         req->operation = LDB_ADD;
1929         req->op.add.message = PyLdbMessage_AsMessage(py_message);
1930
1931         mod = PyLdbModule_AsModule(self);
1932         ret = mod->ops->add(mod, req);
1933
1934         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1935
1936         Py_RETURN_NONE;
1937 }
1938
1939 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args) 
1940 {
1941         int ret;
1942         struct ldb_request *req;
1943         PyObject *py_message;
1944         struct ldb_module *mod;
1945
1946         if (!PyArg_ParseTuple(args, "O", &py_message))
1947                 return NULL;
1948
1949         req = talloc_zero(NULL, struct ldb_request);
1950         req->operation = LDB_MODIFY;
1951         req->op.mod.message = PyLdbMessage_AsMessage(py_message);
1952
1953         mod = PyLdbModule_AsModule(self);
1954         ret = mod->ops->modify(mod, req);
1955
1956         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1957
1958         Py_RETURN_NONE;
1959 }
1960
1961 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args) 
1962 {
1963         int ret;
1964         struct ldb_request *req;
1965         PyObject *py_dn;
1966
1967         if (!PyArg_ParseTuple(args, "O", &py_dn))
1968                 return NULL;
1969
1970         req = talloc_zero(NULL, struct ldb_request);
1971         req->operation = LDB_DELETE;
1972         req->op.del.dn = PyLdbDn_AsDn(py_dn);
1973
1974         ret = PyLdbModule_AsModule(self)->ops->del(PyLdbModule_AsModule(self), req);
1975
1976         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
1977
1978         Py_RETURN_NONE;
1979 }
1980
1981 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
1982 {
1983         int ret;
1984         struct ldb_request *req;
1985         PyObject *py_dn1, *py_dn2;
1986
1987         if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
1988                 return NULL;
1989
1990         req = talloc_zero(NULL, struct ldb_request);
1991
1992         req->operation = LDB_RENAME;
1993         req->op.rename.olddn = PyLdbDn_AsDn(py_dn1);
1994         req->op.rename.newdn = PyLdbDn_AsDn(py_dn2);
1995
1996         ret = PyLdbModule_AsModule(self)->ops->rename(PyLdbModule_AsModule(self), req);
1997
1998         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
1999
2000         Py_RETURN_NONE;
2001 }
2002
2003 static PyMethodDef py_ldb_module_methods[] = {
2004         { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2005         { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2006         { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2007         { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2008         { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2009         { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2010         { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2011         { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2012         { NULL },
2013 };
2014
2015 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2016 {
2017         talloc_free(self->mem_ctx);
2018         PyObject_Del(self);
2019 }
2020
2021 static PyTypeObject PyLdbModule = {
2022         .tp_name = "ldb.LdbModule",
2023         .tp_methods = py_ldb_module_methods,
2024         .tp_repr = (reprfunc)py_ldb_module_repr,
2025         .tp_str = (reprfunc)py_ldb_module_str,
2026         .tp_basicsize = sizeof(PyLdbModuleObject),
2027         .tp_dealloc = (destructor)py_ldb_module_dealloc,
2028         .tp_flags = Py_TPFLAGS_DEFAULT,
2029 };
2030
2031
2032 /**
2033  * Create a ldb_message_element from a Python object.
2034  *
2035  * This will accept any sequence objects that contains strings, or 
2036  * a string object.
2037  *
2038  * A reference to set_obj will be borrowed. 
2039  *
2040  * @param mem_ctx Memory context
2041  * @param set_obj Python object to convert
2042  * @param flags ldb_message_element flags to set
2043  * @param attr_name Name of the attribute
2044  * @return New ldb_message_element, allocated as child of mem_ctx
2045  */
2046 static struct ldb_message_element *PyObject_AsMessageElement(
2047                                                       TALLOC_CTX *mem_ctx,
2048                                                       PyObject *set_obj,
2049                                                       unsigned int flags,
2050                                                       const char *attr_name)
2051 {
2052         struct ldb_message_element *me;
2053
2054         if (PyLdbMessageElement_Check(set_obj)) {
2055                 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2056                 /* We have to talloc_reference() the memory context, not the pointer
2057                  * which may not actually be it's own context */
2058                 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2059                         return PyLdbMessageElement_AsMessageElement(set_obj);
2060                 }
2061                 return NULL;
2062         }
2063
2064         me = talloc(mem_ctx, struct ldb_message_element);
2065         if (me == NULL) {
2066                 PyErr_NoMemory();
2067                 return NULL;
2068         }
2069
2070         me->name = talloc_strdup(me, attr_name);
2071         me->flags = flags;
2072         if (PyString_Check(set_obj)) {
2073                 me->num_values = 1;
2074                 me->values = talloc_array(me, struct ldb_val, me->num_values);
2075                 me->values[0].length = PyString_Size(set_obj);
2076                 me->values[0].data = talloc_memdup(me, 
2077                         (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2078         } else if (PySequence_Check(set_obj)) {
2079                 Py_ssize_t i;
2080                 me->num_values = PySequence_Size(set_obj);
2081                 me->values = talloc_array(me, struct ldb_val, me->num_values);
2082                 for (i = 0; i < me->num_values; i++) {
2083                         PyObject *obj = PySequence_GetItem(set_obj, i);
2084                         if (!PyString_Check(obj)) {
2085                                 PyErr_Format(PyExc_TypeError,
2086                                              "Expected string as element %zd in list", i);
2087                                 talloc_free(me);
2088                                 return NULL;
2089                         }
2090
2091                         me->values[i].length = PyString_Size(obj);
2092                         me->values[i].data = talloc_memdup(me, 
2093                                 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2094                 }
2095         } else {
2096                 talloc_free(me);
2097                 me = NULL;
2098         }
2099
2100         return me;
2101 }
2102
2103
2104 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2105                                         struct ldb_message_element *me)
2106 {
2107         Py_ssize_t i;
2108         PyObject *result;
2109
2110         /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2111         result = PyList_New(me->num_values);
2112
2113         for (i = 0; i < me->num_values; i++) {
2114                 PyList_SetItem(result, i,
2115                         PyObject_FromLdbValue(&me->values[i]));
2116         }
2117
2118         return result;
2119 }
2120
2121 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2122 {
2123         unsigned int i;
2124         if (!PyArg_ParseTuple(args, "I", &i))
2125                 return NULL;
2126         if (i >= PyLdbMessageElement_AsMessageElement(self)->num_values)
2127                 Py_RETURN_NONE;
2128
2129         return PyObject_FromLdbValue(&(PyLdbMessageElement_AsMessageElement(self)->values[i]));
2130 }
2131
2132 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2133 {
2134         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
2135         return PyInt_FromLong(el->flags);
2136 }
2137
2138 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2139 {
2140         unsigned int flags;
2141         struct ldb_message_element *el;
2142         if (!PyArg_ParseTuple(args, "I", &flags))
2143                 return NULL;
2144
2145         el = PyLdbMessageElement_AsMessageElement(self);
2146         el->flags = flags;
2147         Py_RETURN_NONE;
2148 }
2149
2150 static PyMethodDef py_ldb_msg_element_methods[] = {
2151         { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2152         { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2153         { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2154         { NULL },
2155 };
2156
2157 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2158 {
2159         return PyLdbMessageElement_AsMessageElement(self)->num_values;
2160 }
2161
2162 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2163 {
2164         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
2165         if (idx < 0 || idx >= el->num_values) {
2166                 PyErr_SetString(PyExc_IndexError, "Out of range");
2167                 return NULL;
2168         }
2169         return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2170 }
2171
2172 static PySequenceMethods py_ldb_msg_element_seq = {
2173         .sq_length = (lenfunc)py_ldb_msg_element_len,
2174         .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2175 };
2176
2177 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2178 {
2179         int ret = ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self),
2180                                                                           PyLdbMessageElement_AsMessageElement(other));
2181         return SIGN(ret);
2182 }
2183
2184 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2185 {
2186         return PyObject_GetIter(ldb_msg_element_to_set(NULL, PyLdbMessageElement_AsMessageElement(self)));
2187 }
2188
2189 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2190 {
2191         PyLdbMessageElementObject *ret;
2192         ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2193         if (ret == NULL) {
2194                 PyErr_NoMemory();
2195                 return NULL;
2196         }
2197         ret->mem_ctx = talloc_new(NULL);
2198         if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2199                 PyErr_NoMemory();
2200                 return NULL;
2201         }
2202         ret->el = el;
2203         return (PyObject *)ret;
2204 }
2205
2206 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2207 {
2208         PyObject *py_elements = NULL;
2209         struct ldb_message_element *el;
2210         unsigned int flags = 0;
2211         char *name = NULL;
2212         const char * const kwnames[] = { "elements", "flags", "name", NULL };
2213         PyLdbMessageElementObject *ret;
2214         TALLOC_CTX *mem_ctx;
2215
2216         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2217                                          discard_const_p(char *, kwnames),
2218                                          &py_elements, &flags, &name))
2219                 return NULL;
2220
2221         mem_ctx = talloc_new(NULL);
2222         if (mem_ctx == NULL) {
2223                 PyErr_NoMemory();
2224                 return NULL;
2225         }
2226
2227         el = talloc_zero(mem_ctx, struct ldb_message_element);
2228         if (el == NULL) {
2229                 PyErr_NoMemory();
2230                 talloc_free(mem_ctx);
2231                 return NULL;
2232         }
2233
2234         if (py_elements != NULL) {
2235                 Py_ssize_t i;
2236                 if (PyString_Check(py_elements)) {
2237                         el->num_values = 1;
2238                         el->values = talloc_array(el, struct ldb_val, 1);
2239                         if (el->values == NULL) {
2240                                 talloc_free(mem_ctx);
2241                                 PyErr_NoMemory();
2242                                 return NULL;
2243                         }
2244                         el->values[0].length = PyString_Size(py_elements);
2245                         el->values[0].data = talloc_memdup(el->values, 
2246                                 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2247                 } else if (PySequence_Check(py_elements)) {
2248                         el->num_values = PySequence_Size(py_elements);
2249                         el->values = talloc_array(el, struct ldb_val, el->num_values);
2250                         if (el->values == NULL) {
2251                                 talloc_free(mem_ctx);
2252                                 PyErr_NoMemory();
2253                                 return NULL;
2254                         }
2255                         for (i = 0; i < el->num_values; i++) {
2256                                 PyObject *item = PySequence_GetItem(py_elements, i);
2257                                 if (item == NULL) {
2258                                         talloc_free(mem_ctx);
2259                                         return NULL;
2260                                 }
2261                                 if (!PyString_Check(item)) {
2262                                         PyErr_Format(PyExc_TypeError, 
2263                                                      "Expected string as element %zd in list", i);
2264                                         talloc_free(mem_ctx);
2265                                         return NULL;
2266                                 }
2267                                 el->values[i].length = PyString_Size(item);
2268                                 el->values[i].data = talloc_memdup(el,
2269                                         (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2270                         }
2271                 } else {
2272                         PyErr_SetString(PyExc_TypeError, 
2273                                         "Expected string or list");
2274                         talloc_free(mem_ctx);
2275                         return NULL;
2276                 }
2277         }
2278
2279         el->flags = flags;
2280         el->name = talloc_strdup(el, name);
2281
2282         ret = PyObject_New(PyLdbMessageElementObject, type);
2283         if (ret == NULL) {
2284                 talloc_free(mem_ctx);
2285                 return NULL;
2286         }
2287
2288         ret->mem_ctx = mem_ctx;
2289         ret->el = el;
2290         return (PyObject *)ret;
2291 }
2292
2293 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2294 {
2295         char *element_str = NULL;
2296         Py_ssize_t i;
2297         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
2298         PyObject *ret;
2299
2300         for (i = 0; i < el->num_values; i++) {
2301                 PyObject *o = py_ldb_msg_element_find(self, i);
2302                 if (element_str == NULL)
2303                         element_str = talloc_strdup(NULL, PyObject_REPR(o));
2304                 else
2305                         element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
2306         }
2307
2308         if (element_str != NULL) {
2309                 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2310                 talloc_free(element_str);
2311         } else {
2312                 ret = PyString_FromString("MessageElement([])");
2313         }
2314
2315         return ret;
2316 }
2317
2318 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2319 {
2320         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
2321
2322         if (el->num_values == 1)
2323                 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2324         else
2325                 Py_RETURN_NONE;
2326 }
2327
2328 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2329 {
2330         talloc_free(self->mem_ctx);
2331         PyObject_Del(self);
2332 }
2333
2334 static PyTypeObject PyLdbMessageElement = {
2335         .tp_name = "ldb.MessageElement",
2336         .tp_basicsize = sizeof(PyLdbMessageElementObject),
2337         .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2338         .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2339         .tp_str = (reprfunc)py_ldb_msg_element_str,
2340         .tp_methods = py_ldb_msg_element_methods,
2341         .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2342         .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2343         .tp_as_sequence = &py_ldb_msg_element_seq,
2344         .tp_new = py_ldb_msg_element_new,
2345         .tp_flags = Py_TPFLAGS_DEFAULT,
2346 };
2347
2348
2349 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2350 {
2351         PyObject *py_ldb;
2352         PyObject *py_dict;
2353         PyObject *py_ret;
2354         struct ldb_message *msg;
2355         struct ldb_context *ldb_ctx;
2356         unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2357
2358         if (!PyArg_ParseTuple(args, "O!O!|I",
2359                               &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2360                               &mod_flags)) {
2361                 return NULL;
2362         }
2363
2364         /* mask only flags we are going to use */
2365         mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2366         if (!mod_flags) {
2367                 PyErr_SetString(PyExc_ValueError,
2368                                 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2369                                 " expected as mod_flag value");
2370                 return NULL;
2371         }
2372
2373         ldb_ctx = PyLdb_AsLdbContext(py_ldb);
2374
2375         msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2376         if (!msg) {
2377                 return NULL;
2378         }
2379
2380         py_ret = PyLdbMessage_FromMessage(msg);
2381
2382         talloc_unlink(ldb_ctx, msg);
2383
2384         return py_ret;
2385 }
2386
2387 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2388 {
2389         char *name;
2390         if (!PyArg_ParseTuple(args, "s", &name))
2391                 return NULL;
2392
2393         ldb_msg_remove_attr(self->msg, name);
2394
2395         Py_RETURN_NONE;
2396 }
2397
2398 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2399 {
2400         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2401         Py_ssize_t i, j = 0;
2402         PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2403         if (msg->dn != NULL) {
2404                 PyList_SetItem(obj, j, PyString_FromString("dn"));
2405                 j++;
2406         }
2407         for (i = 0; i < msg->num_elements; i++) {
2408                 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2409                 j++;
2410         }
2411         return obj;
2412 }
2413
2414 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2415 {
2416         struct ldb_message_element *el;
2417         char *name;
2418         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2419         if (!PyString_Check(py_name)) {
2420                 PyErr_SetNone(PyExc_TypeError);
2421                 return NULL;
2422         }
2423         name = PyString_AsString(py_name);
2424         if (!strcmp(name, "dn"))
2425                 return PyLdbDn_FromDn(msg->dn);
2426         el = ldb_msg_find_element(msg, name);
2427         if (el == NULL) {
2428                 return NULL;
2429         }
2430         return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2431 }
2432
2433 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2434 {
2435         PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2436         if (ret == NULL) {
2437                 PyErr_SetString(PyExc_KeyError, "No such element");
2438                 return NULL;
2439         }
2440         return ret;
2441 }
2442
2443 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args)
2444 {
2445         PyObject *name, *ret, *retobj;
2446         retobj = NULL;
2447         if (!PyArg_ParseTuple(args, "O|O", &name, &retobj))
2448                 return NULL;
2449
2450         ret = py_ldb_msg_getitem_helper(self, name);
2451         if (ret == NULL) {
2452                 if (PyErr_Occurred())
2453                         return NULL;
2454                 if (retobj != NULL) {
2455                         return retobj;
2456                 } else {
2457                         Py_RETURN_NONE;
2458                 }
2459         }
2460         return ret;
2461 }
2462
2463 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2464 {
2465         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2466         Py_ssize_t i, j = 0;
2467         PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2468         if (msg->dn != NULL) {
2469                 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", PyLdbDn_FromDn(msg->dn)));
2470                 j++;
2471         }
2472         for (i = 0; i < msg->num_elements; i++, j++) {
2473                 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2474                 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2475                 PyList_SetItem(l, j, value);
2476         }
2477         return l;
2478 }
2479
2480 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2481 {
2482         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2483         Py_ssize_t i = 0;
2484         PyObject *l = PyList_New(msg->num_elements);
2485         for (i = 0; i < msg->num_elements; i++) {
2486                 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2487         }
2488         return l;
2489 }
2490
2491 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2492 {
2493         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2494         PyLdbMessageElementObject *py_element;
2495         int ret;
2496         struct ldb_message_element *el;
2497
2498         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2499                 return NULL;
2500
2501         el = talloc_reference(msg, py_element->el);
2502         if (el == NULL) {
2503                 PyErr_NoMemory();
2504                 return NULL;
2505         }
2506
2507         ret = ldb_msg_add(msg, el, el->flags);
2508         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2509
2510         Py_RETURN_NONE;
2511 }
2512
2513 static PyMethodDef py_ldb_msg_methods[] = {
2514         { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2515                 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2516                 "Class method to create ldb.Message object from Dictionary.\n"
2517                 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2518         { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, 
2519                 "S.keys() -> list\n\n"
2520                 "Return sequence of all attribute names." },
2521         { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, 
2522                 "S.remove(name)\n\n"
2523                 "Remove all entries for attributes with the specified name."},
2524         { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS, NULL },
2525         { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2526         { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2527         { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2528                 "S.append(element)\n\n"
2529                 "Add an element to this message." },
2530         { NULL },
2531 };
2532
2533 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2534 {
2535         PyObject *list, *iter;
2536
2537         list = py_ldb_msg_keys(self);
2538         iter = PyObject_GetIter(list);
2539         Py_DECREF(list);
2540         return iter;
2541 }
2542
2543 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2544 {
2545         char *attr_name;
2546
2547         if (!PyString_Check(name)) {
2548                 PyErr_SetNone(PyExc_TypeError);
2549                 return -1;
2550         }
2551
2552         attr_name = PyString_AsString(name);
2553         if (value == NULL) {
2554                 /* delitem */
2555                 ldb_msg_remove_attr(self->msg, attr_name);
2556         } else {
2557                 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2558                                                                            value, 0, attr_name);
2559                 if (el == NULL)
2560                         return -1;
2561                 ldb_msg_remove_attr(PyLdbMessage_AsMessage(self), attr_name);
2562                 ldb_msg_add(PyLdbMessage_AsMessage(self), el, el->flags);
2563         }
2564         return 0;
2565 }
2566
2567 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2568 {
2569         return PyLdbMessage_AsMessage(self)->num_elements;
2570 }
2571
2572 static PyMappingMethods py_ldb_msg_mapping = {
2573         .mp_length = (lenfunc)py_ldb_msg_length,
2574         .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2575         .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2576 };
2577
2578 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2579 {
2580         const char * const kwnames[] = { "dn", NULL };
2581         struct ldb_message *ret;
2582         TALLOC_CTX *mem_ctx;
2583         PyObject *pydn = NULL;
2584         PyLdbMessageObject *py_ret;
2585
2586         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2587                                          discard_const_p(char *, kwnames),
2588                                          &pydn))
2589                 return NULL;
2590
2591         mem_ctx = talloc_new(NULL);
2592         if (mem_ctx == NULL) {
2593                 PyErr_NoMemory();
2594                 return NULL;
2595         }
2596
2597         ret = ldb_msg_new(mem_ctx);
2598         if (ret == NULL) {
2599                 talloc_free(mem_ctx);
2600                 PyErr_NoMemory();
2601                 return NULL;
2602         }
2603
2604         if (pydn != NULL) {
2605                 struct ldb_dn *dn;
2606                 if (!PyObject_AsDn(NULL, pydn, NULL, &dn)) {
2607                         talloc_free(mem_ctx);
2608                         return NULL;
2609                 }
2610                 ret->dn = talloc_reference(ret, dn);
2611         }
2612
2613         py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2614         if (py_ret == NULL) {
2615                 PyErr_NoMemory();
2616                 talloc_free(mem_ctx);
2617                 return NULL;
2618         }
2619
2620         py_ret->mem_ctx = mem_ctx;
2621         py_ret->msg = ret;
2622         return (PyObject *)py_ret;
2623 }
2624
2625 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2626 {
2627         PyLdbMessageObject *ret;
2628
2629         ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2630         if (ret == NULL) {
2631                 PyErr_NoMemory();
2632                 return NULL;
2633         }
2634         ret->mem_ctx = talloc_new(NULL);
2635         ret->msg = talloc_reference(ret->mem_ctx, msg);
2636         return (PyObject *)ret;
2637 }
2638
2639 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2640 {
2641         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2642         return PyLdbDn_FromDn(msg->dn);
2643 }
2644
2645 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2646 {
2647         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2648         if (!PyLdbDn_Check(value)) {
2649                 PyErr_SetNone(PyExc_TypeError);
2650                 return -1;
2651         }
2652
2653         msg->dn = talloc_reference(msg, PyLdbDn_AsDn(value));
2654         return 0;
2655 }
2656
2657 static PyGetSetDef py_ldb_msg_getset[] = {
2658         { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2659         { NULL }
2660 };
2661
2662 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2663 {
2664         PyObject *dict = PyDict_New(), *ret;
2665         if (PyDict_Update(dict, (PyObject *)self) != 0)
2666                 return NULL;
2667         ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2668         Py_DECREF(dict);
2669         return ret;
2670 }
2671
2672 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2673 {
2674         talloc_free(self->mem_ctx);
2675         PyObject_Del(self);
2676 }
2677
2678 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2679                               PyLdbMessageObject *py_msg2)
2680 {
2681         struct ldb_message *msg1 = PyLdbMessage_AsMessage(py_msg1),
2682                            *msg2 = PyLdbMessage_AsMessage(py_msg2);
2683         unsigned int i;
2684         int ret;
2685
2686         if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
2687                 ret = ldb_dn_compare(msg1->dn, msg2->dn);
2688                 if (ret != 0) {
2689                         return SIGN(ret);
2690                 }
2691         }
2692
2693         ret = msg1->num_elements - msg2->num_elements;
2694         if (ret != 0) {
2695                 return SIGN(ret);
2696         }
2697
2698         for (i = 0; i < msg1->num_elements; i++) {
2699                 ret = ldb_msg_element_compare_name(&msg1->elements[i],
2700                                                    &msg2->elements[i]);
2701                 if (ret != 0) {
2702                         return SIGN(ret);
2703                 }
2704
2705                 ret = ldb_msg_element_compare(&msg1->elements[i],
2706                                               &msg2->elements[i]);
2707                 if (ret != 0) {
2708                         return SIGN(ret);
2709                 }
2710         }
2711
2712         return 0;
2713 }
2714
2715 static PyTypeObject PyLdbMessage = {
2716         .tp_name = "ldb.Message",
2717         .tp_methods = py_ldb_msg_methods,
2718         .tp_getset = py_ldb_msg_getset,
2719         .tp_as_mapping = &py_ldb_msg_mapping,
2720         .tp_basicsize = sizeof(PyLdbMessageObject),
2721         .tp_dealloc = (destructor)py_ldb_msg_dealloc,
2722         .tp_new = py_ldb_msg_new,
2723         .tp_repr = (reprfunc)py_ldb_msg_repr,
2724         .tp_flags = Py_TPFLAGS_DEFAULT,
2725         .tp_iter = (getiterfunc)py_ldb_msg_iter,
2726         .tp_compare = (cmpfunc)py_ldb_msg_compare,
2727 };
2728
2729 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
2730 {
2731         PyLdbTreeObject *ret;
2732
2733         ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
2734         if (ret == NULL) {
2735                 PyErr_NoMemory();
2736                 return NULL;
2737         }
2738
2739         ret->mem_ctx = talloc_new(NULL);
2740         ret->tree = talloc_reference(ret->mem_ctx, tree);
2741         return (PyObject *)ret;
2742 }
2743
2744 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
2745 {
2746         talloc_free(self->mem_ctx);
2747         PyObject_Del(self);
2748 }
2749
2750 static PyTypeObject PyLdbTree = {
2751         .tp_name = "ldb.Tree",
2752         .tp_basicsize = sizeof(PyLdbTreeObject),
2753         .tp_dealloc = (destructor)py_ldb_tree_dealloc,
2754         .tp_flags = Py_TPFLAGS_DEFAULT,
2755 };
2756
2757 /* Ldb_module */
2758 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
2759 {
2760         PyObject *py_ldb = (PyObject *)mod->private_data;
2761         PyObject *py_result, *py_base, *py_attrs, *py_tree;
2762
2763         py_base = PyLdbDn_FromDn(req->op.search.base);
2764
2765         if (py_base == NULL)
2766                 return LDB_ERR_OPERATIONS_ERROR;
2767
2768         py_tree = PyLdbTree_FromTree(req->op.search.tree);
2769
2770         if (py_tree == NULL)
2771                 return LDB_ERR_OPERATIONS_ERROR;
2772
2773         if (req->op.search.attrs == NULL) {
2774                 py_attrs = Py_None;
2775         } else {
2776                 int i, len;
2777                 for (len = 0; req->op.search.attrs[len]; len++);
2778                 py_attrs = PyList_New(len);
2779                 for (i = 0; i < len; i++)
2780                         PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
2781         }
2782
2783         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
2784                                         discard_const_p(char, "OiOO"),
2785                                         py_base, req->op.search.scope, py_tree, py_attrs);
2786
2787         Py_DECREF(py_attrs);
2788         Py_DECREF(py_tree);
2789         Py_DECREF(py_base);
2790
2791         if (py_result == NULL) {
2792                 return LDB_ERR_PYTHON_EXCEPTION;
2793         }
2794
2795         req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
2796         if (req->op.search.res == NULL) {
2797                 return LDB_ERR_PYTHON_EXCEPTION;
2798         }
2799
2800         Py_DECREF(py_result);
2801
2802         return LDB_SUCCESS;
2803 }
2804
2805 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
2806 {
2807         PyObject *py_ldb = (PyObject *)mod->private_data;
2808         PyObject *py_result, *py_msg;
2809
2810         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
2811
2812         if (py_msg == NULL) {
2813                 return LDB_ERR_OPERATIONS_ERROR;
2814         }
2815
2816         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
2817                                         discard_const_p(char, "O"),
2818                                         py_msg);
2819
2820         Py_DECREF(py_msg);
2821
2822         if (py_result == NULL) {
2823                 return LDB_ERR_PYTHON_EXCEPTION;
2824         }
2825
2826         Py_DECREF(py_result);
2827
2828         return LDB_SUCCESS;
2829 }
2830
2831 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
2832 {
2833         PyObject *py_ldb = (PyObject *)mod->private_data;
2834         PyObject *py_result, *py_msg;
2835
2836         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
2837
2838         if (py_msg == NULL) {
2839                 return LDB_ERR_OPERATIONS_ERROR;
2840         }
2841
2842         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
2843                                         discard_const_p(char, "O"),
2844                                         py_msg);
2845
2846         Py_DECREF(py_msg);
2847
2848         if (py_result == NULL) {
2849                 return LDB_ERR_PYTHON_EXCEPTION;
2850         }
2851
2852         Py_DECREF(py_result);
2853
2854         return LDB_SUCCESS;
2855 }
2856
2857 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
2858 {
2859         PyObject *py_ldb = (PyObject *)mod->private_data;
2860         PyObject *py_result, *py_dn;
2861
2862         py_dn = PyLdbDn_FromDn(req->op.del.dn);
2863
2864         if (py_dn == NULL)
2865                 return LDB_ERR_OPERATIONS_ERROR;
2866
2867         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
2868                                         discard_const_p(char, "O"),
2869                                         py_dn);
2870
2871         if (py_result == NULL) {
2872                 return LDB_ERR_PYTHON_EXCEPTION;
2873         }
2874
2875         Py_DECREF(py_result);
2876
2877         return LDB_SUCCESS;
2878 }
2879
2880 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
2881 {
2882         PyObject *py_ldb = (PyObject *)mod->private_data;
2883         PyObject *py_result, *py_olddn, *py_newdn;
2884
2885         py_olddn = PyLdbDn_FromDn(req->op.rename.olddn);
2886
2887         if (py_olddn == NULL)
2888                 return LDB_ERR_OPERATIONS_ERROR;
2889
2890         py_newdn = PyLdbDn_FromDn(req->op.rename.newdn);
2891
2892         if (py_newdn == NULL)
2893                 return LDB_ERR_OPERATIONS_ERROR;
2894
2895         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
2896                                         discard_const_p(char, "OO"),
2897                                         py_olddn, py_newdn);
2898
2899         Py_DECREF(py_olddn);
2900         Py_DECREF(py_newdn);
2901
2902         if (py_result == NULL) {
2903                 return LDB_ERR_PYTHON_EXCEPTION;
2904         }
2905
2906         Py_DECREF(py_result);
2907
2908         return LDB_SUCCESS;
2909 }
2910
2911 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
2912 {
2913         PyObject *py_ldb = (PyObject *)mod->private_data;
2914         PyObject *py_result;
2915
2916         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
2917                                         discard_const_p(char, ""));
2918
2919         return LDB_ERR_OPERATIONS_ERROR;
2920 }
2921
2922 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
2923 {
2924         PyObject *py_ldb = (PyObject *)mod->private_data;
2925         PyObject *py_result;
2926
2927         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
2928                                         discard_const_p(char, ""));
2929
2930         return LDB_ERR_OPERATIONS_ERROR;
2931 }
2932
2933 static int py_module_start_transaction(struct ldb_module *mod)
2934 {
2935         PyObject *py_ldb = (PyObject *)mod->private_data;
2936         PyObject *py_result;
2937
2938         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
2939                                         discard_const_p(char, ""));
2940
2941         if (py_result == NULL) {
2942                 return LDB_ERR_PYTHON_EXCEPTION;
2943         }
2944
2945         Py_DECREF(py_result);
2946
2947         return LDB_SUCCESS;
2948 }
2949
2950 static int py_module_end_transaction(struct ldb_module *mod)
2951 {
2952         PyObject *py_ldb = (PyObject *)mod->private_data;
2953         PyObject *py_result;
2954
2955         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
2956                                         discard_const_p(char, ""));
2957
2958         if (py_result == NULL) {
2959                 return LDB_ERR_PYTHON_EXCEPTION;
2960         }
2961
2962         Py_DECREF(py_result);
2963
2964         return LDB_SUCCESS;
2965 }
2966
2967 static int py_module_del_transaction(struct ldb_module *mod)
2968 {
2969         PyObject *py_ldb = (PyObject *)mod->private_data;
2970         PyObject *py_result;
2971
2972         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
2973                                         discard_const_p(char, ""));
2974
2975         if (py_result == NULL) {
2976                 return LDB_ERR_PYTHON_EXCEPTION;
2977         }
2978
2979         Py_DECREF(py_result);
2980
2981         return LDB_SUCCESS;
2982 }
2983
2984 static int py_module_destructor(struct ldb_module *mod)
2985 {
2986         Py_DECREF((PyObject *)mod->private_data);
2987         return 0;
2988 }
2989
2990 static int py_module_init(struct ldb_module *mod)
2991 {
2992         PyObject *py_class = (PyObject *)mod->ops->private_data;
2993         PyObject *py_result, *py_next, *py_ldb;
2994
2995         py_ldb = PyLdb_FromLdbContext(mod->ldb);
2996
2997         if (py_ldb == NULL)
2998                 return LDB_ERR_OPERATIONS_ERROR;
2999
3000         py_next = PyLdbModule_FromModule(mod->next);
3001
3002         if (py_next == NULL)
3003                 return LDB_ERR_OPERATIONS_ERROR;
3004
3005         py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3006                                           py_ldb, py_next);
3007
3008         if (py_result == NULL) {
3009                 return LDB_ERR_PYTHON_EXCEPTION;
3010         }
3011
3012         mod->private_data = py_result;
3013
3014         talloc_set_destructor(mod, py_module_destructor);
3015
3016         return ldb_next_init(mod);
3017 }
3018
3019 static PyObject *py_register_module(PyObject *module, PyObject *args)
3020 {
3021         int ret;
3022         struct ldb_module_ops *ops;
3023         PyObject *input;
3024
3025         if (!PyArg_ParseTuple(args, "O", &input))
3026                 return NULL;
3027
3028         ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3029         if (ops == NULL) {
3030                 PyErr_NoMemory();
3031                 return NULL;
3032         }
3033
3034         ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3035
3036         Py_INCREF(input);
3037         ops->private_data = input;
3038         ops->init_context = py_module_init;
3039         ops->search = py_module_search;
3040         ops->add = py_module_add;
3041         ops->modify = py_module_modify;
3042         ops->del = py_module_del;
3043         ops->rename = py_module_rename;
3044         ops->request = py_module_request;
3045         ops->extended = py_module_extended;
3046         ops->start_transaction = py_module_start_transaction;
3047         ops->end_transaction = py_module_end_transaction;
3048         ops->del_transaction = py_module_del_transaction;
3049
3050         ret = ldb_register_module(ops);
3051
3052         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3053
3054         Py_RETURN_NONE;
3055 }
3056
3057 static PyObject *py_timestring(PyObject *module, PyObject *args)
3058 {
3059         /* most times "time_t" is a signed integer type with 32 or 64 bit:
3060          * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3061         long int t_val;
3062         char *tresult;
3063         PyObject *ret;
3064         if (!PyArg_ParseTuple(args, "l", &t_val))
3065                 return NULL;
3066         tresult = ldb_timestring(NULL, (time_t) t_val);
3067         ret = PyString_FromString(tresult);
3068         talloc_free(tresult);
3069         return ret;
3070 }
3071
3072 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3073 {
3074         char *str;
3075         if (!PyArg_ParseTuple(args, "s", &str))
3076                 return NULL;
3077
3078         return PyInt_FromLong(ldb_string_to_time(str));
3079 }
3080
3081 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3082 {
3083         char *name;
3084         if (!PyArg_ParseTuple(args, "s", &name))
3085                 return NULL;
3086         return PyBool_FromLong(ldb_valid_attr_name(name));
3087 }
3088
3089 static PyMethodDef py_ldb_global_methods[] = {
3090         { "register_module", py_register_module, METH_VARARGS, 
3091                 "S.register_module(module) -> None\n"
3092                 "Register a LDB module."},
3093         { "timestring", py_timestring, METH_VARARGS, 
3094                 "S.timestring(int) -> string\n"
3095                 "Generate a LDAP time string from a UNIX timestamp" },
3096         { "string_to_time", py_string_to_time, METH_VARARGS,
3097                 "S.string_to_time(string) -> int\n"
3098                 "Parse a LDAP time string into a UNIX timestamp." },
3099         { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3100                 "S.valid_attr_name(name) -> bool\n"
3101                 "Check whether the supplied name is a valid attribute name." },
3102         { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3103                 NULL },
3104         { NULL }
3105 };
3106
3107 void initldb(void)
3108 {
3109         PyObject *m;
3110
3111         if (PyType_Ready(&PyLdbDn) < 0)
3112                 return;
3113
3114         if (PyType_Ready(&PyLdbMessage) < 0)
3115                 return;
3116
3117         if (PyType_Ready(&PyLdbMessageElement) < 0)
3118                 return;
3119
3120         if (PyType_Ready(&PyLdb) < 0)
3121                 return;
3122
3123         if (PyType_Ready(&PyLdbModule) < 0)
3124                 return;
3125
3126         if (PyType_Ready(&PyLdbTree) < 0)
3127                 return;
3128
3129         if (PyType_Ready(&PyLdbResult) < 0)
3130                 return;
3131
3132         if (PyType_Ready(&PyLdbControl) < 0)
3133                 return;
3134
3135         m = Py_InitModule3("ldb", py_ldb_global_methods, 
3136                 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3137         if (m == NULL)
3138                 return;
3139
3140         PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3141         PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3142         PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3143         PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3144         PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3145         PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3146         PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3147
3148         PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3149         PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3150         PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3151         PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3152
3153         PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3154         PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3155         PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3156
3157         PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3158         PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3159         PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3160         PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3161         PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3162         PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3163         PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3164         PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3165         PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3166         PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3167         PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3168         PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3169         PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3170         PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3171         PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3172         PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3173         PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3174         PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3175         PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3176         PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3177         PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3178         PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3179         PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3180         PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3181         PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3182         PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3183         PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3184         PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3185         PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3186         PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3187         PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3188         PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3189         PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3190         PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3191         PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3192         PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3193         PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3194         PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3195         PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3196
3197         PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3198         PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3199         PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3200         PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3201
3202         PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3203
3204         PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3205         PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3206
3207         Py_INCREF(&PyLdb);
3208         Py_INCREF(&PyLdbDn);
3209         Py_INCREF(&PyLdbModule);
3210         Py_INCREF(&PyLdbMessage);
3211         Py_INCREF(&PyLdbMessageElement);
3212         Py_INCREF(&PyLdbTree);
3213         Py_INCREF(&PyLdbResult);
3214         Py_INCREF(&PyLdbControl);
3215
3216         PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3217         PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3218         PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3219         PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3220         PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3221         PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3222         PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3223
3224         PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3225
3226 #define ADD_LDB_STRING(val)  PyModule_AddObject(m, #val, PyString_FromString(val))
3227
3228         ADD_LDB_STRING(LDB_SYNTAX_DN);
3229         ADD_LDB_STRING(LDB_SYNTAX_DN);
3230         ADD_LDB_STRING(LDB_SYNTAX_DIRECTORY_STRING);
3231         ADD_LDB_STRING(LDB_SYNTAX_INTEGER);
3232         ADD_LDB_STRING(LDB_SYNTAX_BOOLEAN);
3233         ADD_LDB_STRING(LDB_SYNTAX_OCTET_STRING);
3234         ADD_LDB_STRING(LDB_SYNTAX_UTC_TIME);
3235 }