2 Unix SMB/CIFS implementation.
4 Python interface to ldb.
6 Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7 Copyright (C) 2006 Simo Sorce <idra@samba.org>
8 Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
9 Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10 Copyright (C) 2009-2011 Andrew Tridgell
11 Copyright (C) 2009-2011 Andrew Bartlett
13 ** NOTE! The following LGPL license applies to the ldb
14 ** library. This does NOT imply that all of Samba is released
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of the GNU Lesser General Public
19 License as published by the Free Software Foundation; either
20 version 3 of the License, or (at your option) any later version.
22 This library is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Lesser General Public License for more details.
27 You should have received a copy of the GNU Lesser General Public
28 License along with this library; if not, see <http://www.gnu.org/licenses/>.
31 #include "lib/replace/system/python.h"
32 #include "ldb_private.h"
33 #include "ldb_handlers.h"
35 #include "dlinklist.h"
37 /* discard signature of 'func' in favour of 'target_sig' */
38 #define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func
40 struct py_ldb_search_iterator_reply
;
47 struct ldb_request
*req
;
48 struct py_ldb_search_iterator_reply
*next
;
49 struct py_ldb_search_iterator_reply
*result
;
52 } PyLdbSearchIteratorObject
;
54 struct py_ldb_search_iterator_reply
{
55 struct py_ldb_search_iterator_reply
*prev
, *next
;
56 PyLdbSearchIteratorObject
*py_iter
;
60 static PyObject
*PyLdbMessage_FromMessage(struct ldb_message
*msg
, PyLdbObject
*pyldb
);
61 static PyObject
*PyExc_LdbError
;
63 static PyTypeObject PyLdbControl
;
64 static PyTypeObject PyLdbResult
;
65 static PyTypeObject PyLdbSearchIterator
;
66 static PyTypeObject PyLdbMessage
;
67 #define pyldb_Message_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
68 static PyTypeObject PyLdbDn
;
69 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
70 static PyTypeObject PyLdb
;
71 static PyTypeObject PyLdbMessageElement
;
72 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
74 static PyTypeObject PyLdbTree
;
75 static struct ldb_message_element
*PyObject_AsMessageElement(
79 const char *attr_name
);
80 static PyTypeObject PyLdbBytesType
;
82 #define PYARG_STR_UNI "es"
84 static PyObject
*PyLdbBytes_FromStringAndSize(const char *msg
, int size
)
86 PyObject
* result
= NULL
;
87 PyObject
* args
= NULL
;
88 args
= Py_BuildValue("(y#)", msg
, size
);
92 result
= PyLdbBytesType
.tp_new(&PyLdbBytesType
, args
, NULL
);
97 static PyObject
*richcmp(int cmp_val
, int op
)
101 case Py_LT
: ret
= cmp_val
< 0; break;
102 case Py_LE
: ret
= cmp_val
<= 0; break;
103 case Py_EQ
: ret
= cmp_val
== 0; break;
104 case Py_NE
: ret
= cmp_val
!= 0; break;
105 case Py_GT
: ret
= cmp_val
> 0; break;
106 case Py_GE
: ret
= cmp_val
>= 0; break;
108 Py_INCREF(Py_NotImplemented
);
109 return Py_NotImplemented
;
111 return PyBool_FromLong(ret
);
115 static PyObject
*py_ldb_control_str(PyLdbControlObject
*self
)
117 if (self
->data
!= NULL
) {
118 char* control
= ldb_control_to_string(self
->mem_ctx
, self
->data
);
119 if (control
== NULL
) {
123 return PyUnicode_FromString(control
);
125 return PyUnicode_FromString("ldb control");
129 static void py_ldb_control_dealloc(PyLdbControlObject
*self
)
131 if (self
->mem_ctx
!= NULL
) {
132 talloc_free(self
->mem_ctx
);
135 Py_TYPE(self
)->tp_free(self
);
138 /* Create a text (rather than bytes) interface for a LDB result object */
139 static PyObject
*wrap_text(const char *type
, PyObject
*wrapped
)
141 PyObject
*mod
, *cls
, *constructor
, *inst
;
142 mod
= PyImport_ImportModule("_ldb_text");
145 cls
= PyObject_GetAttrString(mod
, type
);
151 constructor
= PyObject_GetAttrString(cls
, "_wrap");
153 if (constructor
== NULL
) {
156 inst
= PyObject_CallFunction(constructor
, discard_const_p(char, "O"), wrapped
);
157 Py_DECREF(constructor
);
161 static PyObject
*py_ldb_control_get_oid(PyLdbControlObject
*self
,
162 PyObject
*Py_UNUSED(ignored
))
164 return PyUnicode_FromString(self
->data
->oid
);
167 static PyObject
*py_ldb_control_get_critical(PyLdbControlObject
*self
,
168 PyObject
*Py_UNUSED(ignored
))
170 return PyBool_FromLong(self
->data
->critical
);
173 static int py_ldb_control_set_critical(PyLdbControlObject
*self
, PyObject
*value
, void *closure
)
176 PyErr_SetString(PyExc_AttributeError
, "cannot delete critical flag");
179 if (PyObject_IsTrue(value
)) {
180 self
->data
->critical
= true;
182 self
->data
->critical
= false;
187 static PyObject
*py_ldb_control_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
190 const char * const kwnames
[] = { "ldb", "data", NULL
};
191 struct ldb_control
*parsed_controls
;
192 PyLdbControlObject
*ret
;
195 struct ldb_context
*ldb_ctx
;
197 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O!s",
198 discard_const_p(char *, kwnames
),
199 &PyLdb
, &py_ldb
, &data
))
202 mem_ctx
= talloc_new(NULL
);
203 if (mem_ctx
== NULL
) {
208 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(py_ldb
);
209 parsed_controls
= ldb_parse_control_from_string(ldb_ctx
, mem_ctx
, data
);
211 if (!parsed_controls
) {
212 talloc_free(mem_ctx
);
213 PyErr_SetString(PyExc_ValueError
, "unable to parse control string");
217 ret
= PyObject_New(PyLdbControlObject
, type
);
220 talloc_free(mem_ctx
);
224 ret
->mem_ctx
= mem_ctx
;
226 ret
->data
= talloc_move(mem_ctx
, &parsed_controls
);
227 if (ret
->data
== NULL
) {
230 talloc_free(mem_ctx
);
234 return (PyObject
*)ret
;
237 static PyGetSetDef py_ldb_control_getset
[] = {
239 .name
= discard_const_p(char, "oid"),
240 .get
= (getter
)py_ldb_control_get_oid
,
243 .name
= discard_const_p(char, "critical"),
244 .get
= (getter
)py_ldb_control_get_critical
,
245 .set
= (setter
)py_ldb_control_set_critical
,
250 static PyTypeObject PyLdbControl
= {
251 .tp_name
= "ldb.control",
252 .tp_dealloc
= (destructor
)py_ldb_control_dealloc
,
253 .tp_getattro
= PyObject_GenericGetAttr
,
254 .tp_basicsize
= sizeof(PyLdbControlObject
),
255 .tp_getset
= py_ldb_control_getset
,
256 .tp_doc
= "LDB control.",
257 .tp_str
= (reprfunc
)py_ldb_control_str
,
258 .tp_new
= py_ldb_control_new
,
259 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
262 static PyObject
*py_ldb_bytes_str(PyBytesObject
*self
)
267 if (!PyBytes_Check(self
)) {
268 PyErr_Format(PyExc_TypeError
,"Unexpected type");
271 result
= PyBytes_AsStringAndSize((PyObject
*)self
, &msg
, &size
);
273 PyErr_Format(PyExc_TypeError
, "Failed to extract bytes");
276 return PyUnicode_FromStringAndSize(msg
, size
);
279 static PyTypeObject PyLdbBytesType
= {
280 PyVarObject_HEAD_INIT(NULL
, 0)
281 .tp_name
= "ldb.bytes",
282 .tp_doc
= "str/bytes (with custom str)",
283 .tp_str
= (reprfunc
)py_ldb_bytes_str
,
284 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
287 static PyObject
*PyObject_FromLdbValue(const struct ldb_val
*val
)
289 return PyLdbBytes_FromStringAndSize((const char *)val
->data
, val
->length
);
292 static PyObject
*PyStr_FromLdbValue(const struct ldb_val
*val
)
294 return PyUnicode_FromStringAndSize((const char *)val
->data
, val
->length
);
298 * Create a Python object from a ldb_result.
300 * @param result LDB result to convert
301 * @return Python object with converted result (a list object)
303 static PyObject
*PyLdbControl_FromControl(struct ldb_control
*control
)
305 TALLOC_CTX
*ctl_ctx
= talloc_new(NULL
);
306 PyLdbControlObject
*ctrl
;
307 if (ctl_ctx
== NULL
) {
312 ctrl
= (PyLdbControlObject
*)PyLdbControl
.tp_alloc(&PyLdbControl
, 0);
314 talloc_free(ctl_ctx
);
318 ctrl
->mem_ctx
= ctl_ctx
;
319 ctrl
->data
= talloc_steal(ctrl
->mem_ctx
, control
);
320 if (ctrl
->data
== NULL
) {
325 return (PyObject
*) ctrl
;
329 * Create a Python object from a ldb_result.
331 * @param result LDB result to convert
332 * @return Python object with converted result (a list object)
334 static PyObject
*PyLdbResult_FromResult(struct ldb_result
*result
, PyLdbObject
*pyldb
)
336 PyLdbResultObject
*ret
;
337 PyObject
*list
, *controls
, *referals
;
340 if (result
== NULL
) {
344 ret
= (PyLdbResultObject
*)PyLdbResult
.tp_alloc(&PyLdbResult
, 0);
351 Py_INCREF(ret
->pyldb
);
353 list
= PyList_New(result
->count
);
360 for (i
= 0; i
< result
->count
; i
++) {
361 PyObject
*pymessage
= PyLdbMessage_FromMessage(result
->msgs
[i
], pyldb
);
362 if (pymessage
== NULL
) {
367 PyList_SetItem(list
, i
, pymessage
);
370 ret
->mem_ctx
= talloc_new(NULL
);
371 if (ret
->mem_ctx
== NULL
) {
380 if (result
->controls
) {
382 while (result
->controls
[i
]) {
385 controls
= PyList_New(i
);
386 if (controls
== NULL
) {
392 for (i
=0; result
->controls
[i
]; i
++) {
393 PyObject
*ctrl
= (PyObject
*) PyLdbControl_FromControl(result
->controls
[i
]);
401 PyList_SetItem(controls
, i
, ctrl
);
405 * No controls so we keep an empty list
407 controls
= PyList_New(0);
408 if (controls
== NULL
) {
416 ret
->controls
= controls
;
420 while (result
->refs
&& result
->refs
[i
]) {
424 referals
= PyList_New(i
);
425 if (referals
== NULL
) {
432 for (i
= 0;result
->refs
&& result
->refs
[i
]; i
++) {
433 PyList_SetItem(referals
, i
, PyUnicode_FromString(result
->refs
[i
]));
435 ret
->referals
= referals
;
436 return (PyObject
*)ret
;
441 * PyErr_interal_LDB_DN_OR_RAISE does exactly what
442 * PyErr__LDB_DN_OR_RAISE does, but rather than going through the
443 * Python layer to import the Dn object, it directly uses the the
444 * address of the PyTypeObject. This is faster, but can only be done
447 #define PyErr_internal_LDB_DN_OR_RAISE(_py_obj, dn) do { \
448 PyLdbDnObject *_py_dn = NULL; \
449 if (_py_obj == NULL || !pyldb_Dn_Check(_py_obj)) { \
450 PyErr_SetString(PyExc_TypeError, "ldb Dn object required"); \
453 _py_dn = (PyLdbDnObject *)_py_obj; \
454 dn = pyldb_Dn_AS_DN(_py_dn); \
455 if (_py_dn->pyldb->ldb_ctx != ldb_dn_get_ldb_context(dn)) { \
456 PyErr_SetString(PyExc_RuntimeError, \
457 "Dn has a stale LDB connection"); \
463 static PyObject
*py_ldb_dn_validate(PyObject
*self
,
464 PyObject
*Py_UNUSED(ignored
))
466 struct ldb_dn
*dn
= NULL
;
467 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
468 return PyBool_FromLong(ldb_dn_validate(dn
));
471 static PyObject
*py_ldb_dn_is_valid(PyLdbDnObject
*self
,
472 PyObject
*Py_UNUSED(ignored
))
474 return PyBool_FromLong(ldb_dn_is_valid(self
->dn
));
477 static PyObject
*py_ldb_dn_is_special(PyLdbDnObject
*self
,
478 PyObject
*Py_UNUSED(ignored
))
480 return PyBool_FromLong(ldb_dn_is_special(self
->dn
));
483 static PyObject
*py_ldb_dn_is_null(PyObject
*self
,
484 PyObject
*Py_UNUSED(ignored
))
486 struct ldb_dn
*dn
= NULL
;
487 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
488 return PyBool_FromLong(ldb_dn_is_null(dn
));
491 static PyObject
*py_ldb_dn_get_casefold(PyObject
*self
,
492 PyObject
*Py_UNUSED(ignored
))
494 const char *s
= NULL
;
495 struct ldb_dn
*dn
= NULL
;
496 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
497 s
= ldb_dn_get_casefold(dn
);
502 return PyUnicode_FromString(s
);
505 static PyObject
*py_ldb_dn_get_linearized(PyObject
*self
,
506 PyObject
*Py_UNUSED(ignored
))
508 struct ldb_dn
*dn
= NULL
;
509 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
510 return PyUnicode_FromString(ldb_dn_get_linearized(dn
));
513 static PyObject
*py_ldb_dn_canonical_str(PyObject
*self
,
514 PyObject
*Py_UNUSED(ignored
))
516 struct ldb_dn
*dn
= NULL
;
517 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
518 return PyUnicode_FromString(ldb_dn_canonical_string(dn
, dn
));
521 static PyObject
*py_ldb_dn_canonical_ex_str(PyObject
*self
,
522 PyObject
*Py_UNUSED(ignored
))
524 struct ldb_dn
*dn
= NULL
;
525 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
526 return PyUnicode_FromString(ldb_dn_canonical_ex_string(dn
, dn
));
529 static PyObject
*py_ldb_dn_extended_str(PyObject
*self
, PyObject
*args
, PyObject
*kwargs
)
531 const char * const kwnames
[] = { "mode", NULL
};
533 struct ldb_dn
*dn
= NULL
;
534 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
535 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i",
536 discard_const_p(char *, kwnames
),
540 return PyUnicode_FromString(ldb_dn_get_extended_linearized(dn
, dn
, mode
));
543 static PyObject
*py_ldb_dn_get_extended_component(PyObject
*self
, PyObject
*args
)
546 const struct ldb_val
*val
= NULL
;
547 struct ldb_dn
*dn
= NULL
;
548 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
550 if (!PyArg_ParseTuple(args
, "s", &name
)) {
553 val
= ldb_dn_get_extended_component(dn
, name
);
558 return PyBytes_FromStringAndSize((const char *)val
->data
, val
->length
);
561 static PyObject
*py_ldb_dn_set_extended_component(PyObject
*self
, PyObject
*args
)
565 uint8_t *value
= NULL
;
567 struct ldb_dn
*dn
= NULL
;
568 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
570 if (!PyArg_ParseTuple(args
, "sz#", &name
, (char **)&value
, &size
))
574 err
= ldb_dn_set_extended_component(dn
, name
, NULL
);
577 val
.data
= (uint8_t *)value
;
579 err
= ldb_dn_set_extended_component(dn
, name
, &val
);
582 if (err
!= LDB_SUCCESS
) {
583 PyErr_SetString(PyExc_TypeError
, "Failed to set extended component");
590 static PyObject
*py_ldb_dn_repr(PyLdbDnObject
*self
)
592 PyObject
*str
= PyUnicode_FromString(ldb_dn_get_linearized(self
->dn
));
593 PyObject
*repr
, *result
;
596 repr
= PyObject_Repr(str
);
601 result
= PyUnicode_FromFormat("Dn(%s)", PyUnicode_AsUTF8(repr
));
607 static PyObject
*py_ldb_dn_check_special(PyLdbDnObject
*self
, PyObject
*args
)
611 if (!PyArg_ParseTuple(args
, "s", &name
))
614 return PyBool_FromLong(ldb_dn_check_special(self
->dn
, name
));
617 static PyObject
*py_ldb_dn_richcmp(PyObject
*pydn1
, PyObject
*pydn2
, int op
)
620 struct ldb_dn
*dn1
= NULL
;
621 struct ldb_dn
*dn2
= NULL
;
622 if (!pyldb_Dn_Check(pydn2
)) {
623 Py_INCREF(Py_NotImplemented
);
624 return Py_NotImplemented
;
626 PyErr_internal_LDB_DN_OR_RAISE(pydn1
, dn1
);
627 PyErr_internal_LDB_DN_OR_RAISE(pydn2
, dn2
);
629 ret
= ldb_dn_compare(dn1
, dn2
);
630 return richcmp(ret
, op
);
633 static PyObject
*py_ldb_dn_get_parent(PyObject
*self
,
634 PyObject
*Py_UNUSED(ignored
))
636 struct ldb_dn
*dn
= NULL
;
637 struct ldb_dn
*parent
;
638 PyLdbDnObject
*py_ret
= NULL
;
639 PyLdbDnObject
*dn_self
= NULL
;
640 TALLOC_CTX
*mem_ctx
= NULL
;
642 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
644 if (ldb_dn_get_comp_num(dn
) < 1) {
648 mem_ctx
= talloc_new(NULL
);
649 if (mem_ctx
== NULL
) {
654 parent
= ldb_dn_get_parent(mem_ctx
, dn
);
655 if (parent
== NULL
) {
657 talloc_free(mem_ctx
);
661 py_ret
= (PyLdbDnObject
*)PyLdbDn
.tp_alloc(&PyLdbDn
, 0);
662 if (py_ret
== NULL
) {
664 talloc_free(mem_ctx
);
667 dn_self
= (PyLdbDnObject
*)self
;
669 py_ret
->mem_ctx
= mem_ctx
;
671 py_ret
->pyldb
= dn_self
->pyldb
;
672 Py_INCREF(py_ret
->pyldb
);
673 return (PyObject
*)py_ret
;
676 static PyObject
*py_ldb_dn_add_child(PyObject
*self
, PyObject
*args
)
678 PyObject
*py_other
= NULL
;
679 struct ldb_dn
*dn
= NULL
;
680 struct ldb_dn
*other
= NULL
;
681 TALLOC_CTX
*tmp_ctx
= NULL
;
684 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
686 if (!PyArg_ParseTuple(args
, "O", &py_other
)) {
691 * pyldb_Object_AsDn only uses tmp_ctx if py_other is str/bytes, in
692 * which case it allocates a struct ldb_dn. If py_other is a PyLdbDn,
693 * tmp_ctx is unused and the underlying dn is borrowed.
695 * The pieces of other are reassembled onto dn using dn itself as a
696 * talloc context (ldb_dn_add_child assumes all dns are talloc
697 * contexts), after which we don't need any temporary DN we made.
699 tmp_ctx
= talloc_new(NULL
);
700 if (tmp_ctx
== NULL
) {
705 ok
= pyldb_Object_AsDn(tmp_ctx
,
707 ldb_dn_get_ldb_context(dn
),
710 TALLOC_FREE(tmp_ctx
);
714 ok
= ldb_dn_add_child(dn
, other
);
715 TALLOC_FREE(tmp_ctx
);
717 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, NULL
);
723 static PyObject
*py_ldb_dn_add_base(PyObject
*self
, PyObject
*args
)
725 PyObject
*py_other
= NULL
;
726 struct ldb_dn
*other
= NULL
;
727 struct ldb_dn
*dn
= NULL
;
728 TALLOC_CTX
*tmp_ctx
= NULL
;
731 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
733 if (!PyArg_ParseTuple(args
, "O", &py_other
)) {
738 * As noted in py_ldb_dn_add_child() comments, if py_other is a
739 * string, other is an ephemeral struct ldb_dn, but if py_other is a
740 * python DN, other points to the corresponding long-lived DN.
742 tmp_ctx
= talloc_new(NULL
);
743 if (tmp_ctx
== NULL
) {
747 ok
= pyldb_Object_AsDn(tmp_ctx
,
749 ldb_dn_get_ldb_context(dn
),
752 TALLOC_FREE(tmp_ctx
);
756 ok
= ldb_dn_add_base(dn
, other
);
757 TALLOC_FREE(tmp_ctx
);
759 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, NULL
);
765 static PyObject
*py_ldb_dn_copy(struct ldb_dn
*dn
, PyLdbObject
*pyldb
);
767 static PyObject
*py_ldb_dn_copy_method(PyObject
*self
, PyObject
*args
)
769 struct ldb_dn
*dn
= NULL
;
770 PyLdbObject
*pyldb
= NULL
;
771 PyObject
*obj
= Py_None
;
772 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
774 if (!PyArg_ParseTuple(args
, "|O", &obj
)) {
778 if (obj
== Py_None
) {
780 * With no argument, or None, dn.copy() uses its own ldb.
782 * There is not much reason to do this, other than as a
783 * convenience in this situation:
785 * >>> msg.dn = dn.copy(msg.ldb)
787 * when you don't know whether msg has a dn or not (if msg.ldb
788 * is None, msg will now belong to this dn's ldb).
790 pyldb
= ((PyLdbDnObject
*)self
)->pyldb
;
791 } else if (PyObject_TypeCheck(obj
, &PyLdb
)) {
792 pyldb
= (PyLdbObject
*)obj
;
794 PyErr_Format(PyExc_TypeError
,
795 "Expected Ldb or None");
798 if (pyldb
!= ((PyLdbDnObject
*)self
)->pyldb
) {
800 * This is unfortunate, but we can't make a copy of the dn directly,
801 * since the opaque struct ldb_dn has a pointer to the ldb it knows,
802 * and it is the WRONG ONE.
804 * Instead we go via string serialisation.
807 struct ldb_dn
*new_dn
= NULL
;
808 dn_str
= ldb_dn_get_extended_linearized(pyldb
->mem_ctx
, dn
, 1);
809 if (dn_str
== NULL
) {
810 PyErr_Format(PyExc_RuntimeError
,
811 "Could not linearize DN");
814 new_dn
= ldb_dn_new(pyldb
->mem_ctx
,
818 if (new_dn
== NULL
) {
819 PyErr_Format(PyExc_RuntimeError
,
820 "Could not re-parse DN '%s'",
828 return py_ldb_dn_copy(dn
, pyldb
);
831 static PyObject
*py_ldb_dn_remove_base_components(PyObject
*self
, PyObject
*args
)
833 struct ldb_dn
*dn
= NULL
;
836 if (!PyArg_ParseTuple(args
, "i", &i
)) {
840 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
842 ok
= ldb_dn_remove_base_components(dn
, i
);
844 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, NULL
);
851 static PyObject
*py_ldb_dn_is_child_of(PyObject
*self
, PyObject
*args
)
854 struct ldb_dn
*dn
, *base
;
855 if (!PyArg_ParseTuple(args
, "O", &py_base
)) {
859 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
861 if (!pyldb_Object_AsDn(NULL
, py_base
, ldb_dn_get_ldb_context(dn
), &base
))
864 return PyBool_FromLong(ldb_dn_compare_base(base
, dn
) == 0);
867 static PyObject
*py_ldb_dn_get_component_name(PyObject
*self
, PyObject
*args
)
869 struct ldb_dn
*dn
= NULL
;
871 unsigned int num
= 0;
873 if (!PyArg_ParseTuple(args
, "I", &num
)) {
877 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
879 name
= ldb_dn_get_component_name(dn
, num
);
884 return PyUnicode_FromString(name
);
887 static PyObject
*py_ldb_dn_get_component_value(PyObject
*self
, PyObject
*args
)
889 struct ldb_dn
*dn
= NULL
;
890 const struct ldb_val
*val
;
891 unsigned int num
= 0;
893 if (!PyArg_ParseTuple(args
, "I", &num
)) {
897 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
899 val
= ldb_dn_get_component_val(dn
, num
);
904 return PyStr_FromLdbValue(val
);
907 static PyObject
*py_ldb_dn_set_component(PyObject
*self
, PyObject
*args
)
909 unsigned int num
= 0;
910 char *name
= NULL
, *value
= NULL
;
911 struct ldb_val val
= { 0 };
914 struct ldb_dn
*dn
= NULL
;
916 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
918 if (!PyArg_ParseTuple(args
, "Iss#", &num
, &name
, &value
, &size
)) {
922 val
.data
= (unsigned char*) value
;
925 err
= ldb_dn_set_component(dn
, num
, name
, val
);
926 if (err
!= LDB_SUCCESS
) {
927 PyErr_SetString(PyExc_TypeError
, "Failed to set component");
934 static PyObject
*py_ldb_dn_get_rdn_name(PyObject
*self
,
935 PyObject
*Py_UNUSED(ignored
))
937 struct ldb_dn
*dn
= NULL
;
940 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
942 name
= ldb_dn_get_rdn_name(dn
);
947 return PyUnicode_FromString(name
);
950 static PyObject
*py_ldb_dn_get_rdn_value(PyObject
*self
,
951 PyObject
*Py_UNUSED(ignored
))
953 struct ldb_dn
*dn
= NULL
;
954 const struct ldb_val
*val
;
956 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
958 val
= ldb_dn_get_rdn_val(dn
);
963 return PyStr_FromLdbValue(val
);
966 static PyMethodDef py_ldb_dn_methods
[] = {
967 { "validate", (PyCFunction
)py_ldb_dn_validate
, METH_NOARGS
,
968 "S.validate() -> bool\n"
969 "Validate DN is correct." },
970 { "is_valid", (PyCFunction
)py_ldb_dn_is_valid
, METH_NOARGS
,
971 "S.is_valid() -> bool\n" },
972 { "is_special", (PyCFunction
)py_ldb_dn_is_special
, METH_NOARGS
,
973 "S.is_special() -> bool\n"
974 "Check whether this is a special LDB DN." },
975 { "is_null", (PyCFunction
)py_ldb_dn_is_null
, METH_NOARGS
,
976 "Check whether this is a null DN." },
977 { "get_casefold", (PyCFunction
)py_ldb_dn_get_casefold
, METH_NOARGS
,
979 { "get_linearized", PY_DISCARD_FUNC_SIG(PyCFunction
,
980 py_ldb_dn_get_linearized
),
983 { "canonical_str", (PyCFunction
)py_ldb_dn_canonical_str
, METH_NOARGS
,
984 "S.canonical_str() -> string\n"
985 "Canonical version of this DN (like a posix path)." },
986 { "is_child_of", (PyCFunction
)py_ldb_dn_is_child_of
, METH_VARARGS
,
987 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
988 { "canonical_ex_str", (PyCFunction
)py_ldb_dn_canonical_ex_str
, METH_NOARGS
,
989 "S.canonical_ex_str() -> string\n"
990 "Canonical version of this DN (like a posix path, with terminating newline)." },
991 { "extended_str", PY_DISCARD_FUNC_SIG(PyCFunction
,
992 py_ldb_dn_extended_str
),
993 METH_VARARGS
| METH_KEYWORDS
,
994 "S.extended_str(mode=1) -> string\n"
995 "Extended version of this DN" },
996 { "parent", (PyCFunction
)py_ldb_dn_get_parent
, METH_NOARGS
,
998 "Get the parent for this DN." },
999 { "add_child", (PyCFunction
)py_ldb_dn_add_child
, METH_VARARGS
,
1000 "S.add_child(dn) -> bool\n"
1001 "Add a child DN to this DN." },
1002 { "add_base", (PyCFunction
)py_ldb_dn_add_base
, METH_VARARGS
,
1003 "S.add_base(dn) -> bool\n"
1004 "Add a base DN to this DN." },
1005 { "copy", (PyCFunction
)py_ldb_dn_copy_method
, METH_VARARGS
,
1006 "dn.copy(ldb) -> dn\n"
1007 "Make a copy of this DN, attached to the given ldb object." },
1008 { "remove_base_components", (PyCFunction
)py_ldb_dn_remove_base_components
, METH_VARARGS
,
1009 "S.remove_base_components(int) -> bool\n"
1010 "Remove a number of DN components from the base of this DN." },
1011 { "check_special", (PyCFunction
)py_ldb_dn_check_special
, METH_VARARGS
,
1012 "S.check_special(name) -> bool\n\n"
1013 "Check if name is a special DN name"},
1014 { "get_extended_component", (PyCFunction
)py_ldb_dn_get_extended_component
, METH_VARARGS
,
1015 "S.get_extended_component(name) -> string\n\n"
1016 "returns a DN extended component as a binary string"},
1017 { "set_extended_component", (PyCFunction
)py_ldb_dn_set_extended_component
, METH_VARARGS
,
1018 "S.set_extended_component(name, value) -> None\n\n"
1019 "set a DN extended component as a binary string"},
1020 { "get_component_name", (PyCFunction
)py_ldb_dn_get_component_name
, METH_VARARGS
,
1021 "S.get_component_name(num) -> string\n"
1022 "get the attribute name of the specified component" },
1023 { "get_component_value", (PyCFunction
)py_ldb_dn_get_component_value
, METH_VARARGS
,
1024 "S.get_component_value(num) -> string\n"
1025 "get the attribute value of the specified component as a binary string" },
1026 { "set_component", (PyCFunction
)py_ldb_dn_set_component
, METH_VARARGS
,
1027 "S.set_component(num, name, value) -> None\n"
1028 "set the attribute name and value of the specified component" },
1029 { "get_rdn_name", (PyCFunction
)py_ldb_dn_get_rdn_name
, METH_NOARGS
,
1030 "S.get_rdn_name() -> string\n"
1031 "get the RDN attribute name" },
1032 { "get_rdn_value", (PyCFunction
)py_ldb_dn_get_rdn_value
, METH_NOARGS
,
1033 "S.get_rdn_value() -> string\n"
1034 "get the RDN attribute value as a binary string" },
1039 static PyObject
*py_ldb_dn_get_ldb(PyLdbDnObject
*self
, void *closure
)
1041 if (self
->pyldb
== NULL
) {
1044 Py_INCREF(self
->pyldb
);
1045 return (PyObject
*)self
->pyldb
;
1049 static PyGetSetDef py_ldb_dn_getset
[] = {
1051 .name
= discard_const_p(char, "ldb"),
1052 .get
= (getter
)py_ldb_dn_get_ldb
,
1053 .doc
= discard_const_p( /* for Py 3.6; 3.7+ have const char* */
1054 char, "returns the associated ldb object (or None)")
1060 static Py_ssize_t
py_ldb_dn_len(PyLdbDnObject
*self
)
1062 struct ldb_dn
*dn
= pyldb_Dn_AS_DN(self
);
1063 if (dn
== NULL
|| self
->pyldb
->ldb_ctx
!= ldb_dn_get_ldb_context(dn
)) {
1067 return ldb_dn_get_comp_num(dn
);
1071 copy a DN as a python object
1073 static PyObject
*py_ldb_dn_copy(struct ldb_dn
*dn
, PyLdbObject
*pyldb
)
1075 TALLOC_CTX
*mem_ctx
= NULL
;
1076 struct ldb_dn
*new_dn
= NULL
;
1077 PyLdbDnObject
*py_ret
;
1079 if (ldb_dn_get_ldb_context(dn
) != pyldb
->ldb_ctx
) {
1081 * We can't do this, because we can't (for now) change the ldb
1082 * pointer of the underlying dn returned by ldb_dn_copy().
1084 * This error means someone editing this file got confused,
1085 * which is quite understandable.
1087 PyErr_SetString(PyExc_RuntimeError
,
1088 "py_ldb_dn_copy can't copy to a new LDB");
1092 mem_ctx
= talloc_new(NULL
);
1093 if (mem_ctx
== NULL
) {
1094 return PyErr_NoMemory();
1097 new_dn
= ldb_dn_copy(mem_ctx
, dn
);
1098 if (new_dn
== NULL
) {
1099 talloc_free(mem_ctx
);
1100 return PyErr_NoMemory();
1103 py_ret
= (PyLdbDnObject
*)PyLdbDn
.tp_alloc(&PyLdbDn
, 0);
1104 if (py_ret
== NULL
) {
1105 talloc_free(mem_ctx
);
1109 py_ret
->mem_ctx
= mem_ctx
;
1110 py_ret
->dn
= new_dn
;
1112 py_ret
->pyldb
= pyldb
;
1113 Py_INCREF(py_ret
->pyldb
);
1114 return (PyObject
*)py_ret
;
1117 static PyObject
*py_ldb_dn_concat(PyObject
*self
, PyObject
*py_other
)
1119 TALLOC_CTX
*mem_ctx
= NULL
;
1120 struct ldb_dn
*dn
= NULL
;
1121 struct ldb_dn
*other
= NULL
;
1123 struct ldb_dn
*new_dn
= NULL
;
1124 PyLdbDnObject
*py_ret
= NULL
;
1127 PyErr_internal_LDB_DN_OR_RAISE(self
, dn
);
1128 PyErr_internal_LDB_DN_OR_RAISE(py_other
, other
);
1130 mem_ctx
= talloc_new(NULL
);
1131 if (mem_ctx
== NULL
) {
1132 return PyErr_NoMemory();
1135 new_dn
= ldb_dn_copy(mem_ctx
, dn
);
1136 if (new_dn
== NULL
) {
1137 talloc_free(mem_ctx
);
1138 return PyErr_NoMemory();
1141 if (!ldb_dn_add_base(new_dn
, other
)) {
1142 PyErr_SetString(PyExc_RuntimeError
, "unable to concatenate DNs");
1143 talloc_free(mem_ctx
);
1147 py_ret
= (PyLdbDnObject
*)PyLdbDn
.tp_alloc(&PyLdbDn
, 0);
1148 if (py_ret
== NULL
) {
1149 talloc_free(mem_ctx
);
1153 py_ret
->mem_ctx
= mem_ctx
;
1154 py_ret
->dn
= new_dn
;
1156 py_ret
->pyldb
= ((PyLdbDnObject
*)self
)->pyldb
;
1157 Py_INCREF(py_ret
->pyldb
);
1159 return (PyObject
*)py_ret
;
1162 static PySequenceMethods py_ldb_dn_seq
= {
1163 .sq_length
= (lenfunc
)py_ldb_dn_len
,
1164 .sq_concat
= (binaryfunc
)py_ldb_dn_concat
,
1167 static PyObject
*py_ldb_dn_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
1169 struct ldb_dn
*ret
= NULL
;
1171 PyObject
*py_ldb
= NULL
;
1172 struct ldb_context
*ldb_ctx
= NULL
;
1173 TALLOC_CTX
*mem_ctx
= NULL
;
1174 PyLdbDnObject
*py_ret
= NULL
;
1175 const char * const kwnames
[] = { "ldb", "dn", NULL
};
1177 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O!"PYARG_STR_UNI
,
1178 discard_const_p(char *, kwnames
),
1179 &PyLdb
, &py_ldb
, "utf8", &str
))
1182 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(py_ldb
);
1184 mem_ctx
= talloc_new(NULL
);
1185 if (mem_ctx
== NULL
) {
1190 ret
= ldb_dn_new(mem_ctx
, ldb_ctx
, str
);
1191 if (!ldb_dn_validate(ret
)) {
1192 talloc_free(mem_ctx
);
1193 PyErr_SetString(PyExc_ValueError
, "unable to parse dn string");
1197 py_ret
= (PyLdbDnObject
*)type
->tp_alloc(type
, 0);
1198 if (py_ret
== NULL
) {
1199 talloc_free(mem_ctx
);
1203 py_ret
->mem_ctx
= mem_ctx
;
1205 py_ret
->pyldb
= (PyLdbObject
*)py_ldb
;
1206 Py_INCREF(py_ret
->pyldb
);
1209 PyMem_Free(discard_const_p(char, str
));
1211 return (PyObject
*)py_ret
;
1214 static void py_ldb_dn_dealloc(PyLdbDnObject
*self
)
1216 talloc_free(self
->mem_ctx
);
1217 Py_DECREF(self
->pyldb
);
1221 static PyTypeObject PyLdbDn
= {
1222 .tp_name
= "ldb.Dn",
1223 .tp_methods
= py_ldb_dn_methods
,
1224 .tp_str
= (reprfunc
)py_ldb_dn_get_linearized
,
1225 .tp_repr
= (reprfunc
)py_ldb_dn_repr
,
1226 .tp_richcompare
= (richcmpfunc
)py_ldb_dn_richcmp
,
1227 .tp_as_sequence
= &py_ldb_dn_seq
,
1228 .tp_getset
= py_ldb_dn_getset
,
1229 .tp_doc
= "A LDB distinguished name.",
1230 .tp_new
= py_ldb_dn_new
,
1231 .tp_dealloc
= (destructor
)py_ldb_dn_dealloc
,
1232 .tp_basicsize
= sizeof(PyLdbDnObject
),
1233 .tp_flags
= Py_TPFLAGS_DEFAULT
,
1237 static void py_ldb_debug(void *context
, enum ldb_debug_level level
, const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(3, 0);
1238 static void py_ldb_debug(void *context
, enum ldb_debug_level level
, const char *fmt
, va_list ap
)
1240 PyObject
*fn
= (PyObject
*)context
;
1241 PyObject
*result
= NULL
;
1242 result
= PyObject_CallFunction(fn
, discard_const_p(char, "(i,O)"), level
, PyUnicode_FromFormatV(fmt
, ap
));
1246 static PyObject
*py_ldb_debug_func
;
1248 static PyObject
*py_ldb_set_debug(PyObject
*self
, PyObject
*args
)
1251 struct ldb_context
*ldb_ctx
;
1253 if (!PyArg_ParseTuple(args
, "O", &cb
))
1256 if (py_ldb_debug_func
!= NULL
) {
1257 Py_DECREF(py_ldb_debug_func
);
1261 /* FIXME: DECREF cb when exiting program */
1262 py_ldb_debug_func
= cb
;
1263 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1264 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
,
1265 ldb_set_debug(ldb_ctx
, py_ldb_debug
, cb
),
1271 static PyObject
*py_ldb_set_create_perms(PyTypeObject
*self
, PyObject
*args
)
1274 if (!PyArg_ParseTuple(args
, "I", &perms
))
1277 ldb_set_create_perms(pyldb_Ldb_AS_LDBCONTEXT(self
), perms
);
1282 static PyObject
*py_ldb_set_modules_dir(PyTypeObject
*self
, PyObject
*args
)
1285 if (!PyArg_ParseTuple(args
, "s", &modules_dir
))
1288 ldb_set_modules_dir(pyldb_Ldb_AS_LDBCONTEXT(self
), modules_dir
);
1293 static PyObject
*py_ldb_transaction_start(PyLdbObject
*self
,
1294 PyObject
*Py_UNUSED(ignored
))
1296 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1298 ldb_err
= ldb_transaction_start(ldb_ctx
);
1299 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1303 static PyObject
*py_ldb_transaction_commit(PyLdbObject
*self
,
1304 PyObject
*Py_UNUSED(ignored
))
1306 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1308 ldb_err
= ldb_transaction_commit(ldb_ctx
);
1309 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1313 static PyObject
*py_ldb_transaction_prepare_commit(PyLdbObject
*self
,
1314 PyObject
*Py_UNUSED(ignored
))
1316 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1318 ldb_err
= ldb_transaction_prepare_commit(ldb_ctx
);
1319 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1323 static PyObject
*py_ldb_transaction_cancel(PyLdbObject
*self
,
1324 PyObject
*Py_UNUSED(ignored
))
1326 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1328 ldb_err
= ldb_transaction_cancel(ldb_ctx
);
1329 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1333 static PyObject
*py_ldb_setup_wellknown_attributes(PyLdbObject
*self
,
1334 PyObject
*Py_UNUSED(ignored
))
1336 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1338 ldb_err
= ldb_setup_wellknown_attributes(ldb_ctx
);
1339 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ldb_err
, ldb_ctx
);
1343 static PyObject
*py_ldb_repr(PyLdbObject
*self
)
1345 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1346 const char *url
= ldb_get_opaque(ldb_ctx
, "ldb_url");
1348 url
= "no connection";
1350 return PyUnicode_FromFormat("<ldb connection %s>", url
);
1353 static PyObject
*py_ldb_get_root_basedn(PyLdbObject
*self
,
1354 PyObject
*Py_UNUSED(ignored
))
1356 struct ldb_dn
*dn
= ldb_get_root_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1359 return py_ldb_dn_copy(dn
, self
);
1363 static PyObject
*py_ldb_get_schema_basedn(PyLdbObject
*self
,
1364 PyObject
*Py_UNUSED(ignored
))
1366 struct ldb_dn
*dn
= ldb_get_schema_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1369 return py_ldb_dn_copy(dn
, self
);
1372 static PyObject
*py_ldb_get_config_basedn(PyLdbObject
*self
,
1373 PyObject
*Py_UNUSED(ignored
))
1375 struct ldb_dn
*dn
= ldb_get_config_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1378 return py_ldb_dn_copy(dn
, self
);
1381 static PyObject
*py_ldb_get_default_basedn(PyLdbObject
*self
,
1382 PyObject
*Py_UNUSED(ignored
))
1384 struct ldb_dn
*dn
= ldb_get_default_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1387 return py_ldb_dn_copy(dn
, self
);
1390 static const char **PyList_AsStrList(TALLOC_CTX
*mem_ctx
, PyObject
*list
,
1391 const char *paramname
)
1395 if (!PyList_Check(list
)) {
1396 PyErr_Format(PyExc_TypeError
, "%s is not a list", paramname
);
1399 ret
= talloc_array(NULL
, const char *, PyList_Size(list
)+1);
1405 for (i
= 0; i
< PyList_Size(list
); i
++) {
1406 const char *str
= NULL
;
1408 PyObject
*item
= PyList_GetItem(list
, i
);
1409 if (!PyUnicode_Check(item
)) {
1410 PyErr_Format(PyExc_TypeError
, "%s should be strings", paramname
);
1414 str
= PyUnicode_AsUTF8AndSize(item
, &size
);
1419 ret
[i
] = talloc_strndup(ret
, str
, size
);
1425 static PyObject
*py_ldb_connect(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
);
1427 static int py_ldb_init(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1429 const char * const kwnames
[] = { "url", "flags", "options", NULL
};
1431 PyObject
*py_options
= NULL
;
1432 unsigned int flags
= 0;
1434 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|zIO:Ldb.__init__",
1435 discard_const_p(char *, kwnames
),
1436 &url
, &flags
, &py_options
)) {
1441 /* py_ldb_connect returns py_None on success, NULL on error */
1442 PyObject
*result
= py_ldb_connect(self
, args
, kwargs
);
1443 if (result
== NULL
) {
1448 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1449 ldb_set_flags(ldb
, flags
);
1455 static PyObject
*py_ldb_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
1457 TALLOC_CTX
*mem_ctx
= NULL
;
1459 struct ldb_context
*ldb
;
1461 mem_ctx
= talloc_new(NULL
);
1462 if (mem_ctx
== NULL
) {
1463 return PyErr_NoMemory();
1466 ldb
= ldb_init(mem_ctx
, NULL
);
1468 talloc_free(mem_ctx
);
1473 ret
= (PyLdbObject
*)type
->tp_alloc(type
, 0);
1475 talloc_free(mem_ctx
);
1479 ret
->mem_ctx
= mem_ctx
;
1482 return (PyObject
*)ret
;
1485 static PyObject
*py_ldb_connect(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1488 unsigned int flags
= 0;
1489 PyObject
*py_options
= Py_None
;
1491 const char **options
;
1492 const char * const kwnames
[] = { "url", "flags", "options", NULL
};
1493 struct ldb_context
*ldb_ctx
;
1495 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|IO",
1496 discard_const_p(char *, kwnames
),
1497 &url
, &flags
, &py_options
))
1500 if (py_options
== Py_None
) {
1503 options
= PyList_AsStrList(NULL
, py_options
, "options");
1504 if (options
== NULL
)
1508 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1509 ret
= ldb_connect(ldb_ctx
, url
, flags
, options
);
1510 talloc_free(options
);
1512 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1517 static PyObject
*py_ldb_modify(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1520 PyObject
*py_controls
= Py_None
;
1521 struct ldb_context
*ldb_ctx
;
1522 struct ldb_request
*req
;
1523 struct ldb_control
**parsed_controls
;
1524 struct ldb_message
*msg
;
1526 TALLOC_CTX
*mem_ctx
;
1528 const char * const kwnames
[] = { "message", "controls", "validate", NULL
};
1530 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Ob",
1531 discard_const_p(char *, kwnames
),
1532 &py_msg
, &py_controls
, &validate
))
1535 mem_ctx
= talloc_new(NULL
);
1536 if (mem_ctx
== NULL
) {
1540 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1542 if (py_controls
== Py_None
) {
1543 parsed_controls
= NULL
;
1545 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1546 if (controls
== NULL
) {
1547 talloc_free(mem_ctx
);
1550 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1551 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
1552 talloc_free(mem_ctx
);
1553 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
1556 talloc_free(controls
);
1559 if (!pyldb_Message_Check(py_msg
)) {
1560 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message");
1561 talloc_free(mem_ctx
);
1564 msg
= pyldb_Message_AsMessage(py_msg
);
1567 ret
= ldb_msg_sanity_check(ldb_ctx
, msg
);
1568 if (ret
!= LDB_SUCCESS
) {
1569 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1570 talloc_free(mem_ctx
);
1575 ret
= ldb_build_mod_req(&req
, ldb_ctx
, mem_ctx
, msg
, parsed_controls
,
1576 NULL
, ldb_op_default_callback
, NULL
);
1577 if (ret
!= LDB_SUCCESS
) {
1578 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1579 talloc_free(mem_ctx
);
1583 /* do request and autostart a transaction */
1584 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1586 ret
= ldb_transaction_start(ldb_ctx
);
1587 if (ret
!= LDB_SUCCESS
) {
1588 talloc_free(mem_ctx
);
1589 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1593 ret
= ldb_request(ldb_ctx
, req
);
1594 if (ret
== LDB_SUCCESS
) {
1595 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1598 if (ret
== LDB_SUCCESS
) {
1599 ret
= ldb_transaction_commit(ldb_ctx
);
1601 ldb_transaction_cancel(ldb_ctx
);
1604 talloc_free(mem_ctx
);
1605 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1612 * Obtain a ldb message from a Python Dictionary object.
1614 * @param mem_ctx Memory context
1615 * @param py_obj Python Dictionary object
1616 * @param ldb_ctx LDB context
1617 * @param mod_flags Flags to be set on every message element
1618 * @return ldb_message on success or NULL on failure
1620 static struct ldb_message
*PyDict_AsMessage(TALLOC_CTX
*mem_ctx
,
1622 struct ldb_context
*ldb_ctx
,
1623 unsigned int mod_flags
)
1625 struct ldb_message
*msg
;
1626 unsigned int msg_pos
= 0;
1627 Py_ssize_t dict_pos
= 0;
1628 PyObject
*key
, *value
;
1629 struct ldb_message_element
*msg_el
;
1630 PyObject
*dn_value
= PyDict_GetItemString(py_obj
, "dn");
1632 msg
= ldb_msg_new(mem_ctx
);
1637 msg
->elements
= talloc_zero_array(msg
, struct ldb_message_element
, PyDict_Size(py_obj
));
1638 if (msg
->elements
== NULL
) {
1645 struct ldb_dn
*dn
= NULL
;
1646 if (!pyldb_Object_AsDn(msg
, dn_value
, ldb_ctx
, &dn
)) {
1647 PyErr_SetString(PyExc_TypeError
, "unable to import dn object");
1652 PyErr_SetString(PyExc_TypeError
, "dn set but not found");
1656 msg
->dn
= talloc_reference(msg
, dn
);
1657 if (msg
->dn
== NULL
) {
1658 talloc_free(mem_ctx
);
1663 PyErr_SetString(PyExc_TypeError
, "no dn set");
1668 while (PyDict_Next(py_obj
, &dict_pos
, &key
, &value
)) {
1669 const char *key_str
= PyUnicode_AsUTF8(key
);
1670 if (ldb_attr_cmp(key_str
, "dn") != 0) {
1671 msg_el
= PyObject_AsMessageElement(msg
->elements
, value
,
1672 mod_flags
, key_str
);
1673 if (msg_el
== NULL
) {
1674 PyErr_Format(PyExc_TypeError
, "unable to import element '%s'", key_str
);
1678 memcpy(&msg
->elements
[msg_pos
], msg_el
, sizeof(*msg_el
));
1681 * PyObject_AsMessageElement might have returned a
1682 * reference to an existing MessageElement, and so left
1683 * the name and flags unchanged. Thus if those members
1684 * aren’t set, we’ll assume that the user forgot to
1687 if (msg
->elements
[msg_pos
].name
== NULL
) {
1688 /* No name was set — set it now. */
1689 msg
->elements
[msg_pos
].name
= talloc_strdup(msg
->elements
, key_str
);
1690 if (msg
->elements
[msg_pos
].name
== NULL
) {
1696 if (msg
->elements
[msg_pos
].flags
== 0) {
1697 /* No flags were set — set them now. */
1698 msg
->elements
[msg_pos
].flags
= mod_flags
;
1705 msg
->num_elements
= msg_pos
;
1710 static PyObject
*py_ldb_add(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1714 struct ldb_context
*ldb_ctx
;
1715 struct ldb_request
*req
;
1716 struct ldb_message
*msg
= NULL
;
1717 PyObject
*py_controls
= Py_None
;
1718 TALLOC_CTX
*mem_ctx
;
1719 struct ldb_control
**parsed_controls
;
1720 const char * const kwnames
[] = { "message", "controls", NULL
};
1722 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O",
1723 discard_const_p(char *, kwnames
),
1724 &py_obj
, &py_controls
))
1727 mem_ctx
= talloc_new(NULL
);
1728 if (mem_ctx
== NULL
) {
1732 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1734 if (py_controls
== Py_None
) {
1735 parsed_controls
= NULL
;
1737 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1738 if (controls
== NULL
) {
1739 talloc_free(mem_ctx
);
1742 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1743 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
1744 talloc_free(mem_ctx
);
1745 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
1748 talloc_free(controls
);
1751 if (pyldb_Message_Check(py_obj
)) {
1752 msg
= pyldb_Message_AsMessage(py_obj
);
1753 } else if (PyDict_Check(py_obj
)) {
1754 msg
= PyDict_AsMessage(mem_ctx
, py_obj
, ldb_ctx
, LDB_FLAG_MOD_ADD
);
1756 PyErr_SetString(PyExc_TypeError
,
1757 "Dictionary or LdbMessage object expected!");
1761 /* we should have a PyErr already set */
1762 talloc_free(mem_ctx
);
1766 ret
= ldb_msg_sanity_check(ldb_ctx
, msg
);
1767 if (ret
!= LDB_SUCCESS
) {
1768 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1769 talloc_free(mem_ctx
);
1773 ret
= ldb_build_add_req(&req
, ldb_ctx
, mem_ctx
, msg
, parsed_controls
,
1774 NULL
, ldb_op_default_callback
, NULL
);
1775 if (ret
!= LDB_SUCCESS
) {
1776 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1777 talloc_free(mem_ctx
);
1781 /* do request and autostart a transaction */
1782 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1784 ret
= ldb_transaction_start(ldb_ctx
);
1785 if (ret
!= LDB_SUCCESS
) {
1786 talloc_free(mem_ctx
);
1787 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1791 ret
= ldb_request(ldb_ctx
, req
);
1792 if (ret
== LDB_SUCCESS
) {
1793 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1796 if (ret
== LDB_SUCCESS
) {
1797 ret
= ldb_transaction_commit(ldb_ctx
);
1799 ldb_transaction_cancel(ldb_ctx
);
1802 talloc_free(mem_ctx
);
1803 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1808 static PyObject
*py_ldb_delete(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1813 struct ldb_context
*ldb_ctx
;
1814 struct ldb_request
*req
;
1815 PyObject
*py_controls
= Py_None
;
1816 TALLOC_CTX
*mem_ctx
;
1817 struct ldb_control
**parsed_controls
;
1818 const char * const kwnames
[] = { "dn", "controls", NULL
};
1820 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O",
1821 discard_const_p(char *, kwnames
),
1822 &py_dn
, &py_controls
))
1825 mem_ctx
= talloc_new(NULL
);
1826 if (mem_ctx
== NULL
) {
1830 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1832 if (py_controls
== Py_None
) {
1833 parsed_controls
= NULL
;
1835 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1836 if (controls
== NULL
) {
1837 talloc_free(mem_ctx
);
1840 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1841 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
1842 talloc_free(mem_ctx
);
1843 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
1846 talloc_free(controls
);
1849 if (!pyldb_Object_AsDn(mem_ctx
, py_dn
, ldb_ctx
, &dn
)) {
1850 talloc_free(mem_ctx
);
1854 ret
= ldb_build_del_req(&req
, ldb_ctx
, mem_ctx
, dn
, parsed_controls
,
1855 NULL
, ldb_op_default_callback
, NULL
);
1856 if (ret
!= LDB_SUCCESS
) {
1857 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1858 talloc_free(mem_ctx
);
1862 /* do request and autostart a transaction */
1863 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1865 ret
= ldb_transaction_start(ldb_ctx
);
1866 if (ret
!= LDB_SUCCESS
) {
1867 talloc_free(mem_ctx
);
1868 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1872 ret
= ldb_request(ldb_ctx
, req
);
1873 if (ret
== LDB_SUCCESS
) {
1874 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1877 if (ret
== LDB_SUCCESS
) {
1878 ret
= ldb_transaction_commit(ldb_ctx
);
1880 ldb_transaction_cancel(ldb_ctx
);
1883 talloc_free(mem_ctx
);
1884 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1889 static PyObject
*py_ldb_rename(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1891 PyObject
*py_dn1
, *py_dn2
;
1892 struct ldb_dn
*dn1
, *dn2
;
1894 TALLOC_CTX
*mem_ctx
;
1895 PyObject
*py_controls
= Py_None
;
1896 struct ldb_control
**parsed_controls
;
1897 struct ldb_context
*ldb_ctx
;
1898 struct ldb_request
*req
;
1899 const char * const kwnames
[] = { "dn1", "dn2", "controls", NULL
};
1901 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1903 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|O",
1904 discard_const_p(char *, kwnames
),
1905 &py_dn1
, &py_dn2
, &py_controls
))
1909 mem_ctx
= talloc_new(NULL
);
1910 if (mem_ctx
== NULL
) {
1915 if (py_controls
== Py_None
) {
1916 parsed_controls
= NULL
;
1918 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1919 if (controls
== NULL
) {
1920 talloc_free(mem_ctx
);
1923 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1924 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
1925 talloc_free(mem_ctx
);
1926 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
1929 talloc_free(controls
);
1933 if (!pyldb_Object_AsDn(mem_ctx
, py_dn1
, ldb_ctx
, &dn1
)) {
1934 talloc_free(mem_ctx
);
1938 if (!pyldb_Object_AsDn(mem_ctx
, py_dn2
, ldb_ctx
, &dn2
)) {
1939 talloc_free(mem_ctx
);
1943 ret
= ldb_build_rename_req(&req
, ldb_ctx
, mem_ctx
, dn1
, dn2
, parsed_controls
,
1944 NULL
, ldb_op_default_callback
, NULL
);
1945 if (ret
!= LDB_SUCCESS
) {
1946 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1947 talloc_free(mem_ctx
);
1951 /* do request and autostart a transaction */
1952 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1954 ret
= ldb_transaction_start(ldb_ctx
);
1955 if (ret
!= LDB_SUCCESS
) {
1956 talloc_free(mem_ctx
);
1957 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1961 ret
= ldb_request(ldb_ctx
, req
);
1962 if (ret
== LDB_SUCCESS
) {
1963 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1966 if (ret
== LDB_SUCCESS
) {
1967 ret
= ldb_transaction_commit(ldb_ctx
);
1969 ldb_transaction_cancel(ldb_ctx
);
1972 talloc_free(mem_ctx
);
1973 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1978 static PyObject
*py_ldb_schema_attribute_remove(PyLdbObject
*self
, PyObject
*args
)
1981 if (!PyArg_ParseTuple(args
, "s", &name
))
1984 ldb_schema_attribute_remove(pyldb_Ldb_AS_LDBCONTEXT(self
), name
);
1989 static PyObject
*py_ldb_schema_attribute_add(PyLdbObject
*self
, PyObject
*args
)
1991 char *attribute
, *syntax
;
1994 struct ldb_context
*ldb_ctx
;
1996 if (!PyArg_ParseTuple(args
, "sIs", &attribute
, &flags
, &syntax
))
1999 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2000 ret
= ldb_schema_attribute_add(ldb_ctx
, attribute
, flags
, syntax
);
2002 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
2007 static PyObject
*ldb_ldif_to_pyobject(PyLdbObject
*pyldb
, struct ldb_ldif
*ldif
)
2009 PyObject
*obj
= NULL
;
2010 PyObject
*result
= NULL
;
2011 struct ldb_context
*ldb
= pyldb
->ldb_ctx
;
2017 switch (ldif
->changetype
) {
2018 case LDB_CHANGETYPE_NONE
:
2019 case LDB_CHANGETYPE_ADD
:
2020 obj
= PyLdbMessage_FromMessage(ldif
->msg
, pyldb
);
2022 case LDB_CHANGETYPE_MODIFY
:
2023 obj
= PyLdbMessage_FromMessage(ldif
->msg
, pyldb
);
2025 case LDB_CHANGETYPE_DELETE
:
2026 if (ldif
->msg
->num_elements
!= 0) {
2027 PyErr_Format(PyExc_ValueError
,
2028 "CHANGETYPE(DELETE) with num_elements=%u",
2029 ldif
->msg
->num_elements
);
2032 obj
= pyldb_Dn_FromDn(ldif
->msg
->dn
, pyldb
);
2034 case LDB_CHANGETYPE_MODRDN
: {
2035 struct ldb_dn
*olddn
= NULL
;
2036 PyObject
*olddn_obj
= NULL
;
2037 bool deleteoldrdn
= false;
2038 PyObject
*deleteoldrdn_obj
= NULL
;
2039 struct ldb_dn
*newdn
= NULL
;
2040 PyObject
*newdn_obj
= NULL
;
2043 ret
= ldb_ldif_parse_modrdn(ldb
,
2051 if (ret
!= LDB_SUCCESS
) {
2052 PyErr_Format(PyExc_ValueError
,
2053 "ldb_ldif_parse_modrdn() failed");
2057 olddn_obj
= pyldb_Dn_FromDn(olddn
, pyldb
);
2058 if (olddn_obj
== NULL
) {
2062 deleteoldrdn_obj
= Py_True
;
2064 deleteoldrdn_obj
= Py_False
;
2066 newdn_obj
= pyldb_Dn_FromDn(newdn
, pyldb
);
2067 if (newdn_obj
== NULL
) {
2068 deleteoldrdn_obj
= NULL
;
2069 Py_CLEAR(olddn_obj
);
2073 obj
= Py_BuildValue(discard_const_p(char, "{s:O,s:O,s:O}"),
2075 "deleteoldrdn", deleteoldrdn_obj
,
2076 "newdn", newdn_obj
);
2077 Py_CLEAR(olddn_obj
);
2078 deleteoldrdn_obj
= NULL
;
2079 Py_CLEAR(newdn_obj
);
2083 PyErr_Format(PyExc_NotImplementedError
,
2084 "Unsupported LDB_CHANGETYPE(%u)",
2093 /* We don't want this being attached * to the 'ldb' any more */
2094 result
= Py_BuildValue(discard_const_p(char, "(iO)"),
2102 static PyObject
*py_ldb_write_ldif(PyLdbObject
*self
, PyObject
*args
)
2106 struct ldb_ldif ldif
;
2109 TALLOC_CTX
*mem_ctx
;
2111 if (!PyArg_ParseTuple(args
, "Oi", &py_msg
, &changetype
))
2114 if (!pyldb_Message_Check(py_msg
)) {
2115 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for msg");
2119 ldif
.msg
= pyldb_Message_AsMessage(py_msg
);
2120 ldif
.changetype
= changetype
;
2122 mem_ctx
= talloc_new(NULL
);
2123 if (mem_ctx
== NULL
) {
2124 return PyErr_NoMemory();
2127 string
= ldb_ldif_write_string(pyldb_Ldb_AS_LDBCONTEXT(self
), mem_ctx
, &ldif
);
2129 PyErr_SetString(PyExc_KeyError
, "Failed to generate LDIF");
2130 talloc_free(mem_ctx
);
2134 ret
= PyUnicode_FromString(string
);
2136 talloc_free(mem_ctx
);
2141 static PyObject
*py_ldb_parse_ldif(PyLdbObject
*self
, PyObject
*args
)
2143 PyObject
*list
, *ret
;
2144 struct ldb_ldif
*ldif
;
2146 struct ldb_dn
*last_dn
= NULL
;
2148 TALLOC_CTX
*mem_ctx
;
2150 if (!PyArg_ParseTuple(args
, "s", &s
))
2153 mem_ctx
= talloc_new(NULL
);
2158 list
= PyList_New(0);
2160 talloc_free(mem_ctx
);
2164 while (s
&& *s
!= '\0') {
2165 ldif
= ldb_ldif_read_string(self
->ldb_ctx
, &s
);
2166 talloc_steal(mem_ctx
, ldif
);
2169 PyObject
*py_ldif
= ldb_ldif_to_pyobject(self
, ldif
);
2170 if (py_ldif
== NULL
) {
2172 if (PyErr_Occurred() == NULL
) {
2173 PyErr_BadArgument();
2175 talloc_free(mem_ctx
);
2178 res
= PyList_Append(list
, py_ldif
);
2182 talloc_free(mem_ctx
);
2185 last_dn
= ldif
->msg
->dn
;
2187 const char *last_dn_str
= NULL
;
2188 const char *err_string
= NULL
;
2189 if (last_dn
== NULL
) {
2190 PyErr_SetString(PyExc_ValueError
,
2191 "unable to parse LDIF "
2192 "string at first chunk");
2194 talloc_free(mem_ctx
);
2199 = ldb_dn_get_linearized(last_dn
);
2202 = talloc_asprintf(mem_ctx
,
2203 "unable to parse ldif "
2207 PyErr_SetString(PyExc_ValueError
,
2209 talloc_free(mem_ctx
);
2214 talloc_free(mem_ctx
); /* The pyobject already has a reference to the things it needs */
2215 ret
= PyObject_GetIter(list
);
2220 static PyObject
*py_ldb_msg_diff(PyLdbObject
*self
, PyObject
*args
)
2223 PyObject
*py_msg_old
;
2224 PyObject
*py_msg_new
;
2225 struct ldb_message
*diff
;
2226 struct ldb_context
*ldb
;
2228 TALLOC_CTX
*mem_ctx
= NULL
;
2230 if (!PyArg_ParseTuple(args
, "OO", &py_msg_old
, &py_msg_new
))
2233 if (!pyldb_Message_Check(py_msg_old
)) {
2234 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for old message");
2238 if (!pyldb_Message_Check(py_msg_new
)) {
2239 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for new message");
2243 mem_ctx
= talloc_new(NULL
);
2244 if (mem_ctx
== NULL
) {
2249 ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2250 ldb_ret
= ldb_msg_difference(ldb
, mem_ctx
,
2251 pyldb_Message_AsMessage(py_msg_old
),
2252 pyldb_Message_AsMessage(py_msg_new
),
2254 if (ldb_ret
!= LDB_SUCCESS
) {
2255 talloc_free(mem_ctx
);
2256 PyErr_SetString(PyExc_RuntimeError
, "Failed to generate the Ldb Message diff");
2260 diff
= ldb_msg_copy(mem_ctx
, diff
);
2262 talloc_free(mem_ctx
);
2267 py_ret
= PyLdbMessage_FromMessage(diff
, self
);
2269 talloc_free(mem_ctx
);
2274 static PyObject
*py_ldb_schema_format_value(PyLdbObject
*self
, PyObject
*args
)
2276 const struct ldb_schema_attribute
*a
;
2277 struct ldb_val old_val
;
2278 struct ldb_val new_val
;
2279 TALLOC_CTX
*mem_ctx
;
2286 if (!PyArg_ParseTuple(args
, "sO", &element_name
, &val
))
2289 result
= PyBytes_AsStringAndSize(val
, (char **)&old_val
.data
, &size
);
2290 old_val
.length
= size
;
2293 PyErr_SetString(PyExc_RuntimeError
, "Failed to convert passed value to String");
2297 a
= ldb_schema_attribute_by_name(pyldb_Ldb_AS_LDBCONTEXT(self
), element_name
);
2303 mem_ctx
= talloc_new(NULL
);
2304 if (mem_ctx
== NULL
) {
2309 if (a
->syntax
->ldif_write_fn(pyldb_Ldb_AS_LDBCONTEXT(self
), mem_ctx
, &old_val
, &new_val
) != 0) {
2310 talloc_free(mem_ctx
);
2314 ret
= PyBytes_FromStringAndSize((const char *)new_val
.data
, new_val
.length
);
2316 talloc_free(mem_ctx
);
2321 static PyObject
*py_ldb_search(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
2323 PyObject
*py_base
= Py_None
;
2324 int scope
= LDB_SCOPE_DEFAULT
;
2326 PyObject
*py_attrs
= Py_None
;
2327 PyObject
*py_controls
= Py_None
;
2328 const char * const kwnames
[] = { "base", "scope", "expression", "attrs", "controls", NULL
};
2330 struct ldb_result
*res
;
2331 struct ldb_request
*req
;
2333 struct ldb_context
*ldb_ctx
;
2334 struct ldb_control
**parsed_controls
;
2335 struct ldb_dn
*base
;
2337 TALLOC_CTX
*mem_ctx
;
2339 /* type "int" rather than "enum" for "scope" is intentional */
2340 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OizOO",
2341 discard_const_p(char *, kwnames
),
2342 &py_base
, &scope
, &expr
, &py_attrs
, &py_controls
))
2346 mem_ctx
= talloc_new(NULL
);
2347 if (mem_ctx
== NULL
) {
2351 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2353 if (py_attrs
== Py_None
) {
2356 attrs
= PyList_AsStrList(mem_ctx
, py_attrs
, "attrs");
2357 if (attrs
== NULL
) {
2358 talloc_free(mem_ctx
);
2363 if (py_base
== Py_None
) {
2364 base
= ldb_get_default_basedn(ldb_ctx
);
2366 if (!pyldb_Object_AsDn(mem_ctx
, py_base
, ldb_ctx
, &base
)) {
2367 talloc_free(mem_ctx
);
2372 if (py_controls
== Py_None
) {
2373 parsed_controls
= NULL
;
2375 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
2376 if (controls
== NULL
) {
2377 talloc_free(mem_ctx
);
2380 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
2381 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
2382 talloc_free(mem_ctx
);
2383 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
2386 talloc_free(controls
);
2389 res
= talloc_zero(mem_ctx
, struct ldb_result
);
2392 talloc_free(mem_ctx
);
2396 ret
= ldb_build_search_req(&req
, ldb_ctx
, mem_ctx
,
2403 ldb_search_default_callback
,
2406 if (ret
!= LDB_SUCCESS
) {
2407 talloc_free(mem_ctx
);
2408 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2412 talloc_steal(req
, attrs
);
2414 ret
= ldb_request(ldb_ctx
, req
);
2416 if (ret
== LDB_SUCCESS
) {
2417 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
2420 if (ret
!= LDB_SUCCESS
) {
2421 talloc_free(mem_ctx
);
2422 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2426 py_ret
= PyLdbResult_FromResult(res
, self
);
2428 talloc_free(mem_ctx
);
2433 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply
*reply
)
2435 if (reply
->py_iter
!= NULL
) {
2436 DLIST_REMOVE(reply
->py_iter
->state
.next
, reply
);
2437 if (reply
->py_iter
->state
.result
== reply
) {
2438 reply
->py_iter
->state
.result
= NULL
;
2440 reply
->py_iter
= NULL
;
2443 Py_CLEAR(reply
->obj
);
2448 static int py_ldb_search_iterator_callback(struct ldb_request
*req
,
2449 struct ldb_reply
*ares
)
2451 PyLdbSearchIteratorObject
*py_iter
= (PyLdbSearchIteratorObject
*)req
->context
;
2452 struct ldb_result result
= { .msgs
= NULL
};
2453 struct py_ldb_search_iterator_reply
*reply
= NULL
;
2456 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2459 if (ares
->error
!= LDB_SUCCESS
) {
2460 int ret
= ares
->error
;
2462 return ldb_request_done(req
, ret
);
2465 reply
= talloc_zero(py_iter
->mem_ctx
,
2466 struct py_ldb_search_iterator_reply
);
2467 if (reply
== NULL
) {
2469 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2471 reply
->py_iter
= py_iter
;
2472 talloc_set_destructor(reply
, py_ldb_search_iterator_reply_destructor
);
2474 switch (ares
->type
) {
2475 case LDB_REPLY_ENTRY
:
2476 reply
->obj
= PyLdbMessage_FromMessage(ares
->message
, py_iter
->ldb
);
2477 if (reply
->obj
== NULL
) {
2479 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2481 DLIST_ADD_END(py_iter
->state
.next
, reply
);
2485 case LDB_REPLY_REFERRAL
:
2486 reply
->obj
= PyUnicode_FromString(ares
->referral
);
2487 if (reply
->obj
== NULL
) {
2489 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2491 DLIST_ADD_END(py_iter
->state
.next
, reply
);
2495 case LDB_REPLY_DONE
:
2496 result
= (struct ldb_result
) { .controls
= ares
->controls
};
2497 reply
->obj
= PyLdbResult_FromResult(&result
, py_iter
->ldb
);
2498 if (reply
->obj
== NULL
) {
2500 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2502 py_iter
->state
.result
= reply
;
2504 return ldb_request_done(req
, LDB_SUCCESS
);
2508 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2511 static PyObject
*py_ldb_search_iterator(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
2513 PyObject
*py_base
= Py_None
;
2514 int scope
= LDB_SCOPE_DEFAULT
;
2517 PyObject
*py_attrs
= Py_None
;
2518 PyObject
*py_controls
= Py_None
;
2519 const char * const kwnames
[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL
};
2522 struct ldb_context
*ldb_ctx
;
2523 struct ldb_control
**parsed_controls
;
2524 struct ldb_dn
*base
;
2525 PyLdbSearchIteratorObject
*py_iter
;
2527 /* type "int" rather than "enum" for "scope" is intentional */
2528 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OizOOi",
2529 discard_const_p(char *, kwnames
),
2530 &py_base
, &scope
, &expr
, &py_attrs
, &py_controls
, &timeout
))
2533 py_iter
= (PyLdbSearchIteratorObject
*)PyLdbSearchIterator
.tp_alloc(&PyLdbSearchIterator
, 0);
2534 if (py_iter
== NULL
) {
2538 py_iter
->ldb
= self
;
2540 ZERO_STRUCT(py_iter
->state
);
2541 py_iter
->mem_ctx
= talloc_new(NULL
);
2542 if (py_iter
->mem_ctx
== NULL
) {
2548 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2550 if (py_attrs
== Py_None
) {
2553 attrs
= PyList_AsStrList(py_iter
->mem_ctx
, py_attrs
, "attrs");
2554 if (attrs
== NULL
) {
2561 if (py_base
== Py_None
) {
2562 base
= ldb_get_default_basedn(ldb_ctx
);
2564 if (!pyldb_Object_AsDn(py_iter
->mem_ctx
, py_base
, ldb_ctx
, &base
)) {
2571 if (py_controls
== Py_None
) {
2572 parsed_controls
= NULL
;
2574 const char **controls
= NULL
;
2576 controls
= PyList_AsStrList(py_iter
->mem_ctx
,
2577 py_controls
, "controls");
2578 if (controls
== NULL
) {
2584 parsed_controls
= ldb_parse_control_strings(ldb_ctx
,
2587 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
2589 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
2592 talloc_free(controls
);
2595 ret
= ldb_build_search_req(&py_iter
->state
.req
,
2604 py_ldb_search_iterator_callback
,
2606 if (ret
!= LDB_SUCCESS
) {
2608 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2612 ldb_set_timeout(ldb_ctx
, py_iter
->state
.req
, timeout
);
2614 ret
= ldb_request(ldb_ctx
, py_iter
->state
.req
);
2615 if (ret
!= LDB_SUCCESS
) {
2617 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2621 return (PyObject
*)py_iter
;
2624 static PyObject
*py_ldb_get_opaque(PyLdbObject
*self
, PyObject
*args
)
2629 if (!PyArg_ParseTuple(args
, "s", &name
))
2632 data
= ldb_get_opaque(pyldb_Ldb_AS_LDBCONTEXT(self
), name
);
2637 if (data
== (void *)1) {
2639 * This value is sometimes used to indicate that a opaque is
2647 * Let’s hope the opaque data is actually a talloc pointer,
2648 * otherwise calling this would be Very Bad.
2650 const bool *opaque
= talloc_get_type(data
, bool);
2651 if (opaque
!= NULL
) {
2652 return PyBool_FromLong(*opaque
);
2657 const unsigned long long *opaque
= talloc_get_type(
2658 data
, unsigned long long);
2659 if (opaque
!= NULL
) {
2660 return PyLong_FromUnsignedLongLong(*opaque
);
2665 const char *opaque
= talloc_get_type(data
, char);
2666 if (opaque
!= NULL
) {
2667 return PyUnicode_FromString(opaque
);
2671 PyErr_SetString(PyExc_ValueError
, "Unsupported type for opaque");
2675 static PyObject
*py_ldb_set_opaque(PyLdbObject
*self
, PyObject
*args
)
2682 if (!PyArg_ParseTuple(args
, "sO", &name
, &data
))
2685 if (data
== Py_None
) {
2687 } else if (PyBool_Check(data
)) {
2688 bool *opaque
= NULL
;
2691 const int is_true
= PyObject_IsTrue(data
);
2692 if (is_true
== -1) {
2698 opaque
= talloc(self
->ldb_ctx
, bool);
2699 if (opaque
== NULL
) {
2700 return PyErr_NoMemory();
2704 } else if (PyLong_Check(data
)) {
2705 unsigned long long *opaque
= NULL
;
2706 const unsigned long long n
= PyLong_AsUnsignedLongLong(data
);
2707 if (n
== -1 && PyErr_Occurred()) {
2711 opaque
= talloc(self
->ldb_ctx
, unsigned long long);
2712 if (opaque
== NULL
) {
2713 return PyErr_NoMemory();
2717 } else if (PyUnicode_Check(data
)) {
2718 char *opaque
= NULL
;
2719 const char *s
= PyUnicode_AsUTF8(data
);
2724 opaque
= talloc_strdup(self
->ldb_ctx
, s
);
2725 if (opaque
== NULL
) {
2726 return PyErr_NoMemory();
2730 * Assign the right type to the talloc pointer, so that
2731 * py_ldb_get_opaque() can recognize it.
2733 talloc_set_name_const(opaque
, "char");
2737 PyErr_SetString(PyExc_ValueError
,
2738 "Unsupported type for opaque");
2742 ret
= ldb_set_opaque(pyldb_Ldb_AS_LDBCONTEXT(self
), name
, value
);
2744 PyErr_SetLdbError(PyExc_LdbError
,
2746 pyldb_Ldb_AS_LDBCONTEXT(self
));
2753 static PyObject
*py_ldb_sequence_number(PyLdbObject
*self
, PyObject
*args
)
2755 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2759 if (!PyArg_ParseTuple(args
, "i", &type
))
2762 /* FIXME: More interpretation */
2764 ret
= ldb_sequence_number(ldb
, type
, &value
);
2766 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2768 return PyLong_FromLongLong(value
);
2771 static PyObject
*py_ldb_whoami(PyLdbObject
*self
, PyObject
*args
)
2773 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2774 struct ldb_result
*res
= NULL
;
2775 struct ldb_extended
*ext_res
= NULL
;
2779 ret
= ldb_extended(ldb
, LDB_EXTENDED_WHOAMI_OID
, NULL
, &res
);
2780 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2782 ext_res
= res
->extended
;
2783 if (ext_res
== NULL
) {
2784 PyErr_SetString(PyExc_TypeError
, "Got no exop reply");
2788 if (strcmp(ext_res
->oid
, LDB_EXTENDED_WHOAMI_OID
) != 0) {
2789 PyErr_SetString(PyExc_TypeError
, "Got wrong reply OID");
2793 len
= talloc_get_size(ext_res
->data
);
2798 return PyUnicode_FromStringAndSize(ext_res
->data
, len
);
2801 static PyObject
*py_ldb_disconnect(PyLdbObject
*self
, PyObject
*args
)
2804 void *parent
= NULL
;
2805 TALLOC_CTX
*mem_ctx
= NULL
;
2806 struct ldb_context
*ldb
= NULL
;
2808 if (self
->ldb_ctx
== NULL
) {
2809 /* It is hard to see how we'd get here. */
2810 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, NULL
);
2814 ref_count
= talloc_reference_count(self
->ldb_ctx
);
2816 if (ref_count
!= 0) {
2817 PyErr_SetString(PyExc_RuntimeError
,
2818 "ldb.disconnect() not possible as "
2819 "object still has C (or second "
2820 "python object) references");
2824 parent
= talloc_parent(self
->ldb_ctx
);
2826 if (parent
!= self
->mem_ctx
) {
2827 PyErr_SetString(PyExc_RuntimeError
,
2828 "ldb.disconnect() not possible as "
2829 "object is not talloc owned by this "
2835 * This recapitulates py_ldb_new(), cleaning out all the
2836 * connections and state, but leaving the python object in a
2837 * workable condition.
2839 mem_ctx
= talloc_new(NULL
);
2840 if (mem_ctx
== NULL
) {
2841 return PyErr_NoMemory();
2844 ldb
= ldb_init(mem_ctx
, NULL
);
2846 talloc_free(mem_ctx
);
2852 * Notice we allocate the new mem_ctx and ldb before freeing
2853 * the old one. This has two purposes: 1, the python object
2854 * will still be consistent if an exception happens, and 2, it
2855 * ensures the new ldb can't have the same memory address as
2856 * the old one, and ldb address equality is a guard we use in
2857 * Python DNs and such. Repeated calls to disconnect() *can* make
2858 * this happen, so we don't advise doing that.
2860 TALLOC_FREE(self
->mem_ctx
);
2862 self
->mem_ctx
= mem_ctx
;
2863 self
->ldb_ctx
= ldb
;
2869 static const struct ldb_dn_extended_syntax test_dn_syntax
= {
2871 .read_fn
= ldb_handler_copy
,
2872 .write_clear_fn
= ldb_handler_copy
,
2873 .write_hex_fn
= ldb_handler_copy
,
2876 static PyObject
*py_ldb_register_test_extensions(PyLdbObject
*self
,
2877 PyObject
*Py_UNUSED(ignored
))
2879 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2882 ret
= ldb_dn_extended_add_syntax(ldb
, LDB_ATTR_FLAG_FIXED
, &test_dn_syntax
);
2884 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2890 static PyMethodDef py_ldb_methods
[] = {
2891 { "set_debug", (PyCFunction
)py_ldb_set_debug
, METH_VARARGS
,
2892 "S.set_debug(callback) -> None\n"
2893 "Set callback for LDB debug messages.\n"
2894 "The callback should accept a debug level and debug text." },
2895 { "set_create_perms", (PyCFunction
)py_ldb_set_create_perms
, METH_VARARGS
,
2896 "S.set_create_perms(mode) -> None\n"
2897 "Set mode to use when creating new LDB files." },
2898 { "set_modules_dir", (PyCFunction
)py_ldb_set_modules_dir
, METH_VARARGS
,
2899 "S.set_modules_dir(path) -> None\n"
2900 "Set path LDB should search for modules" },
2901 { "transaction_start", (PyCFunction
)py_ldb_transaction_start
, METH_NOARGS
,
2902 "S.transaction_start() -> None\n"
2903 "Start a new transaction." },
2904 { "transaction_prepare_commit", (PyCFunction
)py_ldb_transaction_prepare_commit
, METH_NOARGS
,
2905 "S.transaction_prepare_commit() -> None\n"
2906 "prepare to commit a new transaction (2-stage commit)." },
2907 { "transaction_commit", (PyCFunction
)py_ldb_transaction_commit
, METH_NOARGS
,
2908 "S.transaction_commit() -> None\n"
2909 "commit a new transaction." },
2910 { "transaction_cancel", (PyCFunction
)py_ldb_transaction_cancel
, METH_NOARGS
,
2911 "S.transaction_cancel() -> None\n"
2912 "cancel a new transaction." },
2913 { "setup_wellknown_attributes", (PyCFunction
)py_ldb_setup_wellknown_attributes
, METH_NOARGS
,
2915 { "get_root_basedn", (PyCFunction
)py_ldb_get_root_basedn
, METH_NOARGS
,
2917 { "get_schema_basedn", (PyCFunction
)py_ldb_get_schema_basedn
, METH_NOARGS
,
2919 { "get_default_basedn", (PyCFunction
)py_ldb_get_default_basedn
, METH_NOARGS
,
2921 { "get_config_basedn", (PyCFunction
)py_ldb_get_config_basedn
, METH_NOARGS
,
2923 { "connect", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_connect
),
2924 METH_VARARGS
|METH_KEYWORDS
,
2925 "S.connect(url, flags=0, options=None) -> None\n"
2926 "Connect to a LDB URL." },
2927 { "modify", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_modify
),
2928 METH_VARARGS
|METH_KEYWORDS
,
2929 "S.modify(message, controls=None, validate=False) -> None\n"
2930 "Modify an entry." },
2931 { "add", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_add
),
2932 METH_VARARGS
|METH_KEYWORDS
,
2933 "S.add(message, controls=None) -> None\n"
2935 { "delete", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_delete
),
2936 METH_VARARGS
|METH_KEYWORDS
,
2937 "S.delete(dn, controls=None) -> None\n"
2938 "Remove an entry." },
2939 { "rename", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_rename
),
2940 METH_VARARGS
|METH_KEYWORDS
,
2941 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2942 "Rename an entry." },
2943 { "search", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_search
),
2944 METH_VARARGS
|METH_KEYWORDS
,
2945 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2946 "Search in a database.\n"
2948 ":param base: Optional base DN to search\n"
2949 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2950 ":param expression: Optional search expression\n"
2951 ":param attrs: Attributes to return (defaults to all)\n"
2952 ":param controls: Optional list of controls\n"
2953 ":return: ldb.Result object\n"
2955 { "search_iterator", PY_DISCARD_FUNC_SIG(PyCFunction
,
2956 py_ldb_search_iterator
),
2957 METH_VARARGS
|METH_KEYWORDS
,
2958 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2959 "Search in a database.\n"
2961 ":param base: Optional base DN to search\n"
2962 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2963 ":param expression: Optional search expression\n"
2964 ":param attrs: Attributes to return (defaults to all)\n"
2965 ":param controls: Optional list of controls\n"
2966 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2967 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2969 { "schema_attribute_remove", (PyCFunction
)py_ldb_schema_attribute_remove
, METH_VARARGS
,
2971 { "schema_attribute_add", (PyCFunction
)py_ldb_schema_attribute_add
, METH_VARARGS
,
2973 { "schema_format_value", (PyCFunction
)py_ldb_schema_format_value
, METH_VARARGS
,
2975 { "parse_ldif", (PyCFunction
)py_ldb_parse_ldif
, METH_VARARGS
,
2976 "S.parse_ldif(ldif) -> iter(messages)\n"
2977 "Parse a string formatted using LDIF." },
2978 { "write_ldif", (PyCFunction
)py_ldb_write_ldif
, METH_VARARGS
,
2979 "S.write_ldif(message, changetype) -> ldif\n"
2980 "Print the message as a string formatted using LDIF." },
2981 { "msg_diff", (PyCFunction
)py_ldb_msg_diff
, METH_VARARGS
,
2982 "S.msg_diff(Message) -> Message\n"
2983 "Return an LDB Message of the difference between two Message objects." },
2984 { "get_opaque", (PyCFunction
)py_ldb_get_opaque
, METH_VARARGS
,
2985 "S.get_opaque(name) -> value\n"
2986 "Get an opaque value set on this LDB connection. \n"
2987 ":note: The returned value may not be useful in Python."
2989 { "set_opaque", (PyCFunction
)py_ldb_set_opaque
, METH_VARARGS
,
2990 "S.set_opaque(name, value) -> None\n"
2991 "Set an opaque value on this LDB connection. \n"
2992 ":note: Passing incorrect values may cause crashes." },
2993 { "sequence_number", (PyCFunction
)py_ldb_sequence_number
, METH_VARARGS
,
2994 "S.sequence_number(type) -> value\n"
2995 "Return the value of the sequence according to the requested type" },
2997 (PyCFunction
)py_ldb_whoami
,
2999 "S.whoami() -> value\n"
3000 "Return the RFC4532 whoami string",
3003 (PyCFunction
)py_ldb_disconnect
,
3005 "S.disconnect() -> None\n"
3006 "Make this Ldb object unusable, disconnect and free the "
3007 "underlying LDB, releasing any file handles and sockets.",
3009 { "_register_test_extensions", (PyCFunction
)py_ldb_register_test_extensions
, METH_NOARGS
,
3010 "S._register_test_extensions() -> None\n"
3011 "Register internal extensions used in testing" },
3015 static int py_ldb_contains(PyLdbObject
*self
, PyObject
*obj
)
3017 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
3019 struct ldb_result
*result
;
3023 if (!pyldb_Object_AsDn(ldb_ctx
, obj
, ldb_ctx
, &dn
)) {
3027 ret
= ldb_search(ldb_ctx
, ldb_ctx
, &result
, dn
, LDB_SCOPE_BASE
, NULL
,
3029 if (ret
!= LDB_SUCCESS
) {
3030 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
3034 count
= result
->count
;
3036 talloc_free(result
);
3039 PyErr_Format(PyExc_RuntimeError
,
3040 "Searching for [%s] dn gave %u results!",
3041 ldb_dn_get_linearized(dn
),
3049 static PySequenceMethods py_ldb_seq
= {
3050 .sq_contains
= (objobjproc
)py_ldb_contains
,
3053 static void py_ldb_dealloc(PyLdbObject
*self
)
3055 talloc_free(self
->mem_ctx
);
3056 Py_TYPE(self
)->tp_free(self
);
3059 static PyTypeObject PyLdb
= {
3060 .tp_name
= "ldb.Ldb",
3061 .tp_methods
= py_ldb_methods
,
3062 .tp_repr
= (reprfunc
)py_ldb_repr
,
3063 .tp_new
= py_ldb_new
,
3064 .tp_init
= (initproc
)py_ldb_init
,
3065 .tp_dealloc
= (destructor
)py_ldb_dealloc
,
3066 .tp_getattro
= PyObject_GenericGetAttr
,
3067 .tp_basicsize
= sizeof(PyLdbObject
),
3068 .tp_doc
= "Connection to a LDB database.",
3069 .tp_as_sequence
= &py_ldb_seq
,
3070 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
3073 static void py_ldb_result_dealloc(PyLdbResultObject
*self
)
3075 talloc_free(self
->mem_ctx
);
3076 Py_CLEAR(self
->msgs
);
3077 Py_CLEAR(self
->referals
);
3078 Py_CLEAR(self
->controls
);
3079 Py_DECREF(self
->pyldb
);
3080 Py_TYPE(self
)->tp_free(self
);
3083 static PyObject
*py_ldb_result_get_msgs(PyLdbResultObject
*self
, void *closure
)
3085 Py_INCREF(self
->msgs
);
3089 static PyObject
*py_ldb_result_get_controls(PyLdbResultObject
*self
, void *closure
)
3091 Py_INCREF(self
->controls
);
3092 return self
->controls
;
3095 static PyObject
*py_ldb_result_get_referals(PyLdbResultObject
*self
, void *closure
)
3097 Py_INCREF(self
->referals
);
3098 return self
->referals
;
3101 static PyObject
*py_ldb_result_get_count(PyLdbResultObject
*self
, void *closure
)
3104 if (self
->msgs
== NULL
) {
3105 PyErr_SetString(PyExc_AttributeError
, "Count attribute is meaningless in this context");
3108 size
= PyList_Size(self
->msgs
);
3109 return PyLong_FromLong(size
);
3112 static PyGetSetDef py_ldb_result_getset
[] = {
3114 .name
= discard_const_p(char, "controls"),
3115 .get
= (getter
)py_ldb_result_get_controls
,
3118 .name
= discard_const_p(char, "msgs"),
3119 .get
= (getter
)py_ldb_result_get_msgs
,
3122 .name
= discard_const_p(char, "referals"),
3123 .get
= (getter
)py_ldb_result_get_referals
,
3126 .name
= discard_const_p(char, "count"),
3127 .get
= (getter
)py_ldb_result_get_count
,
3132 static PyObject
*py_ldb_result_iter(PyLdbResultObject
*self
)
3134 return PyObject_GetIter(self
->msgs
);
3137 static Py_ssize_t
py_ldb_result_len(PyLdbResultObject
*self
)
3139 return PySequence_Size(self
->msgs
);
3142 static PyObject
*py_ldb_result_find(PyLdbResultObject
*self
, Py_ssize_t idx
)
3144 return PySequence_GetItem(self
->msgs
, idx
);
3147 static PySequenceMethods py_ldb_result_seq
= {
3148 .sq_length
= (lenfunc
)py_ldb_result_len
,
3149 .sq_item
= (ssizeargfunc
)py_ldb_result_find
,
3152 static PyObject
*py_ldb_result_repr(PyLdbObject
*self
)
3154 return PyUnicode_FromString("<ldb result>");
3158 static PyTypeObject PyLdbResult
= {
3159 .tp_name
= "ldb.Result",
3160 .tp_repr
= (reprfunc
)py_ldb_result_repr
,
3161 .tp_dealloc
= (destructor
)py_ldb_result_dealloc
,
3162 .tp_iter
= (getiterfunc
)py_ldb_result_iter
,
3163 .tp_getset
= py_ldb_result_getset
,
3164 .tp_getattro
= PyObject_GenericGetAttr
,
3165 .tp_basicsize
= sizeof(PyLdbResultObject
),
3166 .tp_as_sequence
= &py_ldb_result_seq
,
3167 .tp_doc
= "LDB result.",
3168 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
3171 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject
*self
)
3173 Py_CLEAR(self
->state
.exception
);
3174 TALLOC_FREE(self
->mem_ctx
);
3175 ZERO_STRUCT(self
->state
);
3176 Py_CLEAR(self
->ldb
);
3177 Py_TYPE(self
)->tp_free(self
);
3180 static PyObject
*py_ldb_search_iterator_next(PyLdbSearchIteratorObject
*self
)
3182 PyObject
*py_ret
= NULL
;
3184 if (self
->state
.req
== NULL
) {
3185 PyErr_SetString(PyExc_RuntimeError
,
3186 "ldb.SearchIterator request already finished");
3191 * TODO: do we want a non-blocking mode?
3192 * In future we may add an optional 'nonblocking'
3193 * argument to search_iterator().
3195 * For now we keep it simple and wait for at
3199 while (self
->state
.next
== NULL
) {
3202 if (self
->state
.result
!= NULL
) {
3204 * We (already) got a final result from the server.
3206 * We stop the iteration and let
3207 * py_ldb_search_iterator_result() will deliver
3208 * the result details.
3210 TALLOC_FREE(self
->state
.req
);
3211 PyErr_SetNone(PyExc_StopIteration
);
3215 ret
= ldb_wait(self
->state
.req
->handle
, LDB_WAIT_NONE
);
3216 if (ret
!= LDB_SUCCESS
) {
3217 struct ldb_context
*ldb_ctx
;
3218 TALLOC_FREE(self
->state
.req
);
3219 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
->ldb
);
3221 * We stop the iteration and let
3222 * py_ldb_search_iterator_result() will deliver
3225 self
->state
.exception
= Py_BuildValue(discard_const_p(char, "(i,s)"),
3226 ret
, ldb_errstring(ldb_ctx
));
3227 PyErr_SetNone(PyExc_StopIteration
);
3232 py_ret
= self
->state
.next
->obj
;
3233 self
->state
.next
->obj
= NULL
;
3234 /* no TALLOC_FREE() as self->state.next is a list */
3235 talloc_free(self
->state
.next
);
3239 static PyObject
*py_ldb_search_iterator_result(PyLdbSearchIteratorObject
*self
,
3240 PyObject
*Py_UNUSED(ignored
))
3242 PyObject
*py_ret
= NULL
;
3244 if (self
->state
.req
!= NULL
) {
3245 PyErr_SetString(PyExc_RuntimeError
,
3246 "ldb.SearchIterator request running");
3250 if (self
->state
.next
!= NULL
) {
3251 PyErr_SetString(PyExc_RuntimeError
,
3252 "ldb.SearchIterator not fully consumed.");
3256 if (self
->state
.exception
!= NULL
) {
3257 PyErr_SetObject(PyExc_LdbError
, self
->state
.exception
);
3258 Py_DECREF(self
->state
.exception
);
3259 self
->state
.exception
= NULL
;
3263 if (self
->state
.result
== NULL
) {
3264 PyErr_SetString(PyExc_RuntimeError
,
3265 "ldb.SearchIterator result already consumed");
3269 py_ret
= self
->state
.result
->obj
;
3270 self
->state
.result
->obj
= NULL
;
3271 TALLOC_FREE(self
->state
.result
);
3275 static PyObject
*py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject
*self
,
3276 PyObject
*Py_UNUSED(ignored
))
3278 if (self
->state
.req
== NULL
) {
3279 PyErr_SetString(PyExc_RuntimeError
,
3280 "ldb.SearchIterator request already finished");
3284 Py_CLEAR(self
->state
.exception
);
3285 TALLOC_FREE(self
->mem_ctx
);
3286 ZERO_STRUCT(self
->state
);
3290 static PyMethodDef py_ldb_search_iterator_methods
[] = {
3291 { "result", (PyCFunction
)py_ldb_search_iterator_result
, METH_NOARGS
,
3292 "S.result() -> ldb.Result (without msgs and referrals)\n" },
3293 { "abandon", (PyCFunction
)py_ldb_search_iterator_abandon
, METH_NOARGS
,
3298 static PyObject
*py_ldb_search_iterator_repr(PyLdbSearchIteratorObject
*self
)
3300 return PyUnicode_FromString("<ldb search iterator>");
3303 static PyTypeObject PyLdbSearchIterator
= {
3304 .tp_name
= "ldb.SearchIterator",
3305 .tp_repr
= (reprfunc
)py_ldb_search_iterator_repr
,
3306 .tp_dealloc
= (destructor
)py_ldb_search_iterator_dealloc
,
3307 .tp_iter
= PyObject_SelfIter
,
3308 .tp_iternext
= (iternextfunc
)py_ldb_search_iterator_next
,
3309 .tp_methods
= py_ldb_search_iterator_methods
,
3310 .tp_basicsize
= sizeof(PyLdbSearchIteratorObject
),
3311 .tp_doc
= "LDB search_iterator.",
3312 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
3316 * Create a ldb_message_element from a Python object.
3318 * This will accept any sequence objects that contains strings, or
3321 * A reference to set_obj might be borrowed.
3323 * @param mem_ctx Memory context
3324 * @param set_obj Python object to convert
3325 * @param flags ldb_message_element flags to set, if a new element is returned
3326 * @param attr_name Name of the attribute to set, if a new element is returned
3327 * @return New ldb_message_element, allocated as child of mem_ctx
3329 static struct ldb_message_element
*PyObject_AsMessageElement(
3330 TALLOC_CTX
*mem_ctx
,
3333 const char *attr_name
)
3335 struct ldb_message_element
*me
;
3336 const char *msg
= NULL
;
3340 if (pyldb_MessageElement_Check(set_obj
)) {
3341 PyLdbMessageElementObject
*set_obj_as_me
= (PyLdbMessageElementObject
*)set_obj
;
3342 /* We have to talloc_reference() the memory context, not the pointer
3343 * which may not actually be it's own context */
3344 if (talloc_reference(mem_ctx
, set_obj_as_me
->mem_ctx
)) {
3345 return pyldb_MessageElement_AsMessageElement(set_obj
);
3350 me
= talloc(mem_ctx
, struct ldb_message_element
);
3356 me
->name
= talloc_strdup(me
, attr_name
);
3357 if (me
->name
== NULL
) {
3363 if (PyBytes_Check(set_obj
) || PyUnicode_Check(set_obj
)) {
3365 me
->values
= talloc_array(me
, struct ldb_val
, me
->num_values
);
3366 if (PyBytes_Check(set_obj
)) {
3368 result
= PyBytes_AsStringAndSize(set_obj
, &_msg
, &size
);
3375 msg
= PyUnicode_AsUTF8AndSize(set_obj
, &size
);
3381 me
->values
[0].data
= talloc_memdup(me
,
3382 (const uint8_t *)msg
,
3384 me
->values
[0].length
= size
;
3385 } else if (PySequence_Check(set_obj
)) {
3387 me
->num_values
= PySequence_Size(set_obj
);
3388 me
->values
= talloc_array(me
, struct ldb_val
, me
->num_values
);
3389 for (i
= 0; i
< me
->num_values
; i
++) {
3390 PyObject
*obj
= PySequence_GetItem(set_obj
, i
);
3391 if (PyBytes_Check(obj
)) {
3393 result
= PyBytes_AsStringAndSize(obj
, &_msg
, &size
);
3399 } else if (PyUnicode_Check(obj
)) {
3400 msg
= PyUnicode_AsUTF8AndSize(obj
, &size
);
3406 PyErr_Format(PyExc_TypeError
,
3407 "Expected string as element %zd in list", i
);
3411 me
->values
[i
].data
= talloc_memdup(me
,
3412 (const uint8_t *)msg
,
3414 me
->values
[i
].length
= size
;
3417 PyErr_Format(PyExc_TypeError
,
3418 "String or List type expected for '%s' attribute", attr_name
);
3427 static PyObject
*ldb_msg_element_to_set(struct ldb_context
*ldb_ctx
,
3428 struct ldb_message_element
*me
)
3433 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
3434 result
= PyList_New(me
->num_values
);
3435 if (result
== NULL
) {
3439 for (i
= 0; i
< me
->num_values
; i
++) {
3440 PyObject
*obj
= NULL
;
3443 obj
= PyObject_FromLdbValue(&me
->values
[i
]);
3449 ret
= PyList_SetItem(result
, i
, obj
);
3460 static PyObject
*py_ldb_msg_element_get(PyLdbMessageElementObject
*self
, PyObject
*args
)
3463 if (!PyArg_ParseTuple(args
, "I", &i
))
3465 if (i
>= pyldb_MessageElement_AsMessageElement(self
)->num_values
)
3468 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self
)->values
[i
]));
3471 static PyObject
*py_ldb_msg_element_flags(PyLdbMessageElementObject
*self
, PyObject
*args
)
3473 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3474 return PyLong_FromLong(el
->flags
);
3477 static PyObject
*py_ldb_msg_element_set_flags(PyLdbMessageElementObject
*self
, PyObject
*args
)
3480 struct ldb_message_element
*el
;
3481 if (!PyArg_ParseTuple(args
, "I", &flags
))
3484 el
= pyldb_MessageElement_AsMessageElement(self
);
3489 static PyMethodDef py_ldb_msg_element_methods
[] = {
3490 { "get", (PyCFunction
)py_ldb_msg_element_get
, METH_VARARGS
, NULL
},
3491 { "set_flags", (PyCFunction
)py_ldb_msg_element_set_flags
, METH_VARARGS
, NULL
},
3492 { "flags", (PyCFunction
)py_ldb_msg_element_flags
, METH_NOARGS
, NULL
},
3496 static Py_ssize_t
py_ldb_msg_element_len(PyLdbMessageElementObject
*self
)
3498 return pyldb_MessageElement_AsMessageElement(self
)->num_values
;
3501 static PyObject
*py_ldb_msg_element_find(PyLdbMessageElementObject
*self
, Py_ssize_t idx
)
3503 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3504 if (idx
< 0 || idx
>= el
->num_values
) {
3505 PyErr_SetString(PyExc_IndexError
, "Out of range");
3508 return PyLdbBytes_FromStringAndSize((char *)el
->values
[idx
].data
, el
->values
[idx
].length
);
3511 static PySequenceMethods py_ldb_msg_element_seq
= {
3512 .sq_length
= (lenfunc
)py_ldb_msg_element_len
,
3513 .sq_item
= (ssizeargfunc
)py_ldb_msg_element_find
,
3516 static PyObject
*py_ldb_msg_element_richcmp(PyObject
*self
, PyObject
*other
, int op
)
3519 if (!pyldb_MessageElement_Check(other
)) {
3520 Py_INCREF(Py_NotImplemented
);
3521 return Py_NotImplemented
;
3523 ret
= ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self
),
3524 pyldb_MessageElement_AsMessageElement(other
));
3525 return richcmp(ret
, op
);
3528 static PyObject
*py_ldb_msg_element_iter(PyLdbMessageElementObject
*self
)
3530 PyObject
*el
= ldb_msg_element_to_set(NULL
,
3531 pyldb_MessageElement_AsMessageElement(self
));
3532 PyObject
*ret
= PyObject_GetIter(el
);
3537 static PyObject
*PyLdbMessageElement_FromMessageElement(struct ldb_message_element
*el
, TALLOC_CTX
*mem_ctx
)
3539 TALLOC_CTX
*ret_mem_ctx
= NULL
;
3540 PyLdbMessageElementObject
*ret
;
3542 ret_mem_ctx
= talloc_new(NULL
);
3543 if (ret_mem_ctx
== NULL
) {
3544 return PyErr_NoMemory();
3547 if (talloc_reference(ret_mem_ctx
, mem_ctx
) == NULL
) {
3548 talloc_free(ret_mem_ctx
);
3553 ret
= PyObject_New(PyLdbMessageElementObject
, &PyLdbMessageElement
);
3555 talloc_free(ret_mem_ctx
);
3559 ret
->mem_ctx
= ret_mem_ctx
;
3561 return (PyObject
*)ret
;
3564 static PyObject
*py_ldb_msg_element_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
3566 PyObject
*py_elements
= NULL
;
3567 struct ldb_message_element
*el
;
3568 unsigned int flags
= 0;
3570 const char * const kwnames
[] = { "elements", "flags", "name", NULL
};
3571 PyLdbMessageElementObject
*ret
;
3572 TALLOC_CTX
*mem_ctx
;
3573 const char *msg
= NULL
;
3577 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OIs",
3578 discard_const_p(char *, kwnames
),
3579 &py_elements
, &flags
, &name
))
3582 mem_ctx
= talloc_new(NULL
);
3583 if (mem_ctx
== NULL
) {
3588 el
= talloc_zero(mem_ctx
, struct ldb_message_element
);
3591 talloc_free(mem_ctx
);
3595 if (py_elements
!= NULL
) {
3597 if (PyBytes_Check(py_elements
) || PyUnicode_Check(py_elements
)) {
3600 el
->values
= talloc_array(el
, struct ldb_val
, 1);
3601 if (el
->values
== NULL
) {
3602 talloc_free(mem_ctx
);
3606 if (PyBytes_Check(py_elements
)) {
3607 result
= PyBytes_AsStringAndSize(py_elements
, &_msg
, &size
);
3610 msg
= PyUnicode_AsUTF8AndSize(py_elements
, &size
);
3611 result
= (msg
== NULL
) ? -1 : 0;
3614 talloc_free(mem_ctx
);
3617 el
->values
[0].data
= talloc_memdup(el
->values
,
3618 (const uint8_t *)msg
, size
+ 1);
3619 el
->values
[0].length
= size
;
3620 } else if (PySequence_Check(py_elements
)) {
3621 el
->num_values
= PySequence_Size(py_elements
);
3622 el
->values
= talloc_array(el
, struct ldb_val
, el
->num_values
);
3623 if (el
->values
== NULL
) {
3624 talloc_free(mem_ctx
);
3628 for (i
= 0; i
< el
->num_values
; i
++) {
3629 PyObject
*item
= PySequence_GetItem(py_elements
, i
);
3631 talloc_free(mem_ctx
);
3634 if (PyBytes_Check(item
)) {
3636 result
= PyBytes_AsStringAndSize(item
, &_msg
, &size
);
3638 } else if (PyUnicode_Check(item
)) {
3639 msg
= PyUnicode_AsUTF8AndSize(item
, &size
);
3640 result
= (msg
== NULL
) ? -1 : 0;
3642 PyErr_Format(PyExc_TypeError
,
3643 "Expected string as element %zd in list", i
);
3647 talloc_free(mem_ctx
);
3650 el
->values
[i
].data
= talloc_memdup(el
,
3651 (const uint8_t *)msg
, size
+1);
3652 el
->values
[i
].length
= size
;
3655 PyErr_SetString(PyExc_TypeError
,
3656 "Expected string or list");
3657 talloc_free(mem_ctx
);
3664 el
->name
= talloc_strdup(el
, name
);
3665 if (el
->name
== NULL
) {
3666 talloc_free(mem_ctx
);
3667 return PyErr_NoMemory();
3671 ret
= PyObject_New(PyLdbMessageElementObject
, type
);
3673 talloc_free(mem_ctx
);
3677 ret
->mem_ctx
= mem_ctx
;
3679 return (PyObject
*)ret
;
3682 static PyObject
*py_ldb_msg_element_repr(PyLdbMessageElementObject
*self
)
3684 char *element_str
= NULL
;
3686 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3687 PyObject
*ret
, *repr
;
3689 for (i
= 0; i
< el
->num_values
; i
++) {
3690 PyObject
*o
= py_ldb_msg_element_find(self
, i
);
3691 repr
= PyObject_Repr(o
);
3692 if (element_str
== NULL
)
3693 element_str
= talloc_strdup(NULL
, PyUnicode_AsUTF8(repr
));
3695 element_str
= talloc_asprintf_append(element_str
, ",%s", PyUnicode_AsUTF8(repr
));
3698 if (element_str
== NULL
) {
3699 return PyErr_NoMemory();
3703 if (element_str
!= NULL
) {
3704 ret
= PyUnicode_FromFormat("MessageElement([%s])", element_str
);
3705 talloc_free(element_str
);
3707 ret
= PyUnicode_FromString("MessageElement([])");
3713 static PyObject
*py_ldb_msg_element_str(PyLdbMessageElementObject
*self
)
3715 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3717 if (el
->num_values
== 1)
3718 return PyUnicode_FromStringAndSize((char *)el
->values
[0].data
, el
->values
[0].length
);
3723 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject
*self
)
3725 talloc_free(self
->mem_ctx
);
3729 static PyObject
*py_ldb_msg_element_get_text(PyObject
*self
, void *closure
)
3731 return wrap_text("MessageElementTextWrapper", self
);
3734 static PyGetSetDef py_ldb_msg_element_getset
[] = {
3736 .name
= discard_const_p(char, "text"),
3737 .get
= (getter
)py_ldb_msg_element_get_text
,
3742 static PyTypeObject PyLdbMessageElement
= {
3743 .tp_name
= "ldb.MessageElement",
3744 .tp_basicsize
= sizeof(PyLdbMessageElementObject
),
3745 .tp_dealloc
= (destructor
)py_ldb_msg_element_dealloc
,
3746 .tp_repr
= (reprfunc
)py_ldb_msg_element_repr
,
3747 .tp_str
= (reprfunc
)py_ldb_msg_element_str
,
3748 .tp_methods
= py_ldb_msg_element_methods
,
3749 .tp_getset
= py_ldb_msg_element_getset
,
3750 .tp_richcompare
= (richcmpfunc
)py_ldb_msg_element_richcmp
,
3751 .tp_iter
= (getiterfunc
)py_ldb_msg_element_iter
,
3752 .tp_as_sequence
= &py_ldb_msg_element_seq
,
3753 .tp_new
= py_ldb_msg_element_new
,
3754 .tp_flags
= Py_TPFLAGS_DEFAULT
,
3755 .tp_doc
= "An element of a Message",
3759 static PyObject
*py_ldb_msg_from_dict(PyTypeObject
*type
, PyObject
*args
)
3764 struct ldb_message
*msg
;
3765 struct ldb_context
*ldb_ctx
;
3766 unsigned int mod_flags
= LDB_FLAG_MOD_REPLACE
;
3768 if (!PyArg_ParseTuple(args
, "O!O!|I",
3769 &PyLdb
, &py_ldb
, &PyDict_Type
, &py_dict
,
3774 /* mask only flags we are going to use */
3775 mod_flags
= LDB_FLAG_MOD_TYPE(mod_flags
);
3777 PyErr_SetString(PyExc_ValueError
,
3778 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3779 " expected as mod_flag value");
3783 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(py_ldb
);
3785 msg
= PyDict_AsMessage(ldb_ctx
, py_dict
, ldb_ctx
, mod_flags
);
3790 py_ret
= PyLdbMessage_FromMessage(msg
, (PyLdbObject
*)py_ldb
);
3792 talloc_unlink(ldb_ctx
, msg
);
3798 #define pyldb_Message_as_message(pyobj) ((PyLdbMessageObject *)pyobj)->msg
3800 #define pyldb_Message_get_pyldb(pyobj) ((PyLdbMessageObject *)pyobj)->pyldb
3803 * PyErr_LDB_MESSAGE_OR_RAISE does 3 things:
3804 * 1. checks that a PyObject is really a PyLdbMessageObject.
3805 * 2. checks that the ldb that the PyLdbMessageObject knows is the ldb that
3806 * its dn knows -- but only if the underlying message has a DN.
3807 * 3. sets message to the relevant struct ldb_message *.
3809 * We need to do all this to ensure the message belongs to the right
3810 * ldb, lest it be freed before we are ready.
3812 #define PyErr_LDB_MESSAGE_OR_RAISE(_py_obj, message) do { \
3813 PyLdbMessageObject *_py_message = NULL; \
3814 struct ldb_dn *_dn = NULL; \
3815 if (_py_obj == NULL || !pyldb_Message_Check(_py_obj)) { \
3816 PyErr_SetString(PyExc_TypeError, \
3817 "ldb Message object required"); \
3820 _py_message = (PyLdbMessageObject *)_py_obj; \
3821 message = pyldb_Message_as_message(_py_message); \
3822 _dn = message->dn; \
3823 if (_dn != NULL && \
3824 (_py_message->pyldb->ldb_ctx != ldb_dn_get_ldb_context(_dn))) { \
3825 PyErr_SetString(PyExc_RuntimeError, \
3826 "Message has a stale LDB connection"); \
3832 static PyObject
*py_ldb_msg_remove_attr(PyObject
*self
, PyObject
*args
)
3835 struct ldb_message
*msg
= NULL
;
3836 PyErr_LDB_MESSAGE_OR_RAISE(self
, msg
);
3838 if (!PyArg_ParseTuple(args
, "s", &name
)) {
3842 ldb_msg_remove_attr(msg
, name
);
3847 static PyObject
*py_ldb_msg_keys(PyObject
*self
,
3848 PyObject
*Py_UNUSED(ignored
))
3850 struct ldb_message
*msg
= NULL
;
3851 Py_ssize_t i
, j
= 0;
3852 PyObject
*obj
= NULL
;
3854 PyErr_LDB_MESSAGE_OR_RAISE(self
, msg
);
3856 obj
= PyList_New(msg
->num_elements
+(msg
->dn
!= NULL
?1:0));
3861 if (msg
->dn
!= NULL
) {
3862 PyObject
*py_dn
= NULL
;
3865 py_dn
= PyUnicode_FromString("dn");
3866 if (py_dn
== NULL
) {
3871 ret
= PyList_SetItem(obj
, j
, py_dn
);
3880 for (i
= 0; i
< msg
->num_elements
; i
++) {
3881 PyObject
*py_name
= NULL
;
3884 py_name
= PyUnicode_FromString(msg
->elements
[i
].name
);
3885 if (py_name
== NULL
) {
3890 ret
= PyList_SetItem(obj
, j
, py_name
);
3902 static int py_ldb_msg_contains(PyLdbMessageObject
*self
, PyObject
*py_name
)
3904 struct ldb_message_element
*el
= NULL
;
3905 const char *name
= NULL
;
3906 struct ldb_message
*msg
= pyldb_Message_as_message(self
);
3907 struct ldb_dn
*dn
= msg
->dn
;
3909 if (dn
!= NULL
&& (self
->pyldb
->ldb_ctx
!= ldb_dn_get_ldb_context(dn
))) {
3913 name
= PyUnicode_AsUTF8(py_name
);
3917 if (!ldb_attr_cmp(name
, "dn")) {
3920 el
= ldb_msg_find_element(msg
, name
);
3921 return el
!= NULL
? 1 : 0;
3924 static PyObject
*py_ldb_msg_getitem(PyObject
*self
, PyObject
*py_name
)
3926 struct ldb_message_element
*el
= NULL
;
3927 const char *name
= NULL
;
3928 struct ldb_message
*msg
= NULL
;
3929 PyErr_LDB_MESSAGE_OR_RAISE(self
, msg
);
3931 name
= PyUnicode_AsUTF8(py_name
);
3935 if (!ldb_attr_cmp(name
, "dn")) {
3936 return pyldb_Dn_FromDn(msg
->dn
, pyldb_Message_get_pyldb(self
));
3938 el
= ldb_msg_find_element(msg
, name
);
3940 PyErr_SetString(PyExc_KeyError
, "No such element");
3944 return PyLdbMessageElement_FromMessageElement(el
, msg
->elements
);
3947 static PyObject
*py_ldb_msg_get(PyObject
*self
, PyObject
*args
, PyObject
*kwargs
)
3949 PyObject
*def
= NULL
;
3950 const char *kwnames
[] = { "name", "default", "idx", NULL
};
3951 const char *name
= NULL
;
3953 struct ldb_message_element
*el
;
3954 struct ldb_message
*msg
= NULL
;
3955 PyErr_LDB_MESSAGE_OR_RAISE(self
, msg
);
3957 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|Oi:msg",
3958 discard_const_p(char *, kwnames
), &name
, &def
, &idx
)) {
3962 if (strcasecmp(name
, "dn") == 0) {
3963 return pyldb_Dn_FromDn(msg
->dn
, pyldb_Message_get_pyldb(self
));
3966 el
= ldb_msg_find_element(msg
, name
);
3968 if (el
== NULL
|| (idx
!= -1 && el
->num_values
<= idx
)) {
3977 return (PyObject
*)PyLdbMessageElement_FromMessageElement(el
, msg
->elements
);
3980 return PyObject_FromLdbValue(&el
->values
[idx
]);
3983 static PyObject
*py_ldb_msg_items(PyObject
*self
,
3984 PyObject
*Py_UNUSED(ignored
))
3986 struct ldb_message
*msg
= NULL
;
3987 Py_ssize_t i
, j
= 0;
3990 PyErr_LDB_MESSAGE_OR_RAISE(self
, msg
);
3992 l
= PyList_New(msg
->num_elements
+ (msg
->dn
== NULL
?0:1));
3994 return PyErr_NoMemory();
3996 if (msg
->dn
!= NULL
) {
3997 PyObject
*value
= NULL
;
3999 PyObject
*obj
= pyldb_Dn_FromDn(msg
->dn
, pyldb_Message_get_pyldb(self
));
4004 value
= Py_BuildValue("(sO)", "dn", obj
);
4006 if (value
== NULL
) {
4010 res
= PyList_SetItem(l
, 0, value
);
4017 for (i
= 0; i
< msg
->num_elements
; i
++, j
++) {
4018 PyObject
*value
= NULL
;
4020 PyObject
*py_el
= PyLdbMessageElement_FromMessageElement(&msg
->elements
[i
],
4022 if (py_el
== NULL
) {
4026 value
= Py_BuildValue("(sO)", msg
->elements
[i
].name
, py_el
);
4028 if (value
== NULL
) {
4032 res
= PyList_SetItem(l
, j
, value
);
4041 static PyObject
*py_ldb_msg_elements(PyObject
*self
,
4042 PyObject
*Py_UNUSED(ignored
))
4046 struct ldb_message
*msg
= NULL
;
4047 PyErr_LDB_MESSAGE_OR_RAISE(self
, msg
);
4049 l
= PyList_New(msg
->num_elements
);
4053 for (i
= 0; i
< msg
->num_elements
; i
++) {
4054 PyObject
*msg_el
= NULL
;
4057 msg_el
= PyLdbMessageElement_FromMessageElement(&msg
->elements
[i
], msg
->elements
);
4058 if (msg_el
== NULL
) {
4063 ret
= PyList_SetItem(l
, i
, msg_el
);
4073 static PyObject
*py_ldb_msg_add(PyObject
*self
, PyObject
*args
)
4075 PyLdbMessageElementObject
*py_element
;
4077 struct ldb_message_element
*el
;
4078 struct ldb_message_element
*el_new
;
4079 struct ldb_message
*msg
= NULL
;
4080 PyErr_LDB_MESSAGE_OR_RAISE(self
, msg
);
4082 if (!PyArg_ParseTuple(args
, "O!", &PyLdbMessageElement
, &py_element
)) {
4086 el
= py_element
->el
;
4088 PyErr_SetString(PyExc_ValueError
, "Invalid MessageElement object");
4091 if (el
->name
== NULL
) {
4092 PyErr_SetString(PyExc_ValueError
,
4093 "The element has no name");
4096 ret
= ldb_msg_add_empty(msg
, el
->name
, el
->flags
, &el_new
);
4097 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
4099 /* now deep copy all attribute values */
4100 el_new
->values
= talloc_array(msg
->elements
, struct ldb_val
, el
->num_values
);
4101 if (el_new
->values
== NULL
) {
4105 el_new
->num_values
= el
->num_values
;
4107 for (i
= 0; i
< el
->num_values
; i
++) {
4108 el_new
->values
[i
] = ldb_val_dup(el_new
->values
, &el
->values
[i
]);
4109 if (el_new
->values
[i
].data
== NULL
4110 && el
->values
[i
].length
!= 0) {
4119 static PyMethodDef py_ldb_msg_methods
[] = {
4120 { "from_dict", (PyCFunction
)py_ldb_msg_from_dict
, METH_CLASS
| METH_VARARGS
,
4121 "Message.from_dict(ldb, dict, mod_flag) -> ldb.Message\n"
4122 "Class method to create ldb.Message object from Dictionary.\n"
4123 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
4124 { "keys", (PyCFunction
)py_ldb_msg_keys
, METH_NOARGS
,
4125 "S.keys() -> list\n\n"
4126 "Return sequence of all attribute names." },
4127 { "remove", (PyCFunction
)py_ldb_msg_remove_attr
, METH_VARARGS
,
4128 "S.remove(name)\n\n"
4129 "Remove all entries for attributes with the specified name."},
4130 { "get", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_msg_get
),
4131 METH_VARARGS
| METH_KEYWORDS
,
4132 "msg.get(name,default=None,idx=None) -> string\n"
4133 "idx is the index into the values array\n"
4134 "if idx is None, then a list is returned\n"
4135 "if idx is not None, then the element with that index is returned\n"
4136 "if you pass the special name 'dn' then the DN object is returned\n"},
4137 { "items", (PyCFunction
)py_ldb_msg_items
, METH_NOARGS
, NULL
},
4138 { "elements", (PyCFunction
)py_ldb_msg_elements
, METH_NOARGS
, NULL
},
4139 { "add", (PyCFunction
)py_ldb_msg_add
, METH_VARARGS
,
4140 "S.add(element)\n\n"
4141 "Add an element to this message." },
4145 static PyObject
*py_ldb_msg_iter(PyObject
*self
)
4147 PyObject
*list
, *iter
;
4149 list
= py_ldb_msg_keys(self
, NULL
);
4153 iter
= PyObject_GetIter(list
);
4158 static int py_ldb_msg_setitem(PyLdbMessageObject
*self
, PyObject
*name
, PyObject
*value
)
4160 const char *attr_name
;
4162 attr_name
= PyUnicode_AsUTF8(name
);
4163 if (attr_name
== NULL
) {
4164 PyErr_SetNone(PyExc_TypeError
);
4168 if (value
== NULL
) {
4170 ldb_msg_remove_attr(self
->msg
, attr_name
);
4173 struct ldb_message_element
*el
= PyObject_AsMessageElement(self
->msg
,
4174 value
, 0, attr_name
);
4178 if (el
->name
== NULL
) {
4180 * If ‘value’ is a MessageElement,
4181 * PyObject_AsMessageElement() will have returned a
4182 * reference to it without setting the name. We don’t
4183 * want to modify the original object to set the name
4184 * ourselves, but making a copy would result in
4185 * different behaviour for a caller relying on a
4186 * reference being kept. Rather than continue with a
4187 * NULL name (and probably fail later on), let’s catch
4188 * this potential mistake early.
4190 PyErr_SetString(PyExc_ValueError
, "MessageElement has no name set");
4191 talloc_unlink(self
->msg
, el
);
4194 ldb_msg_remove_attr(pyldb_Message_AsMessage(self
), attr_name
);
4195 ret
= ldb_msg_add(pyldb_Message_AsMessage(self
), el
, el
->flags
);
4196 if (ret
!= LDB_SUCCESS
) {
4197 PyErr_SetLdbError(PyExc_LdbError
, ret
, NULL
);
4198 talloc_unlink(self
->msg
, el
);
4205 static Py_ssize_t
py_ldb_msg_length(PyLdbMessageObject
*self
)
4207 return pyldb_Message_AsMessage(self
)->num_elements
;
4210 static PySequenceMethods py_ldb_msg_sequence
= {
4211 .sq_contains
= (objobjproc
)py_ldb_msg_contains
,
4214 static PyMappingMethods py_ldb_msg_mapping
= {
4215 .mp_length
= (lenfunc
)py_ldb_msg_length
,
4216 .mp_subscript
= (binaryfunc
)py_ldb_msg_getitem
,
4217 .mp_ass_subscript
= (objobjargproc
)py_ldb_msg_setitem
,
4220 static PyObject
*py_ldb_msg_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
4222 const char * const kwnames
[] = { "dn", NULL
};
4223 struct ldb_message
*ret
;
4224 TALLOC_CTX
*mem_ctx
;
4225 PyObject
*pydn
= NULL
;
4226 PyLdbMessageObject
*py_ret
;
4228 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|O",
4229 discard_const_p(char *, kwnames
),
4233 mem_ctx
= talloc_new(NULL
);
4234 if (mem_ctx
== NULL
) {
4239 ret
= ldb_msg_new(mem_ctx
);
4241 talloc_free(mem_ctx
);
4248 if (!pyldb_Object_AsDn(NULL
, pydn
, NULL
, &dn
)) {
4249 talloc_free(mem_ctx
);
4252 ret
->dn
= talloc_reference(ret
, dn
);
4253 if (ret
->dn
== NULL
) {
4254 talloc_free(mem_ctx
);
4255 return PyErr_NoMemory();
4259 py_ret
= (PyLdbMessageObject
*)type
->tp_alloc(type
, 0);
4260 if (py_ret
== NULL
) {
4262 talloc_free(mem_ctx
);
4266 py_ret
->mem_ctx
= mem_ctx
;
4269 py_ret
->pyldb
= ((PyLdbDnObject
*)pydn
)->pyldb
;
4270 Py_INCREF(py_ret
->pyldb
);
4272 return (PyObject
*)py_ret
;
4275 static PyObject
*PyLdbMessage_FromMessage(struct ldb_message
*msg
, PyLdbObject
*pyldb
)
4277 TALLOC_CTX
*mem_ctx
= NULL
;
4278 struct ldb_message
*msg_ref
= NULL
;
4279 PyLdbMessageObject
*ret
;
4281 mem_ctx
= talloc_new(NULL
);
4282 if (mem_ctx
== NULL
) {
4283 return PyErr_NoMemory();
4286 msg_ref
= talloc_reference(mem_ctx
, msg
);
4287 if (msg_ref
== NULL
) {
4288 talloc_free(mem_ctx
);
4289 return PyErr_NoMemory();
4292 ret
= (PyLdbMessageObject
*)PyLdbMessage
.tp_alloc(&PyLdbMessage
, 0);
4294 talloc_free(mem_ctx
);
4298 ret
->mem_ctx
= mem_ctx
;
4302 Py_INCREF(ret
->pyldb
);
4304 return (PyObject
*)ret
;
4307 static PyObject
*py_ldb_msg_get_dn(PyObject
*self
, void *closure
)
4309 struct ldb_message
*msg
= NULL
;
4310 PyErr_LDB_MESSAGE_OR_RAISE(self
, msg
);
4311 return pyldb_Dn_FromDn(msg
->dn
, pyldb_Message_get_pyldb(self
));
4314 static int py_ldb_msg_set_dn(PyObject
*self
, PyObject
*value
, void *closure
)
4317 * no PyErr_LDB_MESSAGE_OR_RAISE here, because this returns int.
4319 * Also, since this is trying to replace the dn, we don't need to
4320 * check the old one.
4322 struct ldb_message
*msg
= pyldb_Message_as_message(self
);
4323 struct ldb_dn
*dn
= NULL
;
4324 PyLdbObject
*pyldb
= pyldb_Message_get_pyldb(self
);
4325 PyLdbMessageObject
*self_as_msg
= (PyLdbMessageObject
*)self
;
4327 if (value
== NULL
) {
4328 PyErr_SetString(PyExc_AttributeError
, "cannot delete dn");
4331 if (!pyldb_Dn_Check(value
)) {
4332 PyErr_SetString(PyExc_TypeError
, "expected dn");
4336 dn
= talloc_reference(msg
, pyldb_Dn_AS_DN(value
));
4342 if (pyldb
!= NULL
) {
4343 if (pyldb
->ldb_ctx
!= ldb_dn_get_ldb_context(dn
)) {
4344 PyErr_SetString(PyExc_RuntimeError
,
4345 "DN is from the wrong LDB");
4353 self_as_msg
->pyldb
= ((PyLdbDnObject
*)value
)->pyldb
;
4354 Py_INCREF(self_as_msg
->pyldb
);
4359 static PyObject
*py_ldb_msg_get_text(PyObject
*self
, void *closure
)
4361 return wrap_text("MessageTextWrapper", self
);
4366 static PyObject
*py_ldb_msg_get_ldb(PyLdbMessageObject
*self
, void *closure
)
4368 if (self
->pyldb
== NULL
) {
4371 Py_INCREF(self
->pyldb
);
4372 return (PyObject
*)self
->pyldb
;
4376 static PyGetSetDef py_ldb_msg_getset
[] = {
4378 .name
= discard_const_p(char, "dn"),
4379 .get
= (getter
)py_ldb_msg_get_dn
,
4380 .set
= (setter
)py_ldb_msg_set_dn
,
4383 .name
= discard_const_p(char, "text"),
4384 .get
= (getter
)py_ldb_msg_get_text
,
4387 .name
= discard_const_p(char, "ldb"),
4388 .get
= (getter
)py_ldb_msg_get_ldb
,
4389 .doc
= discard_const_p(
4390 char, "returns the associated ldb object (or None)")
4395 static PyObject
*py_ldb_msg_repr(PyLdbMessageObject
*self
)
4397 PyObject
*dict
= PyDict_New(), *ret
, *repr
;
4398 const char *repr_str
= NULL
;
4402 if (PyDict_Update(dict
, (PyObject
*)self
) != 0) {
4406 repr
= PyObject_Repr(dict
);
4411 repr_str
= PyUnicode_AsUTF8(repr
);
4412 if (repr_str
== NULL
) {
4417 ret
= PyUnicode_FromFormat("Message(%s)", repr_str
);
4423 static void py_ldb_msg_dealloc(PyLdbMessageObject
*self
)
4425 talloc_free(self
->mem_ctx
);
4426 /* The pyldb element will only be present if a DN is assigned */
4428 Py_DECREF(self
->pyldb
);
4433 static PyObject
*py_ldb_msg_richcmp(PyLdbMessageObject
*py_msg1
,
4434 PyLdbMessageObject
*py_msg2
, int op
)
4436 struct ldb_message
*msg1
, *msg2
;
4440 if (!pyldb_Message_Check(py_msg2
)) {
4441 Py_INCREF(Py_NotImplemented
);
4442 return Py_NotImplemented
;
4445 PyErr_LDB_MESSAGE_OR_RAISE(py_msg1
, msg1
);
4446 PyErr_LDB_MESSAGE_OR_RAISE(py_msg2
, msg2
);
4448 * FIXME: this can be a non-transitive compare, unsuitable for
4451 * supposing msg1, msg2, and msg3 have 1, 2, and 3 elements
4452 * each. msg2 has a NULL DN, while msg1 has a DN that compares
4453 * higher than msg3. Then:
4455 * msg1 < msg2, due to num_elements.
4456 * msg2 < msg3, due to num_elements.
4457 * msg1 > msg3, due to DNs.
4459 if ((msg1
->dn
!= NULL
) || (msg2
->dn
!= NULL
)) {
4460 ret
= ldb_dn_compare(msg1
->dn
, msg2
->dn
);
4462 return richcmp(ret
, op
);
4466 if (msg1
->num_elements
> msg2
->num_elements
) {
4467 return richcmp(1, op
);
4469 if (msg1
->num_elements
< msg2
->num_elements
) {
4470 return richcmp(-1, op
);
4473 for (i
= 0; i
< msg1
->num_elements
; i
++) {
4474 ret
= ldb_msg_element_compare_name(&msg1
->elements
[i
],
4475 &msg2
->elements
[i
]);
4477 return richcmp(ret
, op
);
4480 ret
= ldb_msg_element_compare(&msg1
->elements
[i
],
4481 &msg2
->elements
[i
]);
4483 return richcmp(ret
, op
);
4487 return richcmp(0, op
);
4490 static PyTypeObject PyLdbMessage
= {
4491 .tp_name
= "ldb.Message",
4492 .tp_methods
= py_ldb_msg_methods
,
4493 .tp_getset
= py_ldb_msg_getset
,
4494 .tp_as_sequence
= &py_ldb_msg_sequence
,
4495 .tp_as_mapping
= &py_ldb_msg_mapping
,
4496 .tp_basicsize
= sizeof(PyLdbMessageObject
),
4497 .tp_dealloc
= (destructor
)py_ldb_msg_dealloc
,
4498 .tp_new
= py_ldb_msg_new
,
4499 .tp_repr
= (reprfunc
)py_ldb_msg_repr
,
4500 .tp_flags
= Py_TPFLAGS_DEFAULT
,
4501 .tp_iter
= (getiterfunc
)py_ldb_msg_iter
,
4502 .tp_richcompare
= (richcmpfunc
)py_ldb_msg_richcmp
,
4503 .tp_doc
= "A LDB Message",
4506 static void py_ldb_tree_dealloc(PyLdbTreeObject
*self
)
4508 talloc_free(self
->mem_ctx
);
4512 static PyTypeObject PyLdbTree
= {
4513 .tp_name
= "ldb.Tree",
4514 .tp_basicsize
= sizeof(PyLdbTreeObject
),
4515 .tp_dealloc
= (destructor
)py_ldb_tree_dealloc
,
4516 .tp_flags
= Py_TPFLAGS_DEFAULT
,
4517 .tp_doc
= "A search tree",
4520 static PyObject
*py_timestring(PyObject
*module
, PyObject
*args
)
4522 /* most times "time_t" is a signed integer type with 32 or 64 bit:
4523 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4527 if (!PyArg_ParseTuple(args
, "l", &t_val
))
4529 tresult
= ldb_timestring(NULL
, (time_t) t_val
);
4530 if (tresult
== NULL
) {
4532 * Most likely EOVERFLOW from gmtime()
4534 PyErr_SetFromErrno(PyExc_OSError
);
4537 ret
= PyUnicode_FromString(tresult
);
4538 talloc_free(tresult
);
4542 static PyObject
*py_string_to_time(PyObject
*module
, PyObject
*args
)
4546 if (!PyArg_ParseTuple(args
, "s", &str
)) {
4549 t
= ldb_string_to_time(str
);
4551 if (t
== 0 && errno
!= 0) {
4552 PyErr_SetFromErrno(PyExc_ValueError
);
4555 return PyLong_FromLong(t
);
4558 static PyObject
*py_valid_attr_name(PyObject
*self
, PyObject
*args
)
4561 if (!PyArg_ParseTuple(args
, "s", &name
))
4563 return PyBool_FromLong(ldb_valid_attr_name(name
));
4567 encode a string using RFC2254 rules
4569 static PyObject
*py_binary_encode(PyObject
*self
, PyObject
*args
)
4571 char *str
, *encoded
;
4572 Py_ssize_t size
= 0;
4576 if (!PyArg_ParseTuple(args
, "s#", &str
, &size
))
4578 val
.data
= (uint8_t *)str
;
4581 encoded
= ldb_binary_encode(NULL
, val
);
4582 if (encoded
== NULL
) {
4583 PyErr_SetString(PyExc_TypeError
, "unable to encode binary string");
4586 ret
= PyUnicode_FromString(encoded
);
4587 talloc_free(encoded
);
4592 decode a string using RFC2254 rules
4594 static PyObject
*py_binary_decode(PyObject
*self
, PyObject
*args
)
4600 if (!PyArg_ParseTuple(args
, "s", &str
))
4603 val
= ldb_binary_decode(NULL
, str
);
4604 if (val
.data
== NULL
) {
4605 PyErr_SetString(PyExc_TypeError
, "unable to decode binary string");
4608 ret
= PyBytes_FromStringAndSize((const char*)val
.data
, val
.length
);
4609 talloc_free(val
.data
);
4613 static PyMethodDef py_ldb_global_methods
[] = {
4614 { "timestring", py_timestring
, METH_VARARGS
,
4615 "S.timestring(int) -> string\n\n"
4616 "Generate a LDAP time string from a UNIX timestamp" },
4617 { "string_to_time", py_string_to_time
, METH_VARARGS
,
4618 "S.string_to_time(string) -> int\n\n"
4619 "Parse a LDAP time string into a UNIX timestamp." },
4620 { "valid_attr_name", py_valid_attr_name
, METH_VARARGS
,
4621 "S.valid_attr_name(name) -> bool\n\n"
4622 "Check whether the supplied name is a valid attribute name." },
4623 { "binary_encode", py_binary_encode
, METH_VARARGS
,
4624 "S.binary_encode(string) -> string\n\n"
4625 "Perform a RFC2254 binary encoding on a string" },
4626 { "binary_decode", py_binary_decode
, METH_VARARGS
,
4627 "S.binary_decode(string) -> string\n\n"
4628 "Perform a RFC2254 binary decode on a string" },
4632 #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."
4634 static struct PyModuleDef moduledef
= {
4635 PyModuleDef_HEAD_INIT
,
4637 .m_doc
= MODULE_DOC
,
4639 .m_methods
= py_ldb_global_methods
,
4642 static PyObject
* module_init(void)
4646 PyLdbBytesType
.tp_base
= &PyBytes_Type
;
4647 if (PyType_Ready(&PyLdbBytesType
) < 0) {
4651 if (PyType_Ready(&PyLdbDn
) < 0)
4654 if (PyType_Ready(&PyLdbMessage
) < 0)
4657 if (PyType_Ready(&PyLdbMessageElement
) < 0)
4660 if (PyType_Ready(&PyLdb
) < 0)
4663 if (PyType_Ready(&PyLdbTree
) < 0)
4666 if (PyType_Ready(&PyLdbResult
) < 0)
4669 if (PyType_Ready(&PyLdbSearchIterator
) < 0)
4672 if (PyType_Ready(&PyLdbControl
) < 0)
4675 m
= PyModule_Create(&moduledef
);
4679 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4681 ADD_LDB_INT(SEQ_HIGHEST_SEQ
);
4682 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP
);
4683 ADD_LDB_INT(SEQ_NEXT
);
4684 ADD_LDB_INT(SCOPE_DEFAULT
);
4685 ADD_LDB_INT(SCOPE_BASE
);
4686 ADD_LDB_INT(SCOPE_ONELEVEL
);
4687 ADD_LDB_INT(SCOPE_SUBTREE
);
4689 ADD_LDB_INT(CHANGETYPE_NONE
);
4690 ADD_LDB_INT(CHANGETYPE_ADD
);
4691 ADD_LDB_INT(CHANGETYPE_DELETE
);
4692 ADD_LDB_INT(CHANGETYPE_MODIFY
);
4693 ADD_LDB_INT(CHANGETYPE_MODRDN
);
4695 ADD_LDB_INT(FLAG_MOD_ADD
);
4696 ADD_LDB_INT(FLAG_MOD_REPLACE
);
4697 ADD_LDB_INT(FLAG_MOD_DELETE
);
4698 ADD_LDB_INT(FLAG_FORCE_NO_BASE64_LDIF
);
4700 ADD_LDB_INT(ATTR_FLAG_HIDDEN
);
4701 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX
);
4702 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE
);
4703 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF
);
4705 ADD_LDB_INT(SUCCESS
);
4706 ADD_LDB_INT(ERR_OPERATIONS_ERROR
);
4707 ADD_LDB_INT(ERR_PROTOCOL_ERROR
);
4708 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED
);
4709 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED
);
4710 ADD_LDB_INT(ERR_COMPARE_FALSE
);
4711 ADD_LDB_INT(ERR_COMPARE_TRUE
);
4712 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED
);
4713 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED
);
4714 ADD_LDB_INT(ERR_REFERRAL
);
4715 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED
);
4716 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION
);
4717 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED
);
4718 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS
);
4719 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE
);
4720 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE
);
4721 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING
);
4722 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION
);
4723 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS
);
4724 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX
);
4725 ADD_LDB_INT(ERR_NO_SUCH_OBJECT
);
4726 ADD_LDB_INT(ERR_ALIAS_PROBLEM
);
4727 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX
);
4728 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM
);
4729 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION
);
4730 ADD_LDB_INT(ERR_INVALID_CREDENTIALS
);
4731 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS
);
4732 ADD_LDB_INT(ERR_BUSY
);
4733 ADD_LDB_INT(ERR_UNAVAILABLE
);
4734 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM
);
4735 ADD_LDB_INT(ERR_LOOP_DETECT
);
4736 ADD_LDB_INT(ERR_NAMING_VIOLATION
);
4737 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION
);
4738 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF
);
4739 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN
);
4740 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS
);
4741 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED
);
4742 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS
);
4743 ADD_LDB_INT(ERR_OTHER
);
4745 ADD_LDB_INT(FLG_RDONLY
);
4746 ADD_LDB_INT(FLG_NOSYNC
);
4747 ADD_LDB_INT(FLG_RECONNECT
);
4748 ADD_LDB_INT(FLG_NOMMAP
);
4749 ADD_LDB_INT(FLG_SHOW_BINARY
);
4750 ADD_LDB_INT(FLG_ENABLE_TRACING
);
4751 ADD_LDB_INT(FLG_DONT_CREATE_DB
);
4753 ADD_LDB_INT(PACKING_FORMAT
);
4754 ADD_LDB_INT(PACKING_FORMAT_V2
);
4756 /* Historical misspelling */
4757 PyModule_AddIntConstant(m
, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM
);
4759 PyModule_AddStringConstant(m
, "__docformat__", "restructuredText");
4761 PyExc_LdbError
= PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL
, NULL
);
4762 PyModule_AddObject(m
, "LdbError", PyExc_LdbError
);
4765 Py_INCREF(&PyLdbDn
);
4766 Py_INCREF(&PyLdbMessage
);
4767 Py_INCREF(&PyLdbMessageElement
);
4768 Py_INCREF(&PyLdbTree
);
4769 Py_INCREF(&PyLdbResult
);
4770 Py_INCREF(&PyLdbControl
);
4772 PyModule_AddObject(m
, "Ldb", (PyObject
*)&PyLdb
);
4773 PyModule_AddObject(m
, "Dn", (PyObject
*)&PyLdbDn
);
4774 PyModule_AddObject(m
, "Message", (PyObject
*)&PyLdbMessage
);
4775 PyModule_AddObject(m
, "MessageElement", (PyObject
*)&PyLdbMessageElement
);
4776 PyModule_AddObject(m
, "Tree", (PyObject
*)&PyLdbTree
);
4777 PyModule_AddObject(m
, "Result", (PyObject
*)&PyLdbResult
);
4778 PyModule_AddObject(m
, "Control", (PyObject
*)&PyLdbControl
);
4780 PyModule_AddStringConstant(m
, "__version__", PACKAGE_VERSION
);
4782 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4784 ADD_LDB_STRING(SYNTAX_DN
);
4785 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING
);
4786 ADD_LDB_STRING(SYNTAX_INTEGER
);
4787 ADD_LDB_STRING(SYNTAX_ORDERED_INTEGER
);
4788 ADD_LDB_STRING(SYNTAX_BOOLEAN
);
4789 ADD_LDB_STRING(SYNTAX_OCTET_STRING
);
4790 ADD_LDB_STRING(SYNTAX_UTC_TIME
);
4791 ADD_LDB_STRING(OID_COMPARATOR_AND
);
4792 ADD_LDB_STRING(OID_COMPARATOR_OR
);
4797 PyMODINIT_FUNC
PyInit_ldb(void);
4798 PyMODINIT_FUNC
PyInit_ldb(void)
4800 return module_init();