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/>.
31 #include "lib/replace/system/python.h"
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 PyLdbDn
;
70 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
71 static PyTypeObject PyLdb
;
72 static PyTypeObject PyLdbMessageElement
;
73 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
75 static PyTypeObject PyLdbTree
;
76 static struct ldb_message_element
*PyObject_AsMessageElement(
80 const char *attr_name
);
81 static PyTypeObject PyLdbBytesType
;
83 #define PYARG_STR_UNI "es"
85 static PyObject
*PyLdbBytes_FromStringAndSize(const char *msg
, int size
)
87 PyObject
* result
= NULL
;
88 PyObject
* args
= NULL
;
89 args
= Py_BuildValue("(y#)", msg
, size
);
93 result
= PyLdbBytesType
.tp_new(&PyLdbBytesType
, args
, NULL
);
98 static PyObject
*richcmp(int cmp_val
, int op
)
102 case Py_LT
: ret
= cmp_val
< 0; break;
103 case Py_LE
: ret
= cmp_val
<= 0; break;
104 case Py_EQ
: ret
= cmp_val
== 0; break;
105 case Py_NE
: ret
= cmp_val
!= 0; break;
106 case Py_GT
: ret
= cmp_val
> 0; break;
107 case Py_GE
: ret
= cmp_val
>= 0; break;
109 Py_INCREF(Py_NotImplemented
);
110 return Py_NotImplemented
;
112 return PyBool_FromLong(ret
);
116 static PyObject
*py_ldb_control_str(PyLdbControlObject
*self
)
118 if (self
->data
!= NULL
) {
119 char* control
= ldb_control_to_string(self
->mem_ctx
, self
->data
);
120 if (control
== NULL
) {
124 return PyUnicode_FromString(control
);
126 return PyUnicode_FromString("ldb control");
130 static void py_ldb_control_dealloc(PyLdbControlObject
*self
)
132 if (self
->mem_ctx
!= NULL
) {
133 talloc_free(self
->mem_ctx
);
136 Py_TYPE(self
)->tp_free(self
);
139 /* Create a text (rather than bytes) interface for a LDB result object */
140 static PyObject
*wrap_text(const char *type
, PyObject
*wrapped
)
142 PyObject
*mod
, *cls
, *constructor
, *inst
;
143 mod
= PyImport_ImportModule("_ldb_text");
146 cls
= PyObject_GetAttrString(mod
, type
);
152 constructor
= PyObject_GetAttrString(cls
, "_wrap");
154 if (constructor
== NULL
) {
157 inst
= PyObject_CallFunction(constructor
, discard_const_p(char, "O"), wrapped
);
158 Py_DECREF(constructor
);
162 static PyObject
*py_ldb_control_get_oid(PyLdbControlObject
*self
,
163 PyObject
*Py_UNUSED(ignored
))
165 return PyUnicode_FromString(self
->data
->oid
);
168 static PyObject
*py_ldb_control_get_critical(PyLdbControlObject
*self
,
169 PyObject
*Py_UNUSED(ignored
))
171 return PyBool_FromLong(self
->data
->critical
);
174 static int py_ldb_control_set_critical(PyLdbControlObject
*self
, PyObject
*value
, void *closure
)
177 PyErr_SetString(PyExc_AttributeError
, "cannot delete critical flag");
180 if (PyObject_IsTrue(value
)) {
181 self
->data
->critical
= true;
183 self
->data
->critical
= false;
188 static PyObject
*py_ldb_control_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
191 const char * const kwnames
[] = { "ldb", "data", NULL
};
192 struct ldb_control
*parsed_controls
;
193 PyLdbControlObject
*ret
;
196 struct ldb_context
*ldb_ctx
;
198 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O!s",
199 discard_const_p(char *, kwnames
),
200 &PyLdb
, &py_ldb
, &data
))
203 mem_ctx
= talloc_new(NULL
);
204 if (mem_ctx
== NULL
) {
209 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(py_ldb
);
210 parsed_controls
= ldb_parse_control_from_string(ldb_ctx
, mem_ctx
, data
);
212 if (!parsed_controls
) {
213 talloc_free(mem_ctx
);
214 PyErr_SetString(PyExc_ValueError
, "unable to parse control string");
218 ret
= PyObject_New(PyLdbControlObject
, type
);
221 talloc_free(mem_ctx
);
225 ret
->mem_ctx
= mem_ctx
;
227 ret
->data
= talloc_move(mem_ctx
, &parsed_controls
);
228 if (ret
->data
== NULL
) {
231 talloc_free(mem_ctx
);
235 return (PyObject
*)ret
;
238 static PyGetSetDef py_ldb_control_getset
[] = {
240 .name
= discard_const_p(char, "oid"),
241 .get
= (getter
)py_ldb_control_get_oid
,
244 .name
= discard_const_p(char, "critical"),
245 .get
= (getter
)py_ldb_control_get_critical
,
246 .set
= (setter
)py_ldb_control_set_critical
,
251 static PyTypeObject PyLdbControl
= {
252 .tp_name
= "ldb.control",
253 .tp_dealloc
= (destructor
)py_ldb_control_dealloc
,
254 .tp_getattro
= PyObject_GenericGetAttr
,
255 .tp_basicsize
= sizeof(PyLdbControlObject
),
256 .tp_getset
= py_ldb_control_getset
,
257 .tp_doc
= "LDB control.",
258 .tp_str
= (reprfunc
)py_ldb_control_str
,
259 .tp_new
= py_ldb_control_new
,
260 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
263 static PyObject
*py_ldb_bytes_str(PyBytesObject
*self
)
268 if (!PyBytes_Check(self
)) {
269 PyErr_Format(PyExc_TypeError
,"Unexpected type");
272 result
= PyBytes_AsStringAndSize((PyObject
*)self
, &msg
, &size
);
274 PyErr_Format(PyExc_TypeError
, "Failed to extract bytes");
277 return PyUnicode_FromStringAndSize(msg
, size
);
280 static PyTypeObject PyLdbBytesType
= {
281 PyVarObject_HEAD_INIT(NULL
, 0)
282 .tp_name
= "ldb.bytes",
283 .tp_doc
= "str/bytes (with custom str)",
284 .tp_str
= (reprfunc
)py_ldb_bytes_str
,
285 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
288 static PyObject
*PyObject_FromLdbValue(const struct ldb_val
*val
)
290 return PyLdbBytes_FromStringAndSize((const char *)val
->data
, val
->length
);
293 static PyObject
*PyStr_FromLdbValue(const struct ldb_val
*val
)
295 return PyUnicode_FromStringAndSize((const char *)val
->data
, val
->length
);
299 * Create a Python object from a ldb_result.
301 * @param result LDB result to convert
302 * @return Python object with converted result (a list object)
304 static PyObject
*PyLdbControl_FromControl(struct ldb_control
*control
)
306 TALLOC_CTX
*ctl_ctx
= talloc_new(NULL
);
307 PyLdbControlObject
*ctrl
;
308 if (ctl_ctx
== NULL
) {
313 ctrl
= (PyLdbControlObject
*)PyLdbControl
.tp_alloc(&PyLdbControl
, 0);
315 talloc_free(ctl_ctx
);
319 ctrl
->mem_ctx
= ctl_ctx
;
320 ctrl
->data
= talloc_steal(ctrl
->mem_ctx
, control
);
321 if (ctrl
->data
== NULL
) {
326 return (PyObject
*) ctrl
;
330 * Create a Python object from a ldb_result.
332 * @param result LDB result to convert
333 * @return Python object with converted result (a list object)
335 static PyObject
*PyLdbResult_FromResult(struct ldb_result
*result
)
337 PyLdbResultObject
*ret
;
338 PyObject
*list
, *controls
, *referals
;
341 if (result
== NULL
) {
345 ret
= (PyLdbResultObject
*)PyLdbResult
.tp_alloc(&PyLdbResult
, 0);
351 list
= PyList_New(result
->count
);
358 for (i
= 0; i
< result
->count
; i
++) {
359 PyObject
*pymessage
= PyLdbMessage_FromMessage(result
->msgs
[i
]);
360 if (pymessage
== NULL
) {
365 PyList_SetItem(list
, i
, pymessage
);
368 ret
->mem_ctx
= talloc_new(NULL
);
369 if (ret
->mem_ctx
== NULL
) {
378 if (result
->controls
) {
380 while (result
->controls
[i
]) {
383 controls
= PyList_New(i
);
384 if (controls
== NULL
) {
390 for (i
=0; result
->controls
[i
]; i
++) {
391 PyObject
*ctrl
= (PyObject
*) PyLdbControl_FromControl(result
->controls
[i
]);
399 PyList_SetItem(controls
, i
, ctrl
);
403 * No controls so we keep an empty list
405 controls
= PyList_New(0);
406 if (controls
== NULL
) {
414 ret
->controls
= controls
;
418 while (result
->refs
&& result
->refs
[i
]) {
422 referals
= PyList_New(i
);
423 if (referals
== NULL
) {
430 for (i
= 0;result
->refs
&& result
->refs
[i
]; i
++) {
431 PyList_SetItem(referals
, i
, PyUnicode_FromString(result
->refs
[i
]));
433 ret
->referals
= referals
;
434 return (PyObject
*)ret
;
437 static PyObject
*py_ldb_dn_validate(PyLdbDnObject
*self
,
438 PyObject
*Py_UNUSED(ignored
))
440 return PyBool_FromLong(ldb_dn_validate(self
->dn
));
443 static PyObject
*py_ldb_dn_is_valid(PyLdbDnObject
*self
,
444 PyObject
*Py_UNUSED(ignored
))
446 return PyBool_FromLong(ldb_dn_is_valid(self
->dn
));
449 static PyObject
*py_ldb_dn_is_special(PyLdbDnObject
*self
,
450 PyObject
*Py_UNUSED(ignored
))
452 return PyBool_FromLong(ldb_dn_is_special(self
->dn
));
455 static PyObject
*py_ldb_dn_is_null(PyLdbDnObject
*self
,
456 PyObject
*Py_UNUSED(ignored
))
458 return PyBool_FromLong(ldb_dn_is_null(self
->dn
));
461 static PyObject
*py_ldb_dn_get_casefold(PyLdbDnObject
*self
,
462 PyObject
*Py_UNUSED(ignored
))
464 const char *s
= ldb_dn_get_casefold(self
->dn
);
469 return PyUnicode_FromString(s
);
472 static PyObject
*py_ldb_dn_get_linearized(PyLdbDnObject
*self
,
473 PyObject
*Py_UNUSED(ignored
))
475 return PyUnicode_FromString(ldb_dn_get_linearized(self
->dn
));
478 static PyObject
*py_ldb_dn_canonical_str(PyLdbDnObject
*self
,
479 PyObject
*Py_UNUSED(ignored
))
481 return PyUnicode_FromString(ldb_dn_canonical_string(self
->dn
, self
->dn
));
484 static PyObject
*py_ldb_dn_canonical_ex_str(PyLdbDnObject
*self
,
485 PyObject
*Py_UNUSED(ignored
))
487 return PyUnicode_FromString(ldb_dn_canonical_ex_string(self
->dn
, self
->dn
));
490 static PyObject
*py_ldb_dn_extended_str(PyLdbDnObject
*self
, PyObject
*args
, PyObject
*kwargs
)
492 const char * const kwnames
[] = { "mode", NULL
};
494 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i",
495 discard_const_p(char *, kwnames
),
498 return PyUnicode_FromString(ldb_dn_get_extended_linearized(self
->dn
, self
->dn
, mode
));
501 static PyObject
*py_ldb_dn_get_extended_component(PyLdbDnObject
*self
, PyObject
*args
)
504 const struct ldb_val
*val
;
506 if (!PyArg_ParseTuple(args
, "s", &name
))
508 val
= ldb_dn_get_extended_component(self
->dn
, name
);
513 return PyBytes_FromStringAndSize((const char *)val
->data
, val
->length
);
516 static PyObject
*py_ldb_dn_set_extended_component(PyLdbDnObject
*self
, PyObject
*args
)
520 uint8_t *value
= NULL
;
523 if (!PyArg_ParseTuple(args
, "sz#", &name
, (char **)&value
, &size
))
527 err
= ldb_dn_set_extended_component(self
->dn
, name
, NULL
);
530 val
.data
= (uint8_t *)value
;
532 err
= ldb_dn_set_extended_component(self
->dn
, name
, &val
);
535 if (err
!= LDB_SUCCESS
) {
536 PyErr_SetString(PyExc_TypeError
, "Failed to set extended component");
543 static PyObject
*py_ldb_dn_repr(PyLdbDnObject
*self
)
545 PyObject
*str
= PyUnicode_FromString(ldb_dn_get_linearized(self
->dn
));
546 PyObject
*repr
, *result
;
549 repr
= PyObject_Repr(str
);
554 result
= PyUnicode_FromFormat("Dn(%s)", PyUnicode_AsUTF8(repr
));
560 static PyObject
*py_ldb_dn_check_special(PyLdbDnObject
*self
, PyObject
*args
)
564 if (!PyArg_ParseTuple(args
, "s", &name
))
567 return PyBool_FromLong(ldb_dn_check_special(self
->dn
, name
));
570 static PyObject
*py_ldb_dn_richcmp(PyObject
*dn1
, PyObject
*dn2
, int op
)
573 if (!pyldb_Dn_Check(dn2
)) {
574 Py_INCREF(Py_NotImplemented
);
575 return Py_NotImplemented
;
577 ret
= ldb_dn_compare(pyldb_Dn_AS_DN(dn1
), pyldb_Dn_AS_DN(dn2
));
578 return richcmp(ret
, op
);
581 static PyObject
*py_ldb_dn_get_parent(PyLdbDnObject
*self
,
582 PyObject
*Py_UNUSED(ignored
))
584 struct ldb_dn
*dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
585 struct ldb_dn
*parent
;
586 PyLdbDnObject
*py_ret
;
587 TALLOC_CTX
*mem_ctx
= NULL
;
589 if (ldb_dn_get_comp_num(dn
) < 1) {
593 mem_ctx
= talloc_new(NULL
);
594 if (mem_ctx
== NULL
) {
599 parent
= ldb_dn_get_parent(mem_ctx
, dn
);
600 if (parent
== NULL
) {
602 talloc_free(mem_ctx
);
606 py_ret
= (PyLdbDnObject
*)PyLdbDn
.tp_alloc(&PyLdbDn
, 0);
607 if (py_ret
== NULL
) {
609 talloc_free(mem_ctx
);
612 py_ret
->mem_ctx
= mem_ctx
;
614 return (PyObject
*)py_ret
;
617 static PyObject
*py_ldb_dn_add_child(PyLdbDnObject
*self
, PyObject
*args
)
620 struct ldb_dn
*dn
, *other
;
622 if (!PyArg_ParseTuple(args
, "O", &py_other
))
625 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
627 if (!pyldb_Object_AsDn(NULL
, py_other
, ldb_dn_get_ldb_context(dn
), &other
))
630 ok
= ldb_dn_add_child(dn
, other
);
632 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, NULL
);
639 static PyObject
*py_ldb_dn_add_base(PyLdbDnObject
*self
, PyObject
*args
)
642 struct ldb_dn
*other
, *dn
;
644 if (!PyArg_ParseTuple(args
, "O", &py_other
))
647 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
649 if (!pyldb_Object_AsDn(NULL
, py_other
, ldb_dn_get_ldb_context(dn
), &other
))
652 ok
= ldb_dn_add_base(dn
, other
);
654 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, NULL
);
661 static PyObject
*py_ldb_dn_remove_base_components(PyLdbDnObject
*self
, PyObject
*args
)
666 if (!PyArg_ParseTuple(args
, "i", &i
))
669 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
671 ok
= ldb_dn_remove_base_components(dn
, i
);
673 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, NULL
);
680 static PyObject
*py_ldb_dn_is_child_of(PyLdbDnObject
*self
, PyObject
*args
)
683 struct ldb_dn
*dn
, *base
;
684 if (!PyArg_ParseTuple(args
, "O", &py_base
))
687 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
689 if (!pyldb_Object_AsDn(NULL
, py_base
, ldb_dn_get_ldb_context(dn
), &base
))
692 return PyBool_FromLong(ldb_dn_compare_base(base
, dn
) == 0);
695 static PyObject
*py_ldb_dn_get_component_name(PyLdbDnObject
*self
, PyObject
*args
)
699 unsigned int num
= 0;
701 if (!PyArg_ParseTuple(args
, "I", &num
))
704 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
706 name
= ldb_dn_get_component_name(dn
, num
);
711 return PyUnicode_FromString(name
);
714 static PyObject
*py_ldb_dn_get_component_value(PyLdbDnObject
*self
, PyObject
*args
)
717 const struct ldb_val
*val
;
718 unsigned int num
= 0;
720 if (!PyArg_ParseTuple(args
, "I", &num
))
723 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
725 val
= ldb_dn_get_component_val(dn
, num
);
730 return PyStr_FromLdbValue(val
);
733 static PyObject
*py_ldb_dn_set_component(PyLdbDnObject
*self
, PyObject
*args
)
735 unsigned int num
= 0;
736 char *name
= NULL
, *value
= NULL
;
737 struct ldb_val val
= { 0 };
741 if (!PyArg_ParseTuple(args
, "Iss#", &num
, &name
, &value
, &size
))
744 val
.data
= (unsigned char*) value
;
747 err
= ldb_dn_set_component(self
->dn
, num
, name
, val
);
748 if (err
!= LDB_SUCCESS
) {
749 PyErr_SetString(PyExc_TypeError
, "Failed to set component");
756 static PyObject
*py_ldb_dn_get_rdn_name(PyLdbDnObject
*self
,
757 PyObject
*Py_UNUSED(ignored
))
762 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
764 name
= ldb_dn_get_rdn_name(dn
);
769 return PyUnicode_FromString(name
);
772 static PyObject
*py_ldb_dn_get_rdn_value(PyLdbDnObject
*self
,
773 PyObject
*Py_UNUSED(ignored
))
776 const struct ldb_val
*val
;
778 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
780 val
= ldb_dn_get_rdn_val(dn
);
785 return PyStr_FromLdbValue(val
);
788 static PyMethodDef py_ldb_dn_methods
[] = {
789 { "validate", (PyCFunction
)py_ldb_dn_validate
, METH_NOARGS
,
790 "S.validate() -> bool\n"
791 "Validate DN is correct." },
792 { "is_valid", (PyCFunction
)py_ldb_dn_is_valid
, METH_NOARGS
,
793 "S.is_valid() -> bool\n" },
794 { "is_special", (PyCFunction
)py_ldb_dn_is_special
, METH_NOARGS
,
795 "S.is_special() -> bool\n"
796 "Check whether this is a special LDB DN." },
797 { "is_null", (PyCFunction
)py_ldb_dn_is_null
, METH_NOARGS
,
798 "Check whether this is a null DN." },
799 { "get_casefold", (PyCFunction
)py_ldb_dn_get_casefold
, METH_NOARGS
,
801 { "get_linearized", PY_DISCARD_FUNC_SIG(PyCFunction
,
802 py_ldb_dn_get_linearized
),
805 { "canonical_str", (PyCFunction
)py_ldb_dn_canonical_str
, METH_NOARGS
,
806 "S.canonical_str() -> string\n"
807 "Canonical version of this DN (like a posix path)." },
808 { "is_child_of", (PyCFunction
)py_ldb_dn_is_child_of
, METH_VARARGS
,
809 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
810 { "canonical_ex_str", (PyCFunction
)py_ldb_dn_canonical_ex_str
, METH_NOARGS
,
811 "S.canonical_ex_str() -> string\n"
812 "Canonical version of this DN (like a posix path, with terminating newline)." },
813 { "extended_str", PY_DISCARD_FUNC_SIG(PyCFunction
,
814 py_ldb_dn_extended_str
),
815 METH_VARARGS
| METH_KEYWORDS
,
816 "S.extended_str(mode=1) -> string\n"
817 "Extended version of this DN" },
818 { "parent", (PyCFunction
)py_ldb_dn_get_parent
, METH_NOARGS
,
820 "Get the parent for this DN." },
821 { "add_child", (PyCFunction
)py_ldb_dn_add_child
, METH_VARARGS
,
822 "S.add_child(dn) -> bool\n"
823 "Add a child DN to this DN." },
824 { "add_base", (PyCFunction
)py_ldb_dn_add_base
, METH_VARARGS
,
825 "S.add_base(dn) -> bool\n"
826 "Add a base DN to this DN." },
827 { "remove_base_components", (PyCFunction
)py_ldb_dn_remove_base_components
, METH_VARARGS
,
828 "S.remove_base_components(int) -> bool\n"
829 "Remove a number of DN components from the base of this DN." },
830 { "check_special", (PyCFunction
)py_ldb_dn_check_special
, METH_VARARGS
,
831 "S.check_special(name) -> bool\n\n"
832 "Check if name is a special DN name"},
833 { "get_extended_component", (PyCFunction
)py_ldb_dn_get_extended_component
, METH_VARARGS
,
834 "S.get_extended_component(name) -> string\n\n"
835 "returns a DN extended component as a binary string"},
836 { "set_extended_component", (PyCFunction
)py_ldb_dn_set_extended_component
, METH_VARARGS
,
837 "S.set_extended_component(name, value) -> None\n\n"
838 "set a DN extended component as a binary string"},
839 { "get_component_name", (PyCFunction
)py_ldb_dn_get_component_name
, METH_VARARGS
,
840 "S.get_component_name(num) -> string\n"
841 "get the attribute name of the specified component" },
842 { "get_component_value", (PyCFunction
)py_ldb_dn_get_component_value
, METH_VARARGS
,
843 "S.get_component_value(num) -> string\n"
844 "get the attribute value of the specified component as a binary string" },
845 { "set_component", (PyCFunction
)py_ldb_dn_set_component
, METH_VARARGS
,
846 "S.set_component(num, name, value) -> None\n"
847 "set the attribute name and value of the specified component" },
848 { "get_rdn_name", (PyCFunction
)py_ldb_dn_get_rdn_name
, METH_NOARGS
,
849 "S.get_rdn_name() -> string\n"
850 "get the RDN attribute name" },
851 { "get_rdn_value", (PyCFunction
)py_ldb_dn_get_rdn_value
, METH_NOARGS
,
852 "S.get_rdn_value() -> string\n"
853 "get the RDN attribute value as a binary string" },
857 static Py_ssize_t
py_ldb_dn_len(PyLdbDnObject
*self
)
859 return ldb_dn_get_comp_num(pyldb_Dn_AS_DN((PyObject
*)self
));
863 copy a DN as a python object
865 static PyObject
*py_ldb_dn_copy(struct ldb_dn
*dn
)
867 TALLOC_CTX
*mem_ctx
= NULL
;
868 struct ldb_dn
*new_dn
= NULL
;
869 PyLdbDnObject
*py_ret
;
871 mem_ctx
= talloc_new(NULL
);
872 if (mem_ctx
== NULL
) {
873 return PyErr_NoMemory();
876 new_dn
= ldb_dn_copy(mem_ctx
, dn
);
877 if (new_dn
== NULL
) {
878 talloc_free(mem_ctx
);
879 return PyErr_NoMemory();
882 py_ret
= (PyLdbDnObject
*)PyLdbDn
.tp_alloc(&PyLdbDn
, 0);
883 if (py_ret
== NULL
) {
884 talloc_free(mem_ctx
);
888 py_ret
->mem_ctx
= mem_ctx
;
890 return (PyObject
*)py_ret
;
893 static PyObject
*py_ldb_dn_concat(PyLdbDnObject
*self
, PyObject
*py_other
)
895 TALLOC_CTX
*mem_ctx
= NULL
;
896 struct ldb_dn
*dn
= pyldb_Dn_AS_DN((PyObject
*)self
),
898 struct ldb_dn
*new_dn
= NULL
;
899 PyLdbDnObject
*py_ret
;
901 if (!pyldb_Object_AsDn(NULL
, py_other
, NULL
, &other
))
904 mem_ctx
= talloc_new(NULL
);
905 if (mem_ctx
== NULL
) {
906 return PyErr_NoMemory();
909 new_dn
= ldb_dn_copy(mem_ctx
, dn
);
910 if (new_dn
== NULL
) {
911 talloc_free(mem_ctx
);
912 return PyErr_NoMemory();
915 if (!ldb_dn_add_base(new_dn
, other
)) {
916 PyErr_SetString(PyExc_RuntimeError
, "unable to concatenate DNs");
917 talloc_free(mem_ctx
);
921 py_ret
= (PyLdbDnObject
*)PyLdbDn
.tp_alloc(&PyLdbDn
, 0);
922 if (py_ret
== NULL
) {
923 talloc_free(mem_ctx
);
927 py_ret
->mem_ctx
= mem_ctx
;
930 return (PyObject
*)py_ret
;
933 static PySequenceMethods py_ldb_dn_seq
= {
934 .sq_length
= (lenfunc
)py_ldb_dn_len
,
935 .sq_concat
= (binaryfunc
)py_ldb_dn_concat
,
938 static PyObject
*py_ldb_dn_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
940 struct ldb_dn
*ret
= NULL
;
942 PyObject
*py_ldb
= NULL
;
943 struct ldb_context
*ldb_ctx
= NULL
;
944 TALLOC_CTX
*mem_ctx
= NULL
;
945 PyLdbDnObject
*py_ret
= NULL
;
946 const char * const kwnames
[] = { "ldb", "dn", NULL
};
948 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O!"PYARG_STR_UNI
,
949 discard_const_p(char *, kwnames
),
950 &PyLdb
, &py_ldb
, "utf8", &str
))
953 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(py_ldb
);
955 mem_ctx
= talloc_new(NULL
);
956 if (mem_ctx
== NULL
) {
961 ret
= ldb_dn_new(mem_ctx
, ldb_ctx
, str
);
962 if (!ldb_dn_validate(ret
)) {
963 talloc_free(mem_ctx
);
964 PyErr_SetString(PyExc_ValueError
, "unable to parse dn string");
968 py_ret
= (PyLdbDnObject
*)type
->tp_alloc(type
, 0);
969 if (py_ret
== NULL
) {
970 talloc_free(mem_ctx
);
974 py_ret
->mem_ctx
= mem_ctx
;
978 PyMem_Free(discard_const_p(char, str
));
980 return (PyObject
*)py_ret
;
983 static void py_ldb_dn_dealloc(PyLdbDnObject
*self
)
985 talloc_free(self
->mem_ctx
);
989 static PyTypeObject PyLdbDn
= {
991 .tp_methods
= py_ldb_dn_methods
,
992 .tp_str
= (reprfunc
)py_ldb_dn_get_linearized
,
993 .tp_repr
= (reprfunc
)py_ldb_dn_repr
,
994 .tp_richcompare
= (richcmpfunc
)py_ldb_dn_richcmp
,
995 .tp_as_sequence
= &py_ldb_dn_seq
,
996 .tp_doc
= "A LDB distinguished name.",
997 .tp_new
= py_ldb_dn_new
,
998 .tp_dealloc
= (destructor
)py_ldb_dn_dealloc
,
999 .tp_basicsize
= sizeof(PyLdbDnObject
),
1000 .tp_flags
= Py_TPFLAGS_DEFAULT
,
1004 static void py_ldb_debug(void *context
, enum ldb_debug_level level
, const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(3, 0);
1005 static void py_ldb_debug(void *context
, enum ldb_debug_level level
, const char *fmt
, va_list ap
)
1007 PyObject
*fn
= (PyObject
*)context
;
1008 PyObject
*result
= NULL
;
1009 result
= PyObject_CallFunction(fn
, discard_const_p(char, "(i,O)"), level
, PyUnicode_FromFormatV(fmt
, ap
));
1013 static PyObject
*py_ldb_debug_func
;
1015 static PyObject
*py_ldb_set_debug(PyObject
*self
, PyObject
*args
)
1018 struct ldb_context
*ldb_ctx
;
1020 if (!PyArg_ParseTuple(args
, "O", &cb
))
1023 if (py_ldb_debug_func
!= NULL
) {
1024 Py_DECREF(py_ldb_debug_func
);
1028 /* FIXME: DECREF cb when exiting program */
1029 py_ldb_debug_func
= cb
;
1030 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1031 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
,
1032 ldb_set_debug(ldb_ctx
, py_ldb_debug
, cb
),
1038 static PyObject
*py_ldb_set_create_perms(PyTypeObject
*self
, PyObject
*args
)
1041 if (!PyArg_ParseTuple(args
, "I", &perms
))
1044 ldb_set_create_perms(pyldb_Ldb_AS_LDBCONTEXT(self
), perms
);
1049 static PyObject
*py_ldb_set_modules_dir(PyTypeObject
*self
, PyObject
*args
)
1052 if (!PyArg_ParseTuple(args
, "s", &modules_dir
))
1055 ldb_set_modules_dir(pyldb_Ldb_AS_LDBCONTEXT(self
), modules_dir
);
1060 static PyObject
*py_ldb_transaction_start(PyLdbObject
*self
,
1061 PyObject
*Py_UNUSED(ignored
))
1063 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1065 ldb_err
= ldb_transaction_start(ldb_ctx
);
1066 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1070 static PyObject
*py_ldb_transaction_commit(PyLdbObject
*self
,
1071 PyObject
*Py_UNUSED(ignored
))
1073 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1075 ldb_err
= ldb_transaction_commit(ldb_ctx
);
1076 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1080 static PyObject
*py_ldb_transaction_prepare_commit(PyLdbObject
*self
,
1081 PyObject
*Py_UNUSED(ignored
))
1083 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1085 ldb_err
= ldb_transaction_prepare_commit(ldb_ctx
);
1086 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1090 static PyObject
*py_ldb_transaction_cancel(PyLdbObject
*self
,
1091 PyObject
*Py_UNUSED(ignored
))
1093 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1095 ldb_err
= ldb_transaction_cancel(ldb_ctx
);
1096 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1100 static PyObject
*py_ldb_setup_wellknown_attributes(PyLdbObject
*self
,
1101 PyObject
*Py_UNUSED(ignored
))
1103 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1105 ldb_err
= ldb_setup_wellknown_attributes(ldb_ctx
);
1106 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1110 static PyObject
*py_ldb_repr(PyLdbObject
*self
)
1112 return PyUnicode_FromString("<ldb connection>");
1115 static PyObject
*py_ldb_get_root_basedn(PyLdbObject
*self
,
1116 PyObject
*Py_UNUSED(ignored
))
1118 struct ldb_dn
*dn
= ldb_get_root_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1121 return py_ldb_dn_copy(dn
);
1125 static PyObject
*py_ldb_get_schema_basedn(PyLdbObject
*self
,
1126 PyObject
*Py_UNUSED(ignored
))
1128 struct ldb_dn
*dn
= ldb_get_schema_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1131 return py_ldb_dn_copy(dn
);
1134 static PyObject
*py_ldb_get_config_basedn(PyLdbObject
*self
,
1135 PyObject
*Py_UNUSED(ignored
))
1137 struct ldb_dn
*dn
= ldb_get_config_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1140 return py_ldb_dn_copy(dn
);
1143 static PyObject
*py_ldb_get_default_basedn(PyLdbObject
*self
,
1144 PyObject
*Py_UNUSED(ignored
))
1146 struct ldb_dn
*dn
= ldb_get_default_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1149 return py_ldb_dn_copy(dn
);
1152 static const char **PyList_AsStrList(TALLOC_CTX
*mem_ctx
, PyObject
*list
,
1153 const char *paramname
)
1157 if (!PyList_Check(list
)) {
1158 PyErr_Format(PyExc_TypeError
, "%s is not a list", paramname
);
1161 ret
= talloc_array(NULL
, const char *, PyList_Size(list
)+1);
1167 for (i
= 0; i
< PyList_Size(list
); i
++) {
1168 const char *str
= NULL
;
1170 PyObject
*item
= PyList_GetItem(list
, i
);
1171 if (!PyUnicode_Check(item
)) {
1172 PyErr_Format(PyExc_TypeError
, "%s should be strings", paramname
);
1176 str
= PyUnicode_AsUTF8AndSize(item
, &size
);
1181 ret
[i
] = talloc_strndup(ret
, str
, size
);
1187 static PyObject
*py_ldb_connect(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
);
1189 static int py_ldb_init(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1191 const char * const kwnames
[] = { "url", "flags", "options", NULL
};
1193 PyObject
*py_options
= NULL
;
1194 unsigned int flags
= 0;
1196 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|zIO:Ldb.__init__",
1197 discard_const_p(char *, kwnames
),
1198 &url
, &flags
, &py_options
)) {
1203 /* py_ldb_connect returns py_None on success, NULL on error */
1204 PyObject
*result
= py_ldb_connect(self
, args
, kwargs
);
1205 if (result
== NULL
) {
1210 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1211 ldb_set_flags(ldb
, flags
);
1217 static PyObject
*py_ldb_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
1219 TALLOC_CTX
*mem_ctx
= NULL
;
1221 struct ldb_context
*ldb
;
1223 mem_ctx
= talloc_new(NULL
);
1224 if (mem_ctx
== NULL
) {
1225 return PyErr_NoMemory();
1228 ldb
= ldb_init(mem_ctx
, NULL
);
1230 talloc_free(mem_ctx
);
1235 ret
= (PyLdbObject
*)type
->tp_alloc(type
, 0);
1237 talloc_free(mem_ctx
);
1241 ret
->mem_ctx
= mem_ctx
;
1244 return (PyObject
*)ret
;
1247 static PyObject
*py_ldb_connect(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1250 unsigned int flags
= 0;
1251 PyObject
*py_options
= Py_None
;
1253 const char **options
;
1254 const char * const kwnames
[] = { "url", "flags", "options", NULL
};
1255 struct ldb_context
*ldb_ctx
;
1257 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|IO",
1258 discard_const_p(char *, kwnames
),
1259 &url
, &flags
, &py_options
))
1262 if (py_options
== Py_None
) {
1265 options
= PyList_AsStrList(NULL
, py_options
, "options");
1266 if (options
== NULL
)
1270 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1271 ret
= ldb_connect(ldb_ctx
, url
, flags
, options
);
1272 talloc_free(options
);
1274 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1279 static PyObject
*py_ldb_modify(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1282 PyObject
*py_controls
= Py_None
;
1283 struct ldb_context
*ldb_ctx
;
1284 struct ldb_request
*req
;
1285 struct ldb_control
**parsed_controls
;
1286 struct ldb_message
*msg
;
1288 TALLOC_CTX
*mem_ctx
;
1290 const char * const kwnames
[] = { "message", "controls", "validate", NULL
};
1292 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Ob",
1293 discard_const_p(char *, kwnames
),
1294 &py_msg
, &py_controls
, &validate
))
1297 mem_ctx
= talloc_new(NULL
);
1298 if (mem_ctx
== NULL
) {
1302 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1304 if (py_controls
== Py_None
) {
1305 parsed_controls
= NULL
;
1307 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1308 if (controls
== NULL
) {
1309 talloc_free(mem_ctx
);
1312 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1313 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
1314 talloc_free(mem_ctx
);
1315 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
1318 talloc_free(controls
);
1321 if (!PyLdbMessage_Check(py_msg
)) {
1322 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message");
1323 talloc_free(mem_ctx
);
1326 msg
= pyldb_Message_AsMessage(py_msg
);
1329 ret
= ldb_msg_sanity_check(ldb_ctx
, msg
);
1330 if (ret
!= LDB_SUCCESS
) {
1331 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1332 talloc_free(mem_ctx
);
1337 ret
= ldb_build_mod_req(&req
, ldb_ctx
, mem_ctx
, msg
, parsed_controls
,
1338 NULL
, ldb_op_default_callback
, NULL
);
1339 if (ret
!= LDB_SUCCESS
) {
1340 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1341 talloc_free(mem_ctx
);
1345 /* do request and autostart a transaction */
1346 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1348 ret
= ldb_transaction_start(ldb_ctx
);
1349 if (ret
!= LDB_SUCCESS
) {
1350 talloc_free(mem_ctx
);
1351 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1355 ret
= ldb_request(ldb_ctx
, req
);
1356 if (ret
== LDB_SUCCESS
) {
1357 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1360 if (ret
== LDB_SUCCESS
) {
1361 ret
= ldb_transaction_commit(ldb_ctx
);
1363 ldb_transaction_cancel(ldb_ctx
);
1366 talloc_free(mem_ctx
);
1367 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1374 * Obtain a ldb message from a Python Dictionary object.
1376 * @param mem_ctx Memory context
1377 * @param py_obj Python Dictionary object
1378 * @param ldb_ctx LDB context
1379 * @param mod_flags Flags to be set on every message element
1380 * @return ldb_message on success or NULL on failure
1382 static struct ldb_message
*PyDict_AsMessage(TALLOC_CTX
*mem_ctx
,
1384 struct ldb_context
*ldb_ctx
,
1385 unsigned int mod_flags
)
1387 struct ldb_message
*msg
;
1388 unsigned int msg_pos
= 0;
1389 Py_ssize_t dict_pos
= 0;
1390 PyObject
*key
, *value
;
1391 struct ldb_message_element
*msg_el
;
1392 PyObject
*dn_value
= PyDict_GetItemString(py_obj
, "dn");
1394 msg
= ldb_msg_new(mem_ctx
);
1399 msg
->elements
= talloc_zero_array(msg
, struct ldb_message_element
, PyDict_Size(py_obj
));
1400 if (msg
->elements
== NULL
) {
1407 struct ldb_dn
*dn
= NULL
;
1408 if (!pyldb_Object_AsDn(msg
, dn_value
, ldb_ctx
, &dn
)) {
1409 PyErr_SetString(PyExc_TypeError
, "unable to import dn object");
1414 PyErr_SetString(PyExc_TypeError
, "dn set but not found");
1418 msg
->dn
= talloc_reference(msg
, dn
);
1419 if (msg
->dn
== NULL
) {
1420 talloc_free(mem_ctx
);
1425 PyErr_SetString(PyExc_TypeError
, "no dn set");
1430 while (PyDict_Next(py_obj
, &dict_pos
, &key
, &value
)) {
1431 const char *key_str
= PyUnicode_AsUTF8(key
);
1432 if (ldb_attr_cmp(key_str
, "dn") != 0) {
1433 msg_el
= PyObject_AsMessageElement(msg
->elements
, value
,
1434 mod_flags
, key_str
);
1435 if (msg_el
== NULL
) {
1436 PyErr_Format(PyExc_TypeError
, "unable to import element '%s'", key_str
);
1440 memcpy(&msg
->elements
[msg_pos
], msg_el
, sizeof(*msg_el
));
1443 * PyObject_AsMessageElement might have returned a
1444 * reference to an existing MessageElement, and so left
1445 * the name and flags unchanged. Thus if those members
1446 * aren’t set, we’ll assume that the user forgot to
1449 if (msg
->elements
[msg_pos
].name
== NULL
) {
1450 /* No name was set — set it now. */
1451 msg
->elements
[msg_pos
].name
= talloc_strdup(msg
->elements
, key_str
);
1452 if (msg
->elements
[msg_pos
].name
== NULL
) {
1458 if (msg
->elements
[msg_pos
].flags
== 0) {
1459 /* No flags were set — set them now. */
1460 msg
->elements
[msg_pos
].flags
= mod_flags
;
1467 msg
->num_elements
= msg_pos
;
1472 static PyObject
*py_ldb_add(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1476 struct ldb_context
*ldb_ctx
;
1477 struct ldb_request
*req
;
1478 struct ldb_message
*msg
= NULL
;
1479 PyObject
*py_controls
= Py_None
;
1480 TALLOC_CTX
*mem_ctx
;
1481 struct ldb_control
**parsed_controls
;
1482 const char * const kwnames
[] = { "message", "controls", NULL
};
1484 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O",
1485 discard_const_p(char *, kwnames
),
1486 &py_obj
, &py_controls
))
1489 mem_ctx
= talloc_new(NULL
);
1490 if (mem_ctx
== NULL
) {
1494 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1496 if (py_controls
== Py_None
) {
1497 parsed_controls
= NULL
;
1499 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1500 if (controls
== NULL
) {
1501 talloc_free(mem_ctx
);
1504 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1505 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
1506 talloc_free(mem_ctx
);
1507 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
1510 talloc_free(controls
);
1513 if (PyLdbMessage_Check(py_obj
)) {
1514 msg
= pyldb_Message_AsMessage(py_obj
);
1515 } else if (PyDict_Check(py_obj
)) {
1516 msg
= PyDict_AsMessage(mem_ctx
, py_obj
, ldb_ctx
, LDB_FLAG_MOD_ADD
);
1518 PyErr_SetString(PyExc_TypeError
,
1519 "Dictionary or LdbMessage object expected!");
1523 /* we should have a PyErr already set */
1524 talloc_free(mem_ctx
);
1528 ret
= ldb_msg_sanity_check(ldb_ctx
, msg
);
1529 if (ret
!= LDB_SUCCESS
) {
1530 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1531 talloc_free(mem_ctx
);
1535 ret
= ldb_build_add_req(&req
, ldb_ctx
, mem_ctx
, msg
, parsed_controls
,
1536 NULL
, ldb_op_default_callback
, NULL
);
1537 if (ret
!= LDB_SUCCESS
) {
1538 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1539 talloc_free(mem_ctx
);
1543 /* do request and autostart a transaction */
1544 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1546 ret
= ldb_transaction_start(ldb_ctx
);
1547 if (ret
!= LDB_SUCCESS
) {
1548 talloc_free(mem_ctx
);
1549 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1553 ret
= ldb_request(ldb_ctx
, req
);
1554 if (ret
== LDB_SUCCESS
) {
1555 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1558 if (ret
== LDB_SUCCESS
) {
1559 ret
= ldb_transaction_commit(ldb_ctx
);
1561 ldb_transaction_cancel(ldb_ctx
);
1564 talloc_free(mem_ctx
);
1565 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1570 static PyObject
*py_ldb_delete(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1575 struct ldb_context
*ldb_ctx
;
1576 struct ldb_request
*req
;
1577 PyObject
*py_controls
= Py_None
;
1578 TALLOC_CTX
*mem_ctx
;
1579 struct ldb_control
**parsed_controls
;
1580 const char * const kwnames
[] = { "dn", "controls", NULL
};
1582 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O",
1583 discard_const_p(char *, kwnames
),
1584 &py_dn
, &py_controls
))
1587 mem_ctx
= talloc_new(NULL
);
1588 if (mem_ctx
== NULL
) {
1592 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1594 if (py_controls
== Py_None
) {
1595 parsed_controls
= NULL
;
1597 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1598 if (controls
== NULL
) {
1599 talloc_free(mem_ctx
);
1602 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1603 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
1604 talloc_free(mem_ctx
);
1605 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
1608 talloc_free(controls
);
1611 if (!pyldb_Object_AsDn(mem_ctx
, py_dn
, ldb_ctx
, &dn
)) {
1612 talloc_free(mem_ctx
);
1616 ret
= ldb_build_del_req(&req
, ldb_ctx
, mem_ctx
, dn
, parsed_controls
,
1617 NULL
, ldb_op_default_callback
, NULL
);
1618 if (ret
!= LDB_SUCCESS
) {
1619 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1620 talloc_free(mem_ctx
);
1624 /* do request and autostart a transaction */
1625 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1627 ret
= ldb_transaction_start(ldb_ctx
);
1628 if (ret
!= LDB_SUCCESS
) {
1629 talloc_free(mem_ctx
);
1630 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1634 ret
= ldb_request(ldb_ctx
, req
);
1635 if (ret
== LDB_SUCCESS
) {
1636 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1639 if (ret
== LDB_SUCCESS
) {
1640 ret
= ldb_transaction_commit(ldb_ctx
);
1642 ldb_transaction_cancel(ldb_ctx
);
1645 talloc_free(mem_ctx
);
1646 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1651 static PyObject
*py_ldb_rename(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1653 PyObject
*py_dn1
, *py_dn2
;
1654 struct ldb_dn
*dn1
, *dn2
;
1656 TALLOC_CTX
*mem_ctx
;
1657 PyObject
*py_controls
= Py_None
;
1658 struct ldb_control
**parsed_controls
;
1659 struct ldb_context
*ldb_ctx
;
1660 struct ldb_request
*req
;
1661 const char * const kwnames
[] = { "dn1", "dn2", "controls", NULL
};
1663 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1665 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|O",
1666 discard_const_p(char *, kwnames
),
1667 &py_dn1
, &py_dn2
, &py_controls
))
1671 mem_ctx
= talloc_new(NULL
);
1672 if (mem_ctx
== NULL
) {
1677 if (py_controls
== Py_None
) {
1678 parsed_controls
= NULL
;
1680 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1681 if (controls
== NULL
) {
1682 talloc_free(mem_ctx
);
1685 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1686 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
1687 talloc_free(mem_ctx
);
1688 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
1691 talloc_free(controls
);
1695 if (!pyldb_Object_AsDn(mem_ctx
, py_dn1
, ldb_ctx
, &dn1
)) {
1696 talloc_free(mem_ctx
);
1700 if (!pyldb_Object_AsDn(mem_ctx
, py_dn2
, ldb_ctx
, &dn2
)) {
1701 talloc_free(mem_ctx
);
1705 ret
= ldb_build_rename_req(&req
, ldb_ctx
, mem_ctx
, dn1
, dn2
, parsed_controls
,
1706 NULL
, ldb_op_default_callback
, NULL
);
1707 if (ret
!= LDB_SUCCESS
) {
1708 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1709 talloc_free(mem_ctx
);
1713 /* do request and autostart a transaction */
1714 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1716 ret
= ldb_transaction_start(ldb_ctx
);
1717 if (ret
!= LDB_SUCCESS
) {
1718 talloc_free(mem_ctx
);
1719 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1723 ret
= ldb_request(ldb_ctx
, req
);
1724 if (ret
== LDB_SUCCESS
) {
1725 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1728 if (ret
== LDB_SUCCESS
) {
1729 ret
= ldb_transaction_commit(ldb_ctx
);
1731 ldb_transaction_cancel(ldb_ctx
);
1734 talloc_free(mem_ctx
);
1735 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1740 static PyObject
*py_ldb_schema_attribute_remove(PyLdbObject
*self
, PyObject
*args
)
1743 if (!PyArg_ParseTuple(args
, "s", &name
))
1746 ldb_schema_attribute_remove(pyldb_Ldb_AS_LDBCONTEXT(self
), name
);
1751 static PyObject
*py_ldb_schema_attribute_add(PyLdbObject
*self
, PyObject
*args
)
1753 char *attribute
, *syntax
;
1756 struct ldb_context
*ldb_ctx
;
1758 if (!PyArg_ParseTuple(args
, "sIs", &attribute
, &flags
, &syntax
))
1761 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1762 ret
= ldb_schema_attribute_add(ldb_ctx
, attribute
, flags
, syntax
);
1764 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1769 static PyObject
*ldb_ldif_to_pyobject(struct ldb_context
*ldb
, struct ldb_ldif
*ldif
)
1771 PyObject
*obj
= NULL
;
1772 PyObject
*result
= NULL
;
1778 switch (ldif
->changetype
) {
1779 case LDB_CHANGETYPE_NONE
:
1780 case LDB_CHANGETYPE_ADD
:
1781 obj
= PyLdbMessage_FromMessage(ldif
->msg
);
1783 case LDB_CHANGETYPE_MODIFY
:
1784 obj
= PyLdbMessage_FromMessage(ldif
->msg
);
1786 case LDB_CHANGETYPE_DELETE
:
1787 if (ldif
->msg
->num_elements
!= 0) {
1788 PyErr_Format(PyExc_ValueError
,
1789 "CHANGETYPE(DELETE) with num_elements=%u",
1790 ldif
->msg
->num_elements
);
1793 obj
= pyldb_Dn_FromDn(ldif
->msg
->dn
);
1795 case LDB_CHANGETYPE_MODRDN
: {
1796 struct ldb_dn
*olddn
= NULL
;
1797 PyObject
*olddn_obj
= NULL
;
1798 bool deleteoldrdn
= false;
1799 PyObject
*deleteoldrdn_obj
= NULL
;
1800 struct ldb_dn
*newdn
= NULL
;
1801 PyObject
*newdn_obj
= NULL
;
1804 ret
= ldb_ldif_parse_modrdn(ldb
,
1812 if (ret
!= LDB_SUCCESS
) {
1813 PyErr_Format(PyExc_ValueError
,
1814 "ldb_ldif_parse_modrdn() failed");
1818 olddn_obj
= pyldb_Dn_FromDn(olddn
);
1819 if (olddn_obj
== NULL
) {
1823 deleteoldrdn_obj
= Py_True
;
1825 deleteoldrdn_obj
= Py_False
;
1827 newdn_obj
= pyldb_Dn_FromDn(newdn
);
1828 if (newdn_obj
== NULL
) {
1829 deleteoldrdn_obj
= NULL
;
1830 Py_CLEAR(olddn_obj
);
1834 obj
= Py_BuildValue(discard_const_p(char, "{s:O,s:O,s:O}"),
1836 "deleteoldrdn", deleteoldrdn_obj
,
1837 "newdn", newdn_obj
);
1838 Py_CLEAR(olddn_obj
);
1839 deleteoldrdn_obj
= NULL
;
1840 Py_CLEAR(newdn_obj
);
1844 PyErr_Format(PyExc_NotImplementedError
,
1845 "Unsupported LDB_CHANGETYPE(%u)",
1854 /* We don't want this being attached * to the 'ldb' any more */
1855 result
= Py_BuildValue(discard_const_p(char, "(iO)"),
1863 static PyObject
*py_ldb_write_ldif(PyLdbObject
*self
, PyObject
*args
)
1867 struct ldb_ldif ldif
;
1870 TALLOC_CTX
*mem_ctx
;
1872 if (!PyArg_ParseTuple(args
, "Oi", &py_msg
, &changetype
))
1875 if (!PyLdbMessage_Check(py_msg
)) {
1876 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for msg");
1880 ldif
.msg
= pyldb_Message_AsMessage(py_msg
);
1881 ldif
.changetype
= changetype
;
1883 mem_ctx
= talloc_new(NULL
);
1884 if (mem_ctx
== NULL
) {
1885 return PyErr_NoMemory();
1888 string
= ldb_ldif_write_string(pyldb_Ldb_AS_LDBCONTEXT(self
), mem_ctx
, &ldif
);
1890 PyErr_SetString(PyExc_KeyError
, "Failed to generate LDIF");
1891 talloc_free(mem_ctx
);
1895 ret
= PyUnicode_FromString(string
);
1897 talloc_free(mem_ctx
);
1902 static PyObject
*py_ldb_parse_ldif(PyLdbObject
*self
, PyObject
*args
)
1904 PyObject
*list
, *ret
;
1905 struct ldb_ldif
*ldif
;
1907 struct ldb_dn
*last_dn
= NULL
;
1909 TALLOC_CTX
*mem_ctx
;
1911 if (!PyArg_ParseTuple(args
, "s", &s
))
1914 mem_ctx
= talloc_new(NULL
);
1919 list
= PyList_New(0);
1921 talloc_free(mem_ctx
);
1925 while (s
&& *s
!= '\0') {
1926 ldif
= ldb_ldif_read_string(self
->ldb_ctx
, &s
);
1927 talloc_steal(mem_ctx
, ldif
);
1930 PyObject
*py_ldif
= ldb_ldif_to_pyobject(self
->ldb_ctx
, ldif
);
1931 if (py_ldif
== NULL
) {
1933 if (PyErr_Occurred() == NULL
) {
1934 PyErr_BadArgument();
1936 talloc_free(mem_ctx
);
1939 res
= PyList_Append(list
, py_ldif
);
1943 talloc_free(mem_ctx
);
1946 last_dn
= ldif
->msg
->dn
;
1948 const char *last_dn_str
= NULL
;
1949 const char *err_string
= NULL
;
1950 if (last_dn
== NULL
) {
1951 PyErr_SetString(PyExc_ValueError
,
1952 "unable to parse LDIF "
1953 "string at first chunk");
1955 talloc_free(mem_ctx
);
1960 = ldb_dn_get_linearized(last_dn
);
1963 = talloc_asprintf(mem_ctx
,
1964 "unable to parse ldif "
1968 PyErr_SetString(PyExc_ValueError
,
1970 talloc_free(mem_ctx
);
1975 talloc_free(mem_ctx
); /* The pyobject already has a reference to the things it needs */
1976 ret
= PyObject_GetIter(list
);
1981 static PyObject
*py_ldb_msg_diff(PyLdbObject
*self
, PyObject
*args
)
1984 PyObject
*py_msg_old
;
1985 PyObject
*py_msg_new
;
1986 struct ldb_message
*diff
;
1987 struct ldb_context
*ldb
;
1989 TALLOC_CTX
*mem_ctx
= NULL
;
1991 if (!PyArg_ParseTuple(args
, "OO", &py_msg_old
, &py_msg_new
))
1994 if (!PyLdbMessage_Check(py_msg_old
)) {
1995 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for old message");
1999 if (!PyLdbMessage_Check(py_msg_new
)) {
2000 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for new message");
2004 mem_ctx
= talloc_new(NULL
);
2005 if (mem_ctx
== NULL
) {
2010 ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2011 ldb_ret
= ldb_msg_difference(ldb
, mem_ctx
,
2012 pyldb_Message_AsMessage(py_msg_old
),
2013 pyldb_Message_AsMessage(py_msg_new
),
2015 if (ldb_ret
!= LDB_SUCCESS
) {
2016 talloc_free(mem_ctx
);
2017 PyErr_SetString(PyExc_RuntimeError
, "Failed to generate the Ldb Message diff");
2021 diff
= ldb_msg_copy(mem_ctx
, diff
);
2023 talloc_free(mem_ctx
);
2028 py_ret
= PyLdbMessage_FromMessage(diff
);
2030 talloc_free(mem_ctx
);
2035 static PyObject
*py_ldb_schema_format_value(PyLdbObject
*self
, PyObject
*args
)
2037 const struct ldb_schema_attribute
*a
;
2038 struct ldb_val old_val
;
2039 struct ldb_val new_val
;
2040 TALLOC_CTX
*mem_ctx
;
2047 if (!PyArg_ParseTuple(args
, "sO", &element_name
, &val
))
2050 result
= PyBytes_AsStringAndSize(val
, (char **)&old_val
.data
, &size
);
2051 old_val
.length
= size
;
2054 PyErr_SetString(PyExc_RuntimeError
, "Failed to convert passed value to String");
2058 a
= ldb_schema_attribute_by_name(pyldb_Ldb_AS_LDBCONTEXT(self
), element_name
);
2064 mem_ctx
= talloc_new(NULL
);
2065 if (mem_ctx
== NULL
) {
2070 if (a
->syntax
->ldif_write_fn(pyldb_Ldb_AS_LDBCONTEXT(self
), mem_ctx
, &old_val
, &new_val
) != 0) {
2071 talloc_free(mem_ctx
);
2075 ret
= PyBytes_FromStringAndSize((const char *)new_val
.data
, new_val
.length
);
2077 talloc_free(mem_ctx
);
2082 static PyObject
*py_ldb_search(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
2084 PyObject
*py_base
= Py_None
;
2085 int scope
= LDB_SCOPE_DEFAULT
;
2087 PyObject
*py_attrs
= Py_None
;
2088 PyObject
*py_controls
= Py_None
;
2089 const char * const kwnames
[] = { "base", "scope", "expression", "attrs", "controls", NULL
};
2091 struct ldb_result
*res
;
2092 struct ldb_request
*req
;
2094 struct ldb_context
*ldb_ctx
;
2095 struct ldb_control
**parsed_controls
;
2096 struct ldb_dn
*base
;
2098 TALLOC_CTX
*mem_ctx
;
2100 /* type "int" rather than "enum" for "scope" is intentional */
2101 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OizOO",
2102 discard_const_p(char *, kwnames
),
2103 &py_base
, &scope
, &expr
, &py_attrs
, &py_controls
))
2107 mem_ctx
= talloc_new(NULL
);
2108 if (mem_ctx
== NULL
) {
2112 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2114 if (py_attrs
== Py_None
) {
2117 attrs
= PyList_AsStrList(mem_ctx
, py_attrs
, "attrs");
2118 if (attrs
== NULL
) {
2119 talloc_free(mem_ctx
);
2124 if (py_base
== Py_None
) {
2125 base
= ldb_get_default_basedn(ldb_ctx
);
2127 if (!pyldb_Object_AsDn(mem_ctx
, py_base
, ldb_ctx
, &base
)) {
2128 talloc_free(mem_ctx
);
2133 if (py_controls
== Py_None
) {
2134 parsed_controls
= NULL
;
2136 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
2137 if (controls
== NULL
) {
2138 talloc_free(mem_ctx
);
2141 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
2142 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
2143 talloc_free(mem_ctx
);
2144 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
2147 talloc_free(controls
);
2150 res
= talloc_zero(mem_ctx
, struct ldb_result
);
2153 talloc_free(mem_ctx
);
2157 ret
= ldb_build_search_req(&req
, ldb_ctx
, mem_ctx
,
2164 ldb_search_default_callback
,
2167 if (ret
!= LDB_SUCCESS
) {
2168 talloc_free(mem_ctx
);
2169 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2173 talloc_steal(req
, attrs
);
2175 ret
= ldb_request(ldb_ctx
, req
);
2177 if (ret
== LDB_SUCCESS
) {
2178 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
2181 if (ret
!= LDB_SUCCESS
) {
2182 talloc_free(mem_ctx
);
2183 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2187 py_ret
= PyLdbResult_FromResult(res
);
2189 talloc_free(mem_ctx
);
2194 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply
*reply
)
2196 if (reply
->py_iter
!= NULL
) {
2197 DLIST_REMOVE(reply
->py_iter
->state
.next
, reply
);
2198 if (reply
->py_iter
->state
.result
== reply
) {
2199 reply
->py_iter
->state
.result
= NULL
;
2201 reply
->py_iter
= NULL
;
2204 Py_CLEAR(reply
->obj
);
2209 static int py_ldb_search_iterator_callback(struct ldb_request
*req
,
2210 struct ldb_reply
*ares
)
2212 PyLdbSearchIteratorObject
*py_iter
= (PyLdbSearchIteratorObject
*)req
->context
;
2213 struct ldb_result result
= { .msgs
= NULL
};
2214 struct py_ldb_search_iterator_reply
*reply
= NULL
;
2217 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2220 if (ares
->error
!= LDB_SUCCESS
) {
2221 int ret
= ares
->error
;
2223 return ldb_request_done(req
, ret
);
2226 reply
= talloc_zero(py_iter
->mem_ctx
,
2227 struct py_ldb_search_iterator_reply
);
2228 if (reply
== NULL
) {
2230 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2232 reply
->py_iter
= py_iter
;
2233 talloc_set_destructor(reply
, py_ldb_search_iterator_reply_destructor
);
2235 switch (ares
->type
) {
2236 case LDB_REPLY_ENTRY
:
2237 reply
->obj
= PyLdbMessage_FromMessage(ares
->message
);
2238 if (reply
->obj
== NULL
) {
2240 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2242 DLIST_ADD_END(py_iter
->state
.next
, reply
);
2246 case LDB_REPLY_REFERRAL
:
2247 reply
->obj
= PyUnicode_FromString(ares
->referral
);
2248 if (reply
->obj
== NULL
) {
2250 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2252 DLIST_ADD_END(py_iter
->state
.next
, reply
);
2256 case LDB_REPLY_DONE
:
2257 result
= (struct ldb_result
) { .controls
= ares
->controls
};
2258 reply
->obj
= PyLdbResult_FromResult(&result
);
2259 if (reply
->obj
== NULL
) {
2261 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2263 py_iter
->state
.result
= reply
;
2265 return ldb_request_done(req
, LDB_SUCCESS
);
2269 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2272 static PyObject
*py_ldb_search_iterator(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
2274 PyObject
*py_base
= Py_None
;
2275 int scope
= LDB_SCOPE_DEFAULT
;
2278 PyObject
*py_attrs
= Py_None
;
2279 PyObject
*py_controls
= Py_None
;
2280 const char * const kwnames
[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL
};
2283 struct ldb_context
*ldb_ctx
;
2284 struct ldb_control
**parsed_controls
;
2285 struct ldb_dn
*base
;
2286 PyLdbSearchIteratorObject
*py_iter
;
2288 /* type "int" rather than "enum" for "scope" is intentional */
2289 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OizOOi",
2290 discard_const_p(char *, kwnames
),
2291 &py_base
, &scope
, &expr
, &py_attrs
, &py_controls
, &timeout
))
2294 py_iter
= (PyLdbSearchIteratorObject
*)PyLdbSearchIterator
.tp_alloc(&PyLdbSearchIterator
, 0);
2295 if (py_iter
== NULL
) {
2299 py_iter
->ldb
= self
;
2301 ZERO_STRUCT(py_iter
->state
);
2302 py_iter
->mem_ctx
= talloc_new(NULL
);
2303 if (py_iter
->mem_ctx
== NULL
) {
2309 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2311 if (py_attrs
== Py_None
) {
2314 attrs
= PyList_AsStrList(py_iter
->mem_ctx
, py_attrs
, "attrs");
2315 if (attrs
== NULL
) {
2322 if (py_base
== Py_None
) {
2323 base
= ldb_get_default_basedn(ldb_ctx
);
2325 if (!pyldb_Object_AsDn(py_iter
->mem_ctx
, py_base
, ldb_ctx
, &base
)) {
2332 if (py_controls
== Py_None
) {
2333 parsed_controls
= NULL
;
2335 const char **controls
= NULL
;
2337 controls
= PyList_AsStrList(py_iter
->mem_ctx
,
2338 py_controls
, "controls");
2339 if (controls
== NULL
) {
2345 parsed_controls
= ldb_parse_control_strings(ldb_ctx
,
2348 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
2350 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
2353 talloc_free(controls
);
2356 ret
= ldb_build_search_req(&py_iter
->state
.req
,
2365 py_ldb_search_iterator_callback
,
2367 if (ret
!= LDB_SUCCESS
) {
2369 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2373 ldb_set_timeout(ldb_ctx
, py_iter
->state
.req
, timeout
);
2375 ret
= ldb_request(ldb_ctx
, py_iter
->state
.req
);
2376 if (ret
!= LDB_SUCCESS
) {
2378 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2382 return (PyObject
*)py_iter
;
2385 static PyObject
*py_ldb_get_opaque(PyLdbObject
*self
, PyObject
*args
)
2390 if (!PyArg_ParseTuple(args
, "s", &name
))
2393 data
= ldb_get_opaque(pyldb_Ldb_AS_LDBCONTEXT(self
), name
);
2398 if (data
== (void *)1) {
2400 * This value is sometimes used to indicate that a opaque is
2408 * Let’s hope the opaque data is actually a talloc pointer,
2409 * otherwise calling this would be Very Bad.
2411 const bool *opaque
= talloc_get_type(data
, bool);
2412 if (opaque
!= NULL
) {
2413 return PyBool_FromLong(*opaque
);
2418 const unsigned long long *opaque
= talloc_get_type(
2419 data
, unsigned long long);
2420 if (opaque
!= NULL
) {
2421 return PyLong_FromUnsignedLongLong(*opaque
);
2426 const char *opaque
= talloc_get_type(data
, char);
2427 if (opaque
!= NULL
) {
2428 return PyUnicode_FromString(opaque
);
2432 PyErr_SetString(PyExc_ValueError
, "Unsupported type for opaque");
2436 static PyObject
*py_ldb_set_opaque(PyLdbObject
*self
, PyObject
*args
)
2443 if (!PyArg_ParseTuple(args
, "sO", &name
, &data
))
2446 if (data
== Py_None
) {
2448 } else if (PyBool_Check(data
)) {
2449 bool *opaque
= NULL
;
2452 const int is_true
= PyObject_IsTrue(data
);
2453 if (is_true
== -1) {
2459 opaque
= talloc(self
->ldb_ctx
, bool);
2460 if (opaque
== NULL
) {
2461 return PyErr_NoMemory();
2465 } else if (PyLong_Check(data
)) {
2466 unsigned long long *opaque
= NULL
;
2467 const unsigned long long n
= PyLong_AsUnsignedLongLong(data
);
2468 if (n
== -1 && PyErr_Occurred()) {
2472 opaque
= talloc(self
->ldb_ctx
, unsigned long long);
2473 if (opaque
== NULL
) {
2474 return PyErr_NoMemory();
2478 } else if (PyUnicode_Check(data
)) {
2479 char *opaque
= NULL
;
2480 const char *s
= PyUnicode_AsUTF8(data
);
2485 opaque
= talloc_strdup(self
->ldb_ctx
, s
);
2486 if (opaque
== NULL
) {
2487 return PyErr_NoMemory();
2491 * Assign the right type to the talloc pointer, so that
2492 * py_ldb_get_opaque() can recognize it.
2494 talloc_set_name_const(opaque
, "char");
2498 PyErr_SetString(PyExc_ValueError
,
2499 "Unsupported type for opaque");
2503 ret
= ldb_set_opaque(pyldb_Ldb_AS_LDBCONTEXT(self
), name
, value
);
2505 PyErr_SetLdbError(PyExc_LdbError
,
2507 pyldb_Ldb_AS_LDBCONTEXT(self
));
2514 static PyObject
*py_ldb_sequence_number(PyLdbObject
*self
, PyObject
*args
)
2516 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2520 if (!PyArg_ParseTuple(args
, "i", &type
))
2523 /* FIXME: More interpretation */
2525 ret
= ldb_sequence_number(ldb
, type
, &value
);
2527 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2529 return PyLong_FromLongLong(value
);
2532 static PyObject
*py_ldb_whoami(PyLdbObject
*self
, PyObject
*args
)
2534 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2535 struct ldb_result
*res
= NULL
;
2536 struct ldb_extended
*ext_res
= NULL
;
2540 ret
= ldb_extended(ldb
, LDB_EXTENDED_WHOAMI_OID
, NULL
, &res
);
2541 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2543 ext_res
= res
->extended
;
2544 if (ext_res
== NULL
) {
2545 PyErr_SetString(PyExc_TypeError
, "Got no exop reply");
2549 if (strcmp(ext_res
->oid
, LDB_EXTENDED_WHOAMI_OID
) != 0) {
2550 PyErr_SetString(PyExc_TypeError
, "Got wrong reply OID");
2554 len
= talloc_get_size(ext_res
->data
);
2559 return PyUnicode_FromStringAndSize(ext_res
->data
, len
);
2563 static const struct ldb_dn_extended_syntax test_dn_syntax
= {
2565 .read_fn
= ldb_handler_copy
,
2566 .write_clear_fn
= ldb_handler_copy
,
2567 .write_hex_fn
= ldb_handler_copy
,
2570 static PyObject
*py_ldb_register_test_extensions(PyLdbObject
*self
,
2571 PyObject
*Py_UNUSED(ignored
))
2573 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2576 ret
= ldb_dn_extended_add_syntax(ldb
, LDB_ATTR_FLAG_FIXED
, &test_dn_syntax
);
2578 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2584 static PyMethodDef py_ldb_methods
[] = {
2585 { "set_debug", (PyCFunction
)py_ldb_set_debug
, METH_VARARGS
,
2586 "S.set_debug(callback) -> None\n"
2587 "Set callback for LDB debug messages.\n"
2588 "The callback should accept a debug level and debug text." },
2589 { "set_create_perms", (PyCFunction
)py_ldb_set_create_perms
, METH_VARARGS
,
2590 "S.set_create_perms(mode) -> None\n"
2591 "Set mode to use when creating new LDB files." },
2592 { "set_modules_dir", (PyCFunction
)py_ldb_set_modules_dir
, METH_VARARGS
,
2593 "S.set_modules_dir(path) -> None\n"
2594 "Set path LDB should search for modules" },
2595 { "transaction_start", (PyCFunction
)py_ldb_transaction_start
, METH_NOARGS
,
2596 "S.transaction_start() -> None\n"
2597 "Start a new transaction." },
2598 { "transaction_prepare_commit", (PyCFunction
)py_ldb_transaction_prepare_commit
, METH_NOARGS
,
2599 "S.transaction_prepare_commit() -> None\n"
2600 "prepare to commit a new transaction (2-stage commit)." },
2601 { "transaction_commit", (PyCFunction
)py_ldb_transaction_commit
, METH_NOARGS
,
2602 "S.transaction_commit() -> None\n"
2603 "commit a new transaction." },
2604 { "transaction_cancel", (PyCFunction
)py_ldb_transaction_cancel
, METH_NOARGS
,
2605 "S.transaction_cancel() -> None\n"
2606 "cancel a new transaction." },
2607 { "setup_wellknown_attributes", (PyCFunction
)py_ldb_setup_wellknown_attributes
, METH_NOARGS
,
2609 { "get_root_basedn", (PyCFunction
)py_ldb_get_root_basedn
, METH_NOARGS
,
2611 { "get_schema_basedn", (PyCFunction
)py_ldb_get_schema_basedn
, METH_NOARGS
,
2613 { "get_default_basedn", (PyCFunction
)py_ldb_get_default_basedn
, METH_NOARGS
,
2615 { "get_config_basedn", (PyCFunction
)py_ldb_get_config_basedn
, METH_NOARGS
,
2617 { "connect", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_connect
),
2618 METH_VARARGS
|METH_KEYWORDS
,
2619 "S.connect(url, flags=0, options=None) -> None\n"
2620 "Connect to a LDB URL." },
2621 { "modify", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_modify
),
2622 METH_VARARGS
|METH_KEYWORDS
,
2623 "S.modify(message, controls=None, validate=False) -> None\n"
2624 "Modify an entry." },
2625 { "add", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_add
),
2626 METH_VARARGS
|METH_KEYWORDS
,
2627 "S.add(message, controls=None) -> None\n"
2629 { "delete", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_delete
),
2630 METH_VARARGS
|METH_KEYWORDS
,
2631 "S.delete(dn, controls=None) -> None\n"
2632 "Remove an entry." },
2633 { "rename", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_rename
),
2634 METH_VARARGS
|METH_KEYWORDS
,
2635 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2636 "Rename an entry." },
2637 { "search", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_search
),
2638 METH_VARARGS
|METH_KEYWORDS
,
2639 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\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 ":return: ldb.Result object\n"
2649 { "search_iterator", PY_DISCARD_FUNC_SIG(PyCFunction
,
2650 py_ldb_search_iterator
),
2651 METH_VARARGS
|METH_KEYWORDS
,
2652 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2653 "Search in a database.\n"
2655 ":param base: Optional base DN to search\n"
2656 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2657 ":param expression: Optional search expression\n"
2658 ":param attrs: Attributes to return (defaults to all)\n"
2659 ":param controls: Optional list of controls\n"
2660 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2661 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2663 { "schema_attribute_remove", (PyCFunction
)py_ldb_schema_attribute_remove
, METH_VARARGS
,
2665 { "schema_attribute_add", (PyCFunction
)py_ldb_schema_attribute_add
, METH_VARARGS
,
2667 { "schema_format_value", (PyCFunction
)py_ldb_schema_format_value
, METH_VARARGS
,
2669 { "parse_ldif", (PyCFunction
)py_ldb_parse_ldif
, METH_VARARGS
,
2670 "S.parse_ldif(ldif) -> iter(messages)\n"
2671 "Parse a string formatted using LDIF." },
2672 { "write_ldif", (PyCFunction
)py_ldb_write_ldif
, METH_VARARGS
,
2673 "S.write_ldif(message, changetype) -> ldif\n"
2674 "Print the message as a string formatted using LDIF." },
2675 { "msg_diff", (PyCFunction
)py_ldb_msg_diff
, METH_VARARGS
,
2676 "S.msg_diff(Message) -> Message\n"
2677 "Return an LDB Message of the difference between two Message objects." },
2678 { "get_opaque", (PyCFunction
)py_ldb_get_opaque
, METH_VARARGS
,
2679 "S.get_opaque(name) -> value\n"
2680 "Get an opaque value set on this LDB connection. \n"
2681 ":note: The returned value may not be useful in Python."
2683 { "set_opaque", (PyCFunction
)py_ldb_set_opaque
, METH_VARARGS
,
2684 "S.set_opaque(name, value) -> None\n"
2685 "Set an opaque value on this LDB connection. \n"
2686 ":note: Passing incorrect values may cause crashes." },
2687 { "sequence_number", (PyCFunction
)py_ldb_sequence_number
, METH_VARARGS
,
2688 "S.sequence_number(type) -> value\n"
2689 "Return the value of the sequence according to the requested type" },
2691 (PyCFunction
)py_ldb_whoami
,
2693 "S.whoami() -> value\n"
2694 "Return the RFC4532 whoami string",
2696 { "_register_test_extensions", (PyCFunction
)py_ldb_register_test_extensions
, METH_NOARGS
,
2697 "S._register_test_extensions() -> None\n"
2698 "Register internal extensions used in testing" },
2702 static int py_ldb_contains(PyLdbObject
*self
, PyObject
*obj
)
2704 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2706 struct ldb_result
*result
;
2710 if (!pyldb_Object_AsDn(ldb_ctx
, obj
, ldb_ctx
, &dn
)) {
2714 ret
= ldb_search(ldb_ctx
, ldb_ctx
, &result
, dn
, LDB_SCOPE_BASE
, NULL
,
2716 if (ret
!= LDB_SUCCESS
) {
2717 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2721 count
= result
->count
;
2723 talloc_free(result
);
2726 PyErr_Format(PyExc_RuntimeError
,
2727 "Searching for [%s] dn gave %u results!",
2728 ldb_dn_get_linearized(dn
),
2736 static PySequenceMethods py_ldb_seq
= {
2737 .sq_contains
= (objobjproc
)py_ldb_contains
,
2740 static void py_ldb_dealloc(PyLdbObject
*self
)
2742 talloc_free(self
->mem_ctx
);
2743 Py_TYPE(self
)->tp_free(self
);
2746 static PyTypeObject PyLdb
= {
2747 .tp_name
= "ldb.Ldb",
2748 .tp_methods
= py_ldb_methods
,
2749 .tp_repr
= (reprfunc
)py_ldb_repr
,
2750 .tp_new
= py_ldb_new
,
2751 .tp_init
= (initproc
)py_ldb_init
,
2752 .tp_dealloc
= (destructor
)py_ldb_dealloc
,
2753 .tp_getattro
= PyObject_GenericGetAttr
,
2754 .tp_basicsize
= sizeof(PyLdbObject
),
2755 .tp_doc
= "Connection to a LDB database.",
2756 .tp_as_sequence
= &py_ldb_seq
,
2757 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
2760 static void py_ldb_result_dealloc(PyLdbResultObject
*self
)
2762 talloc_free(self
->mem_ctx
);
2763 Py_CLEAR(self
->msgs
);
2764 Py_CLEAR(self
->referals
);
2765 Py_CLEAR(self
->controls
);
2766 Py_TYPE(self
)->tp_free(self
);
2769 static PyObject
*py_ldb_result_get_msgs(PyLdbResultObject
*self
, void *closure
)
2771 Py_INCREF(self
->msgs
);
2775 static PyObject
*py_ldb_result_get_controls(PyLdbResultObject
*self
, void *closure
)
2777 Py_INCREF(self
->controls
);
2778 return self
->controls
;
2781 static PyObject
*py_ldb_result_get_referals(PyLdbResultObject
*self
, void *closure
)
2783 Py_INCREF(self
->referals
);
2784 return self
->referals
;
2787 static PyObject
*py_ldb_result_get_count(PyLdbResultObject
*self
, void *closure
)
2790 if (self
->msgs
== NULL
) {
2791 PyErr_SetString(PyExc_AttributeError
, "Count attribute is meaningless in this context");
2794 size
= PyList_Size(self
->msgs
);
2795 return PyLong_FromLong(size
);
2798 static PyGetSetDef py_ldb_result_getset
[] = {
2800 .name
= discard_const_p(char, "controls"),
2801 .get
= (getter
)py_ldb_result_get_controls
,
2804 .name
= discard_const_p(char, "msgs"),
2805 .get
= (getter
)py_ldb_result_get_msgs
,
2808 .name
= discard_const_p(char, "referals"),
2809 .get
= (getter
)py_ldb_result_get_referals
,
2812 .name
= discard_const_p(char, "count"),
2813 .get
= (getter
)py_ldb_result_get_count
,
2818 static PyObject
*py_ldb_result_iter(PyLdbResultObject
*self
)
2820 return PyObject_GetIter(self
->msgs
);
2823 static Py_ssize_t
py_ldb_result_len(PyLdbResultObject
*self
)
2825 return PySequence_Size(self
->msgs
);
2828 static PyObject
*py_ldb_result_find(PyLdbResultObject
*self
, Py_ssize_t idx
)
2830 return PySequence_GetItem(self
->msgs
, idx
);
2833 static PySequenceMethods py_ldb_result_seq
= {
2834 .sq_length
= (lenfunc
)py_ldb_result_len
,
2835 .sq_item
= (ssizeargfunc
)py_ldb_result_find
,
2838 static PyObject
*py_ldb_result_repr(PyLdbObject
*self
)
2840 return PyUnicode_FromString("<ldb result>");
2844 static PyTypeObject PyLdbResult
= {
2845 .tp_name
= "ldb.Result",
2846 .tp_repr
= (reprfunc
)py_ldb_result_repr
,
2847 .tp_dealloc
= (destructor
)py_ldb_result_dealloc
,
2848 .tp_iter
= (getiterfunc
)py_ldb_result_iter
,
2849 .tp_getset
= py_ldb_result_getset
,
2850 .tp_getattro
= PyObject_GenericGetAttr
,
2851 .tp_basicsize
= sizeof(PyLdbResultObject
),
2852 .tp_as_sequence
= &py_ldb_result_seq
,
2853 .tp_doc
= "LDB result.",
2854 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
2857 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject
*self
)
2859 Py_CLEAR(self
->state
.exception
);
2860 TALLOC_FREE(self
->mem_ctx
);
2861 ZERO_STRUCT(self
->state
);
2862 Py_CLEAR(self
->ldb
);
2863 Py_TYPE(self
)->tp_free(self
);
2866 static PyObject
*py_ldb_search_iterator_next(PyLdbSearchIteratorObject
*self
)
2868 PyObject
*py_ret
= NULL
;
2870 if (self
->state
.req
== NULL
) {
2871 PyErr_SetString(PyExc_RuntimeError
,
2872 "ldb.SearchIterator request already finished");
2877 * TODO: do we want a non-blocking mode?
2878 * In future we may add an optional 'nonblocking'
2879 * argument to search_iterator().
2881 * For now we keep it simple and wait for at
2885 while (self
->state
.next
== NULL
) {
2888 if (self
->state
.result
!= NULL
) {
2890 * We (already) got a final result from the server.
2892 * We stop the iteration and let
2893 * py_ldb_search_iterator_result() will deliver
2894 * the result details.
2896 TALLOC_FREE(self
->state
.req
);
2897 PyErr_SetNone(PyExc_StopIteration
);
2901 ret
= ldb_wait(self
->state
.req
->handle
, LDB_WAIT_NONE
);
2902 if (ret
!= LDB_SUCCESS
) {
2903 struct ldb_context
*ldb_ctx
;
2904 TALLOC_FREE(self
->state
.req
);
2905 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
->ldb
);
2907 * We stop the iteration and let
2908 * py_ldb_search_iterator_result() will deliver
2911 self
->state
.exception
= Py_BuildValue(discard_const_p(char, "(i,s)"),
2912 ret
, ldb_errstring(ldb_ctx
));
2913 PyErr_SetNone(PyExc_StopIteration
);
2918 py_ret
= self
->state
.next
->obj
;
2919 self
->state
.next
->obj
= NULL
;
2920 /* no TALLOC_FREE() as self->state.next is a list */
2921 talloc_free(self
->state
.next
);
2925 static PyObject
*py_ldb_search_iterator_result(PyLdbSearchIteratorObject
*self
,
2926 PyObject
*Py_UNUSED(ignored
))
2928 PyObject
*py_ret
= NULL
;
2930 if (self
->state
.req
!= NULL
) {
2931 PyErr_SetString(PyExc_RuntimeError
,
2932 "ldb.SearchIterator request running");
2936 if (self
->state
.next
!= NULL
) {
2937 PyErr_SetString(PyExc_RuntimeError
,
2938 "ldb.SearchIterator not fully consumed.");
2942 if (self
->state
.exception
!= NULL
) {
2943 PyErr_SetObject(PyExc_LdbError
, self
->state
.exception
);
2944 Py_DECREF(self
->state
.exception
);
2945 self
->state
.exception
= NULL
;
2949 if (self
->state
.result
== NULL
) {
2950 PyErr_SetString(PyExc_RuntimeError
,
2951 "ldb.SearchIterator result already consumed");
2955 py_ret
= self
->state
.result
->obj
;
2956 self
->state
.result
->obj
= NULL
;
2957 TALLOC_FREE(self
->state
.result
);
2961 static PyObject
*py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject
*self
,
2962 PyObject
*Py_UNUSED(ignored
))
2964 if (self
->state
.req
== NULL
) {
2965 PyErr_SetString(PyExc_RuntimeError
,
2966 "ldb.SearchIterator request already finished");
2970 Py_CLEAR(self
->state
.exception
);
2971 TALLOC_FREE(self
->mem_ctx
);
2972 ZERO_STRUCT(self
->state
);
2976 static PyMethodDef py_ldb_search_iterator_methods
[] = {
2977 { "result", (PyCFunction
)py_ldb_search_iterator_result
, METH_NOARGS
,
2978 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2979 { "abandon", (PyCFunction
)py_ldb_search_iterator_abandon
, METH_NOARGS
,
2984 static PyObject
*py_ldb_search_iterator_repr(PyLdbSearchIteratorObject
*self
)
2986 return PyUnicode_FromString("<ldb search iterator>");
2989 static PyTypeObject PyLdbSearchIterator
= {
2990 .tp_name
= "ldb.SearchIterator",
2991 .tp_repr
= (reprfunc
)py_ldb_search_iterator_repr
,
2992 .tp_dealloc
= (destructor
)py_ldb_search_iterator_dealloc
,
2993 .tp_iter
= PyObject_SelfIter
,
2994 .tp_iternext
= (iternextfunc
)py_ldb_search_iterator_next
,
2995 .tp_methods
= py_ldb_search_iterator_methods
,
2996 .tp_basicsize
= sizeof(PyLdbSearchIteratorObject
),
2997 .tp_doc
= "LDB search_iterator.",
2998 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
3002 * Create a ldb_message_element from a Python object.
3004 * This will accept any sequence objects that contains strings, or
3007 * A reference to set_obj might be borrowed.
3009 * @param mem_ctx Memory context
3010 * @param set_obj Python object to convert
3011 * @param flags ldb_message_element flags to set, if a new element is returned
3012 * @param attr_name Name of the attribute to set, if a new element is returned
3013 * @return New ldb_message_element, allocated as child of mem_ctx
3015 static struct ldb_message_element
*PyObject_AsMessageElement(
3016 TALLOC_CTX
*mem_ctx
,
3019 const char *attr_name
)
3021 struct ldb_message_element
*me
;
3022 const char *msg
= NULL
;
3026 if (pyldb_MessageElement_Check(set_obj
)) {
3027 PyLdbMessageElementObject
*set_obj_as_me
= (PyLdbMessageElementObject
*)set_obj
;
3028 /* We have to talloc_reference() the memory context, not the pointer
3029 * which may not actually be it's own context */
3030 if (talloc_reference(mem_ctx
, set_obj_as_me
->mem_ctx
)) {
3031 return pyldb_MessageElement_AsMessageElement(set_obj
);
3036 me
= talloc(mem_ctx
, struct ldb_message_element
);
3042 me
->name
= talloc_strdup(me
, attr_name
);
3043 if (me
->name
== NULL
) {
3049 if (PyBytes_Check(set_obj
) || PyUnicode_Check(set_obj
)) {
3051 me
->values
= talloc_array(me
, struct ldb_val
, me
->num_values
);
3052 if (PyBytes_Check(set_obj
)) {
3054 result
= PyBytes_AsStringAndSize(set_obj
, &_msg
, &size
);
3061 msg
= PyUnicode_AsUTF8AndSize(set_obj
, &size
);
3067 me
->values
[0].data
= talloc_memdup(me
,
3068 (const uint8_t *)msg
,
3070 me
->values
[0].length
= size
;
3071 } else if (PySequence_Check(set_obj
)) {
3073 me
->num_values
= PySequence_Size(set_obj
);
3074 me
->values
= talloc_array(me
, struct ldb_val
, me
->num_values
);
3075 for (i
= 0; i
< me
->num_values
; i
++) {
3076 PyObject
*obj
= PySequence_GetItem(set_obj
, i
);
3077 if (PyBytes_Check(obj
)) {
3079 result
= PyBytes_AsStringAndSize(obj
, &_msg
, &size
);
3085 } else if (PyUnicode_Check(obj
)) {
3086 msg
= PyUnicode_AsUTF8AndSize(obj
, &size
);
3092 PyErr_Format(PyExc_TypeError
,
3093 "Expected string as element %zd in list", i
);
3097 me
->values
[i
].data
= talloc_memdup(me
,
3098 (const uint8_t *)msg
,
3100 me
->values
[i
].length
= size
;
3103 PyErr_Format(PyExc_TypeError
,
3104 "String or List type expected for '%s' attribute", attr_name
);
3113 static PyObject
*ldb_msg_element_to_set(struct ldb_context
*ldb_ctx
,
3114 struct ldb_message_element
*me
)
3119 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
3120 result
= PyList_New(me
->num_values
);
3121 if (result
== NULL
) {
3125 for (i
= 0; i
< me
->num_values
; i
++) {
3126 PyObject
*obj
= NULL
;
3129 obj
= PyObject_FromLdbValue(&me
->values
[i
]);
3135 ret
= PyList_SetItem(result
, i
, obj
);
3146 static PyObject
*py_ldb_msg_element_get(PyLdbMessageElementObject
*self
, PyObject
*args
)
3149 if (!PyArg_ParseTuple(args
, "I", &i
))
3151 if (i
>= pyldb_MessageElement_AsMessageElement(self
)->num_values
)
3154 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self
)->values
[i
]));
3157 static PyObject
*py_ldb_msg_element_flags(PyLdbMessageElementObject
*self
, PyObject
*args
)
3159 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3160 return PyLong_FromLong(el
->flags
);
3163 static PyObject
*py_ldb_msg_element_set_flags(PyLdbMessageElementObject
*self
, PyObject
*args
)
3166 struct ldb_message_element
*el
;
3167 if (!PyArg_ParseTuple(args
, "I", &flags
))
3170 el
= pyldb_MessageElement_AsMessageElement(self
);
3175 static PyMethodDef py_ldb_msg_element_methods
[] = {
3176 { "get", (PyCFunction
)py_ldb_msg_element_get
, METH_VARARGS
, NULL
},
3177 { "set_flags", (PyCFunction
)py_ldb_msg_element_set_flags
, METH_VARARGS
, NULL
},
3178 { "flags", (PyCFunction
)py_ldb_msg_element_flags
, METH_NOARGS
, NULL
},
3182 static Py_ssize_t
py_ldb_msg_element_len(PyLdbMessageElementObject
*self
)
3184 return pyldb_MessageElement_AsMessageElement(self
)->num_values
;
3187 static PyObject
*py_ldb_msg_element_find(PyLdbMessageElementObject
*self
, Py_ssize_t idx
)
3189 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3190 if (idx
< 0 || idx
>= el
->num_values
) {
3191 PyErr_SetString(PyExc_IndexError
, "Out of range");
3194 return PyLdbBytes_FromStringAndSize((char *)el
->values
[idx
].data
, el
->values
[idx
].length
);
3197 static PySequenceMethods py_ldb_msg_element_seq
= {
3198 .sq_length
= (lenfunc
)py_ldb_msg_element_len
,
3199 .sq_item
= (ssizeargfunc
)py_ldb_msg_element_find
,
3202 static PyObject
*py_ldb_msg_element_richcmp(PyObject
*self
, PyObject
*other
, int op
)
3205 if (!pyldb_MessageElement_Check(other
)) {
3206 Py_INCREF(Py_NotImplemented
);
3207 return Py_NotImplemented
;
3209 ret
= ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self
),
3210 pyldb_MessageElement_AsMessageElement(other
));
3211 return richcmp(ret
, op
);
3214 static PyObject
*py_ldb_msg_element_iter(PyLdbMessageElementObject
*self
)
3216 PyObject
*el
= ldb_msg_element_to_set(NULL
,
3217 pyldb_MessageElement_AsMessageElement(self
));
3218 PyObject
*ret
= PyObject_GetIter(el
);
3223 static PyObject
*PyLdbMessageElement_FromMessageElement(struct ldb_message_element
*el
, TALLOC_CTX
*mem_ctx
)
3225 TALLOC_CTX
*ret_mem_ctx
= NULL
;
3226 PyLdbMessageElementObject
*ret
;
3228 ret_mem_ctx
= talloc_new(NULL
);
3229 if (ret_mem_ctx
== NULL
) {
3230 return PyErr_NoMemory();
3233 if (talloc_reference(ret_mem_ctx
, mem_ctx
) == NULL
) {
3234 talloc_free(ret_mem_ctx
);
3239 ret
= PyObject_New(PyLdbMessageElementObject
, &PyLdbMessageElement
);
3241 talloc_free(ret_mem_ctx
);
3245 ret
->mem_ctx
= ret_mem_ctx
;
3247 return (PyObject
*)ret
;
3250 static PyObject
*py_ldb_msg_element_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
3252 PyObject
*py_elements
= NULL
;
3253 struct ldb_message_element
*el
;
3254 unsigned int flags
= 0;
3256 const char * const kwnames
[] = { "elements", "flags", "name", NULL
};
3257 PyLdbMessageElementObject
*ret
;
3258 TALLOC_CTX
*mem_ctx
;
3259 const char *msg
= NULL
;
3263 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OIs",
3264 discard_const_p(char *, kwnames
),
3265 &py_elements
, &flags
, &name
))
3268 mem_ctx
= talloc_new(NULL
);
3269 if (mem_ctx
== NULL
) {
3274 el
= talloc_zero(mem_ctx
, struct ldb_message_element
);
3277 talloc_free(mem_ctx
);
3281 if (py_elements
!= NULL
) {
3283 if (PyBytes_Check(py_elements
) || PyUnicode_Check(py_elements
)) {
3286 el
->values
= talloc_array(el
, struct ldb_val
, 1);
3287 if (el
->values
== NULL
) {
3288 talloc_free(mem_ctx
);
3292 if (PyBytes_Check(py_elements
)) {
3293 result
= PyBytes_AsStringAndSize(py_elements
, &_msg
, &size
);
3296 msg
= PyUnicode_AsUTF8AndSize(py_elements
, &size
);
3297 result
= (msg
== NULL
) ? -1 : 0;
3300 talloc_free(mem_ctx
);
3303 el
->values
[0].data
= talloc_memdup(el
->values
,
3304 (const uint8_t *)msg
, size
+ 1);
3305 el
->values
[0].length
= size
;
3306 } else if (PySequence_Check(py_elements
)) {
3307 el
->num_values
= PySequence_Size(py_elements
);
3308 el
->values
= talloc_array(el
, struct ldb_val
, el
->num_values
);
3309 if (el
->values
== NULL
) {
3310 talloc_free(mem_ctx
);
3314 for (i
= 0; i
< el
->num_values
; i
++) {
3315 PyObject
*item
= PySequence_GetItem(py_elements
, i
);
3317 talloc_free(mem_ctx
);
3320 if (PyBytes_Check(item
)) {
3322 result
= PyBytes_AsStringAndSize(item
, &_msg
, &size
);
3324 } else if (PyUnicode_Check(item
)) {
3325 msg
= PyUnicode_AsUTF8AndSize(item
, &size
);
3326 result
= (msg
== NULL
) ? -1 : 0;
3328 PyErr_Format(PyExc_TypeError
,
3329 "Expected string as element %zd in list", i
);
3333 talloc_free(mem_ctx
);
3336 el
->values
[i
].data
= talloc_memdup(el
,
3337 (const uint8_t *)msg
, size
+1);
3338 el
->values
[i
].length
= size
;
3341 PyErr_SetString(PyExc_TypeError
,
3342 "Expected string or list");
3343 talloc_free(mem_ctx
);
3350 el
->name
= talloc_strdup(el
, name
);
3351 if (el
->name
== NULL
) {
3352 talloc_free(mem_ctx
);
3353 return PyErr_NoMemory();
3357 ret
= PyObject_New(PyLdbMessageElementObject
, type
);
3359 talloc_free(mem_ctx
);
3363 ret
->mem_ctx
= mem_ctx
;
3365 return (PyObject
*)ret
;
3368 static PyObject
*py_ldb_msg_element_repr(PyLdbMessageElementObject
*self
)
3370 char *element_str
= NULL
;
3372 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3373 PyObject
*ret
, *repr
;
3375 for (i
= 0; i
< el
->num_values
; i
++) {
3376 PyObject
*o
= py_ldb_msg_element_find(self
, i
);
3377 repr
= PyObject_Repr(o
);
3378 if (element_str
== NULL
)
3379 element_str
= talloc_strdup(NULL
, PyUnicode_AsUTF8(repr
));
3381 element_str
= talloc_asprintf_append(element_str
, ",%s", PyUnicode_AsUTF8(repr
));
3384 if (element_str
== NULL
) {
3385 return PyErr_NoMemory();
3389 if (element_str
!= NULL
) {
3390 ret
= PyUnicode_FromFormat("MessageElement([%s])", element_str
);
3391 talloc_free(element_str
);
3393 ret
= PyUnicode_FromString("MessageElement([])");
3399 static PyObject
*py_ldb_msg_element_str(PyLdbMessageElementObject
*self
)
3401 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3403 if (el
->num_values
== 1)
3404 return PyUnicode_FromStringAndSize((char *)el
->values
[0].data
, el
->values
[0].length
);
3409 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject
*self
)
3411 talloc_free(self
->mem_ctx
);
3415 static PyObject
*py_ldb_msg_element_get_text(PyObject
*self
, void *closure
)
3417 return wrap_text("MessageElementTextWrapper", self
);
3420 static PyGetSetDef py_ldb_msg_element_getset
[] = {
3422 .name
= discard_const_p(char, "text"),
3423 .get
= (getter
)py_ldb_msg_element_get_text
,
3428 static PyTypeObject PyLdbMessageElement
= {
3429 .tp_name
= "ldb.MessageElement",
3430 .tp_basicsize
= sizeof(PyLdbMessageElementObject
),
3431 .tp_dealloc
= (destructor
)py_ldb_msg_element_dealloc
,
3432 .tp_repr
= (reprfunc
)py_ldb_msg_element_repr
,
3433 .tp_str
= (reprfunc
)py_ldb_msg_element_str
,
3434 .tp_methods
= py_ldb_msg_element_methods
,
3435 .tp_getset
= py_ldb_msg_element_getset
,
3436 .tp_richcompare
= (richcmpfunc
)py_ldb_msg_element_richcmp
,
3437 .tp_iter
= (getiterfunc
)py_ldb_msg_element_iter
,
3438 .tp_as_sequence
= &py_ldb_msg_element_seq
,
3439 .tp_new
= py_ldb_msg_element_new
,
3440 .tp_flags
= Py_TPFLAGS_DEFAULT
,
3441 .tp_doc
= "An element of a Message",
3445 static PyObject
*py_ldb_msg_from_dict(PyTypeObject
*type
, PyObject
*args
)
3450 struct ldb_message
*msg
;
3451 struct ldb_context
*ldb_ctx
;
3452 unsigned int mod_flags
= LDB_FLAG_MOD_REPLACE
;
3454 if (!PyArg_ParseTuple(args
, "O!O!|I",
3455 &PyLdb
, &py_ldb
, &PyDict_Type
, &py_dict
,
3460 /* mask only flags we are going to use */
3461 mod_flags
= LDB_FLAG_MOD_TYPE(mod_flags
);
3463 PyErr_SetString(PyExc_ValueError
,
3464 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3465 " expected as mod_flag value");
3469 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(py_ldb
);
3471 msg
= PyDict_AsMessage(ldb_ctx
, py_dict
, ldb_ctx
, mod_flags
);
3476 py_ret
= PyLdbMessage_FromMessage(msg
);
3478 talloc_unlink(ldb_ctx
, msg
);
3483 static PyObject
*py_ldb_msg_remove_attr(PyLdbMessageObject
*self
, PyObject
*args
)
3486 if (!PyArg_ParseTuple(args
, "s", &name
))
3489 ldb_msg_remove_attr(self
->msg
, name
);
3494 static PyObject
*py_ldb_msg_keys(PyLdbMessageObject
*self
,
3495 PyObject
*Py_UNUSED(ignored
))
3497 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3498 Py_ssize_t i
, j
= 0;
3499 PyObject
*obj
= PyList_New(msg
->num_elements
+(msg
->dn
!= NULL
?1:0));
3504 if (msg
->dn
!= NULL
) {
3505 PyObject
*py_dn
= NULL
;
3508 py_dn
= PyUnicode_FromString("dn");
3509 if (py_dn
== NULL
) {
3514 ret
= PyList_SetItem(obj
, j
, py_dn
);
3523 for (i
= 0; i
< msg
->num_elements
; i
++) {
3524 PyObject
*py_name
= NULL
;
3527 py_name
= PyUnicode_FromString(msg
->elements
[i
].name
);
3528 if (py_name
== NULL
) {
3533 ret
= PyList_SetItem(obj
, j
, py_name
);
3545 static int py_ldb_msg_contains(PyLdbMessageObject
*self
, PyObject
*py_name
)
3547 struct ldb_message_element
*el
= NULL
;
3548 const char *name
= NULL
;
3549 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3550 name
= PyUnicode_AsUTF8(py_name
);
3554 if (!ldb_attr_cmp(name
, "dn")) {
3557 el
= ldb_msg_find_element(msg
, name
);
3558 return el
!= NULL
? 1 : 0;
3561 static PyObject
*py_ldb_msg_getitem(PyLdbMessageObject
*self
, PyObject
*py_name
)
3563 struct ldb_message_element
*el
= NULL
;
3564 const char *name
= NULL
;
3565 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3566 name
= PyUnicode_AsUTF8(py_name
);
3570 if (!ldb_attr_cmp(name
, "dn")) {
3571 return pyldb_Dn_FromDn(msg
->dn
);
3573 el
= ldb_msg_find_element(msg
, name
);
3575 PyErr_SetString(PyExc_KeyError
, "No such element");
3579 return PyLdbMessageElement_FromMessageElement(el
, msg
->elements
);
3582 static PyObject
*py_ldb_msg_get(PyLdbMessageObject
*self
, PyObject
*args
, PyObject
*kwargs
)
3584 PyObject
*def
= NULL
;
3585 const char *kwnames
[] = { "name", "default", "idx", NULL
};
3586 const char *name
= NULL
;
3588 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3589 struct ldb_message_element
*el
;
3591 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|Oi:msg",
3592 discard_const_p(char *, kwnames
), &name
, &def
, &idx
)) {
3596 if (strcasecmp(name
, "dn") == 0) {
3597 return pyldb_Dn_FromDn(msg
->dn
);
3600 el
= ldb_msg_find_element(msg
, name
);
3602 if (el
== NULL
|| (idx
!= -1 && el
->num_values
<= idx
)) {
3611 return (PyObject
*)PyLdbMessageElement_FromMessageElement(el
, msg
->elements
);
3614 return PyObject_FromLdbValue(&el
->values
[idx
]);
3617 static PyObject
*py_ldb_msg_items(PyLdbMessageObject
*self
,
3618 PyObject
*Py_UNUSED(ignored
))
3620 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3621 Py_ssize_t i
, j
= 0;
3622 PyObject
*l
= PyList_New(msg
->num_elements
+ (msg
->dn
== NULL
?0:1));
3624 return PyErr_NoMemory();
3626 if (msg
->dn
!= NULL
) {
3627 PyObject
*value
= NULL
;
3628 PyObject
*obj
= pyldb_Dn_FromDn(msg
->dn
);
3630 value
= Py_BuildValue("(sO)", "dn", obj
);
3632 if (value
== NULL
) {
3636 res
= PyList_SetItem(l
, 0, value
);
3643 for (i
= 0; i
< msg
->num_elements
; i
++, j
++) {
3644 PyObject
*value
= NULL
;
3645 PyObject
*py_el
= PyLdbMessageElement_FromMessageElement(&msg
->elements
[i
], msg
->elements
);
3647 value
= Py_BuildValue("(sO)", msg
->elements
[i
].name
, py_el
);
3649 if (value
== NULL
) {
3653 res
= PyList_SetItem(l
, j
, value
);
3662 static PyObject
*py_ldb_msg_elements(PyLdbMessageObject
*self
,
3663 PyObject
*Py_UNUSED(ignored
))
3665 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3667 PyObject
*l
= PyList_New(msg
->num_elements
);
3671 for (i
= 0; i
< msg
->num_elements
; i
++) {
3672 PyObject
*msg_el
= NULL
;
3675 msg_el
= PyLdbMessageElement_FromMessageElement(&msg
->elements
[i
], msg
->elements
);
3676 if (msg_el
== NULL
) {
3681 ret
= PyList_SetItem(l
, i
, msg_el
);
3691 static PyObject
*py_ldb_msg_add(PyLdbMessageObject
*self
, PyObject
*args
)
3693 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3694 PyLdbMessageElementObject
*py_element
;
3696 struct ldb_message_element
*el
;
3697 struct ldb_message_element
*el_new
;
3699 if (!PyArg_ParseTuple(args
, "O!", &PyLdbMessageElement
, &py_element
))
3702 el
= py_element
->el
;
3704 PyErr_SetString(PyExc_ValueError
, "Invalid MessageElement object");
3707 if (el
->name
== NULL
) {
3708 PyErr_SetString(PyExc_ValueError
,
3709 "The element has no name");
3712 ret
= ldb_msg_add_empty(msg
, el
->name
, el
->flags
, &el_new
);
3713 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
3715 /* now deep copy all attribute values */
3716 el_new
->values
= talloc_array(msg
->elements
, struct ldb_val
, el
->num_values
);
3717 if (el_new
->values
== NULL
) {
3721 el_new
->num_values
= el
->num_values
;
3723 for (i
= 0; i
< el
->num_values
; i
++) {
3724 el_new
->values
[i
] = ldb_val_dup(el_new
->values
, &el
->values
[i
]);
3725 if (el_new
->values
[i
].data
== NULL
3726 && el
->values
[i
].length
!= 0) {
3735 static PyMethodDef py_ldb_msg_methods
[] = {
3736 { "from_dict", (PyCFunction
)py_ldb_msg_from_dict
, METH_CLASS
| METH_VARARGS
,
3737 "Message.from_dict(ldb, dict, mod_flag) -> ldb.Message\n"
3738 "Class method to create ldb.Message object from Dictionary.\n"
3739 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3740 { "keys", (PyCFunction
)py_ldb_msg_keys
, METH_NOARGS
,
3741 "S.keys() -> list\n\n"
3742 "Return sequence of all attribute names." },
3743 { "remove", (PyCFunction
)py_ldb_msg_remove_attr
, METH_VARARGS
,
3744 "S.remove(name)\n\n"
3745 "Remove all entries for attributes with the specified name."},
3746 { "get", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_msg_get
),
3747 METH_VARARGS
| METH_KEYWORDS
,
3748 "msg.get(name,default=None,idx=None) -> string\n"
3749 "idx is the index into the values array\n"
3750 "if idx is None, then a list is returned\n"
3751 "if idx is not None, then the element with that index is returned\n"
3752 "if you pass the special name 'dn' then the DN object is returned\n"},
3753 { "items", (PyCFunction
)py_ldb_msg_items
, METH_NOARGS
, NULL
},
3754 { "elements", (PyCFunction
)py_ldb_msg_elements
, METH_NOARGS
, NULL
},
3755 { "add", (PyCFunction
)py_ldb_msg_add
, METH_VARARGS
,
3756 "S.add(element)\n\n"
3757 "Add an element to this message." },
3761 static PyObject
*py_ldb_msg_iter(PyLdbMessageObject
*self
)
3763 PyObject
*list
, *iter
;
3765 list
= py_ldb_msg_keys(self
, NULL
);
3766 iter
= PyObject_GetIter(list
);
3771 static int py_ldb_msg_setitem(PyLdbMessageObject
*self
, PyObject
*name
, PyObject
*value
)
3773 const char *attr_name
;
3775 attr_name
= PyUnicode_AsUTF8(name
);
3776 if (attr_name
== NULL
) {
3777 PyErr_SetNone(PyExc_TypeError
);
3781 if (value
== NULL
) {
3783 ldb_msg_remove_attr(self
->msg
, attr_name
);
3786 struct ldb_message_element
*el
= PyObject_AsMessageElement(self
->msg
,
3787 value
, 0, attr_name
);
3791 if (el
->name
== NULL
) {
3793 * If ‘value’ is a MessageElement,
3794 * PyObject_AsMessageElement() will have returned a
3795 * reference to it without setting the name. We don’t
3796 * want to modify the original object to set the name
3797 * ourselves, but making a copy would result in
3798 * different behaviour for a caller relying on a
3799 * reference being kept. Rather than continue with a
3800 * NULL name (and probably fail later on), let’s catch
3801 * this potential mistake early.
3803 PyErr_SetString(PyExc_ValueError
, "MessageElement has no name set");
3804 talloc_unlink(self
->msg
, el
);
3807 ldb_msg_remove_attr(pyldb_Message_AsMessage(self
), attr_name
);
3808 ret
= ldb_msg_add(pyldb_Message_AsMessage(self
), el
, el
->flags
);
3809 if (ret
!= LDB_SUCCESS
) {
3810 PyErr_SetLdbError(PyExc_LdbError
, ret
, NULL
);
3811 talloc_unlink(self
->msg
, el
);
3818 static Py_ssize_t
py_ldb_msg_length(PyLdbMessageObject
*self
)
3820 return pyldb_Message_AsMessage(self
)->num_elements
;
3823 static PySequenceMethods py_ldb_msg_sequence
= {
3824 .sq_contains
= (objobjproc
)py_ldb_msg_contains
,
3827 static PyMappingMethods py_ldb_msg_mapping
= {
3828 .mp_length
= (lenfunc
)py_ldb_msg_length
,
3829 .mp_subscript
= (binaryfunc
)py_ldb_msg_getitem
,
3830 .mp_ass_subscript
= (objobjargproc
)py_ldb_msg_setitem
,
3833 static PyObject
*py_ldb_msg_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
3835 const char * const kwnames
[] = { "dn", NULL
};
3836 struct ldb_message
*ret
;
3837 TALLOC_CTX
*mem_ctx
;
3838 PyObject
*pydn
= NULL
;
3839 PyLdbMessageObject
*py_ret
;
3841 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|O",
3842 discard_const_p(char *, kwnames
),
3846 mem_ctx
= talloc_new(NULL
);
3847 if (mem_ctx
== NULL
) {
3852 ret
= ldb_msg_new(mem_ctx
);
3854 talloc_free(mem_ctx
);
3861 if (!pyldb_Object_AsDn(NULL
, pydn
, NULL
, &dn
)) {
3862 talloc_free(mem_ctx
);
3865 ret
->dn
= talloc_reference(ret
, dn
);
3866 if (ret
->dn
== NULL
) {
3867 talloc_free(mem_ctx
);
3868 return PyErr_NoMemory();
3872 py_ret
= (PyLdbMessageObject
*)type
->tp_alloc(type
, 0);
3873 if (py_ret
== NULL
) {
3875 talloc_free(mem_ctx
);
3879 py_ret
->mem_ctx
= mem_ctx
;
3881 return (PyObject
*)py_ret
;
3884 static PyObject
*PyLdbMessage_FromMessage(struct ldb_message
*msg
)
3886 TALLOC_CTX
*mem_ctx
= NULL
;
3887 struct ldb_message
*msg_ref
= NULL
;
3888 PyLdbMessageObject
*ret
;
3890 mem_ctx
= talloc_new(NULL
);
3891 if (mem_ctx
== NULL
) {
3892 return PyErr_NoMemory();
3895 msg_ref
= talloc_reference(mem_ctx
, msg
);
3896 if (msg_ref
== NULL
) {
3897 talloc_free(mem_ctx
);
3898 return PyErr_NoMemory();
3901 ret
= (PyLdbMessageObject
*)PyLdbMessage
.tp_alloc(&PyLdbMessage
, 0);
3903 talloc_free(mem_ctx
);
3907 ret
->mem_ctx
= mem_ctx
;
3909 return (PyObject
*)ret
;
3912 static PyObject
*py_ldb_msg_get_dn(PyLdbMessageObject
*self
, void *closure
)
3914 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3915 return pyldb_Dn_FromDn(msg
->dn
);
3918 static int py_ldb_msg_set_dn(PyLdbMessageObject
*self
, PyObject
*value
, void *closure
)
3920 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3921 struct ldb_dn
*dn
= NULL
;
3922 if (value
== NULL
) {
3923 PyErr_SetString(PyExc_AttributeError
, "cannot delete dn");
3926 if (!pyldb_Dn_Check(value
)) {
3927 PyErr_SetString(PyExc_TypeError
, "expected dn");
3931 dn
= talloc_reference(msg
, pyldb_Dn_AS_DN(value
));
3941 static PyObject
*py_ldb_msg_get_text(PyObject
*self
, void *closure
)
3943 return wrap_text("MessageTextWrapper", self
);
3946 static PyGetSetDef py_ldb_msg_getset
[] = {
3948 .name
= discard_const_p(char, "dn"),
3949 .get
= (getter
)py_ldb_msg_get_dn
,
3950 .set
= (setter
)py_ldb_msg_set_dn
,
3953 .name
= discard_const_p(char, "text"),
3954 .get
= (getter
)py_ldb_msg_get_text
,
3959 static PyObject
*py_ldb_msg_repr(PyLdbMessageObject
*self
)
3961 PyObject
*dict
= PyDict_New(), *ret
, *repr
;
3962 const char *repr_str
= NULL
;
3966 if (PyDict_Update(dict
, (PyObject
*)self
) != 0) {
3970 repr
= PyObject_Repr(dict
);
3975 repr_str
= PyUnicode_AsUTF8(repr
);
3976 if (repr_str
== NULL
) {
3981 ret
= PyUnicode_FromFormat("Message(%s)", repr_str
);
3987 static void py_ldb_msg_dealloc(PyLdbMessageObject
*self
)
3989 talloc_free(self
->mem_ctx
);
3993 static PyObject
*py_ldb_msg_richcmp(PyLdbMessageObject
*py_msg1
,
3994 PyLdbMessageObject
*py_msg2
, int op
)
3996 struct ldb_message
*msg1
, *msg2
;
4000 if (!PyLdbMessage_Check(py_msg2
)) {
4001 Py_INCREF(Py_NotImplemented
);
4002 return Py_NotImplemented
;
4005 msg1
= pyldb_Message_AsMessage(py_msg1
),
4006 msg2
= pyldb_Message_AsMessage(py_msg2
);
4008 * FIXME: this can be a non-transitive compare, unsuitable for
4011 * supposing msg1, msg2, and msg3 have 1, 2, and 3 elements
4012 * each. msg2 has a NULL DN, while msg1 has a DN that compares
4013 * higher than msg3. Then:
4015 * msg1 < msg2, due to num_elements.
4016 * msg2 < msg3, due to num_elements.
4017 * msg1 > msg3, due to DNs.
4019 if ((msg1
->dn
!= NULL
) || (msg2
->dn
!= NULL
)) {
4020 ret
= ldb_dn_compare(msg1
->dn
, msg2
->dn
);
4022 return richcmp(ret
, op
);
4026 if (msg1
->num_elements
> msg2
->num_elements
) {
4027 return richcmp(1, op
);
4029 if (msg1
->num_elements
< msg2
->num_elements
) {
4030 return richcmp(-1, op
);
4033 for (i
= 0; i
< msg1
->num_elements
; i
++) {
4034 ret
= ldb_msg_element_compare_name(&msg1
->elements
[i
],
4035 &msg2
->elements
[i
]);
4037 return richcmp(ret
, op
);
4040 ret
= ldb_msg_element_compare(&msg1
->elements
[i
],
4041 &msg2
->elements
[i
]);
4043 return richcmp(ret
, op
);
4047 return richcmp(0, op
);
4050 static PyTypeObject PyLdbMessage
= {
4051 .tp_name
= "ldb.Message",
4052 .tp_methods
= py_ldb_msg_methods
,
4053 .tp_getset
= py_ldb_msg_getset
,
4054 .tp_as_sequence
= &py_ldb_msg_sequence
,
4055 .tp_as_mapping
= &py_ldb_msg_mapping
,
4056 .tp_basicsize
= sizeof(PyLdbMessageObject
),
4057 .tp_dealloc
= (destructor
)py_ldb_msg_dealloc
,
4058 .tp_new
= py_ldb_msg_new
,
4059 .tp_repr
= (reprfunc
)py_ldb_msg_repr
,
4060 .tp_flags
= Py_TPFLAGS_DEFAULT
,
4061 .tp_iter
= (getiterfunc
)py_ldb_msg_iter
,
4062 .tp_richcompare
= (richcmpfunc
)py_ldb_msg_richcmp
,
4063 .tp_doc
= "A LDB Message",
4066 static void py_ldb_tree_dealloc(PyLdbTreeObject
*self
)
4068 talloc_free(self
->mem_ctx
);
4072 static PyTypeObject PyLdbTree
= {
4073 .tp_name
= "ldb.Tree",
4074 .tp_basicsize
= sizeof(PyLdbTreeObject
),
4075 .tp_dealloc
= (destructor
)py_ldb_tree_dealloc
,
4076 .tp_flags
= Py_TPFLAGS_DEFAULT
,
4077 .tp_doc
= "A search tree",
4080 static PyObject
*py_timestring(PyObject
*module
, PyObject
*args
)
4082 /* most times "time_t" is a signed integer type with 32 or 64 bit:
4083 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4087 if (!PyArg_ParseTuple(args
, "l", &t_val
))
4089 tresult
= ldb_timestring(NULL
, (time_t) t_val
);
4090 if (tresult
== NULL
) {
4092 * Most likely EOVERFLOW from gmtime()
4094 PyErr_SetFromErrno(PyExc_OSError
);
4097 ret
= PyUnicode_FromString(tresult
);
4098 talloc_free(tresult
);
4102 static PyObject
*py_string_to_time(PyObject
*module
, PyObject
*args
)
4106 if (!PyArg_ParseTuple(args
, "s", &str
)) {
4109 t
= ldb_string_to_time(str
);
4111 if (t
== 0 && errno
!= 0) {
4112 PyErr_SetFromErrno(PyExc_ValueError
);
4115 return PyLong_FromLong(t
);
4118 static PyObject
*py_valid_attr_name(PyObject
*self
, PyObject
*args
)
4121 if (!PyArg_ParseTuple(args
, "s", &name
))
4123 return PyBool_FromLong(ldb_valid_attr_name(name
));
4127 encode a string using RFC2254 rules
4129 static PyObject
*py_binary_encode(PyObject
*self
, PyObject
*args
)
4131 char *str
, *encoded
;
4132 Py_ssize_t size
= 0;
4136 if (!PyArg_ParseTuple(args
, "s#", &str
, &size
))
4138 val
.data
= (uint8_t *)str
;
4141 encoded
= ldb_binary_encode(NULL
, val
);
4142 if (encoded
== NULL
) {
4143 PyErr_SetString(PyExc_TypeError
, "unable to encode binary string");
4146 ret
= PyUnicode_FromString(encoded
);
4147 talloc_free(encoded
);
4152 decode a string using RFC2254 rules
4154 static PyObject
*py_binary_decode(PyObject
*self
, PyObject
*args
)
4160 if (!PyArg_ParseTuple(args
, "s", &str
))
4163 val
= ldb_binary_decode(NULL
, str
);
4164 if (val
.data
== NULL
) {
4165 PyErr_SetString(PyExc_TypeError
, "unable to decode binary string");
4168 ret
= PyBytes_FromStringAndSize((const char*)val
.data
, val
.length
);
4169 talloc_free(val
.data
);
4173 static PyMethodDef py_ldb_global_methods
[] = {
4174 { "timestring", py_timestring
, METH_VARARGS
,
4175 "S.timestring(int) -> string\n\n"
4176 "Generate a LDAP time string from a UNIX timestamp" },
4177 { "string_to_time", py_string_to_time
, METH_VARARGS
,
4178 "S.string_to_time(string) -> int\n\n"
4179 "Parse a LDAP time string into a UNIX timestamp." },
4180 { "valid_attr_name", py_valid_attr_name
, METH_VARARGS
,
4181 "S.valid_attr_name(name) -> bool\n\n"
4182 "Check whether the supplied name is a valid attribute name." },
4183 { "binary_encode", py_binary_encode
, METH_VARARGS
,
4184 "S.binary_encode(string) -> string\n\n"
4185 "Perform a RFC2254 binary encoding on a string" },
4186 { "binary_decode", py_binary_decode
, METH_VARARGS
,
4187 "S.binary_decode(string) -> string\n\n"
4188 "Perform a RFC2254 binary decode on a string" },
4192 #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."
4194 static struct PyModuleDef moduledef
= {
4195 PyModuleDef_HEAD_INIT
,
4197 .m_doc
= MODULE_DOC
,
4199 .m_methods
= py_ldb_global_methods
,
4202 static PyObject
* module_init(void)
4206 PyLdbBytesType
.tp_base
= &PyBytes_Type
;
4207 if (PyType_Ready(&PyLdbBytesType
) < 0) {
4211 if (PyType_Ready(&PyLdbDn
) < 0)
4214 if (PyType_Ready(&PyLdbMessage
) < 0)
4217 if (PyType_Ready(&PyLdbMessageElement
) < 0)
4220 if (PyType_Ready(&PyLdb
) < 0)
4223 if (PyType_Ready(&PyLdbTree
) < 0)
4226 if (PyType_Ready(&PyLdbResult
) < 0)
4229 if (PyType_Ready(&PyLdbSearchIterator
) < 0)
4232 if (PyType_Ready(&PyLdbControl
) < 0)
4235 m
= PyModule_Create(&moduledef
);
4239 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4241 ADD_LDB_INT(SEQ_HIGHEST_SEQ
);
4242 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP
);
4243 ADD_LDB_INT(SEQ_NEXT
);
4244 ADD_LDB_INT(SCOPE_DEFAULT
);
4245 ADD_LDB_INT(SCOPE_BASE
);
4246 ADD_LDB_INT(SCOPE_ONELEVEL
);
4247 ADD_LDB_INT(SCOPE_SUBTREE
);
4249 ADD_LDB_INT(CHANGETYPE_NONE
);
4250 ADD_LDB_INT(CHANGETYPE_ADD
);
4251 ADD_LDB_INT(CHANGETYPE_DELETE
);
4252 ADD_LDB_INT(CHANGETYPE_MODIFY
);
4253 ADD_LDB_INT(CHANGETYPE_MODRDN
);
4255 ADD_LDB_INT(FLAG_MOD_ADD
);
4256 ADD_LDB_INT(FLAG_MOD_REPLACE
);
4257 ADD_LDB_INT(FLAG_MOD_DELETE
);
4258 ADD_LDB_INT(FLAG_FORCE_NO_BASE64_LDIF
);
4260 ADD_LDB_INT(ATTR_FLAG_HIDDEN
);
4261 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX
);
4262 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE
);
4263 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF
);
4265 ADD_LDB_INT(SUCCESS
);
4266 ADD_LDB_INT(ERR_OPERATIONS_ERROR
);
4267 ADD_LDB_INT(ERR_PROTOCOL_ERROR
);
4268 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED
);
4269 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED
);
4270 ADD_LDB_INT(ERR_COMPARE_FALSE
);
4271 ADD_LDB_INT(ERR_COMPARE_TRUE
);
4272 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED
);
4273 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED
);
4274 ADD_LDB_INT(ERR_REFERRAL
);
4275 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED
);
4276 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION
);
4277 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED
);
4278 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS
);
4279 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE
);
4280 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE
);
4281 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING
);
4282 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION
);
4283 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS
);
4284 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX
);
4285 ADD_LDB_INT(ERR_NO_SUCH_OBJECT
);
4286 ADD_LDB_INT(ERR_ALIAS_PROBLEM
);
4287 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX
);
4288 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM
);
4289 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION
);
4290 ADD_LDB_INT(ERR_INVALID_CREDENTIALS
);
4291 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS
);
4292 ADD_LDB_INT(ERR_BUSY
);
4293 ADD_LDB_INT(ERR_UNAVAILABLE
);
4294 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM
);
4295 ADD_LDB_INT(ERR_LOOP_DETECT
);
4296 ADD_LDB_INT(ERR_NAMING_VIOLATION
);
4297 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION
);
4298 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF
);
4299 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN
);
4300 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS
);
4301 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED
);
4302 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS
);
4303 ADD_LDB_INT(ERR_OTHER
);
4305 ADD_LDB_INT(FLG_RDONLY
);
4306 ADD_LDB_INT(FLG_NOSYNC
);
4307 ADD_LDB_INT(FLG_RECONNECT
);
4308 ADD_LDB_INT(FLG_NOMMAP
);
4309 ADD_LDB_INT(FLG_SHOW_BINARY
);
4310 ADD_LDB_INT(FLG_ENABLE_TRACING
);
4311 ADD_LDB_INT(FLG_DONT_CREATE_DB
);
4313 ADD_LDB_INT(PACKING_FORMAT
);
4314 ADD_LDB_INT(PACKING_FORMAT_V2
);
4316 /* Historical misspelling */
4317 PyModule_AddIntConstant(m
, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM
);
4319 PyModule_AddStringConstant(m
, "__docformat__", "restructuredText");
4321 PyExc_LdbError
= PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL
, NULL
);
4322 PyModule_AddObject(m
, "LdbError", PyExc_LdbError
);
4325 Py_INCREF(&PyLdbDn
);
4326 Py_INCREF(&PyLdbMessage
);
4327 Py_INCREF(&PyLdbMessageElement
);
4328 Py_INCREF(&PyLdbTree
);
4329 Py_INCREF(&PyLdbResult
);
4330 Py_INCREF(&PyLdbControl
);
4332 PyModule_AddObject(m
, "Ldb", (PyObject
*)&PyLdb
);
4333 PyModule_AddObject(m
, "Dn", (PyObject
*)&PyLdbDn
);
4334 PyModule_AddObject(m
, "Message", (PyObject
*)&PyLdbMessage
);
4335 PyModule_AddObject(m
, "MessageElement", (PyObject
*)&PyLdbMessageElement
);
4336 PyModule_AddObject(m
, "Tree", (PyObject
*)&PyLdbTree
);
4337 PyModule_AddObject(m
, "Result", (PyObject
*)&PyLdbResult
);
4338 PyModule_AddObject(m
, "Control", (PyObject
*)&PyLdbControl
);
4340 PyModule_AddStringConstant(m
, "__version__", PACKAGE_VERSION
);
4342 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4344 ADD_LDB_STRING(SYNTAX_DN
);
4345 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING
);
4346 ADD_LDB_STRING(SYNTAX_INTEGER
);
4347 ADD_LDB_STRING(SYNTAX_ORDERED_INTEGER
);
4348 ADD_LDB_STRING(SYNTAX_BOOLEAN
);
4349 ADD_LDB_STRING(SYNTAX_OCTET_STRING
);
4350 ADD_LDB_STRING(SYNTAX_UTC_TIME
);
4351 ADD_LDB_STRING(OID_COMPARATOR_AND
);
4352 ADD_LDB_STRING(OID_COMPARATOR_OR
);
4357 PyMODINIT_FUNC
PyInit_ldb(void);
4358 PyMODINIT_FUNC
PyInit_ldb(void)
4360 return module_init();