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.set_component(num, name, value) -> None\n"
843 "set the attribute name and value of the specified component" },
844 { "get_rdn_name", (PyCFunction
)py_ldb_dn_get_rdn_name
, METH_NOARGS
,
845 "S.get_rdn_name() -> string\n"
846 "get the RDN attribute name" },
847 { "get_rdn_value", (PyCFunction
)py_ldb_dn_get_rdn_value
, METH_NOARGS
,
848 "S.get_rdn_value() -> string\n"
849 "get the RDN attribute value as a binary string" },
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
;
1807 TALLOC_CTX
*mem_ctx
= NULL
;
1809 if (!PyArg_ParseTuple(args
, "OO", &py_msg_old
, &py_msg_new
))
1812 if (!PyLdbMessage_Check(py_msg_old
)) {
1813 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for old message");
1817 if (!PyLdbMessage_Check(py_msg_new
)) {
1818 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for new message");
1822 mem_ctx
= talloc_new(NULL
);
1823 if (mem_ctx
== NULL
) {
1828 ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1829 ldb_ret
= ldb_msg_difference(ldb
, mem_ctx
,
1830 pyldb_Message_AsMessage(py_msg_old
),
1831 pyldb_Message_AsMessage(py_msg_new
),
1833 if (ldb_ret
!= LDB_SUCCESS
) {
1834 talloc_free(mem_ctx
);
1835 PyErr_SetString(PyExc_RuntimeError
, "Failed to generate the Ldb Message diff");
1839 diff
= ldb_msg_copy(mem_ctx
, diff
);
1845 py_ret
= PyLdbMessage_FromMessage(diff
);
1847 talloc_free(mem_ctx
);
1852 static PyObject
*py_ldb_schema_format_value(PyLdbObject
*self
, PyObject
*args
)
1854 const struct ldb_schema_attribute
*a
;
1855 struct ldb_val old_val
;
1856 struct ldb_val new_val
;
1857 TALLOC_CTX
*mem_ctx
;
1864 if (!PyArg_ParseTuple(args
, "sO", &element_name
, &val
))
1867 result
= PyBytes_AsStringAndSize(val
, (char **)&old_val
.data
, &size
);
1868 old_val
.length
= size
;
1871 PyErr_SetString(PyExc_RuntimeError
, "Failed to convert passed value to String");
1875 a
= ldb_schema_attribute_by_name(pyldb_Ldb_AS_LDBCONTEXT(self
), element_name
);
1881 mem_ctx
= talloc_new(NULL
);
1882 if (mem_ctx
== NULL
) {
1887 if (a
->syntax
->ldif_write_fn(pyldb_Ldb_AS_LDBCONTEXT(self
), mem_ctx
, &old_val
, &new_val
) != 0) {
1888 talloc_free(mem_ctx
);
1892 ret
= PyBytes_FromStringAndSize((const char *)new_val
.data
, new_val
.length
);
1894 talloc_free(mem_ctx
);
1899 static PyObject
*py_ldb_search(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1901 PyObject
*py_base
= Py_None
;
1902 int scope
= LDB_SCOPE_DEFAULT
;
1904 PyObject
*py_attrs
= Py_None
;
1905 PyObject
*py_controls
= Py_None
;
1906 const char * const kwnames
[] = { "base", "scope", "expression", "attrs", "controls", NULL
};
1908 struct ldb_result
*res
;
1909 struct ldb_request
*req
;
1911 struct ldb_context
*ldb_ctx
;
1912 struct ldb_control
**parsed_controls
;
1913 struct ldb_dn
*base
;
1915 TALLOC_CTX
*mem_ctx
;
1917 /* type "int" rather than "enum" for "scope" is intentional */
1918 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OizOO",
1919 discard_const_p(char *, kwnames
),
1920 &py_base
, &scope
, &expr
, &py_attrs
, &py_controls
))
1924 mem_ctx
= talloc_new(NULL
);
1925 if (mem_ctx
== NULL
) {
1929 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1931 if (py_attrs
== Py_None
) {
1934 attrs
= PyList_AsStrList(mem_ctx
, py_attrs
, "attrs");
1935 if (attrs
== NULL
) {
1936 talloc_free(mem_ctx
);
1941 if (py_base
== Py_None
) {
1942 base
= ldb_get_default_basedn(ldb_ctx
);
1944 if (!pyldb_Object_AsDn(mem_ctx
, py_base
, ldb_ctx
, &base
)) {
1945 talloc_free(mem_ctx
);
1950 if (py_controls
== Py_None
) {
1951 parsed_controls
= NULL
;
1953 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1954 if (controls
== NULL
) {
1955 talloc_free(mem_ctx
);
1958 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1959 talloc_free(controls
);
1962 res
= talloc_zero(mem_ctx
, struct ldb_result
);
1965 talloc_free(mem_ctx
);
1969 ret
= ldb_build_search_req(&req
, ldb_ctx
, mem_ctx
,
1976 ldb_search_default_callback
,
1979 if (ret
!= LDB_SUCCESS
) {
1980 talloc_free(mem_ctx
);
1981 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1985 talloc_steal(req
, attrs
);
1987 ret
= ldb_request(ldb_ctx
, req
);
1989 if (ret
== LDB_SUCCESS
) {
1990 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1993 if (ret
!= LDB_SUCCESS
) {
1994 talloc_free(mem_ctx
);
1995 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1999 py_ret
= PyLdbResult_FromResult(res
);
2001 talloc_free(mem_ctx
);
2006 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply
*reply
)
2008 if (reply
->py_iter
!= NULL
) {
2009 DLIST_REMOVE(reply
->py_iter
->state
.next
, reply
);
2010 if (reply
->py_iter
->state
.result
== reply
) {
2011 reply
->py_iter
->state
.result
= NULL
;
2013 reply
->py_iter
= NULL
;
2016 if (reply
->obj
!= NULL
) {
2017 Py_DECREF(reply
->obj
);
2024 static int py_ldb_search_iterator_callback(struct ldb_request
*req
,
2025 struct ldb_reply
*ares
)
2027 PyLdbSearchIteratorObject
*py_iter
= (PyLdbSearchIteratorObject
*)req
->context
;
2028 struct ldb_result result
= { .msgs
= NULL
};
2029 struct py_ldb_search_iterator_reply
*reply
= NULL
;
2032 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2035 if (ares
->error
!= LDB_SUCCESS
) {
2036 int ret
= ares
->error
;
2038 return ldb_request_done(req
, ret
);
2041 reply
= talloc_zero(py_iter
->mem_ctx
,
2042 struct py_ldb_search_iterator_reply
);
2043 if (reply
== NULL
) {
2045 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2047 reply
->py_iter
= py_iter
;
2048 talloc_set_destructor(reply
, py_ldb_search_iterator_reply_destructor
);
2050 switch (ares
->type
) {
2051 case LDB_REPLY_ENTRY
:
2052 reply
->obj
= PyLdbMessage_FromMessage(ares
->message
);
2053 if (reply
->obj
== NULL
) {
2055 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2057 DLIST_ADD_END(py_iter
->state
.next
, reply
);
2061 case LDB_REPLY_REFERRAL
:
2062 reply
->obj
= PyUnicode_FromString(ares
->referral
);
2063 if (reply
->obj
== NULL
) {
2065 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2067 DLIST_ADD_END(py_iter
->state
.next
, reply
);
2071 case LDB_REPLY_DONE
:
2072 result
= (struct ldb_result
) { .controls
= ares
->controls
};
2073 reply
->obj
= PyLdbResult_FromResult(&result
);
2074 if (reply
->obj
== NULL
) {
2076 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2078 py_iter
->state
.result
= reply
;
2080 return ldb_request_done(req
, LDB_SUCCESS
);
2084 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2087 static PyObject
*py_ldb_search_iterator(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
2089 PyObject
*py_base
= Py_None
;
2090 int scope
= LDB_SCOPE_DEFAULT
;
2093 PyObject
*py_attrs
= Py_None
;
2094 PyObject
*py_controls
= Py_None
;
2095 const char * const kwnames
[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL
};
2098 struct ldb_context
*ldb_ctx
;
2099 struct ldb_control
**parsed_controls
;
2100 struct ldb_dn
*base
;
2101 PyLdbSearchIteratorObject
*py_iter
;
2103 /* type "int" rather than "enum" for "scope" is intentional */
2104 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OizOOi",
2105 discard_const_p(char *, kwnames
),
2106 &py_base
, &scope
, &expr
, &py_attrs
, &py_controls
, &timeout
))
2109 py_iter
= (PyLdbSearchIteratorObject
*)PyLdbSearchIterator
.tp_alloc(&PyLdbSearchIterator
, 0);
2110 if (py_iter
== NULL
) {
2114 py_iter
->ldb
= self
;
2116 ZERO_STRUCT(py_iter
->state
);
2117 py_iter
->mem_ctx
= talloc_new(NULL
);
2118 if (py_iter
->mem_ctx
== NULL
) {
2124 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2126 if (py_attrs
== Py_None
) {
2129 attrs
= PyList_AsStrList(py_iter
->mem_ctx
, py_attrs
, "attrs");
2130 if (attrs
== NULL
) {
2137 if (py_base
== Py_None
) {
2138 base
= ldb_get_default_basedn(ldb_ctx
);
2140 if (!pyldb_Object_AsDn(py_iter
->mem_ctx
, py_base
, ldb_ctx
, &base
)) {
2147 if (py_controls
== Py_None
) {
2148 parsed_controls
= NULL
;
2150 const char **controls
= NULL
;
2152 controls
= PyList_AsStrList(py_iter
->mem_ctx
,
2153 py_controls
, "controls");
2154 if (controls
== NULL
) {
2160 parsed_controls
= ldb_parse_control_strings(ldb_ctx
,
2163 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
2168 talloc_free(controls
);
2171 ret
= ldb_build_search_req(&py_iter
->state
.req
,
2180 py_ldb_search_iterator_callback
,
2182 if (ret
!= LDB_SUCCESS
) {
2184 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2188 ldb_set_timeout(ldb_ctx
, py_iter
->state
.req
, timeout
);
2190 ret
= ldb_request(ldb_ctx
, py_iter
->state
.req
);
2191 if (ret
!= LDB_SUCCESS
) {
2193 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2197 return (PyObject
*)py_iter
;
2200 static PyObject
*py_ldb_get_opaque(PyLdbObject
*self
, PyObject
*args
)
2205 if (!PyArg_ParseTuple(args
, "s", &name
))
2208 data
= ldb_get_opaque(pyldb_Ldb_AS_LDBCONTEXT(self
), name
);
2213 /* FIXME: More interpretation */
2218 static PyObject
*py_ldb_set_opaque(PyLdbObject
*self
, PyObject
*args
)
2223 if (!PyArg_ParseTuple(args
, "sO", &name
, &data
))
2226 /* FIXME: More interpretation */
2228 ldb_set_opaque(pyldb_Ldb_AS_LDBCONTEXT(self
), name
, data
);
2233 static PyObject
*py_ldb_modules(PyLdbObject
*self
,
2234 PyObject
*Py_UNUSED(ignored
))
2236 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2237 PyObject
*ret
= PyList_New(0);
2238 struct ldb_module
*mod
;
2241 return PyErr_NoMemory();
2243 for (mod
= ldb
->modules
; mod
; mod
= mod
->next
) {
2244 PyObject
*item
= PyLdbModule_FromModule(mod
);
2247 PyErr_SetString(PyExc_RuntimeError
,
2248 "Failed to load LdbModule");
2252 res
= PyList_Append(ret
, item
);
2263 static PyObject
*py_ldb_sequence_number(PyLdbObject
*self
, PyObject
*args
)
2265 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2269 if (!PyArg_ParseTuple(args
, "i", &type
))
2272 /* FIXME: More interpretation */
2274 ret
= ldb_sequence_number(ldb
, type
, &value
);
2276 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2278 return PyLong_FromLongLong(value
);
2282 static const struct ldb_dn_extended_syntax test_dn_syntax
= {
2284 .read_fn
= ldb_handler_copy
,
2285 .write_clear_fn
= ldb_handler_copy
,
2286 .write_hex_fn
= ldb_handler_copy
,
2289 static PyObject
*py_ldb_register_test_extensions(PyLdbObject
*self
,
2290 PyObject
*Py_UNUSED(ignored
))
2292 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2295 ret
= ldb_dn_extended_add_syntax(ldb
, LDB_ATTR_FLAG_FIXED
, &test_dn_syntax
);
2297 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2303 static PyMethodDef py_ldb_methods
[] = {
2304 { "set_debug", (PyCFunction
)py_ldb_set_debug
, METH_VARARGS
,
2305 "S.set_debug(callback) -> None\n"
2306 "Set callback for LDB debug messages.\n"
2307 "The callback should accept a debug level and debug text." },
2308 { "set_create_perms", (PyCFunction
)py_ldb_set_create_perms
, METH_VARARGS
,
2309 "S.set_create_perms(mode) -> None\n"
2310 "Set mode to use when creating new LDB files." },
2311 { "set_modules_dir", (PyCFunction
)py_ldb_set_modules_dir
, METH_VARARGS
,
2312 "S.set_modules_dir(path) -> None\n"
2313 "Set path LDB should search for modules" },
2314 { "transaction_start", (PyCFunction
)py_ldb_transaction_start
, METH_NOARGS
,
2315 "S.transaction_start() -> None\n"
2316 "Start a new transaction." },
2317 { "transaction_prepare_commit", (PyCFunction
)py_ldb_transaction_prepare_commit
, METH_NOARGS
,
2318 "S.transaction_prepare_commit() -> None\n"
2319 "prepare to commit a new transaction (2-stage commit)." },
2320 { "transaction_commit", (PyCFunction
)py_ldb_transaction_commit
, METH_NOARGS
,
2321 "S.transaction_commit() -> None\n"
2322 "commit a new transaction." },
2323 { "transaction_cancel", (PyCFunction
)py_ldb_transaction_cancel
, METH_NOARGS
,
2324 "S.transaction_cancel() -> None\n"
2325 "cancel a new transaction." },
2326 { "setup_wellknown_attributes", (PyCFunction
)py_ldb_setup_wellknown_attributes
, METH_NOARGS
,
2328 { "get_root_basedn", (PyCFunction
)py_ldb_get_root_basedn
, METH_NOARGS
,
2330 { "get_schema_basedn", (PyCFunction
)py_ldb_get_schema_basedn
, METH_NOARGS
,
2332 { "get_default_basedn", (PyCFunction
)py_ldb_get_default_basedn
, METH_NOARGS
,
2334 { "get_config_basedn", (PyCFunction
)py_ldb_get_config_basedn
, METH_NOARGS
,
2336 { "connect", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_connect
),
2337 METH_VARARGS
|METH_KEYWORDS
,
2338 "S.connect(url, flags=0, options=None) -> None\n"
2339 "Connect to a LDB URL." },
2340 { "modify", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_modify
),
2341 METH_VARARGS
|METH_KEYWORDS
,
2342 "S.modify(message, controls=None, validate=False) -> None\n"
2343 "Modify an entry." },
2344 { "add", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_add
),
2345 METH_VARARGS
|METH_KEYWORDS
,
2346 "S.add(message, controls=None) -> None\n"
2348 { "delete", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_delete
),
2349 METH_VARARGS
|METH_KEYWORDS
,
2350 "S.delete(dn, controls=None) -> None\n"
2351 "Remove an entry." },
2352 { "rename", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_rename
),
2353 METH_VARARGS
|METH_KEYWORDS
,
2354 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2355 "Rename an entry." },
2356 { "search", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_search
),
2357 METH_VARARGS
|METH_KEYWORDS
,
2358 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2359 "Search in a database.\n"
2361 ":param base: Optional base DN to search\n"
2362 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2363 ":param expression: Optional search expression\n"
2364 ":param attrs: Attributes to return (defaults to all)\n"
2365 ":param controls: Optional list of controls\n"
2366 ":return: ldb.Result object\n"
2368 { "search_iterator", PY_DISCARD_FUNC_SIG(PyCFunction
,
2369 py_ldb_search_iterator
),
2370 METH_VARARGS
|METH_KEYWORDS
,
2371 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2372 "Search in a database.\n"
2374 ":param base: Optional base DN to search\n"
2375 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2376 ":param expression: Optional search expression\n"
2377 ":param attrs: Attributes to return (defaults to all)\n"
2378 ":param controls: Optional list of controls\n"
2379 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2380 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2382 { "schema_attribute_remove", (PyCFunction
)py_ldb_schema_attribute_remove
, METH_VARARGS
,
2384 { "schema_attribute_add", (PyCFunction
)py_ldb_schema_attribute_add
, METH_VARARGS
,
2386 { "schema_format_value", (PyCFunction
)py_ldb_schema_format_value
, METH_VARARGS
,
2388 { "parse_ldif", (PyCFunction
)py_ldb_parse_ldif
, METH_VARARGS
,
2389 "S.parse_ldif(ldif) -> iter(messages)\n"
2390 "Parse a string formatted using LDIF." },
2391 { "write_ldif", (PyCFunction
)py_ldb_write_ldif
, METH_VARARGS
,
2392 "S.write_ldif(message, changetype) -> ldif\n"
2393 "Print the message as a string formatted using LDIF." },
2394 { "msg_diff", (PyCFunction
)py_ldb_msg_diff
, METH_VARARGS
,
2395 "S.msg_diff(Message) -> Message\n"
2396 "Return an LDB Message of the difference between two Message objects." },
2397 { "get_opaque", (PyCFunction
)py_ldb_get_opaque
, METH_VARARGS
,
2398 "S.get_opaque(name) -> value\n"
2399 "Get an opaque value set on this LDB connection. \n"
2400 ":note: The returned value may not be useful in Python."
2402 { "set_opaque", (PyCFunction
)py_ldb_set_opaque
, METH_VARARGS
,
2403 "S.set_opaque(name, value) -> None\n"
2404 "Set an opaque value on this LDB connection. \n"
2405 ":note: Passing incorrect values may cause crashes." },
2406 { "modules", (PyCFunction
)py_ldb_modules
, METH_NOARGS
,
2407 "S.modules() -> list\n"
2408 "Return the list of modules on this LDB connection " },
2409 { "sequence_number", (PyCFunction
)py_ldb_sequence_number
, METH_VARARGS
,
2410 "S.sequence_number(type) -> value\n"
2411 "Return the value of the sequence according to the requested type" },
2412 { "_register_test_extensions", (PyCFunction
)py_ldb_register_test_extensions
, METH_NOARGS
,
2413 "S._register_test_extensions() -> None\n"
2414 "Register internal extensions used in testing" },
2418 static PyObject
*PyLdbModule_FromModule(struct ldb_module
*mod
)
2420 PyLdbModuleObject
*ret
;
2422 ret
= (PyLdbModuleObject
*)PyLdbModule
.tp_alloc(&PyLdbModule
, 0);
2427 ret
->mem_ctx
= talloc_new(NULL
);
2428 ret
->mod
= talloc_reference(ret
->mem_ctx
, mod
);
2429 return (PyObject
*)ret
;
2432 static PyObject
*py_ldb_get_firstmodule(PyLdbObject
*self
, void *closure
)
2434 struct ldb_module
*mod
= pyldb_Ldb_AS_LDBCONTEXT(self
)->modules
;
2438 return PyLdbModule_FromModule(mod
);
2441 static PyGetSetDef py_ldb_getset
[] = {
2443 .name
= discard_const_p(char, "firstmodule"),
2444 .get
= (getter
)py_ldb_get_firstmodule
,
2449 static int py_ldb_contains(PyLdbObject
*self
, PyObject
*obj
)
2451 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2453 struct ldb_result
*result
;
2457 if (!pyldb_Object_AsDn(ldb_ctx
, obj
, ldb_ctx
, &dn
)) {
2461 ret
= ldb_search(ldb_ctx
, ldb_ctx
, &result
, dn
, LDB_SCOPE_BASE
, NULL
,
2463 if (ret
!= LDB_SUCCESS
) {
2464 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2468 count
= result
->count
;
2470 talloc_free(result
);
2473 PyErr_Format(PyExc_RuntimeError
,
2474 "Searching for [%s] dn gave %u results!",
2475 ldb_dn_get_linearized(dn
),
2483 static PySequenceMethods py_ldb_seq
= {
2484 .sq_contains
= (objobjproc
)py_ldb_contains
,
2487 static PyObject
*PyLdb_FromLdbContext(struct ldb_context
*ldb_ctx
)
2491 ret
= (PyLdbObject
*)PyLdb
.tp_alloc(&PyLdb
, 0);
2496 ret
->mem_ctx
= talloc_new(NULL
);
2497 ret
->ldb_ctx
= talloc_reference(ret
->mem_ctx
, ldb_ctx
);
2498 return (PyObject
*)ret
;
2501 static void py_ldb_dealloc(PyLdbObject
*self
)
2503 talloc_free(self
->mem_ctx
);
2504 Py_TYPE(self
)->tp_free(self
);
2507 static PyTypeObject PyLdb
= {
2508 .tp_name
= "ldb.Ldb",
2509 .tp_methods
= py_ldb_methods
,
2510 .tp_repr
= (reprfunc
)py_ldb_repr
,
2511 .tp_new
= py_ldb_new
,
2512 .tp_init
= (initproc
)py_ldb_init
,
2513 .tp_dealloc
= (destructor
)py_ldb_dealloc
,
2514 .tp_getset
= py_ldb_getset
,
2515 .tp_getattro
= PyObject_GenericGetAttr
,
2516 .tp_basicsize
= sizeof(PyLdbObject
),
2517 .tp_doc
= "Connection to a LDB database.",
2518 .tp_as_sequence
= &py_ldb_seq
,
2519 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
2522 static void py_ldb_result_dealloc(PyLdbResultObject
*self
)
2524 talloc_free(self
->mem_ctx
);
2525 Py_DECREF(self
->msgs
);
2526 Py_DECREF(self
->referals
);
2527 Py_DECREF(self
->controls
);
2528 Py_TYPE(self
)->tp_free(self
);
2531 static PyObject
*py_ldb_result_get_msgs(PyLdbResultObject
*self
, void *closure
)
2533 Py_INCREF(self
->msgs
);
2537 static PyObject
*py_ldb_result_get_controls(PyLdbResultObject
*self
, void *closure
)
2539 Py_INCREF(self
->controls
);
2540 return self
->controls
;
2543 static PyObject
*py_ldb_result_get_referals(PyLdbResultObject
*self
, void *closure
)
2545 Py_INCREF(self
->referals
);
2546 return self
->referals
;
2549 static PyObject
*py_ldb_result_get_count(PyLdbResultObject
*self
, void *closure
)
2552 if (self
->msgs
== NULL
) {
2553 PyErr_SetString(PyExc_AttributeError
, "Count attribute is meaningless in this context");
2556 size
= PyList_Size(self
->msgs
);
2557 return PyLong_FromLong(size
);
2560 static PyGetSetDef py_ldb_result_getset
[] = {
2562 .name
= discard_const_p(char, "controls"),
2563 .get
= (getter
)py_ldb_result_get_controls
,
2566 .name
= discard_const_p(char, "msgs"),
2567 .get
= (getter
)py_ldb_result_get_msgs
,
2570 .name
= discard_const_p(char, "referals"),
2571 .get
= (getter
)py_ldb_result_get_referals
,
2574 .name
= discard_const_p(char, "count"),
2575 .get
= (getter
)py_ldb_result_get_count
,
2580 static PyObject
*py_ldb_result_iter(PyLdbResultObject
*self
)
2582 return PyObject_GetIter(self
->msgs
);
2585 static Py_ssize_t
py_ldb_result_len(PyLdbResultObject
*self
)
2587 return PySequence_Size(self
->msgs
);
2590 static PyObject
*py_ldb_result_find(PyLdbResultObject
*self
, Py_ssize_t idx
)
2592 return PySequence_GetItem(self
->msgs
, idx
);
2595 static PySequenceMethods py_ldb_result_seq
= {
2596 .sq_length
= (lenfunc
)py_ldb_result_len
,
2597 .sq_item
= (ssizeargfunc
)py_ldb_result_find
,
2600 static PyObject
*py_ldb_result_repr(PyLdbObject
*self
)
2602 return PyUnicode_FromString("<ldb result>");
2606 static PyTypeObject PyLdbResult
= {
2607 .tp_name
= "ldb.Result",
2608 .tp_repr
= (reprfunc
)py_ldb_result_repr
,
2609 .tp_dealloc
= (destructor
)py_ldb_result_dealloc
,
2610 .tp_iter
= (getiterfunc
)py_ldb_result_iter
,
2611 .tp_getset
= py_ldb_result_getset
,
2612 .tp_getattro
= PyObject_GenericGetAttr
,
2613 .tp_basicsize
= sizeof(PyLdbResultObject
),
2614 .tp_as_sequence
= &py_ldb_result_seq
,
2615 .tp_doc
= "LDB result.",
2616 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
2619 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject
*self
)
2621 Py_XDECREF(self
->state
.exception
);
2622 TALLOC_FREE(self
->mem_ctx
);
2623 ZERO_STRUCT(self
->state
);
2624 Py_DECREF(self
->ldb
);
2625 Py_TYPE(self
)->tp_free(self
);
2628 static PyObject
*py_ldb_search_iterator_next(PyLdbSearchIteratorObject
*self
)
2630 PyObject
*py_ret
= NULL
;
2632 if (self
->state
.req
== NULL
) {
2633 PyErr_SetString(PyExc_RuntimeError
,
2634 "ldb.SearchIterator request already finished");
2639 * TODO: do we want a non-blocking mode?
2640 * In future we may add an optional 'nonblocking'
2641 * argument to search_iterator().
2643 * For now we keep it simple and wait for at
2647 while (self
->state
.next
== NULL
) {
2650 if (self
->state
.result
!= NULL
) {
2652 * We (already) got a final result from the server.
2654 * We stop the iteration and let
2655 * py_ldb_search_iterator_result() will deliver
2656 * the result details.
2658 TALLOC_FREE(self
->state
.req
);
2659 PyErr_SetNone(PyExc_StopIteration
);
2663 ret
= ldb_wait(self
->state
.req
->handle
, LDB_WAIT_NONE
);
2664 if (ret
!= LDB_SUCCESS
) {
2665 struct ldb_context
*ldb_ctx
;
2666 TALLOC_FREE(self
->state
.req
);
2667 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
->ldb
);
2669 * We stop the iteration and let
2670 * py_ldb_search_iterator_result() will deliver
2673 self
->state
.exception
= Py_BuildValue(discard_const_p(char, "(i,s)"),
2674 ret
, ldb_errstring(ldb_ctx
));
2675 PyErr_SetNone(PyExc_StopIteration
);
2680 py_ret
= self
->state
.next
->obj
;
2681 self
->state
.next
->obj
= NULL
;
2682 /* no TALLOC_FREE() as self->state.next is a list */
2683 talloc_free(self
->state
.next
);
2687 static PyObject
*py_ldb_search_iterator_result(PyLdbSearchIteratorObject
*self
,
2688 PyObject
*Py_UNUSED(ignored
))
2690 PyObject
*py_ret
= NULL
;
2692 if (self
->state
.req
!= NULL
) {
2693 PyErr_SetString(PyExc_RuntimeError
,
2694 "ldb.SearchIterator request running");
2698 if (self
->state
.next
!= NULL
) {
2699 PyErr_SetString(PyExc_RuntimeError
,
2700 "ldb.SearchIterator not fully consumed.");
2704 if (self
->state
.exception
!= NULL
) {
2705 PyErr_SetObject(PyExc_LdbError
, self
->state
.exception
);
2706 self
->state
.exception
= NULL
;
2710 if (self
->state
.result
== NULL
) {
2711 PyErr_SetString(PyExc_RuntimeError
,
2712 "ldb.SearchIterator result already consumed");
2716 py_ret
= self
->state
.result
->obj
;
2717 self
->state
.result
->obj
= NULL
;
2718 TALLOC_FREE(self
->state
.result
);
2722 static PyObject
*py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject
*self
,
2723 PyObject
*Py_UNUSED(ignored
))
2725 if (self
->state
.req
== NULL
) {
2726 PyErr_SetString(PyExc_RuntimeError
,
2727 "ldb.SearchIterator request already finished");
2731 Py_XDECREF(self
->state
.exception
);
2732 TALLOC_FREE(self
->mem_ctx
);
2733 ZERO_STRUCT(self
->state
);
2737 static PyMethodDef py_ldb_search_iterator_methods
[] = {
2738 { "result", (PyCFunction
)py_ldb_search_iterator_result
, METH_NOARGS
,
2739 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2740 { "abandon", (PyCFunction
)py_ldb_search_iterator_abandon
, METH_NOARGS
,
2745 static PyObject
*py_ldb_search_iterator_repr(PyLdbSearchIteratorObject
*self
)
2747 return PyUnicode_FromString("<ldb search iterator>");
2750 static PyTypeObject PyLdbSearchIterator
= {
2751 .tp_name
= "ldb.SearchIterator",
2752 .tp_repr
= (reprfunc
)py_ldb_search_iterator_repr
,
2753 .tp_dealloc
= (destructor
)py_ldb_search_iterator_dealloc
,
2754 .tp_iter
= PyObject_SelfIter
,
2755 .tp_iternext
= (iternextfunc
)py_ldb_search_iterator_next
,
2756 .tp_methods
= py_ldb_search_iterator_methods
,
2757 .tp_basicsize
= sizeof(PyLdbSearchIteratorObject
),
2758 .tp_doc
= "LDB search_iterator.",
2759 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
2762 static PyObject
*py_ldb_module_repr(PyLdbModuleObject
*self
)
2764 return PyUnicode_FromFormat("<ldb module '%s'>",
2765 pyldb_Module_AsModule(self
)->ops
->name
);
2768 static PyObject
*py_ldb_module_str(PyLdbModuleObject
*self
)
2770 return PyUnicode_FromString(pyldb_Module_AsModule(self
)->ops
->name
);
2773 static PyObject
*py_ldb_module_start_transaction(PyLdbModuleObject
*self
,
2774 PyObject
*Py_UNUSED(ignored
))
2776 pyldb_Module_AsModule(self
)->ops
->start_transaction(pyldb_Module_AsModule(self
));
2780 static PyObject
*py_ldb_module_end_transaction(PyLdbModuleObject
*self
,
2781 PyObject
*Py_UNUSED(ignored
))
2783 pyldb_Module_AsModule(self
)->ops
->end_transaction(pyldb_Module_AsModule(self
));
2787 static PyObject
*py_ldb_module_del_transaction(PyLdbModuleObject
*self
,
2788 PyObject
*Py_UNUSED(ignored
))
2790 pyldb_Module_AsModule(self
)->ops
->del_transaction(pyldb_Module_AsModule(self
));
2794 static PyObject
*py_ldb_module_search(PyLdbModuleObject
*self
, PyObject
*args
, PyObject
*kwargs
)
2796 PyObject
*py_base
, *py_tree
, *py_attrs
, *py_ret
;
2798 struct ldb_request
*req
;
2799 const char * const kwnames
[] = { "base", "scope", "tree", "attrs", NULL
};
2800 struct ldb_module
*mod
;
2801 const char * const*attrs
;
2803 /* type "int" rather than "enum" for "scope" is intentional */
2804 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O!iOO",
2805 discard_const_p(char *, kwnames
),
2806 &PyLdbDn
, &py_base
, &scope
, &py_tree
, &py_attrs
))
2811 if (py_attrs
== Py_None
) {
2814 attrs
= PyList_AsStrList(NULL
, py_attrs
, "attrs");
2819 ret
= ldb_build_search_req(&req
, mod
->ldb
, NULL
, pyldb_Dn_AS_DN(py_base
),
2820 scope
, NULL
/* expr */, attrs
,
2821 NULL
/* controls */, NULL
, NULL
, NULL
);
2823 talloc_steal(req
, attrs
);
2825 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, mod
->ldb
);
2827 req
->op
.search
.res
= NULL
;
2829 ret
= mod
->ops
->search(mod
, req
);
2831 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, mod
->ldb
);
2833 py_ret
= PyLdbResult_FromResult(req
->op
.search
.res
);
2841 static PyObject
*py_ldb_module_add(PyLdbModuleObject
*self
, PyObject
*args
)
2843 struct ldb_request
*req
;
2844 PyObject
*py_message
;
2846 struct ldb_module
*mod
;
2848 if (!PyArg_ParseTuple(args
, "O!", &PyLdbMessage
, &py_message
))
2851 req
= talloc_zero(NULL
, struct ldb_request
);
2852 req
->operation
= LDB_ADD
;
2853 req
->op
.add
.message
= pyldb_Message_AsMessage(py_message
);
2855 mod
= pyldb_Module_AsModule(self
);
2856 ret
= mod
->ops
->add(mod
, req
);
2858 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, mod
->ldb
);
2863 static PyObject
*py_ldb_module_modify(PyLdbModuleObject
*self
, PyObject
*args
)
2866 struct ldb_request
*req
;
2867 PyObject
*py_message
;
2868 struct ldb_module
*mod
;
2870 if (!PyArg_ParseTuple(args
, "O!", &PyLdbMessage
, &py_message
))
2873 req
= talloc_zero(NULL
, struct ldb_request
);
2874 req
->operation
= LDB_MODIFY
;
2875 req
->op
.mod
.message
= pyldb_Message_AsMessage(py_message
);
2877 mod
= pyldb_Module_AsModule(self
);
2878 ret
= mod
->ops
->modify(mod
, req
);
2880 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, mod
->ldb
);
2885 static PyObject
*py_ldb_module_delete(PyLdbModuleObject
*self
, PyObject
*args
)
2888 struct ldb_request
*req
;
2891 if (!PyArg_ParseTuple(args
, "O!", &PyLdbDn
, &py_dn
))
2894 req
= talloc_zero(NULL
, struct ldb_request
);
2895 req
->operation
= LDB_DELETE
;
2896 req
->op
.del
.dn
= pyldb_Dn_AS_DN(py_dn
);
2898 ret
= pyldb_Module_AsModule(self
)->ops
->del(pyldb_Module_AsModule(self
), req
);
2900 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
2905 static PyObject
*py_ldb_module_rename(PyLdbModuleObject
*self
, PyObject
*args
)
2908 struct ldb_request
*req
;
2909 PyObject
*py_dn1
, *py_dn2
;
2911 if (!PyArg_ParseTuple(args
, "O!O!", &PyLdbDn
, &py_dn1
, &PyLdbDn
, &py_dn2
))
2914 req
= talloc_zero(NULL
, struct ldb_request
);
2916 req
->operation
= LDB_RENAME
;
2917 req
->op
.rename
.olddn
= pyldb_Dn_AS_DN(py_dn1
);
2918 req
->op
.rename
.newdn
= pyldb_Dn_AS_DN(py_dn2
);
2920 ret
= pyldb_Module_AsModule(self
)->ops
->rename(pyldb_Module_AsModule(self
), req
);
2922 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
2927 static PyMethodDef py_ldb_module_methods
[] = {
2928 { "search", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_module_search
),
2929 METH_VARARGS
|METH_KEYWORDS
, NULL
},
2930 { "add", (PyCFunction
)py_ldb_module_add
, METH_VARARGS
, NULL
},
2931 { "modify", (PyCFunction
)py_ldb_module_modify
, METH_VARARGS
, NULL
},
2932 { "rename", (PyCFunction
)py_ldb_module_rename
, METH_VARARGS
, NULL
},
2933 { "delete", (PyCFunction
)py_ldb_module_delete
, METH_VARARGS
, NULL
},
2934 { "start_transaction", (PyCFunction
)py_ldb_module_start_transaction
, METH_NOARGS
, NULL
},
2935 { "end_transaction", (PyCFunction
)py_ldb_module_end_transaction
, METH_NOARGS
, NULL
},
2936 { "del_transaction", (PyCFunction
)py_ldb_module_del_transaction
, METH_NOARGS
, NULL
},
2940 static void py_ldb_module_dealloc(PyLdbModuleObject
*self
)
2942 talloc_free(self
->mem_ctx
);
2946 static PyTypeObject PyLdbModule
= {
2947 .tp_name
= "ldb.LdbModule",
2948 .tp_methods
= py_ldb_module_methods
,
2949 .tp_repr
= (reprfunc
)py_ldb_module_repr
,
2950 .tp_str
= (reprfunc
)py_ldb_module_str
,
2951 .tp_basicsize
= sizeof(PyLdbModuleObject
),
2952 .tp_dealloc
= (destructor
)py_ldb_module_dealloc
,
2953 .tp_flags
= Py_TPFLAGS_DEFAULT
,
2954 .tp_doc
= "LDB module (extension)",
2959 * Create a ldb_message_element from a Python object.
2961 * This will accept any sequence objects that contains strings, or
2964 * A reference to set_obj will be borrowed.
2966 * @param mem_ctx Memory context
2967 * @param set_obj Python object to convert
2968 * @param flags ldb_message_element flags to set
2969 * @param attr_name Name of the attribute
2970 * @return New ldb_message_element, allocated as child of mem_ctx
2972 static struct ldb_message_element
*PyObject_AsMessageElement(
2973 TALLOC_CTX
*mem_ctx
,
2976 const char *attr_name
)
2978 struct ldb_message_element
*me
;
2979 const char *msg
= NULL
;
2983 if (pyldb_MessageElement_Check(set_obj
)) {
2984 PyLdbMessageElementObject
*set_obj_as_me
= (PyLdbMessageElementObject
*)set_obj
;
2985 /* We have to talloc_reference() the memory context, not the pointer
2986 * which may not actually be it's own context */
2987 if (talloc_reference(mem_ctx
, set_obj_as_me
->mem_ctx
)) {
2988 return pyldb_MessageElement_AsMessageElement(set_obj
);
2993 me
= talloc(mem_ctx
, struct ldb_message_element
);
2999 me
->name
= talloc_strdup(me
, attr_name
);
3001 if (PyBytes_Check(set_obj
) || PyUnicode_Check(set_obj
)) {
3003 me
->values
= talloc_array(me
, struct ldb_val
, me
->num_values
);
3004 if (PyBytes_Check(set_obj
)) {
3006 result
= PyBytes_AsStringAndSize(set_obj
, &_msg
, &size
);
3013 msg
= PyUnicode_AsUTF8AndSize(set_obj
, &size
);
3019 me
->values
[0].data
= talloc_memdup(me
,
3020 (const uint8_t *)msg
,
3022 me
->values
[0].length
= size
;
3023 } else if (PySequence_Check(set_obj
)) {
3025 me
->num_values
= PySequence_Size(set_obj
);
3026 me
->values
= talloc_array(me
, struct ldb_val
, me
->num_values
);
3027 for (i
= 0; i
< me
->num_values
; i
++) {
3028 PyObject
*obj
= PySequence_GetItem(set_obj
, i
);
3029 if (PyBytes_Check(obj
)) {
3031 result
= PyBytes_AsStringAndSize(obj
, &_msg
, &size
);
3037 } else if (PyUnicode_Check(obj
)) {
3038 msg
= PyUnicode_AsUTF8AndSize(obj
, &size
);
3044 PyErr_Format(PyExc_TypeError
,
3045 "Expected string as element %zd in list", i
);
3049 me
->values
[i
].data
= talloc_memdup(me
,
3050 (const uint8_t *)msg
,
3052 me
->values
[i
].length
= size
;
3055 PyErr_Format(PyExc_TypeError
,
3056 "String or List type expected for '%s' attribute", attr_name
);
3065 static PyObject
*ldb_msg_element_to_set(struct ldb_context
*ldb_ctx
,
3066 struct ldb_message_element
*me
)
3071 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
3072 result
= PyList_New(me
->num_values
);
3074 for (i
= 0; i
< me
->num_values
; i
++) {
3075 PyList_SetItem(result
, i
,
3076 PyObject_FromLdbValue(&me
->values
[i
]));
3082 static PyObject
*py_ldb_msg_element_get(PyLdbMessageElementObject
*self
, PyObject
*args
)
3085 if (!PyArg_ParseTuple(args
, "I", &i
))
3087 if (i
>= pyldb_MessageElement_AsMessageElement(self
)->num_values
)
3090 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self
)->values
[i
]));
3093 static PyObject
*py_ldb_msg_element_flags(PyLdbMessageElementObject
*self
, PyObject
*args
)
3095 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3096 return PyLong_FromLong(el
->flags
);
3099 static PyObject
*py_ldb_msg_element_set_flags(PyLdbMessageElementObject
*self
, PyObject
*args
)
3102 struct ldb_message_element
*el
;
3103 if (!PyArg_ParseTuple(args
, "I", &flags
))
3106 el
= pyldb_MessageElement_AsMessageElement(self
);
3111 static PyMethodDef py_ldb_msg_element_methods
[] = {
3112 { "get", (PyCFunction
)py_ldb_msg_element_get
, METH_VARARGS
, NULL
},
3113 { "set_flags", (PyCFunction
)py_ldb_msg_element_set_flags
, METH_VARARGS
, NULL
},
3114 { "flags", (PyCFunction
)py_ldb_msg_element_flags
, METH_NOARGS
, NULL
},
3118 static Py_ssize_t
py_ldb_msg_element_len(PyLdbMessageElementObject
*self
)
3120 return pyldb_MessageElement_AsMessageElement(self
)->num_values
;
3123 static PyObject
*py_ldb_msg_element_find(PyLdbMessageElementObject
*self
, Py_ssize_t idx
)
3125 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3126 if (idx
< 0 || idx
>= el
->num_values
) {
3127 PyErr_SetString(PyExc_IndexError
, "Out of range");
3130 return PyLdbBytes_FromStringAndSize((char *)el
->values
[idx
].data
, el
->values
[idx
].length
);
3133 static PySequenceMethods py_ldb_msg_element_seq
= {
3134 .sq_length
= (lenfunc
)py_ldb_msg_element_len
,
3135 .sq_item
= (ssizeargfunc
)py_ldb_msg_element_find
,
3138 static PyObject
*py_ldb_msg_element_richcmp(PyObject
*self
, PyObject
*other
, int op
)
3141 if (!pyldb_MessageElement_Check(other
)) {
3142 Py_INCREF(Py_NotImplemented
);
3143 return Py_NotImplemented
;
3145 ret
= ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self
),
3146 pyldb_MessageElement_AsMessageElement(other
));
3147 return richcmp(ret
, op
);
3150 static PyObject
*py_ldb_msg_element_iter(PyLdbMessageElementObject
*self
)
3152 PyObject
*el
= ldb_msg_element_to_set(NULL
,
3153 pyldb_MessageElement_AsMessageElement(self
));
3154 PyObject
*ret
= PyObject_GetIter(el
);
3159 static PyObject
*PyLdbMessageElement_FromMessageElement(struct ldb_message_element
*el
, TALLOC_CTX
*mem_ctx
)
3161 PyLdbMessageElementObject
*ret
;
3162 ret
= PyObject_New(PyLdbMessageElementObject
, &PyLdbMessageElement
);
3167 ret
->mem_ctx
= talloc_new(NULL
);
3168 if (talloc_reference(ret
->mem_ctx
, mem_ctx
) == NULL
) {
3173 return (PyObject
*)ret
;
3176 static PyObject
*py_ldb_msg_element_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
3178 PyObject
*py_elements
= NULL
;
3179 struct ldb_message_element
*el
;
3180 unsigned int flags
= 0;
3182 const char * const kwnames
[] = { "elements", "flags", "name", NULL
};
3183 PyLdbMessageElementObject
*ret
;
3184 TALLOC_CTX
*mem_ctx
;
3185 const char *msg
= NULL
;
3189 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OIs",
3190 discard_const_p(char *, kwnames
),
3191 &py_elements
, &flags
, &name
))
3194 mem_ctx
= talloc_new(NULL
);
3195 if (mem_ctx
== NULL
) {
3200 el
= talloc_zero(mem_ctx
, struct ldb_message_element
);
3203 talloc_free(mem_ctx
);
3207 if (py_elements
!= NULL
) {
3209 if (PyBytes_Check(py_elements
) || PyUnicode_Check(py_elements
)) {
3212 el
->values
= talloc_array(el
, struct ldb_val
, 1);
3213 if (el
->values
== NULL
) {
3214 talloc_free(mem_ctx
);
3218 if (PyBytes_Check(py_elements
)) {
3219 result
= PyBytes_AsStringAndSize(py_elements
, &_msg
, &size
);
3222 msg
= PyUnicode_AsUTF8AndSize(py_elements
, &size
);
3223 result
= (msg
== NULL
) ? -1 : 0;
3226 talloc_free(mem_ctx
);
3229 el
->values
[0].data
= talloc_memdup(el
->values
,
3230 (const uint8_t *)msg
, size
+ 1);
3231 el
->values
[0].length
= size
;
3232 } else if (PySequence_Check(py_elements
)) {
3233 el
->num_values
= PySequence_Size(py_elements
);
3234 el
->values
= talloc_array(el
, struct ldb_val
, el
->num_values
);
3235 if (el
->values
== NULL
) {
3236 talloc_free(mem_ctx
);
3240 for (i
= 0; i
< el
->num_values
; i
++) {
3241 PyObject
*item
= PySequence_GetItem(py_elements
, i
);
3243 talloc_free(mem_ctx
);
3246 if (PyBytes_Check(item
)) {
3248 result
= PyBytes_AsStringAndSize(item
, &_msg
, &size
);
3250 } else if (PyUnicode_Check(item
)) {
3251 msg
= PyUnicode_AsUTF8AndSize(item
, &size
);
3252 result
= (msg
== NULL
) ? -1 : 0;
3254 PyErr_Format(PyExc_TypeError
,
3255 "Expected string as element %zd in list", i
);
3259 talloc_free(mem_ctx
);
3262 el
->values
[i
].data
= talloc_memdup(el
,
3263 (const uint8_t *)msg
, size
+1);
3264 el
->values
[i
].length
= size
;
3267 PyErr_SetString(PyExc_TypeError
,
3268 "Expected string or list");
3269 talloc_free(mem_ctx
);
3275 el
->name
= talloc_strdup(el
, name
);
3277 ret
= PyObject_New(PyLdbMessageElementObject
, type
);
3279 talloc_free(mem_ctx
);
3283 ret
->mem_ctx
= mem_ctx
;
3285 return (PyObject
*)ret
;
3288 static PyObject
*py_ldb_msg_element_repr(PyLdbMessageElementObject
*self
)
3290 char *element_str
= NULL
;
3292 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3293 PyObject
*ret
, *repr
;
3295 for (i
= 0; i
< el
->num_values
; i
++) {
3296 PyObject
*o
= py_ldb_msg_element_find(self
, i
);
3297 repr
= PyObject_Repr(o
);
3298 if (element_str
== NULL
)
3299 element_str
= talloc_strdup(NULL
, PyUnicode_AsUTF8(repr
));
3301 element_str
= talloc_asprintf_append(element_str
, ",%s", PyUnicode_AsUTF8(repr
));
3305 if (element_str
!= NULL
) {
3306 ret
= PyUnicode_FromFormat("MessageElement([%s])", element_str
);
3307 talloc_free(element_str
);
3309 ret
= PyUnicode_FromString("MessageElement([])");
3315 static PyObject
*py_ldb_msg_element_str(PyLdbMessageElementObject
*self
)
3317 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3319 if (el
->num_values
== 1)
3320 return PyUnicode_FromStringAndSize((char *)el
->values
[0].data
, el
->values
[0].length
);
3325 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject
*self
)
3327 talloc_free(self
->mem_ctx
);
3331 static PyObject
*py_ldb_msg_element_get_text(PyObject
*self
, void *closure
)
3333 return wrap_text("MessageElementTextWrapper", self
);
3336 static PyGetSetDef py_ldb_msg_element_getset
[] = {
3338 .name
= discard_const_p(char, "text"),
3339 .get
= (getter
)py_ldb_msg_element_get_text
,
3344 static PyTypeObject PyLdbMessageElement
= {
3345 .tp_name
= "ldb.MessageElement",
3346 .tp_basicsize
= sizeof(PyLdbMessageElementObject
),
3347 .tp_dealloc
= (destructor
)py_ldb_msg_element_dealloc
,
3348 .tp_repr
= (reprfunc
)py_ldb_msg_element_repr
,
3349 .tp_str
= (reprfunc
)py_ldb_msg_element_str
,
3350 .tp_methods
= py_ldb_msg_element_methods
,
3351 .tp_getset
= py_ldb_msg_element_getset
,
3352 .tp_richcompare
= (richcmpfunc
)py_ldb_msg_element_richcmp
,
3353 .tp_iter
= (getiterfunc
)py_ldb_msg_element_iter
,
3354 .tp_as_sequence
= &py_ldb_msg_element_seq
,
3355 .tp_new
= py_ldb_msg_element_new
,
3356 .tp_flags
= Py_TPFLAGS_DEFAULT
,
3357 .tp_doc
= "An element of a Message",
3361 static PyObject
*py_ldb_msg_from_dict(PyTypeObject
*type
, PyObject
*args
)
3366 struct ldb_message
*msg
;
3367 struct ldb_context
*ldb_ctx
;
3368 unsigned int mod_flags
= LDB_FLAG_MOD_REPLACE
;
3370 if (!PyArg_ParseTuple(args
, "O!O!|I",
3371 &PyLdb
, &py_ldb
, &PyDict_Type
, &py_dict
,
3376 if (!PyLdb_Check(py_ldb
)) {
3377 PyErr_SetString(PyExc_TypeError
, "Expected Ldb");
3381 /* mask only flags we are going to use */
3382 mod_flags
= LDB_FLAG_MOD_TYPE(mod_flags
);
3384 PyErr_SetString(PyExc_ValueError
,
3385 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3386 " expected as mod_flag value");
3390 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(py_ldb
);
3392 msg
= PyDict_AsMessage(ldb_ctx
, py_dict
, ldb_ctx
, mod_flags
);
3397 py_ret
= PyLdbMessage_FromMessage(msg
);
3399 talloc_unlink(ldb_ctx
, msg
);
3404 static PyObject
*py_ldb_msg_remove_attr(PyLdbMessageObject
*self
, PyObject
*args
)
3407 if (!PyArg_ParseTuple(args
, "s", &name
))
3410 ldb_msg_remove_attr(self
->msg
, name
);
3415 static PyObject
*py_ldb_msg_keys(PyLdbMessageObject
*self
,
3416 PyObject
*Py_UNUSED(ignored
))
3418 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3419 Py_ssize_t i
, j
= 0;
3420 PyObject
*obj
= PyList_New(msg
->num_elements
+(msg
->dn
!= NULL
?1:0));
3421 if (msg
->dn
!= NULL
) {
3422 PyList_SetItem(obj
, j
, PyUnicode_FromString("dn"));
3425 for (i
= 0; i
< msg
->num_elements
; i
++) {
3426 PyList_SetItem(obj
, j
, PyUnicode_FromString(msg
->elements
[i
].name
));
3432 static PyObject
*py_ldb_msg_getitem_helper(PyLdbMessageObject
*self
, PyObject
*py_name
)
3434 struct ldb_message_element
*el
;
3436 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3437 name
= PyUnicode_AsUTF8(py_name
);
3439 PyErr_SetNone(PyExc_TypeError
);
3442 if (!ldb_attr_cmp(name
, "dn"))
3443 return pyldb_Dn_FromDn(msg
->dn
);
3444 el
= ldb_msg_find_element(msg
, name
);
3448 return (PyObject
*)PyLdbMessageElement_FromMessageElement(el
, msg
->elements
);
3451 static PyObject
*py_ldb_msg_getitem(PyLdbMessageObject
*self
, PyObject
*py_name
)
3453 PyObject
*ret
= py_ldb_msg_getitem_helper(self
, py_name
);
3455 PyErr_SetString(PyExc_KeyError
, "No such element");
3461 static PyObject
*py_ldb_msg_get(PyLdbMessageObject
*self
, PyObject
*args
, PyObject
*kwargs
)
3463 PyObject
*def
= NULL
;
3464 const char *kwnames
[] = { "name", "default", "idx", NULL
};
3465 const char *name
= NULL
;
3467 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3468 struct ldb_message_element
*el
;
3470 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|Oi:msg",
3471 discard_const_p(char *, kwnames
), &name
, &def
, &idx
)) {
3475 if (strcasecmp(name
, "dn") == 0) {
3476 return pyldb_Dn_FromDn(msg
->dn
);
3479 el
= ldb_msg_find_element(msg
, name
);
3481 if (el
== NULL
|| (idx
!= -1 && el
->num_values
<= idx
)) {
3490 return (PyObject
*)PyLdbMessageElement_FromMessageElement(el
, msg
->elements
);
3493 return PyObject_FromLdbValue(&el
->values
[idx
]);
3496 static PyObject
*py_ldb_msg_items(PyLdbMessageObject
*self
,
3497 PyObject
*Py_UNUSED(ignored
))
3499 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3500 Py_ssize_t i
, j
= 0;
3501 PyObject
*l
= PyList_New(msg
->num_elements
+ (msg
->dn
== NULL
?0:1));
3503 return PyErr_NoMemory();
3505 if (msg
->dn
!= NULL
) {
3506 PyObject
*value
= NULL
;
3507 PyObject
*obj
= pyldb_Dn_FromDn(msg
->dn
);
3509 value
= Py_BuildValue("(sO)", "dn", obj
);
3511 if (value
== NULL
) {
3515 res
= PyList_SetItem(l
, 0, value
);
3522 for (i
= 0; i
< msg
->num_elements
; i
++, j
++) {
3523 PyObject
*value
= NULL
;
3524 PyObject
*py_el
= PyLdbMessageElement_FromMessageElement(&msg
->elements
[i
], msg
->elements
);
3527 value
= Py_BuildValue("(sO)", msg
->elements
[i
].name
, py_el
);
3528 if (value
== NULL
) {
3532 res
= PyList_SetItem(l
, 0, value
);
3541 static PyObject
*py_ldb_msg_elements(PyLdbMessageObject
*self
,
3542 PyObject
*Py_UNUSED(ignored
))
3544 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3546 PyObject
*l
= PyList_New(msg
->num_elements
);
3547 for (i
= 0; i
< msg
->num_elements
; i
++) {
3548 PyList_SetItem(l
, i
, PyLdbMessageElement_FromMessageElement(&msg
->elements
[i
], msg
->elements
));
3553 static PyObject
*py_ldb_msg_add(PyLdbMessageObject
*self
, PyObject
*args
)
3555 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3556 PyLdbMessageElementObject
*py_element
;
3558 struct ldb_message_element
*el
;
3559 struct ldb_message_element
*el_new
;
3561 if (!PyArg_ParseTuple(args
, "O!", &PyLdbMessageElement
, &py_element
))
3564 el
= py_element
->el
;
3566 PyErr_SetString(PyExc_ValueError
, "Invalid MessageElement object");
3569 if (el
->name
== NULL
) {
3570 PyErr_SetString(PyExc_ValueError
,
3571 "The element has no name");
3574 ret
= ldb_msg_add_empty(msg
, el
->name
, el
->flags
, &el_new
);
3575 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
3577 /* now deep copy all attribute values */
3578 el_new
->values
= talloc_array(msg
->elements
, struct ldb_val
, el
->num_values
);
3579 if (el_new
->values
== NULL
) {
3583 el_new
->num_values
= el
->num_values
;
3585 for (i
= 0; i
< el
->num_values
; i
++) {
3586 el_new
->values
[i
] = ldb_val_dup(el_new
->values
, &el
->values
[i
]);
3587 if (el_new
->values
[i
].data
== NULL
3588 && el
->values
[i
].length
!= 0) {
3597 static PyMethodDef py_ldb_msg_methods
[] = {
3598 { "from_dict", (PyCFunction
)py_ldb_msg_from_dict
, METH_CLASS
| METH_VARARGS
,
3599 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
3600 "Class method to create ldb.Message object from Dictionary.\n"
3601 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3602 { "keys", (PyCFunction
)py_ldb_msg_keys
, METH_NOARGS
,
3603 "S.keys() -> list\n\n"
3604 "Return sequence of all attribute names." },
3605 { "remove", (PyCFunction
)py_ldb_msg_remove_attr
, METH_VARARGS
,
3606 "S.remove(name)\n\n"
3607 "Remove all entries for attributes with the specified name."},
3608 { "get", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_msg_get
),
3609 METH_VARARGS
| METH_KEYWORDS
,
3610 "msg.get(name,default=None,idx=None) -> string\n"
3611 "idx is the index into the values array\n"
3612 "if idx is None, then a list is returned\n"
3613 "if idx is not None, then the element with that index is returned\n"
3614 "if you pass the special name 'dn' then the DN object is returned\n"},
3615 { "items", (PyCFunction
)py_ldb_msg_items
, METH_NOARGS
, NULL
},
3616 { "elements", (PyCFunction
)py_ldb_msg_elements
, METH_NOARGS
, NULL
},
3617 { "add", (PyCFunction
)py_ldb_msg_add
, METH_VARARGS
,
3618 "S.add(element)\n\n"
3619 "Add an element to this message." },
3623 static PyObject
*py_ldb_msg_iter(PyLdbMessageObject
*self
)
3625 PyObject
*list
, *iter
;
3627 list
= py_ldb_msg_keys(self
, NULL
);
3628 iter
= PyObject_GetIter(list
);
3633 static int py_ldb_msg_setitem(PyLdbMessageObject
*self
, PyObject
*name
, PyObject
*value
)
3635 const char *attr_name
;
3637 attr_name
= PyUnicode_AsUTF8(name
);
3638 if (attr_name
== NULL
) {
3639 PyErr_SetNone(PyExc_TypeError
);
3643 if (value
== NULL
) {
3645 ldb_msg_remove_attr(self
->msg
, attr_name
);
3648 struct ldb_message_element
*el
= PyObject_AsMessageElement(self
->msg
,
3649 value
, 0, attr_name
);
3653 ldb_msg_remove_attr(pyldb_Message_AsMessage(self
), attr_name
);
3654 ret
= ldb_msg_add(pyldb_Message_AsMessage(self
), el
, el
->flags
);
3655 if (ret
!= LDB_SUCCESS
) {
3656 PyErr_SetLdbError(PyExc_LdbError
, ret
, NULL
);
3663 static Py_ssize_t
py_ldb_msg_length(PyLdbMessageObject
*self
)
3665 return pyldb_Message_AsMessage(self
)->num_elements
;
3668 static PyMappingMethods py_ldb_msg_mapping
= {
3669 .mp_length
= (lenfunc
)py_ldb_msg_length
,
3670 .mp_subscript
= (binaryfunc
)py_ldb_msg_getitem
,
3671 .mp_ass_subscript
= (objobjargproc
)py_ldb_msg_setitem
,
3674 static PyObject
*py_ldb_msg_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
3676 const char * const kwnames
[] = { "dn", NULL
};
3677 struct ldb_message
*ret
;
3678 TALLOC_CTX
*mem_ctx
;
3679 PyObject
*pydn
= NULL
;
3680 PyLdbMessageObject
*py_ret
;
3682 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|O",
3683 discard_const_p(char *, kwnames
),
3687 mem_ctx
= talloc_new(NULL
);
3688 if (mem_ctx
== NULL
) {
3693 ret
= ldb_msg_new(mem_ctx
);
3695 talloc_free(mem_ctx
);
3702 if (!pyldb_Object_AsDn(NULL
, pydn
, NULL
, &dn
)) {
3703 talloc_free(mem_ctx
);
3706 ret
->dn
= talloc_reference(ret
, dn
);
3709 py_ret
= (PyLdbMessageObject
*)type
->tp_alloc(type
, 0);
3710 if (py_ret
== NULL
) {
3712 talloc_free(mem_ctx
);
3716 py_ret
->mem_ctx
= mem_ctx
;
3718 return (PyObject
*)py_ret
;
3721 static PyObject
*PyLdbMessage_FromMessage(struct ldb_message
*msg
)
3723 PyLdbMessageObject
*ret
;
3725 ret
= (PyLdbMessageObject
*)PyLdbMessage
.tp_alloc(&PyLdbMessage
, 0);
3730 ret
->mem_ctx
= talloc_new(NULL
);
3731 ret
->msg
= talloc_reference(ret
->mem_ctx
, msg
);
3732 return (PyObject
*)ret
;
3735 static PyObject
*py_ldb_msg_get_dn(PyLdbMessageObject
*self
, void *closure
)
3737 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3738 return pyldb_Dn_FromDn(msg
->dn
);
3741 static int py_ldb_msg_set_dn(PyLdbMessageObject
*self
, PyObject
*value
, void *closure
)
3743 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3744 if (value
== NULL
) {
3745 PyErr_SetString(PyExc_AttributeError
, "cannot delete dn");
3748 if (!pyldb_Dn_Check(value
)) {
3749 PyErr_SetString(PyExc_TypeError
, "expected dn");
3753 msg
->dn
= talloc_reference(msg
, pyldb_Dn_AS_DN(value
));
3757 static PyObject
*py_ldb_msg_get_text(PyObject
*self
, void *closure
)
3759 return wrap_text("MessageTextWrapper", self
);
3762 static PyGetSetDef py_ldb_msg_getset
[] = {
3764 .name
= discard_const_p(char, "dn"),
3765 .get
= (getter
)py_ldb_msg_get_dn
,
3766 .set
= (setter
)py_ldb_msg_set_dn
,
3769 .name
= discard_const_p(char, "text"),
3770 .get
= (getter
)py_ldb_msg_get_text
,
3775 static PyObject
*py_ldb_msg_repr(PyLdbMessageObject
*self
)
3777 PyObject
*dict
= PyDict_New(), *ret
, *repr
;
3778 if (PyDict_Update(dict
, (PyObject
*)self
) != 0)
3780 repr
= PyObject_Repr(dict
);
3785 ret
= PyUnicode_FromFormat("Message(%s)", PyUnicode_AsUTF8(repr
));
3791 static void py_ldb_msg_dealloc(PyLdbMessageObject
*self
)
3793 talloc_free(self
->mem_ctx
);
3797 static PyObject
*py_ldb_msg_richcmp(PyLdbMessageObject
*py_msg1
,
3798 PyLdbMessageObject
*py_msg2
, int op
)
3800 struct ldb_message
*msg1
, *msg2
;
3804 if (!PyLdbMessage_Check(py_msg2
)) {
3805 Py_INCREF(Py_NotImplemented
);
3806 return Py_NotImplemented
;
3809 msg1
= pyldb_Message_AsMessage(py_msg1
),
3810 msg2
= pyldb_Message_AsMessage(py_msg2
);
3812 if ((msg1
->dn
!= NULL
) || (msg2
->dn
!= NULL
)) {
3813 ret
= ldb_dn_compare(msg1
->dn
, msg2
->dn
);
3815 return richcmp(ret
, op
);
3819 ret
= msg1
->num_elements
- msg2
->num_elements
;
3821 return richcmp(ret
, op
);
3824 for (i
= 0; i
< msg1
->num_elements
; i
++) {
3825 ret
= ldb_msg_element_compare_name(&msg1
->elements
[i
],
3826 &msg2
->elements
[i
]);
3828 return richcmp(ret
, op
);
3831 ret
= ldb_msg_element_compare(&msg1
->elements
[i
],
3832 &msg2
->elements
[i
]);
3834 return richcmp(ret
, op
);
3838 return richcmp(0, op
);
3841 static PyTypeObject PyLdbMessage
= {
3842 .tp_name
= "ldb.Message",
3843 .tp_methods
= py_ldb_msg_methods
,
3844 .tp_getset
= py_ldb_msg_getset
,
3845 .tp_as_mapping
= &py_ldb_msg_mapping
,
3846 .tp_basicsize
= sizeof(PyLdbMessageObject
),
3847 .tp_dealloc
= (destructor
)py_ldb_msg_dealloc
,
3848 .tp_new
= py_ldb_msg_new
,
3849 .tp_repr
= (reprfunc
)py_ldb_msg_repr
,
3850 .tp_flags
= Py_TPFLAGS_DEFAULT
,
3851 .tp_iter
= (getiterfunc
)py_ldb_msg_iter
,
3852 .tp_richcompare
= (richcmpfunc
)py_ldb_msg_richcmp
,
3853 .tp_doc
= "A LDB Message",
3856 static PyObject
*PyLdbTree_FromTree(struct ldb_parse_tree
*tree
)
3858 PyLdbTreeObject
*ret
;
3860 ret
= (PyLdbTreeObject
*)PyLdbTree
.tp_alloc(&PyLdbTree
, 0);
3866 ret
->mem_ctx
= talloc_new(NULL
);
3867 ret
->tree
= talloc_reference(ret
->mem_ctx
, tree
);
3868 return (PyObject
*)ret
;
3871 static void py_ldb_tree_dealloc(PyLdbTreeObject
*self
)
3873 talloc_free(self
->mem_ctx
);
3877 static PyTypeObject PyLdbTree
= {
3878 .tp_name
= "ldb.Tree",
3879 .tp_basicsize
= sizeof(PyLdbTreeObject
),
3880 .tp_dealloc
= (destructor
)py_ldb_tree_dealloc
,
3881 .tp_flags
= Py_TPFLAGS_DEFAULT
,
3882 .tp_doc
= "A search tree",
3886 static int py_module_search(struct ldb_module
*mod
, struct ldb_request
*req
)
3888 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3889 PyObject
*py_result
, *py_base
, *py_attrs
, *py_tree
;
3891 py_base
= pyldb_Dn_FromDn(req
->op
.search
.base
);
3893 if (py_base
== NULL
)
3894 return LDB_ERR_OPERATIONS_ERROR
;
3896 py_tree
= PyLdbTree_FromTree(req
->op
.search
.tree
);
3898 if (py_tree
== NULL
)
3899 return LDB_ERR_OPERATIONS_ERROR
;
3901 if (req
->op
.search
.attrs
== NULL
) {
3905 for (len
= 0; req
->op
.search
.attrs
[len
]; len
++);
3906 py_attrs
= PyList_New(len
);
3907 for (i
= 0; i
< len
; i
++)
3908 PyList_SetItem(py_attrs
, i
, PyUnicode_FromString(req
->op
.search
.attrs
[i
]));
3911 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "search"),
3912 discard_const_p(char, "OiOO"),
3913 py_base
, req
->op
.search
.scope
, py_tree
, py_attrs
);
3915 Py_DECREF(py_attrs
);
3919 if (py_result
== NULL
) {
3920 return LDB_ERR_PYTHON_EXCEPTION
;
3923 req
->op
.search
.res
= PyLdbResult_AsResult(NULL
, py_result
);
3924 if (req
->op
.search
.res
== NULL
) {
3925 return LDB_ERR_PYTHON_EXCEPTION
;
3928 Py_DECREF(py_result
);
3933 static int py_module_add(struct ldb_module
*mod
, struct ldb_request
*req
)
3935 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3936 PyObject
*py_result
, *py_msg
;
3938 py_msg
= PyLdbMessage_FromMessage(discard_const_p(struct ldb_message
, req
->op
.add
.message
));
3940 if (py_msg
== NULL
) {
3941 return LDB_ERR_OPERATIONS_ERROR
;
3944 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "add"),
3945 discard_const_p(char, "O"),
3950 if (py_result
== NULL
) {
3951 return LDB_ERR_PYTHON_EXCEPTION
;
3954 Py_DECREF(py_result
);
3959 static int py_module_modify(struct ldb_module
*mod
, struct ldb_request
*req
)
3961 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3962 PyObject
*py_result
, *py_msg
;
3964 py_msg
= PyLdbMessage_FromMessage(discard_const_p(struct ldb_message
, req
->op
.mod
.message
));
3966 if (py_msg
== NULL
) {
3967 return LDB_ERR_OPERATIONS_ERROR
;
3970 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "modify"),
3971 discard_const_p(char, "O"),
3976 if (py_result
== NULL
) {
3977 return LDB_ERR_PYTHON_EXCEPTION
;
3980 Py_DECREF(py_result
);
3985 static int py_module_del(struct ldb_module
*mod
, struct ldb_request
*req
)
3987 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3988 PyObject
*py_result
, *py_dn
;
3990 py_dn
= pyldb_Dn_FromDn(req
->op
.del
.dn
);
3993 return LDB_ERR_OPERATIONS_ERROR
;
3995 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "delete"),
3996 discard_const_p(char, "O"),
3999 if (py_result
== NULL
) {
4000 return LDB_ERR_PYTHON_EXCEPTION
;
4003 Py_DECREF(py_result
);
4008 static int py_module_rename(struct ldb_module
*mod
, struct ldb_request
*req
)
4010 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4011 PyObject
*py_result
, *py_olddn
, *py_newdn
;
4013 py_olddn
= pyldb_Dn_FromDn(req
->op
.rename
.olddn
);
4015 if (py_olddn
== NULL
)
4016 return LDB_ERR_OPERATIONS_ERROR
;
4018 py_newdn
= pyldb_Dn_FromDn(req
->op
.rename
.newdn
);
4020 if (py_newdn
== NULL
)
4021 return LDB_ERR_OPERATIONS_ERROR
;
4023 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "rename"),
4024 discard_const_p(char, "OO"),
4025 py_olddn
, py_newdn
);
4027 Py_DECREF(py_olddn
);
4028 Py_DECREF(py_newdn
);
4030 if (py_result
== NULL
) {
4031 return LDB_ERR_PYTHON_EXCEPTION
;
4034 Py_DECREF(py_result
);
4039 static int py_module_request(struct ldb_module
*mod
, struct ldb_request
*req
)
4041 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4042 PyObject
*py_result
;
4044 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "request"),
4045 discard_const_p(char, ""));
4047 Py_XDECREF(py_result
);
4049 return LDB_ERR_OPERATIONS_ERROR
;
4052 static int py_module_extended(struct ldb_module
*mod
, struct ldb_request
*req
)
4054 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4055 PyObject
*py_result
;
4057 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "extended"),
4058 discard_const_p(char, ""));
4060 Py_XDECREF(py_result
);
4062 return LDB_ERR_OPERATIONS_ERROR
;
4065 static int py_module_start_transaction(struct ldb_module
*mod
)
4067 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4068 PyObject
*py_result
;
4070 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "start_transaction"),
4071 discard_const_p(char, ""));
4073 if (py_result
== NULL
) {
4074 return LDB_ERR_PYTHON_EXCEPTION
;
4077 Py_DECREF(py_result
);
4082 static int py_module_end_transaction(struct ldb_module
*mod
)
4084 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4085 PyObject
*py_result
;
4087 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "end_transaction"),
4088 discard_const_p(char, ""));
4090 if (py_result
== NULL
) {
4091 return LDB_ERR_PYTHON_EXCEPTION
;
4094 Py_DECREF(py_result
);
4099 static int py_module_del_transaction(struct ldb_module
*mod
)
4101 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
4102 PyObject
*py_result
;
4104 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "del_transaction"),
4105 discard_const_p(char, ""));
4107 if (py_result
== NULL
) {
4108 return LDB_ERR_PYTHON_EXCEPTION
;
4111 Py_DECREF(py_result
);
4116 static int py_module_destructor(struct ldb_module
*mod
)
4118 Py_DECREF((PyObject
*)mod
->private_data
);
4122 static int py_module_init(struct ldb_module
*mod
)
4124 PyObject
*py_class
= (PyObject
*)mod
->ops
->private_data
;
4125 PyObject
*py_result
, *py_next
, *py_ldb
;
4127 py_ldb
= PyLdb_FromLdbContext(mod
->ldb
);
4130 return LDB_ERR_OPERATIONS_ERROR
;
4132 py_next
= PyLdbModule_FromModule(mod
->next
);
4134 if (py_next
== NULL
)
4135 return LDB_ERR_OPERATIONS_ERROR
;
4137 py_result
= PyObject_CallFunction(py_class
, discard_const_p(char, "OO"),
4140 if (py_result
== NULL
) {
4141 return LDB_ERR_PYTHON_EXCEPTION
;
4144 mod
->private_data
= py_result
;
4146 talloc_set_destructor(mod
, py_module_destructor
);
4148 return ldb_next_init(mod
);
4151 static PyObject
*py_register_module(PyObject
*module
, PyObject
*args
)
4154 struct ldb_module_ops
*ops
;
4156 PyObject
*tmp
= NULL
;
4157 const char *name
= NULL
;
4159 if (!PyArg_ParseTuple(args
, "O", &input
))
4162 ops
= talloc_zero(NULL
, struct ldb_module_ops
);
4168 tmp
= PyObject_GetAttrString(input
, discard_const_p(char, "name"));
4172 name
= PyUnicode_AsUTF8(tmp
);
4179 ops
->name
= talloc_strdup(ops
, name
);
4180 ops
->private_data
= input
;
4181 ops
->init_context
= py_module_init
;
4182 ops
->search
= py_module_search
;
4183 ops
->add
= py_module_add
;
4184 ops
->modify
= py_module_modify
;
4185 ops
->del
= py_module_del
;
4186 ops
->rename
= py_module_rename
;
4187 ops
->request
= py_module_request
;
4188 ops
->extended
= py_module_extended
;
4189 ops
->start_transaction
= py_module_start_transaction
;
4190 ops
->end_transaction
= py_module_end_transaction
;
4191 ops
->del_transaction
= py_module_del_transaction
;
4193 ret
= ldb_register_module(ops
);
4194 if (ret
!= LDB_SUCCESS
) {
4198 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
4203 static PyObject
*py_timestring(PyObject
*module
, PyObject
*args
)
4205 /* most times "time_t" is a signed integer type with 32 or 64 bit:
4206 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4210 if (!PyArg_ParseTuple(args
, "l", &t_val
))
4212 tresult
= ldb_timestring(NULL
, (time_t) t_val
);
4213 ret
= PyUnicode_FromString(tresult
);
4214 talloc_free(tresult
);
4218 static PyObject
*py_string_to_time(PyObject
*module
, PyObject
*args
)
4221 if (!PyArg_ParseTuple(args
, "s", &str
))
4224 return PyLong_FromLong(ldb_string_to_time(str
));
4227 static PyObject
*py_valid_attr_name(PyObject
*self
, PyObject
*args
)
4230 if (!PyArg_ParseTuple(args
, "s", &name
))
4232 return PyBool_FromLong(ldb_valid_attr_name(name
));
4236 encode a string using RFC2254 rules
4238 static PyObject
*py_binary_encode(PyObject
*self
, PyObject
*args
)
4240 char *str
, *encoded
;
4241 Py_ssize_t size
= 0;
4245 if (!PyArg_ParseTuple(args
, "s#", &str
, &size
))
4247 val
.data
= (uint8_t *)str
;
4250 encoded
= ldb_binary_encode(NULL
, val
);
4251 if (encoded
== NULL
) {
4252 PyErr_SetString(PyExc_TypeError
, "unable to encode binary string");
4255 ret
= PyUnicode_FromString(encoded
);
4256 talloc_free(encoded
);
4261 decode a string using RFC2254 rules
4263 static PyObject
*py_binary_decode(PyObject
*self
, PyObject
*args
)
4269 if (!PyArg_ParseTuple(args
, "s", &str
))
4272 val
= ldb_binary_decode(NULL
, str
);
4273 if (val
.data
== NULL
) {
4274 PyErr_SetString(PyExc_TypeError
, "unable to decode binary string");
4277 ret
= PyBytes_FromStringAndSize((const char*)val
.data
, val
.length
);
4278 talloc_free(val
.data
);
4282 static PyMethodDef py_ldb_global_methods
[] = {
4283 { "register_module", py_register_module
, METH_VARARGS
,
4284 "S.register_module(module) -> None\n\n"
4285 "Register a LDB module."},
4286 { "timestring", py_timestring
, METH_VARARGS
,
4287 "S.timestring(int) -> string\n\n"
4288 "Generate a LDAP time string from a UNIX timestamp" },
4289 { "string_to_time", py_string_to_time
, METH_VARARGS
,
4290 "S.string_to_time(string) -> int\n\n"
4291 "Parse a LDAP time string into a UNIX timestamp." },
4292 { "valid_attr_name", py_valid_attr_name
, METH_VARARGS
,
4293 "S.valid_attr_name(name) -> bool\n\nn"
4294 "Check whether the supplied name is a valid attribute name." },
4295 { "binary_encode", py_binary_encode
, METH_VARARGS
,
4296 "S.binary_encode(string) -> string\n\n"
4297 "Perform a RFC2254 binary encoding on a string" },
4298 { "binary_decode", py_binary_decode
, METH_VARARGS
,
4299 "S.binary_decode(string) -> string\n\n"
4300 "Perform a RFC2254 binary decode on a string" },
4304 #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."
4306 #if PY_MAJOR_VERSION >= 3
4307 static struct PyModuleDef moduledef
= {
4308 PyModuleDef_HEAD_INIT
,
4310 .m_doc
= MODULE_DOC
,
4312 .m_methods
= py_ldb_global_methods
,
4316 static PyObject
* module_init(void)
4320 PyLdbBytesType
.tp_base
= &PyBytes_Type
;
4321 if (PyType_Ready(&PyLdbBytesType
) < 0) {
4325 if (PyType_Ready(&PyLdbDn
) < 0)
4328 if (PyType_Ready(&PyLdbMessage
) < 0)
4331 if (PyType_Ready(&PyLdbMessageElement
) < 0)
4334 if (PyType_Ready(&PyLdb
) < 0)
4337 if (PyType_Ready(&PyLdbModule
) < 0)
4340 if (PyType_Ready(&PyLdbTree
) < 0)
4343 if (PyType_Ready(&PyLdbResult
) < 0)
4346 if (PyType_Ready(&PyLdbSearchIterator
) < 0)
4349 if (PyType_Ready(&PyLdbControl
) < 0)
4352 #if PY_MAJOR_VERSION >= 3
4353 m
= PyModule_Create(&moduledef
);
4355 m
= Py_InitModule3("ldb", py_ldb_global_methods
, MODULE_DOC
);
4360 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4362 ADD_LDB_INT(SEQ_HIGHEST_SEQ
);
4363 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP
);
4364 ADD_LDB_INT(SEQ_NEXT
);
4365 ADD_LDB_INT(SCOPE_DEFAULT
);
4366 ADD_LDB_INT(SCOPE_BASE
);
4367 ADD_LDB_INT(SCOPE_ONELEVEL
);
4368 ADD_LDB_INT(SCOPE_SUBTREE
);
4370 ADD_LDB_INT(CHANGETYPE_NONE
);
4371 ADD_LDB_INT(CHANGETYPE_ADD
);
4372 ADD_LDB_INT(CHANGETYPE_DELETE
);
4373 ADD_LDB_INT(CHANGETYPE_MODIFY
);
4375 ADD_LDB_INT(FLAG_MOD_ADD
);
4376 ADD_LDB_INT(FLAG_MOD_REPLACE
);
4377 ADD_LDB_INT(FLAG_MOD_DELETE
);
4378 ADD_LDB_INT(FLAG_FORCE_NO_BASE64_LDIF
);
4380 ADD_LDB_INT(ATTR_FLAG_HIDDEN
);
4381 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX
);
4382 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE
);
4383 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF
);
4385 ADD_LDB_INT(SUCCESS
);
4386 ADD_LDB_INT(ERR_OPERATIONS_ERROR
);
4387 ADD_LDB_INT(ERR_PROTOCOL_ERROR
);
4388 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED
);
4389 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED
);
4390 ADD_LDB_INT(ERR_COMPARE_FALSE
);
4391 ADD_LDB_INT(ERR_COMPARE_TRUE
);
4392 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED
);
4393 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED
);
4394 ADD_LDB_INT(ERR_REFERRAL
);
4395 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED
);
4396 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION
);
4397 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED
);
4398 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS
);
4399 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE
);
4400 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE
);
4401 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING
);
4402 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION
);
4403 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS
);
4404 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX
);
4405 ADD_LDB_INT(ERR_NO_SUCH_OBJECT
);
4406 ADD_LDB_INT(ERR_ALIAS_PROBLEM
);
4407 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX
);
4408 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM
);
4409 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION
);
4410 ADD_LDB_INT(ERR_INVALID_CREDENTIALS
);
4411 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS
);
4412 ADD_LDB_INT(ERR_BUSY
);
4413 ADD_LDB_INT(ERR_UNAVAILABLE
);
4414 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM
);
4415 ADD_LDB_INT(ERR_LOOP_DETECT
);
4416 ADD_LDB_INT(ERR_NAMING_VIOLATION
);
4417 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION
);
4418 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF
);
4419 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN
);
4420 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS
);
4421 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED
);
4422 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS
);
4423 ADD_LDB_INT(ERR_OTHER
);
4425 ADD_LDB_INT(FLG_RDONLY
);
4426 ADD_LDB_INT(FLG_NOSYNC
);
4427 ADD_LDB_INT(FLG_RECONNECT
);
4428 ADD_LDB_INT(FLG_NOMMAP
);
4429 ADD_LDB_INT(FLG_SHOW_BINARY
);
4430 ADD_LDB_INT(FLG_ENABLE_TRACING
);
4431 ADD_LDB_INT(FLG_DONT_CREATE_DB
);
4433 ADD_LDB_INT(PACKING_FORMAT
);
4434 ADD_LDB_INT(PACKING_FORMAT_V2
);
4436 /* Historical misspelling */
4437 PyModule_AddIntConstant(m
, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM
);
4439 PyModule_AddStringConstant(m
, "__docformat__", "restructuredText");
4441 PyExc_LdbError
= PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL
, NULL
);
4442 PyModule_AddObject(m
, "LdbError", PyExc_LdbError
);
4445 Py_INCREF(&PyLdbDn
);
4446 Py_INCREF(&PyLdbModule
);
4447 Py_INCREF(&PyLdbMessage
);
4448 Py_INCREF(&PyLdbMessageElement
);
4449 Py_INCREF(&PyLdbTree
);
4450 Py_INCREF(&PyLdbResult
);
4451 Py_INCREF(&PyLdbControl
);
4453 PyModule_AddObject(m
, "Ldb", (PyObject
*)&PyLdb
);
4454 PyModule_AddObject(m
, "Dn", (PyObject
*)&PyLdbDn
);
4455 PyModule_AddObject(m
, "Message", (PyObject
*)&PyLdbMessage
);
4456 PyModule_AddObject(m
, "MessageElement", (PyObject
*)&PyLdbMessageElement
);
4457 PyModule_AddObject(m
, "Module", (PyObject
*)&PyLdbModule
);
4458 PyModule_AddObject(m
, "Tree", (PyObject
*)&PyLdbTree
);
4459 PyModule_AddObject(m
, "Control", (PyObject
*)&PyLdbControl
);
4461 PyModule_AddStringConstant(m
, "__version__", PACKAGE_VERSION
);
4463 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4465 ADD_LDB_STRING(SYNTAX_DN
);
4466 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING
);
4467 ADD_LDB_STRING(SYNTAX_INTEGER
);
4468 ADD_LDB_STRING(SYNTAX_ORDERED_INTEGER
);
4469 ADD_LDB_STRING(SYNTAX_BOOLEAN
);
4470 ADD_LDB_STRING(SYNTAX_OCTET_STRING
);
4471 ADD_LDB_STRING(SYNTAX_UTC_TIME
);
4472 ADD_LDB_STRING(OID_COMPARATOR_AND
);
4473 ADD_LDB_STRING(OID_COMPARATOR_OR
);
4478 #if PY_MAJOR_VERSION >= 3
4479 PyMODINIT_FUNC
PyInit_ldb(void);
4480 PyMODINIT_FUNC
PyInit_ldb(void)
4482 return module_init();