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 struct py_ldb_search_iterator_reply
;
44 struct ldb_request
*req
;
45 struct py_ldb_search_iterator_reply
*next
;
46 struct py_ldb_search_iterator_reply
*result
;
49 } PyLdbSearchIteratorObject
;
51 struct py_ldb_search_iterator_reply
{
52 struct py_ldb_search_iterator_reply
*prev
, *next
;
53 PyLdbSearchIteratorObject
*py_iter
;
58 static PyObject
*PyLdbMessage_FromMessage(struct ldb_message
*msg
);
59 static PyObject
*PyExc_LdbError
;
61 static PyTypeObject PyLdbControl
;
62 static PyTypeObject PyLdbResult
;
63 static PyTypeObject PyLdbSearchIterator
;
64 static PyTypeObject PyLdbMessage
;
65 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
66 static PyTypeObject PyLdbModule
;
67 static PyTypeObject PyLdbDn
;
68 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
69 static PyTypeObject PyLdb
;
70 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
71 static PyTypeObject PyLdbMessageElement
;
72 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
74 static PyTypeObject PyLdbTree
;
75 static PyObject
*PyLdb_FromLdbContext(struct ldb_context
*ldb_ctx
);
76 static PyObject
*PyLdbModule_FromModule(struct ldb_module
*mod
);
77 static struct ldb_message_element
*PyObject_AsMessageElement(
81 const char *attr_name
);
82 static PyTypeObject PyLdbBytesType
;
84 #if PY_MAJOR_VERSION >= 3
85 #define PyStr_Check PyUnicode_Check
86 #define PyStr_FromString PyUnicode_FromString
87 #define PyStr_FromStringAndSize PyUnicode_FromStringAndSize
88 #define PyStr_FromFormat PyUnicode_FromFormat
89 #define PyStr_FromFormatV PyUnicode_FromFormatV
90 #define PyStr_AsUTF8 PyUnicode_AsUTF8
91 #define PyStr_AsUTF8AndSize PyUnicode_AsUTF8AndSize
92 #define PyInt_FromLong PyLong_FromLong
94 static PyObject
*PyLdbBytes_FromStringAndSize(const char *msg
, int size
)
96 PyObject
* result
= NULL
;
97 PyObject
* args
= NULL
;
98 args
= Py_BuildValue("(y#)", msg
, size
);
99 result
= PyLdbBytesType
.tp_new(&PyLdbBytesType
, args
, NULL
);
104 #define PyStr_Check PyString_Check
105 #define PyStr_FromString PyString_FromString
106 #define PyStr_FromStringAndSize PyString_FromStringAndSize
107 #define PyStr_FromFormat PyString_FromFormat
108 #define PyStr_FromFormatV PyString_FromFormatV
109 #define PyStr_AsUTF8 PyString_AsString
110 #define PyLdbBytes_FromStringAndSize PyString_FromStringAndSize
112 const char *PyStr_AsUTF8AndSize(PyObject
*pystr
, Py_ssize_t
*sizeptr
);
114 PyStr_AsUTF8AndSize(PyObject
*pystr
, Py_ssize_t
*sizeptr
)
116 const char * ret
= PyString_AsString(pystr
);
119 *sizeptr
= PyString_Size(pystr
);
124 static PyObject
*richcmp(int cmp_val
, int op
)
128 case Py_LT
: ret
= cmp_val
< 0; break;
129 case Py_LE
: ret
= cmp_val
<= 0; break;
130 case Py_EQ
: ret
= cmp_val
== 0; break;
131 case Py_NE
: ret
= cmp_val
!= 0; break;
132 case Py_GT
: ret
= cmp_val
> 0; break;
133 case Py_GE
: ret
= cmp_val
>= 0; break;
135 Py_INCREF(Py_NotImplemented
);
136 return Py_NotImplemented
;
138 return PyBool_FromLong(ret
);
142 static PyObject
*py_ldb_control_str(PyLdbControlObject
*self
)
144 if (self
->data
!= NULL
) {
145 char* control
= ldb_control_to_string(self
->mem_ctx
, self
->data
);
146 if (control
== NULL
) {
150 return PyStr_FromString(control
);
152 return PyStr_FromString("ldb control");
156 static void py_ldb_control_dealloc(PyLdbControlObject
*self
)
158 if (self
->mem_ctx
!= NULL
) {
159 talloc_free(self
->mem_ctx
);
162 Py_TYPE(self
)->tp_free(self
);
165 /* Create a text (rather than bytes) interface for a LDB result object */
166 static PyObject
*wrap_text(const char *type
, PyObject
*wrapped
)
168 PyObject
*mod
, *cls
, *constructor
, *inst
;
169 mod
= PyImport_ImportModule("_ldb_text");
172 cls
= PyObject_GetAttrString(mod
, type
);
178 constructor
= PyObject_GetAttrString(cls
, "_wrap");
180 if (constructor
== NULL
) {
183 inst
= PyObject_CallFunction(constructor
, discard_const_p(char, "O"), wrapped
);
184 Py_DECREF(constructor
);
188 static PyObject
*py_ldb_control_get_oid(PyLdbControlObject
*self
)
190 return PyStr_FromString(self
->data
->oid
);
193 static PyObject
*py_ldb_control_get_critical(PyLdbControlObject
*self
)
195 return PyBool_FromLong(self
->data
->critical
);
198 static PyObject
*py_ldb_control_set_critical(PyLdbControlObject
*self
, PyObject
*value
, void *closure
)
200 if (PyObject_IsTrue(value
)) {
201 self
->data
->critical
= true;
203 self
->data
->critical
= false;
208 static PyObject
*py_ldb_control_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
211 const char * const kwnames
[] = { "ldb", "data", NULL
};
212 struct ldb_control
*parsed_controls
;
213 PyLdbControlObject
*ret
;
216 struct ldb_context
*ldb_ctx
;
218 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O!s",
219 discard_const_p(char *, kwnames
),
220 &PyLdb
, &py_ldb
, &data
))
223 mem_ctx
= talloc_new(NULL
);
224 if (mem_ctx
== NULL
) {
229 ldb_ctx
= pyldb_Ldb_AsLdbContext(py_ldb
);
230 parsed_controls
= ldb_parse_control_from_string(ldb_ctx
, mem_ctx
, data
);
232 if (!parsed_controls
) {
233 talloc_free(mem_ctx
);
234 PyErr_SetString(PyExc_ValueError
, "unable to parse control string");
238 ret
= PyObject_New(PyLdbControlObject
, type
);
241 talloc_free(mem_ctx
);
245 ret
->mem_ctx
= mem_ctx
;
247 ret
->data
= talloc_move(mem_ctx
, &parsed_controls
);
248 if (ret
->data
== NULL
) {
251 talloc_free(mem_ctx
);
255 return (PyObject
*)ret
;
258 static PyGetSetDef py_ldb_control_getset
[] = {
259 { discard_const_p(char, "oid"), (getter
)py_ldb_control_get_oid
, NULL
, NULL
},
260 { discard_const_p(char, "critical"), (getter
)py_ldb_control_get_critical
, (setter
)py_ldb_control_set_critical
, NULL
},
264 static PyTypeObject PyLdbControl
= {
265 .tp_name
= "ldb.control",
266 .tp_dealloc
= (destructor
)py_ldb_control_dealloc
,
267 .tp_getattro
= PyObject_GenericGetAttr
,
268 .tp_basicsize
= sizeof(PyLdbControlObject
),
269 .tp_getset
= py_ldb_control_getset
,
270 .tp_doc
= "LDB control.",
271 .tp_str
= (reprfunc
)py_ldb_control_str
,
272 .tp_new
= py_ldb_control_new
,
273 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
276 static void PyErr_SetLdbError(PyObject
*error
, int ret
, struct ldb_context
*ldb_ctx
)
278 if (ret
== LDB_ERR_PYTHON_EXCEPTION
)
279 return; /* Python exception should already be set, just keep that */
281 PyErr_SetObject(error
,
282 Py_BuildValue(discard_const_p(char, "(i,s)"), ret
,
283 ldb_ctx
== NULL
?ldb_strerror(ret
):ldb_errstring(ldb_ctx
)));
285 static PyObject
*py_ldb_bytes_str(PyBytesObject
*self
)
290 if (!PyBytes_Check(self
)) {
291 PyErr_Format(PyExc_TypeError
,"Unexpected type");
294 result
= PyBytes_AsStringAndSize((PyObject
*)self
, &msg
, &size
);
296 PyErr_Format(PyExc_TypeError
, "Failed to extract bytes");
299 return PyUnicode_FromStringAndSize(msg
, size
);
302 static PyTypeObject PyLdbBytesType
= {
303 PyVarObject_HEAD_INIT(NULL
, 0)
304 .tp_name
= "ldb.bytes",
305 .tp_doc
= "str/bytes (with custom str)",
306 .tp_str
= (reprfunc
)py_ldb_bytes_str
,
307 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
310 static PyObject
*PyObject_FromLdbValue(const struct ldb_val
*val
)
312 return PyLdbBytes_FromStringAndSize((const char *)val
->data
, val
->length
);
315 static PyObject
*PyStr_FromLdbValue(const struct ldb_val
*val
)
317 return PyStr_FromStringAndSize((const char *)val
->data
, val
->length
);
321 * Create a Python object from a ldb_result.
323 * @param result LDB result to convert
324 * @return Python object with converted result (a list object)
326 static PyObject
*PyLdbControl_FromControl(struct ldb_control
*control
)
328 TALLOC_CTX
*ctl_ctx
= talloc_new(NULL
);
329 PyLdbControlObject
*ctrl
;
330 if (ctl_ctx
== NULL
) {
335 ctrl
= (PyLdbControlObject
*)PyLdbControl
.tp_alloc(&PyLdbControl
, 0);
337 talloc_free(ctl_ctx
);
341 ctrl
->mem_ctx
= ctl_ctx
;
342 ctrl
->data
= talloc_steal(ctrl
->mem_ctx
, control
);
343 if (ctrl
->data
== NULL
) {
348 return (PyObject
*) ctrl
;
352 * Create a Python object from a ldb_result.
354 * @param result LDB result to convert
355 * @return Python object with converted result (a list object)
357 static PyObject
*PyLdbResult_FromResult(struct ldb_result
*result
)
359 PyLdbResultObject
*ret
;
360 PyObject
*list
, *controls
, *referals
;
363 if (result
== NULL
) {
367 ret
= (PyLdbResultObject
*)PyLdbResult
.tp_alloc(&PyLdbResult
, 0);
373 list
= PyList_New(result
->count
);
380 for (i
= 0; i
< result
->count
; i
++) {
381 PyList_SetItem(list
, i
, PyLdbMessage_FromMessage(result
->msgs
[i
]));
384 ret
->mem_ctx
= talloc_new(NULL
);
385 if (ret
->mem_ctx
== NULL
) {
394 if (result
->controls
) {
396 while (result
->controls
[i
]) {
399 controls
= PyList_New(i
);
400 if (controls
== NULL
) {
405 for (i
=0; result
->controls
[i
]; i
++) {
406 PyObject
*ctrl
= (PyObject
*) PyLdbControl_FromControl(result
->controls
[i
]);
413 PyList_SetItem(controls
, i
, ctrl
);
417 * No controls so we keep an empty list
419 controls
= PyList_New(0);
420 if (controls
== NULL
) {
427 ret
->controls
= controls
;
431 while (result
->refs
&& result
->refs
[i
]) {
435 referals
= PyList_New(i
);
436 if (referals
== NULL
) {
442 for (i
= 0;result
->refs
&& result
->refs
[i
]; i
++) {
443 PyList_SetItem(referals
, i
, PyStr_FromString(result
->refs
[i
]));
445 ret
->referals
= referals
;
446 return (PyObject
*)ret
;
450 * Create a LDB Result from a Python object.
451 * If conversion fails, NULL will be returned and a Python exception set.
453 * Note: the result object only includes the messages at the moment; extended
454 * result, controls and referrals are ignored.
456 * @param mem_ctx Memory context in which to allocate the LDB Result
457 * @param obj Python object to convert
458 * @return a ldb_result, or NULL if the conversion failed
460 static struct ldb_result
*PyLdbResult_AsResult(TALLOC_CTX
*mem_ctx
,
463 struct ldb_result
*res
;
469 res
= talloc_zero(mem_ctx
, struct ldb_result
);
470 res
->count
= PyList_Size(obj
);
471 res
->msgs
= talloc_array(res
, struct ldb_message
*, res
->count
);
472 for (i
= 0; i
< res
->count
; i
++) {
473 PyObject
*item
= PyList_GetItem(obj
, i
);
474 res
->msgs
[i
] = pyldb_Message_AsMessage(item
);
479 static PyObject
*py_ldb_dn_validate(PyLdbDnObject
*self
)
481 return PyBool_FromLong(ldb_dn_validate(self
->dn
));
484 static PyObject
*py_ldb_dn_is_valid(PyLdbDnObject
*self
)
486 return PyBool_FromLong(ldb_dn_is_valid(self
->dn
));
489 static PyObject
*py_ldb_dn_is_special(PyLdbDnObject
*self
)
491 return PyBool_FromLong(ldb_dn_is_special(self
->dn
));
494 static PyObject
*py_ldb_dn_is_null(PyLdbDnObject
*self
)
496 return PyBool_FromLong(ldb_dn_is_null(self
->dn
));
499 static PyObject
*py_ldb_dn_get_casefold(PyLdbDnObject
*self
)
501 return PyStr_FromString(ldb_dn_get_casefold(self
->dn
));
504 static PyObject
*py_ldb_dn_get_linearized(PyLdbDnObject
*self
)
506 return PyStr_FromString(ldb_dn_get_linearized(self
->dn
));
509 static PyObject
*py_ldb_dn_canonical_str(PyLdbDnObject
*self
)
511 return PyStr_FromString(ldb_dn_canonical_string(self
->dn
, self
->dn
));
514 static PyObject
*py_ldb_dn_canonical_ex_str(PyLdbDnObject
*self
)
516 return PyStr_FromString(ldb_dn_canonical_ex_string(self
->dn
, self
->dn
));
519 static PyObject
*py_ldb_dn_extended_str(PyLdbDnObject
*self
, PyObject
*args
, PyObject
*kwargs
)
521 const char * const kwnames
[] = { "mode", NULL
};
523 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i",
524 discard_const_p(char *, kwnames
),
527 return PyStr_FromString(ldb_dn_get_extended_linearized(self
->dn
, self
->dn
, mode
));
530 static PyObject
*py_ldb_dn_get_extended_component(PyLdbDnObject
*self
, PyObject
*args
)
533 const struct ldb_val
*val
;
535 if (!PyArg_ParseTuple(args
, "s", &name
))
537 val
= ldb_dn_get_extended_component(self
->dn
, name
);
542 return PyBytes_FromStringAndSize((const char *)val
->data
, val
->length
);
545 static PyObject
*py_ldb_dn_set_extended_component(PyLdbDnObject
*self
, PyObject
*args
)
549 uint8_t *value
= NULL
;
552 if (!PyArg_ParseTuple(args
, "sz#", &name
, (char **)&value
, &size
))
556 err
= ldb_dn_set_extended_component(self
->dn
, name
, NULL
);
559 val
.data
= (uint8_t *)value
;
561 err
= ldb_dn_set_extended_component(self
->dn
, name
, &val
);
564 if (err
!= LDB_SUCCESS
) {
565 PyErr_SetString(PyExc_TypeError
, "Failed to set extended component");
572 static PyObject
*py_ldb_dn_repr(PyLdbDnObject
*self
)
574 PyObject
*str
= PyStr_FromString(ldb_dn_get_linearized(self
->dn
));
575 PyObject
*repr
, *result
;
578 repr
= PyObject_Repr(str
);
583 result
= PyStr_FromFormat("Dn(%s)", PyStr_AsUTF8(repr
));
589 static PyObject
*py_ldb_dn_check_special(PyLdbDnObject
*self
, PyObject
*args
)
593 if (!PyArg_ParseTuple(args
, "s", &name
))
596 return PyBool_FromLong(ldb_dn_check_special(self
->dn
, name
));
599 static PyObject
*py_ldb_dn_richcmp(PyObject
*dn1
, PyObject
*dn2
, int op
)
602 if (!pyldb_Dn_Check(dn2
)) {
603 Py_INCREF(Py_NotImplemented
);
604 return Py_NotImplemented
;
606 ret
= ldb_dn_compare(pyldb_Dn_AsDn(dn1
), pyldb_Dn_AsDn(dn2
));
607 return richcmp(ret
, op
);
610 static PyObject
*py_ldb_dn_get_parent(PyLdbDnObject
*self
)
612 struct ldb_dn
*dn
= pyldb_Dn_AsDn((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_AsDn((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_AsDn((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_AsDn((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_AsDn((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_AsDn((PyObject
*)self
);
702 name
= ldb_dn_get_component_name(dn
, num
);
707 return PyStr_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_AsDn((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
= { NULL
, };
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
)
757 dn
= pyldb_Dn_AsDn((PyObject
*)self
);
759 name
= ldb_dn_get_rdn_name(dn
);
764 return PyStr_FromString(name
);
767 static PyObject
*py_ldb_dn_get_rdn_value(PyLdbDnObject
*self
)
770 const struct ldb_val
*val
;
772 dn
= pyldb_Dn_AsDn((PyObject
*)self
);
774 val
= ldb_dn_get_rdn_val(dn
);
779 return PyStr_FromLdbValue(val
);
782 static PyMethodDef py_ldb_dn_methods
[] = {
783 { "validate", (PyCFunction
)py_ldb_dn_validate
, METH_NOARGS
,
784 "S.validate() -> bool\n"
785 "Validate DN is correct." },
786 { "is_valid", (PyCFunction
)py_ldb_dn_is_valid
, METH_NOARGS
,
787 "S.is_valid() -> bool\n" },
788 { "is_special", (PyCFunction
)py_ldb_dn_is_special
, METH_NOARGS
,
789 "S.is_special() -> bool\n"
790 "Check whether this is a special LDB DN." },
791 { "is_null", (PyCFunction
)py_ldb_dn_is_null
, METH_NOARGS
,
792 "Check whether this is a null DN." },
793 { "get_casefold", (PyCFunction
)py_ldb_dn_get_casefold
, METH_NOARGS
,
795 { "get_linearized", (PyCFunction
)py_ldb_dn_get_linearized
, METH_NOARGS
,
797 { "canonical_str", (PyCFunction
)py_ldb_dn_canonical_str
, METH_NOARGS
,
798 "S.canonical_str() -> string\n"
799 "Canonical version of this DN (like a posix path)." },
800 { "is_child_of", (PyCFunction
)py_ldb_dn_is_child_of
, METH_VARARGS
,
801 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
802 { "canonical_ex_str", (PyCFunction
)py_ldb_dn_canonical_ex_str
, METH_NOARGS
,
803 "S.canonical_ex_str() -> string\n"
804 "Canonical version of this DN (like a posix path, with terminating newline)." },
805 { "extended_str", (PyCFunction
)py_ldb_dn_extended_str
, METH_VARARGS
| METH_KEYWORDS
,
806 "S.extended_str(mode=1) -> string\n"
807 "Extended version of this DN" },
808 { "parent", (PyCFunction
)py_ldb_dn_get_parent
, METH_NOARGS
,
810 "Get the parent for this DN." },
811 { "add_child", (PyCFunction
)py_ldb_dn_add_child
, METH_VARARGS
,
812 "S.add_child(dn) -> None\n"
813 "Add a child DN to this DN." },
814 { "add_base", (PyCFunction
)py_ldb_dn_add_base
, METH_VARARGS
,
815 "S.add_base(dn) -> None\n"
816 "Add a base DN to this DN." },
817 { "remove_base_components", (PyCFunction
)py_ldb_dn_remove_base_components
, METH_VARARGS
,
818 "S.remove_base_components(int) -> bool\n"
819 "Remove a number of DN components from the base of this DN." },
820 { "check_special", (PyCFunction
)py_ldb_dn_check_special
, METH_VARARGS
,
821 "S.check_special(name) -> bool\n\n"
822 "Check if name is a special DN name"},
823 { "get_extended_component", (PyCFunction
)py_ldb_dn_get_extended_component
, METH_VARARGS
,
824 "S.get_extended_component(name) -> string\n\n"
825 "returns a DN extended component as a binary string"},
826 { "set_extended_component", (PyCFunction
)py_ldb_dn_set_extended_component
, METH_VARARGS
,
827 "S.set_extended_component(name, value) -> None\n\n"
828 "set a DN extended component as a binary string"},
829 { "get_component_name", (PyCFunction
)py_ldb_dn_get_component_name
, METH_VARARGS
,
830 "S.get_component_name(num) -> string\n"
831 "get the attribute name of the specified component" },
832 { "get_component_value", (PyCFunction
)py_ldb_dn_get_component_value
, METH_VARARGS
,
833 "S.get_component_value(num) -> string\n"
834 "get the attribute value of the specified component as a binary string" },
835 { "set_component", (PyCFunction
)py_ldb_dn_set_component
, METH_VARARGS
,
836 "S.get_component_value(num, name, value) -> None\n"
837 "set the attribute name and value of the specified component" },
838 { "get_rdn_name", (PyCFunction
)py_ldb_dn_get_rdn_name
, METH_NOARGS
,
839 "S.get_rdn_name() -> string\n"
840 "get the RDN attribute name" },
841 { "get_rdn_value", (PyCFunction
)py_ldb_dn_get_rdn_value
, METH_NOARGS
,
842 "S.get_rdn_value() -> string\n"
843 "get the RDN attribute value as a binary string" },
847 static Py_ssize_t
py_ldb_dn_len(PyLdbDnObject
*self
)
849 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject
*)self
));
853 copy a DN as a python object
855 static PyObject
*py_ldb_dn_copy(struct ldb_dn
*dn
)
857 PyLdbDnObject
*py_ret
;
859 py_ret
= (PyLdbDnObject
*)PyLdbDn
.tp_alloc(&PyLdbDn
, 0);
860 if (py_ret
== NULL
) {
864 py_ret
->mem_ctx
= talloc_new(NULL
);
865 py_ret
->dn
= ldb_dn_copy(py_ret
->mem_ctx
, dn
);
866 return (PyObject
*)py_ret
;
869 static PyObject
*py_ldb_dn_concat(PyLdbDnObject
*self
, PyObject
*py_other
)
871 struct ldb_dn
*dn
= pyldb_Dn_AsDn((PyObject
*)self
),
873 PyLdbDnObject
*py_ret
;
875 if (!pyldb_Object_AsDn(NULL
, py_other
, NULL
, &other
))
878 py_ret
= (PyLdbDnObject
*)PyLdbDn
.tp_alloc(&PyLdbDn
, 0);
879 if (py_ret
== NULL
) {
883 py_ret
->mem_ctx
= talloc_new(NULL
);
884 py_ret
->dn
= ldb_dn_copy(py_ret
->mem_ctx
, dn
);
885 ldb_dn_add_base(py_ret
->dn
, other
);
886 return (PyObject
*)py_ret
;
889 static PySequenceMethods py_ldb_dn_seq
= {
890 .sq_length
= (lenfunc
)py_ldb_dn_len
,
891 .sq_concat
= (binaryfunc
)py_ldb_dn_concat
,
894 static PyObject
*py_ldb_dn_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
896 struct ldb_dn
*ret
= NULL
;
898 PyObject
*py_ldb
= NULL
;
899 struct ldb_context
*ldb_ctx
= NULL
;
900 TALLOC_CTX
*mem_ctx
= NULL
;
901 PyLdbDnObject
*py_ret
= NULL
;
902 const char * const kwnames
[] = { "ldb", "dn", NULL
};
904 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oes",
905 discard_const_p(char *, kwnames
),
906 &py_ldb
, "utf8", &str
))
909 if (!PyLdb_Check(py_ldb
)) {
910 PyErr_SetString(PyExc_TypeError
, "Expected Ldb");
914 ldb_ctx
= pyldb_Ldb_AsLdbContext(py_ldb
);
916 mem_ctx
= talloc_new(NULL
);
917 if (mem_ctx
== NULL
) {
922 ret
= ldb_dn_new(mem_ctx
, ldb_ctx
, str
);
923 if (!ldb_dn_validate(ret
)) {
924 talloc_free(mem_ctx
);
925 PyErr_SetString(PyExc_ValueError
, "unable to parse dn string");
929 py_ret
= (PyLdbDnObject
*)type
->tp_alloc(type
, 0);
930 if (py_ret
== NULL
) {
931 talloc_free(mem_ctx
);
935 py_ret
->mem_ctx
= mem_ctx
;
939 PyMem_Free(discard_const_p(char, str
));
941 return (PyObject
*)py_ret
;
944 static void py_ldb_dn_dealloc(PyLdbDnObject
*self
)
946 talloc_free(self
->mem_ctx
);
950 static PyTypeObject PyLdbDn
= {
952 .tp_methods
= py_ldb_dn_methods
,
953 .tp_str
= (reprfunc
)py_ldb_dn_get_linearized
,
954 .tp_repr
= (reprfunc
)py_ldb_dn_repr
,
955 .tp_richcompare
= (richcmpfunc
)py_ldb_dn_richcmp
,
956 .tp_as_sequence
= &py_ldb_dn_seq
,
957 .tp_doc
= "A LDB distinguished name.",
958 .tp_new
= py_ldb_dn_new
,
959 .tp_dealloc
= (destructor
)py_ldb_dn_dealloc
,
960 .tp_basicsize
= sizeof(PyLdbDnObject
),
961 .tp_flags
= Py_TPFLAGS_DEFAULT
,
965 static void py_ldb_debug(void *context
, enum ldb_debug_level level
, const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(3, 0);
966 static void py_ldb_debug(void *context
, enum ldb_debug_level level
, const char *fmt
, va_list ap
)
968 PyObject
*fn
= (PyObject
*)context
;
969 PyObject_CallFunction(fn
, discard_const_p(char, "(i,O)"), level
, PyStr_FromFormatV(fmt
, ap
));
972 static PyObject
*py_ldb_debug_func
;
974 static PyObject
*py_ldb_set_debug(PyObject
*self
, PyObject
*args
)
977 struct ldb_context
*ldb_ctx
;
979 if (!PyArg_ParseTuple(args
, "O", &cb
))
982 if (py_ldb_debug_func
!= NULL
) {
983 Py_DECREF(py_ldb_debug_func
);
987 /* FIXME: DECREF cb when exiting program */
988 py_ldb_debug_func
= cb
;
989 ldb_ctx
= pyldb_Ldb_AsLdbContext(self
);
990 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
,
991 ldb_set_debug(ldb_ctx
, py_ldb_debug
, cb
),
997 static PyObject
*py_ldb_set_create_perms(PyTypeObject
*self
, PyObject
*args
)
1000 if (!PyArg_ParseTuple(args
, "I", &perms
))
1003 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self
), perms
);
1008 static PyObject
*py_ldb_set_modules_dir(PyTypeObject
*self
, PyObject
*args
)
1011 if (!PyArg_ParseTuple(args
, "s", &modules_dir
))
1014 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self
), modules_dir
);
1019 static PyObject
*py_ldb_transaction_start(PyLdbObject
*self
)
1021 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AsLdbContext(self
);
1023 ldb_err
= ldb_transaction_start(ldb_ctx
);
1024 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1028 static PyObject
*py_ldb_transaction_commit(PyLdbObject
*self
)
1030 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AsLdbContext(self
);
1032 ldb_err
= ldb_transaction_commit(ldb_ctx
);
1033 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1037 static PyObject
*py_ldb_transaction_prepare_commit(PyLdbObject
*self
)
1039 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AsLdbContext(self
);
1041 ldb_err
= ldb_transaction_prepare_commit(ldb_ctx
);
1042 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1046 static PyObject
*py_ldb_transaction_cancel(PyLdbObject
*self
)
1048 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AsLdbContext(self
);
1050 ldb_err
= ldb_transaction_cancel(ldb_ctx
);
1051 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1055 static PyObject
*py_ldb_setup_wellknown_attributes(PyLdbObject
*self
)
1057 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AsLdbContext(self
);
1059 ldb_err
= ldb_setup_wellknown_attributes(ldb_ctx
);
1060 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1064 static PyObject
*py_ldb_repr(PyLdbObject
*self
)
1066 return PyStr_FromString("<ldb connection>");
1069 static PyObject
*py_ldb_get_root_basedn(PyLdbObject
*self
)
1071 struct ldb_dn
*dn
= ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self
));
1074 return py_ldb_dn_copy(dn
);
1078 static PyObject
*py_ldb_get_schema_basedn(PyLdbObject
*self
)
1080 struct ldb_dn
*dn
= ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self
));
1083 return py_ldb_dn_copy(dn
);
1086 static PyObject
*py_ldb_get_config_basedn(PyLdbObject
*self
)
1088 struct ldb_dn
*dn
= ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self
));
1091 return py_ldb_dn_copy(dn
);
1094 static PyObject
*py_ldb_get_default_basedn(PyLdbObject
*self
)
1096 struct ldb_dn
*dn
= ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self
));
1099 return py_ldb_dn_copy(dn
);
1102 static const char **PyList_AsStrList(TALLOC_CTX
*mem_ctx
, PyObject
*list
,
1103 const char *paramname
)
1107 if (!PyList_Check(list
)) {
1108 PyErr_Format(PyExc_TypeError
, "%s is not a list", paramname
);
1111 ret
= talloc_array(NULL
, const char *, PyList_Size(list
)+1);
1117 for (i
= 0; i
< PyList_Size(list
); i
++) {
1118 const char *str
= NULL
;
1120 PyObject
*item
= PyList_GetItem(list
, i
);
1121 if (!(PyStr_Check(item
) || PyUnicode_Check(item
))) {
1122 PyErr_Format(PyExc_TypeError
, "%s should be strings", paramname
);
1126 str
= PyStr_AsUTF8AndSize(item
, &size
);
1131 ret
[i
] = talloc_strndup(ret
, str
, size
);
1137 static int py_ldb_init(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1139 const char * const kwnames
[] = { "url", "flags", "options", NULL
};
1141 PyObject
*py_options
= Py_None
;
1142 const char **options
;
1143 unsigned int flags
= 0;
1145 struct ldb_context
*ldb
;
1147 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|zIO:Ldb.__init__",
1148 discard_const_p(char *, kwnames
),
1149 &url
, &flags
, &py_options
))
1152 ldb
= pyldb_Ldb_AsLdbContext(self
);
1154 if (py_options
== Py_None
) {
1157 options
= PyList_AsStrList(ldb
, py_options
, "options");
1158 if (options
== NULL
)
1163 ret
= ldb_connect(ldb
, url
, flags
, options
);
1164 if (ret
!= LDB_SUCCESS
) {
1165 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb
);
1170 talloc_free(options
);
1174 static PyObject
*py_ldb_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
1177 struct ldb_context
*ldb
;
1178 ret
= (PyLdbObject
*)type
->tp_alloc(type
, 0);
1183 ret
->mem_ctx
= talloc_new(NULL
);
1184 ldb
= ldb_init(ret
->mem_ctx
, NULL
);
1192 return (PyObject
*)ret
;
1195 static PyObject
*py_ldb_connect(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1198 unsigned int flags
= 0;
1199 PyObject
*py_options
= Py_None
;
1201 const char **options
;
1202 const char * const kwnames
[] = { "url", "flags", "options", NULL
};
1203 struct ldb_context
*ldb_ctx
;
1205 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|zIO",
1206 discard_const_p(char *, kwnames
),
1207 &url
, &flags
, &py_options
))
1210 if (py_options
== Py_None
) {
1213 options
= PyList_AsStrList(NULL
, py_options
, "options");
1214 if (options
== NULL
)
1218 ldb_ctx
= pyldb_Ldb_AsLdbContext(self
);
1219 ret
= ldb_connect(ldb_ctx
, url
, flags
, options
);
1220 talloc_free(options
);
1222 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1227 static PyObject
*py_ldb_modify(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1230 PyObject
*py_controls
= Py_None
;
1231 struct ldb_context
*ldb_ctx
;
1232 struct ldb_request
*req
;
1233 struct ldb_control
**parsed_controls
;
1234 struct ldb_message
*msg
;
1236 TALLOC_CTX
*mem_ctx
;
1238 const char * const kwnames
[] = { "message", "controls", "validate", NULL
};
1240 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Ob",
1241 discard_const_p(char *, kwnames
),
1242 &py_msg
, &py_controls
, &validate
))
1245 mem_ctx
= talloc_new(NULL
);
1246 if (mem_ctx
== NULL
) {
1250 ldb_ctx
= pyldb_Ldb_AsLdbContext(self
);
1252 if (py_controls
== Py_None
) {
1253 parsed_controls
= NULL
;
1255 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1256 if (controls
== NULL
) {
1257 talloc_free(mem_ctx
);
1260 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1261 talloc_free(controls
);
1264 if (!PyLdbMessage_Check(py_msg
)) {
1265 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message");
1266 talloc_free(mem_ctx
);
1269 msg
= pyldb_Message_AsMessage(py_msg
);
1272 ret
= ldb_msg_sanity_check(ldb_ctx
, msg
);
1273 if (ret
!= LDB_SUCCESS
) {
1274 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1275 talloc_free(mem_ctx
);
1280 ret
= ldb_build_mod_req(&req
, ldb_ctx
, mem_ctx
, msg
, parsed_controls
,
1281 NULL
, ldb_op_default_callback
, NULL
);
1282 if (ret
!= LDB_SUCCESS
) {
1283 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1284 talloc_free(mem_ctx
);
1288 /* do request and autostart a transaction */
1289 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1291 ret
= ldb_transaction_start(ldb_ctx
);
1292 if (ret
!= LDB_SUCCESS
) {
1293 talloc_free(mem_ctx
);
1294 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1298 ret
= ldb_request(ldb_ctx
, req
);
1299 if (ret
== LDB_SUCCESS
) {
1300 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1303 if (ret
== LDB_SUCCESS
) {
1304 ret
= ldb_transaction_commit(ldb_ctx
);
1306 ldb_transaction_cancel(ldb_ctx
);
1309 talloc_free(mem_ctx
);
1310 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1317 * Obtain a ldb message from a Python Dictionary object.
1319 * @param mem_ctx Memory context
1320 * @param py_obj Python Dictionary object
1321 * @param ldb_ctx LDB context
1322 * @param mod_flags Flags to be set on every message element
1323 * @return ldb_message on success or NULL on failure
1325 static struct ldb_message
*PyDict_AsMessage(TALLOC_CTX
*mem_ctx
,
1327 struct ldb_context
*ldb_ctx
,
1328 unsigned int mod_flags
)
1330 struct ldb_message
*msg
;
1331 unsigned int msg_pos
= 0;
1332 Py_ssize_t dict_pos
= 0;
1333 PyObject
*key
, *value
;
1334 struct ldb_message_element
*msg_el
;
1335 PyObject
*dn_value
= PyDict_GetItemString(py_obj
, "dn");
1337 msg
= ldb_msg_new(mem_ctx
);
1342 msg
->elements
= talloc_zero_array(msg
, struct ldb_message_element
, PyDict_Size(py_obj
));
1345 if (!pyldb_Object_AsDn(msg
, dn_value
, ldb_ctx
, &msg
->dn
)) {
1346 PyErr_SetString(PyExc_TypeError
, "unable to import dn object");
1349 if (msg
->dn
== NULL
) {
1350 PyErr_SetString(PyExc_TypeError
, "dn set but not found");
1354 PyErr_SetString(PyExc_TypeError
, "no dn set");
1358 while (PyDict_Next(py_obj
, &dict_pos
, &key
, &value
)) {
1359 char *key_str
= PyStr_AsUTF8(key
);
1360 if (ldb_attr_cmp(key_str
, "dn") != 0) {
1361 msg_el
= PyObject_AsMessageElement(msg
->elements
, value
,
1362 mod_flags
, key_str
);
1363 if (msg_el
== NULL
) {
1364 PyErr_Format(PyExc_TypeError
, "unable to import element '%s'", key_str
);
1367 memcpy(&msg
->elements
[msg_pos
], msg_el
, sizeof(*msg_el
));
1372 msg
->num_elements
= msg_pos
;
1377 static PyObject
*py_ldb_add(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1381 struct ldb_context
*ldb_ctx
;
1382 struct ldb_request
*req
;
1383 struct ldb_message
*msg
= NULL
;
1384 PyObject
*py_controls
= Py_None
;
1385 TALLOC_CTX
*mem_ctx
;
1386 struct ldb_control
**parsed_controls
;
1387 const char * const kwnames
[] = { "message", "controls", NULL
};
1389 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O",
1390 discard_const_p(char *, kwnames
),
1391 &py_obj
, &py_controls
))
1394 mem_ctx
= talloc_new(NULL
);
1395 if (mem_ctx
== NULL
) {
1399 ldb_ctx
= pyldb_Ldb_AsLdbContext(self
);
1401 if (py_controls
== Py_None
) {
1402 parsed_controls
= NULL
;
1404 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1405 if (controls
== NULL
) {
1406 talloc_free(mem_ctx
);
1409 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1410 talloc_free(controls
);
1413 if (PyLdbMessage_Check(py_obj
)) {
1414 msg
= pyldb_Message_AsMessage(py_obj
);
1415 } else if (PyDict_Check(py_obj
)) {
1416 msg
= PyDict_AsMessage(mem_ctx
, py_obj
, ldb_ctx
, LDB_FLAG_MOD_ADD
);
1418 PyErr_SetString(PyExc_TypeError
,
1419 "Dictionary or LdbMessage object expected!");
1423 /* we should have a PyErr already set */
1424 talloc_free(mem_ctx
);
1428 ret
= ldb_msg_sanity_check(ldb_ctx
, msg
);
1429 if (ret
!= LDB_SUCCESS
) {
1430 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1431 talloc_free(mem_ctx
);
1435 ret
= ldb_build_add_req(&req
, ldb_ctx
, mem_ctx
, msg
, parsed_controls
,
1436 NULL
, ldb_op_default_callback
, NULL
);
1437 if (ret
!= LDB_SUCCESS
) {
1438 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1439 talloc_free(mem_ctx
);
1443 /* do request and autostart a transaction */
1444 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1446 ret
= ldb_transaction_start(ldb_ctx
);
1447 if (ret
!= LDB_SUCCESS
) {
1448 talloc_free(mem_ctx
);
1449 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1453 ret
= ldb_request(ldb_ctx
, req
);
1454 if (ret
== LDB_SUCCESS
) {
1455 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1458 if (ret
== LDB_SUCCESS
) {
1459 ret
= ldb_transaction_commit(ldb_ctx
);
1461 ldb_transaction_cancel(ldb_ctx
);
1464 talloc_free(mem_ctx
);
1465 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1470 static PyObject
*py_ldb_delete(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1475 struct ldb_context
*ldb_ctx
;
1476 struct ldb_request
*req
;
1477 PyObject
*py_controls
= Py_None
;
1478 TALLOC_CTX
*mem_ctx
;
1479 struct ldb_control
**parsed_controls
;
1480 const char * const kwnames
[] = { "dn", "controls", NULL
};
1482 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O",
1483 discard_const_p(char *, kwnames
),
1484 &py_dn
, &py_controls
))
1487 mem_ctx
= talloc_new(NULL
);
1488 if (mem_ctx
== NULL
) {
1492 ldb_ctx
= pyldb_Ldb_AsLdbContext(self
);
1494 if (py_controls
== Py_None
) {
1495 parsed_controls
= NULL
;
1497 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1498 if (controls
== NULL
) {
1499 talloc_free(mem_ctx
);
1502 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1503 talloc_free(controls
);
1506 if (!pyldb_Object_AsDn(mem_ctx
, py_dn
, ldb_ctx
, &dn
)) {
1507 talloc_free(mem_ctx
);
1511 ret
= ldb_build_del_req(&req
, ldb_ctx
, mem_ctx
, dn
, parsed_controls
,
1512 NULL
, ldb_op_default_callback
, NULL
);
1513 if (ret
!= LDB_SUCCESS
) {
1514 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1515 talloc_free(mem_ctx
);
1519 /* do request and autostart a transaction */
1520 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1522 ret
= ldb_transaction_start(ldb_ctx
);
1523 if (ret
!= LDB_SUCCESS
) {
1524 talloc_free(mem_ctx
);
1525 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1529 ret
= ldb_request(ldb_ctx
, req
);
1530 if (ret
== LDB_SUCCESS
) {
1531 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1534 if (ret
== LDB_SUCCESS
) {
1535 ret
= ldb_transaction_commit(ldb_ctx
);
1537 ldb_transaction_cancel(ldb_ctx
);
1540 talloc_free(mem_ctx
);
1541 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1546 static PyObject
*py_ldb_rename(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1548 PyObject
*py_dn1
, *py_dn2
;
1549 struct ldb_dn
*dn1
, *dn2
;
1551 TALLOC_CTX
*mem_ctx
;
1552 PyObject
*py_controls
= Py_None
;
1553 struct ldb_control
**parsed_controls
;
1554 struct ldb_context
*ldb_ctx
;
1555 struct ldb_request
*req
;
1556 const char * const kwnames
[] = { "dn1", "dn2", "controls", NULL
};
1558 ldb_ctx
= pyldb_Ldb_AsLdbContext(self
);
1560 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|O",
1561 discard_const_p(char *, kwnames
),
1562 &py_dn1
, &py_dn2
, &py_controls
))
1566 mem_ctx
= talloc_new(NULL
);
1567 if (mem_ctx
== NULL
) {
1572 if (py_controls
== Py_None
) {
1573 parsed_controls
= NULL
;
1575 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1576 if (controls
== NULL
) {
1577 talloc_free(mem_ctx
);
1580 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1581 talloc_free(controls
);
1585 if (!pyldb_Object_AsDn(mem_ctx
, py_dn1
, ldb_ctx
, &dn1
)) {
1586 talloc_free(mem_ctx
);
1590 if (!pyldb_Object_AsDn(mem_ctx
, py_dn2
, ldb_ctx
, &dn2
)) {
1591 talloc_free(mem_ctx
);
1595 ret
= ldb_build_rename_req(&req
, ldb_ctx
, mem_ctx
, dn1
, dn2
, parsed_controls
,
1596 NULL
, ldb_op_default_callback
, NULL
);
1597 if (ret
!= LDB_SUCCESS
) {
1598 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1599 talloc_free(mem_ctx
);
1603 /* do request and autostart a transaction */
1604 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1606 ret
= ldb_transaction_start(ldb_ctx
);
1607 if (ret
!= LDB_SUCCESS
) {
1608 talloc_free(mem_ctx
);
1609 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1613 ret
= ldb_request(ldb_ctx
, req
);
1614 if (ret
== LDB_SUCCESS
) {
1615 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1618 if (ret
== LDB_SUCCESS
) {
1619 ret
= ldb_transaction_commit(ldb_ctx
);
1621 ldb_transaction_cancel(ldb_ctx
);
1624 talloc_free(mem_ctx
);
1625 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1630 static PyObject
*py_ldb_schema_attribute_remove(PyLdbObject
*self
, PyObject
*args
)
1633 if (!PyArg_ParseTuple(args
, "s", &name
))
1636 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self
), name
);
1641 static PyObject
*py_ldb_schema_attribute_add(PyLdbObject
*self
, PyObject
*args
)
1643 char *attribute
, *syntax
;
1646 struct ldb_context
*ldb_ctx
;
1648 if (!PyArg_ParseTuple(args
, "sIs", &attribute
, &flags
, &syntax
))
1651 ldb_ctx
= pyldb_Ldb_AsLdbContext(self
);
1652 ret
= ldb_schema_attribute_add(ldb_ctx
, attribute
, flags
, syntax
);
1654 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1659 static PyObject
*ldb_ldif_to_pyobject(struct ldb_ldif
*ldif
)
1664 /* We don't want this attached to the 'ldb' any more */
1665 return Py_BuildValue(discard_const_p(char, "(iO)"),
1667 PyLdbMessage_FromMessage(ldif
->msg
));
1672 static PyObject
*py_ldb_write_ldif(PyLdbObject
*self
, PyObject
*args
)
1676 struct ldb_ldif ldif
;
1679 TALLOC_CTX
*mem_ctx
;
1681 if (!PyArg_ParseTuple(args
, "Oi", &py_msg
, &changetype
))
1684 if (!PyLdbMessage_Check(py_msg
)) {
1685 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for msg");
1689 ldif
.msg
= pyldb_Message_AsMessage(py_msg
);
1690 ldif
.changetype
= changetype
;
1692 mem_ctx
= talloc_new(NULL
);
1694 string
= ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self
), mem_ctx
, &ldif
);
1696 PyErr_SetString(PyExc_KeyError
, "Failed to generate LDIF");
1700 ret
= PyStr_FromString(string
);
1702 talloc_free(mem_ctx
);
1707 static PyObject
*py_ldb_parse_ldif(PyLdbObject
*self
, PyObject
*args
)
1709 PyObject
*list
, *ret
;
1710 struct ldb_ldif
*ldif
;
1712 struct ldb_dn
*last_dn
= NULL
;
1714 TALLOC_CTX
*mem_ctx
;
1716 if (!PyArg_ParseTuple(args
, "s", &s
))
1719 mem_ctx
= talloc_new(NULL
);
1724 list
= PyList_New(0);
1725 while (s
&& *s
!= '\0') {
1726 ldif
= ldb_ldif_read_string(self
->ldb_ctx
, &s
);
1727 talloc_steal(mem_ctx
, ldif
);
1729 PyList_Append(list
, ldb_ldif_to_pyobject(ldif
));
1730 last_dn
= ldif
->msg
->dn
;
1732 const char *last_dn_str
= NULL
;
1733 const char *err_string
= NULL
;
1734 if (last_dn
== NULL
) {
1735 PyErr_SetString(PyExc_ValueError
,
1736 "unable to parse LDIF "
1737 "string at first chunk");
1738 talloc_free(mem_ctx
);
1743 = ldb_dn_get_linearized(last_dn
);
1746 = talloc_asprintf(mem_ctx
,
1747 "unable to parse ldif "
1751 PyErr_SetString(PyExc_ValueError
,
1753 talloc_free(mem_ctx
);
1757 talloc_free(mem_ctx
); /* The pyobject already has a reference to the things it needs */
1758 ret
= PyObject_GetIter(list
);
1763 static PyObject
*py_ldb_msg_diff(PyLdbObject
*self
, PyObject
*args
)
1766 PyObject
*py_msg_old
;
1767 PyObject
*py_msg_new
;
1768 struct ldb_message
*diff
;
1769 struct ldb_context
*ldb
;
1772 if (!PyArg_ParseTuple(args
, "OO", &py_msg_old
, &py_msg_new
))
1775 if (!PyLdbMessage_Check(py_msg_old
)) {
1776 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for old message");
1780 if (!PyLdbMessage_Check(py_msg_new
)) {
1781 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for new message");
1785 ldb
= pyldb_Ldb_AsLdbContext(self
);
1786 ldb_ret
= ldb_msg_difference(ldb
, ldb
,
1787 pyldb_Message_AsMessage(py_msg_old
),
1788 pyldb_Message_AsMessage(py_msg_new
),
1790 if (ldb_ret
!= LDB_SUCCESS
) {
1791 PyErr_SetString(PyExc_RuntimeError
, "Failed to generate the Ldb Message diff");
1795 py_ret
= PyLdbMessage_FromMessage(diff
);
1797 talloc_unlink(ldb
, diff
);
1802 static PyObject
*py_ldb_schema_format_value(PyLdbObject
*self
, PyObject
*args
)
1804 const struct ldb_schema_attribute
*a
;
1805 struct ldb_val old_val
;
1806 struct ldb_val new_val
;
1807 TALLOC_CTX
*mem_ctx
;
1814 if (!PyArg_ParseTuple(args
, "sO", &element_name
, &val
))
1817 result
= PyBytes_AsStringAndSize(val
, (char **)&old_val
.data
, &size
);
1818 old_val
.length
= size
;
1821 PyErr_SetString(PyExc_RuntimeError
, "Failed to convert passed value to String");
1825 a
= ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self
), element_name
);
1831 mem_ctx
= talloc_new(NULL
);
1832 if (mem_ctx
== NULL
) {
1837 if (a
->syntax
->ldif_write_fn(pyldb_Ldb_AsLdbContext(self
), mem_ctx
, &old_val
, &new_val
) != 0) {
1838 talloc_free(mem_ctx
);
1842 ret
= PyBytes_FromStringAndSize((const char *)new_val
.data
, new_val
.length
);
1844 talloc_free(mem_ctx
);
1849 static PyObject
*py_ldb_search(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1851 PyObject
*py_base
= Py_None
;
1852 int scope
= LDB_SCOPE_DEFAULT
;
1854 PyObject
*py_attrs
= Py_None
;
1855 PyObject
*py_controls
= Py_None
;
1856 const char * const kwnames
[] = { "base", "scope", "expression", "attrs", "controls", NULL
};
1858 struct ldb_result
*res
;
1859 struct ldb_request
*req
;
1861 struct ldb_context
*ldb_ctx
;
1862 struct ldb_control
**parsed_controls
;
1863 struct ldb_dn
*base
;
1865 TALLOC_CTX
*mem_ctx
;
1867 /* type "int" rather than "enum" for "scope" is intentional */
1868 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OizOO",
1869 discard_const_p(char *, kwnames
),
1870 &py_base
, &scope
, &expr
, &py_attrs
, &py_controls
))
1874 mem_ctx
= talloc_new(NULL
);
1875 if (mem_ctx
== NULL
) {
1879 ldb_ctx
= pyldb_Ldb_AsLdbContext(self
);
1881 if (py_attrs
== Py_None
) {
1884 attrs
= PyList_AsStrList(mem_ctx
, py_attrs
, "attrs");
1885 if (attrs
== NULL
) {
1886 talloc_free(mem_ctx
);
1891 if (py_base
== Py_None
) {
1892 base
= ldb_get_default_basedn(ldb_ctx
);
1894 if (!pyldb_Object_AsDn(mem_ctx
, py_base
, ldb_ctx
, &base
)) {
1895 talloc_free(mem_ctx
);
1900 if (py_controls
== Py_None
) {
1901 parsed_controls
= NULL
;
1903 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1904 if (controls
== NULL
) {
1905 talloc_free(mem_ctx
);
1908 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1909 talloc_free(controls
);
1912 res
= talloc_zero(mem_ctx
, struct ldb_result
);
1915 talloc_free(mem_ctx
);
1919 ret
= ldb_build_search_req(&req
, ldb_ctx
, mem_ctx
,
1926 ldb_search_default_callback
,
1929 if (ret
!= LDB_SUCCESS
) {
1930 talloc_free(mem_ctx
);
1931 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1935 talloc_steal(req
, attrs
);
1937 ret
= ldb_request(ldb_ctx
, req
);
1939 if (ret
== LDB_SUCCESS
) {
1940 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1943 if (ret
!= LDB_SUCCESS
) {
1944 talloc_free(mem_ctx
);
1945 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1949 py_ret
= PyLdbResult_FromResult(res
);
1951 talloc_free(mem_ctx
);
1956 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply
*reply
)
1958 if (reply
->py_iter
!= NULL
) {
1959 DLIST_REMOVE(reply
->py_iter
->state
.next
, reply
);
1960 if (reply
->py_iter
->state
.result
== reply
) {
1961 reply
->py_iter
->state
.result
= NULL
;
1963 reply
->py_iter
= NULL
;
1966 if (reply
->obj
!= NULL
) {
1967 Py_DECREF(reply
->obj
);
1974 static int py_ldb_search_iterator_callback(struct ldb_request
*req
,
1975 struct ldb_reply
*ares
)
1977 PyLdbSearchIteratorObject
*py_iter
= (PyLdbSearchIteratorObject
*)req
->context
;
1978 struct ldb_result result
= { .msgs
= NULL
};
1979 struct py_ldb_search_iterator_reply
*reply
= NULL
;
1982 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
1985 if (ares
->error
!= LDB_SUCCESS
) {
1986 int ret
= ares
->error
;
1988 return ldb_request_done(req
, ret
);
1991 reply
= talloc_zero(py_iter
->mem_ctx
,
1992 struct py_ldb_search_iterator_reply
);
1993 if (reply
== NULL
) {
1995 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
1997 reply
->py_iter
= py_iter
;
1998 talloc_set_destructor(reply
, py_ldb_search_iterator_reply_destructor
);
2000 switch (ares
->type
) {
2001 case LDB_REPLY_ENTRY
:
2002 reply
->obj
= PyLdbMessage_FromMessage(ares
->message
);
2003 if (reply
->obj
== NULL
) {
2005 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2007 DLIST_ADD_END(py_iter
->state
.next
, reply
);
2011 case LDB_REPLY_REFERRAL
:
2012 reply
->obj
= PyStr_FromString(ares
->referral
);
2013 if (reply
->obj
== NULL
) {
2015 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2017 DLIST_ADD_END(py_iter
->state
.next
, reply
);
2021 case LDB_REPLY_DONE
:
2022 result
= (struct ldb_result
) { .controls
= ares
->controls
};
2023 reply
->obj
= PyLdbResult_FromResult(&result
);
2024 if (reply
->obj
== NULL
) {
2026 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2028 py_iter
->state
.result
= reply
;
2030 return ldb_request_done(req
, LDB_SUCCESS
);
2034 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2037 static PyObject
*py_ldb_search_iterator(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
2039 PyObject
*py_base
= Py_None
;
2040 int scope
= LDB_SCOPE_DEFAULT
;
2043 PyObject
*py_attrs
= Py_None
;
2044 PyObject
*py_controls
= Py_None
;
2045 const char * const kwnames
[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL
};
2048 struct ldb_context
*ldb_ctx
;
2049 struct ldb_control
**parsed_controls
;
2050 struct ldb_dn
*base
;
2051 PyLdbSearchIteratorObject
*py_iter
;
2053 /* type "int" rather than "enum" for "scope" is intentional */
2054 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OizOOi",
2055 discard_const_p(char *, kwnames
),
2056 &py_base
, &scope
, &expr
, &py_attrs
, &py_controls
, &timeout
))
2059 py_iter
= (PyLdbSearchIteratorObject
*)PyLdbSearchIterator
.tp_alloc(&PyLdbSearchIterator
, 0);
2060 if (py_iter
== NULL
) {
2064 py_iter
->ldb
= self
;
2066 ZERO_STRUCT(py_iter
->state
);
2067 py_iter
->mem_ctx
= talloc_new(NULL
);
2068 if (py_iter
->mem_ctx
== NULL
) {
2074 ldb_ctx
= pyldb_Ldb_AsLdbContext(self
);
2076 if (py_attrs
== Py_None
) {
2079 attrs
= PyList_AsStrList(py_iter
->mem_ctx
, py_attrs
, "attrs");
2080 if (attrs
== NULL
) {
2087 if (py_base
== Py_None
) {
2088 base
= ldb_get_default_basedn(ldb_ctx
);
2090 if (!pyldb_Object_AsDn(py_iter
->mem_ctx
, py_base
, ldb_ctx
, &base
)) {
2097 if (py_controls
== Py_None
) {
2098 parsed_controls
= NULL
;
2100 const char **controls
= NULL
;
2102 controls
= PyList_AsStrList(py_iter
->mem_ctx
,
2103 py_controls
, "controls");
2104 if (controls
== NULL
) {
2110 parsed_controls
= ldb_parse_control_strings(ldb_ctx
,
2113 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
2118 talloc_free(controls
);
2121 ret
= ldb_build_search_req(&py_iter
->state
.req
,
2130 py_ldb_search_iterator_callback
,
2132 if (ret
!= LDB_SUCCESS
) {
2134 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2138 ldb_set_timeout(ldb_ctx
, py_iter
->state
.req
, timeout
);
2140 ret
= ldb_request(ldb_ctx
, py_iter
->state
.req
);
2141 if (ret
!= LDB_SUCCESS
) {
2143 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2147 return (PyObject
*)py_iter
;
2150 static PyObject
*py_ldb_get_opaque(PyLdbObject
*self
, PyObject
*args
)
2155 if (!PyArg_ParseTuple(args
, "s", &name
))
2158 data
= ldb_get_opaque(pyldb_Ldb_AsLdbContext(self
), name
);
2163 /* FIXME: More interpretation */
2168 static PyObject
*py_ldb_set_opaque(PyLdbObject
*self
, PyObject
*args
)
2173 if (!PyArg_ParseTuple(args
, "sO", &name
, &data
))
2176 /* FIXME: More interpretation */
2178 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self
), name
, data
);
2183 static PyObject
*py_ldb_modules(PyLdbObject
*self
)
2185 struct ldb_context
*ldb
= pyldb_Ldb_AsLdbContext(self
);
2186 PyObject
*ret
= PyList_New(0);
2187 struct ldb_module
*mod
;
2189 for (mod
= ldb
->modules
; mod
; mod
= mod
->next
) {
2190 PyList_Append(ret
, PyLdbModule_FromModule(mod
));
2196 static PyObject
*py_ldb_sequence_number(PyLdbObject
*self
, PyObject
*args
)
2198 struct ldb_context
*ldb
= pyldb_Ldb_AsLdbContext(self
);
2202 if (!PyArg_ParseTuple(args
, "i", &type
))
2205 /* FIXME: More interpretation */
2207 ret
= ldb_sequence_number(ldb
, type
, &value
);
2209 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2211 return PyLong_FromLongLong(value
);
2215 static const struct ldb_dn_extended_syntax test_dn_syntax
= {
2217 .read_fn
= ldb_handler_copy
,
2218 .write_clear_fn
= ldb_handler_copy
,
2219 .write_hex_fn
= ldb_handler_copy
,
2222 static PyObject
*py_ldb_register_test_extensions(PyLdbObject
*self
)
2224 struct ldb_context
*ldb
= pyldb_Ldb_AsLdbContext(self
);
2227 ret
= ldb_dn_extended_add_syntax(ldb
, LDB_ATTR_FLAG_FIXED
, &test_dn_syntax
);
2229 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2235 static PyMethodDef py_ldb_methods
[] = {
2236 { "set_debug", (PyCFunction
)py_ldb_set_debug
, METH_VARARGS
,
2237 "S.set_debug(callback) -> None\n"
2238 "Set callback for LDB debug messages.\n"
2239 "The callback should accept a debug level and debug text." },
2240 { "set_create_perms", (PyCFunction
)py_ldb_set_create_perms
, METH_VARARGS
,
2241 "S.set_create_perms(mode) -> None\n"
2242 "Set mode to use when creating new LDB files." },
2243 { "set_modules_dir", (PyCFunction
)py_ldb_set_modules_dir
, METH_VARARGS
,
2244 "S.set_modules_dir(path) -> None\n"
2245 "Set path LDB should search for modules" },
2246 { "transaction_start", (PyCFunction
)py_ldb_transaction_start
, METH_NOARGS
,
2247 "S.transaction_start() -> None\n"
2248 "Start a new transaction." },
2249 { "transaction_prepare_commit", (PyCFunction
)py_ldb_transaction_prepare_commit
, METH_NOARGS
,
2250 "S.transaction_prepare_commit() -> None\n"
2251 "prepare to commit a new transaction (2-stage commit)." },
2252 { "transaction_commit", (PyCFunction
)py_ldb_transaction_commit
, METH_NOARGS
,
2253 "S.transaction_commit() -> None\n"
2254 "commit a new transaction." },
2255 { "transaction_cancel", (PyCFunction
)py_ldb_transaction_cancel
, METH_NOARGS
,
2256 "S.transaction_cancel() -> None\n"
2257 "cancel a new transaction." },
2258 { "setup_wellknown_attributes", (PyCFunction
)py_ldb_setup_wellknown_attributes
, METH_NOARGS
,
2260 { "get_root_basedn", (PyCFunction
)py_ldb_get_root_basedn
, METH_NOARGS
,
2262 { "get_schema_basedn", (PyCFunction
)py_ldb_get_schema_basedn
, METH_NOARGS
,
2264 { "get_default_basedn", (PyCFunction
)py_ldb_get_default_basedn
, METH_NOARGS
,
2266 { "get_config_basedn", (PyCFunction
)py_ldb_get_config_basedn
, METH_NOARGS
,
2268 { "connect", (PyCFunction
)py_ldb_connect
, METH_VARARGS
|METH_KEYWORDS
,
2269 "S.connect(url, flags=0, options=None) -> None\n"
2270 "Connect to a LDB URL." },
2271 { "modify", (PyCFunction
)py_ldb_modify
, METH_VARARGS
|METH_KEYWORDS
,
2272 "S.modify(message, controls=None, validate=False) -> None\n"
2273 "Modify an entry." },
2274 { "add", (PyCFunction
)py_ldb_add
, METH_VARARGS
|METH_KEYWORDS
,
2275 "S.add(message, controls=None) -> None\n"
2277 { "delete", (PyCFunction
)py_ldb_delete
, METH_VARARGS
|METH_KEYWORDS
,
2278 "S.delete(dn, controls=None) -> None\n"
2279 "Remove an entry." },
2280 { "rename", (PyCFunction
)py_ldb_rename
, METH_VARARGS
|METH_KEYWORDS
,
2281 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2282 "Rename an entry." },
2283 { "search", (PyCFunction
)py_ldb_search
, METH_VARARGS
|METH_KEYWORDS
,
2284 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2285 "Search in a database.\n"
2287 ":param base: Optional base DN to search\n"
2288 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2289 ":param expression: Optional search expression\n"
2290 ":param attrs: Attributes to return (defaults to all)\n"
2291 ":param controls: Optional list of controls\n"
2292 ":return: ldb.Result object\n"
2294 { "search_iterator", (PyCFunction
)py_ldb_search_iterator
, METH_VARARGS
|METH_KEYWORDS
,
2295 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2296 "Search in a database.\n"
2298 ":param base: Optional base DN to search\n"
2299 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2300 ":param expression: Optional search expression\n"
2301 ":param attrs: Attributes to return (defaults to all)\n"
2302 ":param controls: Optional list of controls\n"
2303 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2304 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2306 { "schema_attribute_remove", (PyCFunction
)py_ldb_schema_attribute_remove
, METH_VARARGS
,
2308 { "schema_attribute_add", (PyCFunction
)py_ldb_schema_attribute_add
, METH_VARARGS
,
2310 { "schema_format_value", (PyCFunction
)py_ldb_schema_format_value
, METH_VARARGS
,
2312 { "parse_ldif", (PyCFunction
)py_ldb_parse_ldif
, METH_VARARGS
,
2313 "S.parse_ldif(ldif) -> iter(messages)\n"
2314 "Parse a string formatted using LDIF." },
2315 { "write_ldif", (PyCFunction
)py_ldb_write_ldif
, METH_VARARGS
,
2316 "S.write_ldif(message, changetype) -> ldif\n"
2317 "Print the message as a string formatted using LDIF." },
2318 { "msg_diff", (PyCFunction
)py_ldb_msg_diff
, METH_VARARGS
,
2319 "S.msg_diff(Message) -> Message\n"
2320 "Return an LDB Message of the difference between two Message objects." },
2321 { "get_opaque", (PyCFunction
)py_ldb_get_opaque
, METH_VARARGS
,
2322 "S.get_opaque(name) -> value\n"
2323 "Get an opaque value set on this LDB connection. \n"
2324 ":note: The returned value may not be useful in Python."
2326 { "set_opaque", (PyCFunction
)py_ldb_set_opaque
, METH_VARARGS
,
2327 "S.set_opaque(name, value) -> None\n"
2328 "Set an opaque value on this LDB connection. \n"
2329 ":note: Passing incorrect values may cause crashes." },
2330 { "modules", (PyCFunction
)py_ldb_modules
, METH_NOARGS
,
2331 "S.modules() -> list\n"
2332 "Return the list of modules on this LDB connection " },
2333 { "sequence_number", (PyCFunction
)py_ldb_sequence_number
, METH_VARARGS
,
2334 "S.sequence_number(type) -> value\n"
2335 "Return the value of the sequence according to the requested type" },
2336 { "_register_test_extensions", (PyCFunction
)py_ldb_register_test_extensions
, METH_NOARGS
,
2337 "S._register_test_extensions() -> None\n"
2338 "Register internal extensions used in testing" },
2342 static PyObject
*PyLdbModule_FromModule(struct ldb_module
*mod
)
2344 PyLdbModuleObject
*ret
;
2346 ret
= (PyLdbModuleObject
*)PyLdbModule
.tp_alloc(&PyLdbModule
, 0);
2351 ret
->mem_ctx
= talloc_new(NULL
);
2352 ret
->mod
= talloc_reference(ret
->mem_ctx
, mod
);
2353 return (PyObject
*)ret
;
2356 static PyObject
*py_ldb_get_firstmodule(PyLdbObject
*self
, void *closure
)
2358 struct ldb_module
*mod
= pyldb_Ldb_AsLdbContext(self
)->modules
;
2362 return PyLdbModule_FromModule(mod
);
2365 static PyGetSetDef py_ldb_getset
[] = {
2366 { discard_const_p(char, "firstmodule"), (getter
)py_ldb_get_firstmodule
, NULL
, NULL
},
2370 static int py_ldb_contains(PyLdbObject
*self
, PyObject
*obj
)
2372 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AsLdbContext(self
);
2374 struct ldb_result
*result
;
2378 if (!pyldb_Object_AsDn(ldb_ctx
, obj
, ldb_ctx
, &dn
)) {
2382 ret
= ldb_search(ldb_ctx
, ldb_ctx
, &result
, dn
, LDB_SCOPE_BASE
, NULL
,
2384 if (ret
!= LDB_SUCCESS
) {
2385 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2389 count
= result
->count
;
2391 talloc_free(result
);
2394 PyErr_Format(PyExc_RuntimeError
,
2395 "Searching for [%s] dn gave %u results!",
2396 ldb_dn_get_linearized(dn
),
2404 static PySequenceMethods py_ldb_seq
= {
2405 .sq_contains
= (objobjproc
)py_ldb_contains
,
2408 static PyObject
*PyLdb_FromLdbContext(struct ldb_context
*ldb_ctx
)
2412 ret
= (PyLdbObject
*)PyLdb
.tp_alloc(&PyLdb
, 0);
2417 ret
->mem_ctx
= talloc_new(NULL
);
2418 ret
->ldb_ctx
= talloc_reference(ret
->mem_ctx
, ldb_ctx
);
2419 return (PyObject
*)ret
;
2422 static void py_ldb_dealloc(PyLdbObject
*self
)
2424 talloc_free(self
->mem_ctx
);
2425 Py_TYPE(self
)->tp_free(self
);
2428 static PyTypeObject PyLdb
= {
2429 .tp_name
= "ldb.Ldb",
2430 .tp_methods
= py_ldb_methods
,
2431 .tp_repr
= (reprfunc
)py_ldb_repr
,
2432 .tp_new
= py_ldb_new
,
2433 .tp_init
= (initproc
)py_ldb_init
,
2434 .tp_dealloc
= (destructor
)py_ldb_dealloc
,
2435 .tp_getset
= py_ldb_getset
,
2436 .tp_getattro
= PyObject_GenericGetAttr
,
2437 .tp_basicsize
= sizeof(PyLdbObject
),
2438 .tp_doc
= "Connection to a LDB database.",
2439 .tp_as_sequence
= &py_ldb_seq
,
2440 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
2443 static void py_ldb_result_dealloc(PyLdbResultObject
*self
)
2445 talloc_free(self
->mem_ctx
);
2446 Py_DECREF(self
->msgs
);
2447 Py_DECREF(self
->referals
);
2448 Py_DECREF(self
->controls
);
2449 Py_TYPE(self
)->tp_free(self
);
2452 static PyObject
*py_ldb_result_get_msgs(PyLdbResultObject
*self
, void *closure
)
2454 Py_INCREF(self
->msgs
);
2458 static PyObject
*py_ldb_result_get_controls(PyLdbResultObject
*self
, void *closure
)
2460 Py_INCREF(self
->controls
);
2461 return self
->controls
;
2464 static PyObject
*py_ldb_result_get_referals(PyLdbResultObject
*self
, void *closure
)
2466 Py_INCREF(self
->referals
);
2467 return self
->referals
;
2470 static PyObject
*py_ldb_result_get_count(PyLdbResultObject
*self
, void *closure
)
2473 if (self
->msgs
== NULL
) {
2474 PyErr_SetString(PyExc_AttributeError
, "Count attribute is meaningless in this context");
2477 size
= PyList_Size(self
->msgs
);
2478 return PyInt_FromLong(size
);
2481 static PyGetSetDef py_ldb_result_getset
[] = {
2482 { discard_const_p(char, "controls"), (getter
)py_ldb_result_get_controls
, NULL
, NULL
},
2483 { discard_const_p(char, "msgs"), (getter
)py_ldb_result_get_msgs
, NULL
, NULL
},
2484 { discard_const_p(char, "referals"), (getter
)py_ldb_result_get_referals
, NULL
, NULL
},
2485 { discard_const_p(char, "count"), (getter
)py_ldb_result_get_count
, NULL
, NULL
},
2489 static PyObject
*py_ldb_result_iter(PyLdbResultObject
*self
)
2491 return PyObject_GetIter(self
->msgs
);
2494 static Py_ssize_t
py_ldb_result_len(PyLdbResultObject
*self
)
2496 return PySequence_Size(self
->msgs
);
2499 static PyObject
*py_ldb_result_find(PyLdbResultObject
*self
, Py_ssize_t idx
)
2501 return PySequence_GetItem(self
->msgs
, idx
);
2504 static PySequenceMethods py_ldb_result_seq
= {
2505 .sq_length
= (lenfunc
)py_ldb_result_len
,
2506 .sq_item
= (ssizeargfunc
)py_ldb_result_find
,
2509 static PyObject
*py_ldb_result_repr(PyLdbObject
*self
)
2511 return PyStr_FromString("<ldb result>");
2515 static PyTypeObject PyLdbResult
= {
2516 .tp_name
= "ldb.Result",
2517 .tp_repr
= (reprfunc
)py_ldb_result_repr
,
2518 .tp_dealloc
= (destructor
)py_ldb_result_dealloc
,
2519 .tp_iter
= (getiterfunc
)py_ldb_result_iter
,
2520 .tp_getset
= py_ldb_result_getset
,
2521 .tp_getattro
= PyObject_GenericGetAttr
,
2522 .tp_basicsize
= sizeof(PyLdbResultObject
),
2523 .tp_as_sequence
= &py_ldb_result_seq
,
2524 .tp_doc
= "LDB result.",
2525 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
2528 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject
*self
)
2530 Py_XDECREF(self
->state
.exception
);
2531 TALLOC_FREE(self
->mem_ctx
);
2532 ZERO_STRUCT(self
->state
);
2533 Py_DECREF(self
->ldb
);
2534 Py_TYPE(self
)->tp_free(self
);
2537 static PyObject
*py_ldb_search_iterator_next(PyLdbSearchIteratorObject
*self
)
2539 PyObject
*py_ret
= NULL
;
2541 if (self
->state
.req
== NULL
) {
2542 PyErr_SetString(PyExc_RuntimeError
,
2543 "ldb.SearchIterator request already finished");
2548 * TODO: do we want a non-blocking mode?
2549 * In future we may add an optional 'nonblocking'
2550 * argument to search_iterator().
2552 * For now we keep it simple and wait for at
2556 while (self
->state
.next
== NULL
) {
2559 if (self
->state
.result
!= NULL
) {
2561 * We (already) got a final result from the server.
2563 * We stop the iteration and let
2564 * py_ldb_search_iterator_result() will deliver
2565 * the result details.
2567 TALLOC_FREE(self
->state
.req
);
2568 PyErr_SetNone(PyExc_StopIteration
);
2572 ret
= ldb_wait(self
->state
.req
->handle
, LDB_WAIT_NONE
);
2573 if (ret
!= LDB_SUCCESS
) {
2574 struct ldb_context
*ldb_ctx
;
2575 TALLOC_FREE(self
->state
.req
);
2576 ldb_ctx
= pyldb_Ldb_AsLdbContext(self
->ldb
);
2578 * We stop the iteration and let
2579 * py_ldb_search_iterator_result() will deliver
2582 self
->state
.exception
= Py_BuildValue(discard_const_p(char, "(i,s)"),
2583 ret
, ldb_errstring(ldb_ctx
));
2584 PyErr_SetNone(PyExc_StopIteration
);
2589 py_ret
= self
->state
.next
->obj
;
2590 self
->state
.next
->obj
= NULL
;
2591 /* no TALLOC_FREE() as self->state.next is a list */
2592 talloc_free(self
->state
.next
);
2596 static PyObject
*py_ldb_search_iterator_result(PyLdbSearchIteratorObject
*self
)
2598 PyObject
*py_ret
= NULL
;
2600 if (self
->state
.req
!= NULL
) {
2601 PyErr_SetString(PyExc_RuntimeError
,
2602 "ldb.SearchIterator request running");
2606 if (self
->state
.next
!= NULL
) {
2607 PyErr_SetString(PyExc_RuntimeError
,
2608 "ldb.SearchIterator not fully consumed.");
2612 if (self
->state
.exception
!= NULL
) {
2613 PyErr_SetObject(PyExc_LdbError
, self
->state
.exception
);
2614 self
->state
.exception
= NULL
;
2618 if (self
->state
.result
== NULL
) {
2619 PyErr_SetString(PyExc_RuntimeError
,
2620 "ldb.SearchIterator result already consumed");
2624 py_ret
= self
->state
.result
->obj
;
2625 self
->state
.result
->obj
= NULL
;
2626 TALLOC_FREE(self
->state
.result
);
2630 static PyObject
*py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject
*self
)
2632 if (self
->state
.req
== NULL
) {
2633 PyErr_SetString(PyExc_RuntimeError
,
2634 "ldb.SearchIterator request already finished");
2638 Py_XDECREF(self
->state
.exception
);
2639 TALLOC_FREE(self
->mem_ctx
);
2640 ZERO_STRUCT(self
->state
);
2644 static PyMethodDef py_ldb_search_iterator_methods
[] = {
2645 { "result", (PyCFunction
)py_ldb_search_iterator_result
, METH_NOARGS
,
2646 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2647 { "abandon", (PyCFunction
)py_ldb_search_iterator_abandon
, METH_NOARGS
,
2652 static PyObject
*py_ldb_search_iterator_repr(PyLdbSearchIteratorObject
*self
)
2654 return PyStr_FromString("<ldb search iterator>");
2657 static PyTypeObject PyLdbSearchIterator
= {
2658 .tp_name
= "ldb.SearchIterator",
2659 .tp_repr
= (reprfunc
)py_ldb_search_iterator_repr
,
2660 .tp_dealloc
= (destructor
)py_ldb_search_iterator_dealloc
,
2661 .tp_iter
= PyObject_SelfIter
,
2662 .tp_iternext
= (iternextfunc
)py_ldb_search_iterator_next
,
2663 .tp_methods
= py_ldb_search_iterator_methods
,
2664 .tp_basicsize
= sizeof(PyLdbSearchIteratorObject
),
2665 .tp_doc
= "LDB search_iterator.",
2666 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
2669 static PyObject
*py_ldb_module_repr(PyLdbModuleObject
*self
)
2671 return PyStr_FromFormat("<ldb module '%s'>",
2672 pyldb_Module_AsModule(self
)->ops
->name
);
2675 static PyObject
*py_ldb_module_str(PyLdbModuleObject
*self
)
2677 return PyStr_FromString(pyldb_Module_AsModule(self
)->ops
->name
);
2680 static PyObject
*py_ldb_module_start_transaction(PyLdbModuleObject
*self
)
2682 pyldb_Module_AsModule(self
)->ops
->start_transaction(pyldb_Module_AsModule(self
));
2686 static PyObject
*py_ldb_module_end_transaction(PyLdbModuleObject
*self
)
2688 pyldb_Module_AsModule(self
)->ops
->end_transaction(pyldb_Module_AsModule(self
));
2692 static PyObject
*py_ldb_module_del_transaction(PyLdbModuleObject
*self
)
2694 pyldb_Module_AsModule(self
)->ops
->del_transaction(pyldb_Module_AsModule(self
));
2698 static PyObject
*py_ldb_module_search(PyLdbModuleObject
*self
, PyObject
*args
, PyObject
*kwargs
)
2700 PyObject
*py_base
, *py_tree
, *py_attrs
, *py_ret
;
2702 struct ldb_request
*req
;
2703 const char * const kwnames
[] = { "base", "scope", "tree", "attrs", NULL
};
2704 struct ldb_module
*mod
;
2705 const char * const*attrs
;
2707 /* type "int" rather than "enum" for "scope" is intentional */
2708 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O!iOO",
2709 discard_const_p(char *, kwnames
),
2710 &PyLdbDn
, &py_base
, &scope
, &py_tree
, &py_attrs
))
2715 if (py_attrs
== Py_None
) {
2718 attrs
= PyList_AsStrList(NULL
, py_attrs
, "attrs");
2723 ret
= ldb_build_search_req(&req
, mod
->ldb
, NULL
, pyldb_Dn_AsDn(py_base
),
2724 scope
, NULL
/* expr */, attrs
,
2725 NULL
/* controls */, NULL
, NULL
, NULL
);
2727 talloc_steal(req
, attrs
);
2729 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, mod
->ldb
);
2731 req
->op
.search
.res
= NULL
;
2733 ret
= mod
->ops
->search(mod
, req
);
2735 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, mod
->ldb
);
2737 py_ret
= PyLdbResult_FromResult(req
->op
.search
.res
);
2745 static PyObject
*py_ldb_module_add(PyLdbModuleObject
*self
, PyObject
*args
)
2747 struct ldb_request
*req
;
2748 PyObject
*py_message
;
2750 struct ldb_module
*mod
;
2752 if (!PyArg_ParseTuple(args
, "O!", &PyLdbMessage
, &py_message
))
2755 req
= talloc_zero(NULL
, struct ldb_request
);
2756 req
->operation
= LDB_ADD
;
2757 req
->op
.add
.message
= pyldb_Message_AsMessage(py_message
);
2759 mod
= pyldb_Module_AsModule(self
);
2760 ret
= mod
->ops
->add(mod
, req
);
2762 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, mod
->ldb
);
2767 static PyObject
*py_ldb_module_modify(PyLdbModuleObject
*self
, PyObject
*args
)
2770 struct ldb_request
*req
;
2771 PyObject
*py_message
;
2772 struct ldb_module
*mod
;
2774 if (!PyArg_ParseTuple(args
, "O!", &PyLdbMessage
, &py_message
))
2777 req
= talloc_zero(NULL
, struct ldb_request
);
2778 req
->operation
= LDB_MODIFY
;
2779 req
->op
.mod
.message
= pyldb_Message_AsMessage(py_message
);
2781 mod
= pyldb_Module_AsModule(self
);
2782 ret
= mod
->ops
->modify(mod
, req
);
2784 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, mod
->ldb
);
2789 static PyObject
*py_ldb_module_delete(PyLdbModuleObject
*self
, PyObject
*args
)
2792 struct ldb_request
*req
;
2795 if (!PyArg_ParseTuple(args
, "O!", &PyLdbDn
, &py_dn
))
2798 req
= talloc_zero(NULL
, struct ldb_request
);
2799 req
->operation
= LDB_DELETE
;
2800 req
->op
.del
.dn
= pyldb_Dn_AsDn(py_dn
);
2802 ret
= pyldb_Module_AsModule(self
)->ops
->del(pyldb_Module_AsModule(self
), req
);
2804 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
2809 static PyObject
*py_ldb_module_rename(PyLdbModuleObject
*self
, PyObject
*args
)
2812 struct ldb_request
*req
;
2813 PyObject
*py_dn1
, *py_dn2
;
2815 if (!PyArg_ParseTuple(args
, "O!O!", &PyLdbDn
, &py_dn1
, &PyLdbDn
, &py_dn2
))
2818 req
= talloc_zero(NULL
, struct ldb_request
);
2820 req
->operation
= LDB_RENAME
;
2821 req
->op
.rename
.olddn
= pyldb_Dn_AsDn(py_dn1
);
2822 req
->op
.rename
.newdn
= pyldb_Dn_AsDn(py_dn2
);
2824 ret
= pyldb_Module_AsModule(self
)->ops
->rename(pyldb_Module_AsModule(self
), req
);
2826 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
2831 static PyMethodDef py_ldb_module_methods
[] = {
2832 { "search", (PyCFunction
)py_ldb_module_search
, METH_VARARGS
|METH_KEYWORDS
, NULL
},
2833 { "add", (PyCFunction
)py_ldb_module_add
, METH_VARARGS
, NULL
},
2834 { "modify", (PyCFunction
)py_ldb_module_modify
, METH_VARARGS
, NULL
},
2835 { "rename", (PyCFunction
)py_ldb_module_rename
, METH_VARARGS
, NULL
},
2836 { "delete", (PyCFunction
)py_ldb_module_delete
, METH_VARARGS
, NULL
},
2837 { "start_transaction", (PyCFunction
)py_ldb_module_start_transaction
, METH_NOARGS
, NULL
},
2838 { "end_transaction", (PyCFunction
)py_ldb_module_end_transaction
, METH_NOARGS
, NULL
},
2839 { "del_transaction", (PyCFunction
)py_ldb_module_del_transaction
, METH_NOARGS
, NULL
},
2843 static void py_ldb_module_dealloc(PyLdbModuleObject
*self
)
2845 talloc_free(self
->mem_ctx
);
2849 static PyTypeObject PyLdbModule
= {
2850 .tp_name
= "ldb.LdbModule",
2851 .tp_methods
= py_ldb_module_methods
,
2852 .tp_repr
= (reprfunc
)py_ldb_module_repr
,
2853 .tp_str
= (reprfunc
)py_ldb_module_str
,
2854 .tp_basicsize
= sizeof(PyLdbModuleObject
),
2855 .tp_dealloc
= (destructor
)py_ldb_module_dealloc
,
2856 .tp_flags
= Py_TPFLAGS_DEFAULT
,
2857 .tp_doc
= "LDB module (extension)",
2862 * Create a ldb_message_element from a Python object.
2864 * This will accept any sequence objects that contains strings, or
2867 * A reference to set_obj will be borrowed.
2869 * @param mem_ctx Memory context
2870 * @param set_obj Python object to convert
2871 * @param flags ldb_message_element flags to set
2872 * @param attr_name Name of the attribute
2873 * @return New ldb_message_element, allocated as child of mem_ctx
2875 static struct ldb_message_element
*PyObject_AsMessageElement(
2876 TALLOC_CTX
*mem_ctx
,
2879 const char *attr_name
)
2881 struct ldb_message_element
*me
;
2882 const char *msg
= NULL
;
2886 if (pyldb_MessageElement_Check(set_obj
)) {
2887 PyLdbMessageElementObject
*set_obj_as_me
= (PyLdbMessageElementObject
*)set_obj
;
2888 /* We have to talloc_reference() the memory context, not the pointer
2889 * which may not actually be it's own context */
2890 if (talloc_reference(mem_ctx
, set_obj_as_me
->mem_ctx
)) {
2891 return pyldb_MessageElement_AsMessageElement(set_obj
);
2896 me
= talloc(mem_ctx
, struct ldb_message_element
);
2902 me
->name
= talloc_strdup(me
, attr_name
);
2904 if (PyBytes_Check(set_obj
) || PyUnicode_Check(set_obj
)) {
2906 me
->values
= talloc_array(me
, struct ldb_val
, me
->num_values
);
2907 if (PyBytes_Check(set_obj
)) {
2909 result
= PyBytes_AsStringAndSize(set_obj
, &_msg
, &size
);
2916 msg
= PyStr_AsUTF8AndSize(set_obj
, &size
);
2922 me
->values
[0].data
= talloc_memdup(me
,
2923 (const uint8_t *)msg
,
2925 me
->values
[0].length
= size
;
2926 } else if (PySequence_Check(set_obj
)) {
2928 me
->num_values
= PySequence_Size(set_obj
);
2929 me
->values
= talloc_array(me
, struct ldb_val
, me
->num_values
);
2930 for (i
= 0; i
< me
->num_values
; i
++) {
2931 PyObject
*obj
= PySequence_GetItem(set_obj
, i
);
2932 if (PyBytes_Check(obj
)) {
2934 result
= PyBytes_AsStringAndSize(obj
, &_msg
, &size
);
2940 } else if (PyUnicode_Check(obj
)) {
2941 msg
= PyStr_AsUTF8AndSize(obj
, &size
);
2947 PyErr_Format(PyExc_TypeError
,
2948 "Expected string as element %zd in list", i
);
2952 me
->values
[i
].data
= talloc_memdup(me
,
2953 (const uint8_t *)msg
,
2955 me
->values
[i
].length
= size
;
2958 PyErr_Format(PyExc_TypeError
,
2959 "String or List type expected for '%s' attribute", attr_name
);
2968 static PyObject
*ldb_msg_element_to_set(struct ldb_context
*ldb_ctx
,
2969 struct ldb_message_element
*me
)
2974 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2975 result
= PyList_New(me
->num_values
);
2977 for (i
= 0; i
< me
->num_values
; i
++) {
2978 PyList_SetItem(result
, i
,
2979 PyObject_FromLdbValue(&me
->values
[i
]));
2985 static PyObject
*py_ldb_msg_element_get(PyLdbMessageElementObject
*self
, PyObject
*args
)
2988 if (!PyArg_ParseTuple(args
, "I", &i
))
2990 if (i
>= pyldb_MessageElement_AsMessageElement(self
)->num_values
)
2993 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self
)->values
[i
]));
2996 static PyObject
*py_ldb_msg_element_flags(PyLdbMessageElementObject
*self
, PyObject
*args
)
2998 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
2999 return PyInt_FromLong(el
->flags
);
3002 static PyObject
*py_ldb_msg_element_set_flags(PyLdbMessageElementObject
*self
, PyObject
*args
)
3005 struct ldb_message_element
*el
;
3006 if (!PyArg_ParseTuple(args
, "I", &flags
))
3009 el
= pyldb_MessageElement_AsMessageElement(self
);
3014 static PyMethodDef py_ldb_msg_element_methods
[] = {
3015 { "get", (PyCFunction
)py_ldb_msg_element_get
, METH_VARARGS
, NULL
},
3016 { "set_flags", (PyCFunction
)py_ldb_msg_element_set_flags
, METH_VARARGS
, NULL
},
3017 { "flags", (PyCFunction
)py_ldb_msg_element_flags
, METH_NOARGS
, NULL
},
3021 static Py_ssize_t
py_ldb_msg_element_len(PyLdbMessageElementObject
*self
)
3023 return pyldb_MessageElement_AsMessageElement(self
)->num_values
;
3026 static PyObject
*py_ldb_msg_element_find(PyLdbMessageElementObject
*self
, Py_ssize_t idx
)
3028 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3029 if (idx
< 0 || idx
>= el
->num_values
) {
3030 PyErr_SetString(PyExc_IndexError
, "Out of range");
3033 return PyLdbBytes_FromStringAndSize((char *)el
->values
[idx
].data
, el
->values
[idx
].length
);
3036 static PySequenceMethods py_ldb_msg_element_seq
= {
3037 .sq_length
= (lenfunc
)py_ldb_msg_element_len
,
3038 .sq_item
= (ssizeargfunc
)py_ldb_msg_element_find
,
3041 static PyObject
*py_ldb_msg_element_richcmp(PyObject
*self
, PyObject
*other
, int op
)
3044 if (!pyldb_MessageElement_Check(other
)) {
3045 Py_INCREF(Py_NotImplemented
);
3046 return Py_NotImplemented
;
3048 ret
= ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self
),
3049 pyldb_MessageElement_AsMessageElement(other
));
3050 return richcmp(ret
, op
);
3053 static PyObject
*py_ldb_msg_element_iter(PyLdbMessageElementObject
*self
)
3055 PyObject
*el
= ldb_msg_element_to_set(NULL
,
3056 pyldb_MessageElement_AsMessageElement(self
));
3057 PyObject
*ret
= PyObject_GetIter(el
);
3062 static PyObject
*PyLdbMessageElement_FromMessageElement(struct ldb_message_element
*el
, TALLOC_CTX
*mem_ctx
)
3064 PyLdbMessageElementObject
*ret
;
3065 ret
= PyObject_New(PyLdbMessageElementObject
, &PyLdbMessageElement
);
3070 ret
->mem_ctx
= talloc_new(NULL
);
3071 if (talloc_reference(ret
->mem_ctx
, mem_ctx
) == NULL
) {
3076 return (PyObject
*)ret
;
3079 static PyObject
*py_ldb_msg_element_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
3081 PyObject
*py_elements
= NULL
;
3082 struct ldb_message_element
*el
;
3083 unsigned int flags
= 0;
3085 const char * const kwnames
[] = { "elements", "flags", "name", NULL
};
3086 PyLdbMessageElementObject
*ret
;
3087 TALLOC_CTX
*mem_ctx
;
3088 const char *msg
= NULL
;
3092 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OIs",
3093 discard_const_p(char *, kwnames
),
3094 &py_elements
, &flags
, &name
))
3097 mem_ctx
= talloc_new(NULL
);
3098 if (mem_ctx
== NULL
) {
3103 el
= talloc_zero(mem_ctx
, struct ldb_message_element
);
3106 talloc_free(mem_ctx
);
3110 if (py_elements
!= NULL
) {
3112 if (PyBytes_Check(py_elements
) || PyUnicode_Check(py_elements
)) {
3115 el
->values
= talloc_array(el
, struct ldb_val
, 1);
3116 if (el
->values
== NULL
) {
3117 talloc_free(mem_ctx
);
3121 if (PyBytes_Check(py_elements
)) {
3122 result
= PyBytes_AsStringAndSize(py_elements
, &_msg
, &size
);
3125 msg
= PyStr_AsUTF8AndSize(py_elements
, &size
);
3126 result
= (msg
== NULL
) ? -1 : 0;
3129 talloc_free(mem_ctx
);
3132 el
->values
[0].data
= talloc_memdup(el
->values
,
3133 (const uint8_t *)msg
, size
+ 1);
3134 el
->values
[0].length
= size
;
3135 } else if (PySequence_Check(py_elements
)) {
3136 el
->num_values
= PySequence_Size(py_elements
);
3137 el
->values
= talloc_array(el
, struct ldb_val
, el
->num_values
);
3138 if (el
->values
== NULL
) {
3139 talloc_free(mem_ctx
);
3143 for (i
= 0; i
< el
->num_values
; i
++) {
3144 PyObject
*item
= PySequence_GetItem(py_elements
, i
);
3146 talloc_free(mem_ctx
);
3149 if (PyBytes_Check(item
)) {
3151 result
= PyBytes_AsStringAndSize(item
, &_msg
, &size
);
3153 } else if (PyUnicode_Check(item
)) {
3154 msg
= PyStr_AsUTF8AndSize(item
, &size
);
3155 result
= (msg
== NULL
) ? -1 : 0;
3157 PyErr_Format(PyExc_TypeError
,
3158 "Expected string as element %zd in list", i
);
3162 talloc_free(mem_ctx
);
3165 el
->values
[i
].data
= talloc_memdup(el
,
3166 (const uint8_t *)msg
, size
+1);
3167 el
->values
[i
].length
= size
;
3170 PyErr_SetString(PyExc_TypeError
,
3171 "Expected string or list");
3172 talloc_free(mem_ctx
);
3178 el
->name
= talloc_strdup(el
, name
);
3180 ret
= PyObject_New(PyLdbMessageElementObject
, type
);
3182 talloc_free(mem_ctx
);
3186 ret
->mem_ctx
= mem_ctx
;
3188 return (PyObject
*)ret
;
3191 static PyObject
*py_ldb_msg_element_repr(PyLdbMessageElementObject
*self
)
3193 char *element_str
= NULL
;
3195 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3196 PyObject
*ret
, *repr
;
3198 for (i
= 0; i
< el
->num_values
; i
++) {
3199 PyObject
*o
= py_ldb_msg_element_find(self
, i
);
3200 repr
= PyObject_Repr(o
);
3201 if (element_str
== NULL
)
3202 element_str
= talloc_strdup(NULL
, PyStr_AsUTF8(repr
));
3204 element_str
= talloc_asprintf_append(element_str
, ",%s", PyStr_AsUTF8(repr
));
3208 if (element_str
!= NULL
) {
3209 ret
= PyStr_FromFormat("MessageElement([%s])", element_str
);
3210 talloc_free(element_str
);
3212 ret
= PyStr_FromString("MessageElement([])");
3218 static PyObject
*py_ldb_msg_element_str(PyLdbMessageElementObject
*self
)
3220 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3222 if (el
->num_values
== 1)
3223 return PyStr_FromStringAndSize((char *)el
->values
[0].data
, el
->values
[0].length
);
3228 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject
*self
)
3230 talloc_free(self
->mem_ctx
);
3234 static PyObject
*py_ldb_msg_element_get_text(PyObject
*self
, void *closure
)
3236 return wrap_text("MessageElementTextWrapper", self
);
3239 static PyGetSetDef py_ldb_msg_element_getset
[] = {
3240 { discard_const_p(char, "text"), (getter
)py_ldb_msg_element_get_text
, NULL
, NULL
},
3244 static PyTypeObject PyLdbMessageElement
= {
3245 .tp_name
= "ldb.MessageElement",
3246 .tp_basicsize
= sizeof(PyLdbMessageElementObject
),
3247 .tp_dealloc
= (destructor
)py_ldb_msg_element_dealloc
,
3248 .tp_repr
= (reprfunc
)py_ldb_msg_element_repr
,
3249 .tp_str
= (reprfunc
)py_ldb_msg_element_str
,
3250 .tp_methods
= py_ldb_msg_element_methods
,
3251 .tp_getset
= py_ldb_msg_element_getset
,
3252 .tp_richcompare
= (richcmpfunc
)py_ldb_msg_element_richcmp
,
3253 .tp_iter
= (getiterfunc
)py_ldb_msg_element_iter
,
3254 .tp_as_sequence
= &py_ldb_msg_element_seq
,
3255 .tp_new
= py_ldb_msg_element_new
,
3256 .tp_flags
= Py_TPFLAGS_DEFAULT
,
3257 .tp_doc
= "An element of a Message",
3261 static PyObject
*py_ldb_msg_from_dict(PyTypeObject
*type
, PyObject
*args
)
3266 struct ldb_message
*msg
;
3267 struct ldb_context
*ldb_ctx
;
3268 unsigned int mod_flags
= LDB_FLAG_MOD_REPLACE
;
3270 if (!PyArg_ParseTuple(args
, "O!O!|I",
3271 &PyLdb
, &py_ldb
, &PyDict_Type
, &py_dict
,
3276 if (!PyLdb_Check(py_ldb
)) {
3277 PyErr_SetString(PyExc_TypeError
, "Expected Ldb");
3281 /* mask only flags we are going to use */
3282 mod_flags
= LDB_FLAG_MOD_TYPE(mod_flags
);
3284 PyErr_SetString(PyExc_ValueError
,
3285 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3286 " expected as mod_flag value");
3290 ldb_ctx
= pyldb_Ldb_AsLdbContext(py_ldb
);
3292 msg
= PyDict_AsMessage(ldb_ctx
, py_dict
, ldb_ctx
, mod_flags
);
3297 py_ret
= PyLdbMessage_FromMessage(msg
);
3299 talloc_unlink(ldb_ctx
, msg
);
3304 static PyObject
*py_ldb_msg_remove_attr(PyLdbMessageObject
*self
, PyObject
*args
)
3307 if (!PyArg_ParseTuple(args
, "s", &name
))
3310 ldb_msg_remove_attr(self
->msg
, name
);
3315 static PyObject
*py_ldb_msg_keys(PyLdbMessageObject
*self
)
3317 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3318 Py_ssize_t i
, j
= 0;
3319 PyObject
*obj
= PyList_New(msg
->num_elements
+(msg
->dn
!= NULL
?1:0));
3320 if (msg
->dn
!= NULL
) {
3321 PyList_SetItem(obj
, j
, PyStr_FromString("dn"));
3324 for (i
= 0; i
< msg
->num_elements
; i
++) {
3325 PyList_SetItem(obj
, j
, PyStr_FromString(msg
->elements
[i
].name
));
3331 static PyObject
*py_ldb_msg_getitem_helper(PyLdbMessageObject
*self
, PyObject
*py_name
)
3333 struct ldb_message_element
*el
;
3335 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3336 name
= PyStr_AsUTF8(py_name
);
3338 PyErr_SetNone(PyExc_TypeError
);
3341 if (!ldb_attr_cmp(name
, "dn"))
3342 return pyldb_Dn_FromDn(msg
->dn
);
3343 el
= ldb_msg_find_element(msg
, name
);
3347 return (PyObject
*)PyLdbMessageElement_FromMessageElement(el
, msg
->elements
);
3350 static PyObject
*py_ldb_msg_getitem(PyLdbMessageObject
*self
, PyObject
*py_name
)
3352 PyObject
*ret
= py_ldb_msg_getitem_helper(self
, py_name
);
3354 PyErr_SetString(PyExc_KeyError
, "No such element");
3360 static PyObject
*py_ldb_msg_get(PyLdbMessageObject
*self
, PyObject
*args
, PyObject
*kwargs
)
3362 PyObject
*def
= NULL
;
3363 const char *kwnames
[] = { "name", "default", "idx", NULL
};
3364 const char *name
= NULL
;
3366 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3367 struct ldb_message_element
*el
;
3369 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|Oi:msg",
3370 discard_const_p(char *, kwnames
), &name
, &def
, &idx
)) {
3374 if (strcasecmp(name
, "dn") == 0) {
3375 return pyldb_Dn_FromDn(msg
->dn
);
3378 el
= ldb_msg_find_element(msg
, name
);
3380 if (el
== NULL
|| (idx
!= -1 && el
->num_values
<= idx
)) {
3389 return (PyObject
*)PyLdbMessageElement_FromMessageElement(el
, msg
->elements
);
3392 return PyObject_FromLdbValue(&el
->values
[idx
]);
3395 static PyObject
*py_ldb_msg_items(PyLdbMessageObject
*self
)
3397 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3398 Py_ssize_t i
, j
= 0;
3399 PyObject
*l
= PyList_New(msg
->num_elements
+ (msg
->dn
== NULL
?0:1));
3400 if (msg
->dn
!= NULL
) {
3401 PyList_SetItem(l
, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg
->dn
)));
3404 for (i
= 0; i
< msg
->num_elements
; i
++, j
++) {
3405 PyObject
*py_el
= PyLdbMessageElement_FromMessageElement(&msg
->elements
[i
], msg
->elements
);
3406 PyObject
*value
= Py_BuildValue("(sO)", msg
->elements
[i
].name
, py_el
);
3407 PyList_SetItem(l
, j
, value
);
3412 static PyObject
*py_ldb_msg_elements(PyLdbMessageObject
*self
)
3414 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3416 PyObject
*l
= PyList_New(msg
->num_elements
);
3417 for (i
= 0; i
< msg
->num_elements
; i
++) {
3418 PyList_SetItem(l
, i
, PyLdbMessageElement_FromMessageElement(&msg
->elements
[i
], msg
->elements
));
3423 static PyObject
*py_ldb_msg_add(PyLdbMessageObject
*self
, PyObject
*args
)
3425 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3426 PyLdbMessageElementObject
*py_element
;
3428 struct ldb_message_element
*el
;
3429 struct ldb_message_element
*el_new
;
3431 if (!PyArg_ParseTuple(args
, "O!", &PyLdbMessageElement
, &py_element
))
3434 el
= py_element
->el
;
3436 PyErr_SetString(PyExc_ValueError
, "Invalid MessageElement object");
3440 ret
= ldb_msg_add_empty(msg
, el
->name
, el
->flags
, &el_new
);
3441 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
3443 /* now deep copy all attribute values */
3444 el_new
->values
= talloc_array(msg
->elements
, struct ldb_val
, el
->num_values
);
3445 if (el_new
->values
== NULL
) {
3449 el_new
->num_values
= el
->num_values
;
3451 for (i
= 0; i
< el
->num_values
; i
++) {
3452 el_new
->values
[i
] = ldb_val_dup(el_new
->values
, &el
->values
[i
]);
3453 if (el_new
->values
[i
].data
== NULL
3454 && el
->values
[i
].length
!= 0) {
3463 static PyMethodDef py_ldb_msg_methods
[] = {
3464 { "from_dict", (PyCFunction
)py_ldb_msg_from_dict
, METH_CLASS
| METH_VARARGS
,
3465 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
3466 "Class method to create ldb.Message object from Dictionary.\n"
3467 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3468 { "keys", (PyCFunction
)py_ldb_msg_keys
, METH_NOARGS
,
3469 "S.keys() -> list\n\n"
3470 "Return sequence of all attribute names." },
3471 { "remove", (PyCFunction
)py_ldb_msg_remove_attr
, METH_VARARGS
,
3472 "S.remove(name)\n\n"
3473 "Remove all entries for attributes with the specified name."},
3474 { "get", (PyCFunction
)py_ldb_msg_get
, METH_VARARGS
| METH_KEYWORDS
,
3475 "msg.get(name,default=None,idx=None) -> string\n"
3476 "idx is the index into the values array\n"
3477 "if idx is None, then a list is returned\n"
3478 "if idx is not None, then the element with that index is returned\n"
3479 "if you pass the special name 'dn' then the DN object is returned\n"},
3480 { "items", (PyCFunction
)py_ldb_msg_items
, METH_NOARGS
, NULL
},
3481 { "elements", (PyCFunction
)py_ldb_msg_elements
, METH_NOARGS
, NULL
},
3482 { "add", (PyCFunction
)py_ldb_msg_add
, METH_VARARGS
,
3483 "S.add(element)\n\n"
3484 "Add an element to this message." },
3488 static PyObject
*py_ldb_msg_iter(PyLdbMessageObject
*self
)
3490 PyObject
*list
, *iter
;
3492 list
= py_ldb_msg_keys(self
);
3493 iter
= PyObject_GetIter(list
);
3498 static int py_ldb_msg_setitem(PyLdbMessageObject
*self
, PyObject
*name
, PyObject
*value
)
3502 attr_name
= PyStr_AsUTF8(name
);
3503 if (attr_name
== NULL
) {
3504 PyErr_SetNone(PyExc_TypeError
);
3508 if (value
== NULL
) {
3510 ldb_msg_remove_attr(self
->msg
, attr_name
);
3513 struct ldb_message_element
*el
= PyObject_AsMessageElement(self
->msg
,
3514 value
, 0, attr_name
);
3518 ldb_msg_remove_attr(pyldb_Message_AsMessage(self
), attr_name
);
3519 ret
= ldb_msg_add(pyldb_Message_AsMessage(self
), el
, el
->flags
);
3520 if (ret
!= LDB_SUCCESS
) {
3521 PyErr_SetLdbError(PyExc_LdbError
, ret
, NULL
);
3528 static Py_ssize_t
py_ldb_msg_length(PyLdbMessageObject
*self
)
3530 return pyldb_Message_AsMessage(self
)->num_elements
;
3533 static PyMappingMethods py_ldb_msg_mapping
= {
3534 .mp_length
= (lenfunc
)py_ldb_msg_length
,
3535 .mp_subscript
= (binaryfunc
)py_ldb_msg_getitem
,
3536 .mp_ass_subscript
= (objobjargproc
)py_ldb_msg_setitem
,
3539 static PyObject
*py_ldb_msg_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
3541 const char * const kwnames
[] = { "dn", NULL
};
3542 struct ldb_message
*ret
;
3543 TALLOC_CTX
*mem_ctx
;
3544 PyObject
*pydn
= NULL
;
3545 PyLdbMessageObject
*py_ret
;
3547 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|O",
3548 discard_const_p(char *, kwnames
),
3552 mem_ctx
= talloc_new(NULL
);
3553 if (mem_ctx
== NULL
) {
3558 ret
= ldb_msg_new(mem_ctx
);
3560 talloc_free(mem_ctx
);
3567 if (!pyldb_Object_AsDn(NULL
, pydn
, NULL
, &dn
)) {
3568 talloc_free(mem_ctx
);
3571 ret
->dn
= talloc_reference(ret
, dn
);
3574 py_ret
= (PyLdbMessageObject
*)type
->tp_alloc(type
, 0);
3575 if (py_ret
== NULL
) {
3577 talloc_free(mem_ctx
);
3581 py_ret
->mem_ctx
= mem_ctx
;
3583 return (PyObject
*)py_ret
;
3586 static PyObject
*PyLdbMessage_FromMessage(struct ldb_message
*msg
)
3588 PyLdbMessageObject
*ret
;
3590 ret
= (PyLdbMessageObject
*)PyLdbMessage
.tp_alloc(&PyLdbMessage
, 0);
3595 ret
->mem_ctx
= talloc_new(NULL
);
3596 ret
->msg
= talloc_reference(ret
->mem_ctx
, msg
);
3597 return (PyObject
*)ret
;
3600 static PyObject
*py_ldb_msg_get_dn(PyLdbMessageObject
*self
, void *closure
)
3602 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3603 return pyldb_Dn_FromDn(msg
->dn
);
3606 static int py_ldb_msg_set_dn(PyLdbMessageObject
*self
, PyObject
*value
, void *closure
)
3608 struct ldb_message
*msg
= pyldb_Message_AsMessage(self
);
3609 if (!pyldb_Dn_Check(value
)) {
3610 PyErr_SetString(PyExc_TypeError
, "expected dn");
3614 msg
->dn
= talloc_reference(msg
, pyldb_Dn_AsDn(value
));
3618 static PyObject
*py_ldb_msg_get_text(PyObject
*self
, void *closure
)
3620 return wrap_text("MessageTextWrapper", self
);
3623 static PyGetSetDef py_ldb_msg_getset
[] = {
3624 { discard_const_p(char, "dn"), (getter
)py_ldb_msg_get_dn
, (setter
)py_ldb_msg_set_dn
, NULL
},
3625 { discard_const_p(char, "text"), (getter
)py_ldb_msg_get_text
, NULL
, NULL
},
3629 static PyObject
*py_ldb_msg_repr(PyLdbMessageObject
*self
)
3631 PyObject
*dict
= PyDict_New(), *ret
, *repr
;
3632 if (PyDict_Update(dict
, (PyObject
*)self
) != 0)
3634 repr
= PyObject_Repr(dict
);
3639 ret
= PyStr_FromFormat("Message(%s)", PyStr_AsUTF8(repr
));
3645 static void py_ldb_msg_dealloc(PyLdbMessageObject
*self
)
3647 talloc_free(self
->mem_ctx
);
3651 static PyObject
*py_ldb_msg_richcmp(PyLdbMessageObject
*py_msg1
,
3652 PyLdbMessageObject
*py_msg2
, int op
)
3654 struct ldb_message
*msg1
, *msg2
;
3658 if (!PyLdbMessage_Check(py_msg2
)) {
3659 Py_INCREF(Py_NotImplemented
);
3660 return Py_NotImplemented
;
3663 msg1
= pyldb_Message_AsMessage(py_msg1
),
3664 msg2
= pyldb_Message_AsMessage(py_msg2
);
3666 if ((msg1
->dn
!= NULL
) || (msg2
->dn
!= NULL
)) {
3667 ret
= ldb_dn_compare(msg1
->dn
, msg2
->dn
);
3669 return richcmp(ret
, op
);
3673 ret
= msg1
->num_elements
- msg2
->num_elements
;
3675 return richcmp(ret
, op
);
3678 for (i
= 0; i
< msg1
->num_elements
; i
++) {
3679 ret
= ldb_msg_element_compare_name(&msg1
->elements
[i
],
3680 &msg2
->elements
[i
]);
3682 return richcmp(ret
, op
);
3685 ret
= ldb_msg_element_compare(&msg1
->elements
[i
],
3686 &msg2
->elements
[i
]);
3688 return richcmp(ret
, op
);
3692 return richcmp(0, op
);
3695 static PyTypeObject PyLdbMessage
= {
3696 .tp_name
= "ldb.Message",
3697 .tp_methods
= py_ldb_msg_methods
,
3698 .tp_getset
= py_ldb_msg_getset
,
3699 .tp_as_mapping
= &py_ldb_msg_mapping
,
3700 .tp_basicsize
= sizeof(PyLdbMessageObject
),
3701 .tp_dealloc
= (destructor
)py_ldb_msg_dealloc
,
3702 .tp_new
= py_ldb_msg_new
,
3703 .tp_repr
= (reprfunc
)py_ldb_msg_repr
,
3704 .tp_flags
= Py_TPFLAGS_DEFAULT
,
3705 .tp_iter
= (getiterfunc
)py_ldb_msg_iter
,
3706 .tp_richcompare
= (richcmpfunc
)py_ldb_msg_richcmp
,
3707 .tp_doc
= "A LDB Message",
3710 static PyObject
*PyLdbTree_FromTree(struct ldb_parse_tree
*tree
)
3712 PyLdbTreeObject
*ret
;
3714 ret
= (PyLdbTreeObject
*)PyLdbTree
.tp_alloc(&PyLdbTree
, 0);
3720 ret
->mem_ctx
= talloc_new(NULL
);
3721 ret
->tree
= talloc_reference(ret
->mem_ctx
, tree
);
3722 return (PyObject
*)ret
;
3725 static void py_ldb_tree_dealloc(PyLdbTreeObject
*self
)
3727 talloc_free(self
->mem_ctx
);
3731 static PyTypeObject PyLdbTree
= {
3732 .tp_name
= "ldb.Tree",
3733 .tp_basicsize
= sizeof(PyLdbTreeObject
),
3734 .tp_dealloc
= (destructor
)py_ldb_tree_dealloc
,
3735 .tp_flags
= Py_TPFLAGS_DEFAULT
,
3736 .tp_doc
= "A search tree",
3740 static int py_module_search(struct ldb_module
*mod
, struct ldb_request
*req
)
3742 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3743 PyObject
*py_result
, *py_base
, *py_attrs
, *py_tree
;
3745 py_base
= pyldb_Dn_FromDn(req
->op
.search
.base
);
3747 if (py_base
== NULL
)
3748 return LDB_ERR_OPERATIONS_ERROR
;
3750 py_tree
= PyLdbTree_FromTree(req
->op
.search
.tree
);
3752 if (py_tree
== NULL
)
3753 return LDB_ERR_OPERATIONS_ERROR
;
3755 if (req
->op
.search
.attrs
== NULL
) {
3759 for (len
= 0; req
->op
.search
.attrs
[len
]; len
++);
3760 py_attrs
= PyList_New(len
);
3761 for (i
= 0; i
< len
; i
++)
3762 PyList_SetItem(py_attrs
, i
, PyStr_FromString(req
->op
.search
.attrs
[i
]));
3765 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "search"),
3766 discard_const_p(char, "OiOO"),
3767 py_base
, req
->op
.search
.scope
, py_tree
, py_attrs
);
3769 Py_DECREF(py_attrs
);
3773 if (py_result
== NULL
) {
3774 return LDB_ERR_PYTHON_EXCEPTION
;
3777 req
->op
.search
.res
= PyLdbResult_AsResult(NULL
, py_result
);
3778 if (req
->op
.search
.res
== NULL
) {
3779 return LDB_ERR_PYTHON_EXCEPTION
;
3782 Py_DECREF(py_result
);
3787 static int py_module_add(struct ldb_module
*mod
, struct ldb_request
*req
)
3789 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3790 PyObject
*py_result
, *py_msg
;
3792 py_msg
= PyLdbMessage_FromMessage(discard_const_p(struct ldb_message
, req
->op
.add
.message
));
3794 if (py_msg
== NULL
) {
3795 return LDB_ERR_OPERATIONS_ERROR
;
3798 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "add"),
3799 discard_const_p(char, "O"),
3804 if (py_result
== NULL
) {
3805 return LDB_ERR_PYTHON_EXCEPTION
;
3808 Py_DECREF(py_result
);
3813 static int py_module_modify(struct ldb_module
*mod
, struct ldb_request
*req
)
3815 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3816 PyObject
*py_result
, *py_msg
;
3818 py_msg
= PyLdbMessage_FromMessage(discard_const_p(struct ldb_message
, req
->op
.mod
.message
));
3820 if (py_msg
== NULL
) {
3821 return LDB_ERR_OPERATIONS_ERROR
;
3824 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "modify"),
3825 discard_const_p(char, "O"),
3830 if (py_result
== NULL
) {
3831 return LDB_ERR_PYTHON_EXCEPTION
;
3834 Py_DECREF(py_result
);
3839 static int py_module_del(struct ldb_module
*mod
, struct ldb_request
*req
)
3841 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3842 PyObject
*py_result
, *py_dn
;
3844 py_dn
= pyldb_Dn_FromDn(req
->op
.del
.dn
);
3847 return LDB_ERR_OPERATIONS_ERROR
;
3849 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "delete"),
3850 discard_const_p(char, "O"),
3853 if (py_result
== NULL
) {
3854 return LDB_ERR_PYTHON_EXCEPTION
;
3857 Py_DECREF(py_result
);
3862 static int py_module_rename(struct ldb_module
*mod
, struct ldb_request
*req
)
3864 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3865 PyObject
*py_result
, *py_olddn
, *py_newdn
;
3867 py_olddn
= pyldb_Dn_FromDn(req
->op
.rename
.olddn
);
3869 if (py_olddn
== NULL
)
3870 return LDB_ERR_OPERATIONS_ERROR
;
3872 py_newdn
= pyldb_Dn_FromDn(req
->op
.rename
.newdn
);
3874 if (py_newdn
== NULL
)
3875 return LDB_ERR_OPERATIONS_ERROR
;
3877 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "rename"),
3878 discard_const_p(char, "OO"),
3879 py_olddn
, py_newdn
);
3881 Py_DECREF(py_olddn
);
3882 Py_DECREF(py_newdn
);
3884 if (py_result
== NULL
) {
3885 return LDB_ERR_PYTHON_EXCEPTION
;
3888 Py_DECREF(py_result
);
3893 static int py_module_request(struct ldb_module
*mod
, struct ldb_request
*req
)
3895 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3896 PyObject
*py_result
;
3898 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "request"),
3899 discard_const_p(char, ""));
3901 Py_XDECREF(py_result
);
3903 return LDB_ERR_OPERATIONS_ERROR
;
3906 static int py_module_extended(struct ldb_module
*mod
, struct ldb_request
*req
)
3908 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3909 PyObject
*py_result
;
3911 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "extended"),
3912 discard_const_p(char, ""));
3914 Py_XDECREF(py_result
);
3916 return LDB_ERR_OPERATIONS_ERROR
;
3919 static int py_module_start_transaction(struct ldb_module
*mod
)
3921 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3922 PyObject
*py_result
;
3924 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "start_transaction"),
3925 discard_const_p(char, ""));
3927 if (py_result
== NULL
) {
3928 return LDB_ERR_PYTHON_EXCEPTION
;
3931 Py_DECREF(py_result
);
3936 static int py_module_end_transaction(struct ldb_module
*mod
)
3938 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3939 PyObject
*py_result
;
3941 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "end_transaction"),
3942 discard_const_p(char, ""));
3944 if (py_result
== NULL
) {
3945 return LDB_ERR_PYTHON_EXCEPTION
;
3948 Py_DECREF(py_result
);
3953 static int py_module_del_transaction(struct ldb_module
*mod
)
3955 PyObject
*py_ldb
= (PyObject
*)mod
->private_data
;
3956 PyObject
*py_result
;
3958 py_result
= PyObject_CallMethod(py_ldb
, discard_const_p(char, "del_transaction"),
3959 discard_const_p(char, ""));
3961 if (py_result
== NULL
) {
3962 return LDB_ERR_PYTHON_EXCEPTION
;
3965 Py_DECREF(py_result
);
3970 static int py_module_destructor(struct ldb_module
*mod
)
3972 Py_DECREF((PyObject
*)mod
->private_data
);
3976 static int py_module_init(struct ldb_module
*mod
)
3978 PyObject
*py_class
= (PyObject
*)mod
->ops
->private_data
;
3979 PyObject
*py_result
, *py_next
, *py_ldb
;
3981 py_ldb
= PyLdb_FromLdbContext(mod
->ldb
);
3984 return LDB_ERR_OPERATIONS_ERROR
;
3986 py_next
= PyLdbModule_FromModule(mod
->next
);
3988 if (py_next
== NULL
)
3989 return LDB_ERR_OPERATIONS_ERROR
;
3991 py_result
= PyObject_CallFunction(py_class
, discard_const_p(char, "OO"),
3994 if (py_result
== NULL
) {
3995 return LDB_ERR_PYTHON_EXCEPTION
;
3998 mod
->private_data
= py_result
;
4000 talloc_set_destructor(mod
, py_module_destructor
);
4002 return ldb_next_init(mod
);
4005 static PyObject
*py_register_module(PyObject
*module
, PyObject
*args
)
4008 struct ldb_module_ops
*ops
;
4011 if (!PyArg_ParseTuple(args
, "O", &input
))
4014 ops
= talloc_zero(NULL
, struct ldb_module_ops
);
4020 ops
->name
= talloc_strdup(ops
, PyStr_AsUTF8(PyObject_GetAttrString(input
, discard_const_p(char, "name"))));
4023 ops
->private_data
= input
;
4024 ops
->init_context
= py_module_init
;
4025 ops
->search
= py_module_search
;
4026 ops
->add
= py_module_add
;
4027 ops
->modify
= py_module_modify
;
4028 ops
->del
= py_module_del
;
4029 ops
->rename
= py_module_rename
;
4030 ops
->request
= py_module_request
;
4031 ops
->extended
= py_module_extended
;
4032 ops
->start_transaction
= py_module_start_transaction
;
4033 ops
->end_transaction
= py_module_end_transaction
;
4034 ops
->del_transaction
= py_module_del_transaction
;
4036 ret
= ldb_register_module(ops
);
4037 if (ret
!= LDB_SUCCESS
) {
4041 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
4046 static PyObject
*py_timestring(PyObject
*module
, PyObject
*args
)
4048 /* most times "time_t" is a signed integer type with 32 or 64 bit:
4049 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4053 if (!PyArg_ParseTuple(args
, "l", &t_val
))
4055 tresult
= ldb_timestring(NULL
, (time_t) t_val
);
4056 ret
= PyStr_FromString(tresult
);
4057 talloc_free(tresult
);
4061 static PyObject
*py_string_to_time(PyObject
*module
, PyObject
*args
)
4064 if (!PyArg_ParseTuple(args
, "s", &str
))
4067 return PyInt_FromLong(ldb_string_to_time(str
));
4070 static PyObject
*py_valid_attr_name(PyObject
*self
, PyObject
*args
)
4073 if (!PyArg_ParseTuple(args
, "s", &name
))
4075 return PyBool_FromLong(ldb_valid_attr_name(name
));
4079 encode a string using RFC2254 rules
4081 static PyObject
*py_binary_encode(PyObject
*self
, PyObject
*args
)
4083 char *str
, *encoded
;
4084 Py_ssize_t size
= 0;
4088 if (!PyArg_ParseTuple(args
, "s#", &str
, &size
))
4090 val
.data
= (uint8_t *)str
;
4093 encoded
= ldb_binary_encode(NULL
, val
);
4094 if (encoded
== NULL
) {
4095 PyErr_SetString(PyExc_TypeError
, "unable to encode binary string");
4098 ret
= PyStr_FromString(encoded
);
4099 talloc_free(encoded
);
4104 decode a string using RFC2254 rules
4106 static PyObject
*py_binary_decode(PyObject
*self
, PyObject
*args
)
4112 if (!PyArg_ParseTuple(args
, "s", &str
))
4115 val
= ldb_binary_decode(NULL
, str
);
4116 if (val
.data
== NULL
) {
4117 PyErr_SetString(PyExc_TypeError
, "unable to decode binary string");
4120 ret
= PyBytes_FromStringAndSize((const char*)val
.data
, val
.length
);
4121 talloc_free(val
.data
);
4125 static PyMethodDef py_ldb_global_methods
[] = {
4126 { "register_module", py_register_module
, METH_VARARGS
,
4127 "S.register_module(module) -> None\n\n"
4128 "Register a LDB module."},
4129 { "timestring", py_timestring
, METH_VARARGS
,
4130 "S.timestring(int) -> string\n\n"
4131 "Generate a LDAP time string from a UNIX timestamp" },
4132 { "string_to_time", py_string_to_time
, METH_VARARGS
,
4133 "S.string_to_time(string) -> int\n\n"
4134 "Parse a LDAP time string into a UNIX timestamp." },
4135 { "valid_attr_name", py_valid_attr_name
, METH_VARARGS
,
4136 "S.valid_attr_name(name) -> bool\n\nn"
4137 "Check whether the supplied name is a valid attribute name." },
4138 { "open", (PyCFunction
)py_ldb_new
, METH_VARARGS
|METH_KEYWORDS
,
4139 "S.open() -> Ldb\n\n"
4140 "Open a new LDB context." },
4141 { "binary_encode", py_binary_encode
, METH_VARARGS
,
4142 "S.binary_encode(string) -> string\n\n"
4143 "Perform a RFC2254 binary encoding on a string" },
4144 { "binary_decode", py_binary_decode
, METH_VARARGS
,
4145 "S.binary_decode(string) -> string\n\n"
4146 "Perform a RFC2254 binary decode on a string" },
4150 #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."
4152 #if PY_MAJOR_VERSION >= 3
4153 static struct PyModuleDef moduledef
= {
4154 PyModuleDef_HEAD_INIT
,
4156 .m_doc
= MODULE_DOC
,
4158 .m_methods
= py_ldb_global_methods
,
4162 static PyObject
* module_init(void)
4166 PyLdbBytesType
.tp_base
= &PyBytes_Type
;
4167 if (PyType_Ready(&PyLdbBytesType
) < 0) {
4171 if (PyType_Ready(&PyLdbDn
) < 0)
4174 if (PyType_Ready(&PyLdbMessage
) < 0)
4177 if (PyType_Ready(&PyLdbMessageElement
) < 0)
4180 if (PyType_Ready(&PyLdb
) < 0)
4183 if (PyType_Ready(&PyLdbModule
) < 0)
4186 if (PyType_Ready(&PyLdbTree
) < 0)
4189 if (PyType_Ready(&PyLdbResult
) < 0)
4192 if (PyType_Ready(&PyLdbSearchIterator
) < 0)
4195 if (PyType_Ready(&PyLdbControl
) < 0)
4198 #if PY_MAJOR_VERSION >= 3
4199 m
= PyModule_Create(&moduledef
);
4201 m
= Py_InitModule3("ldb", py_ldb_global_methods
, MODULE_DOC
);
4206 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4208 ADD_LDB_INT(SEQ_HIGHEST_SEQ
);
4209 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP
);
4210 ADD_LDB_INT(SEQ_NEXT
);
4211 ADD_LDB_INT(SCOPE_DEFAULT
);
4212 ADD_LDB_INT(SCOPE_BASE
);
4213 ADD_LDB_INT(SCOPE_ONELEVEL
);
4214 ADD_LDB_INT(SCOPE_SUBTREE
);
4216 ADD_LDB_INT(CHANGETYPE_NONE
);
4217 ADD_LDB_INT(CHANGETYPE_ADD
);
4218 ADD_LDB_INT(CHANGETYPE_DELETE
);
4219 ADD_LDB_INT(CHANGETYPE_MODIFY
);
4221 ADD_LDB_INT(FLAG_MOD_ADD
);
4222 ADD_LDB_INT(FLAG_MOD_REPLACE
);
4223 ADD_LDB_INT(FLAG_MOD_DELETE
);
4225 ADD_LDB_INT(ATTR_FLAG_HIDDEN
);
4226 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX
);
4227 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE
);
4228 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF
);
4230 ADD_LDB_INT(SUCCESS
);
4231 ADD_LDB_INT(ERR_OPERATIONS_ERROR
);
4232 ADD_LDB_INT(ERR_PROTOCOL_ERROR
);
4233 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED
);
4234 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED
);
4235 ADD_LDB_INT(ERR_COMPARE_FALSE
);
4236 ADD_LDB_INT(ERR_COMPARE_TRUE
);
4237 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED
);
4238 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED
);
4239 ADD_LDB_INT(ERR_REFERRAL
);
4240 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED
);
4241 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION
);
4242 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED
);
4243 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS
);
4244 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE
);
4245 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE
);
4246 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING
);
4247 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION
);
4248 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS
);
4249 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX
);
4250 ADD_LDB_INT(ERR_NO_SUCH_OBJECT
);
4251 ADD_LDB_INT(ERR_ALIAS_PROBLEM
);
4252 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX
);
4253 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM
);
4254 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION
);
4255 ADD_LDB_INT(ERR_INVALID_CREDENTIALS
);
4256 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS
);
4257 ADD_LDB_INT(ERR_BUSY
);
4258 ADD_LDB_INT(ERR_UNAVAILABLE
);
4259 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM
);
4260 ADD_LDB_INT(ERR_LOOP_DETECT
);
4261 ADD_LDB_INT(ERR_NAMING_VIOLATION
);
4262 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION
);
4263 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF
);
4264 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN
);
4265 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS
);
4266 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED
);
4267 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS
);
4268 ADD_LDB_INT(ERR_OTHER
);
4270 ADD_LDB_INT(FLG_RDONLY
);
4271 ADD_LDB_INT(FLG_NOSYNC
);
4272 ADD_LDB_INT(FLG_RECONNECT
);
4273 ADD_LDB_INT(FLG_NOMMAP
);
4274 ADD_LDB_INT(FLG_SHOW_BINARY
);
4275 ADD_LDB_INT(FLG_ENABLE_TRACING
);
4276 ADD_LDB_INT(FLG_DONT_CREATE_DB
);
4279 /* Historical misspelling */
4280 PyModule_AddIntConstant(m
, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM
);
4282 PyModule_AddStringConstant(m
, "__docformat__", "restructuredText");
4284 PyExc_LdbError
= PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL
, NULL
);
4285 PyModule_AddObject(m
, "LdbError", PyExc_LdbError
);
4288 Py_INCREF(&PyLdbDn
);
4289 Py_INCREF(&PyLdbModule
);
4290 Py_INCREF(&PyLdbMessage
);
4291 Py_INCREF(&PyLdbMessageElement
);
4292 Py_INCREF(&PyLdbTree
);
4293 Py_INCREF(&PyLdbResult
);
4294 Py_INCREF(&PyLdbControl
);
4296 PyModule_AddObject(m
, "Ldb", (PyObject
*)&PyLdb
);
4297 PyModule_AddObject(m
, "Dn", (PyObject
*)&PyLdbDn
);
4298 PyModule_AddObject(m
, "Message", (PyObject
*)&PyLdbMessage
);
4299 PyModule_AddObject(m
, "MessageElement", (PyObject
*)&PyLdbMessageElement
);
4300 PyModule_AddObject(m
, "Module", (PyObject
*)&PyLdbModule
);
4301 PyModule_AddObject(m
, "Tree", (PyObject
*)&PyLdbTree
);
4302 PyModule_AddObject(m
, "Control", (PyObject
*)&PyLdbControl
);
4304 PyModule_AddStringConstant(m
, "__version__", PACKAGE_VERSION
);
4306 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4308 ADD_LDB_STRING(SYNTAX_DN
);
4309 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING
);
4310 ADD_LDB_STRING(SYNTAX_INTEGER
);
4311 ADD_LDB_STRING(SYNTAX_BOOLEAN
);
4312 ADD_LDB_STRING(SYNTAX_OCTET_STRING
);
4313 ADD_LDB_STRING(SYNTAX_UTC_TIME
);
4314 ADD_LDB_STRING(OID_COMPARATOR_AND
);
4315 ADD_LDB_STRING(OID_COMPARATOR_OR
);
4320 #if PY_MAJOR_VERSION >= 3
4321 PyMODINIT_FUNC
PyInit_ldb(void);
4322 PyMODINIT_FUNC
PyInit_ldb(void)
4324 return module_init();