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