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