2 Unix SMB/CIFS implementation.
4 Python interface to ldb.
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
13 ** NOTE! The following LGPL license applies to the ldb
14 ** library. This does NOT imply that all of Samba is released
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.
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.
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/>.
32 #include "ldb_private.h"
33 #include "ldb_handlers.h"
35 #include "dlinklist.h"
37 /* discard signature of 'func' in favour of 'target_sig' */
38 #define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func
40 struct py_ldb_search_iterator_reply
;
47 struct ldb_request
*req
;
48 struct py_ldb_search_iterator_reply
*next
;
49 struct py_ldb_search_iterator_reply
*result
;
52 } PyLdbSearchIteratorObject
;
54 struct py_ldb_search_iterator_reply
{
55 struct py_ldb_search_iterator_reply
*prev
, *next
;
56 PyLdbSearchIteratorObject
*py_iter
;
61 static PyObject
*PyLdbMessage_FromMessage(struct ldb_message
*msg
);
62 static PyObject
*PyExc_LdbError
;
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)
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(
84 const char *attr_name
);
85 static PyTypeObject PyLdbBytesType
;
87 #define PYARG_STR_UNI "es"
89 static PyObject
*PyLdbBytes_FromStringAndSize(const char *msg
, int size
)
91 PyObject
* result
= NULL
;
92 PyObject
* args
= NULL
;
93 args
= Py_BuildValue("(y#)", msg
, size
);
97 result
= PyLdbBytesType
.tp_new(&PyLdbBytesType
, args
, NULL
);
102 static PyObject
*richcmp(int cmp_val
, int op
)
106 case Py_LT
: ret
= cmp_val
< 0; break;
107 case Py_LE
: ret
= cmp_val
<= 0; break;
108 case Py_EQ
: ret
= cmp_val
== 0; break;
109 case Py_NE
: ret
= cmp_val
!= 0; break;
110 case Py_GT
: ret
= cmp_val
> 0; break;
111 case Py_GE
: ret
= cmp_val
>= 0; break;
113 Py_INCREF(Py_NotImplemented
);
114 return Py_NotImplemented
;
116 return PyBool_FromLong(ret
);
120 static PyObject
*py_ldb_control_str(PyLdbControlObject
*self
)
122 if (self
->data
!= NULL
) {
123 char* control
= ldb_control_to_string(self
->mem_ctx
, self
->data
);
124 if (control
== NULL
) {
128 return PyUnicode_FromString(control
);
130 return PyUnicode_FromString("ldb control");
134 static void py_ldb_control_dealloc(PyLdbControlObject
*self
)
136 if (self
->mem_ctx
!= NULL
) {
137 talloc_free(self
->mem_ctx
);
140 Py_TYPE(self
)->tp_free(self
);
143 /* Create a text (rather than bytes) interface for a LDB result object */
144 static PyObject
*wrap_text(const char *type
, PyObject
*wrapped
)
146 PyObject
*mod
, *cls
, *constructor
, *inst
;
147 mod
= PyImport_ImportModule("_ldb_text");
150 cls
= PyObject_GetAttrString(mod
, type
);
156 constructor
= PyObject_GetAttrString(cls
, "_wrap");
158 if (constructor
== NULL
) {
161 inst
= PyObject_CallFunction(constructor
, discard_const_p(char, "O"), wrapped
);
162 Py_DECREF(constructor
);
166 static PyObject
*py_ldb_control_get_oid(PyLdbControlObject
*self
,
167 PyObject
*Py_UNUSED(ignored
))
169 return PyUnicode_FromString(self
->data
->oid
);
172 static PyObject
*py_ldb_control_get_critical(PyLdbControlObject
*self
,
173 PyObject
*Py_UNUSED(ignored
))
175 return PyBool_FromLong(self
->data
->critical
);
178 static int py_ldb_control_set_critical(PyLdbControlObject
*self
, PyObject
*value
, void *closure
)
181 PyErr_SetString(PyExc_AttributeError
, "cannot delete critical flag");
184 if (PyObject_IsTrue(value
)) {
185 self
->data
->critical
= true;
187 self
->data
->critical
= false;
192 static PyObject
*py_ldb_control_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
195 const char * const kwnames
[] = { "ldb", "data", NULL
};
196 struct ldb_control
*parsed_controls
;
197 PyLdbControlObject
*ret
;
200 struct ldb_context
*ldb_ctx
;
202 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O!s",
203 discard_const_p(char *, kwnames
),
204 &PyLdb
, &py_ldb
, &data
))
207 mem_ctx
= talloc_new(NULL
);
208 if (mem_ctx
== NULL
) {
213 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(py_ldb
);
214 parsed_controls
= ldb_parse_control_from_string(ldb_ctx
, mem_ctx
, data
);
216 if (!parsed_controls
) {
217 talloc_free(mem_ctx
);
218 PyErr_SetString(PyExc_ValueError
, "unable to parse control string");
222 ret
= PyObject_New(PyLdbControlObject
, type
);
225 talloc_free(mem_ctx
);
229 ret
->mem_ctx
= mem_ctx
;
231 ret
->data
= talloc_move(mem_ctx
, &parsed_controls
);
232 if (ret
->data
== NULL
) {
235 talloc_free(mem_ctx
);
239 return (PyObject
*)ret
;
242 static PyGetSetDef py_ldb_control_getset
[] = {
244 .name
= discard_const_p(char, "oid"),
245 .get
= (getter
)py_ldb_control_get_oid
,
248 .name
= discard_const_p(char, "critical"),
249 .get
= (getter
)py_ldb_control_get_critical
,
250 .set
= (setter
)py_ldb_control_set_critical
,
255 static PyTypeObject PyLdbControl
= {
256 .tp_name
= "ldb.control",
257 .tp_dealloc
= (destructor
)py_ldb_control_dealloc
,
258 .tp_getattro
= PyObject_GenericGetAttr
,
259 .tp_basicsize
= sizeof(PyLdbControlObject
),
260 .tp_getset
= py_ldb_control_getset
,
261 .tp_doc
= "LDB control.",
262 .tp_str
= (reprfunc
)py_ldb_control_str
,
263 .tp_new
= py_ldb_control_new
,
264 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
267 static void PyErr_SetLdbError(PyObject
*error
, int ret
, struct ldb_context
*ldb_ctx
)
269 if (ret
== LDB_ERR_PYTHON_EXCEPTION
)
270 return; /* Python exception should already be set, just keep that */
272 PyErr_SetObject(error
,
273 Py_BuildValue(discard_const_p(char, "(i,s)"), ret
,
274 ldb_ctx
== NULL
?ldb_strerror(ret
):ldb_errstring(ldb_ctx
)));
276 static PyObject
*py_ldb_bytes_str(PyBytesObject
*self
)
281 if (!PyBytes_Check(self
)) {
282 PyErr_Format(PyExc_TypeError
,"Unexpected type");
285 result
= PyBytes_AsStringAndSize((PyObject
*)self
, &msg
, &size
);
287 PyErr_Format(PyExc_TypeError
, "Failed to extract bytes");
290 return PyUnicode_FromStringAndSize(msg
, size
);
293 static PyTypeObject PyLdbBytesType
= {
294 PyVarObject_HEAD_INIT(NULL
, 0)
295 .tp_name
= "ldb.bytes",
296 .tp_doc
= "str/bytes (with custom str)",
297 .tp_str
= (reprfunc
)py_ldb_bytes_str
,
298 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
301 static PyObject
*PyObject_FromLdbValue(const struct ldb_val
*val
)
303 return PyLdbBytes_FromStringAndSize((const char *)val
->data
, val
->length
);
306 static PyObject
*PyStr_FromLdbValue(const struct ldb_val
*val
)
308 return PyUnicode_FromStringAndSize((const char *)val
->data
, val
->length
);
312 * Create a Python object from a ldb_result.
314 * @param result LDB result to convert
315 * @return Python object with converted result (a list object)
317 static PyObject
*PyLdbControl_FromControl(struct ldb_control
*control
)
319 TALLOC_CTX
*ctl_ctx
= talloc_new(NULL
);
320 PyLdbControlObject
*ctrl
;
321 if (ctl_ctx
== NULL
) {
326 ctrl
= (PyLdbControlObject
*)PyLdbControl
.tp_alloc(&PyLdbControl
, 0);
328 talloc_free(ctl_ctx
);
332 ctrl
->mem_ctx
= ctl_ctx
;
333 ctrl
->data
= talloc_steal(ctrl
->mem_ctx
, control
);
334 if (ctrl
->data
== NULL
) {
339 return (PyObject
*) ctrl
;
343 * Create a Python object from a ldb_result.
345 * @param result LDB result to convert
346 * @return Python object with converted result (a list object)
348 static PyObject
*PyLdbResult_FromResult(struct ldb_result
*result
)
350 PyLdbResultObject
*ret
;
351 PyObject
*list
, *controls
, *referals
;
354 if (result
== NULL
) {
358 ret
= (PyLdbResultObject
*)PyLdbResult
.tp_alloc(&PyLdbResult
, 0);
364 list
= PyList_New(result
->count
);
371 for (i
= 0; i
< result
->count
; i
++) {
372 PyList_SetItem(list
, i
, PyLdbMessage_FromMessage(result
->msgs
[i
]));
375 ret
->mem_ctx
= talloc_new(NULL
);
376 if (ret
->mem_ctx
== NULL
) {
385 if (result
->controls
) {
387 while (result
->controls
[i
]) {
390 controls
= PyList_New(i
);
391 if (controls
== NULL
) {
396 for (i
=0; result
->controls
[i
]; i
++) {
397 PyObject
*ctrl
= (PyObject
*) PyLdbControl_FromControl(result
->controls
[i
]);
404 PyList_SetItem(controls
, i
, ctrl
);
408 * No controls so we keep an empty list
410 controls
= PyList_New(0);
411 if (controls
== NULL
) {
418 ret
->controls
= controls
;
422 while (result
->refs
&& result
->refs
[i
]) {
426 referals
= PyList_New(i
);
427 if (referals
== NULL
) {
433 for (i
= 0;result
->refs
&& result
->refs
[i
]; i
++) {
434 PyList_SetItem(referals
, i
, PyUnicode_FromString(result
->refs
[i
]));
436 ret
->referals
= referals
;
437 return (PyObject
*)ret
;
441 * Create a LDB Result from a Python object.
442 * If conversion fails, NULL will be returned and a Python exception set.
444 * Note: the result object only includes the messages at the moment; extended
445 * result, controls and referrals are ignored.
447 * @param mem_ctx Memory context in which to allocate the LDB Result
448 * @param obj Python object to convert
449 * @return a ldb_result, or NULL if the conversion failed
451 static struct ldb_result
*PyLdbResult_AsResult(TALLOC_CTX
*mem_ctx
,
454 struct ldb_result
*res
;
460 if (!PyList_Check(obj
)) {
461 PyErr_SetString(PyExc_ValueError
, "Expected list of LDB results");
465 res
= talloc_zero(mem_ctx
, struct ldb_result
);
470 res
->count
= PyList_Size(obj
);
471 res
->msgs
= talloc_array(res
, struct ldb_message
*, res
->count
);
472 if (res
->msgs
== NULL
) {
477 for (i
= 0; i
< res
->count
; i
++) {
478 PyObject
*item
= PyList_GetItem(obj
, i
);
483 res
->msgs
[i
] = pyldb_Message_AsMessage(item
);
488 static PyObject
*py_ldb_dn_validate(PyLdbDnObject
*self
,
489 PyObject
*Py_UNUSED(ignored
))
491 return PyBool_FromLong(ldb_dn_validate(self
->dn
));
494 static PyObject
*py_ldb_dn_is_valid(PyLdbDnObject
*self
,
495 PyObject
*Py_UNUSED(ignored
))
497 return PyBool_FromLong(ldb_dn_is_valid(self
->dn
));
500 static PyObject
*py_ldb_dn_is_special(PyLdbDnObject
*self
,
501 PyObject
*Py_UNUSED(ignored
))
503 return PyBool_FromLong(ldb_dn_is_special(self
->dn
));
506 static PyObject
*py_ldb_dn_is_null(PyLdbDnObject
*self
,
507 PyObject
*Py_UNUSED(ignored
))
509 return PyBool_FromLong(ldb_dn_is_null(self
->dn
));
512 static PyObject
*py_ldb_dn_get_casefold(PyLdbDnObject
*self
,
513 PyObject
*Py_UNUSED(ignored
))
515 return PyUnicode_FromString(ldb_dn_get_casefold(self
->dn
));
518 static PyObject
*py_ldb_dn_get_linearized(PyLdbDnObject
*self
,
519 PyObject
*Py_UNUSED(ignored
))
521 return PyUnicode_FromString(ldb_dn_get_linearized(self
->dn
));
524 static PyObject
*py_ldb_dn_canonical_str(PyLdbDnObject
*self
,
525 PyObject
*Py_UNUSED(ignored
))
527 return PyUnicode_FromString(ldb_dn_canonical_string(self
->dn
, self
->dn
));
530 static PyObject
*py_ldb_dn_canonical_ex_str(PyLdbDnObject
*self
,
531 PyObject
*Py_UNUSED(ignored
))
533 return PyUnicode_FromString(ldb_dn_canonical_ex_string(self
->dn
, self
->dn
));
536 static PyObject
*py_ldb_dn_extended_str(PyLdbDnObject
*self
, PyObject
*args
, PyObject
*kwargs
)
538 const char * const kwnames
[] = { "mode", NULL
};
540 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i",
541 discard_const_p(char *, kwnames
),
544 return PyUnicode_FromString(ldb_dn_get_extended_linearized(self
->dn
, self
->dn
, mode
));
547 static PyObject
*py_ldb_dn_get_extended_component(PyLdbDnObject
*self
, PyObject
*args
)
550 const struct ldb_val
*val
;
552 if (!PyArg_ParseTuple(args
, "s", &name
))
554 val
= ldb_dn_get_extended_component(self
->dn
, name
);
559 return PyBytes_FromStringAndSize((const char *)val
->data
, val
->length
);
562 static PyObject
*py_ldb_dn_set_extended_component(PyLdbDnObject
*self
, PyObject
*args
)
566 uint8_t *value
= NULL
;
569 if (!PyArg_ParseTuple(args
, "sz#", &name
, (char **)&value
, &size
))
573 err
= ldb_dn_set_extended_component(self
->dn
, name
, NULL
);
576 val
.data
= (uint8_t *)value
;
578 err
= ldb_dn_set_extended_component(self
->dn
, name
, &val
);
581 if (err
!= LDB_SUCCESS
) {
582 PyErr_SetString(PyExc_TypeError
, "Failed to set extended component");
589 static PyObject
*py_ldb_dn_repr(PyLdbDnObject
*self
)
591 PyObject
*str
= PyUnicode_FromString(ldb_dn_get_linearized(self
->dn
));
592 PyObject
*repr
, *result
;
595 repr
= PyObject_Repr(str
);
600 result
= PyUnicode_FromFormat("Dn(%s)", PyUnicode_AsUTF8(repr
));
606 static PyObject
*py_ldb_dn_check_special(PyLdbDnObject
*self
, PyObject
*args
)
610 if (!PyArg_ParseTuple(args
, "s", &name
))
613 return PyBool_FromLong(ldb_dn_check_special(self
->dn
, name
));
616 static PyObject
*py_ldb_dn_richcmp(PyObject
*dn1
, PyObject
*dn2
, int op
)
619 if (!pyldb_Dn_Check(dn2
)) {
620 Py_INCREF(Py_NotImplemented
);
621 return Py_NotImplemented
;
623 ret
= ldb_dn_compare(pyldb_Dn_AS_DN(dn1
), pyldb_Dn_AS_DN(dn2
));
624 return richcmp(ret
, op
);
627 static PyObject
*py_ldb_dn_get_parent(PyLdbDnObject
*self
,
628 PyObject
*Py_UNUSED(ignored
))
630 struct ldb_dn
*dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
631 struct ldb_dn
*parent
;
632 PyLdbDnObject
*py_ret
;
633 TALLOC_CTX
*mem_ctx
= NULL
;
635 if (ldb_dn_get_comp_num(dn
) < 1) {
639 mem_ctx
= talloc_new(NULL
);
640 if (mem_ctx
== NULL
) {
645 parent
= ldb_dn_get_parent(mem_ctx
, dn
);
646 if (parent
== NULL
) {
648 talloc_free(mem_ctx
);
652 py_ret
= (PyLdbDnObject
*)PyLdbDn
.tp_alloc(&PyLdbDn
, 0);
653 if (py_ret
== NULL
) {
655 talloc_free(mem_ctx
);
658 py_ret
->mem_ctx
= mem_ctx
;
660 return (PyObject
*)py_ret
;
663 static PyObject
*py_ldb_dn_add_child(PyLdbDnObject
*self
, PyObject
*args
)
666 struct ldb_dn
*dn
, *other
;
668 if (!PyArg_ParseTuple(args
, "O", &py_other
))
671 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
673 if (!pyldb_Object_AsDn(NULL
, py_other
, ldb_dn_get_ldb_context(dn
), &other
))
676 ok
= ldb_dn_add_child(dn
, other
);
678 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, NULL
);
685 static PyObject
*py_ldb_dn_add_base(PyLdbDnObject
*self
, PyObject
*args
)
688 struct ldb_dn
*other
, *dn
;
690 if (!PyArg_ParseTuple(args
, "O", &py_other
))
693 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
695 if (!pyldb_Object_AsDn(NULL
, py_other
, ldb_dn_get_ldb_context(dn
), &other
))
698 ok
= ldb_dn_add_base(dn
, other
);
700 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, NULL
);
707 static PyObject
*py_ldb_dn_remove_base_components(PyLdbDnObject
*self
, PyObject
*args
)
712 if (!PyArg_ParseTuple(args
, "i", &i
))
715 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
717 ok
= ldb_dn_remove_base_components(dn
, i
);
719 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, NULL
);
726 static PyObject
*py_ldb_dn_is_child_of(PyLdbDnObject
*self
, PyObject
*args
)
729 struct ldb_dn
*dn
, *base
;
730 if (!PyArg_ParseTuple(args
, "O", &py_base
))
733 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
735 if (!pyldb_Object_AsDn(NULL
, py_base
, ldb_dn_get_ldb_context(dn
), &base
))
738 return PyBool_FromLong(ldb_dn_compare_base(base
, dn
) == 0);
741 static PyObject
*py_ldb_dn_get_component_name(PyLdbDnObject
*self
, PyObject
*args
)
745 unsigned int num
= 0;
747 if (!PyArg_ParseTuple(args
, "I", &num
))
750 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
752 name
= ldb_dn_get_component_name(dn
, num
);
757 return PyUnicode_FromString(name
);
760 static PyObject
*py_ldb_dn_get_component_value(PyLdbDnObject
*self
, PyObject
*args
)
763 const struct ldb_val
*val
;
764 unsigned int num
= 0;
766 if (!PyArg_ParseTuple(args
, "I", &num
))
769 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
771 val
= ldb_dn_get_component_val(dn
, num
);
776 return PyStr_FromLdbValue(val
);
779 static PyObject
*py_ldb_dn_set_component(PyLdbDnObject
*self
, PyObject
*args
)
781 unsigned int num
= 0;
782 char *name
= NULL
, *value
= NULL
;
783 struct ldb_val val
= { 0 };
787 if (!PyArg_ParseTuple(args
, "Iss#", &num
, &name
, &value
, &size
))
790 val
.data
= (unsigned char*) value
;
793 err
= ldb_dn_set_component(self
->dn
, num
, name
, val
);
794 if (err
!= LDB_SUCCESS
) {
795 PyErr_SetString(PyExc_TypeError
, "Failed to set component");
802 static PyObject
*py_ldb_dn_get_rdn_name(PyLdbDnObject
*self
,
803 PyObject
*Py_UNUSED(ignored
))
808 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
810 name
= ldb_dn_get_rdn_name(dn
);
815 return PyUnicode_FromString(name
);
818 static PyObject
*py_ldb_dn_get_rdn_value(PyLdbDnObject
*self
,
819 PyObject
*Py_UNUSED(ignored
))
822 const struct ldb_val
*val
;
824 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
826 val
= ldb_dn_get_rdn_val(dn
);
831 return PyStr_FromLdbValue(val
);
834 static PyMethodDef py_ldb_dn_methods
[] = {
835 { "validate", (PyCFunction
)py_ldb_dn_validate
, METH_NOARGS
,
836 "S.validate() -> bool\n"
837 "Validate DN is correct." },
838 { "is_valid", (PyCFunction
)py_ldb_dn_is_valid
, METH_NOARGS
,
839 "S.is_valid() -> bool\n" },
840 { "is_special", (PyCFunction
)py_ldb_dn_is_special
, METH_NOARGS
,
841 "S.is_special() -> bool\n"
842 "Check whether this is a special LDB DN." },
843 { "is_null", (PyCFunction
)py_ldb_dn_is_null
, METH_NOARGS
,
844 "Check whether this is a null DN." },
845 { "get_casefold", (PyCFunction
)py_ldb_dn_get_casefold
, METH_NOARGS
,
847 { "get_linearized", PY_DISCARD_FUNC_SIG(PyCFunction
,
848 py_ldb_dn_get_linearized
),
851 { "canonical_str", (PyCFunction
)py_ldb_dn_canonical_str
, METH_NOARGS
,
852 "S.canonical_str() -> string\n"
853 "Canonical version of this DN (like a posix path)." },
854 { "is_child_of", (PyCFunction
)py_ldb_dn_is_child_of
, METH_VARARGS
,
855 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
856 { "canonical_ex_str", (PyCFunction
)py_ldb_dn_canonical_ex_str
, METH_NOARGS
,
857 "S.canonical_ex_str() -> string\n"
858 "Canonical version of this DN (like a posix path, with terminating newline)." },
859 { "extended_str", PY_DISCARD_FUNC_SIG(PyCFunction
,
860 py_ldb_dn_extended_str
),
861 METH_VARARGS
| METH_KEYWORDS
,
862 "S.extended_str(mode=1) -> string\n"
863 "Extended version of this DN" },
864 { "parent", (PyCFunction
)py_ldb_dn_get_parent
, METH_NOARGS
,
866 "Get the parent for this DN." },
867 { "add_child", (PyCFunction
)py_ldb_dn_add_child
, METH_VARARGS
,
868 "S.add_child(dn) -> bool\n"
869 "Add a child DN to this DN." },
870 { "add_base", (PyCFunction
)py_ldb_dn_add_base
, METH_VARARGS
,
871 "S.add_base(dn) -> bool\n"
872 "Add a base DN to this DN." },
873 { "remove_base_components", (PyCFunction
)py_ldb_dn_remove_base_components
, METH_VARARGS
,
874 "S.remove_base_components(int) -> bool\n"
875 "Remove a number of DN components from the base of this DN." },
876 { "check_special", (PyCFunction
)py_ldb_dn_check_special
, METH_VARARGS
,
877 "S.check_special(name) -> bool\n\n"
878 "Check if name is a special DN name"},
879 { "get_extended_component", (PyCFunction
)py_ldb_dn_get_extended_component
, METH_VARARGS
,
880 "S.get_extended_component(name) -> string\n\n"
881 "returns a DN extended component as a binary string"},
882 { "set_extended_component", (PyCFunction
)py_ldb_dn_set_extended_component
, METH_VARARGS
,
883 "S.set_extended_component(name, value) -> None\n\n"
884 "set a DN extended component as a binary string"},
885 { "get_component_name", (PyCFunction
)py_ldb_dn_get_component_name
, METH_VARARGS
,
886 "S.get_component_name(num) -> string\n"
887 "get the attribute name of the specified component" },
888 { "get_component_value", (PyCFunction
)py_ldb_dn_get_component_value
, METH_VARARGS
,
889 "S.get_component_value(num) -> string\n"
890 "get the attribute value of the specified component as a binary string" },
891 { "set_component", (PyCFunction
)py_ldb_dn_set_component
, METH_VARARGS
,
892 "S.set_component(num, name, value) -> None\n"
893 "set the attribute name and value of the specified component" },
894 { "get_rdn_name", (PyCFunction
)py_ldb_dn_get_rdn_name
, METH_NOARGS
,
895 "S.get_rdn_name() -> string\n"
896 "get the RDN attribute name" },
897 { "get_rdn_value", (PyCFunction
)py_ldb_dn_get_rdn_value
, METH_NOARGS
,
898 "S.get_rdn_value() -> string\n"
899 "get the RDN attribute value as a binary string" },
903 static Py_ssize_t
py_ldb_dn_len(PyLdbDnObject
*self
)
905 return ldb_dn_get_comp_num(pyldb_Dn_AS_DN((PyObject
*)self
));
909 copy a DN as a python object
911 static PyObject
*py_ldb_dn_copy(struct ldb_dn
*dn
)
913 TALLOC_CTX
*mem_ctx
= NULL
;
914 struct ldb_dn
*new_dn
= NULL
;
915 PyLdbDnObject
*py_ret
;
917 mem_ctx
= talloc_new(NULL
);
918 if (mem_ctx
== NULL
) {
919 return PyErr_NoMemory();
922 new_dn
= ldb_dn_copy(mem_ctx
, dn
);
923 if (new_dn
== NULL
) {
924 talloc_free(mem_ctx
);
925 return PyErr_NoMemory();
928 py_ret
= (PyLdbDnObject
*)PyLdbDn
.tp_alloc(&PyLdbDn
, 0);
929 if (py_ret
== NULL
) {
930 talloc_free(mem_ctx
);
934 py_ret
->mem_ctx
= mem_ctx
;
936 return (PyObject
*)py_ret
;
939 static PyObject
*py_ldb_dn_concat(PyLdbDnObject
*self
, PyObject
*py_other
)
941 TALLOC_CTX
*mem_ctx
= NULL
;
942 struct ldb_dn
*dn
= pyldb_Dn_AS_DN((PyObject
*)self
),
944 struct ldb_dn
*new_dn
= NULL
;
945 PyLdbDnObject
*py_ret
;
947 if (!pyldb_Object_AsDn(NULL
, py_other
, NULL
, &other
))
950 mem_ctx
= talloc_new(NULL
);
951 if (mem_ctx
== NULL
) {
952 return PyErr_NoMemory();
955 new_dn
= ldb_dn_copy(mem_ctx
, dn
);
956 if (new_dn
== NULL
) {
957 talloc_free(mem_ctx
);
958 return PyErr_NoMemory();
961 if (!ldb_dn_add_base(new_dn
, other
)) {
962 PyErr_SetString(PyExc_RuntimeError
, "unable to concatenate DNs");
963 talloc_free(mem_ctx
);
967 py_ret
= (PyLdbDnObject
*)PyLdbDn
.tp_alloc(&PyLdbDn
, 0);
968 if (py_ret
== NULL
) {
969 talloc_free(mem_ctx
);
973 py_ret
->mem_ctx
= mem_ctx
;
976 return (PyObject
*)py_ret
;
979 static PySequenceMethods py_ldb_dn_seq
= {
980 .sq_length
= (lenfunc
)py_ldb_dn_len
,
981 .sq_concat
= (binaryfunc
)py_ldb_dn_concat
,
984 static PyObject
*py_ldb_dn_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
986 struct ldb_dn
*ret
= NULL
;
988 PyObject
*py_ldb
= NULL
;
989 struct ldb_context
*ldb_ctx
= NULL
;
990 TALLOC_CTX
*mem_ctx
= NULL
;
991 PyLdbDnObject
*py_ret
= NULL
;
992 const char * const kwnames
[] = { "ldb", "dn", NULL
};
994 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O"PYARG_STR_UNI
,
995 discard_const_p(char *, kwnames
),
996 &py_ldb
, "utf8", &str
))
999 if (!PyLdb_Check(py_ldb
)) {
1000 PyErr_SetString(PyExc_TypeError
, "Expected Ldb");
1003 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(py_ldb
);
1005 mem_ctx
= talloc_new(NULL
);
1006 if (mem_ctx
== NULL
) {
1011 ret
= ldb_dn_new(mem_ctx
, ldb_ctx
, str
);
1012 if (!ldb_dn_validate(ret
)) {
1013 talloc_free(mem_ctx
);
1014 PyErr_SetString(PyExc_ValueError
, "unable to parse dn string");
1018 py_ret
= (PyLdbDnObject
*)type
->tp_alloc(type
, 0);
1019 if (py_ret
== NULL
) {
1020 talloc_free(mem_ctx
);
1024 py_ret
->mem_ctx
= mem_ctx
;
1028 PyMem_Free(discard_const_p(char, str
));
1030 return (PyObject
*)py_ret
;
1033 static void py_ldb_dn_dealloc(PyLdbDnObject
*self
)
1035 talloc_free(self
->mem_ctx
);
1039 static PyTypeObject PyLdbDn
= {
1040 .tp_name
= "ldb.Dn",
1041 .tp_methods
= py_ldb_dn_methods
,
1042 .tp_str
= (reprfunc
)py_ldb_dn_get_linearized
,
1043 .tp_repr
= (reprfunc
)py_ldb_dn_repr
,
1044 .tp_richcompare
= (richcmpfunc
)py_ldb_dn_richcmp
,
1045 .tp_as_sequence
= &py_ldb_dn_seq
,
1046 .tp_doc
= "A LDB distinguished name.",
1047 .tp_new
= py_ldb_dn_new
,
1048 .tp_dealloc
= (destructor
)py_ldb_dn_dealloc
,
1049 .tp_basicsize
= sizeof(PyLdbDnObject
),
1050 .tp_flags
= Py_TPFLAGS_DEFAULT
,
1054 static void py_ldb_debug(void *context
, enum ldb_debug_level level
, const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(3, 0);
1055 static void py_ldb_debug(void *context
, enum ldb_debug_level level
, const char *fmt
, va_list ap
)
1057 PyObject
*fn
= (PyObject
*)context
;
1058 PyObject
*result
= NULL
;
1059 result
= PyObject_CallFunction(fn
, discard_const_p(char, "(i,O)"), level
, PyUnicode_FromFormatV(fmt
, ap
));
1063 static PyObject
*py_ldb_debug_func
;
1065 static PyObject
*py_ldb_set_debug(PyObject
*self
, PyObject
*args
)
1068 struct ldb_context
*ldb_ctx
;
1070 if (!PyArg_ParseTuple(args
, "O", &cb
))
1073 if (py_ldb_debug_func
!= NULL
) {
1074 Py_DECREF(py_ldb_debug_func
);
1078 /* FIXME: DECREF cb when exiting program */
1079 py_ldb_debug_func
= cb
;
1080 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1081 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
,
1082 ldb_set_debug(ldb_ctx
, py_ldb_debug
, cb
),
1088 static PyObject
*py_ldb_set_create_perms(PyTypeObject
*self
, PyObject
*args
)
1091 if (!PyArg_ParseTuple(args
, "I", &perms
))
1094 ldb_set_create_perms(pyldb_Ldb_AS_LDBCONTEXT(self
), perms
);
1099 static PyObject
*py_ldb_set_modules_dir(PyTypeObject
*self
, PyObject
*args
)
1102 if (!PyArg_ParseTuple(args
, "s", &modules_dir
))
1105 ldb_set_modules_dir(pyldb_Ldb_AS_LDBCONTEXT(self
), modules_dir
);
1110 static PyObject
*py_ldb_transaction_start(PyLdbObject
*self
,
1111 PyObject
*Py_UNUSED(ignored
))
1113 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1115 ldb_err
= ldb_transaction_start(ldb_ctx
);
1116 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1120 static PyObject
*py_ldb_transaction_commit(PyLdbObject
*self
,
1121 PyObject
*Py_UNUSED(ignored
))
1123 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1125 ldb_err
= ldb_transaction_commit(ldb_ctx
);
1126 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1130 static PyObject
*py_ldb_transaction_prepare_commit(PyLdbObject
*self
,
1131 PyObject
*Py_UNUSED(ignored
))
1133 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1135 ldb_err
= ldb_transaction_prepare_commit(ldb_ctx
);
1136 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1140 static PyObject
*py_ldb_transaction_cancel(PyLdbObject
*self
,
1141 PyObject
*Py_UNUSED(ignored
))
1143 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1145 ldb_err
= ldb_transaction_cancel(ldb_ctx
);
1146 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1150 static PyObject
*py_ldb_setup_wellknown_attributes(PyLdbObject
*self
,
1151 PyObject
*Py_UNUSED(ignored
))
1153 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1155 ldb_err
= ldb_setup_wellknown_attributes(ldb_ctx
);
1156 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1160 static PyObject
*py_ldb_repr(PyLdbObject
*self
)
1162 return PyUnicode_FromString("<ldb connection>");
1165 static PyObject
*py_ldb_get_root_basedn(PyLdbObject
*self
,
1166 PyObject
*Py_UNUSED(ignored
))
1168 struct ldb_dn
*dn
= ldb_get_root_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1171 return py_ldb_dn_copy(dn
);
1175 static PyObject
*py_ldb_get_schema_basedn(PyLdbObject
*self
,
1176 PyObject
*Py_UNUSED(ignored
))
1178 struct ldb_dn
*dn
= ldb_get_schema_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1181 return py_ldb_dn_copy(dn
);
1184 static PyObject
*py_ldb_get_config_basedn(PyLdbObject
*self
,
1185 PyObject
*Py_UNUSED(ignored
))
1187 struct ldb_dn
*dn
= ldb_get_config_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1190 return py_ldb_dn_copy(dn
);
1193 static PyObject
*py_ldb_get_default_basedn(PyLdbObject
*self
,
1194 PyObject
*Py_UNUSED(ignored
))
1196 struct ldb_dn
*dn
= ldb_get_default_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1199 return py_ldb_dn_copy(dn
);
1202 static const char **PyList_AsStrList(TALLOC_CTX
*mem_ctx
, PyObject
*list
,
1203 const char *paramname
)
1207 if (!PyList_Check(list
)) {
1208 PyErr_Format(PyExc_TypeError
, "%s is not a list", paramname
);
1211 ret
= talloc_array(NULL
, const char *, PyList_Size(list
)+1);
1217 for (i
= 0; i
< PyList_Size(list
); i
++) {
1218 const char *str
= NULL
;
1220 PyObject
*item
= PyList_GetItem(list
, i
);
1221 if (!PyUnicode_Check(item
)) {
1222 PyErr_Format(PyExc_TypeError
, "%s should be strings", paramname
);
1226 str
= PyUnicode_AsUTF8AndSize(item
, &size
);
1231 ret
[i
] = talloc_strndup(ret
, str
, size
);
1237 static int py_ldb_init(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1239 const char * const kwnames
[] = { "url", "flags", "options", NULL
};
1241 PyObject
*py_options
= Py_None
;
1242 const char **options
;
1243 unsigned int flags
= 0;
1245 struct ldb_context
*ldb
;
1247 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|zIO:Ldb.__init__",
1248 discard_const_p(char *, kwnames
),
1249 &url
, &flags
, &py_options
))
1252 ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1254 if (py_options
== Py_None
) {
1257 options
= PyList_AsStrList(ldb
, py_options
, "options");
1258 if (options
== NULL
)
1263 ret
= ldb_connect(ldb
, url
, flags
, options
);
1264 if (ret
!= LDB_SUCCESS
) {
1265 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb
);
1266 talloc_free(options
);
1270 ldb_set_flags(ldb
, flags
);
1273 talloc_free(options
);
1277 static PyObject
*py_ldb_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
1279 TALLOC_CTX
*mem_ctx
= NULL
;
1281 struct ldb_context
*ldb
;
1283 mem_ctx
= talloc_new(NULL
);
1284 if (mem_ctx
== NULL
) {
1285 return PyErr_NoMemory();
1288 ldb
= ldb_init(mem_ctx
, NULL
);
1290 talloc_free(mem_ctx
);
1295 ret
= (PyLdbObject
*)type
->tp_alloc(type
, 0);
1297 talloc_free(mem_ctx
);
1301 ret
->mem_ctx
= mem_ctx
;
1304 return (PyObject
*)ret
;
1307 static PyObject
*py_ldb_connect(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1310 unsigned int flags
= 0;
1311 PyObject
*py_options
= Py_None
;
1313 const char **options
;
1314 const char * const kwnames
[] = { "url", "flags", "options", NULL
};
1315 struct ldb_context
*ldb_ctx
;
1317 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|IO",
1318 discard_const_p(char *, kwnames
),
1319 &url
, &flags
, &py_options
))
1322 if (py_options
== Py_None
) {
1325 options
= PyList_AsStrList(NULL
, py_options
, "options");
1326 if (options
== NULL
)
1330 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1331 ret
= ldb_connect(ldb_ctx
, url
, flags
, options
);
1332 talloc_free(options
);
1334 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1339 static PyObject
*py_ldb_modify(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1342 PyObject
*py_controls
= Py_None
;
1343 struct ldb_context
*ldb_ctx
;
1344 struct ldb_request
*req
;
1345 struct ldb_control
**parsed_controls
;
1346 struct ldb_message
*msg
;
1348 TALLOC_CTX
*mem_ctx
;
1350 const char * const kwnames
[] = { "message", "controls", "validate", NULL
};
1352 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Ob",
1353 discard_const_p(char *, kwnames
),
1354 &py_msg
, &py_controls
, &validate
))
1357 mem_ctx
= talloc_new(NULL
);
1358 if (mem_ctx
== NULL
) {
1362 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1364 if (py_controls
== Py_None
) {
1365 parsed_controls
= NULL
;
1367 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1368 if (controls
== NULL
) {
1369 talloc_free(mem_ctx
);
1372 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1373 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
1374 talloc_free(mem_ctx
);
1375 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
1378 talloc_free(controls
);
1381 if (!PyLdbMessage_Check(py_msg
)) {
1382 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message");
1383 talloc_free(mem_ctx
);
1386 msg
= pyldb_Message_AsMessage(py_msg
);
1389 ret
= ldb_msg_sanity_check(ldb_ctx
, msg
);
1390 if (ret
!= LDB_SUCCESS
) {
1391 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1392 talloc_free(mem_ctx
);
1397 ret
= ldb_build_mod_req(&req
, ldb_ctx
, mem_ctx
, msg
, parsed_controls
,
1398 NULL
, ldb_op_default_callback
, NULL
);
1399 if (ret
!= LDB_SUCCESS
) {
1400 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1401 talloc_free(mem_ctx
);
1405 /* do request and autostart a transaction */
1406 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1408 ret
= ldb_transaction_start(ldb_ctx
);
1409 if (ret
!= LDB_SUCCESS
) {
1410 talloc_free(mem_ctx
);
1411 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1415 ret
= ldb_request(ldb_ctx
, req
);
1416 if (ret
== LDB_SUCCESS
) {
1417 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1420 if (ret
== LDB_SUCCESS
) {
1421 ret
= ldb_transaction_commit(ldb_ctx
);
1423 ldb_transaction_cancel(ldb_ctx
);
1426 talloc_free(mem_ctx
);
1427 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1434 * Obtain a ldb message from a Python Dictionary object.
1436 * @param mem_ctx Memory context
1437 * @param py_obj Python Dictionary object
1438 * @param ldb_ctx LDB context
1439 * @param mod_flags Flags to be set on every message element
1440 * @return ldb_message on success or NULL on failure
1442 static struct ldb_message
*PyDict_AsMessage(TALLOC_CTX
*mem_ctx
,
1444 struct ldb_context
*ldb_ctx
,
1445 unsigned int mod_flags
)
1447 struct ldb_message
*msg
;
1448 unsigned int msg_pos
= 0;
1449 Py_ssize_t dict_pos
= 0;
1450 PyObject
*key
, *value
;
1451 struct ldb_message_element
*msg_el
;
1452 PyObject
*dn_value
= PyDict_GetItemString(py_obj
, "dn");
1454 msg
= ldb_msg_new(mem_ctx
);
1459 msg
->elements
= talloc_zero_array(msg
, struct ldb_message_element
, PyDict_Size(py_obj
));
1460 if (msg
->elements
== NULL
) {
1467 if (!pyldb_Object_AsDn(msg
, dn_value
, ldb_ctx
, &msg
->dn
)) {
1468 PyErr_SetString(PyExc_TypeError
, "unable to import dn object");
1472 if (msg
->dn
== NULL
) {
1473 PyErr_SetString(PyExc_TypeError
, "dn set but not found");
1478 PyErr_SetString(PyExc_TypeError
, "no dn set");
1483 while (PyDict_Next(py_obj
, &dict_pos
, &key
, &value
)) {
1484 const char *key_str
= PyUnicode_AsUTF8(key
);
1485 if (ldb_attr_cmp(key_str
, "dn") != 0) {
1486 msg_el
= PyObject_AsMessageElement(msg
->elements
, value
,
1487 mod_flags
, key_str
);
1488 if (msg_el
== NULL
) {
1489 PyErr_Format(PyExc_TypeError
, "unable to import element '%s'", key_str
);
1493 memcpy(&msg
->elements
[msg_pos
], msg_el
, sizeof(*msg_el
));
1496 * PyObject_AsMessageElement might have returned a
1497 * reference to an existing MessageElement, and so left
1498 * the name and flags unchanged. Thus if those members
1499 * aren’t set, we’ll assume that the user forgot to
1502 if (msg
->elements
[msg_pos
].name
== NULL
) {
1503 /* No name was set — set it now. */
1504 msg
->elements
[msg_pos
].name
= talloc_strdup(msg
->elements
, key_str
);
1505 if (msg
->elements
[msg_pos
].name
== NULL
) {
1511 if (msg
->elements
[msg_pos
].flags
== 0) {
1512 /* No flags were set — set them now. */
1513 msg
->elements
[msg_pos
].flags
= mod_flags
;
1520 msg
->num_elements
= msg_pos
;
1525 static PyObject
*py_ldb_add(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1529 struct ldb_context
*ldb_ctx
;
1530 struct ldb_request
*req
;
1531 struct ldb_message
*msg
= NULL
;
1532 PyObject
*py_controls
= Py_None
;
1533 TALLOC_CTX
*mem_ctx
;
1534 struct ldb_control
**parsed_controls
;
1535 const char * const kwnames
[] = { "message", "controls", NULL
};
1537 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O",
1538 discard_const_p(char *, kwnames
),
1539 &py_obj
, &py_controls
))
1542 mem_ctx
= talloc_new(NULL
);
1543 if (mem_ctx
== NULL
) {
1547 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1549 if (py_controls
== Py_None
) {
1550 parsed_controls
= NULL
;
1552 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1553 if (controls
== NULL
) {
1554 talloc_free(mem_ctx
);
1557 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1558 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
1559 talloc_free(mem_ctx
);
1560 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
1563 talloc_free(controls
);
1566 if (PyLdbMessage_Check(py_obj
)) {
1567 msg
= pyldb_Message_AsMessage(py_obj
);
1568 } else if (PyDict_Check(py_obj
)) {
1569 msg
= PyDict_AsMessage(mem_ctx
, py_obj
, ldb_ctx
, LDB_FLAG_MOD_ADD
);
1571 PyErr_SetString(PyExc_TypeError
,
1572 "Dictionary or LdbMessage object expected!");
1576 /* we should have a PyErr already set */
1577 talloc_free(mem_ctx
);
1581 ret
= ldb_msg_sanity_check(ldb_ctx
, msg
);
1582 if (ret
!= LDB_SUCCESS
) {
1583 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1584 talloc_free(mem_ctx
);
1588 ret
= ldb_build_add_req(&req
, ldb_ctx
, mem_ctx
, msg
, parsed_controls
,
1589 NULL
, ldb_op_default_callback
, NULL
);
1590 if (ret
!= LDB_SUCCESS
) {
1591 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1592 talloc_free(mem_ctx
);
1596 /* do request and autostart a transaction */
1597 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1599 ret
= ldb_transaction_start(ldb_ctx
);
1600 if (ret
!= LDB_SUCCESS
) {
1601 talloc_free(mem_ctx
);
1602 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1606 ret
= ldb_request(ldb_ctx
, req
);
1607 if (ret
== LDB_SUCCESS
) {
1608 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1611 if (ret
== LDB_SUCCESS
) {
1612 ret
= ldb_transaction_commit(ldb_ctx
);
1614 ldb_transaction_cancel(ldb_ctx
);
1617 talloc_free(mem_ctx
);
1618 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1623 static PyObject
*py_ldb_delete(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1628 struct ldb_context
*ldb_ctx
;
1629 struct ldb_request
*req
;
1630 PyObject
*py_controls
= Py_None
;
1631 TALLOC_CTX
*mem_ctx
;
1632 struct ldb_control
**parsed_controls
;
1633 const char * const kwnames
[] = { "dn", "controls", NULL
};
1635 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O",
1636 discard_const_p(char *, kwnames
),
1637 &py_dn
, &py_controls
))
1640 mem_ctx
= talloc_new(NULL
);
1641 if (mem_ctx
== NULL
) {
1645 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1647 if (py_controls
== Py_None
) {
1648 parsed_controls
= NULL
;
1650 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1651 if (controls
== NULL
) {
1652 talloc_free(mem_ctx
);
1655 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1656 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
1657 talloc_free(mem_ctx
);
1658 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
1661 talloc_free(controls
);
1664 if (!pyldb_Object_AsDn(mem_ctx
, py_dn
, ldb_ctx
, &dn
)) {
1665 talloc_free(mem_ctx
);
1669 ret
= ldb_build_del_req(&req
, ldb_ctx
, mem_ctx
, dn
, parsed_controls
,
1670 NULL
, ldb_op_default_callback
, NULL
);
1671 if (ret
!= LDB_SUCCESS
) {
1672 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1673 talloc_free(mem_ctx
);
1677 /* do request and autostart a transaction */
1678 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1680 ret
= ldb_transaction_start(ldb_ctx
);
1681 if (ret
!= LDB_SUCCESS
) {
1682 talloc_free(mem_ctx
);
1683 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1687 ret
= ldb_request(ldb_ctx
, req
);
1688 if (ret
== LDB_SUCCESS
) {
1689 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1692 if (ret
== LDB_SUCCESS
) {
1693 ret
= ldb_transaction_commit(ldb_ctx
);
1695 ldb_transaction_cancel(ldb_ctx
);
1698 talloc_free(mem_ctx
);
1699 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1704 static PyObject
*py_ldb_rename(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1706 PyObject
*py_dn1
, *py_dn2
;
1707 struct ldb_dn
*dn1
, *dn2
;
1709 TALLOC_CTX
*mem_ctx
;
1710 PyObject
*py_controls
= Py_None
;
1711 struct ldb_control
**parsed_controls
;
1712 struct ldb_context
*ldb_ctx
;
1713 struct ldb_request
*req
;
1714 const char * const kwnames
[] = { "dn1", "dn2", "controls", NULL
};
1716 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1718 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|O",
1719 discard_const_p(char *, kwnames
),
1720 &py_dn1
, &py_dn2
, &py_controls
))
1724 mem_ctx
= talloc_new(NULL
);
1725 if (mem_ctx
== NULL
) {
1730 if (py_controls
== Py_None
) {
1731 parsed_controls
= NULL
;
1733 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1734 if (controls
== NULL
) {
1735 talloc_free(mem_ctx
);
1738 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1739 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
1740 talloc_free(mem_ctx
);
1741 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
1744 talloc_free(controls
);
1748 if (!pyldb_Object_AsDn(mem_ctx
, py_dn1
, ldb_ctx
, &dn1
)) {
1749 talloc_free(mem_ctx
);
1753 if (!pyldb_Object_AsDn(mem_ctx
, py_dn2
, ldb_ctx
, &dn2
)) {
1754 talloc_free(mem_ctx
);
1758 ret
= ldb_build_rename_req(&req
, ldb_ctx
, mem_ctx
, dn1
, dn2
, parsed_controls
,
1759 NULL
, ldb_op_default_callback
, NULL
);
1760 if (ret
!= LDB_SUCCESS
) {
1761 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1762 talloc_free(mem_ctx
);
1766 /* do request and autostart a transaction */
1767 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1769 ret
= ldb_transaction_start(ldb_ctx
);
1770 if (ret
!= LDB_SUCCESS
) {
1771 talloc_free(mem_ctx
);
1772 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1776 ret
= ldb_request(ldb_ctx
, req
);
1777 if (ret
== LDB_SUCCESS
) {
1778 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1781 if (ret
== LDB_SUCCESS
) {
1782 ret
= ldb_transaction_commit(ldb_ctx
);
1784 ldb_transaction_cancel(ldb_ctx
);
1787 talloc_free(mem_ctx
);
1788 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1793 static PyObject
*py_ldb_schema_attribute_remove(PyLdbObject
*self
, PyObject
*args
)
1796 if (!PyArg_ParseTuple(args
, "s", &name
))
1799 ldb_schema_attribute_remove(pyldb_Ldb_AS_LDBCONTEXT(self
), name
);
1804 static PyObject
*py_ldb_schema_attribute_add(PyLdbObject
*self
, PyObject
*args
)
1806 char *attribute
, *syntax
;
1809 struct ldb_context
*ldb_ctx
;
1811 if (!PyArg_ParseTuple(args
, "sIs", &attribute
, &flags
, &syntax
))
1814 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1815 ret
= ldb_schema_attribute_add(ldb_ctx
, attribute
, flags
, syntax
);
1817 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1822 static PyObject
*ldb_ldif_to_pyobject(struct ldb_context
*ldb
, struct ldb_ldif
*ldif
)
1824 PyObject
*obj
= NULL
;
1825 PyObject
*result
= NULL
;
1831 switch (ldif
->changetype
) {
1832 case LDB_CHANGETYPE_NONE
:
1833 case LDB_CHANGETYPE_ADD
:
1834 obj
= PyLdbMessage_FromMessage(ldif
->msg
);
1836 case LDB_CHANGETYPE_MODIFY
:
1837 obj
= PyLdbMessage_FromMessage(ldif
->msg
);
1839 case LDB_CHANGETYPE_DELETE
:
1840 if (ldif
->msg
->num_elements
!= 0) {
1841 PyErr_Format(PyExc_ValueError
,
1842 "CHANGETYPE(DELETE) with num_elements=%u",
1843 ldif
->msg
->num_elements
);
1846 obj
= pyldb_Dn_FromDn(ldif
->msg
->dn
);
1848 case LDB_CHANGETYPE_MODRDN
: {
1849 struct ldb_dn
*olddn
= NULL
;
1850 PyObject
*olddn_obj
= NULL
;
1851 bool deleteoldrdn
= false;
1852 PyObject
*deleteoldrdn_obj
= NULL
;
1853 struct ldb_dn
*newdn
= NULL
;
1854 PyObject
*newdn_obj
= NULL
;
1857 ret
= ldb_ldif_parse_modrdn(ldb
,
1865 if (ret
!= LDB_SUCCESS
) {
1866 PyErr_Format(PyExc_ValueError
,
1867 "ldb_ldif_parse_modrdn() failed");
1871 olddn_obj
= pyldb_Dn_FromDn(olddn
);
1872 if (olddn_obj
== NULL
) {
1876 deleteoldrdn_obj
= Py_True
;
1878 deleteoldrdn_obj
= Py_False
;
1880 newdn_obj
= pyldb_Dn_FromDn(newdn
);
1881 if (newdn_obj
== NULL
) {
1882 deleteoldrdn_obj
= NULL
;
1883 Py_CLEAR(olddn_obj
);
1887 obj
= Py_BuildValue(discard_const_p(char, "{s:O,s:O,s:O}"),
1889 "deleteoldrdn", deleteoldrdn_obj
,
1890 "newdn", newdn_obj
);
1891 Py_CLEAR(olddn_obj
);
1892 deleteoldrdn_obj
= NULL
;
1893 Py_CLEAR(newdn_obj
);
1897 PyErr_Format(PyExc_NotImplementedError
,
1898 "Unsupported LDB_CHANGETYPE(%u)",
1907 /* We don't want this being attached * to the 'ldb' any more */
1908 result
= Py_BuildValue(discard_const_p(char, "(iO)"),
1916 static PyObject
*py_ldb_write_ldif(PyLdbObject
*self
, PyObject
*args
)
1920 struct ldb_ldif ldif
;
1923 TALLOC_CTX
*mem_ctx
;
1925 if (!PyArg_ParseTuple(args
, "Oi", &py_msg
, &changetype
))
1928 if (!PyLdbMessage_Check(py_msg
)) {
1929 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for msg");
1933 ldif
.msg
= pyldb_Message_AsMessage(py_msg
);
1934 ldif
.changetype
= changetype
;
1936 mem_ctx
= talloc_new(NULL
);
1937 if (mem_ctx
== NULL
) {
1938 return PyErr_NoMemory();
1941 string
= ldb_ldif_write_string(pyldb_Ldb_AS_LDBCONTEXT(self
), mem_ctx
, &ldif
);
1943 PyErr_SetString(PyExc_KeyError
, "Failed to generate LDIF");
1944 talloc_free(mem_ctx
);
1948 ret
= PyUnicode_FromString(string
);
1950 talloc_free(mem_ctx
);
1955 static PyObject
*py_ldb_parse_ldif(PyLdbObject
*self
, PyObject
*args
)
1957 PyObject
*list
, *ret
;
1958 struct ldb_ldif
*ldif
;
1960 struct ldb_dn
*last_dn
= NULL
;
1962 TALLOC_CTX
*mem_ctx
;
1964 if (!PyArg_ParseTuple(args
, "s", &s
))
1967 mem_ctx
= talloc_new(NULL
);
1972 list
= PyList_New(0);
1974 talloc_free(mem_ctx
);
1978 while (s
&& *s
!= '\0') {
1979 ldif
= ldb_ldif_read_string(self
->ldb_ctx
, &s
);
1980 talloc_steal(mem_ctx
, ldif
);
1983 PyObject
*py_ldif
= ldb_ldif_to_pyobject(self
->ldb_ctx
, ldif
);
1984 if (py_ldif
== NULL
) {
1986 if (PyErr_Occurred() == NULL
) {
1987 PyErr_BadArgument();
1989 talloc_free(mem_ctx
);
1992 res
= PyList_Append(list
, py_ldif
);
1996 talloc_free(mem_ctx
);
1999 last_dn
= ldif
->msg
->dn
;
2001 const char *last_dn_str
= NULL
;
2002 const char *err_string
= NULL
;
2003 if (last_dn
== NULL
) {
2004 PyErr_SetString(PyExc_ValueError
,
2005 "unable to parse LDIF "
2006 "string at first chunk");
2008 talloc_free(mem_ctx
);
2013 = ldb_dn_get_linearized(last_dn
);
2016 = talloc_asprintf(mem_ctx
,
2017 "unable to parse ldif "
2021 PyErr_SetString(PyExc_ValueError
,
2023 talloc_free(mem_ctx
);
2028 talloc_free(mem_ctx
); /* The pyobject already has a reference to the things it needs */
2029 ret
= PyObject_GetIter(list
);
2034 static PyObject
*py_ldb_msg_diff(PyLdbObject
*self
, PyObject
*args
)
2037 PyObject
*py_msg_old
;
2038 PyObject
*py_msg_new
;
2039 struct ldb_message
*diff
;
2040 struct ldb_context
*ldb
;
2042 TALLOC_CTX
*mem_ctx
= NULL
;
2044 if (!PyArg_ParseTuple(args
, "OO", &py_msg_old
, &py_msg_new
))
2047 if (!PyLdbMessage_Check(py_msg_old
)) {
2048 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for old message");
2052 if (!PyLdbMessage_Check(py_msg_new
)) {
2053 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for new message");
2057 mem_ctx
= talloc_new(NULL
);
2058 if (mem_ctx
== NULL
) {
2063 ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2064 ldb_ret
= ldb_msg_difference(ldb
, mem_ctx
,
2065 pyldb_Message_AsMessage(py_msg_old
),
2066 pyldb_Message_AsMessage(py_msg_new
),
2068 if (ldb_ret
!= LDB_SUCCESS
) {
2069 talloc_free(mem_ctx
);
2070 PyErr_SetString(PyExc_RuntimeError
, "Failed to generate the Ldb Message diff");
2074 diff
= ldb_msg_copy(mem_ctx
, diff
);
2076 talloc_free(mem_ctx
);
2081 py_ret
= PyLdbMessage_FromMessage(diff
);
2083 talloc_free(mem_ctx
);
2088 static PyObject
*py_ldb_schema_format_value(PyLdbObject
*self
, PyObject
*args
)
2090 const struct ldb_schema_attribute
*a
;
2091 struct ldb_val old_val
;
2092 struct ldb_val new_val
;
2093 TALLOC_CTX
*mem_ctx
;
2100 if (!PyArg_ParseTuple(args
, "sO", &element_name
, &val
))
2103 result
= PyBytes_AsStringAndSize(val
, (char **)&old_val
.data
, &size
);
2104 old_val
.length
= size
;
2107 PyErr_SetString(PyExc_RuntimeError
, "Failed to convert passed value to String");
2111 a
= ldb_schema_attribute_by_name(pyldb_Ldb_AS_LDBCONTEXT(self
), element_name
);
2117 mem_ctx
= talloc_new(NULL
);
2118 if (mem_ctx
== NULL
) {
2123 if (a
->syntax
->ldif_write_fn(pyldb_Ldb_AS_LDBCONTEXT(self
), mem_ctx
, &old_val
, &new_val
) != 0) {
2124 talloc_free(mem_ctx
);
2128 ret
= PyBytes_FromStringAndSize((const char *)new_val
.data
, new_val
.length
);
2130 talloc_free(mem_ctx
);
2135 static PyObject
*py_ldb_search(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
2137 PyObject
*py_base
= Py_None
;
2138 int scope
= LDB_SCOPE_DEFAULT
;
2140 PyObject
*py_attrs
= Py_None
;
2141 PyObject
*py_controls
= Py_None
;
2142 const char * const kwnames
[] = { "base", "scope", "expression", "attrs", "controls", NULL
};
2144 struct ldb_result
*res
;
2145 struct ldb_request
*req
;
2147 struct ldb_context
*ldb_ctx
;
2148 struct ldb_control
**parsed_controls
;
2149 struct ldb_dn
*base
;
2151 TALLOC_CTX
*mem_ctx
;
2153 /* type "int" rather than "enum" for "scope" is intentional */
2154 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OizOO",
2155 discard_const_p(char *, kwnames
),
2156 &py_base
, &scope
, &expr
, &py_attrs
, &py_controls
))
2160 mem_ctx
= talloc_new(NULL
);
2161 if (mem_ctx
== NULL
) {
2165 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2167 if (py_attrs
== Py_None
) {
2170 attrs
= PyList_AsStrList(mem_ctx
, py_attrs
, "attrs");
2171 if (attrs
== NULL
) {
2172 talloc_free(mem_ctx
);
2177 if (py_base
== Py_None
) {
2178 base
= ldb_get_default_basedn(ldb_ctx
);
2180 if (!pyldb_Object_AsDn(mem_ctx
, py_base
, ldb_ctx
, &base
)) {
2181 talloc_free(mem_ctx
);
2186 if (py_controls
== Py_None
) {
2187 parsed_controls
= NULL
;
2189 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
2190 if (controls
== NULL
) {
2191 talloc_free(mem_ctx
);
2194 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
2195 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
2196 talloc_free(mem_ctx
);
2197 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
2200 talloc_free(controls
);
2203 res
= talloc_zero(mem_ctx
, struct ldb_result
);
2206 talloc_free(mem_ctx
);
2210 ret
= ldb_build_search_req(&req
, ldb_ctx
, mem_ctx
,
2217 ldb_search_default_callback
,
2220 if (ret
!= LDB_SUCCESS
) {
2221 talloc_free(mem_ctx
);
2222 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2226 talloc_steal(req
, attrs
);
2228 ret
= ldb_request(ldb_ctx
, req
);
2230 if (ret
== LDB_SUCCESS
) {
2231 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
2234 if (ret
!= LDB_SUCCESS
) {
2235 talloc_free(mem_ctx
);
2236 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2240 py_ret
= PyLdbResult_FromResult(res
);
2242 talloc_free(mem_ctx
);
2247 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply
*reply
)
2249 if (reply
->py_iter
!= NULL
) {
2250 DLIST_REMOVE(reply
->py_iter
->state
.next
, reply
);
2251 if (reply
->py_iter
->state
.result
== reply
) {
2252 reply
->py_iter
->state
.result
= NULL
;
2254 reply
->py_iter
= NULL
;
2257 Py_CLEAR(reply
->obj
);
2262 static int py_ldb_search_iterator_callback(struct ldb_request
*req
,
2263 struct ldb_reply
*ares
)
2265 PyLdbSearchIteratorObject
*py_iter
= (PyLdbSearchIteratorObject
*)req
->context
;
2266 struct ldb_result result
= { .msgs
= NULL
};
2267 struct py_ldb_search_iterator_reply
*reply
= NULL
;
2270 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2273 if (ares
->error
!= LDB_SUCCESS
) {
2274 int ret
= ares
->error
;
2276 return ldb_request_done(req
, ret
);
2279 reply
= talloc_zero(py_iter
->mem_ctx
,
2280 struct py_ldb_search_iterator_reply
);
2281 if (reply
== NULL
) {
2283 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2285 reply
->py_iter
= py_iter
;
2286 talloc_set_destructor(reply
, py_ldb_search_iterator_reply_destructor
);
2288 switch (ares
->type
) {
2289 case LDB_REPLY_ENTRY
:
2290 reply
->obj
= PyLdbMessage_FromMessage(ares
->message
);
2291 if (reply
->obj
== NULL
) {
2293 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2295 DLIST_ADD_END(py_iter
->state
.next
, reply
);
2299 case LDB_REPLY_REFERRAL
:
2300 reply
->obj
= PyUnicode_FromString(ares
->referral
);
2301 if (reply
->obj
== NULL
) {
2303 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2305 DLIST_ADD_END(py_iter
->state
.next
, reply
);
2309 case LDB_REPLY_DONE
:
2310 result
= (struct ldb_result
) { .controls
= ares
->controls
};
2311 reply
->obj
= PyLdbResult_FromResult(&result
);
2312 if (reply
->obj
== NULL
) {
2314 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2316 py_iter
->state
.result
= reply
;
2318 return ldb_request_done(req
, LDB_SUCCESS
);
2322 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2325 static PyObject
*py_ldb_search_iterator(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
2327 PyObject
*py_base
= Py_None
;
2328 int scope
= LDB_SCOPE_DEFAULT
;
2331 PyObject
*py_attrs
= Py_None
;
2332 PyObject
*py_controls
= Py_None
;
2333 const char * const kwnames
[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL
};
2336 struct ldb_context
*ldb_ctx
;
2337 struct ldb_control
**parsed_controls
;
2338 struct ldb_dn
*base
;
2339 PyLdbSearchIteratorObject
*py_iter
;
2341 /* type "int" rather than "enum" for "scope" is intentional */
2342 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OizOOi",
2343 discard_const_p(char *, kwnames
),
2344 &py_base
, &scope
, &expr
, &py_attrs
, &py_controls
, &timeout
))
2347 py_iter
= (PyLdbSearchIteratorObject
*)PyLdbSearchIterator
.tp_alloc(&PyLdbSearchIterator
, 0);
2348 if (py_iter
== NULL
) {
2352 py_iter
->ldb
= self
;
2354 ZERO_STRUCT(py_iter
->state
);
2355 py_iter
->mem_ctx
= talloc_new(NULL
);
2356 if (py_iter
->mem_ctx
== NULL
) {
2362 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2364 if (py_attrs
== Py_None
) {
2367 attrs
= PyList_AsStrList(py_iter
->mem_ctx
, py_attrs
, "attrs");
2368 if (attrs
== NULL
) {
2375 if (py_base
== Py_None
) {
2376 base
= ldb_get_default_basedn(ldb_ctx
);
2378 if (!pyldb_Object_AsDn(py_iter
->mem_ctx
, py_base
, ldb_ctx
, &base
)) {
2385 if (py_controls
== Py_None
) {
2386 parsed_controls
= NULL
;
2388 const char **controls
= NULL
;
2390 controls
= PyList_AsStrList(py_iter
->mem_ctx
,
2391 py_controls
, "controls");
2392 if (controls
== NULL
) {
2398 parsed_controls
= ldb_parse_control_strings(ldb_ctx
,
2401 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
2403 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
2406 talloc_free(controls
);
2409 ret
= ldb_build_search_req(&py_iter
->state
.req
,
2418 py_ldb_search_iterator_callback
,
2420 if (ret
!= LDB_SUCCESS
) {
2422 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2426 ldb_set_timeout(ldb_ctx
, py_iter
->state
.req
, timeout
);
2428 ret
= ldb_request(ldb_ctx
, py_iter
->state
.req
);
2429 if (ret
!= LDB_SUCCESS
) {
2431 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2435 return (PyObject
*)py_iter
;
2438 static PyObject
*py_ldb_get_opaque(PyLdbObject
*self
, PyObject
*args
)
2443 if (!PyArg_ParseTuple(args
, "s", &name
))
2446 data
= ldb_get_opaque(pyldb_Ldb_AS_LDBCONTEXT(self
), name
);
2451 /* FIXME: More interpretation */
2456 static PyObject
*py_ldb_set_opaque(PyLdbObject
*self
, PyObject
*args
)
2461 if (!PyArg_ParseTuple(args
, "sO", &name
, &data
))
2464 /* FIXME: More interpretation */
2466 ldb_set_opaque(pyldb_Ldb_AS_LDBCONTEXT(self
), name
, data
);
2471 static PyObject
*py_ldb_modules(PyLdbObject
*self
,
2472 PyObject
*Py_UNUSED(ignored
))
2474 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2475 PyObject
*ret
= PyList_New(0);
2476 struct ldb_module
*mod
;
2479 return PyErr_NoMemory();
2481 for (mod
= ldb
->modules
; mod
; mod
= mod
->next
) {
2482 PyObject
*item
= PyLdbModule_FromModule(mod
);
2485 PyErr_SetString(PyExc_RuntimeError
,
2486 "Failed to load LdbModule");
2490 res
= PyList_Append(ret
, item
);
2501 static PyObject
*py_ldb_sequence_number(PyLdbObject
*self
, PyObject
*args
)
2503 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2507 if (!PyArg_ParseTuple(args
, "i", &type
))
2510 /* FIXME: More interpretation */
2512 ret
= ldb_sequence_number(ldb
, type
, &value
);
2514 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2516 return PyLong_FromLongLong(value
);
2519 static PyObject
*py_ldb_whoami(PyLdbObject
*self
, PyObject
*args
)
2521 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2522 struct ldb_result
*res
= NULL
;
2523 struct ldb_extended
*ext_res
= NULL
;
2527 ret
= ldb_extended(ldb
, LDB_EXTENDED_WHOAMI_OID
, NULL
, &res
);
2528 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2530 ext_res
= res
->extended
;
2531 if (ext_res
== NULL
) {
2532 PyErr_SetString(PyExc_TypeError
, "Got no exop reply");
2536 if (strcmp(ext_res
->oid
, LDB_EXTENDED_WHOAMI_OID
) != 0) {
2537 PyErr_SetString(PyExc_TypeError
, "Got wrong reply OID");
2541 len
= talloc_get_size(ext_res
->data
);
2546 return PyUnicode_FromStringAndSize(ext_res
->data
, len
);
2550 static const struct ldb_dn_extended_syntax test_dn_syntax
= {
2552 .read_fn
= ldb_handler_copy
,
2553 .write_clear_fn
= ldb_handler_copy
,
2554 .write_hex_fn
= ldb_handler_copy
,
2557 static PyObject
*py_ldb_register_test_extensions(PyLdbObject
*self
,
2558 PyObject
*Py_UNUSED(ignored
))
2560 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2563 ret
= ldb_dn_extended_add_syntax(ldb
, LDB_ATTR_FLAG_FIXED
, &test_dn_syntax
);
2565 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2571 static PyMethodDef py_ldb_methods
[] = {
2572 { "set_debug", (PyCFunction
)py_ldb_set_debug
, METH_VARARGS
,
2573 "S.set_debug(callback) -> None\n"
2574 "Set callback for LDB debug messages.\n"
2575 "The callback should accept a debug level and debug text." },
2576 { "set_create_perms", (PyCFunction
)py_ldb_set_create_perms
, METH_VARARGS
,
2577 "S.set_create_perms(mode) -> None\n"
2578 "Set mode to use when creating new LDB files." },
2579 { "set_modules_dir", (PyCFunction
)py_ldb_set_modules_dir
, METH_VARARGS
,
2580 "S.set_modules_dir(path) -> None\n"
2581 "Set path LDB should search for modules" },
2582 { "transaction_start", (PyCFunction
)py_ldb_transaction_start
, METH_NOARGS
,
2583 "S.transaction_start() -> None\n"
2584 "Start a new transaction." },
2585 { "transaction_prepare_commit", (PyCFunction
)py_ldb_transaction_prepare_commit
, METH_NOARGS
,
2586 "S.transaction_prepare_commit() -> None\n"
2587 "prepare to commit a new transaction (2-stage commit)." },
2588 { "transaction_commit", (PyCFunction
)py_ldb_transaction_commit
, METH_NOARGS
,
2589 "S.transaction_commit() -> None\n"
2590 "commit a new transaction." },
2591 { "transaction_cancel", (PyCFunction
)py_ldb_transaction_cancel
, METH_NOARGS
,
2592 "S.transaction_cancel() -> None\n"
2593 "cancel a new transaction." },
2594 { "setup_wellknown_attributes", (PyCFunction
)py_ldb_setup_wellknown_attributes
, METH_NOARGS
,
2596 { "get_root_basedn", (PyCFunction
)py_ldb_get_root_basedn
, METH_NOARGS
,
2598 { "get_schema_basedn", (PyCFunction
)py_ldb_get_schema_basedn
, METH_NOARGS
,
2600 { "get_default_basedn", (PyCFunction
)py_ldb_get_default_basedn
, METH_NOARGS
,
2602 { "get_config_basedn", (PyCFunction
)py_ldb_get_config_basedn
, METH_NOARGS
,
2604 { "connect", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_connect
),
2605 METH_VARARGS
|METH_KEYWORDS
,
2606 "S.connect(url, flags=0, options=None) -> None\n"
2607 "Connect to a LDB URL." },
2608 { "modify", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_modify
),
2609 METH_VARARGS
|METH_KEYWORDS
,
2610 "S.modify(message, controls=None, validate=False) -> None\n"
2611 "Modify an entry." },
2612 { "add", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_add
),
2613 METH_VARARGS
|METH_KEYWORDS
,
2614 "S.add(message, controls=None) -> None\n"
2616 { "delete", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_delete
),
2617 METH_VARARGS
|METH_KEYWORDS
,
2618 "S.delete(dn, controls=None) -> None\n"
2619 "Remove an entry." },
2620 { "rename", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_rename
),
2621 METH_VARARGS
|METH_KEYWORDS
,
2622 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2623 "Rename an entry." },
2624 { "search", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_search
),
2625 METH_VARARGS
|METH_KEYWORDS
,
2626 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2627 "Search in a database.\n"
2629 ":param base: Optional base DN to search\n"
2630 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2631 ":param expression: Optional search expression\n"
2632 ":param attrs: Attributes to return (defaults to all)\n"
2633 ":param controls: Optional list of controls\n"
2634 ":return: ldb.Result object\n"
2636 { "search_iterator", PY_DISCARD_FUNC_SIG(PyCFunction
,
2637 py_ldb_search_iterator
),
2638 METH_VARARGS
|METH_KEYWORDS
,
2639 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2640 "Search in a database.\n"
2642 ":param base: Optional base DN to search\n"
2643 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2644 ":param expression: Optional search expression\n"
2645 ":param attrs: Attributes to return (defaults to all)\n"
2646 ":param controls: Optional list of controls\n"
2647 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2648 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2650 { "schema_attribute_remove", (PyCFunction
)py_ldb_schema_attribute_remove
, METH_VARARGS
,
2652 { "schema_attribute_add", (PyCFunction
)py_ldb_schema_attribute_add
, METH_VARARGS
,
2654 { "schema_format_value", (PyCFunction
)py_ldb_schema_format_value
, METH_VARARGS
,
2656 { "parse_ldif", (PyCFunction
)py_ldb_parse_ldif
, METH_VARARGS
,
2657 "S.parse_ldif(ldif) -> iter(messages)\n"
2658 "Parse a string formatted using LDIF." },
2659 { "write_ldif", (PyCFunction
)py_ldb_write_ldif
, METH_VARARGS
,
2660 "S.write_ldif(message, changetype) -> ldif\n"
2661 "Print the message as a string formatted using LDIF." },
2662 { "msg_diff", (PyCFunction
)py_ldb_msg_diff
, METH_VARARGS
,
2663 "S.msg_diff(Message) -> Message\n"
2664 "Return an LDB Message of the difference between two Message objects." },
2665 { "get_opaque", (PyCFunction
)py_ldb_get_opaque
, METH_VARARGS
,
2666 "S.get_opaque(name) -> value\n"
2667 "Get an opaque value set on this LDB connection. \n"
2668 ":note: The returned value may not be useful in Python."
2670 { "set_opaque", (PyCFunction
)py_ldb_set_opaque
, METH_VARARGS
,
2671 "S.set_opaque(name, value) -> None\n"
2672 "Set an opaque value on this LDB connection. \n"
2673 ":note: Passing incorrect values may cause crashes." },
2674 { "modules", (PyCFunction
)py_ldb_modules
, METH_NOARGS
,
2675 "S.modules() -> list\n"
2676 "Return the list of modules on this LDB connection " },
2677 { "sequence_number", (PyCFunction
)py_ldb_sequence_number
, METH_VARARGS
,
2678 "S.sequence_number(type) -> value\n"
2679 "Return the value of the sequence according to the requested type" },
2681 (PyCFunction
)py_ldb_whoami
,
2683 "S.whoami(type) -> value\n"
2684 "Return the RFC4532 whoami string",
2686 { "_register_test_extensions", (PyCFunction
)py_ldb_register_test_extensions
, METH_NOARGS
,
2687 "S._register_test_extensions() -> None\n"
2688 "Register internal extensions used in testing" },
2692 static PyObject
*PyLdbModule_FromModule(struct ldb_module
*mod
)
2694 TALLOC_CTX
*mem_ctx
= NULL
;
2695 struct ldb_module
*mod_ref
= NULL
;
2696 PyLdbModuleObject
*ret
;
2698 mem_ctx
= talloc_new(NULL
);
2699 if (mem_ctx
== NULL
) {
2700 return PyErr_NoMemory();
2703 mod_ref
= talloc_reference(mem_ctx
, mod
);
2704 if (mod_ref
== NULL
) {
2705 talloc_free(mem_ctx
);
2706 return PyErr_NoMemory();
2709 ret
= (PyLdbModuleObject
*)PyLdbModule
.tp_alloc(&PyLdbModule
, 0);
2711 talloc_free(mem_ctx
);
2715 ret
->mem_ctx
= mem_ctx
;
2717 return (PyObject
*)ret
;
2720 static PyObject
*py_ldb_get_firstmodule(PyLdbObject
*self
, void *closure
)
2722 struct ldb_module
*mod
= pyldb_Ldb_AS_LDBCONTEXT(self
)->modules
;
2726 return PyLdbModule_FromModule(mod
);
2729 static PyGetSetDef py_ldb_getset
[] = {
2731 .name
= discard_const_p(char, "firstmodule"),
2732 .get
= (getter
)py_ldb_get_firstmodule
,
2737 static int py_ldb_contains(PyLdbObject
*self
, PyObject
*obj
)
2739 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2741 struct ldb_result
*result
;
2745 if (!pyldb_Object_AsDn(ldb_ctx
, obj
, ldb_ctx
, &dn
)) {
2749 ret
= ldb_search(ldb_ctx
, ldb_ctx
, &result
, dn
, LDB_SCOPE_BASE
, NULL
,
2751 if (ret
!= LDB_SUCCESS
) {
2752 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2756 count
= result
->count
;
2758 talloc_free(result
);
2761 PyErr_Format(PyExc_RuntimeError
,
2762 "Searching for [%s] dn gave %u results!",
2763 ldb_dn_get_linearized(dn
),
2771 static PySequenceMethods py_ldb_seq
= {
2772 .sq_contains
= (objobjproc
)py_ldb_contains
,
2775 static PyObject
*PyLdb_FromLdbContext(struct ldb_context
*ldb_ctx
)
2777 TALLOC_CTX
*mem_ctx
= NULL
;
2778 struct ldb_context
*ldb_ctx_ref
= NULL
;
2781 mem_ctx
= talloc_new(NULL
);
2782 if (mem_ctx
== NULL
) {
2783 return PyErr_NoMemory();
2786 ldb_ctx_ref
= talloc_reference(mem_ctx
, ldb_ctx
);
2787 if (ldb_ctx_ref
== NULL
) {
2788 talloc_free(mem_ctx
);
2789 return PyErr_NoMemory();
2792 ret
= (PyLdbObject
*)PyLdb
.tp_alloc(&PyLdb
, 0);
2794 talloc_free(mem_ctx
);
2798 ret
->mem_ctx
= mem_ctx
;
2799 ret
->ldb_ctx
= ldb_ctx_ref
;
2800 return (PyObject
*)ret
;
2803 static void py_ldb_dealloc(PyLdbObject
*self
)
2805 talloc_free(self
->mem_ctx
);
2806 Py_TYPE(self
)->tp_free(self
);
2809 static PyTypeObject PyLdb
= {
2810 .tp_name
= "ldb.Ldb",
2811 .tp_methods
= py_ldb_methods
,
2812 .tp_repr
= (reprfunc
)py_ldb_repr
,
2813 .tp_new
= py_ldb_new
,
2814 .tp_init
= (initproc
)py_ldb_init
,
2815 .tp_dealloc
= (destructor
)py_ldb_dealloc
,
2816 .tp_getset
= py_ldb_getset
,
2817 .tp_getattro
= PyObject_GenericGetAttr
,
2818 .tp_basicsize
= sizeof(PyLdbObject
),
2819 .tp_doc
= "Connection to a LDB database.",
2820 .tp_as_sequence
= &py_ldb_seq
,
2821 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
2824 static void py_ldb_result_dealloc(PyLdbResultObject
*self
)
2826 talloc_free(self
->mem_ctx
);
2827 Py_CLEAR(self
->msgs
);
2828 Py_CLEAR(self
->referals
);
2829 Py_CLEAR(self
->controls
);
2830 Py_TYPE(self
)->tp_free(self
);
2833 static PyObject
*py_ldb_result_get_msgs(PyLdbResultObject
*self
, void *closure
)
2835 Py_INCREF(self
->msgs
);
2839 static PyObject
*py_ldb_result_get_controls(PyLdbResultObject
*self
, void *closure
)
2841 Py_INCREF(self
->controls
);
2842 return self
->controls
;
2845 static PyObject
*py_ldb_result_get_referals(PyLdbResultObject
*self
, void *closure
)
2847 Py_INCREF(self
->referals
);
2848 return self
->referals
;
2851 static PyObject
*py_ldb_result_get_count(PyLdbResultObject
*self
, void *closure
)
2854 if (self
->msgs
== NULL
) {
2855 PyErr_SetString(PyExc_AttributeError
, "Count attribute is meaningless in this context");
2858 size
= PyList_Size(self
->msgs
);
2859 return PyLong_FromLong(size
);
2862 static PyGetSetDef py_ldb_result_getset
[] = {
2864 .name
= discard_const_p(char, "controls"),
2865 .get
= (getter
)py_ldb_result_get_controls
,
2868 .name
= discard_const_p(char, "msgs"),
2869 .get
= (getter
)py_ldb_result_get_msgs
,
2872 .name
= discard_const_p(char, "referals"),
2873 .get
= (getter
)py_ldb_result_get_referals
,
2876 .name
= discard_const_p(char, "count"),
2877 .get
= (getter
)py_ldb_result_get_count
,
2882 static PyObject
*py_ldb_result_iter(PyLdbResultObject
*self
)
2884 return PyObject_GetIter(self
->msgs
);
2887 static Py_ssize_t
py_ldb_result_len(PyLdbResultObject
*self
)
2889 return PySequence_Size(self
->msgs
);
2892 static PyObject
*py_ldb_result_find(PyLdbResultObject
*self
, Py_ssize_t idx
)
2894 return PySequence_GetItem(self
->msgs
, idx
);
2897 static PySequenceMethods py_ldb_result_seq
= {
2898 .sq_length
= (lenfunc
)py_ldb_result_len
,
2899 .sq_item
= (ssizeargfunc
)py_ldb_result_find
,
2902 static PyObject
*py_ldb_result_repr(PyLdbObject
*self
)
2904 return PyUnicode_FromString("<ldb result>");
2908 static PyTypeObject PyLdbResult
= {
2909 .tp_name
= "ldb.Result",
2910 .tp_repr
= (reprfunc
)py_ldb_result_repr
,
2911 .tp_dealloc
= (destructor
)py_ldb_result_dealloc
,
2912 .tp_iter
= (getiterfunc
)py_ldb_result_iter
,
2913 .tp_getset
= py_ldb_result_getset
,
2914 .tp_getattro
= PyObject_GenericGetAttr
,
2915 .tp_basicsize
= sizeof(PyLdbResultObject
),
2916 .tp_as_sequence
= &py_ldb_result_seq
,
2917 .tp_doc
= "LDB result.",
2918 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
2921 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject
*self
)
2923 Py_CLEAR(self
->state
.exception
);
2924 TALLOC_FREE(self
->mem_ctx
);
2925 ZERO_STRUCT(self
->state
);
2926 Py_CLEAR(self
->ldb
);
2927 Py_TYPE(self
)->tp_free(self
);
2930 static PyObject
*py_ldb_search_iterator_next(PyLdbSearchIteratorObject
*self
)
2932 PyObject
*py_ret
= NULL
;
2934 if (self
->state
.req
== NULL
) {
2935 PyErr_SetString(PyExc_RuntimeError
,
2936 "ldb.SearchIterator request already finished");
2941 * TODO: do we want a non-blocking mode?
2942 * In future we may add an optional 'nonblocking'
2943 * argument to search_iterator().
2945 * For now we keep it simple and wait for at
2949 while (self
->state
.next
== NULL
) {
2952 if (self
->state
.result
!= NULL
) {
2954 * We (already) got a final result from the server.
2956 * We stop the iteration and let
2957 * py_ldb_search_iterator_result() will deliver
2958 * the result details.
2960 TALLOC_FREE(self
->state
.req
);
2961 PyErr_SetNone(PyExc_StopIteration
);
2965 ret
= ldb_wait(self
->state
.req
->handle
, LDB_WAIT_NONE
);
2966 if (ret
!= LDB_SUCCESS
) {
2967 struct ldb_context
*ldb_ctx
;
2968 TALLOC_FREE(self
->state
.req
);
2969 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
->ldb
);
2971 * We stop the iteration and let
2972 * py_ldb_search_iterator_result() will deliver
2975 self
->state
.exception
= Py_BuildValue(discard_const_p(char, "(i,s)"),
2976 ret
, ldb_errstring(ldb_ctx
));
2977 PyErr_SetNone(PyExc_StopIteration
);
2982 py_ret
= self
->state
.next
->obj
;
2983 self
->state
.next
->obj
= NULL
;
2984 /* no TALLOC_FREE() as self->state.next is a list */
2985 talloc_free(self
->state
.next
);
2989 static PyObject
*py_ldb_search_iterator_result(PyLdbSearchIteratorObject
*self
,
2990 PyObject
*Py_UNUSED(ignored
))
2992 PyObject
*py_ret
= NULL
;
2994 if (self
->state
.req
!= NULL
) {
2995 PyErr_SetString(PyExc_RuntimeError
,
2996 "ldb.SearchIterator request running");
3000 if (self
->state
.next
!= NULL
) {
3001 PyErr_SetString(PyExc_RuntimeError
,
3002 "ldb.SearchIterator not fully consumed.");
3006 if (self
->state
.exception
!= NULL
) {
3007 PyErr_SetObject(PyExc_LdbError
, self
->state
.exception
);
3008 self
->state
.exception
= NULL
;
3012 if (self
->state
.result
== NULL
) {
3013 PyErr_SetString(PyExc_RuntimeError
,
3014 "ldb.SearchIterator result already consumed");
3018 py_ret
= self
->state
.result
->obj
;
3019 self
->state
.result
->obj
= NULL
;
3020 TALLOC_FREE(self
->state
.result
);
3024 static PyObject
*py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject
*self
,
3025 PyObject
*Py_UNUSED(ignored
))
3027 if (self
->state
.req
== NULL
) {
3028 PyErr_SetString(PyExc_RuntimeError
,
3029 "ldb.SearchIterator request already finished");
3033 Py_CLEAR(self
->state
.exception
);
3034 TALLOC_FREE(self
->mem_ctx
);
3035 ZERO_STRUCT(self
->state
);
3039 static PyMethodDef py_ldb_search_iterator_methods
[] = {
3040 { "result", (PyCFunction
)py_ldb_search_iterator_result
, METH_NOARGS
,
3041 "S.result() -> ldb.Result (without msgs and referrals)\n" },
3042 { "abandon", (PyCFunction
)py_ldb_search_iterator_abandon
, METH_NOARGS
,
3047 static PyObject
*py_ldb_search_iterator_repr(PyLdbSearchIteratorObject
*self
)
3049 return PyUnicode_FromString("<ldb search iterator>");
3052 static PyTypeObject PyLdbSearchIterator
= {
3053 .tp_name
= "ldb.SearchIterator",
3054 .tp_repr
= (reprfunc
)py_ldb_search_iterator_repr
,
3055 .tp_dealloc
= (destructor
)py_ldb_search_iterator_dealloc
,
3056 .tp_iter
= PyObject_SelfIter
,
3057 .tp_iternext
= (iternextfunc
)py_ldb_search_iterator_next
,
3058 .tp_methods
= py_ldb_search_iterator_methods
,
3059 .tp_basicsize
= sizeof(PyLdbSearchIteratorObject
),
3060 .tp_doc
= "LDB search_iterator.",
3061 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
3064 static PyObject
*py_ldb_module_repr(PyLdbModuleObject
*self
)
3066 return PyUnicode_FromFormat("<ldb module '%s'>",
3067 pyldb_Module_AsModule(self
)->ops
->name
);
3070 static PyObject
*py_ldb_module_str(PyLdbModuleObject
*self
)
3072 return PyUnicode_FromString(pyldb_Module_AsModule(self
)->ops
->name
);
3075 static PyObject
*py_ldb_module_start_transaction(PyLdbModuleObject
*self
,
3076 PyObject
*Py_UNUSED(ignored
))
3078 pyldb_Module_AsModule(self
)->ops
->start_transaction(pyldb_Module_AsModule(self
));
3082 static PyObject
*py_ldb_module_end_transaction(PyLdbModuleObject
*self
,
3083 PyObject
*Py_UNUSED(ignored
))
3085 pyldb_Module_AsModule(self
)->ops
->end_transaction(pyldb_Module_AsModule(self
));
3089 static PyObject
*py_ldb_module_del_transaction(PyLdbModuleObject
*self
,
3090 PyObject
*Py_UNUSED(ignored
))
3092 pyldb_Module_AsModule(self
)->ops
->del_transaction(pyldb_Module_AsModule(self
));
3096 static PyObject
*py_ldb_module_search(PyLdbModuleObject
*self
, PyObject
*args
, PyObject
*kwargs
)
3098 PyObject
*py_base
, *py_tree
, *py_attrs
, *py_ret
;
3100 struct ldb_request
*req
;
3101 const char * const kwnames
[] = { "base", "scope", "tree", "attrs", NULL
};
3102 struct ldb_module
*mod
;
3103 const char * const*attrs
;
3105 /* type "int" rather than "enum" for "scope" is intentional */
3106 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O!iOO",
3107 discard_const_p(char *, kwnames
),
3108 &PyLdbDn
, &py_base
, &scope
, &py_tree
, &py_attrs
))
3113 if (py_attrs
== Py_None
) {
3116 attrs
= PyList_AsStrList(NULL
, py_attrs
, "attrs");
3121 ret
= ldb_build_search_req(&req
, mod
->ldb
, NULL
, pyldb_Dn_AS_DN(py_base
),
3122 scope
, NULL
/* expr */, attrs
,
3123 NULL
/* controls */, NULL
, NULL
, NULL
);
3125 talloc_steal(req
, attrs
);
3127 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, mod
->ldb
);
3129 req
->op
.search
.res
= NULL
;
3131 ret
= mod
->ops
->search(mod
, req
);
3133 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, mod
->ldb
);
3135 py_ret
= PyLdbResult_FromResult(req
->op
.search
.res
);
3143 static PyObject
*py_ldb_module_add(PyLdbModuleObject
*self
, PyObject
*args
)
3145 struct ldb_request
*req
;
3146 PyObject
*py_message
;
3148 struct ldb_module
*mod
;
3150 if (!PyArg_ParseTuple(args
, "O!", &PyLdbMessage
, &py_message
))
3153 req
= talloc_zero(NULL
, struct ldb_request
);
3154 req
->operation
= LDB_ADD
;
3155 req
->op
.add
.message
= pyldb_Message_AsMessage(py_message
);
3157 mod
= pyldb_Module_AsModule(self
);
3158 ret
= mod
->ops
->add(mod
, req
);
3160 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, mod
->ldb
);
3165 static PyObject
*py_ldb_module_modify(PyLdbModuleObject
*self
, PyObject
*args
)
3168 struct ldb_request
*req
;
3169 PyObject
*py_message
;
3170 struct ldb_module
*mod
;
3172 if (!PyArg_ParseTuple(args
, "O!", &PyLdbMessage
, &py_message
))
3175 req
= talloc_zero(NULL
, struct ldb_request
);
3176 req
->operation
= LDB_MODIFY
;
3177 req
->op
.mod
.message
= pyldb_Message_AsMessage(py_message
);
3179 mod
= pyldb_Module_AsModule(self
);
3180 ret
= mod
->ops
->modify(mod
, req
);
3182 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, mod
->ldb
);
3187 static PyObject
*py_ldb_module_delete(PyLdbModuleObject
*self
, PyObject
*args
)
3190 struct ldb_request
*req
;
3193 if (!PyArg_ParseTuple(args
, "O!", &PyLdbDn
, &py_dn
))
3196 req
= talloc_zero(NULL
, struct ldb_request
);
3197 req
->operation
= LDB_DELETE
;
3198 req
->op
.del
.dn
= pyldb_Dn_AS_DN(py_dn
);
3200 ret
= pyldb_Module_AsModule(self
)->ops
->del(pyldb_Module_AsModule(self
), req
);
3202 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
3207 static PyObject
*py_ldb_module_rename(PyLdbModuleObject
*self
, PyObject
*args
)
3210 struct ldb_request
*req
;
3211 PyObject
*py_dn1
, *py_dn2
;
3213 if (!PyArg_ParseTuple(args
, "O!O!", &PyLdbDn
, &py_dn1
, &PyLdbDn
, &py_dn2
))
3216 req
= talloc_zero(NULL
, struct ldb_request
);
3218 req
->operation
= LDB_RENAME
;
3219 req
->op
.rename
.olddn
= pyldb_Dn_AS_DN(py_dn1
);
3220 req
->op
.rename
.newdn
= pyldb_Dn_AS_DN(py_dn2
);
3222 ret
= pyldb_Module_AsModule(self
)->ops
->rename(pyldb_Module_AsModule(self
), req
);
3224 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
3229 static PyMethodDef py_ldb_module_methods
[] = {
3230 { "search", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_module_search
),
3231 METH_VARARGS
|METH_KEYWORDS
, NULL
},
3232 { "add", (PyCFunction
)py_ldb_module_add
, METH_VARARGS
, NULL
},
3233 { "modify", (PyCFunction
)py_ldb_module_modify
, METH_VARARGS
, NULL
},
3234 { "rename", (PyCFunction
)py_ldb_module_rename
, METH_VARARGS
, NULL
},
3235 { "delete", (PyCFunction
)py_ldb_module_delete
, METH_VARARGS
, NULL
},
3236 { "start_transaction", (PyCFunction
)py_ldb_module_start_transaction
, METH_NOARGS
, NULL
},
3237 { "end_transaction", (PyCFunction
)py_ldb_module_end_transaction
, METH_NOARGS
, NULL
},
3238 { "del_transaction", (PyCFunction
)py_ldb_module_del_transaction
, METH_NOARGS
, NULL
},
3242 static void py_ldb_module_dealloc(PyLdbModuleObject
*self
)
3244 talloc_free(self
->mem_ctx
);
3248 static PyTypeObject PyLdbModule
= {
3249 .tp_name
= "ldb.LdbModule",
3250 .tp_methods
= py_ldb_module_methods
,
3251 .tp_repr
= (reprfunc
)py_ldb_module_repr
,
3252 .tp_str
= (reprfunc
)py_ldb_module_str
,
3253 .tp_basicsize
= sizeof(PyLdbModuleObject
),
3254 .tp_dealloc
= (destructor
)py_ldb_module_dealloc
,
3255 .tp_flags
= Py_TPFLAGS_DEFAULT
,
3256 .tp_doc
= "LDB module (extension)",
3261 * Create a ldb_message_element from a Python object.
3263 * This will accept any sequence objects that contains strings, or
3266 * A reference to set_obj might be borrowed.
3268 * @param mem_ctx Memory context
3269 * @param set_obj Python object to convert
3270 * @param flags ldb_message_element flags to set, if a new element is returned
3271 * @param attr_name Name of the attribute to set, if a new element is returned
3272 * @return New ldb_message_element, allocated as child of mem_ctx
3274 static struct ldb_message_element
*PyObject_AsMessageElement(
3275 TALLOC_CTX
*mem_ctx
,
3278 const char *attr_name
)
3280 struct ldb_message_element
*me
;
3281 const char *msg
= NULL
;
3285 if (pyldb_MessageElement_Check(set_obj
)) {
3286 PyLdbMessageElementObject
*set_obj_as_me
= (PyLdbMessageElementObject
*)set_obj
;
3287 /* We have to talloc_reference() the memory context, not the pointer
3288 * which may not actually be it's own context */
3289 if (talloc_reference(mem_ctx
, set_obj_as_me
->mem_ctx
)) {
3290 return pyldb_MessageElement_AsMessageElement(set_obj
);
3295 me
= talloc(mem_ctx
, struct ldb_message_element
);
3301 me
->name
= talloc_strdup(me
, attr_name
);
3302 if (me
->name
== NULL
) {
3308 if (PyBytes_Check(set_obj
) || PyUnicode_Check(set_obj
)) {
3310 me
->values
= talloc_array(me
, struct ldb_val
, me
->num_values
);
3311 if (PyBytes_Check(set_obj
)) {
3313 result
= PyBytes_AsStringAndSize(set_obj
, &_msg
, &size
);
3320 msg
= PyUnicode_AsUTF8AndSize(set_obj
, &size
);
3326 me
->values
[0].data
= talloc_memdup(me
,
3327 (const uint8_t *)msg
,
3329 me
->values
[0].length
= size
;
3330 } else if (PySequence_Check(set_obj
)) {
3332 me
->num_values
= PySequence_Size(set_obj
);
3333 me
->values
= talloc_array(me
, struct ldb_val
, me
->num_values
);
3334 for (i
= 0; i
< me
->num_values
; i
++) {
3335 PyObject
*obj
= PySequence_GetItem(set_obj
, i
);
3336 if (PyBytes_Check(obj
)) {
3338 result
= PyBytes_AsStringAndSize(obj
, &_msg
, &size
);
3344 } else if (PyUnicode_Check(obj
)) {
3345 msg
= PyUnicode_AsUTF8AndSize(obj
, &size
);
3351 PyErr_Format(PyExc_TypeError
,
3352 "Expected string as element %zd in list", i
);
3356 me
->values
[i
].data
= talloc_memdup(me
,
3357 (const uint8_t *)msg
,
3359 me
->values
[i
].length
= size
;
3362 PyErr_Format(PyExc_TypeError
,
3363 "String or List type expected for '%s' attribute", attr_name
);
3372 static PyObject
*ldb_msg_element_to_set(struct ldb_context
*ldb_ctx
,
3373 struct ldb_message_element
*me
)
3378 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
3379 result
= PyList_New(me
->num_values
);
3380 if (result
== NULL
) {
3384 for (i
= 0; i
< me
->num_values
; i
++) {
3385 PyObject
*obj
= NULL
;
3388 obj
= PyObject_FromLdbValue(&me
->values
[i
]);
3394 ret
= PyList_SetItem(result
, i
, obj
);
3405 static PyObject
*py_ldb_msg_element_get(PyLdbMessageElementObject
*self
, PyObject
*args
)
3408 if (!PyArg_ParseTuple(args
, "I", &i
))
3410 if (i
>= pyldb_MessageElement_AsMessageElement(self
)->num_values
)
3413 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self
)->values
[i
]));
3416 static PyObject
*py_ldb_msg_element_flags(PyLdbMessageElementObject
*self
, PyObject
*args
)
3418 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3419 return PyLong_FromLong(el
->flags
);
3422 static PyObject
*py_ldb_msg_element_set_flags(PyLdbMessageElementObject
*self
, PyObject
*args
)
3425 struct ldb_message_element
*el
;
3426 if (!PyArg_ParseTuple(args
, "I", &flags
))
3429 el
= pyldb_MessageElement_AsMessageElement(self
);
3434 static PyMethodDef py_ldb_msg_element_methods
[] = {
3435 { "get", (PyCFunction
)py_ldb_msg_element_get
, METH_VARARGS
, NULL
},
3436 { "set_flags", (PyCFunction
)py_ldb_msg_element_set_flags
, METH_VARARGS
, NULL
},
3437 { "flags", (PyCFunction
)py_ldb_msg_element_flags
, METH_NOARGS
, NULL
},
3441 static Py_ssize_t
py_ldb_msg_element_len(PyLdbMessageElementObject
*self
)
3443 return pyldb_MessageElement_AsMessageElement(self
)->num_values
;
3446 static PyObject
*py_ldb_msg_element_find(PyLdbMessageElementObject
*self
, Py_ssize_t idx
)
3448 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3449 if (idx
< 0 || idx
>= el
->num_values
) {
3450 PyErr_SetString(PyExc_IndexError
, "Out of range");
3453 return PyLdbBytes_FromStringAndSize((char *)el
->values
[idx
].data
, el
->values
[idx
].length
);
3456 static PySequenceMethods py_ldb_msg_element_seq
= {
3457 .sq_length
= (lenfunc
)py_ldb_msg_element_len
,
3458 .sq_item
= (ssizeargfunc
)py_ldb_msg_element_find
,
3461 static PyObject
*py_ldb_msg_element_richcmp(PyObject
*self
, PyObject
*other
, int op
)
3464 if (!pyldb_MessageElement_Check(other
)) {
3465 Py_INCREF(Py_NotImplemented
);
3466 return Py_NotImplemented
;
3468 ret
= ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self
),
3469 pyldb_MessageElement_AsMessageElement(other
));
3470 return richcmp(ret
, op
);
3473 static PyObject
*py_ldb_msg_element_iter(PyLdbMessageElementObject
*self
)
3475 PyObject
*el
= ldb_msg_element_to_set(NULL
,
3476 pyldb_MessageElement_AsMessageElement(self
));
3477 PyObject
*ret
= PyObject_GetIter(el
);
3482 static PyObject
*PyLdbMessageElement_FromMessageElement(struct ldb_message_element
*el
, TALLOC_CTX
*mem_ctx
)
3484 TALLOC_CTX
*ret_mem_ctx
= NULL
;
3485 PyLdbMessageElementObject
*ret
;
3487 ret_mem_ctx
= talloc_new(NULL
);
3488 if (ret_mem_ctx
== NULL
) {
3489 return PyErr_NoMemory();
3492 if (talloc_reference(ret_mem_ctx
, mem_ctx
) == NULL
) {
3493 talloc_free(ret_mem_ctx
);
3498 ret
= PyObject_New(PyLdbMessageElementObject
, &PyLdbMessageElement
);
3500 talloc_free(ret_mem_ctx
);
3504 ret
->mem_ctx
= ret_mem_ctx
;
3506 return (PyObject
*)ret
;
3509 static PyObject
*py_ldb_msg_element_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
3511 PyObject
*py_elements
= NULL
;
3512 struct ldb_message_element
*el
;
3513 unsigned int flags
= 0;
3515 const char * const kwnames
[] = { "elements", "flags", "name", NULL
};
3516 PyLdbMessageElementObject
*ret
;
3517 TALLOC_CTX
*mem_ctx
;
3518 const char *msg
= NULL
;
3522 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OIs",
3523 discard_const_p(char *, kwnames
),
3524 &py_elements
, &flags
, &name
))
3527 mem_ctx
= talloc_new(NULL
);
3528 if (mem_ctx
== NULL
) {
3533 el
= talloc_zero(mem_ctx
, struct ldb_message_element
);
3536 talloc_free(mem_ctx
);
3540 if (py_elements
!= NULL
) {
3542 if (PyBytes_Check(py_elements
) || PyUnicode_Check(py_elements
)) {
3545 el
->values
= talloc_array(el
, struct ldb_val
, 1);
3546 if (el
->values
== NULL
) {
3547 talloc_free(mem_ctx
);
3551 if (PyBytes_Check(py_elements
)) {
3552 result
= PyBytes_AsStringAndSize(py_elements
, &_msg
, &size
);
3555 msg
= PyUnicode_AsUTF8AndSize(py_elements
, &size
);
3556 result
= (msg
== NULL
) ? -1 : 0;
3559 talloc_free(mem_ctx
);
3562 el
->values
[0].data
= talloc_memdup(el
->values
,
3563 (const uint8_t *)msg
, size
+ 1);
3564 el
->values
[0].length
= size
;
3565 } else if (PySequence_Check(py_elements
)) {
3566 el
->num_values
= PySequence_Size(py_elements
);
3567 el
->values
= talloc_array(el
, struct ldb_val
, el
->num_values
);
3568 if (el
->values
== NULL
) {
3569 talloc_free(mem_ctx
);
3573 for (i
= 0; i
< el
->num_values
; i
++) {
3574 PyObject
*item
= PySequence_GetItem(py_elements
, i
);
3576 talloc_free(mem_ctx
);
3579 if (PyBytes_Check(item
)) {
3581 result
= PyBytes_AsStringAndSize(item
, &_msg
, &size
);
3583 } else if (PyUnicode_Check(item
)) {
3584 msg
= PyUnicode_AsUTF8AndSize(item
, &size
);
3585 result
= (msg
== NULL
) ? -1 : 0;
3587 PyErr_Format(PyExc_TypeError
,
3588 "Expected string as element %zd in list", i
);
3592 talloc_free(mem_ctx
);
3595 el
->values
[i
].data
= talloc_memdup(el
,
3596 (const uint8_t *)msg
, size
+1);
3597 el
->values
[i
].length
= size
;
3600 PyErr_SetString(PyExc_TypeError
,
3601 "Expected string or list");
3602 talloc_free(mem_ctx
);
3609 el
->name
= talloc_strdup(el
, name
);
3610 if (el
->name
== NULL
) {
3611 talloc_free(mem_ctx
);
3612 return PyErr_NoMemory();
3616 ret
= PyObject_New(PyLdbMessageElementObject
, type
);
3618 talloc_free(mem_ctx
);
3622 ret
->mem_ctx
= mem_ctx
;
3624 return (PyObject
*)ret
;
3627 static PyObject
*py_ldb_msg_element_repr(PyLdbMessageElementObject
*self
)
3629 char *element_str
= NULL
;
3631 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3632 PyObject
*ret
, *repr
;
3634 for (i
= 0; i
< el
->num_values
; i
++) {
3635 PyObject
*o
= py_ldb_msg_element_find(self
, i
);
3636 repr
= PyObject_Repr(o
);
3637 if (element_str
== NULL
)
3638 element_str
= talloc_strdup(NULL
, PyUnicode_AsUTF8(repr
));
3640 element_str
= talloc_asprintf_append(element_str
, ",%s", PyUnicode_AsUTF8(repr
));
3643 if (element_str
== NULL
) {
3644 return PyErr_NoMemory();
3648 if (element_str
!= NULL
) {
3649 ret
= PyUnicode_FromFormat("MessageElement([%s])", element_str
);
3650 talloc_free(element_str
);
3652 ret
= PyUnicode_FromString("MessageElement([])");
3658 static PyObject
*py_ldb_msg_element_str(PyLdbMessageElementObject
*self
)
3660 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3662 if (el
->num_values
== 1)
3663 return PyUnicode_FromStringAndSize((char *)el
->values
[0].data
, el
->values
[0].length
);
3668 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject
*self
)
3670 talloc_free(self
->mem_ctx
);
3674 static PyObject
*py_ldb_msg_element_get_text(PyObject
*self
, void *closure
)
3676 return wrap_text("MessageElementTextWrapper", self
);
3679 static PyGetSetDef py_ldb_msg_element_getset
[] = {
3681 .name
= discard_const_p(char, "text"),
3682 .get
= (getter
)py_ldb_msg_element_get_text
,
3687 static PyTypeObject PyLdbMessageElement
= {
3688 .tp_name
= "ldb.MessageElement",
3689 .tp_basicsize
= sizeof(PyLdbMessageElementObject
),
3690 .tp_dealloc
= (destructor
)py_ldb_msg_element_dealloc
,
3691 .tp_repr
= (reprfunc
)py_ldb_msg_element_repr
,
3692 .tp_str
= (reprfunc
)py_ldb_msg_element_str
,
3693 .tp_methods
= py_ldb_msg_element_methods
,
3694 .tp_getset
= py_ldb_msg_element_getset
,
3695 .tp_richcompare
= (richcmpfunc
)py_ldb_msg_element_richcmp
,
3696 .tp_iter
= (getiterfunc
)py_ldb_msg_element_iter
,
3697 .tp_as_sequence
= &py_ldb_msg_element_seq
,
3698 .tp_new
= py_ldb_msg_element_new
,
3699 .tp_flags
= Py_TPFLAGS_DEFAULT
,
3700 .tp_doc
= "An element of a Message",
3704 static PyObject
*py_ldb_msg_from_dict(PyTypeObject
*type
, PyObject
*args
)
3709 struct ldb_message
*msg
;
3710 struct ldb_context
*ldb_ctx
;
3711 unsigned int mod_flags
= LDB_FLAG_MOD_REPLACE
;
3713 if (!PyArg_ParseTuple(args
, "O!O!|I",
3714 &PyLdb
, &py_ldb
, &PyDict_Type
, &py_dict
,
3719 if (!PyLdb_Check(py_ldb
)) {
3720 PyErr_SetString(PyExc_TypeError
, "Expected Ldb");
3724 /* mask only flags we are going to use */
3725 mod_flags
= LDB_FLAG_MOD_TYPE(mod_flags
);
3727 PyErr_SetString(PyExc_ValueError
,
3728 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3729 " expected as mod_flag value");
3733 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(py_ldb
);
3735 msg
= PyDict_AsMessage(ldb_ctx
, py_dict
, ldb_ctx
, mod_flags
);
3740 py_ret
= PyLdbMessage_FromMessage(msg
);
3742 talloc_unlink(ldb_ctx
, msg
);
3747 static PyObject
*py_ldb_msg_remove_attr(PyLdbMessageObject
*self
, PyObject
*args
)
3750 if (!PyArg_ParseTuple(args
, "s", &name
))
3753 ldb_msg_remove_attr(self
->msg
, name
);
3758 static PyObject
*py_ldb_msg_keys(PyLdbMessageObject
*self
,
3759 PyObject
*Py_UNUSED(ignored
))
3761 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3762 Py_ssize_t i
, j
= 0;
3763 PyObject
*obj
= PyList_New(msg
->num_elements
+(msg
->dn
!= NULL
?1:0));
3768 if (msg
->dn
!= NULL
) {
3769 PyObject
*py_dn
= NULL
;
3772 py_dn
= PyUnicode_FromString("dn");
3773 if (py_dn
== NULL
) {
3778 ret
= PyList_SetItem(obj
, j
, py_dn
);
3787 for (i
= 0; i
< msg
->num_elements
; i
++) {
3788 PyObject
*py_name
= NULL
;
3791 py_name
= PyUnicode_FromString(msg
->elements
[i
].name
);
3792 if (py_name
== NULL
) {
3797 ret
= PyList_SetItem(obj
, j
, py_name
);
3809 static int py_ldb_msg_contains(PyLdbMessageObject
*self
, PyObject
*py_name
)
3811 struct ldb_message_element
*el
= NULL
;
3812 const char *name
= NULL
;
3813 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3814 name
= PyUnicode_AsUTF8(py_name
);
3818 if (!ldb_attr_cmp(name
, "dn")) {
3821 el
= ldb_msg_find_element(msg
, name
);
3822 return el
!= NULL
? 1 : 0;
3825 static PyObject
*py_ldb_msg_getitem(PyLdbMessageObject
*self
, PyObject
*py_name
)
3827 struct ldb_message_element
*el
= NULL
;
3828 const char *name
= NULL
;
3829 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3830 name
= PyUnicode_AsUTF8(py_name
);
3834 if (!ldb_attr_cmp(name
, "dn")) {
3835 return pyldb_Dn_FromDn(msg
->dn
);
3837 el
= ldb_msg_find_element(msg
, name
);
3839 PyErr_SetString(PyExc_KeyError
, "No such element");
3843 return PyLdbMessageElement_FromMessageElement(el
, msg
->elements
);
3846 static PyObject
*py_ldb_msg_get(PyLdbMessageObject
*self
, PyObject
*args
, PyObject
*kwargs
)
3848 PyObject
*def
= NULL
;
3849 const char *kwnames
[] = { "name", "default", "idx", NULL
};
3850 const char *name
= NULL
;
3852 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3853 struct ldb_message_element
*el
;
3855 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|Oi:msg",
3856 discard_const_p(char *, kwnames
), &name
, &def
, &idx
)) {
3860 if (strcasecmp(name
, "dn") == 0) {
3861 return pyldb_Dn_FromDn(msg
->dn
);
3864 el
= ldb_msg_find_element(msg
, name
);
3866 if (el
== NULL
|| (idx
!= -1 && el
->num_values
<= idx
)) {
3875 return (PyObject
*)PyLdbMessageElement_FromMessageElement(el
, msg
->elements
);
3878 return PyObject_FromLdbValue(&el
->values
[idx
]);
3881 static PyObject
*py_ldb_msg_items(PyLdbMessageObject
*self
,
3882 PyObject
*Py_UNUSED(ignored
))
3884 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3885 Py_ssize_t i
, j
= 0;
3886 PyObject
*l
= PyList_New(msg
->num_elements
+ (msg
->dn
== NULL
?0:1));
3888 return PyErr_NoMemory();
3890 if (msg
->dn
!= NULL
) {
3891 PyObject
*value
= NULL
;
3892 PyObject
*obj
= pyldb_Dn_FromDn(msg
->dn
);
3894 value
= Py_BuildValue("(sO)", "dn", obj
);
3896 if (value
== NULL
) {
3900 res
= PyList_SetItem(l
, 0, value
);
3907 for (i
= 0; i
< msg
->num_elements
; i
++, j
++) {
3908 PyObject
*value
= NULL
;
3909 PyObject
*py_el
= PyLdbMessageElement_FromMessageElement(&msg
->elements
[i
], msg
->elements
);
3911 value
= Py_BuildValue("(sO)", msg
->elements
[i
].name
, py_el
);
3913 if (value
== NULL
) {
3917 res
= PyList_SetItem(l
, j
, value
);
3926 static PyObject
*py_ldb_msg_elements(PyLdbMessageObject
*self
,
3927 PyObject
*Py_UNUSED(ignored
))
3929 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3931 PyObject
*l
= PyList_New(msg
->num_elements
);
3935 for (i
= 0; i
< msg
->num_elements
; i
++) {
3936 PyObject
*msg_el
= NULL
;
3939 msg_el
= PyLdbMessageElement_FromMessageElement(&msg
->elements
[i
], msg
->elements
);
3940 if (msg_el
== NULL
) {
3945 ret
= PyList_SetItem(l
, i
, msg_el
);
3955 static PyObject
*py_ldb_msg_add(PyLdbMessageObject
*self
, PyObject
*args
)
3957 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3958 PyLdbMessageElementObject
*py_element
;
3960 struct ldb_message_element
*el
;
3961 struct ldb_message_element
*el_new
;
3963 if (!PyArg_ParseTuple(args
, "O!", &PyLdbMessageElement
, &py_element
))
3966 el
= py_element
->el
;
3968 PyErr_SetString(PyExc_ValueError
, "Invalid MessageElement object");
3971 if (el
->name
== NULL
) {
3972 PyErr_SetString(PyExc_ValueError
,
3973 "The element has no name");
3976 ret
= ldb_msg_add_empty(msg
, el
->name
, el
->flags
, &el_new
);
3977 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
3979 /* now deep copy all attribute values */
3980 el_new
->values
= talloc_array(msg
->elements
, struct ldb_val
, el
->num_values
);
3981 if (el_new
->values
== NULL
) {
3985 el_new
->num_values
= el
->num_values
;
3987 for (i
= 0; i
< el
->num_values
; i
++) {
3988 el_new
->values
[i
] = ldb_val_dup(el_new
->values
, &el
->values
[i
]);
3989 if (el_new
->values
[i
].data
== NULL
3990 && el
->values
[i
].length
!= 0) {
3999 static PyMethodDef py_ldb_msg_methods
[] = {
4000 { "from_dict", (PyCFunction
)py_ldb_msg_from_dict
, METH_CLASS
| METH_VARARGS
,
4001 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
4002 "Class method to create ldb.Message object from Dictionary.\n"
4003 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
4004 { "keys", (PyCFunction
)py_ldb_msg_keys
, METH_NOARGS
,
4005 "S.keys() -> list\n\n"
4006 "Return sequence of all attribute names." },
4007 { "remove", (PyCFunction
)py_ldb_msg_remove_attr
, METH_VARARGS
,
4008 "S.remove(name)\n\n"
4009 "Remove all entries for attributes with the specified name."},
4010 { "get", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_msg_get
),
4011 METH_VARARGS
| METH_KEYWORDS
,
4012 "msg.get(name,default=None,idx=None) -> string\n"
4013 "idx is the index into the values array\n"
4014 "if idx is None, then a list is returned\n"
4015 "if idx is not None, then the element with that index is returned\n"
4016 "if you pass the special name 'dn' then the DN object is returned\n"},
4017 { "items", (PyCFunction
)py_ldb_msg_items
, METH_NOARGS
, NULL
},
4018 { "elements", (PyCFunction
)py_ldb_msg_elements
, METH_NOARGS
, NULL
},
4019 { "add", (PyCFunction
)py_ldb_msg_add
, METH_VARARGS
,
4020 "S.add(element)\n\n"
4021 "Add an element to this message." },
4025 static PyObject
*py_ldb_msg_iter(PyLdbMessageObject
*self
)
4027 PyObject
*list
, *iter
;
4029 list
= py_ldb_msg_keys(self
, NULL
);
4030 iter
= PyObject_GetIter(list
);
4035 static int py_ldb_msg_setitem(PyLdbMessageObject
*self
, PyObject
*name
, PyObject
*value
)
4037 const char *attr_name
;
4039 attr_name
= PyUnicode_AsUTF8(name
);
4040 if (attr_name
== NULL
) {
4041 PyErr_SetNone(PyExc_TypeError
);
4045 if (value
== NULL
) {
4047 ldb_msg_remove_attr(self
->msg
, attr_name
);
4050 struct ldb_message_element
*el
= PyObject_AsMessageElement(self
->msg
,
4051 value
, 0, attr_name
);
4055 if (el
->name
== NULL
) {
4057 * If ‘value’ is a MessageElement,
4058 * PyObject_AsMessageElement() will have returned a
4059 * reference to it without setting the name. We don’t
4060 * want to modify the original object to set the name
4061 * ourselves, but making a copy would result in
4062 * different behaviour for a caller relying on a
4063 * reference being kept. Rather than continue with a
4064 * NULL name (and probably fail later on), let’s catch
4065 * this potential mistake early.
4067 PyErr_SetString(PyExc_ValueError
, "MessageElement has no name set");
4068 talloc_unlink(self
->msg
, el
);
4071 ldb_msg_remove_attr(pyldb_Message_AsMessage(self
), attr_name
);
4072 ret
= ldb_msg_add(pyldb_Message_AsMessage(self
), el
, el
->flags
);
4073 if (ret
!= LDB_SUCCESS
) {
4074 PyErr_SetLdbError(PyExc_LdbError
, ret
, NULL
);
4075 talloc_unlink(self
->msg
, el
);
4082 static Py_ssize_t
py_ldb_msg_length(PyLdbMessageObject
*self
)
4084 return pyldb_Message_AsMessage(self
)->num_elements
;
4087 static PySequenceMethods py_ldb_msg_sequence
= {
4088 .sq_contains
= (objobjproc
)py_ldb_msg_contains
,
4091 static PyMappingMethods py_ldb_msg_mapping
= {
4092 .mp_length
= (lenfunc
)py_ldb_msg_length
,
4093 .mp_subscript
= (binaryfunc
)py_ldb_msg_getitem
,
4094 .mp_ass_subscript
= (objobjargproc
)py_ldb_msg_setitem
,
4097 static PyObject
*py_ldb_msg_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
4099 const char * const kwnames
[] = { "dn", NULL
};
4100 struct ldb_message
*ret
;
4101 TALLOC_CTX
*mem_ctx
;
4102 PyObject
*pydn
= NULL
;
4103 PyLdbMessageObject
*py_ret
;
4105 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|O",
4106 discard_const_p(char *, kwnames
),
4110 mem_ctx
= talloc_new(NULL
);
4111 if (mem_ctx
== NULL
) {
4116 ret
= ldb_msg_new(mem_ctx
);
4118 talloc_free(mem_ctx
);
4125 if (!pyldb_Object_AsDn(NULL
, pydn
, NULL
, &dn
)) {
4126 talloc_free(mem_ctx
);
4129 ret
->dn
= talloc_reference(ret
, dn
);
4130 if (ret
->dn
== NULL
) {
4131 talloc_free(mem_ctx
);
4132 return PyErr_NoMemory();
4136 py_ret
= (PyLdbMessageObject
*)type
->tp_alloc(type
, 0);
4137 if (py_ret
== NULL
) {
4139 talloc_free(mem_ctx
);
4143 py_ret
->mem_ctx
= mem_ctx
;
4145 return (PyObject
*)py_ret
;
4148 static PyObject
*PyLdbMessage_FromMessage(struct ldb_message
*msg
)
4150 TALLOC_CTX
*mem_ctx
= NULL
;
4151 struct ldb_message
*msg_ref
= NULL
;
4152 PyLdbMessageObject
*ret
;
4154 mem_ctx
= talloc_new(NULL
);
4155 if (mem_ctx
== NULL
) {
4156 return PyErr_NoMemory();
4159 msg_ref
= talloc_reference(mem_ctx
, msg
);
4160 if (msg_ref
== NULL
) {
4161 talloc_free(mem_ctx
);
4162 return PyErr_NoMemory();
4165 ret
= (PyLdbMessageObject
*)PyLdbMessage
.tp_alloc(&PyLdbMessage
, 0);
4167 talloc_free(mem_ctx
);
4171 ret
->mem_ctx
= mem_ctx
;
4173 return (PyObject
*)ret
;
4176 static PyObject
*py_ldb_msg_get_dn(PyLdbMessageObject
*self
, void *closure
)
4178 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
4179 return pyldb_Dn_FromDn(msg
->dn
);
4182 static int py_ldb_msg_set_dn(PyLdbMessageObject
*self
, PyObject
*value
, void *closure
)
4184 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
4185 struct ldb_dn
*dn
= NULL
;
4186 if (value
== NULL
) {
4187 PyErr_SetString(PyExc_AttributeError
, "cannot delete dn");
4190 if (!pyldb_Dn_Check(value
)) {
4191 PyErr_SetString(PyExc_TypeError
, "expected dn");
4195 dn
= talloc_reference(msg
, pyldb_Dn_AS_DN(value
));
4205 static PyObject
*py_ldb_msg_get_text(PyObject
*self
, void *closure
)
4207 return wrap_text("MessageTextWrapper", self
);
4210 static PyGetSetDef py_ldb_msg_getset
[] = {
4212 .name
= discard_const_p(char, "dn"),
4213 .get
= (getter
)py_ldb_msg_get_dn
,
4214 .set
= (setter
)py_ldb_msg_set_dn
,
4217 .name
= discard_const_p(char, "text"),
4218 .get
= (getter
)py_ldb_msg_get_text
,
4223 static PyObject
*py_ldb_msg_repr(PyLdbMessageObject
*self
)
4225 PyObject
*dict
= PyDict_New(), *ret
, *repr
;
4226 const char *repr_str
= NULL
;
4230 if (PyDict_Update(dict
, (PyObject
*)self
) != 0) {
4234 repr
= PyObject_Repr(dict
);
4239 repr_str
= PyUnicode_AsUTF8(repr
);
4240 if (repr_str
== NULL
) {
4245 ret
= PyUnicode_FromFormat("Message(%s)", repr_str
);
4251 static void py_ldb_msg_dealloc(PyLdbMessageObject
*self
)
4253 talloc_free(self
->mem_ctx
);
4257 static PyObject
*py_ldb_msg_richcmp(PyLdbMessageObject
*py_msg1
,
4258 PyLdbMessageObject
*py_msg2
, int op
)
4260 struct ldb_message
*msg1
, *msg2
;
4264 if (!PyLdbMessage_Check(py_msg2
)) {
4265 Py_INCREF(Py_NotImplemented
);
4266 return Py_NotImplemented
;
4269 msg1
= pyldb_Message_AsMessage(py_msg1
),
4270 msg2
= pyldb_Message_AsMessage(py_msg2
);
4272 if ((msg1
->dn
!= NULL
) || (msg2
->dn
!= NULL
)) {
4273 ret
= ldb_dn_compare(msg1
->dn
, msg2
->dn
);
4275 return richcmp(ret
, op
);
4279 ret
= msg1
->num_elements
- msg2
->num_elements
;
4281 return richcmp(ret
, op
);
4284 for (i
= 0; i
< msg1
->num_elements
; i
++) {
4285 ret
= ldb_msg_element_compare_name(&msg1
->elements
[i
],
4286 &msg2
->elements
[i
]);
4288 return richcmp(ret
, op
);
4291 ret
= ldb_msg_element_compare(&msg1
->elements
[i
],
4292 &msg2
->elements
[i
]);
4294 return richcmp(ret
, op
);
4298 return richcmp(0, op
);
4301 static PyTypeObject PyLdbMessage
= {
4302 .tp_name
= "ldb.Message",
4303 .tp_methods
= py_ldb_msg_methods
,
4304 .tp_getset
= py_ldb_msg_getset
,
4305 .tp_as_sequence
= &py_ldb_msg_sequence
,
4306 .tp_as_mapping
= &py_ldb_msg_mapping
,
4307 .tp_basicsize
= sizeof(PyLdbMessageObject
),
4308 .tp_dealloc
= (destructor
)py_ldb_msg_dealloc
,
4309 .tp_new
= py_ldb_msg_new
,
4310 .tp_repr
= (reprfunc
)py_ldb_msg_repr
,
4311 .tp_flags
= Py_TPFLAGS_DEFAULT
,
4312 .tp_iter
= (getiterfunc
)py_ldb_msg_iter
,
4313 .tp_richcompare
= (richcmpfunc
)py_ldb_msg_richcmp
,
4314 .tp_doc
= "A LDB Message",
4317 static PyObject
*PyLdbTree_FromTree(struct ldb_parse_tree
*tree
)
4319 TALLOC_CTX
*mem_ctx
= NULL
;
4320 struct ldb_parse_tree
*tree_ref
= NULL
;
4321 PyLdbTreeObject
*ret
;
4323 mem_ctx
= talloc_new(NULL
);
4324 if (mem_ctx
== NULL
) {
4325 return PyErr_NoMemory();
4328 tree_ref
= talloc_reference(mem_ctx
, tree
);
4329 if (tree_ref
== NULL
) {
4330 talloc_free(mem_ctx
);
4331 return PyErr_NoMemory();
4334 ret
= (PyLdbTreeObject
*)PyLdbTree
.tp_alloc(&PyLdbTree
, 0);
4336 talloc_free(mem_ctx
);
4341 ret
->mem_ctx
= mem_ctx
;
4342 ret
->tree
= tree_ref
;
4343 return (PyObject
*)ret
;
4346 static void py_ldb_tree_dealloc(PyLdbTreeObject
*self
)
4348 talloc_free(self
->mem_ctx
);
4352 static PyTypeObject PyLdbTree
= {
4353 .tp_name
= "ldb.Tree",
4354 .tp_basicsize
= sizeof(PyLdbTreeObject
),
4355 .tp_dealloc
= (destructor
)py_ldb_tree_dealloc
,
4356 .tp_flags
= Py_TPFLAGS_DEFAULT
,
4357 .tp_doc
= "A search tree",
4361 static int py_module_search(struct ldb_module
*mod
, struct ldb_request
*req
)
4363 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4364 PyObject
*py_result
, *py_base
, *py_attrs
, *py_tree
;
4366 py_base
= pyldb_Dn_FromDn(req
->op
.search
.base
);
4368 if (py_base
== NULL
)
4369 return LDB_ERR_OPERATIONS_ERROR
;
4371 py_tree
= PyLdbTree_FromTree(req
->op
.search
.tree
);
4373 if (py_tree
== NULL
) {
4375 return LDB_ERR_OPERATIONS_ERROR
;
4378 if (req
->op
.search
.attrs
== NULL
) {
4382 for (len
= 0; req
->op
.search
.attrs
[len
]; len
++);
4383 py_attrs
= PyList_New(len
);
4384 if (py_attrs
== NULL
) {
4387 return LDB_ERR_OPERATIONS_ERROR
;
4389 for (i
= 0; i
< len
; i
++) {
4390 PyObject
*py_attr
= NULL
;
4393 py_attr
= PyUnicode_FromString(req
->op
.search
.attrs
[i
]);
4394 if (py_attr
== NULL
) {
4397 Py_DECREF(py_attrs
);
4398 return LDB_ERR_OPERATIONS_ERROR
;
4401 ret
= PyList_SetItem(py_attrs
, i
, py_attr
);
4406 Py_DECREF(py_attrs
);
4407 return LDB_ERR_OPERATIONS_ERROR
;
4412 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "search"),
4413 discard_const_p(char, "OiOO"),
4414 py_base
, req
->op
.search
.scope
, py_tree
, py_attrs
);
4416 Py_DECREF(py_attrs
);
4420 if (py_result
== NULL
) {
4421 return LDB_ERR_PYTHON_EXCEPTION
;
4424 req
->op
.search
.res
= PyLdbResult_AsResult(NULL
, py_result
);
4425 if (req
->op
.search
.res
== NULL
) {
4426 Py_DECREF(py_result
);
4427 return LDB_ERR_PYTHON_EXCEPTION
;
4430 Py_DECREF(py_result
);
4435 static int py_module_add(struct ldb_module
*mod
, struct ldb_request
*req
)
4437 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4438 PyObject
*py_result
, *py_msg
;
4440 py_msg
= PyLdbMessage_FromMessage(discard_const_p(struct ldb_message
, req
->op
.add
.message
));
4442 if (py_msg
== NULL
) {
4443 return LDB_ERR_OPERATIONS_ERROR
;
4446 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "add"),
4447 discard_const_p(char, "O"),
4452 if (py_result
== NULL
) {
4453 return LDB_ERR_PYTHON_EXCEPTION
;
4456 Py_DECREF(py_result
);
4461 static int py_module_modify(struct ldb_module
*mod
, struct ldb_request
*req
)
4463 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4464 PyObject
*py_result
, *py_msg
;
4466 py_msg
= PyLdbMessage_FromMessage(discard_const_p(struct ldb_message
, req
->op
.mod
.message
));
4468 if (py_msg
== NULL
) {
4469 return LDB_ERR_OPERATIONS_ERROR
;
4472 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "modify"),
4473 discard_const_p(char, "O"),
4478 if (py_result
== NULL
) {
4479 return LDB_ERR_PYTHON_EXCEPTION
;
4482 Py_DECREF(py_result
);
4487 static int py_module_del(struct ldb_module
*mod
, struct ldb_request
*req
)
4489 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4490 PyObject
*py_result
, *py_dn
;
4492 py_dn
= pyldb_Dn_FromDn(req
->op
.del
.dn
);
4495 return LDB_ERR_OPERATIONS_ERROR
;
4497 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "delete"),
4498 discard_const_p(char, "O"),
4502 if (py_result
== NULL
) {
4503 return LDB_ERR_PYTHON_EXCEPTION
;
4506 Py_DECREF(py_result
);
4511 static int py_module_rename(struct ldb_module
*mod
, struct ldb_request
*req
)
4513 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4514 PyObject
*py_result
, *py_olddn
, *py_newdn
;
4516 py_olddn
= pyldb_Dn_FromDn(req
->op
.rename
.olddn
);
4518 if (py_olddn
== NULL
)
4519 return LDB_ERR_OPERATIONS_ERROR
;
4521 py_newdn
= pyldb_Dn_FromDn(req
->op
.rename
.newdn
);
4523 if (py_newdn
== NULL
) {
4524 Py_DECREF(py_olddn
);
4525 return LDB_ERR_OPERATIONS_ERROR
;
4528 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "rename"),
4529 discard_const_p(char, "OO"),
4530 py_olddn
, py_newdn
);
4532 Py_DECREF(py_olddn
);
4533 Py_DECREF(py_newdn
);
4535 if (py_result
== NULL
) {
4536 return LDB_ERR_PYTHON_EXCEPTION
;
4539 Py_DECREF(py_result
);
4544 static int py_module_request(struct ldb_module
*mod
, struct ldb_request
*req
)
4546 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4547 PyObject
*py_result
;
4549 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "request"),
4550 discard_const_p(char, ""));
4552 Py_XDECREF(py_result
);
4554 return LDB_ERR_OPERATIONS_ERROR
;
4557 static int py_module_extended(struct ldb_module
*mod
, struct ldb_request
*req
)
4559 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4560 PyObject
*py_result
;
4562 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "extended"),
4563 discard_const_p(char, ""));
4565 Py_XDECREF(py_result
);
4567 return LDB_ERR_OPERATIONS_ERROR
;
4570 static int py_module_start_transaction(struct ldb_module
*mod
)
4572 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4573 PyObject
*py_result
;
4575 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "start_transaction"),
4576 discard_const_p(char, ""));
4578 if (py_result
== NULL
) {
4579 return LDB_ERR_PYTHON_EXCEPTION
;
4582 Py_DECREF(py_result
);
4587 static int py_module_end_transaction(struct ldb_module
*mod
)
4589 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4590 PyObject
*py_result
;
4592 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "end_transaction"),
4593 discard_const_p(char, ""));
4595 if (py_result
== NULL
) {
4596 return LDB_ERR_PYTHON_EXCEPTION
;
4599 Py_DECREF(py_result
);
4604 static int py_module_del_transaction(struct ldb_module
*mod
)
4606 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4607 PyObject
*py_result
;
4609 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "del_transaction"),
4610 discard_const_p(char, ""));
4612 if (py_result
== NULL
) {
4613 return LDB_ERR_PYTHON_EXCEPTION
;
4616 Py_DECREF(py_result
);
4621 static int py_module_destructor(struct ldb_module
*mod
)
4623 Py_CLEAR(mod
->private_data
);
4627 static int py_module_init(struct ldb_module
*mod
)
4629 PyObject
*py_class
= (PyObject
*)mod
->ops
->private_data
;
4630 PyObject
*py_result
, *py_next
, *py_ldb
;
4632 py_ldb
= PyLdb_FromLdbContext(mod
->ldb
);
4635 return LDB_ERR_OPERATIONS_ERROR
;
4637 py_next
= PyLdbModule_FromModule(mod
->next
);
4639 if (py_next
== NULL
) {
4641 return LDB_ERR_OPERATIONS_ERROR
;
4644 py_result
= PyObject_CallFunction(py_class
, discard_const_p(char, "OO"),
4650 if (py_result
== NULL
) {
4651 return LDB_ERR_PYTHON_EXCEPTION
;
4654 mod
->private_data
= py_result
;
4656 talloc_set_destructor(mod
, py_module_destructor
);
4658 return ldb_next_init(mod
);
4661 static PyObject
*py_register_module(PyObject
*module
, PyObject
*args
)
4664 struct ldb_module_ops
*ops
;
4666 PyObject
*tmp
= NULL
;
4667 const char *name
= NULL
;
4669 if (!PyArg_ParseTuple(args
, "O", &input
))
4672 ops
= talloc_zero(NULL
, struct ldb_module_ops
);
4678 tmp
= PyObject_GetAttrString(input
, discard_const_p(char, "name"));
4683 name
= PyUnicode_AsUTF8(tmp
);
4690 ops
->name
= talloc_strdup(ops
, name
);
4692 if (ops
->name
== NULL
) {
4694 return PyErr_NoMemory();
4697 ops
->private_data
= input
;
4698 ops
->init_context
= py_module_init
;
4699 ops
->search
= py_module_search
;
4700 ops
->add
= py_module_add
;
4701 ops
->modify
= py_module_modify
;
4702 ops
->del
= py_module_del
;
4703 ops
->rename
= py_module_rename
;
4704 ops
->request
= py_module_request
;
4705 ops
->extended
= py_module_extended
;
4706 ops
->start_transaction
= py_module_start_transaction
;
4707 ops
->end_transaction
= py_module_end_transaction
;
4708 ops
->del_transaction
= py_module_del_transaction
;
4710 ret
= ldb_register_module(ops
);
4711 if (ret
!= LDB_SUCCESS
) {
4716 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
4721 static PyObject
*py_timestring(PyObject
*module
, PyObject
*args
)
4723 /* most times "time_t" is a signed integer type with 32 or 64 bit:
4724 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4728 if (!PyArg_ParseTuple(args
, "l", &t_val
))
4730 tresult
= ldb_timestring(NULL
, (time_t) t_val
);
4731 if (tresult
== NULL
) {
4733 * Most likely EOVERFLOW from gmtime()
4735 PyErr_SetFromErrno(PyExc_OSError
);
4738 ret
= PyUnicode_FromString(tresult
);
4739 talloc_free(tresult
);
4743 static PyObject
*py_string_to_time(PyObject
*module
, PyObject
*args
)
4746 if (!PyArg_ParseTuple(args
, "s", &str
))
4749 return PyLong_FromLong(ldb_string_to_time(str
));
4752 static PyObject
*py_valid_attr_name(PyObject
*self
, PyObject
*args
)
4755 if (!PyArg_ParseTuple(args
, "s", &name
))
4757 return PyBool_FromLong(ldb_valid_attr_name(name
));
4761 encode a string using RFC2254 rules
4763 static PyObject
*py_binary_encode(PyObject
*self
, PyObject
*args
)
4765 char *str
, *encoded
;
4766 Py_ssize_t size
= 0;
4770 if (!PyArg_ParseTuple(args
, "s#", &str
, &size
))
4772 val
.data
= (uint8_t *)str
;
4775 encoded
= ldb_binary_encode(NULL
, val
);
4776 if (encoded
== NULL
) {
4777 PyErr_SetString(PyExc_TypeError
, "unable to encode binary string");
4780 ret
= PyUnicode_FromString(encoded
);
4781 talloc_free(encoded
);
4786 decode a string using RFC2254 rules
4788 static PyObject
*py_binary_decode(PyObject
*self
, PyObject
*args
)
4794 if (!PyArg_ParseTuple(args
, "s", &str
))
4797 val
= ldb_binary_decode(NULL
, str
);
4798 if (val
.data
== NULL
) {
4799 PyErr_SetString(PyExc_TypeError
, "unable to decode binary string");
4802 ret
= PyBytes_FromStringAndSize((const char*)val
.data
, val
.length
);
4803 talloc_free(val
.data
);
4807 static PyMethodDef py_ldb_global_methods
[] = {
4808 { "register_module", py_register_module
, METH_VARARGS
,
4809 "S.register_module(module) -> None\n\n"
4810 "Register a LDB module."},
4811 { "timestring", py_timestring
, METH_VARARGS
,
4812 "S.timestring(int) -> string\n\n"
4813 "Generate a LDAP time string from a UNIX timestamp" },
4814 { "string_to_time", py_string_to_time
, METH_VARARGS
,
4815 "S.string_to_time(string) -> int\n\n"
4816 "Parse a LDAP time string into a UNIX timestamp." },
4817 { "valid_attr_name", py_valid_attr_name
, METH_VARARGS
,
4818 "S.valid_attr_name(name) -> bool\n\n"
4819 "Check whether the supplied name is a valid attribute name." },
4820 { "binary_encode", py_binary_encode
, METH_VARARGS
,
4821 "S.binary_encode(string) -> string\n\n"
4822 "Perform a RFC2254 binary encoding on a string" },
4823 { "binary_decode", py_binary_decode
, METH_VARARGS
,
4824 "S.binary_decode(string) -> string\n\n"
4825 "Perform a RFC2254 binary decode on a string" },
4829 #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."
4831 static struct PyModuleDef moduledef
= {
4832 PyModuleDef_HEAD_INIT
,
4834 .m_doc
= MODULE_DOC
,
4836 .m_methods
= py_ldb_global_methods
,
4839 static PyObject
* module_init(void)
4843 PyLdbBytesType
.tp_base
= &PyBytes_Type
;
4844 if (PyType_Ready(&PyLdbBytesType
) < 0) {
4848 if (PyType_Ready(&PyLdbDn
) < 0)
4851 if (PyType_Ready(&PyLdbMessage
) < 0)
4854 if (PyType_Ready(&PyLdbMessageElement
) < 0)
4857 if (PyType_Ready(&PyLdb
) < 0)
4860 if (PyType_Ready(&PyLdbModule
) < 0)
4863 if (PyType_Ready(&PyLdbTree
) < 0)
4866 if (PyType_Ready(&PyLdbResult
) < 0)
4869 if (PyType_Ready(&PyLdbSearchIterator
) < 0)
4872 if (PyType_Ready(&PyLdbControl
) < 0)
4875 m
= PyModule_Create(&moduledef
);
4879 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4881 ADD_LDB_INT(SEQ_HIGHEST_SEQ
);
4882 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP
);
4883 ADD_LDB_INT(SEQ_NEXT
);
4884 ADD_LDB_INT(SCOPE_DEFAULT
);
4885 ADD_LDB_INT(SCOPE_BASE
);
4886 ADD_LDB_INT(SCOPE_ONELEVEL
);
4887 ADD_LDB_INT(SCOPE_SUBTREE
);
4889 ADD_LDB_INT(CHANGETYPE_NONE
);
4890 ADD_LDB_INT(CHANGETYPE_ADD
);
4891 ADD_LDB_INT(CHANGETYPE_DELETE
);
4892 ADD_LDB_INT(CHANGETYPE_MODIFY
);
4893 ADD_LDB_INT(CHANGETYPE_MODRDN
);
4895 ADD_LDB_INT(FLAG_MOD_ADD
);
4896 ADD_LDB_INT(FLAG_MOD_REPLACE
);
4897 ADD_LDB_INT(FLAG_MOD_DELETE
);
4898 ADD_LDB_INT(FLAG_FORCE_NO_BASE64_LDIF
);
4900 ADD_LDB_INT(ATTR_FLAG_HIDDEN
);
4901 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX
);
4902 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE
);
4903 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF
);
4905 ADD_LDB_INT(SUCCESS
);
4906 ADD_LDB_INT(ERR_OPERATIONS_ERROR
);
4907 ADD_LDB_INT(ERR_PROTOCOL_ERROR
);
4908 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED
);
4909 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED
);
4910 ADD_LDB_INT(ERR_COMPARE_FALSE
);
4911 ADD_LDB_INT(ERR_COMPARE_TRUE
);
4912 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED
);
4913 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED
);
4914 ADD_LDB_INT(ERR_REFERRAL
);
4915 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED
);
4916 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION
);
4917 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED
);
4918 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS
);
4919 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE
);
4920 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE
);
4921 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING
);
4922 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION
);
4923 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS
);
4924 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX
);
4925 ADD_LDB_INT(ERR_NO_SUCH_OBJECT
);
4926 ADD_LDB_INT(ERR_ALIAS_PROBLEM
);
4927 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX
);
4928 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM
);
4929 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION
);
4930 ADD_LDB_INT(ERR_INVALID_CREDENTIALS
);
4931 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS
);
4932 ADD_LDB_INT(ERR_BUSY
);
4933 ADD_LDB_INT(ERR_UNAVAILABLE
);
4934 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM
);
4935 ADD_LDB_INT(ERR_LOOP_DETECT
);
4936 ADD_LDB_INT(ERR_NAMING_VIOLATION
);
4937 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION
);
4938 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF
);
4939 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN
);
4940 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS
);
4941 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED
);
4942 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS
);
4943 ADD_LDB_INT(ERR_OTHER
);
4945 ADD_LDB_INT(FLG_RDONLY
);
4946 ADD_LDB_INT(FLG_NOSYNC
);
4947 ADD_LDB_INT(FLG_RECONNECT
);
4948 ADD_LDB_INT(FLG_NOMMAP
);
4949 ADD_LDB_INT(FLG_SHOW_BINARY
);
4950 ADD_LDB_INT(FLG_ENABLE_TRACING
);
4951 ADD_LDB_INT(FLG_DONT_CREATE_DB
);
4953 ADD_LDB_INT(PACKING_FORMAT
);
4954 ADD_LDB_INT(PACKING_FORMAT_V2
);
4956 /* Historical misspelling */
4957 PyModule_AddIntConstant(m
, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM
);
4959 PyModule_AddStringConstant(m
, "__docformat__", "restructuredText");
4961 PyExc_LdbError
= PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL
, NULL
);
4962 PyModule_AddObject(m
, "LdbError", PyExc_LdbError
);
4965 Py_INCREF(&PyLdbDn
);
4966 Py_INCREF(&PyLdbModule
);
4967 Py_INCREF(&PyLdbMessage
);
4968 Py_INCREF(&PyLdbMessageElement
);
4969 Py_INCREF(&PyLdbTree
);
4970 Py_INCREF(&PyLdbResult
);
4971 Py_INCREF(&PyLdbControl
);
4973 PyModule_AddObject(m
, "Ldb", (PyObject
*)&PyLdb
);
4974 PyModule_AddObject(m
, "Dn", (PyObject
*)&PyLdbDn
);
4975 PyModule_AddObject(m
, "Message", (PyObject
*)&PyLdbMessage
);
4976 PyModule_AddObject(m
, "MessageElement", (PyObject
*)&PyLdbMessageElement
);
4977 PyModule_AddObject(m
, "Module", (PyObject
*)&PyLdbModule
);
4978 PyModule_AddObject(m
, "Tree", (PyObject
*)&PyLdbTree
);
4979 PyModule_AddObject(m
, "Control", (PyObject
*)&PyLdbControl
);
4981 PyModule_AddStringConstant(m
, "__version__", PACKAGE_VERSION
);
4983 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4985 ADD_LDB_STRING(SYNTAX_DN
);
4986 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING
);
4987 ADD_LDB_STRING(SYNTAX_INTEGER
);
4988 ADD_LDB_STRING(SYNTAX_ORDERED_INTEGER
);
4989 ADD_LDB_STRING(SYNTAX_BOOLEAN
);
4990 ADD_LDB_STRING(SYNTAX_OCTET_STRING
);
4991 ADD_LDB_STRING(SYNTAX_UTC_TIME
);
4992 ADD_LDB_STRING(OID_COMPARATOR_AND
);
4993 ADD_LDB_STRING(OID_COMPARATOR_OR
);
4998 PyMODINIT_FUNC
PyInit_ldb(void);
4999 PyMODINIT_FUNC
PyInit_ldb(void)
5001 return module_init();