2 Unix SMB/CIFS implementation.
4 Python interface to ldb.
6 Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7 Copyright (C) 2006 Simo Sorce <idra@samba.org>
8 Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
9 Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10 Copyright (C) 2009-2011 Andrew Tridgell
11 Copyright (C) 2009-2011 Andrew Bartlett
13 ** NOTE! The following LGPL license applies to the ldb
14 ** library. This does NOT imply that all of Samba is released
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of the GNU Lesser General Public
19 License as published by the Free Software Foundation; either
20 version 3 of the License, or (at your option) any later version.
22 This library is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Lesser General Public License for more details.
27 You should have received a copy of the GNU Lesser General Public
28 License along with this library; if not, see <http://www.gnu.org/licenses/>.
32 #include "ldb_private.h"
33 #include "ldb_handlers.h"
35 #include "dlinklist.h"
37 /* discard signature of 'func' in favour of 'target_sig' */
38 #define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func
40 struct py_ldb_search_iterator_reply
;
47 struct ldb_request
*req
;
48 struct py_ldb_search_iterator_reply
*next
;
49 struct py_ldb_search_iterator_reply
*result
;
52 } PyLdbSearchIteratorObject
;
54 struct py_ldb_search_iterator_reply
{
55 struct py_ldb_search_iterator_reply
*prev
, *next
;
56 PyLdbSearchIteratorObject
*py_iter
;
61 static PyObject
*PyLdbMessage_FromMessage(struct ldb_message
*msg
);
62 static PyObject
*PyExc_LdbError
;
64 static PyTypeObject PyLdbControl
;
65 static PyTypeObject PyLdbResult
;
66 static PyTypeObject PyLdbSearchIterator
;
67 static PyTypeObject PyLdbMessage
;
68 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
69 static PyTypeObject PyLdbModule
;
70 static PyTypeObject PyLdbDn
;
71 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
72 static PyTypeObject PyLdb
;
73 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
74 static PyTypeObject PyLdbMessageElement
;
75 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
77 static PyTypeObject PyLdbTree
;
78 static PyObject
*PyLdb_FromLdbContext(struct ldb_context
*ldb_ctx
);
79 static PyObject
*PyLdbModule_FromModule(struct ldb_module
*mod
);
80 static struct ldb_message_element
*PyObject_AsMessageElement(
84 const char *attr_name
);
85 static PyTypeObject PyLdbBytesType
;
87 #if PY_MAJOR_VERSION >= 3
89 #define PYARG_STR_UNI "es"
91 static PyObject
*PyLdbBytes_FromStringAndSize(const char *msg
, int size
)
93 PyObject
* result
= NULL
;
94 PyObject
* args
= NULL
;
95 args
= Py_BuildValue("(y#)", msg
, size
);
96 result
= PyLdbBytesType
.tp_new(&PyLdbBytesType
, args
, NULL
);
101 #define PyLdbBytes_FromStringAndSize PyString_FromStringAndSize
103 #define PYARG_STR_UNI "et"
107 static PyObject
*richcmp(int cmp_val
, int op
)
111 case Py_LT
: ret
= cmp_val
< 0; break;
112 case Py_LE
: ret
= cmp_val
<= 0; break;
113 case Py_EQ
: ret
= cmp_val
== 0; break;
114 case Py_NE
: ret
= cmp_val
!= 0; break;
115 case Py_GT
: ret
= cmp_val
> 0; break;
116 case Py_GE
: ret
= cmp_val
>= 0; break;
118 Py_INCREF(Py_NotImplemented
);
119 return Py_NotImplemented
;
121 return PyBool_FromLong(ret
);
125 static PyObject
*py_ldb_control_str(PyLdbControlObject
*self
)
127 if (self
->data
!= NULL
) {
128 char* control
= ldb_control_to_string(self
->mem_ctx
, self
->data
);
129 if (control
== NULL
) {
133 return PyUnicode_FromString(control
);
135 return PyUnicode_FromString("ldb control");
139 static void py_ldb_control_dealloc(PyLdbControlObject
*self
)
141 if (self
->mem_ctx
!= NULL
) {
142 talloc_free(self
->mem_ctx
);
145 Py_TYPE(self
)->tp_free(self
);
148 /* Create a text (rather than bytes) interface for a LDB result object */
149 static PyObject
*wrap_text(const char *type
, PyObject
*wrapped
)
151 PyObject
*mod
, *cls
, *constructor
, *inst
;
152 mod
= PyImport_ImportModule("_ldb_text");
155 cls
= PyObject_GetAttrString(mod
, type
);
161 constructor
= PyObject_GetAttrString(cls
, "_wrap");
163 if (constructor
== NULL
) {
166 inst
= PyObject_CallFunction(constructor
, discard_const_p(char, "O"), wrapped
);
167 Py_DECREF(constructor
);
171 static PyObject
*py_ldb_control_get_oid(PyLdbControlObject
*self
,
172 PyObject
*Py_UNUSED(ignored
))
174 return PyUnicode_FromString(self
->data
->oid
);
177 static PyObject
*py_ldb_control_get_critical(PyLdbControlObject
*self
,
178 PyObject
*Py_UNUSED(ignored
))
180 return PyBool_FromLong(self
->data
->critical
);
183 static int py_ldb_control_set_critical(PyLdbControlObject
*self
, PyObject
*value
, void *closure
)
185 if (PyObject_IsTrue(value
)) {
186 self
->data
->critical
= true;
188 self
->data
->critical
= false;
193 static PyObject
*py_ldb_control_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
196 const char * const kwnames
[] = { "ldb", "data", NULL
};
197 struct ldb_control
*parsed_controls
;
198 PyLdbControlObject
*ret
;
201 struct ldb_context
*ldb_ctx
;
203 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O!s",
204 discard_const_p(char *, kwnames
),
205 &PyLdb
, &py_ldb
, &data
))
208 mem_ctx
= talloc_new(NULL
);
209 if (mem_ctx
== NULL
) {
214 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(py_ldb
);
215 parsed_controls
= ldb_parse_control_from_string(ldb_ctx
, mem_ctx
, data
);
217 if (!parsed_controls
) {
218 talloc_free(mem_ctx
);
219 PyErr_SetString(PyExc_ValueError
, "unable to parse control string");
223 ret
= PyObject_New(PyLdbControlObject
, type
);
226 talloc_free(mem_ctx
);
230 ret
->mem_ctx
= mem_ctx
;
232 ret
->data
= talloc_move(mem_ctx
, &parsed_controls
);
233 if (ret
->data
== NULL
) {
236 talloc_free(mem_ctx
);
240 return (PyObject
*)ret
;
243 static PyGetSetDef py_ldb_control_getset
[] = {
245 .name
= discard_const_p(char, "oid"),
246 .get
= (getter
)py_ldb_control_get_oid
,
249 .name
= discard_const_p(char, "critical"),
250 .get
= (getter
)py_ldb_control_get_critical
,
251 .set
= (setter
)py_ldb_control_set_critical
,
256 static PyTypeObject PyLdbControl
= {
257 .tp_name
= "ldb.control",
258 .tp_dealloc
= (destructor
)py_ldb_control_dealloc
,
259 .tp_getattro
= PyObject_GenericGetAttr
,
260 .tp_basicsize
= sizeof(PyLdbControlObject
),
261 .tp_getset
= py_ldb_control_getset
,
262 .tp_doc
= "LDB control.",
263 .tp_str
= (reprfunc
)py_ldb_control_str
,
264 .tp_new
= py_ldb_control_new
,
265 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
268 static void PyErr_SetLdbError(PyObject
*error
, int ret
, struct ldb_context
*ldb_ctx
)
270 if (ret
== LDB_ERR_PYTHON_EXCEPTION
)
271 return; /* Python exception should already be set, just keep that */
273 PyErr_SetObject(error
,
274 Py_BuildValue(discard_const_p(char, "(i,s)"), ret
,
275 ldb_ctx
== NULL
?ldb_strerror(ret
):ldb_errstring(ldb_ctx
)));
277 static PyObject
*py_ldb_bytes_str(PyBytesObject
*self
)
282 if (!PyBytes_Check(self
)) {
283 PyErr_Format(PyExc_TypeError
,"Unexpected type");
286 result
= PyBytes_AsStringAndSize((PyObject
*)self
, &msg
, &size
);
288 PyErr_Format(PyExc_TypeError
, "Failed to extract bytes");
291 return PyUnicode_FromStringAndSize(msg
, size
);
294 static PyTypeObject PyLdbBytesType
= {
295 PyVarObject_HEAD_INIT(NULL
, 0)
296 .tp_name
= "ldb.bytes",
297 .tp_doc
= "str/bytes (with custom str)",
298 .tp_str
= (reprfunc
)py_ldb_bytes_str
,
299 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
302 static PyObject
*PyObject_FromLdbValue(const struct ldb_val
*val
)
304 return PyLdbBytes_FromStringAndSize((const char *)val
->data
, val
->length
);
307 static PyObject
*PyStr_FromLdbValue(const struct ldb_val
*val
)
309 return PyUnicode_FromStringAndSize((const char *)val
->data
, val
->length
);
313 * Create a Python object from a ldb_result.
315 * @param result LDB result to convert
316 * @return Python object with converted result (a list object)
318 static PyObject
*PyLdbControl_FromControl(struct ldb_control
*control
)
320 TALLOC_CTX
*ctl_ctx
= talloc_new(NULL
);
321 PyLdbControlObject
*ctrl
;
322 if (ctl_ctx
== NULL
) {
327 ctrl
= (PyLdbControlObject
*)PyLdbControl
.tp_alloc(&PyLdbControl
, 0);
329 talloc_free(ctl_ctx
);
333 ctrl
->mem_ctx
= ctl_ctx
;
334 ctrl
->data
= talloc_steal(ctrl
->mem_ctx
, control
);
335 if (ctrl
->data
== NULL
) {
340 return (PyObject
*) ctrl
;
344 * Create a Python object from a ldb_result.
346 * @param result LDB result to convert
347 * @return Python object with converted result (a list object)
349 static PyObject
*PyLdbResult_FromResult(struct ldb_result
*result
)
351 PyLdbResultObject
*ret
;
352 PyObject
*list
, *controls
, *referals
;
355 if (result
== NULL
) {
359 ret
= (PyLdbResultObject
*)PyLdbResult
.tp_alloc(&PyLdbResult
, 0);
365 list
= PyList_New(result
->count
);
372 for (i
= 0; i
< result
->count
; i
++) {
373 PyList_SetItem(list
, i
, PyLdbMessage_FromMessage(result
->msgs
[i
]));
376 ret
->mem_ctx
= talloc_new(NULL
);
377 if (ret
->mem_ctx
== NULL
) {
386 if (result
->controls
) {
388 while (result
->controls
[i
]) {
391 controls
= PyList_New(i
);
392 if (controls
== NULL
) {
397 for (i
=0; result
->controls
[i
]; i
++) {
398 PyObject
*ctrl
= (PyObject
*) PyLdbControl_FromControl(result
->controls
[i
]);
405 PyList_SetItem(controls
, i
, ctrl
);
409 * No controls so we keep an empty list
411 controls
= PyList_New(0);
412 if (controls
== NULL
) {
419 ret
->controls
= controls
;
423 while (result
->refs
&& result
->refs
[i
]) {
427 referals
= PyList_New(i
);
428 if (referals
== NULL
) {
434 for (i
= 0;result
->refs
&& result
->refs
[i
]; i
++) {
435 PyList_SetItem(referals
, i
, PyUnicode_FromString(result
->refs
[i
]));
437 ret
->referals
= referals
;
438 return (PyObject
*)ret
;
442 * Create a LDB Result from a Python object.
443 * If conversion fails, NULL will be returned and a Python exception set.
445 * Note: the result object only includes the messages at the moment; extended
446 * result, controls and referrals are ignored.
448 * @param mem_ctx Memory context in which to allocate the LDB Result
449 * @param obj Python object to convert
450 * @return a ldb_result, or NULL if the conversion failed
452 static struct ldb_result
*PyLdbResult_AsResult(TALLOC_CTX
*mem_ctx
,
455 struct ldb_result
*res
;
461 res
= talloc_zero(mem_ctx
, struct ldb_result
);
462 res
->count
= PyList_Size(obj
);
463 res
->msgs
= talloc_array(res
, struct ldb_message
*, res
->count
);
464 for (i
= 0; i
< res
->count
; i
++) {
465 PyObject
*item
= PyList_GetItem(obj
, i
);
466 res
->msgs
[i
] = pyldb_Message_AsMessage(item
);
471 static PyObject
*py_ldb_dn_validate(PyLdbDnObject
*self
,
472 PyObject
*Py_UNUSED(ignored
))
474 return PyBool_FromLong(ldb_dn_validate(self
->dn
));
477 static PyObject
*py_ldb_dn_is_valid(PyLdbDnObject
*self
,
478 PyObject
*Py_UNUSED(ignored
))
480 return PyBool_FromLong(ldb_dn_is_valid(self
->dn
));
483 static PyObject
*py_ldb_dn_is_special(PyLdbDnObject
*self
,
484 PyObject
*Py_UNUSED(ignored
))
486 return PyBool_FromLong(ldb_dn_is_special(self
->dn
));
489 static PyObject
*py_ldb_dn_is_null(PyLdbDnObject
*self
,
490 PyObject
*Py_UNUSED(ignored
))
492 return PyBool_FromLong(ldb_dn_is_null(self
->dn
));
495 static PyObject
*py_ldb_dn_get_casefold(PyLdbDnObject
*self
,
496 PyObject
*Py_UNUSED(ignored
))
498 return PyUnicode_FromString(ldb_dn_get_casefold(self
->dn
));
501 static PyObject
*py_ldb_dn_get_linearized(PyLdbDnObject
*self
)
503 return PyUnicode_FromString(ldb_dn_get_linearized(self
->dn
));
506 static PyObject
*py_ldb_dn_canonical_str(PyLdbDnObject
*self
,
507 PyObject
*Py_UNUSED(ignored
))
509 return PyUnicode_FromString(ldb_dn_canonical_string(self
->dn
, self
->dn
));
512 static PyObject
*py_ldb_dn_canonical_ex_str(PyLdbDnObject
*self
,
513 PyObject
*Py_UNUSED(ignored
))
515 return PyUnicode_FromString(ldb_dn_canonical_ex_string(self
->dn
, self
->dn
));
518 static PyObject
*py_ldb_dn_extended_str(PyLdbDnObject
*self
, PyObject
*args
, PyObject
*kwargs
)
520 const char * const kwnames
[] = { "mode", NULL
};
522 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i",
523 discard_const_p(char *, kwnames
),
526 return PyUnicode_FromString(ldb_dn_get_extended_linearized(self
->dn
, self
->dn
, mode
));
529 static PyObject
*py_ldb_dn_get_extended_component(PyLdbDnObject
*self
, PyObject
*args
)
532 const struct ldb_val
*val
;
534 if (!PyArg_ParseTuple(args
, "s", &name
))
536 val
= ldb_dn_get_extended_component(self
->dn
, name
);
541 return PyBytes_FromStringAndSize((const char *)val
->data
, val
->length
);
544 static PyObject
*py_ldb_dn_set_extended_component(PyLdbDnObject
*self
, PyObject
*args
)
548 uint8_t *value
= NULL
;
551 if (!PyArg_ParseTuple(args
, "sz#", &name
, (char **)&value
, &size
))
555 err
= ldb_dn_set_extended_component(self
->dn
, name
, NULL
);
558 val
.data
= (uint8_t *)value
;
560 err
= ldb_dn_set_extended_component(self
->dn
, name
, &val
);
563 if (err
!= LDB_SUCCESS
) {
564 PyErr_SetString(PyExc_TypeError
, "Failed to set extended component");
571 static PyObject
*py_ldb_dn_repr(PyLdbDnObject
*self
)
573 PyObject
*str
= PyUnicode_FromString(ldb_dn_get_linearized(self
->dn
));
574 PyObject
*repr
, *result
;
577 repr
= PyObject_Repr(str
);
582 result
= PyUnicode_FromFormat("Dn(%s)", PyUnicode_AsUTF8(repr
));
588 static PyObject
*py_ldb_dn_check_special(PyLdbDnObject
*self
, PyObject
*args
)
592 if (!PyArg_ParseTuple(args
, "s", &name
))
595 return PyBool_FromLong(ldb_dn_check_special(self
->dn
, name
));
598 static PyObject
*py_ldb_dn_richcmp(PyObject
*dn1
, PyObject
*dn2
, int op
)
601 if (!pyldb_Dn_Check(dn2
)) {
602 Py_INCREF(Py_NotImplemented
);
603 return Py_NotImplemented
;
605 ret
= ldb_dn_compare(pyldb_Dn_AS_DN(dn1
), pyldb_Dn_AS_DN(dn2
));
606 return richcmp(ret
, op
);
609 static PyObject
*py_ldb_dn_get_parent(PyLdbDnObject
*self
,
610 PyObject
*Py_UNUSED(ignored
))
612 struct ldb_dn
*dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
613 struct ldb_dn
*parent
;
614 PyLdbDnObject
*py_ret
;
615 TALLOC_CTX
*mem_ctx
= talloc_new(NULL
);
617 parent
= ldb_dn_get_parent(mem_ctx
, dn
);
618 if (parent
== NULL
) {
619 talloc_free(mem_ctx
);
623 py_ret
= (PyLdbDnObject
*)PyLdbDn
.tp_alloc(&PyLdbDn
, 0);
624 if (py_ret
== NULL
) {
626 talloc_free(mem_ctx
);
629 py_ret
->mem_ctx
= mem_ctx
;
631 return (PyObject
*)py_ret
;
634 static PyObject
*py_ldb_dn_add_child(PyLdbDnObject
*self
, PyObject
*args
)
637 struct ldb_dn
*dn
, *other
;
638 if (!PyArg_ParseTuple(args
, "O", &py_other
))
641 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
643 if (!pyldb_Object_AsDn(NULL
, py_other
, ldb_dn_get_ldb_context(dn
), &other
))
646 return PyBool_FromLong(ldb_dn_add_child(dn
, other
));
649 static PyObject
*py_ldb_dn_add_base(PyLdbDnObject
*self
, PyObject
*args
)
652 struct ldb_dn
*other
, *dn
;
653 if (!PyArg_ParseTuple(args
, "O", &py_other
))
656 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
658 if (!pyldb_Object_AsDn(NULL
, py_other
, ldb_dn_get_ldb_context(dn
), &other
))
661 return PyBool_FromLong(ldb_dn_add_base(dn
, other
));
664 static PyObject
*py_ldb_dn_remove_base_components(PyLdbDnObject
*self
, PyObject
*args
)
668 if (!PyArg_ParseTuple(args
, "i", &i
))
671 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
673 return PyBool_FromLong(ldb_dn_remove_base_components(dn
, i
));
676 static PyObject
*py_ldb_dn_is_child_of(PyLdbDnObject
*self
, PyObject
*args
)
679 struct ldb_dn
*dn
, *base
;
680 if (!PyArg_ParseTuple(args
, "O", &py_base
))
683 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
685 if (!pyldb_Object_AsDn(NULL
, py_base
, ldb_dn_get_ldb_context(dn
), &base
))
688 return PyBool_FromLong(ldb_dn_compare_base(base
, dn
) == 0);
691 static PyObject
*py_ldb_dn_get_component_name(PyLdbDnObject
*self
, PyObject
*args
)
695 unsigned int num
= 0;
697 if (!PyArg_ParseTuple(args
, "I", &num
))
700 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
702 name
= ldb_dn_get_component_name(dn
, num
);
707 return PyUnicode_FromString(name
);
710 static PyObject
*py_ldb_dn_get_component_value(PyLdbDnObject
*self
, PyObject
*args
)
713 const struct ldb_val
*val
;
714 unsigned int num
= 0;
716 if (!PyArg_ParseTuple(args
, "I", &num
))
719 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
721 val
= ldb_dn_get_component_val(dn
, num
);
726 return PyStr_FromLdbValue(val
);
729 static PyObject
*py_ldb_dn_set_component(PyLdbDnObject
*self
, PyObject
*args
)
731 unsigned int num
= 0;
732 char *name
= NULL
, *value
= NULL
;
733 struct ldb_val val
= { 0 };
737 if (!PyArg_ParseTuple(args
, "Iss#", &num
, &name
, &value
, &size
))
740 val
.data
= (unsigned char*) value
;
743 err
= ldb_dn_set_component(self
->dn
, num
, name
, val
);
744 if (err
!= LDB_SUCCESS
) {
745 PyErr_SetString(PyExc_TypeError
, "Failed to set component");
752 static PyObject
*py_ldb_dn_get_rdn_name(PyLdbDnObject
*self
,
753 PyObject
*Py_UNUSED(ignored
))
758 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
760 name
= ldb_dn_get_rdn_name(dn
);
765 return PyUnicode_FromString(name
);
768 static PyObject
*py_ldb_dn_get_rdn_value(PyLdbDnObject
*self
,
769 PyObject
*Py_UNUSED(ignored
))
772 const struct ldb_val
*val
;
774 dn
= pyldb_Dn_AS_DN((PyObject
*)self
);
776 val
= ldb_dn_get_rdn_val(dn
);
781 return PyStr_FromLdbValue(val
);
784 static PyMethodDef py_ldb_dn_methods
[] = {
785 { "validate", (PyCFunction
)py_ldb_dn_validate
, METH_NOARGS
,
786 "S.validate() -> bool\n"
787 "Validate DN is correct." },
788 { "is_valid", (PyCFunction
)py_ldb_dn_is_valid
, METH_NOARGS
,
789 "S.is_valid() -> bool\n" },
790 { "is_special", (PyCFunction
)py_ldb_dn_is_special
, METH_NOARGS
,
791 "S.is_special() -> bool\n"
792 "Check whether this is a special LDB DN." },
793 { "is_null", (PyCFunction
)py_ldb_dn_is_null
, METH_NOARGS
,
794 "Check whether this is a null DN." },
795 { "get_casefold", (PyCFunction
)py_ldb_dn_get_casefold
, METH_NOARGS
,
797 { "get_linearized", PY_DISCARD_FUNC_SIG(PyCFunction
,
798 py_ldb_dn_get_linearized
),
801 { "canonical_str", (PyCFunction
)py_ldb_dn_canonical_str
, METH_NOARGS
,
802 "S.canonical_str() -> string\n"
803 "Canonical version of this DN (like a posix path)." },
804 { "is_child_of", (PyCFunction
)py_ldb_dn_is_child_of
, METH_VARARGS
,
805 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
806 { "canonical_ex_str", (PyCFunction
)py_ldb_dn_canonical_ex_str
, METH_NOARGS
,
807 "S.canonical_ex_str() -> string\n"
808 "Canonical version of this DN (like a posix path, with terminating newline)." },
809 { "extended_str", PY_DISCARD_FUNC_SIG(PyCFunction
,
810 py_ldb_dn_extended_str
),
811 METH_VARARGS
| METH_KEYWORDS
,
812 "S.extended_str(mode=1) -> string\n"
813 "Extended version of this DN" },
814 { "parent", (PyCFunction
)py_ldb_dn_get_parent
, METH_NOARGS
,
816 "Get the parent for this DN." },
817 { "add_child", (PyCFunction
)py_ldb_dn_add_child
, METH_VARARGS
,
818 "S.add_child(dn) -> None\n"
819 "Add a child DN to this DN." },
820 { "add_base", (PyCFunction
)py_ldb_dn_add_base
, METH_VARARGS
,
821 "S.add_base(dn) -> None\n"
822 "Add a base DN to this DN." },
823 { "remove_base_components", (PyCFunction
)py_ldb_dn_remove_base_components
, METH_VARARGS
,
824 "S.remove_base_components(int) -> bool\n"
825 "Remove a number of DN components from the base of this DN." },
826 { "check_special", (PyCFunction
)py_ldb_dn_check_special
, METH_VARARGS
,
827 "S.check_special(name) -> bool\n\n"
828 "Check if name is a special DN name"},
829 { "get_extended_component", (PyCFunction
)py_ldb_dn_get_extended_component
, METH_VARARGS
,
830 "S.get_extended_component(name) -> string\n\n"
831 "returns a DN extended component as a binary string"},
832 { "set_extended_component", (PyCFunction
)py_ldb_dn_set_extended_component
, METH_VARARGS
,
833 "S.set_extended_component(name, value) -> None\n\n"
834 "set a DN extended component as a binary string"},
835 { "get_component_name", (PyCFunction
)py_ldb_dn_get_component_name
, METH_VARARGS
,
836 "S.get_component_name(num) -> string\n"
837 "get the attribute name of the specified component" },
838 { "get_component_value", (PyCFunction
)py_ldb_dn_get_component_value
, METH_VARARGS
,
839 "S.get_component_value(num) -> string\n"
840 "get the attribute value of the specified component as a binary string" },
841 { "set_component", (PyCFunction
)py_ldb_dn_set_component
, METH_VARARGS
,
842 "S.get_component_value(num, name, value) -> None\n"
843 "set the attribute name and value of the specified component" },
844 { "get_rdn_name", (PyCFunction
)py_ldb_dn_get_rdn_name
, METH_NOARGS
,
845 "S.get_rdn_name() -> string\n"
846 "get the RDN attribute name" },
847 { "get_rdn_value", (PyCFunction
)py_ldb_dn_get_rdn_value
, METH_NOARGS
,
848 "S.get_rdn_value() -> string\n"
849 "get the RDN attribute value as a binary string" },
853 static Py_ssize_t
py_ldb_dn_len(PyLdbDnObject
*self
)
855 return ldb_dn_get_comp_num(pyldb_Dn_AS_DN((PyObject
*)self
));
859 copy a DN as a python object
861 static PyObject
*py_ldb_dn_copy(struct ldb_dn
*dn
)
863 PyLdbDnObject
*py_ret
;
865 py_ret
= (PyLdbDnObject
*)PyLdbDn
.tp_alloc(&PyLdbDn
, 0);
866 if (py_ret
== NULL
) {
870 py_ret
->mem_ctx
= talloc_new(NULL
);
871 py_ret
->dn
= ldb_dn_copy(py_ret
->mem_ctx
, dn
);
872 return (PyObject
*)py_ret
;
875 static PyObject
*py_ldb_dn_concat(PyLdbDnObject
*self
, PyObject
*py_other
)
877 struct ldb_dn
*dn
= pyldb_Dn_AS_DN((PyObject
*)self
),
879 PyLdbDnObject
*py_ret
;
881 if (!pyldb_Object_AsDn(NULL
, py_other
, NULL
, &other
))
884 py_ret
= (PyLdbDnObject
*)PyLdbDn
.tp_alloc(&PyLdbDn
, 0);
885 if (py_ret
== NULL
) {
889 py_ret
->mem_ctx
= talloc_new(NULL
);
890 py_ret
->dn
= ldb_dn_copy(py_ret
->mem_ctx
, dn
);
891 ldb_dn_add_base(py_ret
->dn
, other
);
892 return (PyObject
*)py_ret
;
895 static PySequenceMethods py_ldb_dn_seq
= {
896 .sq_length
= (lenfunc
)py_ldb_dn_len
,
897 .sq_concat
= (binaryfunc
)py_ldb_dn_concat
,
900 static PyObject
*py_ldb_dn_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
902 struct ldb_dn
*ret
= NULL
;
904 PyObject
*py_ldb
= NULL
;
905 struct ldb_context
*ldb_ctx
= NULL
;
906 TALLOC_CTX
*mem_ctx
= NULL
;
907 PyLdbDnObject
*py_ret
= NULL
;
908 const char * const kwnames
[] = { "ldb", "dn", NULL
};
910 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O"PYARG_STR_UNI
,
911 discard_const_p(char *, kwnames
),
912 &py_ldb
, "utf8", &str
))
915 if (!PyLdb_Check(py_ldb
)) {
916 PyErr_SetString(PyExc_TypeError
, "Expected Ldb");
919 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(py_ldb
);
921 mem_ctx
= talloc_new(NULL
);
922 if (mem_ctx
== NULL
) {
927 ret
= ldb_dn_new(mem_ctx
, ldb_ctx
, str
);
928 if (!ldb_dn_validate(ret
)) {
929 talloc_free(mem_ctx
);
930 PyErr_SetString(PyExc_ValueError
, "unable to parse dn string");
934 py_ret
= (PyLdbDnObject
*)type
->tp_alloc(type
, 0);
935 if (py_ret
== NULL
) {
936 talloc_free(mem_ctx
);
940 py_ret
->mem_ctx
= mem_ctx
;
944 PyMem_Free(discard_const_p(char, str
));
946 return (PyObject
*)py_ret
;
949 static void py_ldb_dn_dealloc(PyLdbDnObject
*self
)
951 talloc_free(self
->mem_ctx
);
955 static PyTypeObject PyLdbDn
= {
957 .tp_methods
= py_ldb_dn_methods
,
958 .tp_str
= (reprfunc
)py_ldb_dn_get_linearized
,
959 .tp_repr
= (reprfunc
)py_ldb_dn_repr
,
960 .tp_richcompare
= (richcmpfunc
)py_ldb_dn_richcmp
,
961 .tp_as_sequence
= &py_ldb_dn_seq
,
962 .tp_doc
= "A LDB distinguished name.",
963 .tp_new
= py_ldb_dn_new
,
964 .tp_dealloc
= (destructor
)py_ldb_dn_dealloc
,
965 .tp_basicsize
= sizeof(PyLdbDnObject
),
966 .tp_flags
= Py_TPFLAGS_DEFAULT
,
970 static void py_ldb_debug(void *context
, enum ldb_debug_level level
, const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(3, 0);
971 static void py_ldb_debug(void *context
, enum ldb_debug_level level
, const char *fmt
, va_list ap
)
973 PyObject
*fn
= (PyObject
*)context
;
974 PyObject_CallFunction(fn
, discard_const_p(char, "(i,O)"), level
, PyUnicode_FromFormatV(fmt
, ap
));
977 static PyObject
*py_ldb_debug_func
;
979 static PyObject
*py_ldb_set_debug(PyObject
*self
, PyObject
*args
)
982 struct ldb_context
*ldb_ctx
;
984 if (!PyArg_ParseTuple(args
, "O", &cb
))
987 if (py_ldb_debug_func
!= NULL
) {
988 Py_DECREF(py_ldb_debug_func
);
992 /* FIXME: DECREF cb when exiting program */
993 py_ldb_debug_func
= cb
;
994 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
995 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
,
996 ldb_set_debug(ldb_ctx
, py_ldb_debug
, cb
),
1002 static PyObject
*py_ldb_set_create_perms(PyTypeObject
*self
, PyObject
*args
)
1005 if (!PyArg_ParseTuple(args
, "I", &perms
))
1008 ldb_set_create_perms(pyldb_Ldb_AS_LDBCONTEXT(self
), perms
);
1013 static PyObject
*py_ldb_set_modules_dir(PyTypeObject
*self
, PyObject
*args
)
1016 if (!PyArg_ParseTuple(args
, "s", &modules_dir
))
1019 ldb_set_modules_dir(pyldb_Ldb_AS_LDBCONTEXT(self
), modules_dir
);
1024 static PyObject
*py_ldb_transaction_start(PyLdbObject
*self
,
1025 PyObject
*Py_UNUSED(ignored
))
1027 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1029 ldb_err
= ldb_transaction_start(ldb_ctx
);
1030 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1034 static PyObject
*py_ldb_transaction_commit(PyLdbObject
*self
,
1035 PyObject
*Py_UNUSED(ignored
))
1037 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1039 ldb_err
= ldb_transaction_commit(ldb_ctx
);
1040 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1044 static PyObject
*py_ldb_transaction_prepare_commit(PyLdbObject
*self
,
1045 PyObject
*Py_UNUSED(ignored
))
1047 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1049 ldb_err
= ldb_transaction_prepare_commit(ldb_ctx
);
1050 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1054 static PyObject
*py_ldb_transaction_cancel(PyLdbObject
*self
,
1055 PyObject
*Py_UNUSED(ignored
))
1057 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1059 ldb_err
= ldb_transaction_cancel(ldb_ctx
);
1060 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1064 static PyObject
*py_ldb_setup_wellknown_attributes(PyLdbObject
*self
,
1065 PyObject
*Py_UNUSED(ignored
))
1067 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1069 ldb_err
= ldb_setup_wellknown_attributes(ldb_ctx
);
1070 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1074 static PyObject
*py_ldb_repr(PyLdbObject
*self
)
1076 return PyUnicode_FromString("<ldb connection>");
1079 static PyObject
*py_ldb_get_root_basedn(PyLdbObject
*self
,
1080 PyObject
*Py_UNUSED(ignored
))
1082 struct ldb_dn
*dn
= ldb_get_root_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1085 return py_ldb_dn_copy(dn
);
1089 static PyObject
*py_ldb_get_schema_basedn(PyLdbObject
*self
,
1090 PyObject
*Py_UNUSED(ignored
))
1092 struct ldb_dn
*dn
= ldb_get_schema_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1095 return py_ldb_dn_copy(dn
);
1098 static PyObject
*py_ldb_get_config_basedn(PyLdbObject
*self
,
1099 PyObject
*Py_UNUSED(ignored
))
1101 struct ldb_dn
*dn
= ldb_get_config_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1104 return py_ldb_dn_copy(dn
);
1107 static PyObject
*py_ldb_get_default_basedn(PyLdbObject
*self
,
1108 PyObject
*Py_UNUSED(ignored
))
1110 struct ldb_dn
*dn
= ldb_get_default_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1113 return py_ldb_dn_copy(dn
);
1116 static const char **PyList_AsStrList(TALLOC_CTX
*mem_ctx
, PyObject
*list
,
1117 const char *paramname
)
1121 if (!PyList_Check(list
)) {
1122 PyErr_Format(PyExc_TypeError
, "%s is not a list", paramname
);
1125 ret
= talloc_array(NULL
, const char *, PyList_Size(list
)+1);
1131 for (i
= 0; i
< PyList_Size(list
); i
++) {
1132 const char *str
= NULL
;
1134 PyObject
*item
= PyList_GetItem(list
, i
);
1135 if (!PyUnicode_Check(item
)) {
1136 PyErr_Format(PyExc_TypeError
, "%s should be strings", paramname
);
1140 str
= PyUnicode_AsUTF8AndSize(item
, &size
);
1145 ret
[i
] = talloc_strndup(ret
, str
, size
);
1151 static int py_ldb_init(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1153 const char * const kwnames
[] = { "url", "flags", "options", NULL
};
1155 PyObject
*py_options
= Py_None
;
1156 const char **options
;
1157 unsigned int flags
= 0;
1159 struct ldb_context
*ldb
;
1161 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|zIO:Ldb.__init__",
1162 discard_const_p(char *, kwnames
),
1163 &url
, &flags
, &py_options
))
1166 ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1168 if (py_options
== Py_None
) {
1171 options
= PyList_AsStrList(ldb
, py_options
, "options");
1172 if (options
== NULL
)
1177 ret
= ldb_connect(ldb
, url
, flags
, options
);
1178 if (ret
!= LDB_SUCCESS
) {
1179 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb
);
1183 ldb_set_flags(ldb
, flags
);
1186 talloc_free(options
);
1190 static PyObject
*py_ldb_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
1193 struct ldb_context
*ldb
;
1194 ret
= (PyLdbObject
*)type
->tp_alloc(type
, 0);
1199 ret
->mem_ctx
= talloc_new(NULL
);
1200 ldb
= ldb_init(ret
->mem_ctx
, NULL
);
1208 return (PyObject
*)ret
;
1211 static PyObject
*py_ldb_connect(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1214 unsigned int flags
= 0;
1215 PyObject
*py_options
= Py_None
;
1217 const char **options
;
1218 const char * const kwnames
[] = { "url", "flags", "options", NULL
};
1219 struct ldb_context
*ldb_ctx
;
1221 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|IO",
1222 discard_const_p(char *, kwnames
),
1223 &url
, &flags
, &py_options
))
1226 if (py_options
== Py_None
) {
1229 options
= PyList_AsStrList(NULL
, py_options
, "options");
1230 if (options
== NULL
)
1234 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1235 ret
= ldb_connect(ldb_ctx
, url
, flags
, options
);
1236 talloc_free(options
);
1238 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1243 static PyObject
*py_ldb_modify(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1246 PyObject
*py_controls
= Py_None
;
1247 struct ldb_context
*ldb_ctx
;
1248 struct ldb_request
*req
;
1249 struct ldb_control
**parsed_controls
;
1250 struct ldb_message
*msg
;
1252 TALLOC_CTX
*mem_ctx
;
1254 const char * const kwnames
[] = { "message", "controls", "validate", NULL
};
1256 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Ob",
1257 discard_const_p(char *, kwnames
),
1258 &py_msg
, &py_controls
, &validate
))
1261 mem_ctx
= talloc_new(NULL
);
1262 if (mem_ctx
== NULL
) {
1266 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1268 if (py_controls
== Py_None
) {
1269 parsed_controls
= NULL
;
1271 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1272 if (controls
== NULL
) {
1273 talloc_free(mem_ctx
);
1276 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1277 talloc_free(controls
);
1280 if (!PyLdbMessage_Check(py_msg
)) {
1281 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message");
1282 talloc_free(mem_ctx
);
1285 msg
= pyldb_Message_AsMessage(py_msg
);
1288 ret
= ldb_msg_sanity_check(ldb_ctx
, msg
);
1289 if (ret
!= LDB_SUCCESS
) {
1290 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1291 talloc_free(mem_ctx
);
1296 ret
= ldb_build_mod_req(&req
, ldb_ctx
, mem_ctx
, msg
, parsed_controls
,
1297 NULL
, ldb_op_default_callback
, NULL
);
1298 if (ret
!= LDB_SUCCESS
) {
1299 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1300 talloc_free(mem_ctx
);
1304 /* do request and autostart a transaction */
1305 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1307 ret
= ldb_transaction_start(ldb_ctx
);
1308 if (ret
!= LDB_SUCCESS
) {
1309 talloc_free(mem_ctx
);
1310 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1314 ret
= ldb_request(ldb_ctx
, req
);
1315 if (ret
== LDB_SUCCESS
) {
1316 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1319 if (ret
== LDB_SUCCESS
) {
1320 ret
= ldb_transaction_commit(ldb_ctx
);
1322 ldb_transaction_cancel(ldb_ctx
);
1325 talloc_free(mem_ctx
);
1326 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1333 * Obtain a ldb message from a Python Dictionary object.
1335 * @param mem_ctx Memory context
1336 * @param py_obj Python Dictionary object
1337 * @param ldb_ctx LDB context
1338 * @param mod_flags Flags to be set on every message element
1339 * @return ldb_message on success or NULL on failure
1341 static struct ldb_message
*PyDict_AsMessage(TALLOC_CTX
*mem_ctx
,
1343 struct ldb_context
*ldb_ctx
,
1344 unsigned int mod_flags
)
1346 struct ldb_message
*msg
;
1347 unsigned int msg_pos
= 0;
1348 Py_ssize_t dict_pos
= 0;
1349 PyObject
*key
, *value
;
1350 struct ldb_message_element
*msg_el
;
1351 PyObject
*dn_value
= PyDict_GetItemString(py_obj
, "dn");
1353 msg
= ldb_msg_new(mem_ctx
);
1358 msg
->elements
= talloc_zero_array(msg
, struct ldb_message_element
, PyDict_Size(py_obj
));
1361 if (!pyldb_Object_AsDn(msg
, dn_value
, ldb_ctx
, &msg
->dn
)) {
1362 PyErr_SetString(PyExc_TypeError
, "unable to import dn object");
1365 if (msg
->dn
== NULL
) {
1366 PyErr_SetString(PyExc_TypeError
, "dn set but not found");
1370 PyErr_SetString(PyExc_TypeError
, "no dn set");
1374 while (PyDict_Next(py_obj
, &dict_pos
, &key
, &value
)) {
1375 const char *key_str
= PyUnicode_AsUTF8(key
);
1376 if (ldb_attr_cmp(key_str
, "dn") != 0) {
1377 msg_el
= PyObject_AsMessageElement(msg
->elements
, value
,
1378 mod_flags
, key_str
);
1379 if (msg_el
== NULL
) {
1380 PyErr_Format(PyExc_TypeError
, "unable to import element '%s'", key_str
);
1383 memcpy(&msg
->elements
[msg_pos
], msg_el
, sizeof(*msg_el
));
1388 msg
->num_elements
= msg_pos
;
1393 static PyObject
*py_ldb_add(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1397 struct ldb_context
*ldb_ctx
;
1398 struct ldb_request
*req
;
1399 struct ldb_message
*msg
= NULL
;
1400 PyObject
*py_controls
= Py_None
;
1401 TALLOC_CTX
*mem_ctx
;
1402 struct ldb_control
**parsed_controls
;
1403 const char * const kwnames
[] = { "message", "controls", NULL
};
1405 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O",
1406 discard_const_p(char *, kwnames
),
1407 &py_obj
, &py_controls
))
1410 mem_ctx
= talloc_new(NULL
);
1411 if (mem_ctx
== NULL
) {
1415 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1417 if (py_controls
== Py_None
) {
1418 parsed_controls
= NULL
;
1420 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1421 if (controls
== NULL
) {
1422 talloc_free(mem_ctx
);
1425 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1426 talloc_free(controls
);
1429 if (PyLdbMessage_Check(py_obj
)) {
1430 msg
= pyldb_Message_AsMessage(py_obj
);
1431 } else if (PyDict_Check(py_obj
)) {
1432 msg
= PyDict_AsMessage(mem_ctx
, py_obj
, ldb_ctx
, LDB_FLAG_MOD_ADD
);
1434 PyErr_SetString(PyExc_TypeError
,
1435 "Dictionary or LdbMessage object expected!");
1439 /* we should have a PyErr already set */
1440 talloc_free(mem_ctx
);
1444 ret
= ldb_msg_sanity_check(ldb_ctx
, msg
);
1445 if (ret
!= LDB_SUCCESS
) {
1446 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1447 talloc_free(mem_ctx
);
1451 ret
= ldb_build_add_req(&req
, ldb_ctx
, mem_ctx
, msg
, parsed_controls
,
1452 NULL
, ldb_op_default_callback
, NULL
);
1453 if (ret
!= LDB_SUCCESS
) {
1454 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1455 talloc_free(mem_ctx
);
1459 /* do request and autostart a transaction */
1460 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1462 ret
= ldb_transaction_start(ldb_ctx
);
1463 if (ret
!= LDB_SUCCESS
) {
1464 talloc_free(mem_ctx
);
1465 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1469 ret
= ldb_request(ldb_ctx
, req
);
1470 if (ret
== LDB_SUCCESS
) {
1471 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1474 if (ret
== LDB_SUCCESS
) {
1475 ret
= ldb_transaction_commit(ldb_ctx
);
1477 ldb_transaction_cancel(ldb_ctx
);
1480 talloc_free(mem_ctx
);
1481 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1486 static PyObject
*py_ldb_delete(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1491 struct ldb_context
*ldb_ctx
;
1492 struct ldb_request
*req
;
1493 PyObject
*py_controls
= Py_None
;
1494 TALLOC_CTX
*mem_ctx
;
1495 struct ldb_control
**parsed_controls
;
1496 const char * const kwnames
[] = { "dn", "controls", NULL
};
1498 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O",
1499 discard_const_p(char *, kwnames
),
1500 &py_dn
, &py_controls
))
1503 mem_ctx
= talloc_new(NULL
);
1504 if (mem_ctx
== NULL
) {
1508 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1510 if (py_controls
== Py_None
) {
1511 parsed_controls
= NULL
;
1513 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1514 if (controls
== NULL
) {
1515 talloc_free(mem_ctx
);
1518 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1519 talloc_free(controls
);
1522 if (!pyldb_Object_AsDn(mem_ctx
, py_dn
, ldb_ctx
, &dn
)) {
1523 talloc_free(mem_ctx
);
1527 ret
= ldb_build_del_req(&req
, ldb_ctx
, mem_ctx
, dn
, parsed_controls
,
1528 NULL
, ldb_op_default_callback
, NULL
);
1529 if (ret
!= LDB_SUCCESS
) {
1530 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1531 talloc_free(mem_ctx
);
1535 /* do request and autostart a transaction */
1536 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1538 ret
= ldb_transaction_start(ldb_ctx
);
1539 if (ret
!= LDB_SUCCESS
) {
1540 talloc_free(mem_ctx
);
1541 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1545 ret
= ldb_request(ldb_ctx
, req
);
1546 if (ret
== LDB_SUCCESS
) {
1547 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1550 if (ret
== LDB_SUCCESS
) {
1551 ret
= ldb_transaction_commit(ldb_ctx
);
1553 ldb_transaction_cancel(ldb_ctx
);
1556 talloc_free(mem_ctx
);
1557 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1562 static PyObject
*py_ldb_rename(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1564 PyObject
*py_dn1
, *py_dn2
;
1565 struct ldb_dn
*dn1
, *dn2
;
1567 TALLOC_CTX
*mem_ctx
;
1568 PyObject
*py_controls
= Py_None
;
1569 struct ldb_control
**parsed_controls
;
1570 struct ldb_context
*ldb_ctx
;
1571 struct ldb_request
*req
;
1572 const char * const kwnames
[] = { "dn1", "dn2", "controls", NULL
};
1574 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1576 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|O",
1577 discard_const_p(char *, kwnames
),
1578 &py_dn1
, &py_dn2
, &py_controls
))
1582 mem_ctx
= talloc_new(NULL
);
1583 if (mem_ctx
== NULL
) {
1588 if (py_controls
== Py_None
) {
1589 parsed_controls
= NULL
;
1591 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1592 if (controls
== NULL
) {
1593 talloc_free(mem_ctx
);
1596 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1597 talloc_free(controls
);
1601 if (!pyldb_Object_AsDn(mem_ctx
, py_dn1
, ldb_ctx
, &dn1
)) {
1602 talloc_free(mem_ctx
);
1606 if (!pyldb_Object_AsDn(mem_ctx
, py_dn2
, ldb_ctx
, &dn2
)) {
1607 talloc_free(mem_ctx
);
1611 ret
= ldb_build_rename_req(&req
, ldb_ctx
, mem_ctx
, dn1
, dn2
, parsed_controls
,
1612 NULL
, ldb_op_default_callback
, NULL
);
1613 if (ret
!= LDB_SUCCESS
) {
1614 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1615 talloc_free(mem_ctx
);
1619 /* do request and autostart a transaction */
1620 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1622 ret
= ldb_transaction_start(ldb_ctx
);
1623 if (ret
!= LDB_SUCCESS
) {
1624 talloc_free(mem_ctx
);
1625 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1629 ret
= ldb_request(ldb_ctx
, req
);
1630 if (ret
== LDB_SUCCESS
) {
1631 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1634 if (ret
== LDB_SUCCESS
) {
1635 ret
= ldb_transaction_commit(ldb_ctx
);
1637 ldb_transaction_cancel(ldb_ctx
);
1640 talloc_free(mem_ctx
);
1641 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1646 static PyObject
*py_ldb_schema_attribute_remove(PyLdbObject
*self
, PyObject
*args
)
1649 if (!PyArg_ParseTuple(args
, "s", &name
))
1652 ldb_schema_attribute_remove(pyldb_Ldb_AS_LDBCONTEXT(self
), name
);
1657 static PyObject
*py_ldb_schema_attribute_add(PyLdbObject
*self
, PyObject
*args
)
1659 char *attribute
, *syntax
;
1662 struct ldb_context
*ldb_ctx
;
1664 if (!PyArg_ParseTuple(args
, "sIs", &attribute
, &flags
, &syntax
))
1667 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1668 ret
= ldb_schema_attribute_add(ldb_ctx
, attribute
, flags
, syntax
);
1670 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1675 static PyObject
*ldb_ldif_to_pyobject(struct ldb_ldif
*ldif
)
1680 /* We don't want this attached to the 'ldb' any more */
1681 PyObject
*obj
= PyLdbMessage_FromMessage(ldif
->msg
);
1683 Py_BuildValue(discard_const_p(char, "(iO)"),
1692 static PyObject
*py_ldb_write_ldif(PyLdbObject
*self
, PyObject
*args
)
1696 struct ldb_ldif ldif
;
1699 TALLOC_CTX
*mem_ctx
;
1701 if (!PyArg_ParseTuple(args
, "Oi", &py_msg
, &changetype
))
1704 if (!PyLdbMessage_Check(py_msg
)) {
1705 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for msg");
1709 ldif
.msg
= pyldb_Message_AsMessage(py_msg
);
1710 ldif
.changetype
= changetype
;
1712 mem_ctx
= talloc_new(NULL
);
1714 string
= ldb_ldif_write_string(pyldb_Ldb_AS_LDBCONTEXT(self
), mem_ctx
, &ldif
);
1716 PyErr_SetString(PyExc_KeyError
, "Failed to generate LDIF");
1720 ret
= PyUnicode_FromString(string
);
1722 talloc_free(mem_ctx
);
1727 static PyObject
*py_ldb_parse_ldif(PyLdbObject
*self
, PyObject
*args
)
1729 PyObject
*list
, *ret
;
1730 struct ldb_ldif
*ldif
;
1732 struct ldb_dn
*last_dn
= NULL
;
1734 TALLOC_CTX
*mem_ctx
;
1736 if (!PyArg_ParseTuple(args
, "s", &s
))
1739 mem_ctx
= talloc_new(NULL
);
1744 list
= PyList_New(0);
1745 while (s
&& *s
!= '\0') {
1746 ldif
= ldb_ldif_read_string(self
->ldb_ctx
, &s
);
1747 talloc_steal(mem_ctx
, ldif
);
1750 PyObject
*py_ldif
= ldb_ldif_to_pyobject(ldif
);
1751 if (py_ldif
== NULL
) {
1753 PyErr_BadArgument();
1754 talloc_free(mem_ctx
);
1757 res
= PyList_Append(list
, py_ldif
);
1761 talloc_free(mem_ctx
);
1764 last_dn
= ldif
->msg
->dn
;
1766 const char *last_dn_str
= NULL
;
1767 const char *err_string
= NULL
;
1768 if (last_dn
== NULL
) {
1769 PyErr_SetString(PyExc_ValueError
,
1770 "unable to parse LDIF "
1771 "string at first chunk");
1773 talloc_free(mem_ctx
);
1778 = ldb_dn_get_linearized(last_dn
);
1781 = talloc_asprintf(mem_ctx
,
1782 "unable to parse ldif "
1786 PyErr_SetString(PyExc_ValueError
,
1788 talloc_free(mem_ctx
);
1793 talloc_free(mem_ctx
); /* The pyobject already has a reference to the things it needs */
1794 ret
= PyObject_GetIter(list
);
1799 static PyObject
*py_ldb_msg_diff(PyLdbObject
*self
, PyObject
*args
)
1802 PyObject
*py_msg_old
;
1803 PyObject
*py_msg_new
;
1804 struct ldb_message
*diff
;
1805 struct ldb_context
*ldb
;
1808 if (!PyArg_ParseTuple(args
, "OO", &py_msg_old
, &py_msg_new
))
1811 if (!PyLdbMessage_Check(py_msg_old
)) {
1812 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for old message");
1816 if (!PyLdbMessage_Check(py_msg_new
)) {
1817 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for new message");
1821 ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1822 ldb_ret
= ldb_msg_difference(ldb
, ldb
,
1823 pyldb_Message_AsMessage(py_msg_old
),
1824 pyldb_Message_AsMessage(py_msg_new
),
1826 if (ldb_ret
!= LDB_SUCCESS
) {
1827 PyErr_SetString(PyExc_RuntimeError
, "Failed to generate the Ldb Message diff");
1831 py_ret
= PyLdbMessage_FromMessage(diff
);
1833 talloc_unlink(ldb
, diff
);
1838 static PyObject
*py_ldb_schema_format_value(PyLdbObject
*self
, PyObject
*args
)
1840 const struct ldb_schema_attribute
*a
;
1841 struct ldb_val old_val
;
1842 struct ldb_val new_val
;
1843 TALLOC_CTX
*mem_ctx
;
1850 if (!PyArg_ParseTuple(args
, "sO", &element_name
, &val
))
1853 result
= PyBytes_AsStringAndSize(val
, (char **)&old_val
.data
, &size
);
1854 old_val
.length
= size
;
1857 PyErr_SetString(PyExc_RuntimeError
, "Failed to convert passed value to String");
1861 a
= ldb_schema_attribute_by_name(pyldb_Ldb_AS_LDBCONTEXT(self
), element_name
);
1867 mem_ctx
= talloc_new(NULL
);
1868 if (mem_ctx
== NULL
) {
1873 if (a
->syntax
->ldif_write_fn(pyldb_Ldb_AS_LDBCONTEXT(self
), mem_ctx
, &old_val
, &new_val
) != 0) {
1874 talloc_free(mem_ctx
);
1878 ret
= PyBytes_FromStringAndSize((const char *)new_val
.data
, new_val
.length
);
1880 talloc_free(mem_ctx
);
1885 static PyObject
*py_ldb_search(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1887 PyObject
*py_base
= Py_None
;
1888 int scope
= LDB_SCOPE_DEFAULT
;
1890 PyObject
*py_attrs
= Py_None
;
1891 PyObject
*py_controls
= Py_None
;
1892 const char * const kwnames
[] = { "base", "scope", "expression", "attrs", "controls", NULL
};
1894 struct ldb_result
*res
;
1895 struct ldb_request
*req
;
1897 struct ldb_context
*ldb_ctx
;
1898 struct ldb_control
**parsed_controls
;
1899 struct ldb_dn
*base
;
1901 TALLOC_CTX
*mem_ctx
;
1903 /* type "int" rather than "enum" for "scope" is intentional */
1904 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OizOO",
1905 discard_const_p(char *, kwnames
),
1906 &py_base
, &scope
, &expr
, &py_attrs
, &py_controls
))
1910 mem_ctx
= talloc_new(NULL
);
1911 if (mem_ctx
== NULL
) {
1915 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1917 if (py_attrs
== Py_None
) {
1920 attrs
= PyList_AsStrList(mem_ctx
, py_attrs
, "attrs");
1921 if (attrs
== NULL
) {
1922 talloc_free(mem_ctx
);
1927 if (py_base
== Py_None
) {
1928 base
= ldb_get_default_basedn(ldb_ctx
);
1930 if (!pyldb_Object_AsDn(mem_ctx
, py_base
, ldb_ctx
, &base
)) {
1931 talloc_free(mem_ctx
);
1936 if (py_controls
== Py_None
) {
1937 parsed_controls
= NULL
;
1939 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1940 if (controls
== NULL
) {
1941 talloc_free(mem_ctx
);
1944 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1945 talloc_free(controls
);
1948 res
= talloc_zero(mem_ctx
, struct ldb_result
);
1951 talloc_free(mem_ctx
);
1955 ret
= ldb_build_search_req(&req
, ldb_ctx
, mem_ctx
,
1962 ldb_search_default_callback
,
1965 if (ret
!= LDB_SUCCESS
) {
1966 talloc_free(mem_ctx
);
1967 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1971 talloc_steal(req
, attrs
);
1973 ret
= ldb_request(ldb_ctx
, req
);
1975 if (ret
== LDB_SUCCESS
) {
1976 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1979 if (ret
!= LDB_SUCCESS
) {
1980 talloc_free(mem_ctx
);
1981 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1985 py_ret
= PyLdbResult_FromResult(res
);
1987 talloc_free(mem_ctx
);
1992 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply
*reply
)
1994 if (reply
->py_iter
!= NULL
) {
1995 DLIST_REMOVE(reply
->py_iter
->state
.next
, reply
);
1996 if (reply
->py_iter
->state
.result
== reply
) {
1997 reply
->py_iter
->state
.result
= NULL
;
1999 reply
->py_iter
= NULL
;
2002 if (reply
->obj
!= NULL
) {
2003 Py_DECREF(reply
->obj
);
2010 static int py_ldb_search_iterator_callback(struct ldb_request
*req
,
2011 struct ldb_reply
*ares
)
2013 PyLdbSearchIteratorObject
*py_iter
= (PyLdbSearchIteratorObject
*)req
->context
;
2014 struct ldb_result result
= { .msgs
= NULL
};
2015 struct py_ldb_search_iterator_reply
*reply
= NULL
;
2018 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2021 if (ares
->error
!= LDB_SUCCESS
) {
2022 int ret
= ares
->error
;
2024 return ldb_request_done(req
, ret
);
2027 reply
= talloc_zero(py_iter
->mem_ctx
,
2028 struct py_ldb_search_iterator_reply
);
2029 if (reply
== NULL
) {
2031 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2033 reply
->py_iter
= py_iter
;
2034 talloc_set_destructor(reply
, py_ldb_search_iterator_reply_destructor
);
2036 switch (ares
->type
) {
2037 case LDB_REPLY_ENTRY
:
2038 reply
->obj
= PyLdbMessage_FromMessage(ares
->message
);
2039 if (reply
->obj
== NULL
) {
2041 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2043 DLIST_ADD_END(py_iter
->state
.next
, reply
);
2047 case LDB_REPLY_REFERRAL
:
2048 reply
->obj
= PyUnicode_FromString(ares
->referral
);
2049 if (reply
->obj
== NULL
) {
2051 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2053 DLIST_ADD_END(py_iter
->state
.next
, reply
);
2057 case LDB_REPLY_DONE
:
2058 result
= (struct ldb_result
) { .controls
= ares
->controls
};
2059 reply
->obj
= PyLdbResult_FromResult(&result
);
2060 if (reply
->obj
== NULL
) {
2062 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2064 py_iter
->state
.result
= reply
;
2066 return ldb_request_done(req
, LDB_SUCCESS
);
2070 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2073 static PyObject
*py_ldb_search_iterator(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
2075 PyObject
*py_base
= Py_None
;
2076 int scope
= LDB_SCOPE_DEFAULT
;
2079 PyObject
*py_attrs
= Py_None
;
2080 PyObject
*py_controls
= Py_None
;
2081 const char * const kwnames
[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL
};
2084 struct ldb_context
*ldb_ctx
;
2085 struct ldb_control
**parsed_controls
;
2086 struct ldb_dn
*base
;
2087 PyLdbSearchIteratorObject
*py_iter
;
2089 /* type "int" rather than "enum" for "scope" is intentional */
2090 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OizOOi",
2091 discard_const_p(char *, kwnames
),
2092 &py_base
, &scope
, &expr
, &py_attrs
, &py_controls
, &timeout
))
2095 py_iter
= (PyLdbSearchIteratorObject
*)PyLdbSearchIterator
.tp_alloc(&PyLdbSearchIterator
, 0);
2096 if (py_iter
== NULL
) {
2100 py_iter
->ldb
= self
;
2102 ZERO_STRUCT(py_iter
->state
);
2103 py_iter
->mem_ctx
= talloc_new(NULL
);
2104 if (py_iter
->mem_ctx
== NULL
) {
2110 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2112 if (py_attrs
== Py_None
) {
2115 attrs
= PyList_AsStrList(py_iter
->mem_ctx
, py_attrs
, "attrs");
2116 if (attrs
== NULL
) {
2123 if (py_base
== Py_None
) {
2124 base
= ldb_get_default_basedn(ldb_ctx
);
2126 if (!pyldb_Object_AsDn(py_iter
->mem_ctx
, py_base
, ldb_ctx
, &base
)) {
2133 if (py_controls
== Py_None
) {
2134 parsed_controls
= NULL
;
2136 const char **controls
= NULL
;
2138 controls
= PyList_AsStrList(py_iter
->mem_ctx
,
2139 py_controls
, "controls");
2140 if (controls
== NULL
) {
2146 parsed_controls
= ldb_parse_control_strings(ldb_ctx
,
2149 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
2154 talloc_free(controls
);
2157 ret
= ldb_build_search_req(&py_iter
->state
.req
,
2166 py_ldb_search_iterator_callback
,
2168 if (ret
!= LDB_SUCCESS
) {
2170 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2174 ldb_set_timeout(ldb_ctx
, py_iter
->state
.req
, timeout
);
2176 ret
= ldb_request(ldb_ctx
, py_iter
->state
.req
);
2177 if (ret
!= LDB_SUCCESS
) {
2179 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2183 return (PyObject
*)py_iter
;
2186 static PyObject
*py_ldb_get_opaque(PyLdbObject
*self
, PyObject
*args
)
2191 if (!PyArg_ParseTuple(args
, "s", &name
))
2194 data
= ldb_get_opaque(pyldb_Ldb_AS_LDBCONTEXT(self
), name
);
2199 /* FIXME: More interpretation */
2204 static PyObject
*py_ldb_set_opaque(PyLdbObject
*self
, PyObject
*args
)
2209 if (!PyArg_ParseTuple(args
, "sO", &name
, &data
))
2212 /* FIXME: More interpretation */
2214 ldb_set_opaque(pyldb_Ldb_AS_LDBCONTEXT(self
), name
, data
);
2219 static PyObject
*py_ldb_modules(PyLdbObject
*self
,
2220 PyObject
*Py_UNUSED(ignored
))
2222 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2223 PyObject
*ret
= PyList_New(0);
2224 struct ldb_module
*mod
;
2227 return PyErr_NoMemory();
2229 for (mod
= ldb
->modules
; mod
; mod
= mod
->next
) {
2230 PyObject
*item
= PyLdbModule_FromModule(mod
);
2233 PyErr_SetString(PyExc_RuntimeError
,
2234 "Failed to load LdbModule");
2238 res
= PyList_Append(ret
, item
);
2249 static PyObject
*py_ldb_sequence_number(PyLdbObject
*self
, PyObject
*args
)
2251 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2255 if (!PyArg_ParseTuple(args
, "i", &type
))
2258 /* FIXME: More interpretation */
2260 ret
= ldb_sequence_number(ldb
, type
, &value
);
2262 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2264 return PyLong_FromLongLong(value
);
2268 static const struct ldb_dn_extended_syntax test_dn_syntax
= {
2270 .read_fn
= ldb_handler_copy
,
2271 .write_clear_fn
= ldb_handler_copy
,
2272 .write_hex_fn
= ldb_handler_copy
,
2275 static PyObject
*py_ldb_register_test_extensions(PyLdbObject
*self
,
2276 PyObject
*Py_UNUSED(ignored
))
2278 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2281 ret
= ldb_dn_extended_add_syntax(ldb
, LDB_ATTR_FLAG_FIXED
, &test_dn_syntax
);
2283 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2289 static PyMethodDef py_ldb_methods
[] = {
2290 { "set_debug", (PyCFunction
)py_ldb_set_debug
, METH_VARARGS
,
2291 "S.set_debug(callback) -> None\n"
2292 "Set callback for LDB debug messages.\n"
2293 "The callback should accept a debug level and debug text." },
2294 { "set_create_perms", (PyCFunction
)py_ldb_set_create_perms
, METH_VARARGS
,
2295 "S.set_create_perms(mode) -> None\n"
2296 "Set mode to use when creating new LDB files." },
2297 { "set_modules_dir", (PyCFunction
)py_ldb_set_modules_dir
, METH_VARARGS
,
2298 "S.set_modules_dir(path) -> None\n"
2299 "Set path LDB should search for modules" },
2300 { "transaction_start", (PyCFunction
)py_ldb_transaction_start
, METH_NOARGS
,
2301 "S.transaction_start() -> None\n"
2302 "Start a new transaction." },
2303 { "transaction_prepare_commit", (PyCFunction
)py_ldb_transaction_prepare_commit
, METH_NOARGS
,
2304 "S.transaction_prepare_commit() -> None\n"
2305 "prepare to commit a new transaction (2-stage commit)." },
2306 { "transaction_commit", (PyCFunction
)py_ldb_transaction_commit
, METH_NOARGS
,
2307 "S.transaction_commit() -> None\n"
2308 "commit a new transaction." },
2309 { "transaction_cancel", (PyCFunction
)py_ldb_transaction_cancel
, METH_NOARGS
,
2310 "S.transaction_cancel() -> None\n"
2311 "cancel a new transaction." },
2312 { "setup_wellknown_attributes", (PyCFunction
)py_ldb_setup_wellknown_attributes
, METH_NOARGS
,
2314 { "get_root_basedn", (PyCFunction
)py_ldb_get_root_basedn
, METH_NOARGS
,
2316 { "get_schema_basedn", (PyCFunction
)py_ldb_get_schema_basedn
, METH_NOARGS
,
2318 { "get_default_basedn", (PyCFunction
)py_ldb_get_default_basedn
, METH_NOARGS
,
2320 { "get_config_basedn", (PyCFunction
)py_ldb_get_config_basedn
, METH_NOARGS
,
2322 { "connect", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_connect
),
2323 METH_VARARGS
|METH_KEYWORDS
,
2324 "S.connect(url, flags=0, options=None) -> None\n"
2325 "Connect to a LDB URL." },
2326 { "modify", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_modify
),
2327 METH_VARARGS
|METH_KEYWORDS
,
2328 "S.modify(message, controls=None, validate=False) -> None\n"
2329 "Modify an entry." },
2330 { "add", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_add
),
2331 METH_VARARGS
|METH_KEYWORDS
,
2332 "S.add(message, controls=None) -> None\n"
2334 { "delete", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_delete
),
2335 METH_VARARGS
|METH_KEYWORDS
,
2336 "S.delete(dn, controls=None) -> None\n"
2337 "Remove an entry." },
2338 { "rename", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_rename
),
2339 METH_VARARGS
|METH_KEYWORDS
,
2340 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2341 "Rename an entry." },
2342 { "search", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_search
),
2343 METH_VARARGS
|METH_KEYWORDS
,
2344 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2345 "Search in a database.\n"
2347 ":param base: Optional base DN to search\n"
2348 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2349 ":param expression: Optional search expression\n"
2350 ":param attrs: Attributes to return (defaults to all)\n"
2351 ":param controls: Optional list of controls\n"
2352 ":return: ldb.Result object\n"
2354 { "search_iterator", PY_DISCARD_FUNC_SIG(PyCFunction
,
2355 py_ldb_search_iterator
),
2356 METH_VARARGS
|METH_KEYWORDS
,
2357 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2358 "Search in a database.\n"
2360 ":param base: Optional base DN to search\n"
2361 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2362 ":param expression: Optional search expression\n"
2363 ":param attrs: Attributes to return (defaults to all)\n"
2364 ":param controls: Optional list of controls\n"
2365 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2366 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2368 { "schema_attribute_remove", (PyCFunction
)py_ldb_schema_attribute_remove
, METH_VARARGS
,
2370 { "schema_attribute_add", (PyCFunction
)py_ldb_schema_attribute_add
, METH_VARARGS
,
2372 { "schema_format_value", (PyCFunction
)py_ldb_schema_format_value
, METH_VARARGS
,
2374 { "parse_ldif", (PyCFunction
)py_ldb_parse_ldif
, METH_VARARGS
,
2375 "S.parse_ldif(ldif) -> iter(messages)\n"
2376 "Parse a string formatted using LDIF." },
2377 { "write_ldif", (PyCFunction
)py_ldb_write_ldif
, METH_VARARGS
,
2378 "S.write_ldif(message, changetype) -> ldif\n"
2379 "Print the message as a string formatted using LDIF." },
2380 { "msg_diff", (PyCFunction
)py_ldb_msg_diff
, METH_VARARGS
,
2381 "S.msg_diff(Message) -> Message\n"
2382 "Return an LDB Message of the difference between two Message objects." },
2383 { "get_opaque", (PyCFunction
)py_ldb_get_opaque
, METH_VARARGS
,
2384 "S.get_opaque(name) -> value\n"
2385 "Get an opaque value set on this LDB connection. \n"
2386 ":note: The returned value may not be useful in Python."
2388 { "set_opaque", (PyCFunction
)py_ldb_set_opaque
, METH_VARARGS
,
2389 "S.set_opaque(name, value) -> None\n"
2390 "Set an opaque value on this LDB connection. \n"
2391 ":note: Passing incorrect values may cause crashes." },
2392 { "modules", (PyCFunction
)py_ldb_modules
, METH_NOARGS
,
2393 "S.modules() -> list\n"
2394 "Return the list of modules on this LDB connection " },
2395 { "sequence_number", (PyCFunction
)py_ldb_sequence_number
, METH_VARARGS
,
2396 "S.sequence_number(type) -> value\n"
2397 "Return the value of the sequence according to the requested type" },
2398 { "_register_test_extensions", (PyCFunction
)py_ldb_register_test_extensions
, METH_NOARGS
,
2399 "S._register_test_extensions() -> None\n"
2400 "Register internal extensions used in testing" },
2404 static PyObject
*PyLdbModule_FromModule(struct ldb_module
*mod
)
2406 PyLdbModuleObject
*ret
;
2408 ret
= (PyLdbModuleObject
*)PyLdbModule
.tp_alloc(&PyLdbModule
, 0);
2413 ret
->mem_ctx
= talloc_new(NULL
);
2414 ret
->mod
= talloc_reference(ret
->mem_ctx
, mod
);
2415 return (PyObject
*)ret
;
2418 static PyObject
*py_ldb_get_firstmodule(PyLdbObject
*self
, void *closure
)
2420 struct ldb_module
*mod
= pyldb_Ldb_AS_LDBCONTEXT(self
)->modules
;
2424 return PyLdbModule_FromModule(mod
);
2427 static PyGetSetDef py_ldb_getset
[] = {
2429 .name
= discard_const_p(char, "firstmodule"),
2430 .get
= (getter
)py_ldb_get_firstmodule
,
2435 static int py_ldb_contains(PyLdbObject
*self
, PyObject
*obj
)
2437 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2439 struct ldb_result
*result
;
2443 if (!pyldb_Object_AsDn(ldb_ctx
, obj
, ldb_ctx
, &dn
)) {
2447 ret
= ldb_search(ldb_ctx
, ldb_ctx
, &result
, dn
, LDB_SCOPE_BASE
, NULL
,
2449 if (ret
!= LDB_SUCCESS
) {
2450 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2454 count
= result
->count
;
2456 talloc_free(result
);
2459 PyErr_Format(PyExc_RuntimeError
,
2460 "Searching for [%s] dn gave %u results!",
2461 ldb_dn_get_linearized(dn
),
2469 static PySequenceMethods py_ldb_seq
= {
2470 .sq_contains
= (objobjproc
)py_ldb_contains
,
2473 static PyObject
*PyLdb_FromLdbContext(struct ldb_context
*ldb_ctx
)
2477 ret
= (PyLdbObject
*)PyLdb
.tp_alloc(&PyLdb
, 0);
2482 ret
->mem_ctx
= talloc_new(NULL
);
2483 ret
->ldb_ctx
= talloc_reference(ret
->mem_ctx
, ldb_ctx
);
2484 return (PyObject
*)ret
;
2487 static void py_ldb_dealloc(PyLdbObject
*self
)
2489 talloc_free(self
->mem_ctx
);
2490 Py_TYPE(self
)->tp_free(self
);
2493 static PyTypeObject PyLdb
= {
2494 .tp_name
= "ldb.Ldb",
2495 .tp_methods
= py_ldb_methods
,
2496 .tp_repr
= (reprfunc
)py_ldb_repr
,
2497 .tp_new
= py_ldb_new
,
2498 .tp_init
= (initproc
)py_ldb_init
,
2499 .tp_dealloc
= (destructor
)py_ldb_dealloc
,
2500 .tp_getset
= py_ldb_getset
,
2501 .tp_getattro
= PyObject_GenericGetAttr
,
2502 .tp_basicsize
= sizeof(PyLdbObject
),
2503 .tp_doc
= "Connection to a LDB database.",
2504 .tp_as_sequence
= &py_ldb_seq
,
2505 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
2508 static void py_ldb_result_dealloc(PyLdbResultObject
*self
)
2510 talloc_free(self
->mem_ctx
);
2511 Py_DECREF(self
->msgs
);
2512 Py_DECREF(self
->referals
);
2513 Py_DECREF(self
->controls
);
2514 Py_TYPE(self
)->tp_free(self
);
2517 static PyObject
*py_ldb_result_get_msgs(PyLdbResultObject
*self
, void *closure
)
2519 Py_INCREF(self
->msgs
);
2523 static PyObject
*py_ldb_result_get_controls(PyLdbResultObject
*self
, void *closure
)
2525 Py_INCREF(self
->controls
);
2526 return self
->controls
;
2529 static PyObject
*py_ldb_result_get_referals(PyLdbResultObject
*self
, void *closure
)
2531 Py_INCREF(self
->referals
);
2532 return self
->referals
;
2535 static PyObject
*py_ldb_result_get_count(PyLdbResultObject
*self
, void *closure
)
2538 if (self
->msgs
== NULL
) {
2539 PyErr_SetString(PyExc_AttributeError
, "Count attribute is meaningless in this context");
2542 size
= PyList_Size(self
->msgs
);
2543 return PyLong_FromLong(size
);
2546 static PyGetSetDef py_ldb_result_getset
[] = {
2548 .name
= discard_const_p(char, "controls"),
2549 .get
= (getter
)py_ldb_result_get_controls
,
2552 .name
= discard_const_p(char, "msgs"),
2553 .get
= (getter
)py_ldb_result_get_msgs
,
2556 .name
= discard_const_p(char, "referals"),
2557 .get
= (getter
)py_ldb_result_get_referals
,
2560 .name
= discard_const_p(char, "count"),
2561 .get
= (getter
)py_ldb_result_get_count
,
2566 static PyObject
*py_ldb_result_iter(PyLdbResultObject
*self
)
2568 return PyObject_GetIter(self
->msgs
);
2571 static Py_ssize_t
py_ldb_result_len(PyLdbResultObject
*self
)
2573 return PySequence_Size(self
->msgs
);
2576 static PyObject
*py_ldb_result_find(PyLdbResultObject
*self
, Py_ssize_t idx
)
2578 return PySequence_GetItem(self
->msgs
, idx
);
2581 static PySequenceMethods py_ldb_result_seq
= {
2582 .sq_length
= (lenfunc
)py_ldb_result_len
,
2583 .sq_item
= (ssizeargfunc
)py_ldb_result_find
,
2586 static PyObject
*py_ldb_result_repr(PyLdbObject
*self
)
2588 return PyUnicode_FromString("<ldb result>");
2592 static PyTypeObject PyLdbResult
= {
2593 .tp_name
= "ldb.Result",
2594 .tp_repr
= (reprfunc
)py_ldb_result_repr
,
2595 .tp_dealloc
= (destructor
)py_ldb_result_dealloc
,
2596 .tp_iter
= (getiterfunc
)py_ldb_result_iter
,
2597 .tp_getset
= py_ldb_result_getset
,
2598 .tp_getattro
= PyObject_GenericGetAttr
,
2599 .tp_basicsize
= sizeof(PyLdbResultObject
),
2600 .tp_as_sequence
= &py_ldb_result_seq
,
2601 .tp_doc
= "LDB result.",
2602 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
2605 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject
*self
)
2607 Py_XDECREF(self
->state
.exception
);
2608 TALLOC_FREE(self
->mem_ctx
);
2609 ZERO_STRUCT(self
->state
);
2610 Py_DECREF(self
->ldb
);
2611 Py_TYPE(self
)->tp_free(self
);
2614 static PyObject
*py_ldb_search_iterator_next(PyLdbSearchIteratorObject
*self
)
2616 PyObject
*py_ret
= NULL
;
2618 if (self
->state
.req
== NULL
) {
2619 PyErr_SetString(PyExc_RuntimeError
,
2620 "ldb.SearchIterator request already finished");
2625 * TODO: do we want a non-blocking mode?
2626 * In future we may add an optional 'nonblocking'
2627 * argument to search_iterator().
2629 * For now we keep it simple and wait for at
2633 while (self
->state
.next
== NULL
) {
2636 if (self
->state
.result
!= NULL
) {
2638 * We (already) got a final result from the server.
2640 * We stop the iteration and let
2641 * py_ldb_search_iterator_result() will deliver
2642 * the result details.
2644 TALLOC_FREE(self
->state
.req
);
2645 PyErr_SetNone(PyExc_StopIteration
);
2649 ret
= ldb_wait(self
->state
.req
->handle
, LDB_WAIT_NONE
);
2650 if (ret
!= LDB_SUCCESS
) {
2651 struct ldb_context
*ldb_ctx
;
2652 TALLOC_FREE(self
->state
.req
);
2653 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
->ldb
);
2655 * We stop the iteration and let
2656 * py_ldb_search_iterator_result() will deliver
2659 self
->state
.exception
= Py_BuildValue(discard_const_p(char, "(i,s)"),
2660 ret
, ldb_errstring(ldb_ctx
));
2661 PyErr_SetNone(PyExc_StopIteration
);
2666 py_ret
= self
->state
.next
->obj
;
2667 self
->state
.next
->obj
= NULL
;
2668 /* no TALLOC_FREE() as self->state.next is a list */
2669 talloc_free(self
->state
.next
);
2673 static PyObject
*py_ldb_search_iterator_result(PyLdbSearchIteratorObject
*self
,
2674 PyObject
*Py_UNUSED(ignored
))
2676 PyObject
*py_ret
= NULL
;
2678 if (self
->state
.req
!= NULL
) {
2679 PyErr_SetString(PyExc_RuntimeError
,
2680 "ldb.SearchIterator request running");
2684 if (self
->state
.next
!= NULL
) {
2685 PyErr_SetString(PyExc_RuntimeError
,
2686 "ldb.SearchIterator not fully consumed.");
2690 if (self
->state
.exception
!= NULL
) {
2691 PyErr_SetObject(PyExc_LdbError
, self
->state
.exception
);
2692 self
->state
.exception
= NULL
;
2696 if (self
->state
.result
== NULL
) {
2697 PyErr_SetString(PyExc_RuntimeError
,
2698 "ldb.SearchIterator result already consumed");
2702 py_ret
= self
->state
.result
->obj
;
2703 self
->state
.result
->obj
= NULL
;
2704 TALLOC_FREE(self
->state
.result
);
2708 static PyObject
*py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject
*self
,
2709 PyObject
*Py_UNUSED(ignored
))
2711 if (self
->state
.req
== NULL
) {
2712 PyErr_SetString(PyExc_RuntimeError
,
2713 "ldb.SearchIterator request already finished");
2717 Py_XDECREF(self
->state
.exception
);
2718 TALLOC_FREE(self
->mem_ctx
);
2719 ZERO_STRUCT(self
->state
);
2723 static PyMethodDef py_ldb_search_iterator_methods
[] = {
2724 { "result", (PyCFunction
)py_ldb_search_iterator_result
, METH_NOARGS
,
2725 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2726 { "abandon", (PyCFunction
)py_ldb_search_iterator_abandon
, METH_NOARGS
,
2731 static PyObject
*py_ldb_search_iterator_repr(PyLdbSearchIteratorObject
*self
)
2733 return PyUnicode_FromString("<ldb search iterator>");
2736 static PyTypeObject PyLdbSearchIterator
= {
2737 .tp_name
= "ldb.SearchIterator",
2738 .tp_repr
= (reprfunc
)py_ldb_search_iterator_repr
,
2739 .tp_dealloc
= (destructor
)py_ldb_search_iterator_dealloc
,
2740 .tp_iter
= PyObject_SelfIter
,
2741 .tp_iternext
= (iternextfunc
)py_ldb_search_iterator_next
,
2742 .tp_methods
= py_ldb_search_iterator_methods
,
2743 .tp_basicsize
= sizeof(PyLdbSearchIteratorObject
),
2744 .tp_doc
= "LDB search_iterator.",
2745 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
2748 static PyObject
*py_ldb_module_repr(PyLdbModuleObject
*self
)
2750 return PyUnicode_FromFormat("<ldb module '%s'>",
2751 pyldb_Module_AsModule(self
)->ops
->name
);
2754 static PyObject
*py_ldb_module_str(PyLdbModuleObject
*self
)
2756 return PyUnicode_FromString(pyldb_Module_AsModule(self
)->ops
->name
);
2759 static PyObject
*py_ldb_module_start_transaction(PyLdbModuleObject
*self
,
2760 PyObject
*Py_UNUSED(ignored
))
2762 pyldb_Module_AsModule(self
)->ops
->start_transaction(pyldb_Module_AsModule(self
));
2766 static PyObject
*py_ldb_module_end_transaction(PyLdbModuleObject
*self
,
2767 PyObject
*Py_UNUSED(ignored
))
2769 pyldb_Module_AsModule(self
)->ops
->end_transaction(pyldb_Module_AsModule(self
));
2773 static PyObject
*py_ldb_module_del_transaction(PyLdbModuleObject
*self
,
2774 PyObject
*Py_UNUSED(ignored
))
2776 pyldb_Module_AsModule(self
)->ops
->del_transaction(pyldb_Module_AsModule(self
));
2780 static PyObject
*py_ldb_module_search(PyLdbModuleObject
*self
, PyObject
*args
, PyObject
*kwargs
)
2782 PyObject
*py_base
, *py_tree
, *py_attrs
, *py_ret
;
2784 struct ldb_request
*req
;
2785 const char * const kwnames
[] = { "base", "scope", "tree", "attrs", NULL
};
2786 struct ldb_module
*mod
;
2787 const char * const*attrs
;
2789 /* type "int" rather than "enum" for "scope" is intentional */
2790 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O!iOO",
2791 discard_const_p(char *, kwnames
),
2792 &PyLdbDn
, &py_base
, &scope
, &py_tree
, &py_attrs
))
2797 if (py_attrs
== Py_None
) {
2800 attrs
= PyList_AsStrList(NULL
, py_attrs
, "attrs");
2805 ret
= ldb_build_search_req(&req
, mod
->ldb
, NULL
, pyldb_Dn_AS_DN(py_base
),
2806 scope
, NULL
/* expr */, attrs
,
2807 NULL
/* controls */, NULL
, NULL
, NULL
);
2809 talloc_steal(req
, attrs
);
2811 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, mod
->ldb
);
2813 req
->op
.search
.res
= NULL
;
2815 ret
= mod
->ops
->search(mod
, req
);
2817 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, mod
->ldb
);
2819 py_ret
= PyLdbResult_FromResult(req
->op
.search
.res
);
2827 static PyObject
*py_ldb_module_add(PyLdbModuleObject
*self
, PyObject
*args
)
2829 struct ldb_request
*req
;
2830 PyObject
*py_message
;
2832 struct ldb_module
*mod
;
2834 if (!PyArg_ParseTuple(args
, "O!", &PyLdbMessage
, &py_message
))
2837 req
= talloc_zero(NULL
, struct ldb_request
);
2838 req
->operation
= LDB_ADD
;
2839 req
->op
.add
.message
= pyldb_Message_AsMessage(py_message
);
2841 mod
= pyldb_Module_AsModule(self
);
2842 ret
= mod
->ops
->add(mod
, req
);
2844 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, mod
->ldb
);
2849 static PyObject
*py_ldb_module_modify(PyLdbModuleObject
*self
, PyObject
*args
)
2852 struct ldb_request
*req
;
2853 PyObject
*py_message
;
2854 struct ldb_module
*mod
;
2856 if (!PyArg_ParseTuple(args
, "O!", &PyLdbMessage
, &py_message
))
2859 req
= talloc_zero(NULL
, struct ldb_request
);
2860 req
->operation
= LDB_MODIFY
;
2861 req
->op
.mod
.message
= pyldb_Message_AsMessage(py_message
);
2863 mod
= pyldb_Module_AsModule(self
);
2864 ret
= mod
->ops
->modify(mod
, req
);
2866 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, mod
->ldb
);
2871 static PyObject
*py_ldb_module_delete(PyLdbModuleObject
*self
, PyObject
*args
)
2874 struct ldb_request
*req
;
2877 if (!PyArg_ParseTuple(args
, "O!", &PyLdbDn
, &py_dn
))
2880 req
= talloc_zero(NULL
, struct ldb_request
);
2881 req
->operation
= LDB_DELETE
;
2882 req
->op
.del
.dn
= pyldb_Dn_AS_DN(py_dn
);
2884 ret
= pyldb_Module_AsModule(self
)->ops
->del(pyldb_Module_AsModule(self
), req
);
2886 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
2891 static PyObject
*py_ldb_module_rename(PyLdbModuleObject
*self
, PyObject
*args
)
2894 struct ldb_request
*req
;
2895 PyObject
*py_dn1
, *py_dn2
;
2897 if (!PyArg_ParseTuple(args
, "O!O!", &PyLdbDn
, &py_dn1
, &PyLdbDn
, &py_dn2
))
2900 req
= talloc_zero(NULL
, struct ldb_request
);
2902 req
->operation
= LDB_RENAME
;
2903 req
->op
.rename
.olddn
= pyldb_Dn_AS_DN(py_dn1
);
2904 req
->op
.rename
.newdn
= pyldb_Dn_AS_DN(py_dn2
);
2906 ret
= pyldb_Module_AsModule(self
)->ops
->rename(pyldb_Module_AsModule(self
), req
);
2908 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
2913 static PyMethodDef py_ldb_module_methods
[] = {
2914 { "search", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_module_search
),
2915 METH_VARARGS
|METH_KEYWORDS
, NULL
},
2916 { "add", (PyCFunction
)py_ldb_module_add
, METH_VARARGS
, NULL
},
2917 { "modify", (PyCFunction
)py_ldb_module_modify
, METH_VARARGS
, NULL
},
2918 { "rename", (PyCFunction
)py_ldb_module_rename
, METH_VARARGS
, NULL
},
2919 { "delete", (PyCFunction
)py_ldb_module_delete
, METH_VARARGS
, NULL
},
2920 { "start_transaction", (PyCFunction
)py_ldb_module_start_transaction
, METH_NOARGS
, NULL
},
2921 { "end_transaction", (PyCFunction
)py_ldb_module_end_transaction
, METH_NOARGS
, NULL
},
2922 { "del_transaction", (PyCFunction
)py_ldb_module_del_transaction
, METH_NOARGS
, NULL
},
2926 static void py_ldb_module_dealloc(PyLdbModuleObject
*self
)
2928 talloc_free(self
->mem_ctx
);
2932 static PyTypeObject PyLdbModule
= {
2933 .tp_name
= "ldb.LdbModule",
2934 .tp_methods
= py_ldb_module_methods
,
2935 .tp_repr
= (reprfunc
)py_ldb_module_repr
,
2936 .tp_str
= (reprfunc
)py_ldb_module_str
,
2937 .tp_basicsize
= sizeof(PyLdbModuleObject
),
2938 .tp_dealloc
= (destructor
)py_ldb_module_dealloc
,
2939 .tp_flags
= Py_TPFLAGS_DEFAULT
,
2940 .tp_doc
= "LDB module (extension)",
2945 * Create a ldb_message_element from a Python object.
2947 * This will accept any sequence objects that contains strings, or
2950 * A reference to set_obj will be borrowed.
2952 * @param mem_ctx Memory context
2953 * @param set_obj Python object to convert
2954 * @param flags ldb_message_element flags to set
2955 * @param attr_name Name of the attribute
2956 * @return New ldb_message_element, allocated as child of mem_ctx
2958 static struct ldb_message_element
*PyObject_AsMessageElement(
2959 TALLOC_CTX
*mem_ctx
,
2962 const char *attr_name
)
2964 struct ldb_message_element
*me
;
2965 const char *msg
= NULL
;
2969 if (pyldb_MessageElement_Check(set_obj
)) {
2970 PyLdbMessageElementObject
*set_obj_as_me
= (PyLdbMessageElementObject
*)set_obj
;
2971 /* We have to talloc_reference() the memory context, not the pointer
2972 * which may not actually be it's own context */
2973 if (talloc_reference(mem_ctx
, set_obj_as_me
->mem_ctx
)) {
2974 return pyldb_MessageElement_AsMessageElement(set_obj
);
2979 me
= talloc(mem_ctx
, struct ldb_message_element
);
2985 me
->name
= talloc_strdup(me
, attr_name
);
2987 if (PyBytes_Check(set_obj
) || PyUnicode_Check(set_obj
)) {
2989 me
->values
= talloc_array(me
, struct ldb_val
, me
->num_values
);
2990 if (PyBytes_Check(set_obj
)) {
2992 result
= PyBytes_AsStringAndSize(set_obj
, &_msg
, &size
);
2999 msg
= PyUnicode_AsUTF8AndSize(set_obj
, &size
);
3005 me
->values
[0].data
= talloc_memdup(me
,
3006 (const uint8_t *)msg
,
3008 me
->values
[0].length
= size
;
3009 } else if (PySequence_Check(set_obj
)) {
3011 me
->num_values
= PySequence_Size(set_obj
);
3012 me
->values
= talloc_array(me
, struct ldb_val
, me
->num_values
);
3013 for (i
= 0; i
< me
->num_values
; i
++) {
3014 PyObject
*obj
= PySequence_GetItem(set_obj
, i
);
3015 if (PyBytes_Check(obj
)) {
3017 result
= PyBytes_AsStringAndSize(obj
, &_msg
, &size
);
3023 } else if (PyUnicode_Check(obj
)) {
3024 msg
= PyUnicode_AsUTF8AndSize(obj
, &size
);
3030 PyErr_Format(PyExc_TypeError
,
3031 "Expected string as element %zd in list", i
);
3035 me
->values
[i
].data
= talloc_memdup(me
,
3036 (const uint8_t *)msg
,
3038 me
->values
[i
].length
= size
;
3041 PyErr_Format(PyExc_TypeError
,
3042 "String or List type expected for '%s' attribute", attr_name
);
3051 static PyObject
*ldb_msg_element_to_set(struct ldb_context
*ldb_ctx
,
3052 struct ldb_message_element
*me
)
3057 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
3058 result
= PyList_New(me
->num_values
);
3060 for (i
= 0; i
< me
->num_values
; i
++) {
3061 PyList_SetItem(result
, i
,
3062 PyObject_FromLdbValue(&me
->values
[i
]));
3068 static PyObject
*py_ldb_msg_element_get(PyLdbMessageElementObject
*self
, PyObject
*args
)
3071 if (!PyArg_ParseTuple(args
, "I", &i
))
3073 if (i
>= pyldb_MessageElement_AsMessageElement(self
)->num_values
)
3076 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self
)->values
[i
]));
3079 static PyObject
*py_ldb_msg_element_flags(PyLdbMessageElementObject
*self
, PyObject
*args
)
3081 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3082 return PyLong_FromLong(el
->flags
);
3085 static PyObject
*py_ldb_msg_element_set_flags(PyLdbMessageElementObject
*self
, PyObject
*args
)
3088 struct ldb_message_element
*el
;
3089 if (!PyArg_ParseTuple(args
, "I", &flags
))
3092 el
= pyldb_MessageElement_AsMessageElement(self
);
3097 static PyMethodDef py_ldb_msg_element_methods
[] = {
3098 { "get", (PyCFunction
)py_ldb_msg_element_get
, METH_VARARGS
, NULL
},
3099 { "set_flags", (PyCFunction
)py_ldb_msg_element_set_flags
, METH_VARARGS
, NULL
},
3100 { "flags", (PyCFunction
)py_ldb_msg_element_flags
, METH_NOARGS
, NULL
},
3104 static Py_ssize_t
py_ldb_msg_element_len(PyLdbMessageElementObject
*self
)
3106 return pyldb_MessageElement_AsMessageElement(self
)->num_values
;
3109 static PyObject
*py_ldb_msg_element_find(PyLdbMessageElementObject
*self
, Py_ssize_t idx
)
3111 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3112 if (idx
< 0 || idx
>= el
->num_values
) {
3113 PyErr_SetString(PyExc_IndexError
, "Out of range");
3116 return PyLdbBytes_FromStringAndSize((char *)el
->values
[idx
].data
, el
->values
[idx
].length
);
3119 static PySequenceMethods py_ldb_msg_element_seq
= {
3120 .sq_length
= (lenfunc
)py_ldb_msg_element_len
,
3121 .sq_item
= (ssizeargfunc
)py_ldb_msg_element_find
,
3124 static PyObject
*py_ldb_msg_element_richcmp(PyObject
*self
, PyObject
*other
, int op
)
3127 if (!pyldb_MessageElement_Check(other
)) {
3128 Py_INCREF(Py_NotImplemented
);
3129 return Py_NotImplemented
;
3131 ret
= ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self
),
3132 pyldb_MessageElement_AsMessageElement(other
));
3133 return richcmp(ret
, op
);
3136 static PyObject
*py_ldb_msg_element_iter(PyLdbMessageElementObject
*self
)
3138 PyObject
*el
= ldb_msg_element_to_set(NULL
,
3139 pyldb_MessageElement_AsMessageElement(self
));
3140 PyObject
*ret
= PyObject_GetIter(el
);
3145 static PyObject
*PyLdbMessageElement_FromMessageElement(struct ldb_message_element
*el
, TALLOC_CTX
*mem_ctx
)
3147 PyLdbMessageElementObject
*ret
;
3148 ret
= PyObject_New(PyLdbMessageElementObject
, &PyLdbMessageElement
);
3153 ret
->mem_ctx
= talloc_new(NULL
);
3154 if (talloc_reference(ret
->mem_ctx
, mem_ctx
) == NULL
) {
3159 return (PyObject
*)ret
;
3162 static PyObject
*py_ldb_msg_element_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
3164 PyObject
*py_elements
= NULL
;
3165 struct ldb_message_element
*el
;
3166 unsigned int flags
= 0;
3168 const char * const kwnames
[] = { "elements", "flags", "name", NULL
};
3169 PyLdbMessageElementObject
*ret
;
3170 TALLOC_CTX
*mem_ctx
;
3171 const char *msg
= NULL
;
3175 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OIs",
3176 discard_const_p(char *, kwnames
),
3177 &py_elements
, &flags
, &name
))
3180 mem_ctx
= talloc_new(NULL
);
3181 if (mem_ctx
== NULL
) {
3186 el
= talloc_zero(mem_ctx
, struct ldb_message_element
);
3189 talloc_free(mem_ctx
);
3193 if (py_elements
!= NULL
) {
3195 if (PyBytes_Check(py_elements
) || PyUnicode_Check(py_elements
)) {
3198 el
->values
= talloc_array(el
, struct ldb_val
, 1);
3199 if (el
->values
== NULL
) {
3200 talloc_free(mem_ctx
);
3204 if (PyBytes_Check(py_elements
)) {
3205 result
= PyBytes_AsStringAndSize(py_elements
, &_msg
, &size
);
3208 msg
= PyUnicode_AsUTF8AndSize(py_elements
, &size
);
3209 result
= (msg
== NULL
) ? -1 : 0;
3212 talloc_free(mem_ctx
);
3215 el
->values
[0].data
= talloc_memdup(el
->values
,
3216 (const uint8_t *)msg
, size
+ 1);
3217 el
->values
[0].length
= size
;
3218 } else if (PySequence_Check(py_elements
)) {
3219 el
->num_values
= PySequence_Size(py_elements
);
3220 el
->values
= talloc_array(el
, struct ldb_val
, el
->num_values
);
3221 if (el
->values
== NULL
) {
3222 talloc_free(mem_ctx
);
3226 for (i
= 0; i
< el
->num_values
; i
++) {
3227 PyObject
*item
= PySequence_GetItem(py_elements
, i
);
3229 talloc_free(mem_ctx
);
3232 if (PyBytes_Check(item
)) {
3234 result
= PyBytes_AsStringAndSize(item
, &_msg
, &size
);
3236 } else if (PyUnicode_Check(item
)) {
3237 msg
= PyUnicode_AsUTF8AndSize(item
, &size
);
3238 result
= (msg
== NULL
) ? -1 : 0;
3240 PyErr_Format(PyExc_TypeError
,
3241 "Expected string as element %zd in list", i
);
3245 talloc_free(mem_ctx
);
3248 el
->values
[i
].data
= talloc_memdup(el
,
3249 (const uint8_t *)msg
, size
+1);
3250 el
->values
[i
].length
= size
;
3253 PyErr_SetString(PyExc_TypeError
,
3254 "Expected string or list");
3255 talloc_free(mem_ctx
);
3261 el
->name
= talloc_strdup(el
, name
);
3263 ret
= PyObject_New(PyLdbMessageElementObject
, type
);
3265 talloc_free(mem_ctx
);
3269 ret
->mem_ctx
= mem_ctx
;
3271 return (PyObject
*)ret
;
3274 static PyObject
*py_ldb_msg_element_repr(PyLdbMessageElementObject
*self
)
3276 char *element_str
= NULL
;
3278 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3279 PyObject
*ret
, *repr
;
3281 for (i
= 0; i
< el
->num_values
; i
++) {
3282 PyObject
*o
= py_ldb_msg_element_find(self
, i
);
3283 repr
= PyObject_Repr(o
);
3284 if (element_str
== NULL
)
3285 element_str
= talloc_strdup(NULL
, PyUnicode_AsUTF8(repr
));
3287 element_str
= talloc_asprintf_append(element_str
, ",%s", PyUnicode_AsUTF8(repr
));
3291 if (element_str
!= NULL
) {
3292 ret
= PyUnicode_FromFormat("MessageElement([%s])", element_str
);
3293 talloc_free(element_str
);
3295 ret
= PyUnicode_FromString("MessageElement([])");
3301 static PyObject
*py_ldb_msg_element_str(PyLdbMessageElementObject
*self
)
3303 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3305 if (el
->num_values
== 1)
3306 return PyUnicode_FromStringAndSize((char *)el
->values
[0].data
, el
->values
[0].length
);
3311 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject
*self
)
3313 talloc_free(self
->mem_ctx
);
3317 static PyObject
*py_ldb_msg_element_get_text(PyObject
*self
, void *closure
)
3319 return wrap_text("MessageElementTextWrapper", self
);
3322 static PyGetSetDef py_ldb_msg_element_getset
[] = {
3324 .name
= discard_const_p(char, "text"),
3325 .get
= (getter
)py_ldb_msg_element_get_text
,
3330 static PyTypeObject PyLdbMessageElement
= {
3331 .tp_name
= "ldb.MessageElement",
3332 .tp_basicsize
= sizeof(PyLdbMessageElementObject
),
3333 .tp_dealloc
= (destructor
)py_ldb_msg_element_dealloc
,
3334 .tp_repr
= (reprfunc
)py_ldb_msg_element_repr
,
3335 .tp_str
= (reprfunc
)py_ldb_msg_element_str
,
3336 .tp_methods
= py_ldb_msg_element_methods
,
3337 .tp_getset
= py_ldb_msg_element_getset
,
3338 .tp_richcompare
= (richcmpfunc
)py_ldb_msg_element_richcmp
,
3339 .tp_iter
= (getiterfunc
)py_ldb_msg_element_iter
,
3340 .tp_as_sequence
= &py_ldb_msg_element_seq
,
3341 .tp_new
= py_ldb_msg_element_new
,
3342 .tp_flags
= Py_TPFLAGS_DEFAULT
,
3343 .tp_doc
= "An element of a Message",
3347 static PyObject
*py_ldb_msg_from_dict(PyTypeObject
*type
, PyObject
*args
)
3352 struct ldb_message
*msg
;
3353 struct ldb_context
*ldb_ctx
;
3354 unsigned int mod_flags
= LDB_FLAG_MOD_REPLACE
;
3356 if (!PyArg_ParseTuple(args
, "O!O!|I",
3357 &PyLdb
, &py_ldb
, &PyDict_Type
, &py_dict
,
3362 if (!PyLdb_Check(py_ldb
)) {
3363 PyErr_SetString(PyExc_TypeError
, "Expected Ldb");
3367 /* mask only flags we are going to use */
3368 mod_flags
= LDB_FLAG_MOD_TYPE(mod_flags
);
3370 PyErr_SetString(PyExc_ValueError
,
3371 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3372 " expected as mod_flag value");
3376 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(py_ldb
);
3378 msg
= PyDict_AsMessage(ldb_ctx
, py_dict
, ldb_ctx
, mod_flags
);
3383 py_ret
= PyLdbMessage_FromMessage(msg
);
3385 talloc_unlink(ldb_ctx
, msg
);
3390 static PyObject
*py_ldb_msg_remove_attr(PyLdbMessageObject
*self
, PyObject
*args
)
3393 if (!PyArg_ParseTuple(args
, "s", &name
))
3396 ldb_msg_remove_attr(self
->msg
, name
);
3401 static PyObject
*py_ldb_msg_keys(PyLdbMessageObject
*self
,
3402 PyObject
*Py_UNUSED(ignored
))
3404 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3405 Py_ssize_t i
, j
= 0;
3406 PyObject
*obj
= PyList_New(msg
->num_elements
+(msg
->dn
!= NULL
?1:0));
3407 if (msg
->dn
!= NULL
) {
3408 PyList_SetItem(obj
, j
, PyUnicode_FromString("dn"));
3411 for (i
= 0; i
< msg
->num_elements
; i
++) {
3412 PyList_SetItem(obj
, j
, PyUnicode_FromString(msg
->elements
[i
].name
));
3418 static PyObject
*py_ldb_msg_getitem_helper(PyLdbMessageObject
*self
, PyObject
*py_name
)
3420 struct ldb_message_element
*el
;
3422 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3423 name
= PyUnicode_AsUTF8(py_name
);
3425 PyErr_SetNone(PyExc_TypeError
);
3428 if (!ldb_attr_cmp(name
, "dn"))
3429 return pyldb_Dn_FromDn(msg
->dn
);
3430 el
= ldb_msg_find_element(msg
, name
);
3434 return (PyObject
*)PyLdbMessageElement_FromMessageElement(el
, msg
->elements
);
3437 static PyObject
*py_ldb_msg_getitem(PyLdbMessageObject
*self
, PyObject
*py_name
)
3439 PyObject
*ret
= py_ldb_msg_getitem_helper(self
, py_name
);
3441 PyErr_SetString(PyExc_KeyError
, "No such element");
3447 static PyObject
*py_ldb_msg_get(PyLdbMessageObject
*self
, PyObject
*args
, PyObject
*kwargs
)
3449 PyObject
*def
= NULL
;
3450 const char *kwnames
[] = { "name", "default", "idx", NULL
};
3451 const char *name
= NULL
;
3453 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3454 struct ldb_message_element
*el
;
3456 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|Oi:msg",
3457 discard_const_p(char *, kwnames
), &name
, &def
, &idx
)) {
3461 if (strcasecmp(name
, "dn") == 0) {
3462 return pyldb_Dn_FromDn(msg
->dn
);
3465 el
= ldb_msg_find_element(msg
, name
);
3467 if (el
== NULL
|| (idx
!= -1 && el
->num_values
<= idx
)) {
3476 return (PyObject
*)PyLdbMessageElement_FromMessageElement(el
, msg
->elements
);
3479 return PyObject_FromLdbValue(&el
->values
[idx
]);
3482 static PyObject
*py_ldb_msg_items(PyLdbMessageObject
*self
,
3483 PyObject
*Py_UNUSED(ignored
))
3485 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3486 Py_ssize_t i
, j
= 0;
3487 PyObject
*l
= PyList_New(msg
->num_elements
+ (msg
->dn
== NULL
?0:1));
3489 return PyErr_NoMemory();
3491 if (msg
->dn
!= NULL
) {
3492 PyObject
*value
= NULL
;
3493 PyObject
*obj
= pyldb_Dn_FromDn(msg
->dn
);
3495 value
= Py_BuildValue("(sO)", "dn", obj
);
3497 if (value
== NULL
) {
3501 res
= PyList_SetItem(l
, 0, value
);
3508 for (i
= 0; i
< msg
->num_elements
; i
++, j
++) {
3509 PyObject
*value
= NULL
;
3510 PyObject
*py_el
= PyLdbMessageElement_FromMessageElement(&msg
->elements
[i
], msg
->elements
);
3513 value
= Py_BuildValue("(sO)", msg
->elements
[i
].name
, py_el
);
3514 if (value
== NULL
) {
3518 res
= PyList_SetItem(l
, 0, value
);
3527 static PyObject
*py_ldb_msg_elements(PyLdbMessageObject
*self
,
3528 PyObject
*Py_UNUSED(ignored
))
3530 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3532 PyObject
*l
= PyList_New(msg
->num_elements
);
3533 for (i
= 0; i
< msg
->num_elements
; i
++) {
3534 PyList_SetItem(l
, i
, PyLdbMessageElement_FromMessageElement(&msg
->elements
[i
], msg
->elements
));
3539 static PyObject
*py_ldb_msg_add(PyLdbMessageObject
*self
, PyObject
*args
)
3541 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3542 PyLdbMessageElementObject
*py_element
;
3544 struct ldb_message_element
*el
;
3545 struct ldb_message_element
*el_new
;
3547 if (!PyArg_ParseTuple(args
, "O!", &PyLdbMessageElement
, &py_element
))
3550 el
= py_element
->el
;
3552 PyErr_SetString(PyExc_ValueError
, "Invalid MessageElement object");
3555 if (el
->name
== NULL
) {
3556 PyErr_SetString(PyExc_ValueError
,
3557 "The element has no name");
3560 ret
= ldb_msg_add_empty(msg
, el
->name
, el
->flags
, &el_new
);
3561 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
3563 /* now deep copy all attribute values */
3564 el_new
->values
= talloc_array(msg
->elements
, struct ldb_val
, el
->num_values
);
3565 if (el_new
->values
== NULL
) {
3569 el_new
->num_values
= el
->num_values
;
3571 for (i
= 0; i
< el
->num_values
; i
++) {
3572 el_new
->values
[i
] = ldb_val_dup(el_new
->values
, &el
->values
[i
]);
3573 if (el_new
->values
[i
].data
== NULL
3574 && el
->values
[i
].length
!= 0) {
3583 static PyMethodDef py_ldb_msg_methods
[] = {
3584 { "from_dict", (PyCFunction
)py_ldb_msg_from_dict
, METH_CLASS
| METH_VARARGS
,
3585 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
3586 "Class method to create ldb.Message object from Dictionary.\n"
3587 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3588 { "keys", (PyCFunction
)py_ldb_msg_keys
, METH_NOARGS
,
3589 "S.keys() -> list\n\n"
3590 "Return sequence of all attribute names." },
3591 { "remove", (PyCFunction
)py_ldb_msg_remove_attr
, METH_VARARGS
,
3592 "S.remove(name)\n\n"
3593 "Remove all entries for attributes with the specified name."},
3594 { "get", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_msg_get
),
3595 METH_VARARGS
| METH_KEYWORDS
,
3596 "msg.get(name,default=None,idx=None) -> string\n"
3597 "idx is the index into the values array\n"
3598 "if idx is None, then a list is returned\n"
3599 "if idx is not None, then the element with that index is returned\n"
3600 "if you pass the special name 'dn' then the DN object is returned\n"},
3601 { "items", (PyCFunction
)py_ldb_msg_items
, METH_NOARGS
, NULL
},
3602 { "elements", (PyCFunction
)py_ldb_msg_elements
, METH_NOARGS
, NULL
},
3603 { "add", (PyCFunction
)py_ldb_msg_add
, METH_VARARGS
,
3604 "S.add(element)\n\n"
3605 "Add an element to this message." },
3609 static PyObject
*py_ldb_msg_iter(PyLdbMessageObject
*self
)
3611 PyObject
*list
, *iter
;
3613 list
= py_ldb_msg_keys(self
, NULL
);
3614 iter
= PyObject_GetIter(list
);
3619 static int py_ldb_msg_setitem(PyLdbMessageObject
*self
, PyObject
*name
, PyObject
*value
)
3621 const char *attr_name
;
3623 attr_name
= PyUnicode_AsUTF8(name
);
3624 if (attr_name
== NULL
) {
3625 PyErr_SetNone(PyExc_TypeError
);
3629 if (value
== NULL
) {
3631 ldb_msg_remove_attr(self
->msg
, attr_name
);
3634 struct ldb_message_element
*el
= PyObject_AsMessageElement(self
->msg
,
3635 value
, 0, attr_name
);
3639 ldb_msg_remove_attr(pyldb_Message_AsMessage(self
), attr_name
);
3640 ret
= ldb_msg_add(pyldb_Message_AsMessage(self
), el
, el
->flags
);
3641 if (ret
!= LDB_SUCCESS
) {
3642 PyErr_SetLdbError(PyExc_LdbError
, ret
, NULL
);
3649 static Py_ssize_t
py_ldb_msg_length(PyLdbMessageObject
*self
)
3651 return pyldb_Message_AsMessage(self
)->num_elements
;
3654 static PyMappingMethods py_ldb_msg_mapping
= {
3655 .mp_length
= (lenfunc
)py_ldb_msg_length
,
3656 .mp_subscript
= (binaryfunc
)py_ldb_msg_getitem
,
3657 .mp_ass_subscript
= (objobjargproc
)py_ldb_msg_setitem
,
3660 static PyObject
*py_ldb_msg_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
3662 const char * const kwnames
[] = { "dn", NULL
};
3663 struct ldb_message
*ret
;
3664 TALLOC_CTX
*mem_ctx
;
3665 PyObject
*pydn
= NULL
;
3666 PyLdbMessageObject
*py_ret
;
3668 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|O",
3669 discard_const_p(char *, kwnames
),
3673 mem_ctx
= talloc_new(NULL
);
3674 if (mem_ctx
== NULL
) {
3679 ret
= ldb_msg_new(mem_ctx
);
3681 talloc_free(mem_ctx
);
3688 if (!pyldb_Object_AsDn(NULL
, pydn
, NULL
, &dn
)) {
3689 talloc_free(mem_ctx
);
3692 ret
->dn
= talloc_reference(ret
, dn
);
3695 py_ret
= (PyLdbMessageObject
*)type
->tp_alloc(type
, 0);
3696 if (py_ret
== NULL
) {
3698 talloc_free(mem_ctx
);
3702 py_ret
->mem_ctx
= mem_ctx
;
3704 return (PyObject
*)py_ret
;
3707 static PyObject
*PyLdbMessage_FromMessage(struct ldb_message
*msg
)
3709 PyLdbMessageObject
*ret
;
3711 ret
= (PyLdbMessageObject
*)PyLdbMessage
.tp_alloc(&PyLdbMessage
, 0);
3716 ret
->mem_ctx
= talloc_new(NULL
);
3717 ret
->msg
= talloc_reference(ret
->mem_ctx
, msg
);
3718 return (PyObject
*)ret
;
3721 static PyObject
*py_ldb_msg_get_dn(PyLdbMessageObject
*self
, void *closure
)
3723 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3724 return pyldb_Dn_FromDn(msg
->dn
);
3727 static int py_ldb_msg_set_dn(PyLdbMessageObject
*self
, PyObject
*value
, void *closure
)
3729 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3730 if (!pyldb_Dn_Check(value
)) {
3731 PyErr_SetString(PyExc_TypeError
, "expected dn");
3735 msg
->dn
= talloc_reference(msg
, pyldb_Dn_AS_DN(value
));
3739 static PyObject
*py_ldb_msg_get_text(PyObject
*self
, void *closure
)
3741 return wrap_text("MessageTextWrapper", self
);
3744 static PyGetSetDef py_ldb_msg_getset
[] = {
3746 .name
= discard_const_p(char, "dn"),
3747 .get
= (getter
)py_ldb_msg_get_dn
,
3748 .set
= (setter
)py_ldb_msg_set_dn
,
3751 .name
= discard_const_p(char, "text"),
3752 .get
= (getter
)py_ldb_msg_get_text
,
3757 static PyObject
*py_ldb_msg_repr(PyLdbMessageObject
*self
)
3759 PyObject
*dict
= PyDict_New(), *ret
, *repr
;
3760 if (PyDict_Update(dict
, (PyObject
*)self
) != 0)
3762 repr
= PyObject_Repr(dict
);
3767 ret
= PyUnicode_FromFormat("Message(%s)", PyUnicode_AsUTF8(repr
));
3773 static void py_ldb_msg_dealloc(PyLdbMessageObject
*self
)
3775 talloc_free(self
->mem_ctx
);
3779 static PyObject
*py_ldb_msg_richcmp(PyLdbMessageObject
*py_msg1
,
3780 PyLdbMessageObject
*py_msg2
, int op
)
3782 struct ldb_message
*msg1
, *msg2
;
3786 if (!PyLdbMessage_Check(py_msg2
)) {
3787 Py_INCREF(Py_NotImplemented
);
3788 return Py_NotImplemented
;
3791 msg1
= pyldb_Message_AsMessage(py_msg1
),
3792 msg2
= pyldb_Message_AsMessage(py_msg2
);
3794 if ((msg1
->dn
!= NULL
) || (msg2
->dn
!= NULL
)) {
3795 ret
= ldb_dn_compare(msg1
->dn
, msg2
->dn
);
3797 return richcmp(ret
, op
);
3801 ret
= msg1
->num_elements
- msg2
->num_elements
;
3803 return richcmp(ret
, op
);
3806 for (i
= 0; i
< msg1
->num_elements
; i
++) {
3807 ret
= ldb_msg_element_compare_name(&msg1
->elements
[i
],
3808 &msg2
->elements
[i
]);
3810 return richcmp(ret
, op
);
3813 ret
= ldb_msg_element_compare(&msg1
->elements
[i
],
3814 &msg2
->elements
[i
]);
3816 return richcmp(ret
, op
);
3820 return richcmp(0, op
);
3823 static PyTypeObject PyLdbMessage
= {
3824 .tp_name
= "ldb.Message",
3825 .tp_methods
= py_ldb_msg_methods
,
3826 .tp_getset
= py_ldb_msg_getset
,
3827 .tp_as_mapping
= &py_ldb_msg_mapping
,
3828 .tp_basicsize
= sizeof(PyLdbMessageObject
),
3829 .tp_dealloc
= (destructor
)py_ldb_msg_dealloc
,
3830 .tp_new
= py_ldb_msg_new
,
3831 .tp_repr
= (reprfunc
)py_ldb_msg_repr
,
3832 .tp_flags
= Py_TPFLAGS_DEFAULT
,
3833 .tp_iter
= (getiterfunc
)py_ldb_msg_iter
,
3834 .tp_richcompare
= (richcmpfunc
)py_ldb_msg_richcmp
,
3835 .tp_doc
= "A LDB Message",
3838 static PyObject
*PyLdbTree_FromTree(struct ldb_parse_tree
*tree
)
3840 PyLdbTreeObject
*ret
;
3842 ret
= (PyLdbTreeObject
*)PyLdbTree
.tp_alloc(&PyLdbTree
, 0);
3848 ret
->mem_ctx
= talloc_new(NULL
);
3849 ret
->tree
= talloc_reference(ret
->mem_ctx
, tree
);
3850 return (PyObject
*)ret
;
3853 static void py_ldb_tree_dealloc(PyLdbTreeObject
*self
)
3855 talloc_free(self
->mem_ctx
);
3859 static PyTypeObject PyLdbTree
= {
3860 .tp_name
= "ldb.Tree",
3861 .tp_basicsize
= sizeof(PyLdbTreeObject
),
3862 .tp_dealloc
= (destructor
)py_ldb_tree_dealloc
,
3863 .tp_flags
= Py_TPFLAGS_DEFAULT
,
3864 .tp_doc
= "A search tree",
3868 static int py_module_search(struct ldb_module
*mod
, struct ldb_request
*req
)
3870 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3871 PyObject
*py_result
, *py_base
, *py_attrs
, *py_tree
;
3873 py_base
= pyldb_Dn_FromDn(req
->op
.search
.base
);
3875 if (py_base
== NULL
)
3876 return LDB_ERR_OPERATIONS_ERROR
;
3878 py_tree
= PyLdbTree_FromTree(req
->op
.search
.tree
);
3880 if (py_tree
== NULL
)
3881 return LDB_ERR_OPERATIONS_ERROR
;
3883 if (req
->op
.search
.attrs
== NULL
) {
3887 for (len
= 0; req
->op
.search
.attrs
[len
]; len
++);
3888 py_attrs
= PyList_New(len
);
3889 for (i
= 0; i
< len
; i
++)
3890 PyList_SetItem(py_attrs
, i
, PyUnicode_FromString(req
->op
.search
.attrs
[i
]));
3893 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "search"),
3894 discard_const_p(char, "OiOO"),
3895 py_base
, req
->op
.search
.scope
, py_tree
, py_attrs
);
3897 Py_DECREF(py_attrs
);
3901 if (py_result
== NULL
) {
3902 return LDB_ERR_PYTHON_EXCEPTION
;
3905 req
->op
.search
.res
= PyLdbResult_AsResult(NULL
, py_result
);
3906 if (req
->op
.search
.res
== NULL
) {
3907 return LDB_ERR_PYTHON_EXCEPTION
;
3910 Py_DECREF(py_result
);
3915 static int py_module_add(struct ldb_module
*mod
, struct ldb_request
*req
)
3917 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3918 PyObject
*py_result
, *py_msg
;
3920 py_msg
= PyLdbMessage_FromMessage(discard_const_p(struct ldb_message
, req
->op
.add
.message
));
3922 if (py_msg
== NULL
) {
3923 return LDB_ERR_OPERATIONS_ERROR
;
3926 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "add"),
3927 discard_const_p(char, "O"),
3932 if (py_result
== NULL
) {
3933 return LDB_ERR_PYTHON_EXCEPTION
;
3936 Py_DECREF(py_result
);
3941 static int py_module_modify(struct ldb_module
*mod
, struct ldb_request
*req
)
3943 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3944 PyObject
*py_result
, *py_msg
;
3946 py_msg
= PyLdbMessage_FromMessage(discard_const_p(struct ldb_message
, req
->op
.mod
.message
));
3948 if (py_msg
== NULL
) {
3949 return LDB_ERR_OPERATIONS_ERROR
;
3952 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "modify"),
3953 discard_const_p(char, "O"),
3958 if (py_result
== NULL
) {
3959 return LDB_ERR_PYTHON_EXCEPTION
;
3962 Py_DECREF(py_result
);
3967 static int py_module_del(struct ldb_module
*mod
, struct ldb_request
*req
)
3969 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3970 PyObject
*py_result
, *py_dn
;
3972 py_dn
= pyldb_Dn_FromDn(req
->op
.del
.dn
);
3975 return LDB_ERR_OPERATIONS_ERROR
;
3977 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "delete"),
3978 discard_const_p(char, "O"),
3981 if (py_result
== NULL
) {
3982 return LDB_ERR_PYTHON_EXCEPTION
;
3985 Py_DECREF(py_result
);
3990 static int py_module_rename(struct ldb_module
*mod
, struct ldb_request
*req
)
3992 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3993 PyObject
*py_result
, *py_olddn
, *py_newdn
;
3995 py_olddn
= pyldb_Dn_FromDn(req
->op
.rename
.olddn
);
3997 if (py_olddn
== NULL
)
3998 return LDB_ERR_OPERATIONS_ERROR
;
4000 py_newdn
= pyldb_Dn_FromDn(req
->op
.rename
.newdn
);
4002 if (py_newdn
== NULL
)
4003 return LDB_ERR_OPERATIONS_ERROR
;
4005 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "rename"),
4006 discard_const_p(char, "OO"),
4007 py_olddn
, py_newdn
);
4009 Py_DECREF(py_olddn
);
4010 Py_DECREF(py_newdn
);
4012 if (py_result
== NULL
) {
4013 return LDB_ERR_PYTHON_EXCEPTION
;
4016 Py_DECREF(py_result
);
4021 static int py_module_request(struct ldb_module
*mod
, struct ldb_request
*req
)
4023 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4024 PyObject
*py_result
;
4026 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "request"),
4027 discard_const_p(char, ""));
4029 Py_XDECREF(py_result
);
4031 return LDB_ERR_OPERATIONS_ERROR
;
4034 static int py_module_extended(struct ldb_module
*mod
, struct ldb_request
*req
)
4036 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4037 PyObject
*py_result
;
4039 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "extended"),
4040 discard_const_p(char, ""));
4042 Py_XDECREF(py_result
);
4044 return LDB_ERR_OPERATIONS_ERROR
;
4047 static int py_module_start_transaction(struct ldb_module
*mod
)
4049 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4050 PyObject
*py_result
;
4052 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "start_transaction"),
4053 discard_const_p(char, ""));
4055 if (py_result
== NULL
) {
4056 return LDB_ERR_PYTHON_EXCEPTION
;
4059 Py_DECREF(py_result
);
4064 static int py_module_end_transaction(struct ldb_module
*mod
)
4066 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4067 PyObject
*py_result
;
4069 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "end_transaction"),
4070 discard_const_p(char, ""));
4072 if (py_result
== NULL
) {
4073 return LDB_ERR_PYTHON_EXCEPTION
;
4076 Py_DECREF(py_result
);
4081 static int py_module_del_transaction(struct ldb_module
*mod
)
4083 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4084 PyObject
*py_result
;
4086 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "del_transaction"),
4087 discard_const_p(char, ""));
4089 if (py_result
== NULL
) {
4090 return LDB_ERR_PYTHON_EXCEPTION
;
4093 Py_DECREF(py_result
);
4098 static int py_module_destructor(struct ldb_module
*mod
)
4100 Py_DECREF((PyObject
*)mod
->private_data
);
4104 static int py_module_init(struct ldb_module
*mod
)
4106 PyObject
*py_class
= (PyObject
*)mod
->ops
->private_data
;
4107 PyObject
*py_result
, *py_next
, *py_ldb
;
4109 py_ldb
= PyLdb_FromLdbContext(mod
->ldb
);
4112 return LDB_ERR_OPERATIONS_ERROR
;
4114 py_next
= PyLdbModule_FromModule(mod
->next
);
4116 if (py_next
== NULL
)
4117 return LDB_ERR_OPERATIONS_ERROR
;
4119 py_result
= PyObject_CallFunction(py_class
, discard_const_p(char, "OO"),
4122 if (py_result
== NULL
) {
4123 return LDB_ERR_PYTHON_EXCEPTION
;
4126 mod
->private_data
= py_result
;
4128 talloc_set_destructor(mod
, py_module_destructor
);
4130 return ldb_next_init(mod
);
4133 static PyObject
*py_register_module(PyObject
*module
, PyObject
*args
)
4136 struct ldb_module_ops
*ops
;
4138 PyObject
*tmp
= NULL
;
4139 const char *name
= NULL
;
4141 if (!PyArg_ParseTuple(args
, "O", &input
))
4144 ops
= talloc_zero(NULL
, struct ldb_module_ops
);
4150 tmp
= PyObject_GetAttrString(input
, discard_const_p(char, "name"));
4154 name
= PyUnicode_AsUTF8(tmp
);
4161 ops
->name
= talloc_strdup(ops
, name
);
4162 ops
->private_data
= input
;
4163 ops
->init_context
= py_module_init
;
4164 ops
->search
= py_module_search
;
4165 ops
->add
= py_module_add
;
4166 ops
->modify
= py_module_modify
;
4167 ops
->del
= py_module_del
;
4168 ops
->rename
= py_module_rename
;
4169 ops
->request
= py_module_request
;
4170 ops
->extended
= py_module_extended
;
4171 ops
->start_transaction
= py_module_start_transaction
;
4172 ops
->end_transaction
= py_module_end_transaction
;
4173 ops
->del_transaction
= py_module_del_transaction
;
4175 ret
= ldb_register_module(ops
);
4176 if (ret
!= LDB_SUCCESS
) {
4180 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
4185 static PyObject
*py_timestring(PyObject
*module
, PyObject
*args
)
4187 /* most times "time_t" is a signed integer type with 32 or 64 bit:
4188 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4192 if (!PyArg_ParseTuple(args
, "l", &t_val
))
4194 tresult
= ldb_timestring(NULL
, (time_t) t_val
);
4195 ret
= PyUnicode_FromString(tresult
);
4196 talloc_free(tresult
);
4200 static PyObject
*py_string_to_time(PyObject
*module
, PyObject
*args
)
4203 if (!PyArg_ParseTuple(args
, "s", &str
))
4206 return PyLong_FromLong(ldb_string_to_time(str
));
4209 static PyObject
*py_valid_attr_name(PyObject
*self
, PyObject
*args
)
4212 if (!PyArg_ParseTuple(args
, "s", &name
))
4214 return PyBool_FromLong(ldb_valid_attr_name(name
));
4218 encode a string using RFC2254 rules
4220 static PyObject
*py_binary_encode(PyObject
*self
, PyObject
*args
)
4222 char *str
, *encoded
;
4223 Py_ssize_t size
= 0;
4227 if (!PyArg_ParseTuple(args
, "s#", &str
, &size
))
4229 val
.data
= (uint8_t *)str
;
4232 encoded
= ldb_binary_encode(NULL
, val
);
4233 if (encoded
== NULL
) {
4234 PyErr_SetString(PyExc_TypeError
, "unable to encode binary string");
4237 ret
= PyUnicode_FromString(encoded
);
4238 talloc_free(encoded
);
4243 decode a string using RFC2254 rules
4245 static PyObject
*py_binary_decode(PyObject
*self
, PyObject
*args
)
4251 if (!PyArg_ParseTuple(args
, "s", &str
))
4254 val
= ldb_binary_decode(NULL
, str
);
4255 if (val
.data
== NULL
) {
4256 PyErr_SetString(PyExc_TypeError
, "unable to decode binary string");
4259 ret
= PyBytes_FromStringAndSize((const char*)val
.data
, val
.length
);
4260 talloc_free(val
.data
);
4264 static PyMethodDef py_ldb_global_methods
[] = {
4265 { "register_module", py_register_module
, METH_VARARGS
,
4266 "S.register_module(module) -> None\n\n"
4267 "Register a LDB module."},
4268 { "timestring", py_timestring
, METH_VARARGS
,
4269 "S.timestring(int) -> string\n\n"
4270 "Generate a LDAP time string from a UNIX timestamp" },
4271 { "string_to_time", py_string_to_time
, METH_VARARGS
,
4272 "S.string_to_time(string) -> int\n\n"
4273 "Parse a LDAP time string into a UNIX timestamp." },
4274 { "valid_attr_name", py_valid_attr_name
, METH_VARARGS
,
4275 "S.valid_attr_name(name) -> bool\n\nn"
4276 "Check whether the supplied name is a valid attribute name." },
4277 { "binary_encode", py_binary_encode
, METH_VARARGS
,
4278 "S.binary_encode(string) -> string\n\n"
4279 "Perform a RFC2254 binary encoding on a string" },
4280 { "binary_decode", py_binary_decode
, METH_VARARGS
,
4281 "S.binary_decode(string) -> string\n\n"
4282 "Perform a RFC2254 binary decode on a string" },
4286 #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."
4288 #if PY_MAJOR_VERSION >= 3
4289 static struct PyModuleDef moduledef
= {
4290 PyModuleDef_HEAD_INIT
,
4292 .m_doc
= MODULE_DOC
,
4294 .m_methods
= py_ldb_global_methods
,
4298 static PyObject
* module_init(void)
4302 PyLdbBytesType
.tp_base
= &PyBytes_Type
;
4303 if (PyType_Ready(&PyLdbBytesType
) < 0) {
4307 if (PyType_Ready(&PyLdbDn
) < 0)
4310 if (PyType_Ready(&PyLdbMessage
) < 0)
4313 if (PyType_Ready(&PyLdbMessageElement
) < 0)
4316 if (PyType_Ready(&PyLdb
) < 0)
4319 if (PyType_Ready(&PyLdbModule
) < 0)
4322 if (PyType_Ready(&PyLdbTree
) < 0)
4325 if (PyType_Ready(&PyLdbResult
) < 0)
4328 if (PyType_Ready(&PyLdbSearchIterator
) < 0)
4331 if (PyType_Ready(&PyLdbControl
) < 0)
4334 #if PY_MAJOR_VERSION >= 3
4335 m
= PyModule_Create(&moduledef
);
4337 m
= Py_InitModule3("ldb", py_ldb_global_methods
, MODULE_DOC
);
4342 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4344 ADD_LDB_INT(SEQ_HIGHEST_SEQ
);
4345 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP
);
4346 ADD_LDB_INT(SEQ_NEXT
);
4347 ADD_LDB_INT(SCOPE_DEFAULT
);
4348 ADD_LDB_INT(SCOPE_BASE
);
4349 ADD_LDB_INT(SCOPE_ONELEVEL
);
4350 ADD_LDB_INT(SCOPE_SUBTREE
);
4352 ADD_LDB_INT(CHANGETYPE_NONE
);
4353 ADD_LDB_INT(CHANGETYPE_ADD
);
4354 ADD_LDB_INT(CHANGETYPE_DELETE
);
4355 ADD_LDB_INT(CHANGETYPE_MODIFY
);
4357 ADD_LDB_INT(FLAG_MOD_ADD
);
4358 ADD_LDB_INT(FLAG_MOD_REPLACE
);
4359 ADD_LDB_INT(FLAG_MOD_DELETE
);
4360 ADD_LDB_INT(FLAG_FORCE_NO_BASE64_LDIF
);
4362 ADD_LDB_INT(ATTR_FLAG_HIDDEN
);
4363 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX
);
4364 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE
);
4365 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF
);
4367 ADD_LDB_INT(SUCCESS
);
4368 ADD_LDB_INT(ERR_OPERATIONS_ERROR
);
4369 ADD_LDB_INT(ERR_PROTOCOL_ERROR
);
4370 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED
);
4371 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED
);
4372 ADD_LDB_INT(ERR_COMPARE_FALSE
);
4373 ADD_LDB_INT(ERR_COMPARE_TRUE
);
4374 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED
);
4375 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED
);
4376 ADD_LDB_INT(ERR_REFERRAL
);
4377 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED
);
4378 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION
);
4379 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED
);
4380 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS
);
4381 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE
);
4382 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE
);
4383 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING
);
4384 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION
);
4385 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS
);
4386 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX
);
4387 ADD_LDB_INT(ERR_NO_SUCH_OBJECT
);
4388 ADD_LDB_INT(ERR_ALIAS_PROBLEM
);
4389 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX
);
4390 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM
);
4391 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION
);
4392 ADD_LDB_INT(ERR_INVALID_CREDENTIALS
);
4393 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS
);
4394 ADD_LDB_INT(ERR_BUSY
);
4395 ADD_LDB_INT(ERR_UNAVAILABLE
);
4396 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM
);
4397 ADD_LDB_INT(ERR_LOOP_DETECT
);
4398 ADD_LDB_INT(ERR_NAMING_VIOLATION
);
4399 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION
);
4400 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF
);
4401 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN
);
4402 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS
);
4403 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED
);
4404 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS
);
4405 ADD_LDB_INT(ERR_OTHER
);
4407 ADD_LDB_INT(FLG_RDONLY
);
4408 ADD_LDB_INT(FLG_NOSYNC
);
4409 ADD_LDB_INT(FLG_RECONNECT
);
4410 ADD_LDB_INT(FLG_NOMMAP
);
4411 ADD_LDB_INT(FLG_SHOW_BINARY
);
4412 ADD_LDB_INT(FLG_ENABLE_TRACING
);
4413 ADD_LDB_INT(FLG_DONT_CREATE_DB
);
4415 ADD_LDB_INT(PACKING_FORMAT
);
4416 ADD_LDB_INT(PACKING_FORMAT_V2
);
4418 /* Historical misspelling */
4419 PyModule_AddIntConstant(m
, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM
);
4421 PyModule_AddStringConstant(m
, "__docformat__", "restructuredText");
4423 PyExc_LdbError
= PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL
, NULL
);
4424 PyModule_AddObject(m
, "LdbError", PyExc_LdbError
);
4427 Py_INCREF(&PyLdbDn
);
4428 Py_INCREF(&PyLdbModule
);
4429 Py_INCREF(&PyLdbMessage
);
4430 Py_INCREF(&PyLdbMessageElement
);
4431 Py_INCREF(&PyLdbTree
);
4432 Py_INCREF(&PyLdbResult
);
4433 Py_INCREF(&PyLdbControl
);
4435 PyModule_AddObject(m
, "Ldb", (PyObject
*)&PyLdb
);
4436 PyModule_AddObject(m
, "Dn", (PyObject
*)&PyLdbDn
);
4437 PyModule_AddObject(m
, "Message", (PyObject
*)&PyLdbMessage
);
4438 PyModule_AddObject(m
, "MessageElement", (PyObject
*)&PyLdbMessageElement
);
4439 PyModule_AddObject(m
, "Module", (PyObject
*)&PyLdbModule
);
4440 PyModule_AddObject(m
, "Tree", (PyObject
*)&PyLdbTree
);
4441 PyModule_AddObject(m
, "Control", (PyObject
*)&PyLdbControl
);
4443 PyModule_AddStringConstant(m
, "__version__", PACKAGE_VERSION
);
4445 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4447 ADD_LDB_STRING(SYNTAX_DN
);
4448 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING
);
4449 ADD_LDB_STRING(SYNTAX_INTEGER
);
4450 ADD_LDB_STRING(SYNTAX_ORDERED_INTEGER
);
4451 ADD_LDB_STRING(SYNTAX_BOOLEAN
);
4452 ADD_LDB_STRING(SYNTAX_OCTET_STRING
);
4453 ADD_LDB_STRING(SYNTAX_UTC_TIME
);
4454 ADD_LDB_STRING(OID_COMPARATOR_AND
);
4455 ADD_LDB_STRING(OID_COMPARATOR_OR
);
4460 #if PY_MAJOR_VERSION >= 3
4461 PyMODINIT_FUNC
PyInit_ldb(void);
4462 PyMODINIT_FUNC
PyInit_ldb(void)
4464 return module_init();