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