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