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