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