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 53604736 : static PyObject *PyLdbBytes_FromStringAndSize(const char *msg, int size)
90 : {
91 53604736 : PyObject* result = NULL;
92 53604736 : PyObject* args = NULL;
93 53604736 : args = Py_BuildValue("(y#)", msg, size);
94 53604736 : if (args == NULL) {
95 0 : return NULL;
96 : }
97 53604736 : result = PyLdbBytesType.tp_new(&PyLdbBytesType, args, NULL);
98 47208964 : Py_DECREF(args);
99 46937379 : return result;
100 : }
101 :
102 24662461 : static PyObject *richcmp(int cmp_val, int op)
103 : {
104 2851628 : int ret;
105 24662461 : switch (op) {
106 4205 : case Py_LT: ret = cmp_val < 0; break;
107 0 : case Py_LE: ret = cmp_val <= 0; break;
108 22872764 : case Py_EQ: ret = cmp_val == 0; break;
109 1785492 : 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 24662461 : 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 105729 : static void py_ldb_control_dealloc(PyLdbControlObject *self)
135 : {
136 105729 : if (self->mem_ctx != NULL) {
137 105729 : talloc_free(self->mem_ctx);
138 : }
139 105729 : self->data = NULL;
140 105729 : Py_TYPE(self)->tp_free(self);
141 105729 : }
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 166238 : static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
268 : {
269 166238 : PyObject *exc = NULL;
270 166238 : if (ret == LDB_ERR_PYTHON_EXCEPTION) {
271 0 : return; /* Python exception should already be set, just keep that */
272 : }
273 332476 : exc = Py_BuildValue("(i,s)", ret,
274 166238 : ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx));
275 166238 : 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 166238 : PyErr_SetObject(error, exc);
285 135550 : Py_DECREF(exc);
286 : }
287 :
288 4142609 : static PyObject *py_ldb_bytes_str(PyBytesObject *self)
289 : {
290 4142609 : char *msg = NULL;
291 482751 : Py_ssize_t size;
292 4142609 : int result = 0;
293 4142609 : if (!PyBytes_Check(self)) {
294 0 : PyErr_Format(PyExc_TypeError,"Unexpected type");
295 0 : return NULL;
296 : }
297 4142609 : result = PyBytes_AsStringAndSize((PyObject *)self, &msg, &size);
298 4142609 : if (result != 0) {
299 0 : PyErr_Format(PyExc_TypeError, "Failed to extract bytes");
300 0 : return NULL;
301 : }
302 4142609 : 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 33588412 : static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
314 : {
315 33588412 : return PyLdbBytes_FromStringAndSize((const char *)val->data, val->length);
316 : }
317 :
318 525061 : static PyObject *PyStr_FromLdbValue(const struct ldb_val *val)
319 : {
320 525061 : 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 105725 : static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
330 : {
331 105725 : TALLOC_CTX *ctl_ctx = talloc_new(NULL);
332 22 : PyLdbControlObject *ctrl;
333 105725 : if (ctl_ctx == NULL) {
334 0 : PyErr_NoMemory();
335 0 : return NULL;
336 : }
337 :
338 105725 : ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
339 105725 : if (ctrl == NULL) {
340 0 : talloc_free(ctl_ctx);
341 0 : PyErr_NoMemory();
342 0 : return NULL;
343 : }
344 105725 : ctrl->mem_ctx = ctl_ctx;
345 105725 : ctrl->data = talloc_steal(ctrl->mem_ctx, control);
346 105725 : if (ctrl->data == NULL) {
347 0 : Py_DECREF(ctrl);
348 0 : PyErr_NoMemory();
349 0 : return NULL;
350 : }
351 105703 : 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 3150032 : static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
361 : {
362 262746 : PyLdbResultObject *ret;
363 262746 : PyObject *list, *controls, *referals;
364 262746 : Py_ssize_t i;
365 :
366 3150032 : if (result == NULL) {
367 3 : Py_RETURN_NONE;
368 : }
369 :
370 3150029 : ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
371 3150029 : if (ret == NULL) {
372 0 : PyErr_NoMemory();
373 0 : return NULL;
374 : }
375 :
376 3150029 : list = PyList_New(result->count);
377 3150029 : if (list == NULL) {
378 0 : PyErr_NoMemory();
379 0 : Py_DECREF(ret);
380 0 : return NULL;
381 : }
382 :
383 8238508 : for (i = 0; i < result->count; i++) {
384 5088479 : PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
385 : }
386 :
387 3150029 : ret->mem_ctx = talloc_new(NULL);
388 3150029 : 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 3150029 : ret->msgs = list;
396 :
397 3150029 : if (result->controls) {
398 105701 : i = 0;
399 211448 : while (result->controls[i]) {
400 105725 : i++;
401 : }
402 105723 : controls = PyList_New(i);
403 105723 : if (controls == NULL) {
404 0 : Py_DECREF(ret);
405 0 : PyErr_NoMemory();
406 0 : return NULL;
407 : }
408 211448 : for (i=0; result->controls[i]; i++) {
409 105725 : PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
410 105725 : if (ctrl == NULL) {
411 0 : Py_DECREF(ret);
412 0 : Py_DECREF(controls);
413 0 : PyErr_NoMemory();
414 0 : return NULL;
415 : }
416 105725 : PyList_SetItem(controls, i, ctrl);
417 : }
418 : } else {
419 : /*
420 : * No controls so we keep an empty list
421 : */
422 3044306 : controls = PyList_New(0);
423 3044306 : if (controls == NULL) {
424 0 : Py_DECREF(ret);
425 0 : PyErr_NoMemory();
426 0 : return NULL;
427 : }
428 : }
429 :
430 3150029 : ret->controls = controls;
431 :
432 3150029 : i = 0;
433 :
434 3299235 : while (result->refs && result->refs[i]) {
435 149206 : i++;
436 : }
437 :
438 3150029 : referals = PyList_New(i);
439 3150029 : if (referals == NULL) {
440 0 : Py_DECREF(ret);
441 0 : PyErr_NoMemory();
442 0 : return NULL;
443 : }
444 :
445 3299235 : for (i = 0;result->refs && result->refs[i]; i++) {
446 149206 : PyList_SetItem(referals, i, PyUnicode_FromString(result->refs[i]));
447 : }
448 3150029 : ret->referals = referals;
449 3150029 : 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 7886021 : static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self,
531 : PyObject *Py_UNUSED(ignored))
532 : {
533 7886021 : return PyUnicode_FromString(ldb_dn_get_linearized(self->dn));
534 : }
535 :
536 28162 : static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self,
537 : PyObject *Py_UNUSED(ignored))
538 : {
539 28162 : 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 3934519 : 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 3934519 : if (!PyArg_ParseTuple(args, "s", &name))
565 0 : return NULL;
566 3934519 : val = ldb_dn_get_extended_component(self->dn, name);
567 3934519 : if (val == NULL) {
568 1849138 : Py_RETURN_NONE;
569 : }
570 :
571 2085381 : 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 64761 : static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
602 : {
603 64761 : PyObject *str = PyUnicode_FromString(ldb_dn_get_linearized(self->dn));
604 0 : PyObject *repr, *result;
605 64761 : if (str == NULL)
606 0 : return NULL;
607 64761 : repr = PyObject_Repr(str);
608 64761 : if (repr == NULL) {
609 0 : Py_DECREF(str);
610 0 : return NULL;
611 : }
612 64761 : result = PyUnicode_FromFormat("Dn(%s)", PyUnicode_AsUTF8(repr));
613 36258 : Py_DECREF(str);
614 36258 : Py_DECREF(repr);
615 64761 : 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 26592556 : static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op)
629 : {
630 3074048 : int ret;
631 26592556 : if (!pyldb_Dn_Check(dn2)) {
632 1639587 : Py_INCREF(Py_NotImplemented);
633 1931105 : return Py_NotImplemented;
634 : }
635 24661451 : ret = ldb_dn_compare(pyldb_Dn_AS_DN(dn1), pyldb_Dn_AS_DN(dn2));
636 24661451 : return richcmp(ret, op);
637 : }
638 :
639 2260431 : static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self,
640 : PyObject *Py_UNUSED(ignored))
641 : {
642 2260431 : struct ldb_dn *dn = pyldb_Dn_AS_DN((PyObject *)self);
643 249777 : struct ldb_dn *parent;
644 249777 : PyLdbDnObject *py_ret;
645 2260431 : TALLOC_CTX *mem_ctx = NULL;
646 :
647 2260431 : if (ldb_dn_get_comp_num(dn) < 1) {
648 3 : Py_RETURN_NONE;
649 : }
650 :
651 2260428 : mem_ctx = talloc_new(NULL);
652 2260428 : if (mem_ctx == NULL) {
653 0 : PyErr_NoMemory();
654 0 : return NULL;
655 : }
656 :
657 2260428 : parent = ldb_dn_get_parent(mem_ctx, dn);
658 2260428 : if (parent == NULL) {
659 0 : PyErr_NoMemory();
660 0 : talloc_free(mem_ctx);
661 0 : return NULL;
662 : }
663 :
664 2260428 : py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
665 2260428 : if (py_ret == NULL) {
666 0 : PyErr_NoMemory();
667 0 : talloc_free(mem_ctx);
668 0 : return NULL;
669 : }
670 2260428 : py_ret->mem_ctx = mem_ctx;
671 2260428 : py_ret->dn = parent;
672 2260428 : return (PyObject *)py_ret;
673 : }
674 :
675 5764 : 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 5764 : if (!PyArg_ParseTuple(args, "O", &py_other))
681 0 : return NULL;
682 :
683 5764 : dn = pyldb_Dn_AS_DN((PyObject *)self);
684 :
685 5764 : if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
686 0 : return NULL;
687 :
688 5764 : ok = ldb_dn_add_child(dn, other);
689 5764 : if (!ok) {
690 0 : PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, NULL);
691 0 : return NULL;
692 : }
693 :
694 5764 : 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 908613 : 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 908613 : if (!PyArg_ParseTuple(args, "O", &py_base))
743 0 : return NULL;
744 :
745 908613 : dn = pyldb_Dn_AS_DN((PyObject *)self);
746 :
747 908613 : if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base))
748 0 : return NULL;
749 :
750 908613 : return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
751 : }
752 :
753 618 : 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 618 : unsigned int num = 0;
758 :
759 618 : if (!PyArg_ParseTuple(args, "I", &num))
760 0 : return NULL;
761 :
762 618 : dn = pyldb_Dn_AS_DN((PyObject *)self);
763 :
764 618 : name = ldb_dn_get_component_name(dn, num);
765 618 : if (name == NULL) {
766 12 : Py_RETURN_NONE;
767 : }
768 :
769 606 : 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 524666 : static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
792 : {
793 524666 : unsigned int num = 0;
794 524666 : char *name = NULL, *value = NULL;
795 524666 : struct ldb_val val = { 0 };
796 72189 : int err;
797 524666 : Py_ssize_t size = 0;
798 :
799 524666 : if (!PyArg_ParseTuple(args, "Iss#", &num, &name, &value, &size))
800 3 : return NULL;
801 :
802 524663 : val.data = (unsigned char*) value;
803 524663 : val.length = size;
804 :
805 524663 : err = ldb_dn_set_component(self->dn, num, name, val);
806 524663 : if (err != LDB_SUCCESS) {
807 3 : PyErr_SetString(PyExc_TypeError, "Failed to set component");
808 3 : return NULL;
809 : }
810 :
811 524660 : Py_RETURN_NONE;
812 : }
813 :
814 13159496 : 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 13159496 : dn = pyldb_Dn_AS_DN((PyObject *)self);
821 :
822 13159496 : name = ldb_dn_get_rdn_name(dn);
823 13159496 : if (name == NULL) {
824 0 : Py_RETURN_NONE;
825 : }
826 :
827 13159496 : return PyUnicode_FromString(name);
828 : }
829 :
830 524777 : 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 524777 : dn = pyldb_Dn_AS_DN((PyObject *)self);
837 :
838 524777 : val = ldb_dn_get_rdn_val(dn);
839 524777 : if (val == NULL) {
840 0 : Py_RETURN_NONE;
841 : }
842 :
843 524777 : 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 1469174 : static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
924 : {
925 1469174 : TALLOC_CTX *mem_ctx = NULL;
926 1469174 : struct ldb_dn *new_dn = NULL;
927 126102 : PyLdbDnObject *py_ret;
928 :
929 1469174 : mem_ctx = talloc_new(NULL);
930 1469174 : if (mem_ctx == NULL) {
931 0 : return PyErr_NoMemory();
932 : }
933 :
934 1469174 : new_dn = ldb_dn_copy(mem_ctx, dn);
935 1469174 : if (new_dn == NULL) {
936 0 : talloc_free(mem_ctx);
937 0 : return PyErr_NoMemory();
938 : }
939 :
940 1469174 : py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
941 1469174 : if (py_ret == NULL) {
942 0 : talloc_free(mem_ctx);
943 0 : PyErr_NoMemory();
944 0 : return NULL;
945 : }
946 1469174 : py_ret->mem_ctx = mem_ctx;
947 1469174 : py_ret->dn = new_dn;
948 1469174 : 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 1420357 : static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
997 : {
998 1420357 : struct ldb_dn *ret = NULL;
999 1420357 : char *str = NULL;
1000 1420357 : PyObject *py_ldb = NULL;
1001 1420357 : struct ldb_context *ldb_ctx = NULL;
1002 1420357 : TALLOC_CTX *mem_ctx = NULL;
1003 1420357 : PyLdbDnObject *py_ret = NULL;
1004 1420357 : const char * const kwnames[] = { "ldb", "dn", NULL };
1005 :
1006 1420357 : 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 1420353 : if (!PyLdb_Check(py_ldb)) {
1012 0 : PyErr_SetString(PyExc_TypeError, "Expected Ldb");
1013 0 : goto out;
1014 : }
1015 1420353 : ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(py_ldb);
1016 :
1017 1420353 : mem_ctx = talloc_new(NULL);
1018 1420353 : if (mem_ctx == NULL) {
1019 0 : PyErr_NoMemory();
1020 0 : goto out;
1021 : }
1022 :
1023 1420353 : ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
1024 1420353 : 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 1413500 : py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
1031 1413500 : if (py_ret == NULL) {
1032 0 : talloc_free(mem_ctx);
1033 0 : PyErr_NoMemory();
1034 0 : goto out;
1035 : }
1036 1413500 : py_ret->mem_ctx = mem_ctx;
1037 1413500 : py_ret->dn = ret;
1038 1420357 : out:
1039 1420357 : if (str != NULL) {
1040 1420353 : PyMem_Free(discard_const_p(char, str));
1041 : }
1042 1420357 : return (PyObject *)py_ret;
1043 : }
1044 :
1045 28477698 : static void py_ldb_dn_dealloc(PyLdbDnObject *self)
1046 : {
1047 28477698 : talloc_free(self->mem_ctx);
1048 28477698 : PyObject_Del(self);
1049 28477698 : }
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 35004 : static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
1101 : {
1102 450 : unsigned int perms;
1103 35004 : if (!PyArg_ParseTuple(args, "I", &perms))
1104 0 : return NULL;
1105 :
1106 35004 : ldb_set_create_perms(pyldb_Ldb_AS_LDBCONTEXT(self), perms);
1107 :
1108 35004 : Py_RETURN_NONE;
1109 : }
1110 :
1111 35000 : static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
1112 : {
1113 450 : char *modules_dir;
1114 35000 : if (!PyArg_ParseTuple(args, "s", &modules_dir))
1115 0 : return NULL;
1116 :
1117 35000 : ldb_set_modules_dir(pyldb_Ldb_AS_LDBCONTEXT(self), modules_dir);
1118 :
1119 35000 : Py_RETURN_NONE;
1120 : }
1121 :
1122 38908 : static PyObject *py_ldb_transaction_start(PyLdbObject *self,
1123 : PyObject *Py_UNUSED(ignored))
1124 : {
1125 38908 : struct ldb_context *ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1126 285 : int ldb_err;
1127 38908 : ldb_err = ldb_transaction_start(ldb_ctx);
1128 38908 : PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1129 38908 : 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 317 : static PyObject *py_ldb_transaction_cancel(PyLdbObject *self,
1153 : PyObject *Py_UNUSED(ignored))
1154 : {
1155 317 : struct ldb_context *ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1156 0 : int ldb_err;
1157 317 : ldb_err = ldb_transaction_cancel(ldb_ctx);
1158 317 : PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1159 317 : 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 1266489 : static PyObject *py_ldb_get_root_basedn(PyLdbObject *self,
1178 : PyObject *Py_UNUSED(ignored))
1179 : {
1180 1266489 : struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AS_LDBCONTEXT(self));
1181 1266489 : if (dn == NULL)
1182 4 : Py_RETURN_NONE;
1183 1266485 : return py_ldb_dn_copy(dn);
1184 : }
1185 :
1186 :
1187 21452 : static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self,
1188 : PyObject *Py_UNUSED(ignored))
1189 : {
1190 21452 : struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AS_LDBCONTEXT(self));
1191 21452 : if (dn == NULL)
1192 4 : Py_RETURN_NONE;
1193 21448 : return py_ldb_dn_copy(dn);
1194 : }
1195 :
1196 50820 : static PyObject *py_ldb_get_config_basedn(PyLdbObject *self,
1197 : PyObject *Py_UNUSED(ignored))
1198 : {
1199 50820 : struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AS_LDBCONTEXT(self));
1200 50820 : if (dn == NULL)
1201 4 : Py_RETURN_NONE;
1202 50816 : return py_ldb_dn_copy(dn);
1203 : }
1204 :
1205 130431 : static PyObject *py_ldb_get_default_basedn(PyLdbObject *self,
1206 : PyObject *Py_UNUSED(ignored))
1207 : {
1208 130431 : struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AS_LDBCONTEXT(self));
1209 130431 : if (dn == NULL)
1210 6 : Py_RETURN_NONE;
1211 130425 : return py_ldb_dn_copy(dn);
1212 : }
1213 :
1214 5668525 : static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list,
1215 : const char *paramname)
1216 : {
1217 545113 : const char **ret;
1218 545113 : Py_ssize_t i;
1219 5668525 : if (!PyList_Check(list)) {
1220 29 : PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
1221 29 : return NULL;
1222 : }
1223 5668496 : ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
1224 5668496 : if (ret == NULL) {
1225 0 : PyErr_NoMemory();
1226 0 : return NULL;
1227 : }
1228 :
1229 23286336 : for (i = 0; i < PyList_Size(list); i++) {
1230 17617840 : const char *str = NULL;
1231 1677159 : Py_ssize_t size;
1232 17617840 : PyObject *item = PyList_GetItem(list, i);
1233 17617840 : 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 17617840 : str = PyUnicode_AsUTF8AndSize(item, &size);
1239 17617840 : if (str == NULL) {
1240 0 : talloc_free(ret);
1241 0 : return NULL;
1242 : }
1243 17617840 : ret[i] = talloc_strndup(ret, str, size);
1244 : }
1245 5668496 : ret[i] = NULL;
1246 5668496 : 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 39395 : static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1290 : {
1291 39395 : TALLOC_CTX *mem_ctx = NULL;
1292 463 : PyLdbObject *ret;
1293 463 : struct ldb_context *ldb;
1294 :
1295 39395 : mem_ctx = talloc_new(NULL);
1296 39395 : if (mem_ctx == NULL) {
1297 0 : return PyErr_NoMemory();
1298 : }
1299 :
1300 39395 : ldb = ldb_init(mem_ctx, NULL);
1301 39395 : if (ldb == NULL) {
1302 0 : talloc_free(mem_ctx);
1303 0 : PyErr_NoMemory();
1304 0 : return NULL;
1305 : }
1306 :
1307 39395 : ret = (PyLdbObject *)type->tp_alloc(type, 0);
1308 39395 : if (ret == NULL) {
1309 0 : talloc_free(mem_ctx);
1310 0 : PyErr_NoMemory();
1311 0 : return NULL;
1312 : }
1313 39395 : ret->mem_ctx = mem_ctx;
1314 :
1315 39395 : ret->ldb_ctx = ldb;
1316 39395 : return (PyObject *)ret;
1317 : }
1318 :
1319 34518 : static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1320 : {
1321 34518 : char *url = NULL;
1322 34518 : unsigned int flags = 0;
1323 34518 : PyObject *py_options = Py_None;
1324 426 : int ret;
1325 426 : const char **options;
1326 34518 : const char * const kwnames[] = { "url", "flags", "options", NULL };
1327 426 : struct ldb_context *ldb_ctx;
1328 :
1329 34518 : if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|IO",
1330 : discard_const_p(char *, kwnames),
1331 : &url, &flags, &py_options))
1332 0 : return NULL;
1333 :
1334 34518 : if (py_options == Py_None) {
1335 31500 : 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 34518 : ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1343 34518 : ret = ldb_connect(ldb_ctx, url, flags, options);
1344 34518 : talloc_free(options);
1345 :
1346 34518 : PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1347 :
1348 33919 : Py_RETURN_NONE;
1349 : }
1350 :
1351 252746 : static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1352 : {
1353 15562 : PyObject *py_msg;
1354 252746 : 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 252746 : bool validate=true;
1362 252746 : const char * const kwnames[] = { "message", "controls", "validate", NULL };
1363 :
1364 252746 : 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 252746 : mem_ctx = talloc_new(NULL);
1370 252746 : if (mem_ctx == NULL) {
1371 0 : PyErr_NoMemory();
1372 0 : return NULL;
1373 : }
1374 252746 : ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1375 :
1376 252746 : if (py_controls == Py_None) {
1377 72931 : parsed_controls = NULL;
1378 : } else {
1379 179391 : const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1380 179391 : if (controls == NULL) {
1381 3 : talloc_free(mem_ctx);
1382 3 : return NULL;
1383 : }
1384 179388 : parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1385 179388 : 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 179388 : talloc_free(controls);
1391 : }
1392 :
1393 252743 : 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 252740 : msg = pyldb_Message_AsMessage(py_msg);
1399 :
1400 252740 : if (validate) {
1401 252677 : ret = ldb_msg_sanity_check(ldb_ctx, msg);
1402 252677 : 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 252739 : ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1410 : NULL, ldb_op_default_callback, NULL);
1411 252739 : 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 252739 : ret = ldb_transaction_start(ldb_ctx);
1421 252739 : 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 252739 : ret = ldb_request(ldb_ctx, req);
1428 252739 : if (ret == LDB_SUCCESS) {
1429 252677 : ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1430 : }
1431 :
1432 252739 : if (ret == LDB_SUCCESS) {
1433 248074 : ret = ldb_transaction_commit(ldb_ctx);
1434 : } else {
1435 4665 : ldb_transaction_cancel(ldb_ctx);
1436 : }
1437 :
1438 252739 : talloc_free(mem_ctx);
1439 252739 : PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1440 :
1441 248074 : 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 206359 : 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 206359 : unsigned int msg_pos = 0;
1461 206359 : Py_ssize_t dict_pos = 0;
1462 285 : PyObject *key, *value;
1463 285 : struct ldb_message_element *msg_el;
1464 206359 : PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1465 :
1466 206359 : msg = ldb_msg_new(mem_ctx);
1467 206359 : if (msg == NULL) {
1468 0 : PyErr_NoMemory();
1469 0 : return NULL;
1470 : }
1471 206359 : msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1472 206359 : if (msg->elements == NULL) {
1473 0 : PyErr_NoMemory();
1474 0 : TALLOC_FREE(msg);
1475 0 : return NULL;
1476 : }
1477 :
1478 206359 : if (dn_value) {
1479 206353 : 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 206353 : 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 1099354 : while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1496 876620 : const char *key_str = PyUnicode_AsUTF8(key);
1497 876620 : if (ldb_attr_cmp(key_str, "dn") != 0) {
1498 670267 : msg_el = PyObject_AsMessageElement(msg->elements, value,
1499 : mod_flags, key_str);
1500 670267 : 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 670267 : 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 670267 : 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 670267 : 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 670267 : msg_pos++;
1529 : }
1530 : }
1531 :
1532 206353 : msg->num_elements = msg_pos;
1533 :
1534 206353 : return msg;
1535 : }
1536 :
1537 691276 : 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 691276 : struct ldb_message *msg = NULL;
1544 691276 : PyObject *py_controls = Py_None;
1545 85961 : TALLOC_CTX *mem_ctx;
1546 85961 : struct ldb_control **parsed_controls;
1547 691276 : const char * const kwnames[] = { "message", "controls", NULL };
1548 :
1549 691276 : if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1550 : discard_const_p(char *, kwnames),
1551 : &py_obj, &py_controls))
1552 3 : return NULL;
1553 :
1554 691273 : mem_ctx = talloc_new(NULL);
1555 691273 : if (mem_ctx == NULL) {
1556 0 : PyErr_NoMemory();
1557 0 : return NULL;
1558 : }
1559 691273 : ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1560 :
1561 691273 : if (py_controls == Py_None) {
1562 380914 : 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 691261 : if (PyLdbMessage_Check(py_obj)) {
1579 487385 : msg = pyldb_Message_AsMessage(py_obj);
1580 203876 : } else if (PyDict_Check(py_obj)) {
1581 203870 : 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 691261 : if (!msg) {
1588 : /* we should have a PyErr already set */
1589 6 : talloc_free(mem_ctx);
1590 6 : return NULL;
1591 : }
1592 :
1593 691255 : ret = ldb_msg_sanity_check(ldb_ctx, msg);
1594 691255 : 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 691254 : ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1601 : NULL, ldb_op_default_callback, NULL);
1602 691254 : 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 691254 : ret = ldb_transaction_start(ldb_ctx);
1612 691254 : 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 691254 : ret = ldb_request(ldb_ctx, req);
1619 691254 : if (ret == LDB_SUCCESS) {
1620 691230 : ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1621 : }
1622 :
1623 691254 : if (ret == LDB_SUCCESS) {
1624 690084 : ret = ldb_transaction_commit(ldb_ctx);
1625 : } else {
1626 1170 : ldb_transaction_cancel(ldb_ctx);
1627 : }
1628 :
1629 691254 : talloc_free(mem_ctx);
1630 691254 : PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1631 :
1632 690084 : Py_RETURN_NONE;
1633 : }
1634 :
1635 79098 : 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 79098 : PyObject *py_controls = Py_None;
1643 559 : TALLOC_CTX *mem_ctx;
1644 559 : struct ldb_control **parsed_controls;
1645 79098 : const char * const kwnames[] = { "dn", "controls", NULL };
1646 :
1647 79098 : if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1648 : discard_const_p(char *, kwnames),
1649 : &py_dn, &py_controls))
1650 0 : return NULL;
1651 :
1652 79098 : mem_ctx = talloc_new(NULL);
1653 79098 : if (mem_ctx == NULL) {
1654 0 : PyErr_NoMemory();
1655 0 : return NULL;
1656 : }
1657 79098 : ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1658 :
1659 79098 : if (py_controls == Py_None) {
1660 71401 : 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 79098 : if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1677 0 : talloc_free(mem_ctx);
1678 0 : return NULL;
1679 : }
1680 :
1681 79098 : ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1682 : NULL, ldb_op_default_callback, NULL);
1683 79098 : 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 79098 : ret = ldb_transaction_start(ldb_ctx);
1693 79098 : 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 79098 : ret = ldb_request(ldb_ctx, req);
1700 79098 : if (ret == LDB_SUCCESS) {
1701 79094 : ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1702 : }
1703 :
1704 79098 : if (ret == LDB_SUCCESS) {
1705 36931 : ret = ldb_transaction_commit(ldb_ctx);
1706 : } else {
1707 42167 : ldb_transaction_cancel(ldb_ctx);
1708 : }
1709 :
1710 79098 : talloc_free(mem_ctx);
1711 79098 : PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1712 :
1713 36931 : 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 19388 : static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1817 : {
1818 481 : char *attribute, *syntax;
1819 481 : unsigned int flags;
1820 481 : int ret;
1821 481 : struct ldb_context *ldb_ctx;
1822 :
1823 19388 : if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1824 0 : return NULL;
1825 :
1826 19388 : ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1827 19388 : ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1828 :
1829 19388 : PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1830 :
1831 19388 : Py_RETURN_NONE;
1832 : }
1833 :
1834 524545 : static PyObject *ldb_ldif_to_pyobject(struct ldb_context *ldb, struct ldb_ldif *ldif)
1835 : {
1836 524545 : PyObject *obj = NULL;
1837 524545 : PyObject *result = NULL;
1838 :
1839 524545 : if (ldif == NULL) {
1840 0 : Py_RETURN_NONE;
1841 : }
1842 :
1843 524545 : switch (ldif->changetype) {
1844 476131 : case LDB_CHANGETYPE_NONE:
1845 : case LDB_CHANGETYPE_ADD:
1846 476131 : obj = PyLdbMessage_FromMessage(ldif->msg);
1847 476131 : break;
1848 48410 : case LDB_CHANGETYPE_MODIFY:
1849 48410 : obj = PyLdbMessage_FromMessage(ldif->msg);
1850 48410 : 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 524545 : if (obj == NULL) {
1916 0 : return NULL;
1917 : }
1918 :
1919 : /* We don't want this being attached * to the 'ldb' any more */
1920 611258 : result = Py_BuildValue(discard_const_p(char, "(iO)"),
1921 524545 : ldif->changetype,
1922 : obj);
1923 524545 : Py_CLEAR(obj);
1924 437832 : return result;
1925 : }
1926 :
1927 :
1928 14541 : 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 14541 : if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1938 0 : return NULL;
1939 :
1940 14541 : if (!PyLdbMessage_Check(py_msg)) {
1941 0 : PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1942 0 : return NULL;
1943 : }
1944 :
1945 14541 : ldif.msg = pyldb_Message_AsMessage(py_msg);
1946 14541 : ldif.changetype = changetype;
1947 :
1948 14541 : mem_ctx = talloc_new(NULL);
1949 14541 : if (mem_ctx == NULL) {
1950 0 : return PyErr_NoMemory();
1951 : }
1952 :
1953 14541 : string = ldb_ldif_write_string(pyldb_Ldb_AS_LDBCONTEXT(self), mem_ctx, &ldif);
1954 14541 : 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 14541 : ret = PyUnicode_FromString(string);
1961 :
1962 14541 : talloc_free(mem_ctx);
1963 :
1964 14541 : return ret;
1965 : }
1966 :
1967 61505 : 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 61505 : struct ldb_dn *last_dn = NULL;
1973 :
1974 4124 : TALLOC_CTX *mem_ctx;
1975 :
1976 61505 : if (!PyArg_ParseTuple(args, "s", &s))
1977 0 : return NULL;
1978 :
1979 61505 : mem_ctx = talloc_new(NULL);
1980 61505 : if (!mem_ctx) {
1981 0 : Py_RETURN_NONE;
1982 : }
1983 :
1984 61505 : list = PyList_New(0);
1985 61505 : if (list == NULL) {
1986 0 : talloc_free(mem_ctx);
1987 0 : return NULL;
1988 : }
1989 :
1990 586050 : while (s && *s != '\0') {
1991 524545 : ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1992 524545 : talloc_steal(mem_ctx, ldif);
1993 524545 : if (ldif) {
1994 524545 : int res = 0;
1995 524545 : PyObject *py_ldif = ldb_ldif_to_pyobject(self->ldb_ctx, ldif);
1996 524545 : 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 524545 : res = PyList_Append(list, py_ldif);
2005 524545 : Py_CLEAR(py_ldif);
2006 524545 : if (res == -1) {
2007 0 : Py_CLEAR(list);
2008 0 : talloc_free(mem_ctx);
2009 0 : return NULL;
2010 : }
2011 524545 : 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 61505 : talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
2041 61505 : ret = PyObject_GetIter(list);
2042 61505 : Py_DECREF(list);
2043 57381 : 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 25883 : 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 25883 : if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
2113 0 : return NULL;
2114 :
2115 25883 : result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
2116 25883 : old_val.length = size;
2117 :
2118 25883 : if (result != 0) {
2119 0 : PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
2120 0 : return NULL;
2121 : }
2122 :
2123 25883 : a = ldb_schema_attribute_by_name(pyldb_Ldb_AS_LDBCONTEXT(self), element_name);
2124 :
2125 25883 : if (a == NULL) {
2126 0 : Py_RETURN_NONE;
2127 : }
2128 :
2129 25883 : mem_ctx = talloc_new(NULL);
2130 25883 : if (mem_ctx == NULL) {
2131 0 : PyErr_NoMemory();
2132 0 : return NULL;
2133 : }
2134 :
2135 25883 : 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 25883 : ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
2141 :
2142 25883 : talloc_free(mem_ctx);
2143 :
2144 25883 : return ret;
2145 : }
2146 :
2147 3267454 : static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
2148 : {
2149 3267454 : PyObject *py_base = Py_None;
2150 3267454 : int scope = LDB_SCOPE_DEFAULT;
2151 3267454 : char *expr = NULL;
2152 3267454 : PyObject *py_attrs = Py_None;
2153 3267454 : PyObject *py_controls = Py_None;
2154 3267454 : const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
2155 276281 : int ret;
2156 276281 : struct ldb_result *res;
2157 276281 : struct ldb_request *req;
2158 276281 : const char **attrs;
2159 276281 : struct ldb_context *ldb_ctx;
2160 276281 : struct ldb_control **parsed_controls;
2161 276281 : struct ldb_dn *base;
2162 276281 : PyObject *py_ret;
2163 276281 : TALLOC_CTX *mem_ctx;
2164 :
2165 : /* type "int" rather than "enum" for "scope" is intentional */
2166 3267454 : 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 3267445 : mem_ctx = talloc_new(NULL);
2173 3267445 : if (mem_ctx == NULL) {
2174 0 : PyErr_NoMemory();
2175 0 : return NULL;
2176 : }
2177 3267445 : ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
2178 :
2179 3267445 : if (py_attrs == Py_None) {
2180 596521 : attrs = NULL;
2181 : } else {
2182 2615420 : attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
2183 2615420 : if (attrs == NULL) {
2184 11 : talloc_free(mem_ctx);
2185 11 : return NULL;
2186 : }
2187 : }
2188 :
2189 3267434 : if (py_base == Py_None) {
2190 2246 : base = ldb_get_default_basedn(ldb_ctx);
2191 : } else {
2192 3265188 : 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 3267431 : if (py_controls == Py_None) {
2199 667324 : parsed_controls = NULL;
2200 : } else {
2201 2583689 : const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
2202 2583689 : if (controls == NULL) {
2203 3 : talloc_free(mem_ctx);
2204 3 : return NULL;
2205 : }
2206 2583686 : parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
2207 2583686 : 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 2583686 : talloc_free(controls);
2213 : }
2214 :
2215 3267428 : res = talloc_zero(mem_ctx, struct ldb_result);
2216 3267428 : if (res == NULL) {
2217 0 : PyErr_NoMemory();
2218 0 : talloc_free(mem_ctx);
2219 0 : return NULL;
2220 : }
2221 :
2222 3267428 : 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 3267428 : 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 3267422 : talloc_steal(req, attrs);
2239 :
2240 3267422 : ret = ldb_request(ldb_ctx, req);
2241 :
2242 3267422 : if (ret == LDB_SUCCESS) {
2243 3267215 : ret = ldb_wait(req->handle, LDB_WAIT_ALL);
2244 : }
2245 :
2246 3267422 : if (ret != LDB_SUCCESS) {
2247 117444 : talloc_free(mem_ctx);
2248 117444 : PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2249 117444 : return NULL;
2250 : }
2251 :
2252 3149978 : py_ret = PyLdbResult_FromResult(res);
2253 :
2254 3149978 : talloc_free(mem_ctx);
2255 :
2256 3149978 : return py_ret;
2257 : }
2258 :
2259 15383 : static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
2260 : {
2261 15383 : if (reply->py_iter != NULL) {
2262 15383 : DLIST_REMOVE(reply->py_iter->state.next, reply);
2263 15383 : if (reply->py_iter->state.result == reply) {
2264 51 : reply->py_iter->state.result = NULL;
2265 : }
2266 15383 : reply->py_iter = NULL;
2267 : }
2268 :
2269 15383 : Py_CLEAR(reply->obj);
2270 :
2271 15383 : return 0;
2272 : }
2273 :
2274 16750 : static int py_ldb_search_iterator_callback(struct ldb_request *req,
2275 : struct ldb_reply *ares)
2276 : {
2277 16750 : PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
2278 16750 : struct ldb_result result = { .msgs = NULL };
2279 16750 : struct py_ldb_search_iterator_reply *reply = NULL;
2280 :
2281 16750 : if (ares == NULL) {
2282 0 : return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2283 : }
2284 :
2285 16750 : 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 15383 : reply = talloc_zero(py_iter->mem_ctx,
2292 : struct py_ldb_search_iterator_reply);
2293 15383 : if (reply == NULL) {
2294 0 : TALLOC_FREE(ares);
2295 0 : return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2296 : }
2297 15383 : reply->py_iter = py_iter;
2298 15383 : talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
2299 :
2300 15383 : switch (ares->type) {
2301 15314 : case LDB_REPLY_ENTRY:
2302 15314 : reply->obj = PyLdbMessage_FromMessage(ares->message);
2303 15314 : if (reply->obj == NULL) {
2304 0 : TALLOC_FREE(ares);
2305 0 : return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2306 : }
2307 15314 : DLIST_ADD_END(py_iter->state.next, reply);
2308 15314 : TALLOC_FREE(ares);
2309 15314 : 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 39404 : static void py_ldb_dealloc(PyLdbObject *self)
2816 : {
2817 39404 : talloc_free(self->mem_ctx);
2818 39404 : Py_TYPE(self)->tp_free(self);
2819 39404 : }
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 3150029 : static void py_ldb_result_dealloc(PyLdbResultObject *self)
2837 : {
2838 3150029 : talloc_free(self->mem_ctx);
2839 3150029 : Py_CLEAR(self->msgs);
2840 3150029 : Py_CLEAR(self->referals);
2841 3150029 : Py_CLEAR(self->controls);
2842 3150029 : Py_TYPE(self)->tp_free(self);
2843 3150029 : }
2844 :
2845 5973 : static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2846 : {
2847 5973 : Py_INCREF(self->msgs);
2848 5973 : 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 1826 : static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2864 : {
2865 0 : Py_ssize_t size;
2866 1826 : if (self->msgs == NULL) {
2867 0 : PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2868 0 : return NULL;
2869 : }
2870 1826 : size = PyList_Size(self->msgs);
2871 1826 : 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 165600 : static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2895 : {
2896 165600 : return PyObject_GetIter(self->msgs);
2897 : }
2898 :
2899 1808957 : static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2900 : {
2901 1808957 : return PySequence_Size(self->msgs);
2902 : }
2903 :
2904 4670887 : static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2905 : {
2906 4670887 : 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 3485642 : while (self->state.next == NULL) {
2962 0 : int ret;
2963 :
2964 3470788 : 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 3470739 : ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE);
2978 3470739 : 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(PyExc_LdbError, ret, mod->ldb);
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(PyExc_LdbError, ret, mod->ldb);
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 : req->operation = LDB_ADD;
3168 0 : req->op.add.message = pyldb_Message_AsMessage(py_message);
3169 :
3170 0 : mod = pyldb_Module_AsModule(self);
3171 0 : ret = mod->ops->add(mod, req);
3172 :
3173 0 : PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
3174 :
3175 0 : Py_RETURN_NONE;
3176 : }
3177 :
3178 0 : static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
3179 : {
3180 0 : int ret;
3181 0 : struct ldb_request *req;
3182 0 : PyObject *py_message;
3183 0 : struct ldb_module *mod;
3184 :
3185 0 : if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
3186 0 : return NULL;
3187 :
3188 0 : req = talloc_zero(NULL, struct ldb_request);
3189 0 : req->operation = LDB_MODIFY;
3190 0 : req->op.mod.message = pyldb_Message_AsMessage(py_message);
3191 :
3192 0 : mod = pyldb_Module_AsModule(self);
3193 0 : ret = mod->ops->modify(mod, req);
3194 :
3195 0 : PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
3196 :
3197 0 : Py_RETURN_NONE;
3198 : }
3199 :
3200 0 : static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
3201 : {
3202 0 : int ret;
3203 0 : struct ldb_request *req;
3204 0 : PyObject *py_dn;
3205 :
3206 0 : if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
3207 0 : return NULL;
3208 :
3209 0 : req = talloc_zero(NULL, struct ldb_request);
3210 0 : req->operation = LDB_DELETE;
3211 0 : req->op.del.dn = pyldb_Dn_AS_DN(py_dn);
3212 :
3213 0 : ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
3214 :
3215 0 : PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3216 :
3217 0 : Py_RETURN_NONE;
3218 : }
3219 :
3220 0 : static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
3221 : {
3222 0 : int ret;
3223 0 : struct ldb_request *req;
3224 0 : PyObject *py_dn1, *py_dn2;
3225 :
3226 0 : if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
3227 0 : return NULL;
3228 :
3229 0 : req = talloc_zero(NULL, struct ldb_request);
3230 :
3231 0 : req->operation = LDB_RENAME;
3232 0 : req->op.rename.olddn = pyldb_Dn_AS_DN(py_dn1);
3233 0 : req->op.rename.newdn = pyldb_Dn_AS_DN(py_dn2);
3234 :
3235 0 : ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
3236 :
3237 0 : PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3238 :
3239 0 : Py_RETURN_NONE;
3240 : }
3241 :
3242 : static PyMethodDef py_ldb_module_methods[] = {
3243 : { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_module_search),
3244 : METH_VARARGS|METH_KEYWORDS, NULL },
3245 : { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
3246 : { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
3247 : { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
3248 : { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
3249 : { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
3250 : { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
3251 : { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
3252 : {0},
3253 : };
3254 :
3255 11 : static void py_ldb_module_dealloc(PyLdbModuleObject *self)
3256 : {
3257 11 : talloc_free(self->mem_ctx);
3258 11 : PyObject_Del(self);
3259 11 : }
3260 :
3261 : static PyTypeObject PyLdbModule = {
3262 : .tp_name = "ldb.LdbModule",
3263 : .tp_methods = py_ldb_module_methods,
3264 : .tp_repr = (reprfunc)py_ldb_module_repr,
3265 : .tp_str = (reprfunc)py_ldb_module_str,
3266 : .tp_basicsize = sizeof(PyLdbModuleObject),
3267 : .tp_dealloc = (destructor)py_ldb_module_dealloc,
3268 : .tp_flags = Py_TPFLAGS_DEFAULT,
3269 : .tp_doc = "LDB module (extension)",
3270 : };
3271 :
3272 :
3273 : /**
3274 : * Create a ldb_message_element from a Python object.
3275 : *
3276 : * This will accept any sequence objects that contains strings, or
3277 : * a string object.
3278 : *
3279 : * A reference to set_obj might be borrowed.
3280 : *
3281 : * @param mem_ctx Memory context
3282 : * @param set_obj Python object to convert
3283 : * @param flags ldb_message_element flags to set, if a new element is returned
3284 : * @param attr_name Name of the attribute to set, if a new element is returned
3285 : * @return New ldb_message_element, allocated as child of mem_ctx
3286 : */
3287 1015141 : static struct ldb_message_element *PyObject_AsMessageElement(
3288 : TALLOC_CTX *mem_ctx,
3289 : PyObject *set_obj,
3290 : unsigned int flags,
3291 : const char *attr_name)
3292 : {
3293 19946 : struct ldb_message_element *me;
3294 1015141 : const char *msg = NULL;
3295 19946 : Py_ssize_t size;
3296 19946 : int result;
3297 :
3298 1015141 : if (pyldb_MessageElement_Check(set_obj)) {
3299 332845 : PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
3300 : /* We have to talloc_reference() the memory context, not the pointer
3301 : * which may not actually be it's own context */
3302 332845 : if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
3303 332845 : return pyldb_MessageElement_AsMessageElement(set_obj);
3304 : }
3305 0 : return NULL;
3306 : }
3307 :
3308 682296 : me = talloc(mem_ctx, struct ldb_message_element);
3309 682296 : if (me == NULL) {
3310 0 : PyErr_NoMemory();
3311 0 : return NULL;
3312 : }
3313 :
3314 682296 : me->name = talloc_strdup(me, attr_name);
3315 682296 : if (me->name == NULL) {
3316 0 : PyErr_NoMemory();
3317 0 : talloc_free(me);
3318 0 : return NULL;
3319 : }
3320 682296 : me->flags = flags;
3321 682296 : if (PyBytes_Check(set_obj) || PyUnicode_Check(set_obj)) {
3322 661201 : me->num_values = 1;
3323 661201 : me->values = talloc_array(me, struct ldb_val, me->num_values);
3324 661201 : if (PyBytes_Check(set_obj)) {
3325 269662 : char *_msg = NULL;
3326 269662 : result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
3327 269662 : if (result != 0) {
3328 0 : talloc_free(me);
3329 0 : return NULL;
3330 : }
3331 269662 : msg = _msg;
3332 : } else {
3333 391539 : msg = PyUnicode_AsUTF8AndSize(set_obj, &size);
3334 391539 : if (msg == NULL) {
3335 0 : talloc_free(me);
3336 0 : return NULL;
3337 : }
3338 : }
3339 661201 : me->values[0].data = talloc_memdup(me,
3340 : (const uint8_t *)msg,
3341 : size+1);
3342 661201 : me->values[0].length = size;
3343 21095 : } else if (PySequence_Check(set_obj)) {
3344 1708 : Py_ssize_t i;
3345 21095 : me->num_values = PySequence_Size(set_obj);
3346 21095 : me->values = talloc_array(me, struct ldb_val, me->num_values);
3347 62996 : for (i = 0; i < me->num_values; i++) {
3348 41901 : PyObject *obj = PySequence_GetItem(set_obj, i);
3349 41901 : if (PyBytes_Check(obj)) {
3350 17217 : char *_msg = NULL;
3351 17217 : result = PyBytes_AsStringAndSize(obj, &_msg, &size);
3352 17217 : if (result != 0) {
3353 0 : talloc_free(me);
3354 0 : return NULL;
3355 : }
3356 17217 : msg = _msg;
3357 24684 : } else if (PyUnicode_Check(obj)) {
3358 24684 : msg = PyUnicode_AsUTF8AndSize(obj, &size);
3359 24684 : if (msg == NULL) {
3360 0 : talloc_free(me);
3361 0 : return NULL;
3362 : }
3363 : } else {
3364 0 : PyErr_Format(PyExc_TypeError,
3365 : "Expected string as element %zd in list", i);
3366 0 : talloc_free(me);
3367 0 : return NULL;
3368 : }
3369 41901 : me->values[i].data = talloc_memdup(me,
3370 : (const uint8_t *)msg,
3371 : size+1);
3372 41901 : me->values[i].length = size;
3373 : }
3374 : } else {
3375 0 : PyErr_Format(PyExc_TypeError,
3376 : "String or List type expected for '%s' attribute", attr_name);
3377 0 : talloc_free(me);
3378 0 : me = NULL;
3379 : }
3380 :
3381 679630 : return me;
3382 : }
3383 :
3384 :
3385 25992421 : static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
3386 : struct ldb_message_element *me)
3387 : {
3388 2980826 : Py_ssize_t i;
3389 2980826 : PyObject *result;
3390 :
3391 : /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
3392 25992421 : result = PyList_New(me->num_values);
3393 25992421 : if (result == NULL) {
3394 0 : return NULL;
3395 : }
3396 :
3397 59572205 : for (i = 0; i < me->num_values; i++) {
3398 33579784 : PyObject *obj = NULL;
3399 3985290 : int ret;
3400 :
3401 33579784 : obj = PyObject_FromLdbValue(&me->values[i]);
3402 33579784 : if (obj == NULL) {
3403 0 : Py_DECREF(result);
3404 0 : return NULL;
3405 : }
3406 :
3407 33579784 : ret = PyList_SetItem(result, i, obj);
3408 33579784 : if (ret) {
3409 0 : Py_DECREF(obj);
3410 0 : Py_DECREF(result);
3411 0 : return NULL;
3412 : }
3413 : }
3414 :
3415 23011595 : return result;
3416 : }
3417 :
3418 0 : static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
3419 : {
3420 0 : unsigned int i;
3421 0 : if (!PyArg_ParseTuple(args, "I", &i))
3422 0 : return NULL;
3423 0 : if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
3424 0 : Py_RETURN_NONE;
3425 :
3426 0 : return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
3427 : }
3428 :
3429 52 : static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
3430 : {
3431 52 : struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3432 52 : return PyLong_FromLong(el->flags);
3433 : }
3434 :
3435 5277 : static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
3436 : {
3437 22 : unsigned int flags;
3438 22 : struct ldb_message_element *el;
3439 5277 : if (!PyArg_ParseTuple(args, "I", &flags))
3440 0 : return NULL;
3441 :
3442 5277 : el = pyldb_MessageElement_AsMessageElement(self);
3443 5277 : el->flags = flags;
3444 5277 : Py_RETURN_NONE;
3445 : }
3446 :
3447 : static PyMethodDef py_ldb_msg_element_methods[] = {
3448 : { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
3449 : { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
3450 : { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
3451 : {0},
3452 : };
3453 :
3454 28377985 : static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
3455 : {
3456 28377985 : return pyldb_MessageElement_AsMessageElement(self)->num_values;
3457 : }
3458 :
3459 20016330 : static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
3460 : {
3461 20016330 : struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3462 20016330 : if (idx < 0 || idx >= el->num_values) {
3463 6 : PyErr_SetString(PyExc_IndexError, "Out of range");
3464 6 : return NULL;
3465 : }
3466 20016324 : return PyLdbBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
3467 : }
3468 :
3469 : static PySequenceMethods py_ldb_msg_element_seq = {
3470 : .sq_length = (lenfunc)py_ldb_msg_element_len,
3471 : .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
3472 : };
3473 :
3474 369 : static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
3475 : {
3476 12 : int ret;
3477 369 : if (!pyldb_MessageElement_Check(other)) {
3478 168 : Py_INCREF(Py_NotImplemented);
3479 187 : return Py_NotImplemented;
3480 : }
3481 182 : ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
3482 : pyldb_MessageElement_AsMessageElement(other));
3483 182 : return richcmp(ret, op);
3484 : }
3485 :
3486 25992421 : static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
3487 : {
3488 25992421 : PyObject *el = ldb_msg_element_to_set(NULL,
3489 : pyldb_MessageElement_AsMessageElement(self));
3490 25992421 : PyObject *ret = PyObject_GetIter(el);
3491 22873673 : Py_DECREF(el);
3492 25992421 : return ret;
3493 : }
3494 :
3495 44670753 : static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
3496 : {
3497 44670753 : TALLOC_CTX *ret_mem_ctx = NULL;
3498 5366431 : PyLdbMessageElementObject *ret;
3499 :
3500 44670753 : ret_mem_ctx = talloc_new(NULL);
3501 44670753 : if (ret_mem_ctx == NULL) {
3502 0 : return PyErr_NoMemory();
3503 : }
3504 :
3505 44670753 : if (talloc_reference(ret_mem_ctx, mem_ctx) == NULL) {
3506 0 : talloc_free(ret_mem_ctx);
3507 0 : PyErr_NoMemory();
3508 0 : return NULL;
3509 : }
3510 :
3511 44670753 : ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
3512 44670753 : if (ret == NULL) {
3513 0 : talloc_free(ret_mem_ctx);
3514 0 : PyErr_NoMemory();
3515 0 : return NULL;
3516 : }
3517 44670753 : ret->mem_ctx = ret_mem_ctx;
3518 44670753 : ret->el = el;
3519 44670753 : return (PyObject *)ret;
3520 : }
3521 :
3522 330380 : static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3523 : {
3524 330380 : PyObject *py_elements = NULL;
3525 17282 : struct ldb_message_element *el;
3526 330380 : unsigned int flags = 0;
3527 330380 : char *name = NULL;
3528 330380 : const char * const kwnames[] = { "elements", "flags", "name", NULL };
3529 17282 : PyLdbMessageElementObject *ret;
3530 17282 : TALLOC_CTX *mem_ctx;
3531 330380 : const char *msg = NULL;
3532 17282 : Py_ssize_t size;
3533 17282 : int result;
3534 :
3535 330380 : if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
3536 : discard_const_p(char *, kwnames),
3537 : &py_elements, &flags, &name))
3538 0 : return NULL;
3539 :
3540 330380 : mem_ctx = talloc_new(NULL);
3541 330380 : if (mem_ctx == NULL) {
3542 0 : PyErr_NoMemory();
3543 0 : return NULL;
3544 : }
3545 :
3546 330380 : el = talloc_zero(mem_ctx, struct ldb_message_element);
3547 330380 : if (el == NULL) {
3548 0 : PyErr_NoMemory();
3549 0 : talloc_free(mem_ctx);
3550 0 : return NULL;
3551 : }
3552 :
3553 330380 : if (py_elements != NULL) {
3554 17282 : Py_ssize_t i;
3555 330380 : if (PyBytes_Check(py_elements) || PyUnicode_Check(py_elements)) {
3556 317397 : char *_msg = NULL;
3557 317397 : el->num_values = 1;
3558 317397 : el->values = talloc_array(el, struct ldb_val, 1);
3559 317397 : if (el->values == NULL) {
3560 0 : talloc_free(mem_ctx);
3561 0 : PyErr_NoMemory();
3562 0 : return NULL;
3563 : }
3564 317397 : if (PyBytes_Check(py_elements)) {
3565 87078 : result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
3566 87078 : msg = _msg;
3567 : } else {
3568 230319 : msg = PyUnicode_AsUTF8AndSize(py_elements, &size);
3569 230319 : result = (msg == NULL) ? -1 : 0;
3570 : }
3571 317397 : if (result != 0) {
3572 0 : talloc_free(mem_ctx);
3573 0 : return NULL;
3574 : }
3575 317397 : el->values[0].data = talloc_memdup(el->values,
3576 : (const uint8_t *)msg, size + 1);
3577 317397 : el->values[0].length = size;
3578 12983 : } else if (PySequence_Check(py_elements)) {
3579 12983 : el->num_values = PySequence_Size(py_elements);
3580 12983 : el->values = talloc_array(el, struct ldb_val, el->num_values);
3581 12983 : if (el->values == NULL) {
3582 0 : talloc_free(mem_ctx);
3583 0 : PyErr_NoMemory();
3584 0 : return NULL;
3585 : }
3586 33681 : for (i = 0; i < el->num_values; i++) {
3587 20698 : PyObject *item = PySequence_GetItem(py_elements, i);
3588 20698 : if (item == NULL) {
3589 0 : talloc_free(mem_ctx);
3590 0 : return NULL;
3591 : }
3592 20698 : if (PyBytes_Check(item)) {
3593 10926 : char *_msg = NULL;
3594 10926 : result = PyBytes_AsStringAndSize(item, &_msg, &size);
3595 10926 : msg = _msg;
3596 9772 : } else if (PyUnicode_Check(item)) {
3597 9772 : msg = PyUnicode_AsUTF8AndSize(item, &size);
3598 9772 : result = (msg == NULL) ? -1 : 0;
3599 : } else {
3600 0 : PyErr_Format(PyExc_TypeError,
3601 : "Expected string as element %zd in list", i);
3602 0 : result = -1;
3603 : }
3604 20698 : if (result != 0) {
3605 0 : talloc_free(mem_ctx);
3606 0 : return NULL;
3607 : }
3608 20698 : el->values[i].data = talloc_memdup(el,
3609 : (const uint8_t *)msg, size+1);
3610 20698 : el->values[i].length = size;
3611 : }
3612 : } else {
3613 0 : PyErr_SetString(PyExc_TypeError,
3614 : "Expected string or list");
3615 0 : talloc_free(mem_ctx);
3616 0 : return NULL;
3617 : }
3618 : }
3619 :
3620 330380 : el->flags = flags;
3621 330380 : if (name != NULL) {
3622 330220 : el->name = talloc_strdup(el, name);
3623 330220 : if (el->name == NULL) {
3624 0 : talloc_free(mem_ctx);
3625 0 : return PyErr_NoMemory();
3626 : }
3627 : }
3628 :
3629 330380 : ret = PyObject_New(PyLdbMessageElementObject, type);
3630 330380 : if (ret == NULL) {
3631 0 : talloc_free(mem_ctx);
3632 0 : return NULL;
3633 : }
3634 :
3635 330380 : ret->mem_ctx = mem_ctx;
3636 330380 : ret->el = el;
3637 330380 : return (PyObject *)ret;
3638 : }
3639 :
3640 58462 : static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
3641 : {
3642 58462 : char *element_str = NULL;
3643 0 : Py_ssize_t i;
3644 58462 : struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3645 0 : PyObject *ret, *repr;
3646 :
3647 116948 : for (i = 0; i < el->num_values; i++) {
3648 58486 : PyObject *o = py_ldb_msg_element_find(self, i);
3649 58486 : repr = PyObject_Repr(o);
3650 58486 : if (element_str == NULL)
3651 58462 : element_str = talloc_strdup(NULL, PyUnicode_AsUTF8(repr));
3652 : else
3653 24 : element_str = talloc_asprintf_append(element_str, ",%s", PyUnicode_AsUTF8(repr));
3654 36880 : Py_DECREF(repr);
3655 :
3656 58486 : if (element_str == NULL) {
3657 0 : return PyErr_NoMemory();
3658 : }
3659 : }
3660 :
3661 58462 : if (element_str != NULL) {
3662 58462 : ret = PyUnicode_FromFormat("MessageElement([%s])", element_str);
3663 58462 : talloc_free(element_str);
3664 : } else {
3665 0 : ret = PyUnicode_FromString("MessageElement([])");
3666 : }
3667 :
3668 58462 : return ret;
3669 : }
3670 :
3671 83570 : static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
3672 : {
3673 83570 : struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3674 :
3675 83570 : if (el->num_values == 1)
3676 83570 : return PyUnicode_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
3677 : else
3678 0 : Py_RETURN_NONE;
3679 : }
3680 :
3681 55880887 : static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
3682 : {
3683 55880887 : talloc_free(self->mem_ctx);
3684 55880887 : PyObject_Del(self);
3685 55880887 : }
3686 :
3687 27 : static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
3688 : {
3689 27 : return wrap_text("MessageElementTextWrapper", self);
3690 : }
3691 :
3692 : static PyGetSetDef py_ldb_msg_element_getset[] = {
3693 : {
3694 : .name = discard_const_p(char, "text"),
3695 : .get = (getter)py_ldb_msg_element_get_text,
3696 : },
3697 : { .name = NULL }
3698 : };
3699 :
3700 : static PyTypeObject PyLdbMessageElement = {
3701 : .tp_name = "ldb.MessageElement",
3702 : .tp_basicsize = sizeof(PyLdbMessageElementObject),
3703 : .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
3704 : .tp_repr = (reprfunc)py_ldb_msg_element_repr,
3705 : .tp_str = (reprfunc)py_ldb_msg_element_str,
3706 : .tp_methods = py_ldb_msg_element_methods,
3707 : .tp_getset = py_ldb_msg_element_getset,
3708 : .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
3709 : .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
3710 : .tp_as_sequence = &py_ldb_msg_element_seq,
3711 : .tp_new = py_ldb_msg_element_new,
3712 : .tp_flags = Py_TPFLAGS_DEFAULT,
3713 : .tp_doc = "An element of a Message",
3714 : };
3715 :
3716 :
3717 2507 : static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
3718 : {
3719 0 : PyObject *py_ldb;
3720 0 : PyObject *py_dict;
3721 0 : PyObject *py_ret;
3722 0 : struct ldb_message *msg;
3723 0 : struct ldb_context *ldb_ctx;
3724 2507 : unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
3725 :
3726 2507 : if (!PyArg_ParseTuple(args, "O!O!|I",
3727 : &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
3728 : &mod_flags)) {
3729 12 : return NULL;
3730 : }
3731 :
3732 2495 : if (!PyLdb_Check(py_ldb)) {
3733 0 : PyErr_SetString(PyExc_TypeError, "Expected Ldb");
3734 0 : return NULL;
3735 : }
3736 :
3737 : /* mask only flags we are going to use */
3738 2495 : mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
3739 2495 : if (!mod_flags) {
3740 6 : PyErr_SetString(PyExc_ValueError,
3741 : "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3742 : " expected as mod_flag value");
3743 6 : return NULL;
3744 : }
3745 :
3746 2489 : ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(py_ldb);
3747 :
3748 2489 : msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
3749 2489 : if (!msg) {
3750 6 : return NULL;
3751 : }
3752 :
3753 2483 : py_ret = PyLdbMessage_FromMessage(msg);
3754 :
3755 2483 : talloc_unlink(ldb_ctx, msg);
3756 :
3757 2483 : return py_ret;
3758 : }
3759 :
3760 751882 : static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
3761 : {
3762 182 : char *name;
3763 751882 : if (!PyArg_ParseTuple(args, "s", &name))
3764 0 : return NULL;
3765 :
3766 751882 : ldb_msg_remove_attr(self->msg, name);
3767 :
3768 751882 : Py_RETURN_NONE;
3769 : }
3770 :
3771 2909457 : static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self,
3772 : PyObject *Py_UNUSED(ignored))
3773 : {
3774 2909457 : struct ldb_message *msg = pyldb_Message_AsMessage(self);
3775 2909457 : Py_ssize_t i, j = 0;
3776 2909459 : PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
3777 2909457 : if (obj == NULL) {
3778 0 : return NULL;
3779 : }
3780 :
3781 2909457 : if (msg->dn != NULL) {
3782 2909454 : PyObject *py_dn = NULL;
3783 244846 : int ret;
3784 :
3785 2909454 : py_dn = PyUnicode_FromString("dn");
3786 2909454 : if (py_dn == NULL) {
3787 0 : Py_DECREF(obj);
3788 0 : return NULL;
3789 : }
3790 :
3791 2909454 : ret = PyList_SetItem(obj, j, py_dn);
3792 2909454 : if (ret) {
3793 0 : Py_DECREF(py_dn);
3794 0 : Py_DECREF(obj);
3795 0 : return NULL;
3796 : }
3797 :
3798 2664608 : j++;
3799 : }
3800 32309140 : for (i = 0; i < msg->num_elements; i++) {
3801 29399683 : PyObject *py_name = NULL;
3802 3349031 : int ret;
3803 :
3804 29399683 : py_name = PyUnicode_FromString(msg->elements[i].name);
3805 29399683 : if (py_name == NULL) {
3806 0 : Py_DECREF(obj);
3807 0 : return NULL;
3808 : }
3809 :
3810 29399683 : ret = PyList_SetItem(obj, j, py_name);
3811 29399683 : if (ret) {
3812 0 : Py_DECREF(py_name);
3813 0 : Py_DECREF(obj);
3814 0 : return NULL;
3815 : }
3816 :
3817 29399683 : j++;
3818 : }
3819 2664609 : return obj;
3820 : }
3821 :
3822 2260069 : static int py_ldb_msg_contains(PyLdbMessageObject *self, PyObject *py_name)
3823 : {
3824 2260069 : struct ldb_message_element *el = NULL;
3825 2260069 : const char *name = NULL;
3826 2260069 : struct ldb_message *msg = pyldb_Message_AsMessage(self);
3827 2260069 : name = PyUnicode_AsUTF8(py_name);
3828 2260069 : if (name == NULL) {
3829 3 : return -1;
3830 : }
3831 2260066 : if (!ldb_attr_cmp(name, "dn")) {
3832 1777 : return 1;
3833 : }
3834 2258289 : el = ldb_msg_find_element(msg, name);
3835 2258289 : return el != NULL ? 1 : 0;
3836 : }
3837 :
3838 45269725 : static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
3839 : {
3840 45269725 : struct ldb_message_element *el = NULL;
3841 45269725 : const char *name = NULL;
3842 45269725 : struct ldb_message *msg = pyldb_Message_AsMessage(self);
3843 45269725 : name = PyUnicode_AsUTF8(py_name);
3844 45269725 : if (name == NULL) {
3845 3 : return NULL;
3846 : }
3847 45269722 : if (!ldb_attr_cmp(name, "dn")) {
3848 672000 : return pyldb_Dn_FromDn(msg->dn);
3849 : }
3850 44597722 : el = ldb_msg_find_element(msg, name);
3851 44597722 : if (el == NULL) {
3852 1143 : PyErr_SetString(PyExc_KeyError, "No such element");
3853 1143 : return NULL;
3854 : }
3855 :
3856 44596579 : return PyLdbMessageElement_FromMessageElement(el, msg->elements);
3857 : }
3858 :
3859 98126 : static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
3860 : {
3861 98126 : PyObject *def = NULL;
3862 98126 : const char *kwnames[] = { "name", "default", "idx", NULL };
3863 98126 : const char *name = NULL;
3864 98126 : int idx = -1;
3865 98126 : struct ldb_message *msg = pyldb_Message_AsMessage(self);
3866 3147 : struct ldb_message_element *el;
3867 :
3868 98126 : if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
3869 : discard_const_p(char *, kwnames), &name, &def, &idx)) {
3870 3 : return NULL;
3871 : }
3872 :
3873 98123 : if (strcasecmp(name, "dn") == 0) {
3874 1069 : return pyldb_Dn_FromDn(msg->dn);
3875 : }
3876 :
3877 97054 : el = ldb_msg_find_element(msg, name);
3878 :
3879 97054 : if (el == NULL || (idx != -1 && el->num_values <= idx)) {
3880 14270 : if (def != NULL) {
3881 170 : Py_INCREF(def);
3882 170 : return def;
3883 : }
3884 14100 : Py_RETURN_NONE;
3885 : }
3886 :
3887 82784 : if (idx == -1) {
3888 74156 : return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3889 : }
3890 :
3891 8628 : return PyObject_FromLdbValue(&el->values[idx]);
3892 : }
3893 :
3894 12 : static PyObject *py_ldb_msg_items(PyLdbMessageObject *self,
3895 : PyObject *Py_UNUSED(ignored))
3896 : {
3897 12 : struct ldb_message *msg = pyldb_Message_AsMessage(self);
3898 12 : Py_ssize_t i, j = 0;
3899 12 : PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
3900 12 : if (l == NULL) {
3901 0 : return PyErr_NoMemory();
3902 : }
3903 12 : if (msg->dn != NULL) {
3904 6 : PyObject *value = NULL;
3905 6 : PyObject *obj = pyldb_Dn_FromDn(msg->dn);
3906 6 : int res = 0;
3907 6 : value = Py_BuildValue("(sO)", "dn", obj);
3908 6 : Py_CLEAR(obj);
3909 6 : if (value == NULL) {
3910 0 : Py_CLEAR(l);
3911 0 : return NULL;
3912 : }
3913 6 : res = PyList_SetItem(l, 0, value);
3914 6 : if (res == -1) {
3915 0 : Py_CLEAR(l);
3916 0 : return NULL;
3917 : }
3918 6 : j++;
3919 : }
3920 24 : for (i = 0; i < msg->num_elements; i++, j++) {
3921 12 : PyObject *value = NULL;
3922 12 : PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3923 12 : int res = 0;
3924 12 : value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
3925 12 : Py_CLEAR(py_el);
3926 12 : if (value == NULL ) {
3927 0 : Py_CLEAR(l);
3928 0 : return NULL;
3929 : }
3930 12 : res = PyList_SetItem(l, j, value);
3931 12 : if (res == -1) {
3932 0 : Py_CLEAR(l);
3933 0 : return NULL;
3934 : }
3935 : }
3936 12 : return l;
3937 : }
3938 :
3939 9 : static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self,
3940 : PyObject *Py_UNUSED(ignored))
3941 : {
3942 9 : struct ldb_message *msg = pyldb_Message_AsMessage(self);
3943 9 : Py_ssize_t i = 0;
3944 9 : PyObject *l = PyList_New(msg->num_elements);
3945 9 : if (l == NULL) {
3946 0 : return NULL;
3947 : }
3948 15 : for (i = 0; i < msg->num_elements; i++) {
3949 6 : PyObject *msg_el = NULL;
3950 0 : int ret;
3951 :
3952 6 : msg_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3953 6 : if (msg_el == NULL) {
3954 0 : Py_DECREF(l);
3955 0 : return NULL;
3956 : }
3957 :
3958 6 : ret = PyList_SetItem(l, i, msg_el);
3959 6 : if (ret) {
3960 0 : Py_DECREF(msg_el);
3961 0 : Py_DECREF(l);
3962 0 : return NULL;
3963 : }
3964 : }
3965 9 : return l;
3966 : }
3967 :
3968 2707 : static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
3969 : {
3970 2707 : struct ldb_message *msg = pyldb_Message_AsMessage(self);
3971 2 : PyLdbMessageElementObject *py_element;
3972 2 : int i, ret;
3973 2 : struct ldb_message_element *el;
3974 2 : struct ldb_message_element *el_new;
3975 :
3976 2707 : if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
3977 0 : return NULL;
3978 :
3979 2707 : el = py_element->el;
3980 2707 : if (el == NULL) {
3981 0 : PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
3982 0 : return NULL;
3983 : }
3984 2707 : if (el->name == NULL) {
3985 0 : PyErr_SetString(PyExc_ValueError,
3986 : "The element has no name");
3987 0 : return NULL;
3988 : }
3989 2707 : ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
3990 2707 : PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3991 :
3992 : /* now deep copy all attribute values */
3993 2707 : el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
3994 2707 : if (el_new->values == NULL) {
3995 0 : PyErr_NoMemory();
3996 0 : return NULL;
3997 : }
3998 2707 : el_new->num_values = el->num_values;
3999 :
4000 4863 : for (i = 0; i < el->num_values; i++) {
4001 2156 : el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
4002 2156 : if (el_new->values[i].data == NULL
4003 0 : && el->values[i].length != 0) {
4004 0 : PyErr_NoMemory();
4005 0 : return NULL;
4006 : }
4007 : }
4008 :
4009 2707 : Py_RETURN_NONE;
4010 : }
4011 :
4012 : static PyMethodDef py_ldb_msg_methods[] = {
4013 : { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
4014 : "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
4015 : "Class method to create ldb.Message object from Dictionary.\n"
4016 : "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
4017 : { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
4018 : "S.keys() -> list\n\n"
4019 : "Return sequence of all attribute names." },
4020 : { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
4021 : "S.remove(name)\n\n"
4022 : "Remove all entries for attributes with the specified name."},
4023 : { "get", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_msg_get),
4024 : METH_VARARGS | METH_KEYWORDS,
4025 : "msg.get(name,default=None,idx=None) -> string\n"
4026 : "idx is the index into the values array\n"
4027 : "if idx is None, then a list is returned\n"
4028 : "if idx is not None, then the element with that index is returned\n"
4029 : "if you pass the special name 'dn' then the DN object is returned\n"},
4030 : { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
4031 : { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
4032 : { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
4033 : "S.add(element)\n\n"
4034 : "Add an element to this message." },
4035 : {0},
4036 : };
4037 :
4038 2546707 : static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
4039 : {
4040 244738 : PyObject *list, *iter;
4041 :
4042 2546707 : list = py_ldb_msg_keys(self, NULL);
4043 2546707 : iter = PyObject_GetIter(list);
4044 2085533 : Py_DECREF(list);
4045 2546707 : return iter;
4046 : }
4047 :
4048 346459 : static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
4049 : {
4050 18954 : const char *attr_name;
4051 :
4052 346459 : attr_name = PyUnicode_AsUTF8(name);
4053 346459 : if (attr_name == NULL) {
4054 0 : PyErr_SetNone(PyExc_TypeError);
4055 0 : return -1;
4056 : }
4057 :
4058 346459 : if (value == NULL) {
4059 : /* delitem */
4060 1585 : ldb_msg_remove_attr(self->msg, attr_name);
4061 : } else {
4062 18904 : int ret;
4063 344874 : struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
4064 : value, 0, attr_name);
4065 344874 : if (el == NULL) {
4066 0 : return -1;
4067 : }
4068 344874 : if (el->name == NULL) {
4069 : /*
4070 : * If ‘value’ is a MessageElement,
4071 : * PyObject_AsMessageElement() will have returned a
4072 : * reference to it without setting the name. We don’t
4073 : * want to modify the original object to set the name
4074 : * ourselves, but making a copy would result in
4075 : * different behaviour for a caller relying on a
4076 : * reference being kept. Rather than continue with a
4077 : * NULL name (and probably fail later on), let’s catch
4078 : * this potential mistake early.
4079 : */
4080 0 : PyErr_SetString(PyExc_ValueError, "MessageElement has no name set");
4081 0 : talloc_unlink(self->msg, el);
4082 0 : return -1;
4083 : }
4084 344874 : ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
4085 344874 : ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
4086 344874 : if (ret != LDB_SUCCESS) {
4087 0 : PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
4088 0 : talloc_unlink(self->msg, el);
4089 0 : return -1;
4090 : }
4091 : }
4092 327505 : return 0;
4093 : }
4094 :
4095 35837 : static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
4096 : {
4097 35837 : return pyldb_Message_AsMessage(self)->num_elements;
4098 : }
4099 :
4100 : static PySequenceMethods py_ldb_msg_sequence = {
4101 : .sq_contains = (objobjproc)py_ldb_msg_contains,
4102 : };
4103 :
4104 : static PyMappingMethods py_ldb_msg_mapping = {
4105 : .mp_length = (lenfunc)py_ldb_msg_length,
4106 : .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
4107 : .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
4108 : };
4109 :
4110 213309 : static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4111 : {
4112 213309 : const char * const kwnames[] = { "dn", NULL };
4113 14556 : struct ldb_message *ret;
4114 14556 : TALLOC_CTX *mem_ctx;
4115 213309 : PyObject *pydn = NULL;
4116 14556 : PyLdbMessageObject *py_ret;
4117 :
4118 213309 : if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
4119 : discard_const_p(char *, kwnames),
4120 : &pydn))
4121 0 : return NULL;
4122 :
4123 213309 : mem_ctx = talloc_new(NULL);
4124 213309 : if (mem_ctx == NULL) {
4125 0 : PyErr_NoMemory();
4126 0 : return NULL;
4127 : }
4128 :
4129 213309 : ret = ldb_msg_new(mem_ctx);
4130 213309 : if (ret == NULL) {
4131 0 : talloc_free(mem_ctx);
4132 0 : PyErr_NoMemory();
4133 0 : return NULL;
4134 : }
4135 :
4136 213309 : if (pydn != NULL) {
4137 1416 : struct ldb_dn *dn;
4138 10093 : if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
4139 0 : talloc_free(mem_ctx);
4140 0 : return NULL;
4141 : }
4142 10093 : ret->dn = talloc_reference(ret, dn);
4143 10093 : if (ret->dn == NULL) {
4144 0 : talloc_free(mem_ctx);
4145 0 : return PyErr_NoMemory();
4146 : }
4147 : }
4148 :
4149 213309 : py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
4150 213309 : if (py_ret == NULL) {
4151 0 : PyErr_NoMemory();
4152 0 : talloc_free(mem_ctx);
4153 0 : return NULL;
4154 : }
4155 :
4156 213309 : py_ret->mem_ctx = mem_ctx;
4157 213309 : py_ret->msg = ret;
4158 213309 : return (PyObject *)py_ret;
4159 : }
4160 :
4161 5641965 : static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
4162 : {
4163 5641965 : TALLOC_CTX *mem_ctx = NULL;
4164 5641965 : struct ldb_message *msg_ref = NULL;
4165 472104 : PyLdbMessageObject *ret;
4166 :
4167 5641965 : mem_ctx = talloc_new(NULL);
4168 5641965 : if (mem_ctx == NULL) {
4169 0 : return PyErr_NoMemory();
4170 : }
4171 :
4172 5641965 : msg_ref = talloc_reference(mem_ctx, msg);
4173 5641965 : if (msg_ref == NULL) {
4174 0 : talloc_free(mem_ctx);
4175 0 : return PyErr_NoMemory();
4176 : }
4177 :
4178 5641965 : ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
4179 5641965 : if (ret == NULL) {
4180 0 : talloc_free(mem_ctx);
4181 0 : PyErr_NoMemory();
4182 0 : return NULL;
4183 : }
4184 5641965 : ret->mem_ctx = mem_ctx;
4185 5641965 : ret->msg = msg_ref;
4186 5641965 : return (PyObject *)ret;
4187 : }
4188 :
4189 20889877 : static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
4190 : {
4191 20889877 : struct ldb_message *msg = pyldb_Message_AsMessage(self);
4192 20889877 : return pyldb_Dn_FromDn(msg->dn);
4193 : }
4194 :
4195 209637 : static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
4196 : {
4197 209637 : struct ldb_message *msg = pyldb_Message_AsMessage(self);
4198 209637 : struct ldb_dn *dn = NULL;
4199 209637 : if (value == NULL) {
4200 0 : PyErr_SetString(PyExc_AttributeError, "cannot delete dn");
4201 0 : return -1;
4202 : }
4203 209637 : if (!pyldb_Dn_Check(value)) {
4204 3 : PyErr_SetString(PyExc_TypeError, "expected dn");
4205 3 : return -1;
4206 : }
4207 :
4208 209634 : dn = talloc_reference(msg, pyldb_Dn_AS_DN(value));
4209 209634 : if (dn == NULL) {
4210 0 : PyErr_NoMemory();
4211 0 : return -1;
4212 : }
4213 :
4214 209634 : msg->dn = dn;
4215 209634 : return 0;
4216 : }
4217 :
4218 117 : static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure)
4219 : {
4220 117 : return wrap_text("MessageTextWrapper", self);
4221 : }
4222 :
4223 : static PyGetSetDef py_ldb_msg_getset[] = {
4224 : {
4225 : .name = discard_const_p(char, "dn"),
4226 : .get = (getter)py_ldb_msg_get_dn,
4227 : .set = (setter)py_ldb_msg_set_dn,
4228 : },
4229 : {
4230 : .name = discard_const_p(char, "text"),
4231 : .get = (getter)py_ldb_msg_get_text,
4232 : },
4233 : { .name = NULL },
4234 : };
4235 :
4236 64752 : static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
4237 : {
4238 64752 : PyObject *dict = PyDict_New(), *ret, *repr;
4239 64752 : const char *repr_str = NULL;
4240 64752 : if (dict == NULL) {
4241 0 : return NULL;
4242 : }
4243 64752 : if (PyDict_Update(dict, (PyObject *)self) != 0) {
4244 0 : Py_DECREF(dict);
4245 0 : return NULL;
4246 : }
4247 64752 : repr = PyObject_Repr(dict);
4248 64752 : if (repr == NULL) {
4249 0 : Py_DECREF(dict);
4250 0 : return NULL;
4251 : }
4252 64752 : repr_str = PyUnicode_AsUTF8(repr);
4253 64752 : if (repr_str == NULL) {
4254 0 : Py_DECREF(repr);
4255 0 : Py_DECREF(dict);
4256 0 : return NULL;
4257 : }
4258 64752 : ret = PyUnicode_FromFormat("Message(%s)", repr_str);
4259 36251 : Py_DECREF(repr);
4260 36251 : Py_DECREF(dict);
4261 64752 : return ret;
4262 : }
4263 :
4264 5855274 : static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
4265 : {
4266 5855274 : talloc_free(self->mem_ctx);
4267 5855274 : PyObject_Del(self);
4268 5855274 : }
4269 :
4270 1781 : static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1,
4271 : PyLdbMessageObject *py_msg2, int op)
4272 : {
4273 1 : struct ldb_message *msg1, *msg2;
4274 1 : unsigned int i;
4275 1 : int ret;
4276 :
4277 1781 : if (!PyLdbMessage_Check(py_msg2)) {
4278 948 : Py_INCREF(Py_NotImplemented);
4279 953 : return Py_NotImplemented;
4280 : }
4281 :
4282 828 : msg1 = pyldb_Message_AsMessage(py_msg1),
4283 828 : msg2 = pyldb_Message_AsMessage(py_msg2);
4284 :
4285 828 : if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
4286 825 : ret = ldb_dn_compare(msg1->dn, msg2->dn);
4287 825 : if (ret != 0) {
4288 0 : return richcmp(ret, op);
4289 : }
4290 : }
4291 :
4292 828 : ret = msg1->num_elements - msg2->num_elements;
4293 828 : if (ret != 0) {
4294 0 : return richcmp(ret, op);
4295 : }
4296 :
4297 8148 : for (i = 0; i < msg1->num_elements; i++) {
4298 7325 : ret = ldb_msg_element_compare_name(&msg1->elements[i],
4299 7323 : &msg2->elements[i]);
4300 7323 : if (ret != 0) {
4301 0 : return richcmp(ret, op);
4302 : }
4303 :
4304 7325 : ret = ldb_msg_element_compare(&msg1->elements[i],
4305 7323 : &msg2->elements[i]);
4306 7323 : if (ret != 0) {
4307 3 : return richcmp(ret, op);
4308 : }
4309 : }
4310 :
4311 825 : return richcmp(0, op);
4312 : }
4313 :
4314 : static PyTypeObject PyLdbMessage = {
4315 : .tp_name = "ldb.Message",
4316 : .tp_methods = py_ldb_msg_methods,
4317 : .tp_getset = py_ldb_msg_getset,
4318 : .tp_as_sequence = &py_ldb_msg_sequence,
4319 : .tp_as_mapping = &py_ldb_msg_mapping,
4320 : .tp_basicsize = sizeof(PyLdbMessageObject),
4321 : .tp_dealloc = (destructor)py_ldb_msg_dealloc,
4322 : .tp_new = py_ldb_msg_new,
4323 : .tp_repr = (reprfunc)py_ldb_msg_repr,
4324 : .tp_flags = Py_TPFLAGS_DEFAULT,
4325 : .tp_iter = (getiterfunc)py_ldb_msg_iter,
4326 : .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp,
4327 : .tp_doc = "A LDB Message",
4328 : };
4329 :
4330 3 : static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
4331 : {
4332 3 : TALLOC_CTX *mem_ctx = NULL;
4333 3 : struct ldb_parse_tree *tree_ref = NULL;
4334 0 : PyLdbTreeObject *ret;
4335 :
4336 3 : mem_ctx = talloc_new(NULL);
4337 3 : if (mem_ctx == NULL) {
4338 0 : return PyErr_NoMemory();
4339 : }
4340 :
4341 3 : tree_ref = talloc_reference(mem_ctx, tree);
4342 3 : if (tree_ref == NULL) {
4343 0 : talloc_free(mem_ctx);
4344 0 : return PyErr_NoMemory();
4345 : }
4346 :
4347 3 : ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
4348 3 : if (ret == NULL) {
4349 0 : talloc_free(mem_ctx);
4350 0 : PyErr_NoMemory();
4351 0 : return NULL;
4352 : }
4353 :
4354 3 : ret->mem_ctx = mem_ctx;
4355 3 : ret->tree = tree_ref;
4356 3 : return (PyObject *)ret;
4357 : }
4358 :
4359 3 : static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
4360 : {
4361 3 : talloc_free(self->mem_ctx);
4362 3 : PyObject_Del(self);
4363 3 : }
4364 :
4365 : static PyTypeObject PyLdbTree = {
4366 : .tp_name = "ldb.Tree",
4367 : .tp_basicsize = sizeof(PyLdbTreeObject),
4368 : .tp_dealloc = (destructor)py_ldb_tree_dealloc,
4369 : .tp_flags = Py_TPFLAGS_DEFAULT,
4370 : .tp_doc = "A search tree",
4371 : };
4372 :
4373 : /* Ldb_module */
4374 3 : static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
4375 : {
4376 3 : PyObject *py_ldb = (PyObject *)mod->private_data;
4377 0 : PyObject *py_result, *py_base, *py_attrs, *py_tree;
4378 :
4379 3 : py_base = pyldb_Dn_FromDn(req->op.search.base);
4380 :
4381 3 : if (py_base == NULL)
4382 0 : return LDB_ERR_OPERATIONS_ERROR;
4383 :
4384 3 : py_tree = PyLdbTree_FromTree(req->op.search.tree);
4385 :
4386 3 : if (py_tree == NULL) {
4387 0 : Py_DECREF(py_base);
4388 0 : return LDB_ERR_OPERATIONS_ERROR;
4389 : }
4390 :
4391 3 : if (req->op.search.attrs == NULL) {
4392 0 : py_attrs = Py_None;
4393 : } else {
4394 : int i, len;
4395 15 : for (len = 0; req->op.search.attrs[len]; len++);
4396 3 : py_attrs = PyList_New(len);
4397 3 : if (py_attrs == NULL) {
4398 0 : Py_DECREF(py_tree);
4399 0 : Py_DECREF(py_base);
4400 0 : return LDB_ERR_OPERATIONS_ERROR;
4401 : }
4402 15 : for (i = 0; i < len; i++) {
4403 12 : PyObject *py_attr = NULL;
4404 0 : int ret;
4405 :
4406 12 : py_attr = PyUnicode_FromString(req->op.search.attrs[i]);
4407 12 : if (py_attr == NULL) {
4408 0 : Py_DECREF(py_tree);
4409 0 : Py_DECREF(py_base);
4410 0 : Py_DECREF(py_attrs);
4411 0 : return LDB_ERR_OPERATIONS_ERROR;
4412 : }
4413 :
4414 12 : ret = PyList_SetItem(py_attrs, i, py_attr);
4415 12 : if (ret) {
4416 0 : Py_DECREF(py_attr);
4417 0 : Py_DECREF(py_tree);
4418 0 : Py_DECREF(py_base);
4419 0 : Py_DECREF(py_attrs);
4420 0 : return LDB_ERR_OPERATIONS_ERROR;
4421 : }
4422 : }
4423 : }
4424 :
4425 3 : py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
4426 : discard_const_p(char, "OiOO"),
4427 3 : py_base, req->op.search.scope, py_tree, py_attrs);
4428 :
4429 3 : Py_DECREF(py_attrs);
4430 3 : Py_DECREF(py_tree);
4431 3 : Py_DECREF(py_base);
4432 :
4433 3 : if (py_result == NULL) {
4434 0 : return LDB_ERR_PYTHON_EXCEPTION;
4435 : }
4436 :
4437 3 : req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
4438 3 : if (req->op.search.res == NULL) {
4439 3 : Py_DECREF(py_result);
4440 3 : return LDB_ERR_PYTHON_EXCEPTION;
4441 : }
4442 :
4443 0 : Py_DECREF(py_result);
4444 :
4445 0 : return LDB_SUCCESS;
4446 : }
4447 :
4448 0 : static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
4449 : {
4450 0 : PyObject *py_ldb = (PyObject *)mod->private_data;
4451 0 : PyObject *py_result, *py_msg;
4452 :
4453 0 : py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
4454 :
4455 0 : if (py_msg == NULL) {
4456 0 : return LDB_ERR_OPERATIONS_ERROR;
4457 : }
4458 :
4459 0 : py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
4460 : discard_const_p(char, "O"),
4461 : py_msg);
4462 :
4463 0 : Py_DECREF(py_msg);
4464 :
4465 0 : if (py_result == NULL) {
4466 0 : return LDB_ERR_PYTHON_EXCEPTION;
4467 : }
4468 :
4469 0 : Py_DECREF(py_result);
4470 :
4471 0 : return LDB_SUCCESS;
4472 : }
4473 :
4474 0 : static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
4475 : {
4476 0 : PyObject *py_ldb = (PyObject *)mod->private_data;
4477 0 : PyObject *py_result, *py_msg;
4478 :
4479 0 : py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
4480 :
4481 0 : if (py_msg == NULL) {
4482 0 : return LDB_ERR_OPERATIONS_ERROR;
4483 : }
4484 :
4485 0 : py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
4486 : discard_const_p(char, "O"),
4487 : py_msg);
4488 :
4489 0 : Py_DECREF(py_msg);
4490 :
4491 0 : if (py_result == NULL) {
4492 0 : return LDB_ERR_PYTHON_EXCEPTION;
4493 : }
4494 :
4495 0 : Py_DECREF(py_result);
4496 :
4497 0 : return LDB_SUCCESS;
4498 : }
4499 :
4500 0 : static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
4501 : {
4502 0 : PyObject *py_ldb = (PyObject *)mod->private_data;
4503 0 : PyObject *py_result, *py_dn;
4504 :
4505 0 : py_dn = pyldb_Dn_FromDn(req->op.del.dn);
4506 :
4507 0 : if (py_dn == NULL)
4508 0 : return LDB_ERR_OPERATIONS_ERROR;
4509 :
4510 0 : py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
4511 : discard_const_p(char, "O"),
4512 : py_dn);
4513 0 : Py_DECREF(py_dn);
4514 :
4515 0 : if (py_result == NULL) {
4516 0 : return LDB_ERR_PYTHON_EXCEPTION;
4517 : }
4518 :
4519 0 : Py_DECREF(py_result);
4520 :
4521 0 : return LDB_SUCCESS;
4522 : }
4523 :
4524 0 : static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
4525 : {
4526 0 : PyObject *py_ldb = (PyObject *)mod->private_data;
4527 0 : PyObject *py_result, *py_olddn, *py_newdn;
4528 :
4529 0 : py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
4530 :
4531 0 : if (py_olddn == NULL)
4532 0 : return LDB_ERR_OPERATIONS_ERROR;
4533 :
4534 0 : py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
4535 :
4536 0 : if (py_newdn == NULL) {
4537 0 : Py_DECREF(py_olddn);
4538 0 : return LDB_ERR_OPERATIONS_ERROR;
4539 : }
4540 :
4541 0 : py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
4542 : discard_const_p(char, "OO"),
4543 : py_olddn, py_newdn);
4544 :
4545 0 : Py_DECREF(py_olddn);
4546 0 : Py_DECREF(py_newdn);
4547 :
4548 0 : if (py_result == NULL) {
4549 0 : return LDB_ERR_PYTHON_EXCEPTION;
4550 : }
4551 :
4552 0 : Py_DECREF(py_result);
4553 :
4554 0 : return LDB_SUCCESS;
4555 : }
4556 :
4557 3 : static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
4558 : {
4559 3 : PyObject *py_ldb = (PyObject *)mod->private_data;
4560 0 : PyObject *py_result;
4561 :
4562 3 : py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
4563 : discard_const_p(char, ""));
4564 :
4565 3 : Py_XDECREF(py_result);
4566 :
4567 3 : return LDB_ERR_OPERATIONS_ERROR;
4568 : }
4569 :
4570 0 : static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
4571 : {
4572 0 : PyObject *py_ldb = (PyObject *)mod->private_data;
4573 0 : PyObject *py_result;
4574 :
4575 0 : py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
4576 : discard_const_p(char, ""));
4577 :
4578 0 : Py_XDECREF(py_result);
4579 :
4580 0 : return LDB_ERR_OPERATIONS_ERROR;
4581 : }
4582 :
4583 0 : static int py_module_start_transaction(struct ldb_module *mod)
4584 : {
4585 0 : PyObject *py_ldb = (PyObject *)mod->private_data;
4586 0 : PyObject *py_result;
4587 :
4588 0 : py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
4589 : discard_const_p(char, ""));
4590 :
4591 0 : if (py_result == NULL) {
4592 0 : return LDB_ERR_PYTHON_EXCEPTION;
4593 : }
4594 :
4595 0 : Py_DECREF(py_result);
4596 :
4597 0 : return LDB_SUCCESS;
4598 : }
4599 :
4600 0 : static int py_module_end_transaction(struct ldb_module *mod)
4601 : {
4602 0 : PyObject *py_ldb = (PyObject *)mod->private_data;
4603 0 : PyObject *py_result;
4604 :
4605 0 : py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
4606 : discard_const_p(char, ""));
4607 :
4608 0 : if (py_result == NULL) {
4609 0 : return LDB_ERR_PYTHON_EXCEPTION;
4610 : }
4611 :
4612 0 : Py_DECREF(py_result);
4613 :
4614 0 : return LDB_SUCCESS;
4615 : }
4616 :
4617 0 : static int py_module_del_transaction(struct ldb_module *mod)
4618 : {
4619 0 : PyObject *py_ldb = (PyObject *)mod->private_data;
4620 0 : PyObject *py_result;
4621 :
4622 0 : py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
4623 : discard_const_p(char, ""));
4624 :
4625 0 : if (py_result == NULL) {
4626 0 : return LDB_ERR_PYTHON_EXCEPTION;
4627 : }
4628 :
4629 0 : Py_DECREF(py_result);
4630 :
4631 0 : return LDB_SUCCESS;
4632 : }
4633 :
4634 3 : static int py_module_destructor(struct ldb_module *mod)
4635 : {
4636 3 : Py_CLEAR(mod->private_data);
4637 3 : return 0;
4638 : }
4639 :
4640 3 : static int py_module_init(struct ldb_module *mod)
4641 : {
4642 3 : PyObject *py_class = (PyObject *)mod->ops->private_data;
4643 0 : PyObject *py_result, *py_next, *py_ldb;
4644 :
4645 3 : py_ldb = PyLdb_FromLdbContext(mod->ldb);
4646 :
4647 3 : if (py_ldb == NULL)
4648 0 : return LDB_ERR_OPERATIONS_ERROR;
4649 :
4650 3 : py_next = PyLdbModule_FromModule(mod->next);
4651 :
4652 3 : if (py_next == NULL) {
4653 0 : Py_DECREF(py_ldb);
4654 0 : return LDB_ERR_OPERATIONS_ERROR;
4655 : }
4656 :
4657 3 : py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
4658 : py_ldb, py_next);
4659 :
4660 3 : Py_DECREF(py_next);
4661 3 : Py_DECREF(py_ldb);
4662 :
4663 3 : if (py_result == NULL) {
4664 0 : return LDB_ERR_PYTHON_EXCEPTION;
4665 : }
4666 :
4667 3 : mod->private_data = py_result;
4668 :
4669 3 : talloc_set_destructor(mod, py_module_destructor);
4670 :
4671 3 : return ldb_next_init(mod);
4672 : }
4673 :
4674 6 : static PyObject *py_register_module(PyObject *module, PyObject *args)
4675 : {
4676 0 : int ret;
4677 0 : struct ldb_module_ops *ops;
4678 0 : PyObject *input;
4679 6 : PyObject *tmp = NULL;
4680 6 : const char *name = NULL;
4681 :
4682 6 : if (!PyArg_ParseTuple(args, "O", &input))
4683 0 : return NULL;
4684 :
4685 6 : ops = talloc_zero(NULL, struct ldb_module_ops);
4686 6 : if (ops == NULL) {
4687 0 : PyErr_NoMemory();
4688 0 : return NULL;
4689 : }
4690 :
4691 6 : tmp = PyObject_GetAttrString(input, discard_const_p(char, "name"));
4692 6 : if (tmp == NULL) {
4693 0 : TALLOC_FREE(ops);
4694 0 : return NULL;
4695 : }
4696 6 : name = PyUnicode_AsUTF8(tmp);
4697 6 : if (name == NULL) {
4698 0 : Py_DECREF(tmp);
4699 0 : TALLOC_FREE(ops);
4700 0 : return NULL;
4701 : }
4702 :
4703 6 : ops->name = talloc_strdup(ops, name);
4704 6 : Py_XDECREF(tmp);
4705 6 : if (ops->name == NULL) {
4706 0 : TALLOC_FREE(ops);
4707 0 : return PyErr_NoMemory();
4708 : }
4709 6 : Py_INCREF(input);
4710 6 : ops->private_data = input;
4711 6 : ops->init_context = py_module_init;
4712 6 : ops->search = py_module_search;
4713 6 : ops->add = py_module_add;
4714 6 : ops->modify = py_module_modify;
4715 6 : ops->del = py_module_del;
4716 6 : ops->rename = py_module_rename;
4717 6 : ops->request = py_module_request;
4718 6 : ops->extended = py_module_extended;
4719 6 : ops->start_transaction = py_module_start_transaction;
4720 6 : ops->end_transaction = py_module_end_transaction;
4721 6 : ops->del_transaction = py_module_del_transaction;
4722 :
4723 6 : ret = ldb_register_module(ops);
4724 6 : if (ret != LDB_SUCCESS) {
4725 0 : Py_DECREF(input);
4726 0 : TALLOC_FREE(ops);
4727 : }
4728 :
4729 6 : PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
4730 :
4731 6 : Py_RETURN_NONE;
4732 : }
4733 :
4734 5078 : static PyObject *py_timestring(PyObject *module, PyObject *args)
4735 : {
4736 : /* most times "time_t" is a signed integer type with 32 or 64 bit:
4737 : * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4738 45 : long int t_val;
4739 45 : char *tresult;
4740 45 : PyObject *ret;
4741 5078 : if (!PyArg_ParseTuple(args, "l", &t_val))
4742 0 : return NULL;
4743 5078 : tresult = ldb_timestring(NULL, (time_t) t_val);
4744 5078 : if (tresult == NULL) {
4745 : /*
4746 : * Most likely EOVERFLOW from gmtime()
4747 : */
4748 9 : PyErr_SetFromErrno(PyExc_OSError);
4749 9 : return NULL;
4750 : }
4751 5069 : ret = PyUnicode_FromString(tresult);
4752 5069 : talloc_free(tresult);
4753 5069 : return ret;
4754 : }
4755 :
4756 5988 : static PyObject *py_string_to_time(PyObject *module, PyObject *args)
4757 : {
4758 72 : char *str;
4759 5988 : if (!PyArg_ParseTuple(args, "s", &str))
4760 0 : return NULL;
4761 :
4762 5988 : return PyLong_FromLong(ldb_string_to_time(str));
4763 : }
4764 :
4765 6 : static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
4766 : {
4767 0 : char *name;
4768 6 : if (!PyArg_ParseTuple(args, "s", &name))
4769 0 : return NULL;
4770 6 : return PyBool_FromLong(ldb_valid_attr_name(name));
4771 : }
4772 :
4773 : /*
4774 : encode a string using RFC2254 rules
4775 : */
4776 58361 : static PyObject *py_binary_encode(PyObject *self, PyObject *args)
4777 : {
4778 90 : char *str, *encoded;
4779 58361 : Py_ssize_t size = 0;
4780 90 : struct ldb_val val;
4781 90 : PyObject *ret;
4782 :
4783 58361 : if (!PyArg_ParseTuple(args, "s#", &str, &size))
4784 0 : return NULL;
4785 58361 : val.data = (uint8_t *)str;
4786 58361 : val.length = size;
4787 :
4788 58361 : encoded = ldb_binary_encode(NULL, val);
4789 58361 : if (encoded == NULL) {
4790 0 : PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
4791 0 : return NULL;
4792 : }
4793 58361 : ret = PyUnicode_FromString(encoded);
4794 58361 : talloc_free(encoded);
4795 58361 : return ret;
4796 : }
4797 :
4798 : /*
4799 : decode a string using RFC2254 rules
4800 : */
4801 3 : static PyObject *py_binary_decode(PyObject *self, PyObject *args)
4802 : {
4803 0 : char *str;
4804 0 : struct ldb_val val;
4805 0 : PyObject *ret;
4806 :
4807 3 : if (!PyArg_ParseTuple(args, "s", &str))
4808 0 : return NULL;
4809 :
4810 3 : val = ldb_binary_decode(NULL, str);
4811 3 : if (val.data == NULL) {
4812 0 : PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
4813 0 : return NULL;
4814 : }
4815 3 : ret = PyBytes_FromStringAndSize((const char*)val.data, val.length);
4816 3 : talloc_free(val.data);
4817 3 : return ret;
4818 : }
4819 :
4820 : static PyMethodDef py_ldb_global_methods[] = {
4821 : { "register_module", py_register_module, METH_VARARGS,
4822 : "S.register_module(module) -> None\n\n"
4823 : "Register a LDB module."},
4824 : { "timestring", py_timestring, METH_VARARGS,
4825 : "S.timestring(int) -> string\n\n"
4826 : "Generate a LDAP time string from a UNIX timestamp" },
4827 : { "string_to_time", py_string_to_time, METH_VARARGS,
4828 : "S.string_to_time(string) -> int\n\n"
4829 : "Parse a LDAP time string into a UNIX timestamp." },
4830 : { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
4831 : "S.valid_attr_name(name) -> bool\n\n"
4832 : "Check whether the supplied name is a valid attribute name." },
4833 : { "binary_encode", py_binary_encode, METH_VARARGS,
4834 : "S.binary_encode(string) -> string\n\n"
4835 : "Perform a RFC2254 binary encoding on a string" },
4836 : { "binary_decode", py_binary_decode, METH_VARARGS,
4837 : "S.binary_decode(string) -> string\n\n"
4838 : "Perform a RFC2254 binary decode on a string" },
4839 : {0}
4840 : };
4841 :
4842 : #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."
4843 :
4844 : static struct PyModuleDef moduledef = {
4845 : PyModuleDef_HEAD_INIT,
4846 : .m_name = "ldb",
4847 : .m_doc = MODULE_DOC,
4848 : .m_size = -1,
4849 : .m_methods = py_ldb_global_methods,
4850 : };
4851 :
4852 12656 : static PyObject* module_init(void)
4853 : {
4854 536 : PyObject *m;
4855 :
4856 12656 : PyLdbBytesType.tp_base = &PyBytes_Type;
4857 12656 : if (PyType_Ready(&PyLdbBytesType) < 0) {
4858 0 : return NULL;
4859 : }
4860 :
4861 12656 : if (PyType_Ready(&PyLdbDn) < 0)
4862 0 : return NULL;
4863 :
4864 12656 : if (PyType_Ready(&PyLdbMessage) < 0)
4865 0 : return NULL;
4866 :
4867 12656 : if (PyType_Ready(&PyLdbMessageElement) < 0)
4868 0 : return NULL;
4869 :
4870 12656 : if (PyType_Ready(&PyLdb) < 0)
4871 0 : return NULL;
4872 :
4873 12656 : if (PyType_Ready(&PyLdbModule) < 0)
4874 0 : return NULL;
4875 :
4876 12656 : if (PyType_Ready(&PyLdbTree) < 0)
4877 0 : return NULL;
4878 :
4879 12656 : if (PyType_Ready(&PyLdbResult) < 0)
4880 0 : return NULL;
4881 :
4882 12656 : if (PyType_Ready(&PyLdbSearchIterator) < 0)
4883 0 : return NULL;
4884 :
4885 12656 : if (PyType_Ready(&PyLdbControl) < 0)
4886 0 : return NULL;
4887 :
4888 12656 : m = PyModule_Create(&moduledef);
4889 12656 : if (m == NULL)
4890 0 : return NULL;
4891 :
4892 : #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4893 :
4894 12656 : ADD_LDB_INT(SEQ_HIGHEST_SEQ);
4895 12656 : ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP);
4896 12656 : ADD_LDB_INT(SEQ_NEXT);
4897 12656 : ADD_LDB_INT(SCOPE_DEFAULT);
4898 12656 : ADD_LDB_INT(SCOPE_BASE);
4899 12656 : ADD_LDB_INT(SCOPE_ONELEVEL);
4900 12656 : ADD_LDB_INT(SCOPE_SUBTREE);
4901 :
4902 12656 : ADD_LDB_INT(CHANGETYPE_NONE);
4903 12656 : ADD_LDB_INT(CHANGETYPE_ADD);
4904 12656 : ADD_LDB_INT(CHANGETYPE_DELETE);
4905 12656 : ADD_LDB_INT(CHANGETYPE_MODIFY);
4906 12656 : ADD_LDB_INT(CHANGETYPE_MODRDN);
4907 :
4908 12656 : ADD_LDB_INT(FLAG_MOD_ADD);
4909 12656 : ADD_LDB_INT(FLAG_MOD_REPLACE);
4910 12656 : ADD_LDB_INT(FLAG_MOD_DELETE);
4911 12656 : ADD_LDB_INT(FLAG_FORCE_NO_BASE64_LDIF);
4912 :
4913 12656 : ADD_LDB_INT(ATTR_FLAG_HIDDEN);
4914 12656 : ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX);
4915 12656 : ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE);
4916 12656 : ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF);
4917 :
4918 12656 : ADD_LDB_INT(SUCCESS);
4919 12656 : ADD_LDB_INT(ERR_OPERATIONS_ERROR);
4920 12656 : ADD_LDB_INT(ERR_PROTOCOL_ERROR);
4921 12656 : ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED);
4922 12656 : ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED);
4923 12656 : ADD_LDB_INT(ERR_COMPARE_FALSE);
4924 12656 : ADD_LDB_INT(ERR_COMPARE_TRUE);
4925 12656 : ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED);
4926 12656 : ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED);
4927 12656 : ADD_LDB_INT(ERR_REFERRAL);
4928 12656 : ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED);
4929 12656 : ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION);
4930 12656 : ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED);
4931 12656 : ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS);
4932 12656 : ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE);
4933 12656 : ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE);
4934 12656 : ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING);
4935 12656 : ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION);
4936 12656 : ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS);
4937 12656 : ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX);
4938 12656 : ADD_LDB_INT(ERR_NO_SUCH_OBJECT);
4939 12656 : ADD_LDB_INT(ERR_ALIAS_PROBLEM);
4940 12656 : ADD_LDB_INT(ERR_INVALID_DN_SYNTAX);
4941 12656 : ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM);
4942 12656 : ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION);
4943 12656 : ADD_LDB_INT(ERR_INVALID_CREDENTIALS);
4944 12656 : ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS);
4945 12656 : ADD_LDB_INT(ERR_BUSY);
4946 12656 : ADD_LDB_INT(ERR_UNAVAILABLE);
4947 12656 : ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM);
4948 12656 : ADD_LDB_INT(ERR_LOOP_DETECT);
4949 12656 : ADD_LDB_INT(ERR_NAMING_VIOLATION);
4950 12656 : ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION);
4951 12656 : ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF);
4952 12656 : ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN);
4953 12656 : ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS);
4954 12656 : ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED);
4955 12656 : ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS);
4956 12656 : ADD_LDB_INT(ERR_OTHER);
4957 :
4958 12656 : ADD_LDB_INT(FLG_RDONLY);
4959 12656 : ADD_LDB_INT(FLG_NOSYNC);
4960 12656 : ADD_LDB_INT(FLG_RECONNECT);
4961 12656 : ADD_LDB_INT(FLG_NOMMAP);
4962 12656 : ADD_LDB_INT(FLG_SHOW_BINARY);
4963 12656 : ADD_LDB_INT(FLG_ENABLE_TRACING);
4964 12656 : ADD_LDB_INT(FLG_DONT_CREATE_DB);
4965 :
4966 12656 : ADD_LDB_INT(PACKING_FORMAT);
4967 12656 : ADD_LDB_INT(PACKING_FORMAT_V2);
4968 :
4969 : /* Historical misspelling */
4970 12656 : PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
4971 :
4972 12656 : PyModule_AddStringConstant(m, "__docformat__", "restructuredText");
4973 :
4974 12656 : PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
4975 12656 : PyModule_AddObject(m, "LdbError", PyExc_LdbError);
4976 :
4977 10532 : Py_INCREF(&PyLdb);
4978 10532 : Py_INCREF(&PyLdbDn);
4979 10532 : Py_INCREF(&PyLdbModule);
4980 10532 : Py_INCREF(&PyLdbMessage);
4981 10532 : Py_INCREF(&PyLdbMessageElement);
4982 10532 : Py_INCREF(&PyLdbTree);
4983 10532 : Py_INCREF(&PyLdbResult);
4984 10532 : Py_INCREF(&PyLdbControl);
4985 :
4986 12656 : PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
4987 12656 : PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
4988 12656 : PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
4989 12656 : PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
4990 12656 : PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
4991 12656 : PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
4992 12656 : PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
4993 :
4994 12656 : PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
4995 :
4996 : #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4997 :
4998 12656 : ADD_LDB_STRING(SYNTAX_DN);
4999 12656 : ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
5000 12656 : ADD_LDB_STRING(SYNTAX_INTEGER);
5001 12656 : ADD_LDB_STRING(SYNTAX_ORDERED_INTEGER);
5002 12656 : ADD_LDB_STRING(SYNTAX_BOOLEAN);
5003 12656 : ADD_LDB_STRING(SYNTAX_OCTET_STRING);
5004 12656 : ADD_LDB_STRING(SYNTAX_UTC_TIME);
5005 12656 : ADD_LDB_STRING(OID_COMPARATOR_AND);
5006 12656 : ADD_LDB_STRING(OID_COMPARATOR_OR);
5007 :
5008 12656 : return m;
5009 : }
5010 :
5011 : PyMODINIT_FUNC PyInit_ldb(void);
5012 12656 : PyMODINIT_FUNC PyInit_ldb(void)
5013 : {
5014 12656 : return module_init();
5015 : }
|