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