lib/ldb: Use new PYARG_ES format for parseTuple
[nivanova/samba-autobuild/.git] / 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    Copyright (C) 2009-2011 Andrew Tridgell
11    Copyright (C) 2009-2011 Andrew Bartlett
12
13     ** NOTE! The following LGPL license applies to the ldb
14     ** library. This does NOT imply that all of Samba is released
15     ** under the LGPL
16
17    This library is free software; you can redistribute it and/or
18    modify it under the terms of the GNU Lesser General Public
19    License as published by the Free Software Foundation; either
20    version 3 of the License, or (at your option) any later version.
21
22    This library is distributed in the hope that it will be useful,
23    but WITHOUT ANY WARRANTY; without even the implied warranty of
24    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25    Lesser General Public License for more details.
26
27    You should have received a copy of the GNU Lesser General Public
28    License along with this library; if not, see <http://www.gnu.org/licenses/>.
29 */
30
31 #include <Python.h>
32 #include "ldb_private.h"
33 #include "ldb_handlers.h"
34 #include "pyldb.h"
35 #include "dlinklist.h"
36
37 struct py_ldb_search_iterator_reply;
38
39 typedef struct {
40         PyObject_HEAD
41         TALLOC_CTX *mem_ctx;
42         PyLdbObject *ldb;
43         struct {
44                 struct ldb_request *req;
45                 struct py_ldb_search_iterator_reply *next;
46                 struct py_ldb_search_iterator_reply *result;
47                 PyObject *exception;
48         } state;
49 } PyLdbSearchIteratorObject;
50
51 struct py_ldb_search_iterator_reply {
52         struct py_ldb_search_iterator_reply *prev, *next;
53         PyLdbSearchIteratorObject *py_iter;
54         PyObject *obj;
55 };
56
57 void initldb(void);
58 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
59 static PyObject *PyExc_LdbError;
60
61 static PyTypeObject PyLdbControl;
62 static PyTypeObject PyLdbResult;
63 static PyTypeObject PyLdbSearchIterator;
64 static PyTypeObject PyLdbMessage;
65 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
66 static PyTypeObject PyLdbModule;
67 static PyTypeObject PyLdbDn;
68 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
69 static PyTypeObject PyLdb;
70 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
71 static PyTypeObject PyLdbMessageElement;
72 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
73
74 static PyTypeObject PyLdbTree;
75 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
76 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
77 static struct ldb_message_element *PyObject_AsMessageElement(
78                                                       TALLOC_CTX *mem_ctx,
79                                                       PyObject *set_obj,
80                                                       unsigned int flags,
81                                                       const char *attr_name);
82 static PyTypeObject PyLdbBytesType;
83
84 #if PY_MAJOR_VERSION >= 3
85 #define PyStr_Check PyUnicode_Check
86 #define PyStr_FromString PyUnicode_FromString
87 #define PyStr_FromStringAndSize PyUnicode_FromStringAndSize
88 #define PyStr_FromFormat PyUnicode_FromFormat
89 #define PyStr_FromFormatV PyUnicode_FromFormatV
90 #define PyStr_AsUTF8 PyUnicode_AsUTF8
91 #define PyStr_AsUTF8AndSize PyUnicode_AsUTF8AndSize
92 #define PyInt_FromLong PyLong_FromLong
93
94 #define PYARG_STR_UNI "es"
95
96 static PyObject *PyLdbBytes_FromStringAndSize(const char *msg, int size)
97 {
98         PyObject* result = NULL;
99         PyObject* args = NULL;
100         args = Py_BuildValue("(y#)", msg, size);
101         result = PyLdbBytesType.tp_new(&PyLdbBytesType, args, NULL);
102         Py_DECREF(args);
103         return result;
104 }
105 #else
106 #define PyStr_Check PyString_Check
107 #define PyStr_FromString PyString_FromString
108 #define PyStr_FromStringAndSize PyString_FromStringAndSize
109 #define PyStr_FromFormat PyString_FromFormat
110 #define PyStr_FromFormatV PyString_FromFormatV
111 #define PyStr_AsUTF8 PyString_AsString
112 #define PyLdbBytes_FromStringAndSize PyString_FromStringAndSize
113
114 #define PYARG_STR_UNI "et"
115
116 const char *PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr);
117 const char *
118 PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr)
119 {
120         const char * ret = PyString_AsString(pystr);
121         if (ret == NULL)
122                 return NULL;
123         *sizeptr = PyString_Size(pystr);
124         return ret;
125 }
126 #endif
127
128 static PyObject *richcmp(int cmp_val, int op)
129 {
130         int ret;
131         switch (op) {
132                 case Py_LT: ret = cmp_val < 0;  break;
133                 case Py_LE: ret = cmp_val <= 0; break;
134                 case Py_EQ: ret = cmp_val == 0; break;
135                 case Py_NE: ret = cmp_val != 0; break;
136                 case Py_GT: ret = cmp_val > 0;  break;
137                 case Py_GE: ret = cmp_val >= 0; break;
138                 default:
139                         Py_INCREF(Py_NotImplemented);
140                         return Py_NotImplemented;
141         }
142         return PyBool_FromLong(ret);
143 }
144
145
146 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
147 {
148         if (self->data != NULL) {
149                 char* control = ldb_control_to_string(self->mem_ctx, self->data);
150                 if (control == NULL) {
151                         PyErr_NoMemory();
152                         return NULL;
153                 }
154                 return PyStr_FromString(control);
155         } else {
156                 return PyStr_FromString("ldb control");
157         }
158 }
159
160 static void py_ldb_control_dealloc(PyLdbControlObject *self)
161 {
162         if (self->mem_ctx != NULL) {
163                 talloc_free(self->mem_ctx);
164         }
165         self->data = NULL;
166         Py_TYPE(self)->tp_free(self);
167 }
168
169 /* Create a text (rather than bytes) interface for a LDB result object */
170 static PyObject *wrap_text(const char *type, PyObject *wrapped)
171 {
172         PyObject *mod, *cls, *constructor, *inst;
173         mod = PyImport_ImportModule("_ldb_text");
174         if (mod == NULL)
175                 return NULL;
176         cls = PyObject_GetAttrString(mod, type);
177         Py_DECREF(mod);
178         if (cls == NULL) {
179                 Py_DECREF(mod);
180                 return NULL;
181         }
182         constructor = PyObject_GetAttrString(cls, "_wrap");
183         Py_DECREF(cls);
184         if (constructor == NULL) {
185                 return NULL;
186         }
187         inst = PyObject_CallFunction(constructor, discard_const_p(char, "O"), wrapped);
188         Py_DECREF(constructor);
189         return inst;
190 }
191
192 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
193 {
194         return PyStr_FromString(self->data->oid);
195 }
196
197 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
198 {
199         return PyBool_FromLong(self->data->critical);
200 }
201
202 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
203 {
204         if (PyObject_IsTrue(value)) {
205                 self->data->critical = true;
206         } else {
207                 self->data->critical = false;
208         }
209         return 0;
210 }
211
212 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
213 {
214         char *data = NULL;
215         const char * const kwnames[] = { "ldb", "data", NULL };
216         struct ldb_control *parsed_controls;
217         PyLdbControlObject *ret;
218         PyObject *py_ldb;
219         TALLOC_CTX *mem_ctx;
220         struct ldb_context *ldb_ctx;
221
222         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s",
223                                          discard_const_p(char *, kwnames),
224                                          &PyLdb, &py_ldb, &data))
225                 return NULL;
226
227         mem_ctx = talloc_new(NULL);
228         if (mem_ctx == NULL) {
229                 PyErr_NoMemory();
230                 return NULL;
231         }
232
233         ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
234         parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
235
236         if (!parsed_controls) {
237                 talloc_free(mem_ctx);
238                 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
239                 return NULL;
240         }
241
242         ret = PyObject_New(PyLdbControlObject, type);
243         if (ret == NULL) {
244                 PyErr_NoMemory();
245                 talloc_free(mem_ctx);
246                 return NULL;
247         }
248
249         ret->mem_ctx = mem_ctx;
250
251         ret->data = talloc_move(mem_ctx, &parsed_controls);
252         if (ret->data == NULL) {
253                 Py_DECREF(ret);
254                 PyErr_NoMemory();
255                 talloc_free(mem_ctx);
256                 return NULL;
257         }
258
259         return (PyObject *)ret;
260 }
261
262 static PyGetSetDef py_ldb_control_getset[] = {
263         { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
264         { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
265         { NULL }
266 };
267
268 static PyTypeObject PyLdbControl = {
269         .tp_name = "ldb.control",
270         .tp_dealloc = (destructor)py_ldb_control_dealloc,
271         .tp_getattro = PyObject_GenericGetAttr,
272         .tp_basicsize = sizeof(PyLdbControlObject),
273         .tp_getset = py_ldb_control_getset,
274         .tp_doc = "LDB control.",
275         .tp_str = (reprfunc)py_ldb_control_str,
276         .tp_new = py_ldb_control_new,
277         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
278 };
279
280 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
281 {
282         if (ret == LDB_ERR_PYTHON_EXCEPTION)
283                 return; /* Python exception should already be set, just keep that */
284
285         PyErr_SetObject(error, 
286                         Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
287                                       ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
288 }
289 static PyObject *py_ldb_bytes_str(PyBytesObject *self)
290 {
291         char *msg = NULL;
292         Py_ssize_t size;
293         int result = 0;
294         if (!PyBytes_Check(self)) {
295                 PyErr_Format(PyExc_TypeError,"Unexpected type");
296                 return NULL;
297         }
298         result = PyBytes_AsStringAndSize((PyObject *)self, &msg, &size);
299         if (result != 0) {
300                 PyErr_Format(PyExc_TypeError, "Failed to extract bytes");
301                 return NULL;
302         }
303         return PyUnicode_FromStringAndSize(msg, size);
304 }
305
306 static PyTypeObject PyLdbBytesType = {
307         PyVarObject_HEAD_INIT(NULL, 0)
308         .tp_name = "ldb.bytes",
309         .tp_doc = "str/bytes (with custom str)",
310         .tp_str = (reprfunc)py_ldb_bytes_str,
311         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
312 };
313
314 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
315 {
316         return PyLdbBytes_FromStringAndSize((const char *)val->data, val->length);
317 }
318
319 static PyObject *PyStr_FromLdbValue(const struct ldb_val *val)
320 {
321         return PyStr_FromStringAndSize((const char *)val->data, val->length);
322 }
323
324 /**
325  * Create a Python object from a ldb_result.
326  *
327  * @param result LDB result to convert
328  * @return Python object with converted result (a list object)
329  */
330 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
331 {
332         TALLOC_CTX *ctl_ctx = talloc_new(NULL);
333         PyLdbControlObject *ctrl;
334         if (ctl_ctx == NULL) {
335                 PyErr_NoMemory();
336                 return NULL;
337         }
338
339         ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
340         if (ctrl == NULL) {
341                 talloc_free(ctl_ctx);
342                 PyErr_NoMemory();
343                 return NULL;
344         }
345         ctrl->mem_ctx = ctl_ctx;
346         ctrl->data = talloc_steal(ctrl->mem_ctx, control);
347         if (ctrl->data == NULL) {
348                 Py_DECREF(ctrl);
349                 PyErr_NoMemory();
350                 return NULL;
351         }
352         return (PyObject*) ctrl;
353 }
354
355 /**
356  * Create a Python object from a ldb_result.
357  *
358  * @param result LDB result to convert
359  * @return Python object with converted result (a list object)
360  */
361 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
362 {
363         PyLdbResultObject *ret;
364         PyObject *list, *controls, *referals;
365         Py_ssize_t i;
366
367         if (result == NULL) {
368                 Py_RETURN_NONE;
369         }
370
371         ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
372         if (ret == NULL) {
373                 PyErr_NoMemory();
374                 return NULL;
375         }
376
377         list = PyList_New(result->count);
378         if (list == NULL) {
379                 PyErr_NoMemory();
380                 Py_DECREF(ret);
381                 return NULL;
382         }
383
384         for (i = 0; i < result->count; i++) {
385                 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
386         }
387
388         ret->mem_ctx = talloc_new(NULL);
389         if (ret->mem_ctx == NULL) {
390                 Py_DECREF(list);
391                 Py_DECREF(ret);
392                 PyErr_NoMemory();
393                 return NULL;
394         }
395
396         ret->msgs = list;
397
398         if (result->controls) {
399                 i = 0;
400                 while (result->controls[i]) {
401                         i++;
402                 }
403                 controls = PyList_New(i);
404                 if (controls == NULL) {
405                         Py_DECREF(ret);
406                         PyErr_NoMemory();
407                         return NULL;
408                 }
409                 for (i=0; result->controls[i]; i++) {
410                         PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
411                         if (ctrl == NULL) {
412                                 Py_DECREF(ret);
413                                 Py_DECREF(controls);
414                                 PyErr_NoMemory();
415                                 return NULL;
416                         }
417                         PyList_SetItem(controls, i, ctrl);
418                 }
419         } else {
420                 /*
421                  * No controls so we keep an empty list
422                  */
423                 controls = PyList_New(0);
424                 if (controls == NULL) {
425                         Py_DECREF(ret);
426                         PyErr_NoMemory();
427                         return NULL;
428                 }
429         }
430
431         ret->controls = controls;
432
433         i = 0;
434
435         while (result->refs && result->refs[i]) {
436                 i++;
437         }
438
439         referals = PyList_New(i);
440         if (referals == NULL) {
441                 Py_DECREF(ret);
442                 PyErr_NoMemory();
443                 return NULL;
444         }
445
446         for (i = 0;result->refs && result->refs[i]; i++) {
447                 PyList_SetItem(referals, i, PyStr_FromString(result->refs[i]));
448         }
449         ret->referals = referals;
450         return (PyObject *)ret;
451 }
452
453 /**
454  * Create a LDB Result from a Python object.
455  * If conversion fails, NULL will be returned and a Python exception set.
456  *
457  * Note: the result object only includes the messages at the moment; extended
458  * result, controls and referrals are ignored.
459  *
460  * @param mem_ctx Memory context in which to allocate the LDB Result
461  * @param obj Python object to convert
462  * @return a ldb_result, or NULL if the conversion failed
463  */
464 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, 
465                                                PyObject *obj)
466 {
467         struct ldb_result *res;
468         Py_ssize_t i;
469
470         if (obj == Py_None)
471                 return NULL;
472
473         res = talloc_zero(mem_ctx, struct ldb_result);
474         res->count = PyList_Size(obj);
475         res->msgs = talloc_array(res, struct ldb_message *, res->count);
476         for (i = 0; i < res->count; i++) {
477                 PyObject *item = PyList_GetItem(obj, i);
478                 res->msgs[i] = pyldb_Message_AsMessage(item);
479         }
480         return res;
481 }
482
483 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
484 {
485         return PyBool_FromLong(ldb_dn_validate(self->dn));
486 }
487
488 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
489 {
490         return PyBool_FromLong(ldb_dn_is_valid(self->dn));
491 }
492
493 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
494 {
495         return PyBool_FromLong(ldb_dn_is_special(self->dn));
496 }
497
498 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
499 {
500         return PyBool_FromLong(ldb_dn_is_null(self->dn));
501 }
502  
503 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
504 {
505         return PyStr_FromString(ldb_dn_get_casefold(self->dn));
506 }
507
508 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
509 {
510         return PyStr_FromString(ldb_dn_get_linearized(self->dn));
511 }
512
513 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
514 {
515         return PyStr_FromString(ldb_dn_canonical_string(self->dn, self->dn));
516 }
517
518 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
519 {
520         return PyStr_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
521 }
522
523 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
524 {
525         const char * const kwnames[] = { "mode", NULL };
526         int mode = 1;
527         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
528                                          discard_const_p(char *, kwnames),
529                                          &mode))
530                 return NULL;
531         return PyStr_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
532 }
533
534 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
535 {
536         char *name;
537         const struct ldb_val *val;
538
539         if (!PyArg_ParseTuple(args, "s", &name))
540                 return NULL;
541         val = ldb_dn_get_extended_component(self->dn, name);
542         if (val == NULL) {
543                 Py_RETURN_NONE;
544         }
545
546         return PyBytes_FromStringAndSize((const char *)val->data, val->length);
547 }
548
549 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
550 {
551         char *name;
552         int err;
553         uint8_t *value = NULL;
554         Py_ssize_t size = 0;
555
556         if (!PyArg_ParseTuple(args, "sz#", &name, (char **)&value, &size))
557                 return NULL;
558
559         if (value == NULL) {
560                 err = ldb_dn_set_extended_component(self->dn, name, NULL);
561         } else {
562                 struct ldb_val val;
563                 val.data = (uint8_t *)value;
564                 val.length = size;
565                 err = ldb_dn_set_extended_component(self->dn, name, &val);
566         }
567
568         if (err != LDB_SUCCESS) {
569                 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
570                 return NULL;
571         }
572
573         Py_RETURN_NONE;
574 }
575
576 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
577 {
578         PyObject *str = PyStr_FromString(ldb_dn_get_linearized(self->dn));
579         PyObject *repr, *result;
580         if (str == NULL)
581                 return NULL;
582         repr = PyObject_Repr(str);
583         if (repr == NULL) {
584                 Py_DECREF(str);
585                 return NULL;
586         }
587         result = PyStr_FromFormat("Dn(%s)", PyStr_AsUTF8(repr));
588         Py_DECREF(str);
589         Py_DECREF(repr);
590         return result;
591 }
592
593 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
594 {
595         char *name;
596
597         if (!PyArg_ParseTuple(args, "s", &name))
598                 return NULL;
599
600         return PyBool_FromLong(ldb_dn_check_special(self->dn, name));
601 }
602
603 static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op)
604 {
605         int ret;
606         if (!pyldb_Dn_Check(dn2)) {
607                 Py_INCREF(Py_NotImplemented);
608                 return Py_NotImplemented;
609         }
610         ret = ldb_dn_compare(pyldb_Dn_AsDn(dn1), pyldb_Dn_AsDn(dn2));
611         return richcmp(ret, op);
612 }
613
614 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
615 {
616         struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
617         struct ldb_dn *parent;
618         PyLdbDnObject *py_ret;
619         TALLOC_CTX *mem_ctx = talloc_new(NULL);
620
621         parent = ldb_dn_get_parent(mem_ctx, dn);
622         if (parent == NULL) {
623                 talloc_free(mem_ctx);
624                 Py_RETURN_NONE;
625         }
626
627         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
628         if (py_ret == NULL) {
629                 PyErr_NoMemory();
630                 talloc_free(mem_ctx);
631                 return NULL;
632         }
633         py_ret->mem_ctx = mem_ctx;
634         py_ret->dn = parent;
635         return (PyObject *)py_ret;
636 }
637
638 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
639 {
640         PyObject *py_other;
641         struct ldb_dn *dn, *other;
642         if (!PyArg_ParseTuple(args, "O", &py_other))
643                 return NULL;
644
645         dn = pyldb_Dn_AsDn((PyObject *)self);
646
647         if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
648                 return NULL;
649
650         return PyBool_FromLong(ldb_dn_add_child(dn, other));
651 }
652
653 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
654 {
655         PyObject *py_other;
656         struct ldb_dn *other, *dn;
657         if (!PyArg_ParseTuple(args, "O", &py_other))
658                 return NULL;
659
660         dn = pyldb_Dn_AsDn((PyObject *)self);
661
662         if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
663                 return NULL;
664
665         return PyBool_FromLong(ldb_dn_add_base(dn, other));
666 }
667
668 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
669 {
670         struct ldb_dn *dn;
671         int i;
672         if (!PyArg_ParseTuple(args, "i", &i))
673                 return NULL;
674
675         dn = pyldb_Dn_AsDn((PyObject *)self);
676
677         return PyBool_FromLong(ldb_dn_remove_base_components(dn, i));
678 }
679
680 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
681 {
682         PyObject *py_base;
683         struct ldb_dn *dn, *base;
684         if (!PyArg_ParseTuple(args, "O", &py_base))
685                 return NULL;
686
687         dn = pyldb_Dn_AsDn((PyObject *)self);
688
689         if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base))
690                 return NULL;
691
692         return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
693 }
694
695 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
696 {
697         struct ldb_dn *dn;
698         const char *name;
699         unsigned int num = 0;
700
701         if (!PyArg_ParseTuple(args, "I", &num))
702                 return NULL;
703
704         dn = pyldb_Dn_AsDn((PyObject *)self);
705
706         name = ldb_dn_get_component_name(dn, num);
707         if (name == NULL) {
708                 Py_RETURN_NONE;
709         }
710
711         return PyStr_FromString(name);
712 }
713
714 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
715 {
716         struct ldb_dn *dn;
717         const struct ldb_val *val;
718         unsigned int num = 0;
719
720         if (!PyArg_ParseTuple(args, "I", &num))
721                 return NULL;
722
723         dn = pyldb_Dn_AsDn((PyObject *)self);
724
725         val = ldb_dn_get_component_val(dn, num);
726         if (val == NULL) {
727                 Py_RETURN_NONE;
728         }
729
730         return PyStr_FromLdbValue(val);
731 }
732
733 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
734 {
735         unsigned int num = 0;
736         char *name = NULL, *value = NULL;
737         struct ldb_val val = { NULL, };
738         int err;
739         Py_ssize_t size = 0;
740
741         if (!PyArg_ParseTuple(args, "Iss#", &num, &name, &value, &size))
742                 return NULL;
743
744         val.data = (unsigned char*) value;
745         val.length = size;
746
747         err = ldb_dn_set_component(self->dn, num, name, val);
748         if (err != LDB_SUCCESS) {
749                 PyErr_SetString(PyExc_TypeError, "Failed to set component");
750                 return NULL;
751         }
752
753         Py_RETURN_NONE;
754 }
755
756 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self)
757 {
758         struct ldb_dn *dn;
759         const char *name;
760
761         dn = pyldb_Dn_AsDn((PyObject *)self);
762
763         name = ldb_dn_get_rdn_name(dn);
764         if (name == NULL) {
765                 Py_RETURN_NONE;
766         }
767
768         return PyStr_FromString(name);
769 }
770
771 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self)
772 {
773         struct ldb_dn *dn;
774         const struct ldb_val *val;
775
776         dn = pyldb_Dn_AsDn((PyObject *)self);
777
778         val = ldb_dn_get_rdn_val(dn);
779         if (val == NULL) {
780                 Py_RETURN_NONE;
781         }
782
783         return PyStr_FromLdbValue(val);
784 }
785
786 static PyMethodDef py_ldb_dn_methods[] = {
787         { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS, 
788                 "S.validate() -> bool\n"
789                 "Validate DN is correct." },
790         { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
791                 "S.is_valid() -> bool\n" },
792         { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
793                 "S.is_special() -> bool\n"
794                 "Check whether this is a special LDB DN." },
795         { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
796                 "Check whether this is a null DN." },
797         { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
798                 NULL },
799         { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
800                 NULL },
801         { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
802                 "S.canonical_str() -> string\n"
803                 "Canonical version of this DN (like a posix path)." },
804         { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
805                 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
806         { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
807                 "S.canonical_ex_str() -> string\n"
808                 "Canonical version of this DN (like a posix path, with terminating newline)." },
809         { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
810                 "S.extended_str(mode=1) -> string\n"
811                 "Extended version of this DN" },
812         { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
813                 "S.parent() -> dn\n"
814                 "Get the parent for this DN." },
815         { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS, 
816                 "S.add_child(dn) -> None\n"
817                 "Add a child DN to this DN." },
818         { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
819                 "S.add_base(dn) -> None\n"
820                 "Add a base DN to this DN." },
821         { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
822                 "S.remove_base_components(int) -> bool\n"
823                 "Remove a number of DN components from the base of this DN." },
824         { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
825                 "S.check_special(name) -> bool\n\n"
826                 "Check if name is a special DN name"},
827         { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
828                 "S.get_extended_component(name) -> string\n\n"
829                 "returns a DN extended component as a binary string"},
830         { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
831                 "S.set_extended_component(name, value) -> None\n\n"
832                 "set a DN extended component as a binary string"},
833         { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
834                 "S.get_component_name(num) -> string\n"
835                 "get the attribute name of the specified component" },
836         { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
837                 "S.get_component_value(num) -> string\n"
838                 "get the attribute value of the specified component as a binary string" },
839         { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
840                 "S.get_component_value(num, name, value) -> None\n"
841                 "set the attribute name and value of the specified component" },
842         { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
843                 "S.get_rdn_name() -> string\n"
844                 "get the RDN attribute name" },
845         { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
846                 "S.get_rdn_value() -> string\n"
847                 "get the RDN attribute value as a binary string" },
848         { NULL }
849 };
850
851 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
852 {
853         return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
854 }
855
856 /*
857   copy a DN as a python object
858  */
859 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
860 {
861         PyLdbDnObject *py_ret;
862
863         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
864         if (py_ret == NULL) {
865                 PyErr_NoMemory();
866                 return NULL;
867         }
868         py_ret->mem_ctx = talloc_new(NULL);
869         py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
870         return (PyObject *)py_ret;
871 }
872
873 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
874 {
875         struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self), 
876                                   *other;
877         PyLdbDnObject *py_ret;
878
879         if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
880                 return NULL;
881
882         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
883         if (py_ret == NULL) {
884                 PyErr_NoMemory();
885                 return NULL;
886         }
887         py_ret->mem_ctx = talloc_new(NULL);
888         py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
889         ldb_dn_add_base(py_ret->dn, other);
890         return (PyObject *)py_ret;
891 }
892
893 static PySequenceMethods py_ldb_dn_seq = {
894         .sq_length = (lenfunc)py_ldb_dn_len,
895         .sq_concat = (binaryfunc)py_ldb_dn_concat,
896 };
897
898 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
899 {
900         struct ldb_dn *ret = NULL;
901         char *str = NULL;
902         PyObject *py_ldb = NULL;
903         struct ldb_context *ldb_ctx = NULL;
904         TALLOC_CTX *mem_ctx = NULL;
905         PyLdbDnObject *py_ret = NULL;
906         const char * const kwnames[] = { "ldb", "dn", NULL };
907
908         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O"PYARG_STR_UNI,
909                                          discard_const_p(char *, kwnames),
910                                          &py_ldb, "utf8", &str))
911                 goto out;
912
913         if (!PyLdb_Check(py_ldb)) {
914                 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
915                 goto out;
916         }
917
918         ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
919
920         mem_ctx = talloc_new(NULL);
921         if (mem_ctx == NULL) {
922                 PyErr_NoMemory();
923                 goto out;
924         }
925
926         ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
927         if (!ldb_dn_validate(ret)) {
928                 talloc_free(mem_ctx);
929                 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
930                 goto out;
931         }
932
933         py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
934         if (py_ret == NULL) {
935                 talloc_free(mem_ctx);
936                 PyErr_NoMemory();
937                 goto out;
938         }
939         py_ret->mem_ctx = mem_ctx;
940         py_ret->dn = ret;
941 out:
942         if (str != NULL) {
943                 PyMem_Free(discard_const_p(char, str));
944         }
945         return (PyObject *)py_ret;
946 }
947
948 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
949 {
950         talloc_free(self->mem_ctx);
951         PyObject_Del(self);
952 }
953
954 static PyTypeObject PyLdbDn = {
955         .tp_name = "ldb.Dn",
956         .tp_methods = py_ldb_dn_methods,
957         .tp_str = (reprfunc)py_ldb_dn_get_linearized,
958         .tp_repr = (reprfunc)py_ldb_dn_repr,
959         .tp_richcompare = (richcmpfunc)py_ldb_dn_richcmp,
960         .tp_as_sequence = &py_ldb_dn_seq,
961         .tp_doc = "A LDB distinguished name.",
962         .tp_new = py_ldb_dn_new,
963         .tp_dealloc = (destructor)py_ldb_dn_dealloc,
964         .tp_basicsize = sizeof(PyLdbDnObject),
965         .tp_flags = Py_TPFLAGS_DEFAULT,
966 };
967
968 /* Debug */
969 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
970 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
971 {
972         PyObject *fn = (PyObject *)context;
973         PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyStr_FromFormatV(fmt, ap));
974 }
975
976 static PyObject *py_ldb_debug_func;
977
978 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
979 {
980         PyObject *cb;
981         struct ldb_context *ldb_ctx;
982
983         if (!PyArg_ParseTuple(args, "O", &cb))
984                 return NULL;
985
986         if (py_ldb_debug_func != NULL) {
987                 Py_DECREF(py_ldb_debug_func);
988         }
989
990         Py_INCREF(cb);
991         /* FIXME: DECREF cb when exiting program */
992         py_ldb_debug_func = cb;
993         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
994         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
995                 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
996                 ldb_ctx);
997
998         Py_RETURN_NONE;
999 }
1000
1001 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
1002 {
1003         unsigned int perms;
1004         if (!PyArg_ParseTuple(args, "I", &perms))
1005                 return NULL;
1006
1007         ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
1008
1009         Py_RETURN_NONE;
1010 }
1011
1012 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
1013 {
1014         char *modules_dir;
1015         if (!PyArg_ParseTuple(args, "s", &modules_dir))
1016                 return NULL;
1017
1018         ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
1019
1020         Py_RETURN_NONE;
1021 }
1022
1023 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
1024 {
1025         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1026         int ldb_err;
1027         ldb_err = ldb_transaction_start(ldb_ctx);
1028         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1029         Py_RETURN_NONE;
1030 }
1031
1032 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
1033 {
1034         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1035         int ldb_err;
1036         ldb_err = ldb_transaction_commit(ldb_ctx);
1037         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1038         Py_RETURN_NONE;
1039 }
1040
1041 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
1042 {
1043         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1044         int ldb_err;
1045         ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
1046         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1047         Py_RETURN_NONE;
1048 }
1049
1050 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
1051 {
1052         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1053         int ldb_err;
1054         ldb_err = ldb_transaction_cancel(ldb_ctx);
1055         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1056         Py_RETURN_NONE;
1057 }
1058
1059 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
1060 {
1061         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1062         int ldb_err;
1063         ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
1064         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1065         Py_RETURN_NONE;
1066 }
1067
1068 static PyObject *py_ldb_repr(PyLdbObject *self)
1069 {
1070         return PyStr_FromString("<ldb connection>");
1071 }
1072
1073 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
1074 {
1075         struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
1076         if (dn == NULL)
1077                 Py_RETURN_NONE;
1078         return py_ldb_dn_copy(dn);
1079 }
1080
1081
1082 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
1083 {
1084         struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
1085         if (dn == NULL)
1086                 Py_RETURN_NONE;
1087         return py_ldb_dn_copy(dn);
1088 }
1089
1090 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
1091 {
1092         struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
1093         if (dn == NULL)
1094                 Py_RETURN_NONE;
1095         return py_ldb_dn_copy(dn);
1096 }
1097
1098 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
1099 {
1100         struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
1101         if (dn == NULL)
1102                 Py_RETURN_NONE;
1103         return py_ldb_dn_copy(dn);
1104 }
1105
1106 static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list,
1107                     const char *paramname)
1108 {
1109         const char **ret;
1110         Py_ssize_t i;
1111         if (!PyList_Check(list)) {
1112                 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
1113                 return NULL;
1114         }
1115         ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
1116         if (ret == NULL) {
1117                 PyErr_NoMemory();
1118                 return NULL;
1119         }
1120
1121         for (i = 0; i < PyList_Size(list); i++) {
1122                 const char *str = NULL;
1123                 Py_ssize_t size;
1124                 PyObject *item = PyList_GetItem(list, i);
1125                 if (!(PyStr_Check(item) || PyUnicode_Check(item))) {
1126                         PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
1127                         talloc_free(ret);
1128                         return NULL;
1129                 }
1130                 str = PyStr_AsUTF8AndSize(item, &size);
1131                 if (str == NULL) {
1132                         talloc_free(ret);
1133                         return NULL;
1134                 }
1135                 ret[i] = talloc_strndup(ret, str, size);
1136         }
1137         ret[i] = NULL;
1138         return ret;
1139 }
1140
1141 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1142 {
1143         const char * const kwnames[] = { "url", "flags", "options", NULL };
1144         char *url = NULL;
1145         PyObject *py_options = Py_None;
1146         const char **options;
1147         unsigned int flags = 0;
1148         int ret;
1149         struct ldb_context *ldb;
1150
1151         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1152                                          discard_const_p(char *, kwnames),
1153                                          &url, &flags, &py_options))
1154                 return -1;
1155
1156         ldb = pyldb_Ldb_AsLdbContext(self);
1157
1158         if (py_options == Py_None) {
1159                 options = NULL;
1160         } else {
1161                 options = PyList_AsStrList(ldb, py_options, "options");
1162                 if (options == NULL)
1163                         return -1;
1164         }
1165
1166         if (url != NULL) {
1167                 ret = ldb_connect(ldb, url, flags, options);
1168                 if (ret != LDB_SUCCESS) {
1169                         PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1170                         return -1;
1171                 }
1172         }
1173
1174         talloc_free(options);
1175         return 0;
1176 }
1177
1178 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1179 {
1180         PyLdbObject *ret;
1181         struct ldb_context *ldb;
1182         ret = (PyLdbObject *)type->tp_alloc(type, 0);
1183         if (ret == NULL) {
1184                 PyErr_NoMemory();
1185                 return NULL;
1186         }
1187         ret->mem_ctx = talloc_new(NULL);
1188         ldb = ldb_init(ret->mem_ctx, NULL);
1189
1190         if (ldb == NULL) {
1191                 PyErr_NoMemory();
1192                 return NULL;
1193         }
1194
1195         ret->ldb_ctx = ldb;
1196         return (PyObject *)ret;
1197 }
1198
1199 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1200 {
1201         char *url = NULL;
1202         unsigned int flags = 0;
1203         PyObject *py_options = Py_None;
1204         int ret;
1205         const char **options;
1206         const char * const kwnames[] = { "url", "flags", "options", NULL };
1207         struct ldb_context *ldb_ctx;
1208
1209         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
1210                                          discard_const_p(char *, kwnames),
1211                                          &url, &flags, &py_options))
1212                 return NULL;
1213
1214         if (py_options == Py_None) {
1215                 options = NULL;
1216         } else {
1217                 options = PyList_AsStrList(NULL, py_options, "options");
1218                 if (options == NULL)
1219                         return NULL;
1220         }
1221
1222         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1223         ret = ldb_connect(ldb_ctx, url, flags, options);
1224         talloc_free(options);
1225
1226         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1227
1228         Py_RETURN_NONE;
1229 }
1230
1231 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1232 {
1233         PyObject *py_msg;
1234         PyObject *py_controls = Py_None;
1235         struct ldb_context *ldb_ctx;
1236         struct ldb_request *req;
1237         struct ldb_control **parsed_controls;
1238         struct ldb_message *msg;
1239         int ret;
1240         TALLOC_CTX *mem_ctx;
1241         bool validate=true;
1242         const char * const kwnames[] = { "message", "controls", "validate", NULL };
1243
1244         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1245                                          discard_const_p(char *, kwnames),
1246                                          &py_msg, &py_controls, &validate))
1247                 return NULL;
1248
1249         mem_ctx = talloc_new(NULL);
1250         if (mem_ctx == NULL) {
1251                 PyErr_NoMemory();
1252                 return NULL;
1253         }
1254         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1255
1256         if (py_controls == Py_None) {
1257                 parsed_controls = NULL;
1258         } else {
1259                 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1260                 if (controls == NULL) {
1261                         talloc_free(mem_ctx);
1262                         return NULL;
1263                 }
1264                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1265                 talloc_free(controls);
1266         }
1267
1268         if (!PyLdbMessage_Check(py_msg)) {
1269                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1270                 talloc_free(mem_ctx);
1271                 return NULL;
1272         }
1273         msg = pyldb_Message_AsMessage(py_msg);
1274
1275         if (validate) {
1276                 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1277                 if (ret != LDB_SUCCESS) {
1278                         PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1279                         talloc_free(mem_ctx);
1280                         return NULL;
1281                 }
1282         }
1283
1284         ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1285                                 NULL, ldb_op_default_callback, NULL);
1286         if (ret != LDB_SUCCESS) {
1287                 PyErr_SetString(PyExc_TypeError, "failed to build request");
1288                 talloc_free(mem_ctx);
1289                 return NULL;
1290         }
1291
1292         /* do request and autostart a transaction */
1293         /* Then let's LDB handle the message error in case of pb as they are meaningful */
1294
1295         ret = ldb_transaction_start(ldb_ctx);
1296         if (ret != LDB_SUCCESS) {
1297                 talloc_free(mem_ctx);
1298                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1299                 return NULL;
1300         }
1301
1302         ret = ldb_request(ldb_ctx, req);
1303         if (ret == LDB_SUCCESS) {
1304                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1305         }
1306
1307         if (ret == LDB_SUCCESS) {
1308                 ret = ldb_transaction_commit(ldb_ctx);
1309         } else {
1310                 ldb_transaction_cancel(ldb_ctx);
1311         }
1312
1313         talloc_free(mem_ctx);
1314         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1315
1316         Py_RETURN_NONE;
1317 }
1318
1319
1320 /**
1321  * Obtain a ldb message from a Python Dictionary object.
1322  *
1323  * @param mem_ctx Memory context
1324  * @param py_obj Python Dictionary object
1325  * @param ldb_ctx LDB context
1326  * @param mod_flags Flags to be set on every message element
1327  * @return ldb_message on success or NULL on failure
1328  */
1329 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1330                                             PyObject *py_obj,
1331                                             struct ldb_context *ldb_ctx,
1332                                             unsigned int mod_flags)
1333 {
1334         struct ldb_message *msg;
1335         unsigned int msg_pos = 0;
1336         Py_ssize_t dict_pos = 0;
1337         PyObject *key, *value;
1338         struct ldb_message_element *msg_el;
1339         PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1340
1341         msg = ldb_msg_new(mem_ctx);
1342         if (msg == NULL) {
1343                 PyErr_NoMemory();
1344                 return NULL;
1345         }
1346         msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1347
1348         if (dn_value) {
1349                 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1350                         PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1351                         return NULL;
1352                 }
1353                 if (msg->dn == NULL) {
1354                         PyErr_SetString(PyExc_TypeError, "dn set but not found");
1355                         return NULL;
1356                 }
1357         } else {
1358                 PyErr_SetString(PyExc_TypeError, "no dn set");
1359                 return NULL;
1360         }
1361
1362         while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1363                 const char *key_str = PyStr_AsUTF8(key);
1364                 if (ldb_attr_cmp(key_str, "dn") != 0) {
1365                         msg_el = PyObject_AsMessageElement(msg->elements, value,
1366                                                            mod_flags, key_str);
1367                         if (msg_el == NULL) {
1368                                 PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str);
1369                                 return NULL;
1370                         }
1371                         memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1372                         msg_pos++;
1373                 }
1374         }
1375
1376         msg->num_elements = msg_pos;
1377
1378         return msg;
1379 }
1380
1381 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1382 {
1383         PyObject *py_obj;
1384         int ret;
1385         struct ldb_context *ldb_ctx;
1386         struct ldb_request *req;
1387         struct ldb_message *msg = NULL;
1388         PyObject *py_controls = Py_None;
1389         TALLOC_CTX *mem_ctx;
1390         struct ldb_control **parsed_controls;
1391         const char * const kwnames[] = { "message", "controls", NULL };
1392
1393         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1394                                          discard_const_p(char *, kwnames),
1395                                          &py_obj, &py_controls))
1396                 return NULL;
1397
1398         mem_ctx = talloc_new(NULL);
1399         if (mem_ctx == NULL) {
1400                 PyErr_NoMemory();
1401                 return NULL;
1402         }
1403         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1404
1405         if (py_controls == Py_None) {
1406                 parsed_controls = NULL;
1407         } else {
1408                 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1409                 if (controls == NULL) {
1410                         talloc_free(mem_ctx);
1411                         return NULL;
1412                 }
1413                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1414                 talloc_free(controls);
1415         }
1416
1417         if (PyLdbMessage_Check(py_obj)) {
1418                 msg = pyldb_Message_AsMessage(py_obj);
1419         } else if (PyDict_Check(py_obj)) {
1420                 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1421         } else {
1422                 PyErr_SetString(PyExc_TypeError,
1423                                 "Dictionary or LdbMessage object expected!");
1424         }
1425
1426         if (!msg) {
1427                 /* we should have a PyErr already set */
1428                 talloc_free(mem_ctx);
1429                 return NULL;
1430         }
1431
1432         ret = ldb_msg_sanity_check(ldb_ctx, msg);
1433         if (ret != LDB_SUCCESS) {
1434                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1435                 talloc_free(mem_ctx);
1436                 return NULL;
1437         }
1438
1439         ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1440                                 NULL, ldb_op_default_callback, NULL);
1441         if (ret != LDB_SUCCESS) {
1442                 PyErr_SetString(PyExc_TypeError, "failed to build request");
1443                 talloc_free(mem_ctx);
1444                 return NULL;
1445         }
1446
1447         /* do request and autostart a transaction */
1448         /* Then let's LDB handle the message error in case of pb as they are meaningful */
1449
1450         ret = ldb_transaction_start(ldb_ctx);
1451         if (ret != LDB_SUCCESS) {
1452                 talloc_free(mem_ctx);
1453                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1454                 return NULL;
1455         }
1456
1457         ret = ldb_request(ldb_ctx, req);
1458         if (ret == LDB_SUCCESS) {
1459                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1460         }
1461
1462         if (ret == LDB_SUCCESS) {
1463                 ret = ldb_transaction_commit(ldb_ctx);
1464         } else {
1465                 ldb_transaction_cancel(ldb_ctx);
1466         }
1467
1468         talloc_free(mem_ctx);
1469         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1470
1471         Py_RETURN_NONE;
1472 }
1473
1474 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1475 {
1476         PyObject *py_dn;
1477         struct ldb_dn *dn;
1478         int ret;
1479         struct ldb_context *ldb_ctx;
1480         struct ldb_request *req;
1481         PyObject *py_controls = Py_None;
1482         TALLOC_CTX *mem_ctx;
1483         struct ldb_control **parsed_controls;
1484         const char * const kwnames[] = { "dn", "controls", NULL };
1485
1486         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1487                                          discard_const_p(char *, kwnames),
1488                                          &py_dn, &py_controls))
1489                 return NULL;
1490
1491         mem_ctx = talloc_new(NULL);
1492         if (mem_ctx == NULL) {
1493                 PyErr_NoMemory();
1494                 return NULL;
1495         }
1496         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1497
1498         if (py_controls == Py_None) {
1499                 parsed_controls = NULL;
1500         } else {
1501                 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1502                 if (controls == NULL) {
1503                         talloc_free(mem_ctx);
1504                         return NULL;
1505                 }
1506                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1507                 talloc_free(controls);
1508         }
1509
1510         if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1511                 talloc_free(mem_ctx);
1512                 return NULL;
1513         }
1514
1515         ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1516                                 NULL, ldb_op_default_callback, NULL);
1517         if (ret != LDB_SUCCESS) {
1518                 PyErr_SetString(PyExc_TypeError, "failed to build request");
1519                 talloc_free(mem_ctx);
1520                 return NULL;
1521         }
1522
1523         /* do request and autostart a transaction */
1524         /* Then let's LDB handle the message error in case of pb as they are meaningful */
1525
1526         ret = ldb_transaction_start(ldb_ctx);
1527         if (ret != LDB_SUCCESS) {
1528                 talloc_free(mem_ctx);
1529                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1530                 return NULL;
1531         }
1532
1533         ret = ldb_request(ldb_ctx, req);
1534         if (ret == LDB_SUCCESS) {
1535                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1536         }
1537
1538         if (ret == LDB_SUCCESS) {
1539                 ret = ldb_transaction_commit(ldb_ctx);
1540         } else {
1541                 ldb_transaction_cancel(ldb_ctx);
1542         }
1543
1544         talloc_free(mem_ctx);
1545         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1546
1547         Py_RETURN_NONE;
1548 }
1549
1550 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1551 {
1552         PyObject *py_dn1, *py_dn2;
1553         struct ldb_dn *dn1, *dn2;
1554         int ret;
1555         TALLOC_CTX *mem_ctx;
1556         PyObject *py_controls = Py_None;
1557         struct ldb_control **parsed_controls;
1558         struct ldb_context *ldb_ctx;
1559         struct ldb_request *req;
1560         const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1561
1562         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1563
1564         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1565                                          discard_const_p(char *, kwnames),
1566                                          &py_dn1, &py_dn2, &py_controls))
1567                 return NULL;
1568
1569
1570         mem_ctx = talloc_new(NULL);
1571         if (mem_ctx == NULL) {
1572                 PyErr_NoMemory();
1573                 return NULL;
1574         }
1575
1576         if (py_controls == Py_None) {
1577                 parsed_controls = NULL;
1578         } else {
1579                 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1580                 if (controls == NULL) {
1581                         talloc_free(mem_ctx);
1582                         return NULL;
1583                 }
1584                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1585                 talloc_free(controls);
1586         }
1587
1588
1589         if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1590                 talloc_free(mem_ctx);
1591                 return NULL;
1592         }
1593
1594         if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1595                 talloc_free(mem_ctx);
1596                 return NULL;
1597         }
1598
1599         ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1600                                 NULL, ldb_op_default_callback, NULL);
1601         if (ret != LDB_SUCCESS) {
1602                 PyErr_SetString(PyExc_TypeError, "failed to build request");
1603                 talloc_free(mem_ctx);
1604                 return NULL;
1605         }
1606
1607         /* do request and autostart a transaction */
1608         /* Then let's LDB handle the message error in case of pb as they are meaningful */
1609
1610         ret = ldb_transaction_start(ldb_ctx);
1611         if (ret != LDB_SUCCESS) {
1612                 talloc_free(mem_ctx);
1613                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1614                 return NULL;
1615         }
1616
1617         ret = ldb_request(ldb_ctx, req);
1618         if (ret == LDB_SUCCESS) {
1619                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1620         }
1621
1622         if (ret == LDB_SUCCESS) {
1623                 ret = ldb_transaction_commit(ldb_ctx);
1624         } else {
1625                 ldb_transaction_cancel(ldb_ctx);
1626         }
1627
1628         talloc_free(mem_ctx);
1629         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1630
1631         Py_RETURN_NONE;
1632 }
1633
1634 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1635 {
1636         char *name;
1637         if (!PyArg_ParseTuple(args, "s", &name))
1638                 return NULL;
1639
1640         ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1641
1642         Py_RETURN_NONE;
1643 }
1644
1645 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1646 {
1647         char *attribute, *syntax;
1648         unsigned int flags;
1649         int ret;
1650         struct ldb_context *ldb_ctx;
1651
1652         if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1653                 return NULL;
1654
1655         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1656         ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1657
1658         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1659
1660         Py_RETURN_NONE;
1661 }
1662
1663 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1664 {
1665         if (ldif == NULL) {
1666                 Py_RETURN_NONE;
1667         } else {
1668         /* We don't want this attached to the 'ldb' any more */
1669                 return Py_BuildValue(discard_const_p(char, "(iO)"),
1670                                      ldif->changetype,
1671                                      PyLdbMessage_FromMessage(ldif->msg));
1672         }
1673 }
1674
1675
1676 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1677 {
1678         int changetype;
1679         PyObject *py_msg;
1680         struct ldb_ldif ldif;
1681         PyObject *ret;
1682         char *string;
1683         TALLOC_CTX *mem_ctx;
1684
1685         if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1686                 return NULL;
1687
1688         if (!PyLdbMessage_Check(py_msg)) {
1689                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1690                 return NULL;
1691         }
1692
1693         ldif.msg = pyldb_Message_AsMessage(py_msg);
1694         ldif.changetype = changetype;
1695
1696         mem_ctx = talloc_new(NULL);
1697
1698         string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1699         if (!string) {
1700                 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1701                 return NULL;
1702         }
1703
1704         ret = PyStr_FromString(string);
1705
1706         talloc_free(mem_ctx);
1707
1708         return ret;
1709 }
1710
1711 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1712 {
1713         PyObject *list, *ret;
1714         struct ldb_ldif *ldif;
1715         const char *s;
1716         struct ldb_dn *last_dn = NULL;
1717
1718         TALLOC_CTX *mem_ctx;
1719
1720         if (!PyArg_ParseTuple(args, "s", &s))
1721                 return NULL;
1722
1723         mem_ctx = talloc_new(NULL);
1724         if (!mem_ctx) {
1725                 Py_RETURN_NONE;
1726         }
1727
1728         list = PyList_New(0);
1729         while (s && *s != '\0') {
1730                 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1731                 talloc_steal(mem_ctx, ldif);
1732                 if (ldif) {
1733                         PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1734                         last_dn = ldif->msg->dn;
1735                 } else {
1736                         const char *last_dn_str = NULL;
1737                         const char *err_string = NULL;
1738                         if (last_dn == NULL) {
1739                                 PyErr_SetString(PyExc_ValueError,
1740                                                 "unable to parse LDIF "
1741                                                 "string at first chunk");
1742                                 talloc_free(mem_ctx);
1743                                 return NULL;
1744                         }
1745
1746                         last_dn_str
1747                                 = ldb_dn_get_linearized(last_dn);
1748
1749                         err_string
1750                                 = talloc_asprintf(mem_ctx,
1751                                                   "unable to parse ldif "
1752                                                   "string AFTER %s",
1753                                                   last_dn_str);
1754
1755                         PyErr_SetString(PyExc_ValueError,
1756                                         err_string);
1757                         talloc_free(mem_ctx);
1758                         return NULL;
1759                 }
1760         }
1761         talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1762         ret = PyObject_GetIter(list);
1763         Py_DECREF(list);
1764         return ret;
1765 }
1766
1767 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1768 {
1769         int ldb_ret;
1770         PyObject *py_msg_old;
1771         PyObject *py_msg_new;
1772         struct ldb_message *diff;
1773         struct ldb_context *ldb;
1774         PyObject *py_ret;
1775
1776         if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1777                 return NULL;
1778
1779         if (!PyLdbMessage_Check(py_msg_old)) {
1780                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1781                 return NULL;
1782         }
1783
1784         if (!PyLdbMessage_Check(py_msg_new)) {
1785                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1786                 return NULL;
1787         }
1788
1789         ldb = pyldb_Ldb_AsLdbContext(self);
1790         ldb_ret = ldb_msg_difference(ldb, ldb,
1791                                      pyldb_Message_AsMessage(py_msg_old),
1792                                      pyldb_Message_AsMessage(py_msg_new),
1793                                      &diff);
1794         if (ldb_ret != LDB_SUCCESS) {
1795                 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1796                 return NULL;
1797         }
1798
1799         py_ret = PyLdbMessage_FromMessage(diff);
1800
1801         talloc_unlink(ldb, diff);
1802
1803         return py_ret;
1804 }
1805
1806 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1807 {
1808         const struct ldb_schema_attribute *a;
1809         struct ldb_val old_val;
1810         struct ldb_val new_val;
1811         TALLOC_CTX *mem_ctx;
1812         PyObject *ret;
1813         char *element_name;
1814         PyObject *val;
1815         Py_ssize_t size;
1816         int result;
1817
1818         if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1819                 return NULL;
1820
1821         result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
1822         old_val.length = size;
1823
1824         if (result != 0) {
1825                 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1826                 return NULL;
1827         }
1828
1829         a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1830
1831         if (a == NULL) {
1832                 Py_RETURN_NONE;
1833         }
1834
1835         mem_ctx = talloc_new(NULL);
1836         if (mem_ctx == NULL) {
1837                 PyErr_NoMemory();
1838                 return NULL;
1839         }
1840
1841         if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1842                 talloc_free(mem_ctx);
1843                 Py_RETURN_NONE;
1844         }
1845
1846         ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
1847
1848         talloc_free(mem_ctx);
1849
1850         return ret;
1851 }
1852
1853 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1854 {
1855         PyObject *py_base = Py_None;
1856         int scope = LDB_SCOPE_DEFAULT;
1857         char *expr = NULL;
1858         PyObject *py_attrs = Py_None;
1859         PyObject *py_controls = Py_None;
1860         const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1861         int ret;
1862         struct ldb_result *res;
1863         struct ldb_request *req;
1864         const char **attrs;
1865         struct ldb_context *ldb_ctx;
1866         struct ldb_control **parsed_controls;
1867         struct ldb_dn *base;
1868         PyObject *py_ret;
1869         TALLOC_CTX *mem_ctx;
1870
1871         /* type "int" rather than "enum" for "scope" is intentional */
1872         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1873                                          discard_const_p(char *, kwnames),
1874                                          &py_base, &scope, &expr, &py_attrs, &py_controls))
1875                 return NULL;
1876
1877
1878         mem_ctx = talloc_new(NULL);
1879         if (mem_ctx == NULL) {
1880                 PyErr_NoMemory();
1881                 return NULL;
1882         }
1883         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1884
1885         if (py_attrs == Py_None) {
1886                 attrs = NULL;
1887         } else {
1888                 attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
1889                 if (attrs == NULL) {
1890                         talloc_free(mem_ctx);
1891                         return NULL;
1892                 }
1893         }
1894
1895         if (py_base == Py_None) {
1896                 base = ldb_get_default_basedn(ldb_ctx);
1897         } else {
1898                 if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
1899                         talloc_free(mem_ctx);
1900                         return NULL;
1901                 }
1902         }
1903
1904         if (py_controls == Py_None) {
1905                 parsed_controls = NULL;
1906         } else {
1907                 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1908                 if (controls == NULL) {
1909                         talloc_free(mem_ctx);
1910                         return NULL;
1911                 }
1912                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1913                 talloc_free(controls);
1914         }
1915
1916         res = talloc_zero(mem_ctx, struct ldb_result);
1917         if (res == NULL) {
1918                 PyErr_NoMemory();
1919                 talloc_free(mem_ctx);
1920                 return NULL;
1921         }
1922
1923         ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1924                                    base,
1925                                    scope,
1926                                    expr,
1927                                    attrs,
1928                                    parsed_controls,
1929                                    res,
1930                                    ldb_search_default_callback,
1931                                    NULL);
1932
1933         if (ret != LDB_SUCCESS) {
1934                 talloc_free(mem_ctx);
1935                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1936                 return NULL;
1937         }
1938
1939         talloc_steal(req, attrs);
1940
1941         ret = ldb_request(ldb_ctx, req);
1942
1943         if (ret == LDB_SUCCESS) {
1944                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1945         }
1946
1947         if (ret != LDB_SUCCESS) {
1948                 talloc_free(mem_ctx);
1949                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1950                 return NULL;
1951         }
1952
1953         py_ret = PyLdbResult_FromResult(res);
1954
1955         talloc_free(mem_ctx);
1956
1957         return py_ret;
1958 }
1959
1960 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
1961 {
1962         if (reply->py_iter != NULL) {
1963                 DLIST_REMOVE(reply->py_iter->state.next, reply);
1964                 if (reply->py_iter->state.result == reply) {
1965                         reply->py_iter->state.result = NULL;
1966                 }
1967                 reply->py_iter = NULL;
1968         }
1969
1970         if (reply->obj != NULL) {
1971                 Py_DECREF(reply->obj);
1972                 reply->obj = NULL;
1973         }
1974
1975         return 0;
1976 }
1977
1978 static int py_ldb_search_iterator_callback(struct ldb_request *req,
1979                                            struct ldb_reply *ares)
1980 {
1981         PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
1982         struct ldb_result result = { .msgs = NULL };
1983         struct py_ldb_search_iterator_reply *reply = NULL;
1984
1985         if (ares == NULL) {
1986                 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1987         }
1988
1989         if (ares->error != LDB_SUCCESS) {
1990                 int ret = ares->error;
1991                 TALLOC_FREE(ares);
1992                 return ldb_request_done(req, ret);
1993         }
1994
1995         reply = talloc_zero(py_iter->mem_ctx,
1996                             struct py_ldb_search_iterator_reply);
1997         if (reply == NULL) {
1998                 TALLOC_FREE(ares);
1999                 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2000         }
2001         reply->py_iter = py_iter;
2002         talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
2003
2004         switch (ares->type) {
2005         case LDB_REPLY_ENTRY:
2006                 reply->obj = PyLdbMessage_FromMessage(ares->message);
2007                 if (reply->obj == NULL) {
2008                         TALLOC_FREE(ares);
2009                         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2010                 }
2011                 DLIST_ADD_END(py_iter->state.next, reply);
2012                 TALLOC_FREE(ares);
2013                 return LDB_SUCCESS;
2014
2015         case LDB_REPLY_REFERRAL:
2016                 reply->obj = PyStr_FromString(ares->referral);
2017                 if (reply->obj == NULL) {
2018                         TALLOC_FREE(ares);
2019                         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2020                 }
2021                 DLIST_ADD_END(py_iter->state.next, reply);
2022                 TALLOC_FREE(ares);
2023                 return LDB_SUCCESS;
2024
2025         case LDB_REPLY_DONE:
2026                 result = (struct ldb_result) { .controls = ares->controls };
2027                 reply->obj = PyLdbResult_FromResult(&result);
2028                 if (reply->obj == NULL) {
2029                         TALLOC_FREE(ares);
2030                         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2031                 }
2032                 py_iter->state.result = reply;
2033                 TALLOC_FREE(ares);
2034                 return ldb_request_done(req, LDB_SUCCESS);
2035         }
2036
2037         TALLOC_FREE(ares);
2038         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2039 }
2040
2041 static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs)
2042 {
2043         PyObject *py_base = Py_None;
2044         int scope = LDB_SCOPE_DEFAULT;
2045         int timeout = 0;
2046         char *expr = NULL;
2047         PyObject *py_attrs = Py_None;
2048         PyObject *py_controls = Py_None;
2049         const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL };
2050         int ret;
2051         const char **attrs;
2052         struct ldb_context *ldb_ctx;
2053         struct ldb_control **parsed_controls;
2054         struct ldb_dn *base;
2055         PyLdbSearchIteratorObject *py_iter;
2056
2057         /* type "int" rather than "enum" for "scope" is intentional */
2058         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi",
2059                                          discard_const_p(char *, kwnames),
2060                                          &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout))
2061                 return NULL;
2062
2063         py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0);
2064         if (py_iter == NULL) {
2065                 PyErr_NoMemory();
2066                 return NULL;
2067         }
2068         py_iter->ldb = self;
2069         Py_INCREF(self);
2070         ZERO_STRUCT(py_iter->state);
2071         py_iter->mem_ctx = talloc_new(NULL);
2072         if (py_iter->mem_ctx == NULL) {
2073                 Py_DECREF(py_iter);
2074                 PyErr_NoMemory();
2075                 return NULL;
2076         }
2077
2078         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2079
2080         if (py_attrs == Py_None) {
2081                 attrs = NULL;
2082         } else {
2083                 attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs");
2084                 if (attrs == NULL) {
2085                         Py_DECREF(py_iter);
2086                         PyErr_NoMemory();
2087                         return NULL;
2088                 }
2089         }
2090
2091         if (py_base == Py_None) {
2092                 base = ldb_get_default_basedn(ldb_ctx);
2093         } else {
2094                 if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) {
2095                         Py_DECREF(py_iter);
2096                         PyErr_NoMemory();
2097                         return NULL;
2098                 }
2099         }
2100
2101         if (py_controls == Py_None) {
2102                 parsed_controls = NULL;
2103         } else {
2104                 const char **controls = NULL;
2105
2106                 controls = PyList_AsStrList(py_iter->mem_ctx,
2107                                             py_controls, "controls");
2108                 if (controls == NULL) {
2109                         Py_DECREF(py_iter);
2110                         PyErr_NoMemory();
2111                         return NULL;
2112                 }
2113
2114                 parsed_controls = ldb_parse_control_strings(ldb_ctx,
2115                                                             py_iter->mem_ctx,
2116                                                             controls);
2117                 if (controls[0] != NULL && parsed_controls == NULL) {
2118                         Py_DECREF(py_iter);
2119                         PyErr_NoMemory();
2120                         return NULL;
2121                 }
2122                 talloc_free(controls);
2123         }
2124
2125         ret = ldb_build_search_req(&py_iter->state.req,
2126                                    ldb_ctx,
2127                                    py_iter->mem_ctx,
2128                                    base,
2129                                    scope,
2130                                    expr,
2131                                    attrs,
2132                                    parsed_controls,
2133                                    py_iter,
2134                                    py_ldb_search_iterator_callback,
2135                                    NULL);
2136         if (ret != LDB_SUCCESS) {
2137                 Py_DECREF(py_iter);
2138                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2139                 return NULL;
2140         }
2141
2142         ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout);
2143
2144         ret = ldb_request(ldb_ctx, py_iter->state.req);
2145         if (ret != LDB_SUCCESS) {
2146                 Py_DECREF(py_iter);
2147                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2148                 return NULL;
2149         }
2150
2151         return (PyObject *)py_iter;
2152 }
2153
2154 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
2155 {
2156         char *name;
2157         void *data;
2158
2159         if (!PyArg_ParseTuple(args, "s", &name))
2160                 return NULL;
2161
2162         data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
2163
2164         if (data == NULL)
2165                 Py_RETURN_NONE;
2166
2167         /* FIXME: More interpretation */
2168
2169         Py_RETURN_TRUE;
2170 }
2171
2172 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
2173 {
2174         char *name;
2175         PyObject *data;
2176
2177         if (!PyArg_ParseTuple(args, "sO", &name, &data))
2178                 return NULL;
2179
2180         /* FIXME: More interpretation */
2181
2182         ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
2183
2184         Py_RETURN_NONE;
2185 }
2186
2187 static PyObject *py_ldb_modules(PyLdbObject *self)
2188 {
2189         struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2190         PyObject *ret = PyList_New(0);
2191         struct ldb_module *mod;
2192
2193         for (mod = ldb->modules; mod; mod = mod->next) {
2194                 PyList_Append(ret, PyLdbModule_FromModule(mod));
2195         }
2196
2197         return ret;
2198 }
2199
2200 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
2201 {
2202         struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2203         int type, ret;
2204         uint64_t value;
2205
2206         if (!PyArg_ParseTuple(args, "i", &type))
2207                 return NULL;
2208
2209         /* FIXME: More interpretation */
2210
2211         ret = ldb_sequence_number(ldb, type, &value);
2212
2213         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2214
2215         return PyLong_FromLongLong(value);
2216 }
2217
2218
2219 static const struct ldb_dn_extended_syntax test_dn_syntax = {
2220         .name             = "TEST",
2221         .read_fn          = ldb_handler_copy,
2222         .write_clear_fn   = ldb_handler_copy,
2223         .write_hex_fn     = ldb_handler_copy,
2224 };
2225
2226 static PyObject *py_ldb_register_test_extensions(PyLdbObject *self)
2227 {
2228         struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2229         int ret;
2230
2231         ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax);
2232
2233         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2234
2235         Py_RETURN_NONE;
2236 }
2237
2238
2239 static PyMethodDef py_ldb_methods[] = {
2240         { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, 
2241                 "S.set_debug(callback) -> None\n"
2242                 "Set callback for LDB debug messages.\n"
2243                 "The callback should accept a debug level and debug text." },
2244         { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS, 
2245                 "S.set_create_perms(mode) -> None\n"
2246                 "Set mode to use when creating new LDB files." },
2247         { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
2248                 "S.set_modules_dir(path) -> None\n"
2249                 "Set path LDB should search for modules" },
2250         { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS, 
2251                 "S.transaction_start() -> None\n"
2252                 "Start a new transaction." },
2253         { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
2254                 "S.transaction_prepare_commit() -> None\n"
2255                 "prepare to commit a new transaction (2-stage commit)." },
2256         { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, 
2257                 "S.transaction_commit() -> None\n"
2258                 "commit a new transaction." },
2259         { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS, 
2260                 "S.transaction_cancel() -> None\n"
2261                 "cancel a new transaction." },
2262         { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS, 
2263                 NULL },
2264         { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
2265                 NULL },
2266         { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
2267                 NULL },
2268         { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
2269                 NULL },
2270         { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
2271                 NULL },
2272         { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS, 
2273                 "S.connect(url, flags=0, options=None) -> None\n"
2274                 "Connect to a LDB URL." },
2275         { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
2276                 "S.modify(message, controls=None, validate=False) -> None\n"
2277                 "Modify an entry." },
2278         { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
2279                 "S.add(message, controls=None) -> None\n"
2280                 "Add an entry." },
2281         { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
2282                 "S.delete(dn, controls=None) -> None\n"
2283                 "Remove an entry." },
2284         { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
2285                 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2286                 "Rename an entry." },
2287         { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
2288                 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2289                 "Search in a database.\n"
2290                 "\n"
2291                 ":param base: Optional base DN to search\n"
2292                 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2293                 ":param expression: Optional search expression\n"
2294                 ":param attrs: Attributes to return (defaults to all)\n"
2295                 ":param controls: Optional list of controls\n"
2296                 ":return: ldb.Result object\n"
2297         },
2298         { "search_iterator", (PyCFunction)py_ldb_search_iterator, METH_VARARGS|METH_KEYWORDS,
2299                 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2300                 "Search in a database.\n"
2301                 "\n"
2302                 ":param base: Optional base DN to search\n"
2303                 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2304                 ":param expression: Optional search expression\n"
2305                 ":param attrs: Attributes to return (defaults to all)\n"
2306                 ":param controls: Optional list of controls\n"
2307                 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2308                 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2309         },
2310         { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
2311                 NULL },
2312         { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
2313                 NULL },
2314         { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
2315                 NULL },
2316         { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
2317                 "S.parse_ldif(ldif) -> iter(messages)\n"
2318                 "Parse a string formatted using LDIF." },
2319         { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
2320                 "S.write_ldif(message, changetype) -> ldif\n"
2321                 "Print the message as a string formatted using LDIF." },
2322         { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
2323                 "S.msg_diff(Message) -> Message\n"
2324                 "Return an LDB Message of the difference between two Message objects." },
2325         { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
2326                 "S.get_opaque(name) -> value\n"
2327                 "Get an opaque value set on this LDB connection. \n"
2328                 ":note: The returned value may not be useful in Python."
2329         },
2330         { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
2331                 "S.set_opaque(name, value) -> None\n"
2332                 "Set an opaque value on this LDB connection. \n"
2333                 ":note: Passing incorrect values may cause crashes." },
2334         { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
2335                 "S.modules() -> list\n"
2336                 "Return the list of modules on this LDB connection " },
2337         { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
2338                 "S.sequence_number(type) -> value\n"
2339                 "Return the value of the sequence according to the requested type" },
2340         { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS,
2341                 "S._register_test_extensions() -> None\n"
2342                 "Register internal extensions used in testing" },
2343         { NULL },
2344 };
2345
2346 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
2347 {
2348         PyLdbModuleObject *ret;
2349
2350         ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
2351         if (ret == NULL) {
2352                 PyErr_NoMemory();
2353                 return NULL;
2354         }
2355         ret->mem_ctx = talloc_new(NULL);
2356         ret->mod = talloc_reference(ret->mem_ctx, mod);
2357         return (PyObject *)ret;
2358 }
2359
2360 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
2361 {
2362         struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules;
2363         if (mod == NULL) {
2364                 Py_RETURN_NONE;
2365         }
2366         return PyLdbModule_FromModule(mod);
2367 }
2368
2369 static PyGetSetDef py_ldb_getset[] = {
2370         { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
2371         { NULL }
2372 };
2373
2374 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
2375 {
2376         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2377         struct ldb_dn *dn;
2378         struct ldb_result *result;
2379         unsigned int count;
2380         int ret;
2381
2382         if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2383                 return -1;
2384         }
2385
2386         ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2387                          NULL);
2388         if (ret != LDB_SUCCESS) {
2389                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2390                 return -1;
2391         }
2392
2393         count = result->count;
2394
2395         talloc_free(result);
2396
2397         if (count > 1) {
2398                 PyErr_Format(PyExc_RuntimeError,
2399                              "Searching for [%s] dn gave %u results!",
2400                              ldb_dn_get_linearized(dn),
2401                              count);
2402                 return -1;
2403         }
2404
2405         return count;
2406 }
2407
2408 static PySequenceMethods py_ldb_seq = {
2409         .sq_contains = (objobjproc)py_ldb_contains,
2410 };
2411
2412 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2413 {
2414         PyLdbObject *ret;
2415
2416         ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2417         if (ret == NULL) {
2418                 PyErr_NoMemory();
2419                 return NULL;
2420         }
2421         ret->mem_ctx = talloc_new(NULL);
2422         ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
2423         return (PyObject *)ret;
2424 }
2425
2426 static void py_ldb_dealloc(PyLdbObject *self)
2427 {
2428         talloc_free(self->mem_ctx);
2429         Py_TYPE(self)->tp_free(self);
2430 }
2431
2432 static PyTypeObject PyLdb = {
2433         .tp_name = "ldb.Ldb",
2434         .tp_methods = py_ldb_methods,
2435         .tp_repr = (reprfunc)py_ldb_repr,
2436         .tp_new = py_ldb_new,
2437         .tp_init = (initproc)py_ldb_init,
2438         .tp_dealloc = (destructor)py_ldb_dealloc,
2439         .tp_getset = py_ldb_getset,
2440         .tp_getattro = PyObject_GenericGetAttr,
2441         .tp_basicsize = sizeof(PyLdbObject),
2442         .tp_doc = "Connection to a LDB database.",
2443         .tp_as_sequence = &py_ldb_seq,
2444         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2445 };
2446
2447 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2448 {
2449         talloc_free(self->mem_ctx);
2450         Py_DECREF(self->msgs);
2451         Py_DECREF(self->referals);
2452         Py_DECREF(self->controls);
2453         Py_TYPE(self)->tp_free(self);
2454 }
2455
2456 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2457 {
2458         Py_INCREF(self->msgs);
2459         return self->msgs;
2460 }
2461
2462 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2463 {
2464         Py_INCREF(self->controls);
2465         return self->controls;
2466 }
2467
2468 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2469 {
2470         Py_INCREF(self->referals);
2471         return self->referals;
2472 }
2473
2474 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2475 {
2476         Py_ssize_t size;
2477         if (self->msgs == NULL) {
2478                 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2479                 return NULL;
2480         }
2481         size = PyList_Size(self->msgs);
2482         return PyInt_FromLong(size);
2483 }
2484
2485 static PyGetSetDef py_ldb_result_getset[] = {
2486         { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
2487         { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
2488         { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
2489         { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
2490         { NULL }
2491 };
2492
2493 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2494 {
2495         return PyObject_GetIter(self->msgs);
2496 }
2497
2498 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2499 {
2500         return PySequence_Size(self->msgs);
2501 }
2502
2503 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2504 {
2505         return PySequence_GetItem(self->msgs, idx);
2506 }
2507
2508 static PySequenceMethods py_ldb_result_seq = {
2509         .sq_length = (lenfunc)py_ldb_result_len,
2510         .sq_item = (ssizeargfunc)py_ldb_result_find,
2511 };
2512
2513 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2514 {
2515         return PyStr_FromString("<ldb result>");
2516 }
2517
2518
2519 static PyTypeObject PyLdbResult = {
2520         .tp_name = "ldb.Result",
2521         .tp_repr = (reprfunc)py_ldb_result_repr,
2522         .tp_dealloc = (destructor)py_ldb_result_dealloc,
2523         .tp_iter = (getiterfunc)py_ldb_result_iter,
2524         .tp_getset = py_ldb_result_getset,
2525         .tp_getattro = PyObject_GenericGetAttr,
2526         .tp_basicsize = sizeof(PyLdbResultObject),
2527         .tp_as_sequence = &py_ldb_result_seq,
2528         .tp_doc = "LDB result.",
2529         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2530 };
2531
2532 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self)
2533 {
2534         Py_XDECREF(self->state.exception);
2535         TALLOC_FREE(self->mem_ctx);
2536         ZERO_STRUCT(self->state);
2537         Py_DECREF(self->ldb);
2538         Py_TYPE(self)->tp_free(self);
2539 }
2540
2541 static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self)
2542 {
2543         PyObject *py_ret = NULL;
2544
2545         if (self->state.req == NULL) {
2546                 PyErr_SetString(PyExc_RuntimeError,
2547                                 "ldb.SearchIterator request already finished");
2548                 return NULL;
2549         }
2550
2551         /*
2552          * TODO: do we want a non-blocking mode?
2553          * In future we may add an optional 'nonblocking'
2554          * argument to search_iterator().
2555          *
2556          * For now we keep it simple and wait for at
2557          * least one reply.
2558          */
2559
2560         while (self->state.next == NULL) {
2561                 int ret;
2562
2563                 if (self->state.result != NULL) {
2564                         /*
2565                          * We (already) got a final result from the server.
2566                          *
2567                          * We stop the iteration and let
2568                          * py_ldb_search_iterator_result() will deliver
2569                          * the result details.
2570                          */
2571                         TALLOC_FREE(self->state.req);
2572                         PyErr_SetNone(PyExc_StopIteration);
2573                         return NULL;
2574                 }
2575
2576                 ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE);
2577                 if (ret != LDB_SUCCESS) {
2578                         struct ldb_context *ldb_ctx;
2579                         TALLOC_FREE(self->state.req);
2580                         ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb);
2581                         /*
2582                          * We stop the iteration and let
2583                          * py_ldb_search_iterator_result() will deliver
2584                          * the exception.
2585                          */
2586                         self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"),
2587                                                 ret, ldb_errstring(ldb_ctx));
2588                         PyErr_SetNone(PyExc_StopIteration);
2589                         return NULL;
2590                 }
2591         }
2592
2593         py_ret = self->state.next->obj;
2594         self->state.next->obj = NULL;
2595         /* no TALLOC_FREE() as self->state.next is a list */
2596         talloc_free(self->state.next);
2597         return py_ret;
2598 }
2599
2600 static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self)
2601 {
2602         PyObject *py_ret = NULL;
2603
2604         if (self->state.req != NULL) {
2605                 PyErr_SetString(PyExc_RuntimeError,
2606                                 "ldb.SearchIterator request running");
2607                 return NULL;
2608         }
2609
2610         if (self->state.next != NULL) {
2611                 PyErr_SetString(PyExc_RuntimeError,
2612                                 "ldb.SearchIterator not fully consumed.");
2613                 return NULL;
2614         }
2615
2616         if (self->state.exception != NULL) {
2617                 PyErr_SetObject(PyExc_LdbError, self->state.exception);
2618                 self->state.exception = NULL;
2619                 return NULL;
2620         }
2621
2622         if (self->state.result == NULL) {
2623                 PyErr_SetString(PyExc_RuntimeError,
2624                                 "ldb.SearchIterator result already consumed");
2625                 return NULL;
2626         }
2627
2628         py_ret = self->state.result->obj;
2629         self->state.result->obj = NULL;
2630         TALLOC_FREE(self->state.result);
2631         return py_ret;
2632 }
2633
2634 static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self)
2635 {
2636         if (self->state.req == NULL) {
2637                 PyErr_SetString(PyExc_RuntimeError,
2638                                 "ldb.SearchIterator request already finished");
2639                 return NULL;
2640         }
2641
2642         Py_XDECREF(self->state.exception);
2643         TALLOC_FREE(self->mem_ctx);
2644         ZERO_STRUCT(self->state);
2645         Py_RETURN_NONE;
2646 }
2647
2648 static PyMethodDef py_ldb_search_iterator_methods[] = {
2649         { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS,
2650                 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2651         { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS,
2652                 "S.abandon()\n" },
2653         { NULL }
2654 };
2655
2656 static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self)
2657 {
2658         return PyStr_FromString("<ldb search iterator>");
2659 }
2660
2661 static PyTypeObject PyLdbSearchIterator = {
2662         .tp_name = "ldb.SearchIterator",
2663         .tp_repr = (reprfunc)py_ldb_search_iterator_repr,
2664         .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc,
2665         .tp_iter = PyObject_SelfIter,
2666         .tp_iternext = (iternextfunc)py_ldb_search_iterator_next,
2667         .tp_methods = py_ldb_search_iterator_methods,
2668         .tp_basicsize = sizeof(PyLdbSearchIteratorObject),
2669         .tp_doc = "LDB search_iterator.",
2670         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2671 };
2672
2673 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2674 {
2675         return PyStr_FromFormat("<ldb module '%s'>",
2676                 pyldb_Module_AsModule(self)->ops->name);
2677 }
2678
2679 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2680 {
2681         return PyStr_FromString(pyldb_Module_AsModule(self)->ops->name);
2682 }
2683
2684 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2685 {
2686         pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2687         Py_RETURN_NONE;
2688 }
2689
2690 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2691 {
2692         pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2693         Py_RETURN_NONE;
2694 }
2695
2696 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2697 {
2698         pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2699         Py_RETURN_NONE;
2700 }
2701
2702 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2703 {
2704         PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2705         int ret, scope;
2706         struct ldb_request *req;
2707         const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2708         struct ldb_module *mod;
2709         const char * const*attrs;
2710
2711         /* type "int" rather than "enum" for "scope" is intentional */
2712         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2713                                          discard_const_p(char *, kwnames),
2714                                          &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2715                 return NULL;
2716
2717         mod = self->mod;
2718
2719         if (py_attrs == Py_None) {
2720                 attrs = NULL;
2721         } else {
2722                 attrs = PyList_AsStrList(NULL, py_attrs, "attrs");
2723                 if (attrs == NULL)
2724                         return NULL;
2725         }
2726
2727         ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base), 
2728                              scope, NULL /* expr */, attrs,
2729                              NULL /* controls */, NULL, NULL, NULL);
2730
2731         talloc_steal(req, attrs);
2732
2733         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2734
2735         req->op.search.res = NULL;
2736
2737         ret = mod->ops->search(mod, req);
2738
2739         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2740
2741         py_ret = PyLdbResult_FromResult(req->op.search.res);
2742
2743         talloc_free(req);
2744
2745         return py_ret;
2746 }
2747
2748
2749 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2750 {
2751         struct ldb_request *req;
2752         PyObject *py_message;
2753         int ret;
2754         struct ldb_module *mod;
2755
2756         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2757                 return NULL;
2758
2759         req = talloc_zero(NULL, struct ldb_request);
2760         req->operation = LDB_ADD;
2761         req->op.add.message = pyldb_Message_AsMessage(py_message);
2762
2763         mod = pyldb_Module_AsModule(self);
2764         ret = mod->ops->add(mod, req);
2765
2766         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2767
2768         Py_RETURN_NONE;
2769 }
2770
2771 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args) 
2772 {
2773         int ret;
2774         struct ldb_request *req;
2775         PyObject *py_message;
2776         struct ldb_module *mod;
2777
2778         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2779                 return NULL;
2780
2781         req = talloc_zero(NULL, struct ldb_request);
2782         req->operation = LDB_MODIFY;
2783         req->op.mod.message = pyldb_Message_AsMessage(py_message);
2784
2785         mod = pyldb_Module_AsModule(self);
2786         ret = mod->ops->modify(mod, req);
2787
2788         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2789
2790         Py_RETURN_NONE;
2791 }
2792
2793 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args) 
2794 {
2795         int ret;
2796         struct ldb_request *req;
2797         PyObject *py_dn;
2798
2799         if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2800                 return NULL;
2801
2802         req = talloc_zero(NULL, struct ldb_request);
2803         req->operation = LDB_DELETE;
2804         req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2805
2806         ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2807
2808         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2809
2810         Py_RETURN_NONE;
2811 }
2812
2813 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2814 {
2815         int ret;
2816         struct ldb_request *req;
2817         PyObject *py_dn1, *py_dn2;
2818
2819         if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2820                 return NULL;
2821
2822         req = talloc_zero(NULL, struct ldb_request);
2823
2824         req->operation = LDB_RENAME;
2825         req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2826         req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2827
2828         ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2829
2830         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2831
2832         Py_RETURN_NONE;
2833 }
2834
2835 static PyMethodDef py_ldb_module_methods[] = {
2836         { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2837         { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2838         { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2839         { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2840         { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2841         { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2842         { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2843         { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2844         { NULL },
2845 };
2846
2847 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2848 {
2849         talloc_free(self->mem_ctx);
2850         PyObject_Del(self);
2851 }
2852
2853 static PyTypeObject PyLdbModule = {
2854         .tp_name = "ldb.LdbModule",
2855         .tp_methods = py_ldb_module_methods,
2856         .tp_repr = (reprfunc)py_ldb_module_repr,
2857         .tp_str = (reprfunc)py_ldb_module_str,
2858         .tp_basicsize = sizeof(PyLdbModuleObject),
2859         .tp_dealloc = (destructor)py_ldb_module_dealloc,
2860         .tp_flags = Py_TPFLAGS_DEFAULT,
2861         .tp_doc = "LDB module (extension)",
2862 };
2863
2864
2865 /**
2866  * Create a ldb_message_element from a Python object.
2867  *
2868  * This will accept any sequence objects that contains strings, or 
2869  * a string object.
2870  *
2871  * A reference to set_obj will be borrowed. 
2872  *
2873  * @param mem_ctx Memory context
2874  * @param set_obj Python object to convert
2875  * @param flags ldb_message_element flags to set
2876  * @param attr_name Name of the attribute
2877  * @return New ldb_message_element, allocated as child of mem_ctx
2878  */
2879 static struct ldb_message_element *PyObject_AsMessageElement(
2880                                                       TALLOC_CTX *mem_ctx,
2881                                                       PyObject *set_obj,
2882                                                       unsigned int flags,
2883                                                       const char *attr_name)
2884 {
2885         struct ldb_message_element *me;
2886         const char *msg = NULL;
2887         Py_ssize_t size;
2888         int result;
2889
2890         if (pyldb_MessageElement_Check(set_obj)) {
2891                 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2892                 /* We have to talloc_reference() the memory context, not the pointer
2893                  * which may not actually be it's own context */
2894                 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2895                         return pyldb_MessageElement_AsMessageElement(set_obj);
2896                 }
2897                 return NULL;
2898         }
2899
2900         me = talloc(mem_ctx, struct ldb_message_element);
2901         if (me == NULL) {
2902                 PyErr_NoMemory();
2903                 return NULL;
2904         }
2905
2906         me->name = talloc_strdup(me, attr_name);
2907         me->flags = flags;
2908         if (PyBytes_Check(set_obj) || PyUnicode_Check(set_obj)) {
2909                 me->num_values = 1;
2910                 me->values = talloc_array(me, struct ldb_val, me->num_values);
2911                 if (PyBytes_Check(set_obj)) {
2912                         char *_msg = NULL;
2913                         result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
2914                         if (result != 0) {
2915                                 talloc_free(me);
2916                                 return NULL;
2917                         }
2918                         msg = _msg;
2919                 } else {
2920                         msg = PyStr_AsUTF8AndSize(set_obj, &size);
2921                         if (msg == NULL) {
2922                                 talloc_free(me);
2923                                 return NULL;
2924                         }
2925                 }
2926                 me->values[0].data = talloc_memdup(me,
2927                                                    (const uint8_t *)msg,
2928                                                    size+1);
2929                 me->values[0].length = size;
2930         } else if (PySequence_Check(set_obj)) {
2931                 Py_ssize_t i;
2932                 me->num_values = PySequence_Size(set_obj);
2933                 me->values = talloc_array(me, struct ldb_val, me->num_values);
2934                 for (i = 0; i < me->num_values; i++) {
2935                         PyObject *obj = PySequence_GetItem(set_obj, i);
2936                         if (PyBytes_Check(obj)) {
2937                                 char *_msg = NULL;
2938                                 result = PyBytes_AsStringAndSize(obj, &_msg, &size);
2939                                 if (result != 0) {
2940                                         talloc_free(me);
2941                                         return NULL;
2942                                 }
2943                                 msg = _msg;
2944                         } else if (PyUnicode_Check(obj)) {
2945                                 msg = PyStr_AsUTF8AndSize(obj, &size);
2946                                 if (msg == NULL) {
2947                                         talloc_free(me);
2948                                         return NULL;
2949                                 }
2950                         } else {
2951                                 PyErr_Format(PyExc_TypeError,
2952                                              "Expected string as element %zd in list", i);
2953                                 talloc_free(me);
2954                                 return NULL;
2955                         }
2956                         me->values[i].data = talloc_memdup(me,
2957                                                            (const uint8_t *)msg,
2958                                                            size+1);
2959                         me->values[i].length = size;
2960                 }
2961         } else {
2962                 PyErr_Format(PyExc_TypeError,
2963                              "String or List type expected for '%s' attribute", attr_name);
2964                 talloc_free(me);
2965                 me = NULL;
2966         }
2967
2968         return me;
2969 }
2970
2971
2972 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2973                                         struct ldb_message_element *me)
2974 {
2975         Py_ssize_t i;
2976         PyObject *result;
2977
2978         /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2979         result = PyList_New(me->num_values);
2980
2981         for (i = 0; i < me->num_values; i++) {
2982                 PyList_SetItem(result, i,
2983                         PyObject_FromLdbValue(&me->values[i]));
2984         }
2985
2986         return result;
2987 }
2988
2989 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2990 {
2991         unsigned int i;
2992         if (!PyArg_ParseTuple(args, "I", &i))
2993                 return NULL;
2994         if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2995                 Py_RETURN_NONE;
2996
2997         return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2998 }
2999
3000 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
3001 {
3002         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3003         return PyInt_FromLong(el->flags);
3004 }
3005
3006 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
3007 {
3008         unsigned int flags;
3009         struct ldb_message_element *el;
3010         if (!PyArg_ParseTuple(args, "I", &flags))
3011                 return NULL;
3012
3013         el = pyldb_MessageElement_AsMessageElement(self);
3014         el->flags = flags;
3015         Py_RETURN_NONE;
3016 }
3017
3018 static PyMethodDef py_ldb_msg_element_methods[] = {
3019         { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
3020         { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
3021         { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
3022         { NULL },
3023 };
3024
3025 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
3026 {
3027         return pyldb_MessageElement_AsMessageElement(self)->num_values;
3028 }
3029
3030 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
3031 {
3032         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3033         if (idx < 0 || idx >= el->num_values) {
3034                 PyErr_SetString(PyExc_IndexError, "Out of range");
3035                 return NULL;
3036         }
3037         return PyLdbBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
3038 }
3039
3040 static PySequenceMethods py_ldb_msg_element_seq = {
3041         .sq_length = (lenfunc)py_ldb_msg_element_len,
3042         .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
3043 };
3044
3045 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
3046 {
3047         int ret;
3048         if (!pyldb_MessageElement_Check(other)) {
3049                 Py_INCREF(Py_NotImplemented);
3050                 return Py_NotImplemented;
3051         }
3052         ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
3053                                                                           pyldb_MessageElement_AsMessageElement(other));
3054         return richcmp(ret, op);
3055 }
3056
3057 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
3058 {
3059         PyObject *el = ldb_msg_element_to_set(NULL,
3060                                               pyldb_MessageElement_AsMessageElement(self));
3061         PyObject *ret = PyObject_GetIter(el);
3062         Py_DECREF(el);
3063         return ret;
3064 }
3065
3066 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
3067 {
3068         PyLdbMessageElementObject *ret;
3069         ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
3070         if (ret == NULL) {
3071                 PyErr_NoMemory();
3072                 return NULL;
3073         }
3074         ret->mem_ctx = talloc_new(NULL);
3075         if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
3076                 PyErr_NoMemory();
3077                 return NULL;
3078         }
3079         ret->el = el;
3080         return (PyObject *)ret;
3081 }
3082
3083 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3084 {
3085         PyObject *py_elements = NULL;
3086         struct ldb_message_element *el;
3087         unsigned int flags = 0;
3088         char *name = NULL;
3089         const char * const kwnames[] = { "elements", "flags", "name", NULL };
3090         PyLdbMessageElementObject *ret;
3091         TALLOC_CTX *mem_ctx;
3092         const char *msg = NULL;
3093         Py_ssize_t size;
3094         int result;
3095
3096         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
3097                                          discard_const_p(char *, kwnames),
3098                                          &py_elements, &flags, &name))
3099                 return NULL;
3100
3101         mem_ctx = talloc_new(NULL);
3102         if (mem_ctx == NULL) {
3103                 PyErr_NoMemory();
3104                 return NULL;
3105         }
3106
3107         el = talloc_zero(mem_ctx, struct ldb_message_element);
3108         if (el == NULL) {
3109                 PyErr_NoMemory();
3110                 talloc_free(mem_ctx);
3111                 return NULL;
3112         }
3113
3114         if (py_elements != NULL) {
3115                 Py_ssize_t i;
3116                 if (PyBytes_Check(py_elements) || PyUnicode_Check(py_elements)) {
3117                         char *_msg = NULL;
3118                         el->num_values = 1;
3119                         el->values = talloc_array(el, struct ldb_val, 1);
3120                         if (el->values == NULL) {
3121                                 talloc_free(mem_ctx);
3122                                 PyErr_NoMemory();
3123                                 return NULL;
3124                         }
3125                         if (PyBytes_Check(py_elements)) {
3126                                 result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
3127                                 msg = _msg;
3128                         } else {
3129                                 msg = PyStr_AsUTF8AndSize(py_elements, &size);
3130                                 result = (msg == NULL) ? -1 : 0;
3131                         }
3132                         if (result != 0) {
3133                                 talloc_free(mem_ctx);
3134                                 return NULL;
3135                         }
3136                         el->values[0].data = talloc_memdup(el->values, 
3137                                 (const uint8_t *)msg, size + 1);
3138                         el->values[0].length = size;
3139                 } else if (PySequence_Check(py_elements)) {
3140                         el->num_values = PySequence_Size(py_elements);
3141                         el->values = talloc_array(el, struct ldb_val, el->num_values);
3142                         if (el->values == NULL) {
3143                                 talloc_free(mem_ctx);
3144                                 PyErr_NoMemory();
3145                                 return NULL;
3146                         }
3147                         for (i = 0; i < el->num_values; i++) {
3148                                 PyObject *item = PySequence_GetItem(py_elements, i);
3149                                 if (item == NULL) {
3150                                         talloc_free(mem_ctx);
3151                                         return NULL;
3152                                 }
3153                                 if (PyBytes_Check(item)) {
3154                                         char *_msg = NULL;
3155                                         result = PyBytes_AsStringAndSize(item, &_msg, &size);
3156                                         msg = _msg;
3157                                 } else if (PyUnicode_Check(item)) {
3158                                         msg = PyStr_AsUTF8AndSize(item, &size);
3159                                         result = (msg == NULL) ? -1 : 0;
3160                                 } else {
3161                                         PyErr_Format(PyExc_TypeError, 
3162                                                      "Expected string as element %zd in list", i);
3163                                         result = -1;
3164                                 }
3165                                 if (result != 0) {
3166                                         talloc_free(mem_ctx);
3167                                         return NULL;
3168                                 }
3169                                 el->values[i].data = talloc_memdup(el,
3170                                         (const uint8_t *)msg, size+1);
3171                                 el->values[i].length = size;
3172                         }
3173                 } else {
3174                         PyErr_SetString(PyExc_TypeError, 
3175                                         "Expected string or list");
3176                         talloc_free(mem_ctx);
3177                         return NULL;
3178                 }
3179         }
3180
3181         el->flags = flags;
3182         el->name = talloc_strdup(el, name);
3183
3184         ret = PyObject_New(PyLdbMessageElementObject, type);
3185         if (ret == NULL) {
3186                 talloc_free(mem_ctx);
3187                 return NULL;
3188         }
3189
3190         ret->mem_ctx = mem_ctx;
3191         ret->el = el;
3192         return (PyObject *)ret;
3193 }
3194
3195 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
3196 {
3197         char *element_str = NULL;
3198         Py_ssize_t i;
3199         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3200         PyObject *ret, *repr;
3201
3202         for (i = 0; i < el->num_values; i++) {
3203                 PyObject *o = py_ldb_msg_element_find(self, i);
3204                 repr = PyObject_Repr(o);
3205                 if (element_str == NULL)
3206                         element_str = talloc_strdup(NULL, PyStr_AsUTF8(repr));
3207                 else
3208                         element_str = talloc_asprintf_append(element_str, ",%s", PyStr_AsUTF8(repr));
3209                 Py_DECREF(repr);
3210         }
3211
3212         if (element_str != NULL) {
3213                 ret = PyStr_FromFormat("MessageElement([%s])", element_str);
3214                 talloc_free(element_str);
3215         } else {
3216                 ret = PyStr_FromString("MessageElement([])");
3217         }
3218
3219         return ret;
3220 }
3221
3222 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
3223 {
3224         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3225
3226         if (el->num_values == 1)
3227                 return PyStr_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
3228         else
3229                 Py_RETURN_NONE;
3230 }
3231
3232 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
3233 {
3234         talloc_free(self->mem_ctx);
3235         PyObject_Del(self);
3236 }
3237
3238 static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
3239 {
3240         return wrap_text("MessageElementTextWrapper", self);
3241 }
3242
3243 static PyGetSetDef py_ldb_msg_element_getset[] = {
3244         { discard_const_p(char, "text"), (getter)py_ldb_msg_element_get_text, NULL, NULL },
3245         { NULL }
3246 };
3247
3248 static PyTypeObject PyLdbMessageElement = {
3249         .tp_name = "ldb.MessageElement",
3250         .tp_basicsize = sizeof(PyLdbMessageElementObject),
3251         .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
3252         .tp_repr = (reprfunc)py_ldb_msg_element_repr,
3253         .tp_str = (reprfunc)py_ldb_msg_element_str,
3254         .tp_methods = py_ldb_msg_element_methods,
3255         .tp_getset = py_ldb_msg_element_getset,
3256         .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
3257         .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
3258         .tp_as_sequence = &py_ldb_msg_element_seq,
3259         .tp_new = py_ldb_msg_element_new,
3260         .tp_flags = Py_TPFLAGS_DEFAULT,
3261         .tp_doc = "An element of a Message",
3262 };
3263
3264
3265 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
3266 {
3267         PyObject *py_ldb;
3268         PyObject *py_dict;
3269         PyObject *py_ret;
3270         struct ldb_message *msg;
3271         struct ldb_context *ldb_ctx;
3272         unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
3273
3274         if (!PyArg_ParseTuple(args, "O!O!|I",
3275                               &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
3276                               &mod_flags)) {
3277                 return NULL;
3278         }
3279
3280         if (!PyLdb_Check(py_ldb)) {
3281                 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
3282                 return NULL;
3283         }
3284
3285         /* mask only flags we are going to use */
3286         mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
3287         if (!mod_flags) {
3288                 PyErr_SetString(PyExc_ValueError,
3289                                 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3290                                 " expected as mod_flag value");
3291                 return NULL;
3292         }
3293
3294         ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
3295
3296         msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
3297         if (!msg) {
3298                 return NULL;
3299         }
3300
3301         py_ret = PyLdbMessage_FromMessage(msg);
3302
3303         talloc_unlink(ldb_ctx, msg);
3304
3305         return py_ret;
3306 }
3307
3308 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
3309 {
3310         char *name;
3311         if (!PyArg_ParseTuple(args, "s", &name))
3312                 return NULL;
3313
3314         ldb_msg_remove_attr(self->msg, name);
3315
3316         Py_RETURN_NONE;
3317 }
3318
3319 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
3320 {
3321         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3322         Py_ssize_t i, j = 0;
3323         PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
3324         if (msg->dn != NULL) {
3325                 PyList_SetItem(obj, j, PyStr_FromString("dn"));
3326                 j++;
3327         }
3328         for (i = 0; i < msg->num_elements; i++) {
3329                 PyList_SetItem(obj, j, PyStr_FromString(msg->elements[i].name));
3330                 j++;
3331         }
3332         return obj;
3333 }
3334
3335 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
3336 {
3337         struct ldb_message_element *el;
3338         const char *name;
3339         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3340         name = PyStr_AsUTF8(py_name);
3341         if (name == NULL) {
3342                 PyErr_SetNone(PyExc_TypeError);
3343                 return NULL;
3344         }
3345         if (!ldb_attr_cmp(name, "dn"))
3346                 return pyldb_Dn_FromDn(msg->dn);
3347         el = ldb_msg_find_element(msg, name);
3348         if (el == NULL) {
3349                 return NULL;
3350         }
3351         return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3352 }
3353
3354 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
3355 {
3356         PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
3357         if (ret == NULL) {
3358                 PyErr_SetString(PyExc_KeyError, "No such element");
3359                 return NULL;
3360         }
3361         return ret;
3362 }
3363
3364 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
3365 {
3366         PyObject *def = NULL;
3367         const char *kwnames[] = { "name", "default", "idx", NULL };
3368         const char *name = NULL;
3369         int idx = -1;
3370         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3371         struct ldb_message_element *el;
3372
3373         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
3374                                          discard_const_p(char *, kwnames), &name, &def, &idx)) {
3375                 return NULL;
3376         }
3377
3378         if (strcasecmp(name, "dn") == 0) {
3379                 return pyldb_Dn_FromDn(msg->dn);
3380         }
3381
3382         el = ldb_msg_find_element(msg, name);
3383
3384         if (el == NULL || (idx != -1 && el->num_values <= idx)) {
3385                 if (def != NULL) {
3386                         Py_INCREF(def);
3387                         return def;
3388                 }
3389                 Py_RETURN_NONE;
3390         }
3391
3392         if (idx == -1) {
3393                 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3394         }
3395
3396         return PyObject_FromLdbValue(&el->values[idx]);
3397 }
3398
3399 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
3400 {
3401         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3402         Py_ssize_t i, j = 0;
3403         PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
3404         if (msg->dn != NULL) {
3405                 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
3406                 j++;
3407         }
3408         for (i = 0; i < msg->num_elements; i++, j++) {
3409                 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3410                 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
3411                 PyList_SetItem(l, j, value);
3412         }
3413         return l;
3414 }
3415
3416 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
3417 {
3418         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3419         Py_ssize_t i = 0;
3420         PyObject *l = PyList_New(msg->num_elements);
3421         for (i = 0; i < msg->num_elements; i++) {
3422                 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
3423         }
3424         return l;
3425 }
3426
3427 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
3428 {
3429         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3430         PyLdbMessageElementObject *py_element;
3431         int i, ret;
3432         struct ldb_message_element *el;
3433         struct ldb_message_element *el_new;
3434
3435         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
3436                 return NULL;
3437
3438         el = py_element->el;
3439         if (el == NULL) {
3440                 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
3441                 return NULL;
3442         }
3443
3444         ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
3445         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3446
3447         /* now deep copy all attribute values */
3448         el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
3449         if (el_new->values == NULL) {
3450                 PyErr_NoMemory();
3451                 return NULL;
3452         }
3453         el_new->num_values = el->num_values;
3454
3455         for (i = 0; i < el->num_values; i++) {
3456                 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
3457                 if (el_new->values[i].data == NULL
3458                                 && el->values[i].length != 0) {
3459                         PyErr_NoMemory();
3460                         return NULL;
3461                 }
3462         }
3463
3464         Py_RETURN_NONE;
3465 }
3466
3467 static PyMethodDef py_ldb_msg_methods[] = {
3468         { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
3469                 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
3470                 "Class method to create ldb.Message object from Dictionary.\n"
3471                 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3472         { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, 
3473                 "S.keys() -> list\n\n"
3474                 "Return sequence of all attribute names." },
3475         { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, 
3476                 "S.remove(name)\n\n"
3477                 "Remove all entries for attributes with the specified name."},
3478         { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
3479           "msg.get(name,default=None,idx=None) -> string\n"
3480           "idx is the index into the values array\n"
3481           "if idx is None, then a list is returned\n"
3482           "if idx is not None, then the element with that index is returned\n"
3483           "if you pass the special name 'dn' then the DN object is returned\n"},
3484         { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
3485         { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
3486         { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
3487                 "S.add(element)\n\n"
3488                 "Add an element to this message." },
3489         { NULL },
3490 };
3491
3492 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
3493 {
3494         PyObject *list, *iter;
3495
3496         list = py_ldb_msg_keys(self);
3497         iter = PyObject_GetIter(list);
3498         Py_DECREF(list);
3499         return iter;
3500 }
3501
3502 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
3503 {
3504         const char *attr_name;
3505
3506         attr_name = PyStr_AsUTF8(name);
3507         if (attr_name == NULL) {
3508                 PyErr_SetNone(PyExc_TypeError);
3509                 return -1;
3510         }
3511
3512         if (value == NULL) {
3513                 /* delitem */
3514                 ldb_msg_remove_attr(self->msg, attr_name);
3515         } else {
3516                 int ret;
3517                 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
3518                                                                            value, 0, attr_name);
3519                 if (el == NULL) {
3520                         return -1;
3521                 }
3522                 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
3523                 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
3524                 if (ret != LDB_SUCCESS) {
3525                         PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
3526                         return -1;
3527                 }
3528         }
3529         return 0;
3530 }
3531
3532 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
3533 {
3534         return pyldb_Message_AsMessage(self)->num_elements;
3535 }
3536
3537 static PyMappingMethods py_ldb_msg_mapping = {
3538         .mp_length = (lenfunc)py_ldb_msg_length,
3539         .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
3540         .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
3541 };
3542
3543 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3544 {
3545         const char * const kwnames[] = { "dn", NULL };
3546         struct ldb_message *ret;
3547         TALLOC_CTX *mem_ctx;
3548         PyObject *pydn = NULL;
3549         PyLdbMessageObject *py_ret;
3550
3551         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
3552                                          discard_const_p(char *, kwnames),
3553                                          &pydn))
3554                 return NULL;
3555
3556         mem_ctx = talloc_new(NULL);
3557         if (mem_ctx == NULL) {
3558                 PyErr_NoMemory();
3559                 return NULL;
3560         }
3561
3562         ret = ldb_msg_new(mem_ctx);
3563         if (ret == NULL) {
3564                 talloc_free(mem_ctx);
3565                 PyErr_NoMemory();
3566                 return NULL;
3567         }
3568
3569         if (pydn != NULL) {
3570                 struct ldb_dn *dn;
3571                 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
3572                         talloc_free(mem_ctx);
3573                         return NULL;
3574                 }
3575                 ret->dn = talloc_reference(ret, dn);
3576         }
3577
3578         py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
3579         if (py_ret == NULL) {
3580                 PyErr_NoMemory();
3581                 talloc_free(mem_ctx);
3582                 return NULL;
3583         }
3584
3585         py_ret->mem_ctx = mem_ctx;
3586         py_ret->msg = ret;
3587         return (PyObject *)py_ret;
3588 }
3589
3590 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
3591 {
3592         PyLdbMessageObject *ret;
3593
3594         ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
3595         if (ret == NULL) {
3596                 PyErr_NoMemory();
3597                 return NULL;
3598         }
3599         ret->mem_ctx = talloc_new(NULL);
3600         ret->msg = talloc_reference(ret->mem_ctx, msg);
3601         return (PyObject *)ret;
3602 }
3603
3604 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
3605 {
3606         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3607         return pyldb_Dn_FromDn(msg->dn);
3608 }
3609
3610 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
3611 {
3612         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3613         if (!pyldb_Dn_Check(value)) {
3614                 PyErr_SetString(PyExc_TypeError, "expected dn");
3615                 return -1;
3616         }
3617
3618         msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
3619         return 0;
3620 }
3621
3622 static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure)
3623 {
3624         return wrap_text("MessageTextWrapper", self);
3625 }
3626
3627 static PyGetSetDef py_ldb_msg_getset[] = {
3628         { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
3629         { discard_const_p(char, "text"), (getter)py_ldb_msg_get_text, NULL, NULL },
3630         { NULL }
3631 };
3632
3633 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
3634 {
3635         PyObject *dict = PyDict_New(), *ret, *repr;
3636         if (PyDict_Update(dict, (PyObject *)self) != 0)
3637                 return NULL;
3638         repr = PyObject_Repr(dict);
3639         if (repr == NULL) {
3640                 Py_DECREF(dict);
3641                 return NULL;
3642         }
3643         ret = PyStr_FromFormat("Message(%s)", PyStr_AsUTF8(repr));
3644         Py_DECREF(repr);
3645         Py_DECREF(dict);
3646         return ret;
3647 }
3648
3649 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
3650 {
3651         talloc_free(self->mem_ctx);
3652         PyObject_Del(self);
3653 }
3654
3655 static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1,
3656                               PyLdbMessageObject *py_msg2, int op)
3657 {
3658         struct ldb_message *msg1, *msg2;
3659         unsigned int i;
3660         int ret;
3661
3662         if (!PyLdbMessage_Check(py_msg2)) {
3663                 Py_INCREF(Py_NotImplemented);
3664                 return Py_NotImplemented;
3665         }
3666
3667         msg1 = pyldb_Message_AsMessage(py_msg1),
3668         msg2 = pyldb_Message_AsMessage(py_msg2);
3669
3670         if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3671                 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3672                 if (ret != 0) {
3673                         return richcmp(ret, op);
3674                 }
3675         }
3676
3677         ret = msg1->num_elements - msg2->num_elements;
3678         if (ret != 0) {
3679                 return richcmp(ret, op);
3680         }
3681
3682         for (i = 0; i < msg1->num_elements; i++) {
3683                 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3684                                                    &msg2->elements[i]);
3685                 if (ret != 0) {
3686                         return richcmp(ret, op);
3687                 }
3688
3689                 ret = ldb_msg_element_compare(&msg1->elements[i],
3690                                               &msg2->elements[i]);
3691                 if (ret != 0) {
3692                         return richcmp(ret, op);
3693                 }
3694         }
3695
3696         return richcmp(0, op);
3697 }
3698
3699 static PyTypeObject PyLdbMessage = {
3700         .tp_name = "ldb.Message",
3701         .tp_methods = py_ldb_msg_methods,
3702         .tp_getset = py_ldb_msg_getset,
3703         .tp_as_mapping = &py_ldb_msg_mapping,
3704         .tp_basicsize = sizeof(PyLdbMessageObject),
3705         .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3706         .tp_new = py_ldb_msg_new,
3707         .tp_repr = (reprfunc)py_ldb_msg_repr,
3708         .tp_flags = Py_TPFLAGS_DEFAULT,
3709         .tp_iter = (getiterfunc)py_ldb_msg_iter,
3710         .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp,
3711         .tp_doc = "A LDB Message",
3712 };
3713
3714 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3715 {
3716         PyLdbTreeObject *ret;
3717
3718         ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3719         if (ret == NULL) {
3720                 PyErr_NoMemory();
3721                 return NULL;
3722         }
3723
3724         ret->mem_ctx = talloc_new(NULL);
3725         ret->tree = talloc_reference(ret->mem_ctx, tree);
3726         return (PyObject *)ret;
3727 }
3728
3729 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3730 {
3731         talloc_free(self->mem_ctx);
3732         PyObject_Del(self);
3733 }
3734
3735 static PyTypeObject PyLdbTree = {
3736         .tp_name = "ldb.Tree",
3737         .tp_basicsize = sizeof(PyLdbTreeObject),
3738         .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3739         .tp_flags = Py_TPFLAGS_DEFAULT,
3740         .tp_doc = "A search tree",
3741 };
3742
3743 /* Ldb_module */
3744 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3745 {
3746         PyObject *py_ldb = (PyObject *)mod->private_data;
3747         PyObject *py_result, *py_base, *py_attrs, *py_tree;
3748
3749         py_base = pyldb_Dn_FromDn(req->op.search.base);
3750
3751         if (py_base == NULL)
3752                 return LDB_ERR_OPERATIONS_ERROR;
3753
3754         py_tree = PyLdbTree_FromTree(req->op.search.tree);
3755
3756         if (py_tree == NULL)
3757                 return LDB_ERR_OPERATIONS_ERROR;
3758
3759         if (req->op.search.attrs == NULL) {
3760                 py_attrs = Py_None;
3761         } else {
3762                 int i, len;
3763                 for (len = 0; req->op.search.attrs[len]; len++);
3764                 py_attrs = PyList_New(len);
3765                 for (i = 0; i < len; i++)
3766                         PyList_SetItem(py_attrs, i, PyStr_FromString(req->op.search.attrs[i]));
3767         }
3768
3769         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3770                                         discard_const_p(char, "OiOO"),
3771                                         py_base, req->op.search.scope, py_tree, py_attrs);
3772
3773         Py_DECREF(py_attrs);
3774         Py_DECREF(py_tree);
3775         Py_DECREF(py_base);
3776
3777         if (py_result == NULL) {
3778                 return LDB_ERR_PYTHON_EXCEPTION;
3779         }
3780
3781         req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3782         if (req->op.search.res == NULL) {
3783                 return LDB_ERR_PYTHON_EXCEPTION;
3784         }
3785
3786         Py_DECREF(py_result);
3787
3788         return LDB_SUCCESS;
3789 }
3790
3791 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3792 {
3793         PyObject *py_ldb = (PyObject *)mod->private_data;
3794         PyObject *py_result, *py_msg;
3795
3796         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3797
3798         if (py_msg == NULL) {
3799                 return LDB_ERR_OPERATIONS_ERROR;
3800         }
3801
3802         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3803                                         discard_const_p(char, "O"),
3804                                         py_msg);
3805
3806         Py_DECREF(py_msg);
3807
3808         if (py_result == NULL) {
3809                 return LDB_ERR_PYTHON_EXCEPTION;
3810         }
3811
3812         Py_DECREF(py_result);
3813
3814         return LDB_SUCCESS;
3815 }
3816
3817 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3818 {
3819         PyObject *py_ldb = (PyObject *)mod->private_data;
3820         PyObject *py_result, *py_msg;
3821
3822         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3823
3824         if (py_msg == NULL) {
3825                 return LDB_ERR_OPERATIONS_ERROR;
3826         }
3827
3828         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3829                                         discard_const_p(char, "O"),
3830                                         py_msg);
3831
3832         Py_DECREF(py_msg);
3833
3834         if (py_result == NULL) {
3835                 return LDB_ERR_PYTHON_EXCEPTION;
3836         }
3837
3838         Py_DECREF(py_result);
3839
3840         return LDB_SUCCESS;
3841 }
3842
3843 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3844 {
3845         PyObject *py_ldb = (PyObject *)mod->private_data;
3846         PyObject *py_result, *py_dn;
3847
3848         py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3849
3850         if (py_dn == NULL)
3851                 return LDB_ERR_OPERATIONS_ERROR;
3852
3853         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3854                                         discard_const_p(char, "O"),
3855                                         py_dn);
3856
3857         if (py_result == NULL) {
3858                 return LDB_ERR_PYTHON_EXCEPTION;
3859         }
3860
3861         Py_DECREF(py_result);
3862
3863         return LDB_SUCCESS;
3864 }
3865
3866 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3867 {
3868         PyObject *py_ldb = (PyObject *)mod->private_data;
3869         PyObject *py_result, *py_olddn, *py_newdn;
3870
3871         py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3872
3873         if (py_olddn == NULL)
3874                 return LDB_ERR_OPERATIONS_ERROR;
3875
3876         py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3877
3878         if (py_newdn == NULL)
3879                 return LDB_ERR_OPERATIONS_ERROR;
3880
3881         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3882                                         discard_const_p(char, "OO"),
3883                                         py_olddn, py_newdn);
3884
3885         Py_DECREF(py_olddn);
3886         Py_DECREF(py_newdn);
3887
3888         if (py_result == NULL) {
3889                 return LDB_ERR_PYTHON_EXCEPTION;
3890         }
3891
3892         Py_DECREF(py_result);
3893
3894         return LDB_SUCCESS;
3895 }
3896
3897 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3898 {
3899         PyObject *py_ldb = (PyObject *)mod->private_data;
3900         PyObject *py_result;
3901
3902         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3903                                         discard_const_p(char, ""));
3904
3905         Py_XDECREF(py_result);
3906
3907         return LDB_ERR_OPERATIONS_ERROR;
3908 }
3909
3910 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3911 {
3912         PyObject *py_ldb = (PyObject *)mod->private_data;
3913         PyObject *py_result;
3914
3915         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3916                                         discard_const_p(char, ""));
3917
3918         Py_XDECREF(py_result);
3919
3920         return LDB_ERR_OPERATIONS_ERROR;
3921 }
3922
3923 static int py_module_start_transaction(struct ldb_module *mod)
3924 {
3925         PyObject *py_ldb = (PyObject *)mod->private_data;
3926         PyObject *py_result;
3927
3928         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3929                                         discard_const_p(char, ""));
3930
3931         if (py_result == NULL) {
3932                 return LDB_ERR_PYTHON_EXCEPTION;
3933         }
3934
3935         Py_DECREF(py_result);
3936
3937         return LDB_SUCCESS;
3938 }
3939
3940 static int py_module_end_transaction(struct ldb_module *mod)
3941 {
3942         PyObject *py_ldb = (PyObject *)mod->private_data;
3943         PyObject *py_result;
3944
3945         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3946                                         discard_const_p(char, ""));
3947
3948         if (py_result == NULL) {
3949                 return LDB_ERR_PYTHON_EXCEPTION;
3950         }
3951
3952         Py_DECREF(py_result);
3953
3954         return LDB_SUCCESS;
3955 }
3956
3957 static int py_module_del_transaction(struct ldb_module *mod)
3958 {
3959         PyObject *py_ldb = (PyObject *)mod->private_data;
3960         PyObject *py_result;
3961
3962         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3963                                         discard_const_p(char, ""));
3964
3965         if (py_result == NULL) {
3966                 return LDB_ERR_PYTHON_EXCEPTION;
3967         }
3968
3969         Py_DECREF(py_result);
3970
3971         return LDB_SUCCESS;
3972 }
3973
3974 static int py_module_destructor(struct ldb_module *mod)
3975 {
3976         Py_DECREF((PyObject *)mod->private_data);
3977         return 0;
3978 }
3979
3980 static int py_module_init(struct ldb_module *mod)
3981 {
3982         PyObject *py_class = (PyObject *)mod->ops->private_data;
3983         PyObject *py_result, *py_next, *py_ldb;
3984
3985         py_ldb = PyLdb_FromLdbContext(mod->ldb);
3986
3987         if (py_ldb == NULL)
3988                 return LDB_ERR_OPERATIONS_ERROR;
3989
3990         py_next = PyLdbModule_FromModule(mod->next);
3991
3992         if (py_next == NULL)
3993                 return LDB_ERR_OPERATIONS_ERROR;
3994
3995         py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3996                                           py_ldb, py_next);
3997
3998         if (py_result == NULL) {
3999                 return LDB_ERR_PYTHON_EXCEPTION;
4000         }
4001
4002         mod->private_data = py_result;
4003
4004         talloc_set_destructor(mod, py_module_destructor);
4005
4006         return ldb_next_init(mod);
4007 }
4008
4009 static PyObject *py_register_module(PyObject *module, PyObject *args)
4010 {
4011         int ret;
4012         struct ldb_module_ops *ops;
4013         PyObject *input;
4014
4015         if (!PyArg_ParseTuple(args, "O", &input))
4016                 return NULL;
4017
4018         ops = talloc_zero(NULL, struct ldb_module_ops);
4019         if (ops == NULL) {
4020                 PyErr_NoMemory();
4021                 return NULL;
4022         }
4023
4024         ops->name = talloc_strdup(ops, PyStr_AsUTF8(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
4025
4026         Py_INCREF(input);
4027         ops->private_data = input;
4028         ops->init_context = py_module_init;
4029         ops->search = py_module_search;
4030         ops->add = py_module_add;
4031         ops->modify = py_module_modify;
4032         ops->del = py_module_del;
4033         ops->rename = py_module_rename;
4034         ops->request = py_module_request;
4035         ops->extended = py_module_extended;
4036         ops->start_transaction = py_module_start_transaction;
4037         ops->end_transaction = py_module_end_transaction;
4038         ops->del_transaction = py_module_del_transaction;
4039
4040         ret = ldb_register_module(ops);
4041         if (ret != LDB_SUCCESS) {
4042                 TALLOC_FREE(ops);
4043         }
4044
4045         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
4046
4047         Py_RETURN_NONE;
4048 }
4049
4050 static PyObject *py_timestring(PyObject *module, PyObject *args)
4051 {
4052         /* most times "time_t" is a signed integer type with 32 or 64 bit:
4053          * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4054         long int t_val;
4055         char *tresult;
4056         PyObject *ret;
4057         if (!PyArg_ParseTuple(args, "l", &t_val))
4058                 return NULL;
4059         tresult = ldb_timestring(NULL, (time_t) t_val);
4060         ret = PyStr_FromString(tresult);
4061         talloc_free(tresult);
4062         return ret;
4063 }
4064
4065 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
4066 {
4067         char *str;
4068         if (!PyArg_ParseTuple(args, "s", &str))
4069                 return NULL;
4070
4071         return PyInt_FromLong(ldb_string_to_time(str));
4072 }
4073
4074 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
4075 {
4076         char *name;
4077         if (!PyArg_ParseTuple(args, "s", &name))
4078                 return NULL;
4079         return PyBool_FromLong(ldb_valid_attr_name(name));
4080 }
4081
4082 /*
4083   encode a string using RFC2254 rules
4084  */
4085 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
4086 {
4087         char *str, *encoded;
4088         Py_ssize_t size = 0;
4089         struct ldb_val val;
4090         PyObject *ret;
4091
4092         if (!PyArg_ParseTuple(args, "s#", &str, &size))
4093                 return NULL;
4094         val.data = (uint8_t *)str;
4095         val.length = size;
4096
4097         encoded = ldb_binary_encode(NULL, val);
4098         if (encoded == NULL) {
4099                 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
4100                 return NULL;
4101         }
4102         ret = PyStr_FromString(encoded);
4103         talloc_free(encoded);
4104         return ret;
4105 }
4106
4107 /*
4108   decode a string using RFC2254 rules
4109  */
4110 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
4111 {
4112         char *str;
4113         struct ldb_val val;
4114         PyObject *ret;
4115
4116         if (!PyArg_ParseTuple(args, "s", &str))
4117                 return NULL;
4118
4119         val = ldb_binary_decode(NULL, str);
4120         if (val.data == NULL) {
4121                 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
4122                 return NULL;
4123         }
4124         ret = PyBytes_FromStringAndSize((const char*)val.data, val.length);
4125         talloc_free(val.data);
4126         return ret;
4127 }
4128
4129 static PyMethodDef py_ldb_global_methods[] = {
4130         { "register_module", py_register_module, METH_VARARGS, 
4131                 "S.register_module(module) -> None\n\n"
4132                 "Register a LDB module."},
4133         { "timestring", py_timestring, METH_VARARGS, 
4134                 "S.timestring(int) -> string\n\n"
4135                 "Generate a LDAP time string from a UNIX timestamp" },
4136         { "string_to_time", py_string_to_time, METH_VARARGS,
4137                 "S.string_to_time(string) -> int\n\n"
4138                 "Parse a LDAP time string into a UNIX timestamp." },
4139         { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
4140                 "S.valid_attr_name(name) -> bool\n\nn"
4141                 "Check whether the supplied name is a valid attribute name." },
4142         { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
4143                 "S.open() -> Ldb\n\n"
4144                 "Open a new LDB context." },
4145         { "binary_encode", py_binary_encode, METH_VARARGS,
4146                 "S.binary_encode(string) -> string\n\n"
4147                 "Perform a RFC2254 binary encoding on a string" },
4148         { "binary_decode", py_binary_decode, METH_VARARGS,
4149                 "S.binary_decode(string) -> string\n\n"
4150                 "Perform a RFC2254 binary decode on a string" },
4151         { NULL }
4152 };
4153
4154 #define MODULE_DOC "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server."
4155
4156 #if PY_MAJOR_VERSION >= 3
4157 static struct PyModuleDef moduledef = {
4158         PyModuleDef_HEAD_INIT,
4159         .m_name = "ldb",
4160         .m_doc = MODULE_DOC,
4161         .m_size = -1,
4162         .m_methods = py_ldb_global_methods,
4163 };
4164 #endif
4165
4166 static PyObject* module_init(void)
4167 {
4168         PyObject *m;
4169
4170         PyLdbBytesType.tp_base = &PyBytes_Type;
4171         if (PyType_Ready(&PyLdbBytesType) < 0) {
4172                 return NULL;
4173         }
4174
4175         if (PyType_Ready(&PyLdbDn) < 0)
4176                 return NULL;
4177
4178         if (PyType_Ready(&PyLdbMessage) < 0)
4179                 return NULL;
4180
4181         if (PyType_Ready(&PyLdbMessageElement) < 0)
4182                 return NULL;
4183
4184         if (PyType_Ready(&PyLdb) < 0)
4185                 return NULL;
4186
4187         if (PyType_Ready(&PyLdbModule) < 0)
4188                 return NULL;
4189
4190         if (PyType_Ready(&PyLdbTree) < 0)
4191                 return NULL;
4192
4193         if (PyType_Ready(&PyLdbResult) < 0)
4194                 return NULL;
4195
4196         if (PyType_Ready(&PyLdbSearchIterator) < 0)
4197                 return NULL;
4198
4199         if (PyType_Ready(&PyLdbControl) < 0)
4200                 return NULL;
4201
4202 #if PY_MAJOR_VERSION >= 3
4203         m = PyModule_Create(&moduledef);
4204 #else
4205         m = Py_InitModule3("ldb", py_ldb_global_methods, MODULE_DOC);
4206 #endif
4207         if (m == NULL)
4208                 return NULL;
4209
4210 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4211
4212         ADD_LDB_INT(SEQ_HIGHEST_SEQ);
4213         ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP);
4214         ADD_LDB_INT(SEQ_NEXT);
4215         ADD_LDB_INT(SCOPE_DEFAULT);
4216         ADD_LDB_INT(SCOPE_BASE);
4217         ADD_LDB_INT(SCOPE_ONELEVEL);
4218         ADD_LDB_INT(SCOPE_SUBTREE);
4219
4220         ADD_LDB_INT(CHANGETYPE_NONE);
4221         ADD_LDB_INT(CHANGETYPE_ADD);
4222         ADD_LDB_INT(CHANGETYPE_DELETE);
4223         ADD_LDB_INT(CHANGETYPE_MODIFY);
4224
4225         ADD_LDB_INT(FLAG_MOD_ADD);
4226         ADD_LDB_INT(FLAG_MOD_REPLACE);
4227         ADD_LDB_INT(FLAG_MOD_DELETE);
4228
4229         ADD_LDB_INT(ATTR_FLAG_HIDDEN);
4230         ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX);
4231         ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE);
4232         ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF);
4233
4234         ADD_LDB_INT(SUCCESS);
4235         ADD_LDB_INT(ERR_OPERATIONS_ERROR);
4236         ADD_LDB_INT(ERR_PROTOCOL_ERROR);
4237         ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED);
4238         ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED);
4239         ADD_LDB_INT(ERR_COMPARE_FALSE);
4240         ADD_LDB_INT(ERR_COMPARE_TRUE);
4241         ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED);
4242         ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED);
4243         ADD_LDB_INT(ERR_REFERRAL);
4244         ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED);
4245         ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION);
4246         ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED);
4247         ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS);
4248         ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE);
4249         ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE);
4250         ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING);
4251         ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION);
4252         ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS);
4253         ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX);
4254         ADD_LDB_INT(ERR_NO_SUCH_OBJECT);
4255         ADD_LDB_INT(ERR_ALIAS_PROBLEM);
4256         ADD_LDB_INT(ERR_INVALID_DN_SYNTAX);
4257         ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM);
4258         ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION);
4259         ADD_LDB_INT(ERR_INVALID_CREDENTIALS);
4260         ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS);
4261         ADD_LDB_INT(ERR_BUSY);
4262         ADD_LDB_INT(ERR_UNAVAILABLE);
4263         ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM);
4264         ADD_LDB_INT(ERR_LOOP_DETECT);
4265         ADD_LDB_INT(ERR_NAMING_VIOLATION);
4266         ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION);
4267         ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF);
4268         ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN);
4269         ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS);
4270         ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED);
4271         ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS);
4272         ADD_LDB_INT(ERR_OTHER);
4273
4274         ADD_LDB_INT(FLG_RDONLY);
4275         ADD_LDB_INT(FLG_NOSYNC);
4276         ADD_LDB_INT(FLG_RECONNECT);
4277         ADD_LDB_INT(FLG_NOMMAP);
4278         ADD_LDB_INT(FLG_SHOW_BINARY);
4279         ADD_LDB_INT(FLG_ENABLE_TRACING);
4280         ADD_LDB_INT(FLG_DONT_CREATE_DB);
4281
4282
4283         /* Historical misspelling */
4284         PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
4285
4286         PyModule_AddStringConstant(m, "__docformat__", "restructuredText");
4287
4288         PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
4289         PyModule_AddObject(m, "LdbError", PyExc_LdbError);
4290
4291         Py_INCREF(&PyLdb);
4292         Py_INCREF(&PyLdbDn);
4293         Py_INCREF(&PyLdbModule);
4294         Py_INCREF(&PyLdbMessage);
4295         Py_INCREF(&PyLdbMessageElement);
4296         Py_INCREF(&PyLdbTree);
4297         Py_INCREF(&PyLdbResult);
4298         Py_INCREF(&PyLdbControl);
4299
4300         PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
4301         PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
4302         PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
4303         PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
4304         PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
4305         PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
4306         PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
4307
4308         PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
4309
4310 #define ADD_LDB_STRING(val)  PyModule_AddStringConstant(m, #val, LDB_## val)
4311
4312         ADD_LDB_STRING(SYNTAX_DN);
4313         ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
4314         ADD_LDB_STRING(SYNTAX_INTEGER);
4315         ADD_LDB_STRING(SYNTAX_BOOLEAN);
4316         ADD_LDB_STRING(SYNTAX_OCTET_STRING);
4317         ADD_LDB_STRING(SYNTAX_UTC_TIME);
4318         ADD_LDB_STRING(OID_COMPARATOR_AND);
4319         ADD_LDB_STRING(OID_COMPARATOR_OR);
4320
4321         return m;
4322 }
4323
4324 #if PY_MAJOR_VERSION >= 3
4325 PyMODINIT_FUNC PyInit_ldb(void);
4326 PyMODINIT_FUNC PyInit_ldb(void)
4327 {
4328         return module_init();
4329 }
4330 #else
4331 void initldb(void);
4332 void initldb(void)
4333 {
4334         module_init();
4335 }
4336 #endif