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 return PyUnicode_FromString("<ldb connection>");
1348 static PyObject
*py_ldb_get_root_basedn(PyLdbObject
*self
,
1349 PyObject
*Py_UNUSED(ignored
))
1351 struct ldb_dn
*dn
= ldb_get_root_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1354 return py_ldb_dn_copy(dn
, self
);
1358 static PyObject
*py_ldb_get_schema_basedn(PyLdbObject
*self
,
1359 PyObject
*Py_UNUSED(ignored
))
1361 struct ldb_dn
*dn
= ldb_get_schema_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1364 return py_ldb_dn_copy(dn
, self
);
1367 static PyObject
*py_ldb_get_config_basedn(PyLdbObject
*self
,
1368 PyObject
*Py_UNUSED(ignored
))
1370 struct ldb_dn
*dn
= ldb_get_config_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1373 return py_ldb_dn_copy(dn
, self
);
1376 static PyObject
*py_ldb_get_default_basedn(PyLdbObject
*self
,
1377 PyObject
*Py_UNUSED(ignored
))
1379 struct ldb_dn
*dn
= ldb_get_default_basedn(pyldb_Ldb_AS_LDBCONTEXT(self
));
1382 return py_ldb_dn_copy(dn
, self
);
1385 static const char **PyList_AsStrList(TALLOC_CTX
*mem_ctx
, PyObject
*list
,
1386 const char *paramname
)
1390 if (!PyList_Check(list
)) {
1391 PyErr_Format(PyExc_TypeError
, "%s is not a list", paramname
);
1394 ret
= talloc_array(NULL
, const char *, PyList_Size(list
)+1);
1400 for (i
= 0; i
< PyList_Size(list
); i
++) {
1401 const char *str
= NULL
;
1403 PyObject
*item
= PyList_GetItem(list
, i
);
1404 if (!PyUnicode_Check(item
)) {
1405 PyErr_Format(PyExc_TypeError
, "%s should be strings", paramname
);
1409 str
= PyUnicode_AsUTF8AndSize(item
, &size
);
1414 ret
[i
] = talloc_strndup(ret
, str
, size
);
1420 static PyObject
*py_ldb_connect(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
);
1422 static int py_ldb_init(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1424 const char * const kwnames
[] = { "url", "flags", "options", NULL
};
1426 PyObject
*py_options
= NULL
;
1427 unsigned int flags
= 0;
1429 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|zIO:Ldb.__init__",
1430 discard_const_p(char *, kwnames
),
1431 &url
, &flags
, &py_options
)) {
1436 /* py_ldb_connect returns py_None on success, NULL on error */
1437 PyObject
*result
= py_ldb_connect(self
, args
, kwargs
);
1438 if (result
== NULL
) {
1443 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1444 ldb_set_flags(ldb
, flags
);
1450 static PyObject
*py_ldb_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
1452 TALLOC_CTX
*mem_ctx
= NULL
;
1454 struct ldb_context
*ldb
;
1456 mem_ctx
= talloc_new(NULL
);
1457 if (mem_ctx
== NULL
) {
1458 return PyErr_NoMemory();
1461 ldb
= ldb_init(mem_ctx
, NULL
);
1463 talloc_free(mem_ctx
);
1468 ret
= (PyLdbObject
*)type
->tp_alloc(type
, 0);
1470 talloc_free(mem_ctx
);
1474 ret
->mem_ctx
= mem_ctx
;
1477 return (PyObject
*)ret
;
1480 static PyObject
*py_ldb_connect(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1483 unsigned int flags
= 0;
1484 PyObject
*py_options
= Py_None
;
1486 const char **options
;
1487 const char * const kwnames
[] = { "url", "flags", "options", NULL
};
1488 struct ldb_context
*ldb_ctx
;
1490 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|IO",
1491 discard_const_p(char *, kwnames
),
1492 &url
, &flags
, &py_options
))
1495 if (py_options
== Py_None
) {
1498 options
= PyList_AsStrList(NULL
, py_options
, "options");
1499 if (options
== NULL
)
1503 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1504 ret
= ldb_connect(ldb_ctx
, url
, flags
, options
);
1505 talloc_free(options
);
1507 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1512 static PyObject
*py_ldb_modify(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1515 PyObject
*py_controls
= Py_None
;
1516 struct ldb_context
*ldb_ctx
;
1517 struct ldb_request
*req
;
1518 struct ldb_control
**parsed_controls
;
1519 struct ldb_message
*msg
;
1521 TALLOC_CTX
*mem_ctx
;
1523 const char * const kwnames
[] = { "message", "controls", "validate", NULL
};
1525 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Ob",
1526 discard_const_p(char *, kwnames
),
1527 &py_msg
, &py_controls
, &validate
))
1530 mem_ctx
= talloc_new(NULL
);
1531 if (mem_ctx
== NULL
) {
1535 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1537 if (py_controls
== Py_None
) {
1538 parsed_controls
= NULL
;
1540 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1541 if (controls
== NULL
) {
1542 talloc_free(mem_ctx
);
1545 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1546 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
1547 talloc_free(mem_ctx
);
1548 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
1551 talloc_free(controls
);
1554 if (!pyldb_Message_Check(py_msg
)) {
1555 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message");
1556 talloc_free(mem_ctx
);
1559 msg
= pyldb_Message_AsMessage(py_msg
);
1562 ret
= ldb_msg_sanity_check(ldb_ctx
, msg
);
1563 if (ret
!= LDB_SUCCESS
) {
1564 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1565 talloc_free(mem_ctx
);
1570 ret
= ldb_build_mod_req(&req
, ldb_ctx
, mem_ctx
, msg
, parsed_controls
,
1571 NULL
, ldb_op_default_callback
, NULL
);
1572 if (ret
!= LDB_SUCCESS
) {
1573 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1574 talloc_free(mem_ctx
);
1578 /* do request and autostart a transaction */
1579 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1581 ret
= ldb_transaction_start(ldb_ctx
);
1582 if (ret
!= LDB_SUCCESS
) {
1583 talloc_free(mem_ctx
);
1584 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1588 ret
= ldb_request(ldb_ctx
, req
);
1589 if (ret
== LDB_SUCCESS
) {
1590 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1593 if (ret
== LDB_SUCCESS
) {
1594 ret
= ldb_transaction_commit(ldb_ctx
);
1596 ldb_transaction_cancel(ldb_ctx
);
1599 talloc_free(mem_ctx
);
1600 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1607 * Obtain a ldb message from a Python Dictionary object.
1609 * @param mem_ctx Memory context
1610 * @param py_obj Python Dictionary object
1611 * @param ldb_ctx LDB context
1612 * @param mod_flags Flags to be set on every message element
1613 * @return ldb_message on success or NULL on failure
1615 static struct ldb_message
*PyDict_AsMessage(TALLOC_CTX
*mem_ctx
,
1617 struct ldb_context
*ldb_ctx
,
1618 unsigned int mod_flags
)
1620 struct ldb_message
*msg
;
1621 unsigned int msg_pos
= 0;
1622 Py_ssize_t dict_pos
= 0;
1623 PyObject
*key
, *value
;
1624 struct ldb_message_element
*msg_el
;
1625 PyObject
*dn_value
= PyDict_GetItemString(py_obj
, "dn");
1627 msg
= ldb_msg_new(mem_ctx
);
1632 msg
->elements
= talloc_zero_array(msg
, struct ldb_message_element
, PyDict_Size(py_obj
));
1633 if (msg
->elements
== NULL
) {
1640 struct ldb_dn
*dn
= NULL
;
1641 if (!pyldb_Object_AsDn(msg
, dn_value
, ldb_ctx
, &dn
)) {
1642 PyErr_SetString(PyExc_TypeError
, "unable to import dn object");
1647 PyErr_SetString(PyExc_TypeError
, "dn set but not found");
1651 msg
->dn
= talloc_reference(msg
, dn
);
1652 if (msg
->dn
== NULL
) {
1653 talloc_free(mem_ctx
);
1658 PyErr_SetString(PyExc_TypeError
, "no dn set");
1663 while (PyDict_Next(py_obj
, &dict_pos
, &key
, &value
)) {
1664 const char *key_str
= PyUnicode_AsUTF8(key
);
1665 if (ldb_attr_cmp(key_str
, "dn") != 0) {
1666 msg_el
= PyObject_AsMessageElement(msg
->elements
, value
,
1667 mod_flags
, key_str
);
1668 if (msg_el
== NULL
) {
1669 PyErr_Format(PyExc_TypeError
, "unable to import element '%s'", key_str
);
1673 memcpy(&msg
->elements
[msg_pos
], msg_el
, sizeof(*msg_el
));
1676 * PyObject_AsMessageElement might have returned a
1677 * reference to an existing MessageElement, and so left
1678 * the name and flags unchanged. Thus if those members
1679 * aren’t set, we’ll assume that the user forgot to
1682 if (msg
->elements
[msg_pos
].name
== NULL
) {
1683 /* No name was set — set it now. */
1684 msg
->elements
[msg_pos
].name
= talloc_strdup(msg
->elements
, key_str
);
1685 if (msg
->elements
[msg_pos
].name
== NULL
) {
1691 if (msg
->elements
[msg_pos
].flags
== 0) {
1692 /* No flags were set — set them now. */
1693 msg
->elements
[msg_pos
].flags
= mod_flags
;
1700 msg
->num_elements
= msg_pos
;
1705 static PyObject
*py_ldb_add(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1709 struct ldb_context
*ldb_ctx
;
1710 struct ldb_request
*req
;
1711 struct ldb_message
*msg
= NULL
;
1712 PyObject
*py_controls
= Py_None
;
1713 TALLOC_CTX
*mem_ctx
;
1714 struct ldb_control
**parsed_controls
;
1715 const char * const kwnames
[] = { "message", "controls", NULL
};
1717 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O",
1718 discard_const_p(char *, kwnames
),
1719 &py_obj
, &py_controls
))
1722 mem_ctx
= talloc_new(NULL
);
1723 if (mem_ctx
== NULL
) {
1727 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1729 if (py_controls
== Py_None
) {
1730 parsed_controls
= NULL
;
1732 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1733 if (controls
== NULL
) {
1734 talloc_free(mem_ctx
);
1737 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1738 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
1739 talloc_free(mem_ctx
);
1740 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
1743 talloc_free(controls
);
1746 if (pyldb_Message_Check(py_obj
)) {
1747 msg
= pyldb_Message_AsMessage(py_obj
);
1748 } else if (PyDict_Check(py_obj
)) {
1749 msg
= PyDict_AsMessage(mem_ctx
, py_obj
, ldb_ctx
, LDB_FLAG_MOD_ADD
);
1751 PyErr_SetString(PyExc_TypeError
,
1752 "Dictionary or LdbMessage object expected!");
1756 /* we should have a PyErr already set */
1757 talloc_free(mem_ctx
);
1761 ret
= ldb_msg_sanity_check(ldb_ctx
, msg
);
1762 if (ret
!= LDB_SUCCESS
) {
1763 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1764 talloc_free(mem_ctx
);
1768 ret
= ldb_build_add_req(&req
, ldb_ctx
, mem_ctx
, msg
, parsed_controls
,
1769 NULL
, ldb_op_default_callback
, NULL
);
1770 if (ret
!= LDB_SUCCESS
) {
1771 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1772 talloc_free(mem_ctx
);
1776 /* do request and autostart a transaction */
1777 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1779 ret
= ldb_transaction_start(ldb_ctx
);
1780 if (ret
!= LDB_SUCCESS
) {
1781 talloc_free(mem_ctx
);
1782 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1786 ret
= ldb_request(ldb_ctx
, req
);
1787 if (ret
== LDB_SUCCESS
) {
1788 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1791 if (ret
== LDB_SUCCESS
) {
1792 ret
= ldb_transaction_commit(ldb_ctx
);
1794 ldb_transaction_cancel(ldb_ctx
);
1797 talloc_free(mem_ctx
);
1798 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1803 static PyObject
*py_ldb_delete(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1808 struct ldb_context
*ldb_ctx
;
1809 struct ldb_request
*req
;
1810 PyObject
*py_controls
= Py_None
;
1811 TALLOC_CTX
*mem_ctx
;
1812 struct ldb_control
**parsed_controls
;
1813 const char * const kwnames
[] = { "dn", "controls", NULL
};
1815 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O",
1816 discard_const_p(char *, kwnames
),
1817 &py_dn
, &py_controls
))
1820 mem_ctx
= talloc_new(NULL
);
1821 if (mem_ctx
== NULL
) {
1825 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1827 if (py_controls
== Py_None
) {
1828 parsed_controls
= NULL
;
1830 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1831 if (controls
== NULL
) {
1832 talloc_free(mem_ctx
);
1835 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1836 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
1837 talloc_free(mem_ctx
);
1838 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
1841 talloc_free(controls
);
1844 if (!pyldb_Object_AsDn(mem_ctx
, py_dn
, ldb_ctx
, &dn
)) {
1845 talloc_free(mem_ctx
);
1849 ret
= ldb_build_del_req(&req
, ldb_ctx
, mem_ctx
, dn
, parsed_controls
,
1850 NULL
, ldb_op_default_callback
, NULL
);
1851 if (ret
!= LDB_SUCCESS
) {
1852 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1853 talloc_free(mem_ctx
);
1857 /* do request and autostart a transaction */
1858 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1860 ret
= ldb_transaction_start(ldb_ctx
);
1861 if (ret
!= LDB_SUCCESS
) {
1862 talloc_free(mem_ctx
);
1863 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1867 ret
= ldb_request(ldb_ctx
, req
);
1868 if (ret
== LDB_SUCCESS
) {
1869 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1872 if (ret
== LDB_SUCCESS
) {
1873 ret
= ldb_transaction_commit(ldb_ctx
);
1875 ldb_transaction_cancel(ldb_ctx
);
1878 talloc_free(mem_ctx
);
1879 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1884 static PyObject
*py_ldb_rename(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1886 PyObject
*py_dn1
, *py_dn2
;
1887 struct ldb_dn
*dn1
, *dn2
;
1889 TALLOC_CTX
*mem_ctx
;
1890 PyObject
*py_controls
= Py_None
;
1891 struct ldb_control
**parsed_controls
;
1892 struct ldb_context
*ldb_ctx
;
1893 struct ldb_request
*req
;
1894 const char * const kwnames
[] = { "dn1", "dn2", "controls", NULL
};
1896 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1898 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|O",
1899 discard_const_p(char *, kwnames
),
1900 &py_dn1
, &py_dn2
, &py_controls
))
1904 mem_ctx
= talloc_new(NULL
);
1905 if (mem_ctx
== NULL
) {
1910 if (py_controls
== Py_None
) {
1911 parsed_controls
= NULL
;
1913 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
1914 if (controls
== NULL
) {
1915 talloc_free(mem_ctx
);
1918 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
1919 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
1920 talloc_free(mem_ctx
);
1921 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
1924 talloc_free(controls
);
1928 if (!pyldb_Object_AsDn(mem_ctx
, py_dn1
, ldb_ctx
, &dn1
)) {
1929 talloc_free(mem_ctx
);
1933 if (!pyldb_Object_AsDn(mem_ctx
, py_dn2
, ldb_ctx
, &dn2
)) {
1934 talloc_free(mem_ctx
);
1938 ret
= ldb_build_rename_req(&req
, ldb_ctx
, mem_ctx
, dn1
, dn2
, parsed_controls
,
1939 NULL
, ldb_op_default_callback
, NULL
);
1940 if (ret
!= LDB_SUCCESS
) {
1941 PyErr_SetString(PyExc_TypeError
, "failed to build request");
1942 talloc_free(mem_ctx
);
1946 /* do request and autostart a transaction */
1947 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1949 ret
= ldb_transaction_start(ldb_ctx
);
1950 if (ret
!= LDB_SUCCESS
) {
1951 talloc_free(mem_ctx
);
1952 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
1956 ret
= ldb_request(ldb_ctx
, req
);
1957 if (ret
== LDB_SUCCESS
) {
1958 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1961 if (ret
== LDB_SUCCESS
) {
1962 ret
= ldb_transaction_commit(ldb_ctx
);
1964 ldb_transaction_cancel(ldb_ctx
);
1967 talloc_free(mem_ctx
);
1968 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
1973 static PyObject
*py_ldb_schema_attribute_remove(PyLdbObject
*self
, PyObject
*args
)
1976 if (!PyArg_ParseTuple(args
, "s", &name
))
1979 ldb_schema_attribute_remove(pyldb_Ldb_AS_LDBCONTEXT(self
), name
);
1984 static PyObject
*py_ldb_schema_attribute_add(PyLdbObject
*self
, PyObject
*args
)
1986 char *attribute
, *syntax
;
1989 struct ldb_context
*ldb_ctx
;
1991 if (!PyArg_ParseTuple(args
, "sIs", &attribute
, &flags
, &syntax
))
1994 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
1995 ret
= ldb_schema_attribute_add(ldb_ctx
, attribute
, flags
, syntax
);
1997 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb_ctx
);
2002 static PyObject
*ldb_ldif_to_pyobject(PyLdbObject
*pyldb
, struct ldb_ldif
*ldif
)
2004 PyObject
*obj
= NULL
;
2005 PyObject
*result
= NULL
;
2006 struct ldb_context
*ldb
= pyldb
->ldb_ctx
;
2012 switch (ldif
->changetype
) {
2013 case LDB_CHANGETYPE_NONE
:
2014 case LDB_CHANGETYPE_ADD
:
2015 obj
= PyLdbMessage_FromMessage(ldif
->msg
, pyldb
);
2017 case LDB_CHANGETYPE_MODIFY
:
2018 obj
= PyLdbMessage_FromMessage(ldif
->msg
, pyldb
);
2020 case LDB_CHANGETYPE_DELETE
:
2021 if (ldif
->msg
->num_elements
!= 0) {
2022 PyErr_Format(PyExc_ValueError
,
2023 "CHANGETYPE(DELETE) with num_elements=%u",
2024 ldif
->msg
->num_elements
);
2027 obj
= pyldb_Dn_FromDn(ldif
->msg
->dn
, pyldb
);
2029 case LDB_CHANGETYPE_MODRDN
: {
2030 struct ldb_dn
*olddn
= NULL
;
2031 PyObject
*olddn_obj
= NULL
;
2032 bool deleteoldrdn
= false;
2033 PyObject
*deleteoldrdn_obj
= NULL
;
2034 struct ldb_dn
*newdn
= NULL
;
2035 PyObject
*newdn_obj
= NULL
;
2038 ret
= ldb_ldif_parse_modrdn(ldb
,
2046 if (ret
!= LDB_SUCCESS
) {
2047 PyErr_Format(PyExc_ValueError
,
2048 "ldb_ldif_parse_modrdn() failed");
2052 olddn_obj
= pyldb_Dn_FromDn(olddn
, pyldb
);
2053 if (olddn_obj
== NULL
) {
2057 deleteoldrdn_obj
= Py_True
;
2059 deleteoldrdn_obj
= Py_False
;
2061 newdn_obj
= pyldb_Dn_FromDn(newdn
, pyldb
);
2062 if (newdn_obj
== NULL
) {
2063 deleteoldrdn_obj
= NULL
;
2064 Py_CLEAR(olddn_obj
);
2068 obj
= Py_BuildValue(discard_const_p(char, "{s:O,s:O,s:O}"),
2070 "deleteoldrdn", deleteoldrdn_obj
,
2071 "newdn", newdn_obj
);
2072 Py_CLEAR(olddn_obj
);
2073 deleteoldrdn_obj
= NULL
;
2074 Py_CLEAR(newdn_obj
);
2078 PyErr_Format(PyExc_NotImplementedError
,
2079 "Unsupported LDB_CHANGETYPE(%u)",
2088 /* We don't want this being attached * to the 'ldb' any more */
2089 result
= Py_BuildValue(discard_const_p(char, "(iO)"),
2097 static PyObject
*py_ldb_write_ldif(PyLdbObject
*self
, PyObject
*args
)
2101 struct ldb_ldif ldif
;
2104 TALLOC_CTX
*mem_ctx
;
2106 if (!PyArg_ParseTuple(args
, "Oi", &py_msg
, &changetype
))
2109 if (!pyldb_Message_Check(py_msg
)) {
2110 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for msg");
2114 ldif
.msg
= pyldb_Message_AsMessage(py_msg
);
2115 ldif
.changetype
= changetype
;
2117 mem_ctx
= talloc_new(NULL
);
2118 if (mem_ctx
== NULL
) {
2119 return PyErr_NoMemory();
2122 string
= ldb_ldif_write_string(pyldb_Ldb_AS_LDBCONTEXT(self
), mem_ctx
, &ldif
);
2124 PyErr_SetString(PyExc_KeyError
, "Failed to generate LDIF");
2125 talloc_free(mem_ctx
);
2129 ret
= PyUnicode_FromString(string
);
2131 talloc_free(mem_ctx
);
2136 static PyObject
*py_ldb_parse_ldif(PyLdbObject
*self
, PyObject
*args
)
2138 PyObject
*list
, *ret
;
2139 struct ldb_ldif
*ldif
;
2141 struct ldb_dn
*last_dn
= NULL
;
2143 TALLOC_CTX
*mem_ctx
;
2145 if (!PyArg_ParseTuple(args
, "s", &s
))
2148 mem_ctx
= talloc_new(NULL
);
2153 list
= PyList_New(0);
2155 talloc_free(mem_ctx
);
2159 while (s
&& *s
!= '\0') {
2160 ldif
= ldb_ldif_read_string(self
->ldb_ctx
, &s
);
2161 talloc_steal(mem_ctx
, ldif
);
2164 PyObject
*py_ldif
= ldb_ldif_to_pyobject(self
, ldif
);
2165 if (py_ldif
== NULL
) {
2167 if (PyErr_Occurred() == NULL
) {
2168 PyErr_BadArgument();
2170 talloc_free(mem_ctx
);
2173 res
= PyList_Append(list
, py_ldif
);
2177 talloc_free(mem_ctx
);
2180 last_dn
= ldif
->msg
->dn
;
2182 const char *last_dn_str
= NULL
;
2183 const char *err_string
= NULL
;
2184 if (last_dn
== NULL
) {
2185 PyErr_SetString(PyExc_ValueError
,
2186 "unable to parse LDIF "
2187 "string at first chunk");
2189 talloc_free(mem_ctx
);
2194 = ldb_dn_get_linearized(last_dn
);
2197 = talloc_asprintf(mem_ctx
,
2198 "unable to parse ldif "
2202 PyErr_SetString(PyExc_ValueError
,
2204 talloc_free(mem_ctx
);
2209 talloc_free(mem_ctx
); /* The pyobject already has a reference to the things it needs */
2210 ret
= PyObject_GetIter(list
);
2215 static PyObject
*py_ldb_msg_diff(PyLdbObject
*self
, PyObject
*args
)
2218 PyObject
*py_msg_old
;
2219 PyObject
*py_msg_new
;
2220 struct ldb_message
*diff
;
2221 struct ldb_context
*ldb
;
2223 TALLOC_CTX
*mem_ctx
= NULL
;
2225 if (!PyArg_ParseTuple(args
, "OO", &py_msg_old
, &py_msg_new
))
2228 if (!pyldb_Message_Check(py_msg_old
)) {
2229 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for old message");
2233 if (!pyldb_Message_Check(py_msg_new
)) {
2234 PyErr_SetString(PyExc_TypeError
, "Expected Ldb Message for new message");
2238 mem_ctx
= talloc_new(NULL
);
2239 if (mem_ctx
== NULL
) {
2244 ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2245 ldb_ret
= ldb_msg_difference(ldb
, mem_ctx
,
2246 pyldb_Message_AsMessage(py_msg_old
),
2247 pyldb_Message_AsMessage(py_msg_new
),
2249 if (ldb_ret
!= LDB_SUCCESS
) {
2250 talloc_free(mem_ctx
);
2251 PyErr_SetString(PyExc_RuntimeError
, "Failed to generate the Ldb Message diff");
2255 diff
= ldb_msg_copy(mem_ctx
, diff
);
2257 talloc_free(mem_ctx
);
2262 py_ret
= PyLdbMessage_FromMessage(diff
, self
);
2264 talloc_free(mem_ctx
);
2269 static PyObject
*py_ldb_schema_format_value(PyLdbObject
*self
, PyObject
*args
)
2271 const struct ldb_schema_attribute
*a
;
2272 struct ldb_val old_val
;
2273 struct ldb_val new_val
;
2274 TALLOC_CTX
*mem_ctx
;
2281 if (!PyArg_ParseTuple(args
, "sO", &element_name
, &val
))
2284 result
= PyBytes_AsStringAndSize(val
, (char **)&old_val
.data
, &size
);
2285 old_val
.length
= size
;
2288 PyErr_SetString(PyExc_RuntimeError
, "Failed to convert passed value to String");
2292 a
= ldb_schema_attribute_by_name(pyldb_Ldb_AS_LDBCONTEXT(self
), element_name
);
2298 mem_ctx
= talloc_new(NULL
);
2299 if (mem_ctx
== NULL
) {
2304 if (a
->syntax
->ldif_write_fn(pyldb_Ldb_AS_LDBCONTEXT(self
), mem_ctx
, &old_val
, &new_val
) != 0) {
2305 talloc_free(mem_ctx
);
2309 ret
= PyBytes_FromStringAndSize((const char *)new_val
.data
, new_val
.length
);
2311 talloc_free(mem_ctx
);
2316 static PyObject
*py_ldb_search(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
2318 PyObject
*py_base
= Py_None
;
2319 int scope
= LDB_SCOPE_DEFAULT
;
2321 PyObject
*py_attrs
= Py_None
;
2322 PyObject
*py_controls
= Py_None
;
2323 const char * const kwnames
[] = { "base", "scope", "expression", "attrs", "controls", NULL
};
2325 struct ldb_result
*res
;
2326 struct ldb_request
*req
;
2328 struct ldb_context
*ldb_ctx
;
2329 struct ldb_control
**parsed_controls
;
2330 struct ldb_dn
*base
;
2332 TALLOC_CTX
*mem_ctx
;
2334 /* type "int" rather than "enum" for "scope" is intentional */
2335 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OizOO",
2336 discard_const_p(char *, kwnames
),
2337 &py_base
, &scope
, &expr
, &py_attrs
, &py_controls
))
2341 mem_ctx
= talloc_new(NULL
);
2342 if (mem_ctx
== NULL
) {
2346 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2348 if (py_attrs
== Py_None
) {
2351 attrs
= PyList_AsStrList(mem_ctx
, py_attrs
, "attrs");
2352 if (attrs
== NULL
) {
2353 talloc_free(mem_ctx
);
2358 if (py_base
== Py_None
) {
2359 base
= ldb_get_default_basedn(ldb_ctx
);
2361 if (!pyldb_Object_AsDn(mem_ctx
, py_base
, ldb_ctx
, &base
)) {
2362 talloc_free(mem_ctx
);
2367 if (py_controls
== Py_None
) {
2368 parsed_controls
= NULL
;
2370 const char **controls
= PyList_AsStrList(mem_ctx
, py_controls
, "controls");
2371 if (controls
== NULL
) {
2372 talloc_free(mem_ctx
);
2375 parsed_controls
= ldb_parse_control_strings(ldb_ctx
, mem_ctx
, controls
);
2376 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
2377 talloc_free(mem_ctx
);
2378 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
2381 talloc_free(controls
);
2384 res
= talloc_zero(mem_ctx
, struct ldb_result
);
2387 talloc_free(mem_ctx
);
2391 ret
= ldb_build_search_req(&req
, ldb_ctx
, mem_ctx
,
2398 ldb_search_default_callback
,
2401 if (ret
!= LDB_SUCCESS
) {
2402 talloc_free(mem_ctx
);
2403 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2407 talloc_steal(req
, attrs
);
2409 ret
= ldb_request(ldb_ctx
, req
);
2411 if (ret
== LDB_SUCCESS
) {
2412 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
2415 if (ret
!= LDB_SUCCESS
) {
2416 talloc_free(mem_ctx
);
2417 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2421 py_ret
= PyLdbResult_FromResult(res
, self
);
2423 talloc_free(mem_ctx
);
2428 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply
*reply
)
2430 if (reply
->py_iter
!= NULL
) {
2431 DLIST_REMOVE(reply
->py_iter
->state
.next
, reply
);
2432 if (reply
->py_iter
->state
.result
== reply
) {
2433 reply
->py_iter
->state
.result
= NULL
;
2435 reply
->py_iter
= NULL
;
2438 Py_CLEAR(reply
->obj
);
2443 static int py_ldb_search_iterator_callback(struct ldb_request
*req
,
2444 struct ldb_reply
*ares
)
2446 PyLdbSearchIteratorObject
*py_iter
= (PyLdbSearchIteratorObject
*)req
->context
;
2447 struct ldb_result result
= { .msgs
= NULL
};
2448 struct py_ldb_search_iterator_reply
*reply
= NULL
;
2451 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2454 if (ares
->error
!= LDB_SUCCESS
) {
2455 int ret
= ares
->error
;
2457 return ldb_request_done(req
, ret
);
2460 reply
= talloc_zero(py_iter
->mem_ctx
,
2461 struct py_ldb_search_iterator_reply
);
2462 if (reply
== NULL
) {
2464 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2466 reply
->py_iter
= py_iter
;
2467 talloc_set_destructor(reply
, py_ldb_search_iterator_reply_destructor
);
2469 switch (ares
->type
) {
2470 case LDB_REPLY_ENTRY
:
2471 reply
->obj
= PyLdbMessage_FromMessage(ares
->message
, py_iter
->ldb
);
2472 if (reply
->obj
== NULL
) {
2474 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2476 DLIST_ADD_END(py_iter
->state
.next
, reply
);
2480 case LDB_REPLY_REFERRAL
:
2481 reply
->obj
= PyUnicode_FromString(ares
->referral
);
2482 if (reply
->obj
== NULL
) {
2484 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2486 DLIST_ADD_END(py_iter
->state
.next
, reply
);
2490 case LDB_REPLY_DONE
:
2491 result
= (struct ldb_result
) { .controls
= ares
->controls
};
2492 reply
->obj
= PyLdbResult_FromResult(&result
, py_iter
->ldb
);
2493 if (reply
->obj
== NULL
) {
2495 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2497 py_iter
->state
.result
= reply
;
2499 return ldb_request_done(req
, LDB_SUCCESS
);
2503 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
2506 static PyObject
*py_ldb_search_iterator(PyLdbObject
*self
, PyObject
*args
, PyObject
*kwargs
)
2508 PyObject
*py_base
= Py_None
;
2509 int scope
= LDB_SCOPE_DEFAULT
;
2512 PyObject
*py_attrs
= Py_None
;
2513 PyObject
*py_controls
= Py_None
;
2514 const char * const kwnames
[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL
};
2517 struct ldb_context
*ldb_ctx
;
2518 struct ldb_control
**parsed_controls
;
2519 struct ldb_dn
*base
;
2520 PyLdbSearchIteratorObject
*py_iter
;
2522 /* type "int" rather than "enum" for "scope" is intentional */
2523 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OizOOi",
2524 discard_const_p(char *, kwnames
),
2525 &py_base
, &scope
, &expr
, &py_attrs
, &py_controls
, &timeout
))
2528 py_iter
= (PyLdbSearchIteratorObject
*)PyLdbSearchIterator
.tp_alloc(&PyLdbSearchIterator
, 0);
2529 if (py_iter
== NULL
) {
2533 py_iter
->ldb
= self
;
2535 ZERO_STRUCT(py_iter
->state
);
2536 py_iter
->mem_ctx
= talloc_new(NULL
);
2537 if (py_iter
->mem_ctx
== NULL
) {
2543 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2545 if (py_attrs
== Py_None
) {
2548 attrs
= PyList_AsStrList(py_iter
->mem_ctx
, py_attrs
, "attrs");
2549 if (attrs
== NULL
) {
2556 if (py_base
== Py_None
) {
2557 base
= ldb_get_default_basedn(ldb_ctx
);
2559 if (!pyldb_Object_AsDn(py_iter
->mem_ctx
, py_base
, ldb_ctx
, &base
)) {
2566 if (py_controls
== Py_None
) {
2567 parsed_controls
= NULL
;
2569 const char **controls
= NULL
;
2571 controls
= PyList_AsStrList(py_iter
->mem_ctx
,
2572 py_controls
, "controls");
2573 if (controls
== NULL
) {
2579 parsed_controls
= ldb_parse_control_strings(ldb_ctx
,
2582 if (controls
[0] != NULL
&& parsed_controls
== NULL
) {
2584 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, ldb_ctx
);
2587 talloc_free(controls
);
2590 ret
= ldb_build_search_req(&py_iter
->state
.req
,
2599 py_ldb_search_iterator_callback
,
2601 if (ret
!= LDB_SUCCESS
) {
2603 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2607 ldb_set_timeout(ldb_ctx
, py_iter
->state
.req
, timeout
);
2609 ret
= ldb_request(ldb_ctx
, py_iter
->state
.req
);
2610 if (ret
!= LDB_SUCCESS
) {
2612 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
2616 return (PyObject
*)py_iter
;
2619 static PyObject
*py_ldb_get_opaque(PyLdbObject
*self
, PyObject
*args
)
2624 if (!PyArg_ParseTuple(args
, "s", &name
))
2627 data
= ldb_get_opaque(pyldb_Ldb_AS_LDBCONTEXT(self
), name
);
2632 if (data
== (void *)1) {
2634 * This value is sometimes used to indicate that a opaque is
2642 * Let’s hope the opaque data is actually a talloc pointer,
2643 * otherwise calling this would be Very Bad.
2645 const bool *opaque
= talloc_get_type(data
, bool);
2646 if (opaque
!= NULL
) {
2647 return PyBool_FromLong(*opaque
);
2652 const unsigned long long *opaque
= talloc_get_type(
2653 data
, unsigned long long);
2654 if (opaque
!= NULL
) {
2655 return PyLong_FromUnsignedLongLong(*opaque
);
2660 const char *opaque
= talloc_get_type(data
, char);
2661 if (opaque
!= NULL
) {
2662 return PyUnicode_FromString(opaque
);
2666 PyErr_SetString(PyExc_ValueError
, "Unsupported type for opaque");
2670 static PyObject
*py_ldb_set_opaque(PyLdbObject
*self
, PyObject
*args
)
2677 if (!PyArg_ParseTuple(args
, "sO", &name
, &data
))
2680 if (data
== Py_None
) {
2682 } else if (PyBool_Check(data
)) {
2683 bool *opaque
= NULL
;
2686 const int is_true
= PyObject_IsTrue(data
);
2687 if (is_true
== -1) {
2693 opaque
= talloc(self
->ldb_ctx
, bool);
2694 if (opaque
== NULL
) {
2695 return PyErr_NoMemory();
2699 } else if (PyLong_Check(data
)) {
2700 unsigned long long *opaque
= NULL
;
2701 const unsigned long long n
= PyLong_AsUnsignedLongLong(data
);
2702 if (n
== -1 && PyErr_Occurred()) {
2706 opaque
= talloc(self
->ldb_ctx
, unsigned long long);
2707 if (opaque
== NULL
) {
2708 return PyErr_NoMemory();
2712 } else if (PyUnicode_Check(data
)) {
2713 char *opaque
= NULL
;
2714 const char *s
= PyUnicode_AsUTF8(data
);
2719 opaque
= talloc_strdup(self
->ldb_ctx
, s
);
2720 if (opaque
== NULL
) {
2721 return PyErr_NoMemory();
2725 * Assign the right type to the talloc pointer, so that
2726 * py_ldb_get_opaque() can recognize it.
2728 talloc_set_name_const(opaque
, "char");
2732 PyErr_SetString(PyExc_ValueError
,
2733 "Unsupported type for opaque");
2737 ret
= ldb_set_opaque(pyldb_Ldb_AS_LDBCONTEXT(self
), name
, value
);
2739 PyErr_SetLdbError(PyExc_LdbError
,
2741 pyldb_Ldb_AS_LDBCONTEXT(self
));
2748 static PyObject
*py_ldb_sequence_number(PyLdbObject
*self
, PyObject
*args
)
2750 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2754 if (!PyArg_ParseTuple(args
, "i", &type
))
2757 /* FIXME: More interpretation */
2759 ret
= ldb_sequence_number(ldb
, type
, &value
);
2761 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2763 return PyLong_FromLongLong(value
);
2766 static PyObject
*py_ldb_whoami(PyLdbObject
*self
, PyObject
*args
)
2768 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2769 struct ldb_result
*res
= NULL
;
2770 struct ldb_extended
*ext_res
= NULL
;
2774 ret
= ldb_extended(ldb
, LDB_EXTENDED_WHOAMI_OID
, NULL
, &res
);
2775 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2777 ext_res
= res
->extended
;
2778 if (ext_res
== NULL
) {
2779 PyErr_SetString(PyExc_TypeError
, "Got no exop reply");
2783 if (strcmp(ext_res
->oid
, LDB_EXTENDED_WHOAMI_OID
) != 0) {
2784 PyErr_SetString(PyExc_TypeError
, "Got wrong reply OID");
2788 len
= talloc_get_size(ext_res
->data
);
2793 return PyUnicode_FromStringAndSize(ext_res
->data
, len
);
2796 static PyObject
*py_ldb_disconnect(PyLdbObject
*self
, PyObject
*args
)
2799 void *parent
= NULL
;
2800 TALLOC_CTX
*mem_ctx
= NULL
;
2801 struct ldb_context
*ldb
= NULL
;
2803 if (self
->ldb_ctx
== NULL
) {
2804 /* It is hard to see how we'd get here. */
2805 PyErr_SetLdbError(PyExc_LdbError
, LDB_ERR_OPERATIONS_ERROR
, NULL
);
2809 ref_count
= talloc_reference_count(self
->ldb_ctx
);
2811 if (ref_count
!= 0) {
2812 PyErr_SetString(PyExc_RuntimeError
,
2813 "ldb.disconnect() not possible as "
2814 "object still has C (or second "
2815 "python object) references");
2819 parent
= talloc_parent(self
->ldb_ctx
);
2821 if (parent
!= self
->mem_ctx
) {
2822 PyErr_SetString(PyExc_RuntimeError
,
2823 "ldb.disconnect() not possible as "
2824 "object is not talloc owned by this "
2830 * This recapitulates py_ldb_new(), cleaning out all the
2831 * connections and state, but leaving the python object in a
2832 * workable condition.
2834 mem_ctx
= talloc_new(NULL
);
2835 if (mem_ctx
== NULL
) {
2836 return PyErr_NoMemory();
2839 ldb
= ldb_init(mem_ctx
, NULL
);
2841 talloc_free(mem_ctx
);
2847 * Notice we allocate the new mem_ctx and ldb before freeing
2848 * the old one. This has two purposes: 1, the python object
2849 * will still be consistent if an exception happens, and 2, it
2850 * ensures the new ldb can't have the same memory address as
2851 * the old one, and ldb address equality is a guard we use in
2852 * Python DNs and such. Repeated calls to disconnect() *can* make
2853 * this happen, so we don't advise doing that.
2855 TALLOC_FREE(self
->mem_ctx
);
2857 self
->mem_ctx
= mem_ctx
;
2858 self
->ldb_ctx
= ldb
;
2864 static const struct ldb_dn_extended_syntax test_dn_syntax
= {
2866 .read_fn
= ldb_handler_copy
,
2867 .write_clear_fn
= ldb_handler_copy
,
2868 .write_hex_fn
= ldb_handler_copy
,
2871 static PyObject
*py_ldb_register_test_extensions(PyLdbObject
*self
,
2872 PyObject
*Py_UNUSED(ignored
))
2874 struct ldb_context
*ldb
= pyldb_Ldb_AS_LDBCONTEXT(self
);
2877 ret
= ldb_dn_extended_add_syntax(ldb
, LDB_ATTR_FLAG_FIXED
, &test_dn_syntax
);
2879 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, ldb
);
2885 static PyMethodDef py_ldb_methods
[] = {
2886 { "set_debug", (PyCFunction
)py_ldb_set_debug
, METH_VARARGS
,
2887 "S.set_debug(callback) -> None\n"
2888 "Set callback for LDB debug messages.\n"
2889 "The callback should accept a debug level and debug text." },
2890 { "set_create_perms", (PyCFunction
)py_ldb_set_create_perms
, METH_VARARGS
,
2891 "S.set_create_perms(mode) -> None\n"
2892 "Set mode to use when creating new LDB files." },
2893 { "set_modules_dir", (PyCFunction
)py_ldb_set_modules_dir
, METH_VARARGS
,
2894 "S.set_modules_dir(path) -> None\n"
2895 "Set path LDB should search for modules" },
2896 { "transaction_start", (PyCFunction
)py_ldb_transaction_start
, METH_NOARGS
,
2897 "S.transaction_start() -> None\n"
2898 "Start a new transaction." },
2899 { "transaction_prepare_commit", (PyCFunction
)py_ldb_transaction_prepare_commit
, METH_NOARGS
,
2900 "S.transaction_prepare_commit() -> None\n"
2901 "prepare to commit a new transaction (2-stage commit)." },
2902 { "transaction_commit", (PyCFunction
)py_ldb_transaction_commit
, METH_NOARGS
,
2903 "S.transaction_commit() -> None\n"
2904 "commit a new transaction." },
2905 { "transaction_cancel", (PyCFunction
)py_ldb_transaction_cancel
, METH_NOARGS
,
2906 "S.transaction_cancel() -> None\n"
2907 "cancel a new transaction." },
2908 { "setup_wellknown_attributes", (PyCFunction
)py_ldb_setup_wellknown_attributes
, METH_NOARGS
,
2910 { "get_root_basedn", (PyCFunction
)py_ldb_get_root_basedn
, METH_NOARGS
,
2912 { "get_schema_basedn", (PyCFunction
)py_ldb_get_schema_basedn
, METH_NOARGS
,
2914 { "get_default_basedn", (PyCFunction
)py_ldb_get_default_basedn
, METH_NOARGS
,
2916 { "get_config_basedn", (PyCFunction
)py_ldb_get_config_basedn
, METH_NOARGS
,
2918 { "connect", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_connect
),
2919 METH_VARARGS
|METH_KEYWORDS
,
2920 "S.connect(url, flags=0, options=None) -> None\n"
2921 "Connect to a LDB URL." },
2922 { "modify", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_modify
),
2923 METH_VARARGS
|METH_KEYWORDS
,
2924 "S.modify(message, controls=None, validate=False) -> None\n"
2925 "Modify an entry." },
2926 { "add", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_add
),
2927 METH_VARARGS
|METH_KEYWORDS
,
2928 "S.add(message, controls=None) -> None\n"
2930 { "delete", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_delete
),
2931 METH_VARARGS
|METH_KEYWORDS
,
2932 "S.delete(dn, controls=None) -> None\n"
2933 "Remove an entry." },
2934 { "rename", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_rename
),
2935 METH_VARARGS
|METH_KEYWORDS
,
2936 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2937 "Rename an entry." },
2938 { "search", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_search
),
2939 METH_VARARGS
|METH_KEYWORDS
,
2940 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2941 "Search in a database.\n"
2943 ":param base: Optional base DN to search\n"
2944 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2945 ":param expression: Optional search expression\n"
2946 ":param attrs: Attributes to return (defaults to all)\n"
2947 ":param controls: Optional list of controls\n"
2948 ":return: ldb.Result object\n"
2950 { "search_iterator", PY_DISCARD_FUNC_SIG(PyCFunction
,
2951 py_ldb_search_iterator
),
2952 METH_VARARGS
|METH_KEYWORDS
,
2953 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2954 "Search in a database.\n"
2956 ":param base: Optional base DN to search\n"
2957 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2958 ":param expression: Optional search expression\n"
2959 ":param attrs: Attributes to return (defaults to all)\n"
2960 ":param controls: Optional list of controls\n"
2961 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2962 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2964 { "schema_attribute_remove", (PyCFunction
)py_ldb_schema_attribute_remove
, METH_VARARGS
,
2966 { "schema_attribute_add", (PyCFunction
)py_ldb_schema_attribute_add
, METH_VARARGS
,
2968 { "schema_format_value", (PyCFunction
)py_ldb_schema_format_value
, METH_VARARGS
,
2970 { "parse_ldif", (PyCFunction
)py_ldb_parse_ldif
, METH_VARARGS
,
2971 "S.parse_ldif(ldif) -> iter(messages)\n"
2972 "Parse a string formatted using LDIF." },
2973 { "write_ldif", (PyCFunction
)py_ldb_write_ldif
, METH_VARARGS
,
2974 "S.write_ldif(message, changetype) -> ldif\n"
2975 "Print the message as a string formatted using LDIF." },
2976 { "msg_diff", (PyCFunction
)py_ldb_msg_diff
, METH_VARARGS
,
2977 "S.msg_diff(Message) -> Message\n"
2978 "Return an LDB Message of the difference between two Message objects." },
2979 { "get_opaque", (PyCFunction
)py_ldb_get_opaque
, METH_VARARGS
,
2980 "S.get_opaque(name) -> value\n"
2981 "Get an opaque value set on this LDB connection. \n"
2982 ":note: The returned value may not be useful in Python."
2984 { "set_opaque", (PyCFunction
)py_ldb_set_opaque
, METH_VARARGS
,
2985 "S.set_opaque(name, value) -> None\n"
2986 "Set an opaque value on this LDB connection. \n"
2987 ":note: Passing incorrect values may cause crashes." },
2988 { "sequence_number", (PyCFunction
)py_ldb_sequence_number
, METH_VARARGS
,
2989 "S.sequence_number(type) -> value\n"
2990 "Return the value of the sequence according to the requested type" },
2992 (PyCFunction
)py_ldb_whoami
,
2994 "S.whoami() -> value\n"
2995 "Return the RFC4532 whoami string",
2998 (PyCFunction
)py_ldb_disconnect
,
3000 "S.disconnect() -> None\n"
3001 "Make this Ldb object unusable, disconnect and free the "
3002 "underlying LDB, releasing any file handles and sockets.",
3004 { "_register_test_extensions", (PyCFunction
)py_ldb_register_test_extensions
, METH_NOARGS
,
3005 "S._register_test_extensions() -> None\n"
3006 "Register internal extensions used in testing" },
3010 static int py_ldb_contains(PyLdbObject
*self
, PyObject
*obj
)
3012 struct ldb_context
*ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
);
3014 struct ldb_result
*result
;
3018 if (!pyldb_Object_AsDn(ldb_ctx
, obj
, ldb_ctx
, &dn
)) {
3022 ret
= ldb_search(ldb_ctx
, ldb_ctx
, &result
, dn
, LDB_SCOPE_BASE
, NULL
,
3024 if (ret
!= LDB_SUCCESS
) {
3025 PyErr_SetLdbError(PyExc_LdbError
, ret
, ldb_ctx
);
3029 count
= result
->count
;
3031 talloc_free(result
);
3034 PyErr_Format(PyExc_RuntimeError
,
3035 "Searching for [%s] dn gave %u results!",
3036 ldb_dn_get_linearized(dn
),
3044 static PySequenceMethods py_ldb_seq
= {
3045 .sq_contains
= (objobjproc
)py_ldb_contains
,
3048 static void py_ldb_dealloc(PyLdbObject
*self
)
3050 talloc_free(self
->mem_ctx
);
3051 Py_TYPE(self
)->tp_free(self
);
3054 static PyTypeObject PyLdb
= {
3055 .tp_name
= "ldb.Ldb",
3056 .tp_methods
= py_ldb_methods
,
3057 .tp_repr
= (reprfunc
)py_ldb_repr
,
3058 .tp_new
= py_ldb_new
,
3059 .tp_init
= (initproc
)py_ldb_init
,
3060 .tp_dealloc
= (destructor
)py_ldb_dealloc
,
3061 .tp_getattro
= PyObject_GenericGetAttr
,
3062 .tp_basicsize
= sizeof(PyLdbObject
),
3063 .tp_doc
= "Connection to a LDB database.",
3064 .tp_as_sequence
= &py_ldb_seq
,
3065 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
3068 static void py_ldb_result_dealloc(PyLdbResultObject
*self
)
3070 talloc_free(self
->mem_ctx
);
3071 Py_CLEAR(self
->msgs
);
3072 Py_CLEAR(self
->referals
);
3073 Py_CLEAR(self
->controls
);
3074 Py_DECREF(self
->pyldb
);
3075 Py_TYPE(self
)->tp_free(self
);
3078 static PyObject
*py_ldb_result_get_msgs(PyLdbResultObject
*self
, void *closure
)
3080 Py_INCREF(self
->msgs
);
3084 static PyObject
*py_ldb_result_get_controls(PyLdbResultObject
*self
, void *closure
)
3086 Py_INCREF(self
->controls
);
3087 return self
->controls
;
3090 static PyObject
*py_ldb_result_get_referals(PyLdbResultObject
*self
, void *closure
)
3092 Py_INCREF(self
->referals
);
3093 return self
->referals
;
3096 static PyObject
*py_ldb_result_get_count(PyLdbResultObject
*self
, void *closure
)
3099 if (self
->msgs
== NULL
) {
3100 PyErr_SetString(PyExc_AttributeError
, "Count attribute is meaningless in this context");
3103 size
= PyList_Size(self
->msgs
);
3104 return PyLong_FromLong(size
);
3107 static PyGetSetDef py_ldb_result_getset
[] = {
3109 .name
= discard_const_p(char, "controls"),
3110 .get
= (getter
)py_ldb_result_get_controls
,
3113 .name
= discard_const_p(char, "msgs"),
3114 .get
= (getter
)py_ldb_result_get_msgs
,
3117 .name
= discard_const_p(char, "referals"),
3118 .get
= (getter
)py_ldb_result_get_referals
,
3121 .name
= discard_const_p(char, "count"),
3122 .get
= (getter
)py_ldb_result_get_count
,
3127 static PyObject
*py_ldb_result_iter(PyLdbResultObject
*self
)
3129 return PyObject_GetIter(self
->msgs
);
3132 static Py_ssize_t
py_ldb_result_len(PyLdbResultObject
*self
)
3134 return PySequence_Size(self
->msgs
);
3137 static PyObject
*py_ldb_result_find(PyLdbResultObject
*self
, Py_ssize_t idx
)
3139 return PySequence_GetItem(self
->msgs
, idx
);
3142 static PySequenceMethods py_ldb_result_seq
= {
3143 .sq_length
= (lenfunc
)py_ldb_result_len
,
3144 .sq_item
= (ssizeargfunc
)py_ldb_result_find
,
3147 static PyObject
*py_ldb_result_repr(PyLdbObject
*self
)
3149 return PyUnicode_FromString("<ldb result>");
3153 static PyTypeObject PyLdbResult
= {
3154 .tp_name
= "ldb.Result",
3155 .tp_repr
= (reprfunc
)py_ldb_result_repr
,
3156 .tp_dealloc
= (destructor
)py_ldb_result_dealloc
,
3157 .tp_iter
= (getiterfunc
)py_ldb_result_iter
,
3158 .tp_getset
= py_ldb_result_getset
,
3159 .tp_getattro
= PyObject_GenericGetAttr
,
3160 .tp_basicsize
= sizeof(PyLdbResultObject
),
3161 .tp_as_sequence
= &py_ldb_result_seq
,
3162 .tp_doc
= "LDB result.",
3163 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
3166 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject
*self
)
3168 Py_CLEAR(self
->state
.exception
);
3169 TALLOC_FREE(self
->mem_ctx
);
3170 ZERO_STRUCT(self
->state
);
3171 Py_CLEAR(self
->ldb
);
3172 Py_TYPE(self
)->tp_free(self
);
3175 static PyObject
*py_ldb_search_iterator_next(PyLdbSearchIteratorObject
*self
)
3177 PyObject
*py_ret
= NULL
;
3179 if (self
->state
.req
== NULL
) {
3180 PyErr_SetString(PyExc_RuntimeError
,
3181 "ldb.SearchIterator request already finished");
3186 * TODO: do we want a non-blocking mode?
3187 * In future we may add an optional 'nonblocking'
3188 * argument to search_iterator().
3190 * For now we keep it simple and wait for at
3194 while (self
->state
.next
== NULL
) {
3197 if (self
->state
.result
!= NULL
) {
3199 * We (already) got a final result from the server.
3201 * We stop the iteration and let
3202 * py_ldb_search_iterator_result() will deliver
3203 * the result details.
3205 TALLOC_FREE(self
->state
.req
);
3206 PyErr_SetNone(PyExc_StopIteration
);
3210 ret
= ldb_wait(self
->state
.req
->handle
, LDB_WAIT_NONE
);
3211 if (ret
!= LDB_SUCCESS
) {
3212 struct ldb_context
*ldb_ctx
;
3213 TALLOC_FREE(self
->state
.req
);
3214 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(self
->ldb
);
3216 * We stop the iteration and let
3217 * py_ldb_search_iterator_result() will deliver
3220 self
->state
.exception
= Py_BuildValue(discard_const_p(char, "(i,s)"),
3221 ret
, ldb_errstring(ldb_ctx
));
3222 PyErr_SetNone(PyExc_StopIteration
);
3227 py_ret
= self
->state
.next
->obj
;
3228 self
->state
.next
->obj
= NULL
;
3229 /* no TALLOC_FREE() as self->state.next is a list */
3230 talloc_free(self
->state
.next
);
3234 static PyObject
*py_ldb_search_iterator_result(PyLdbSearchIteratorObject
*self
,
3235 PyObject
*Py_UNUSED(ignored
))
3237 PyObject
*py_ret
= NULL
;
3239 if (self
->state
.req
!= NULL
) {
3240 PyErr_SetString(PyExc_RuntimeError
,
3241 "ldb.SearchIterator request running");
3245 if (self
->state
.next
!= NULL
) {
3246 PyErr_SetString(PyExc_RuntimeError
,
3247 "ldb.SearchIterator not fully consumed.");
3251 if (self
->state
.exception
!= NULL
) {
3252 PyErr_SetObject(PyExc_LdbError
, self
->state
.exception
);
3253 Py_DECREF(self
->state
.exception
);
3254 self
->state
.exception
= NULL
;
3258 if (self
->state
.result
== NULL
) {
3259 PyErr_SetString(PyExc_RuntimeError
,
3260 "ldb.SearchIterator result already consumed");
3264 py_ret
= self
->state
.result
->obj
;
3265 self
->state
.result
->obj
= NULL
;
3266 TALLOC_FREE(self
->state
.result
);
3270 static PyObject
*py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject
*self
,
3271 PyObject
*Py_UNUSED(ignored
))
3273 if (self
->state
.req
== NULL
) {
3274 PyErr_SetString(PyExc_RuntimeError
,
3275 "ldb.SearchIterator request already finished");
3279 Py_CLEAR(self
->state
.exception
);
3280 TALLOC_FREE(self
->mem_ctx
);
3281 ZERO_STRUCT(self
->state
);
3285 static PyMethodDef py_ldb_search_iterator_methods
[] = {
3286 { "result", (PyCFunction
)py_ldb_search_iterator_result
, METH_NOARGS
,
3287 "S.result() -> ldb.Result (without msgs and referrals)\n" },
3288 { "abandon", (PyCFunction
)py_ldb_search_iterator_abandon
, METH_NOARGS
,
3293 static PyObject
*py_ldb_search_iterator_repr(PyLdbSearchIteratorObject
*self
)
3295 return PyUnicode_FromString("<ldb search iterator>");
3298 static PyTypeObject PyLdbSearchIterator
= {
3299 .tp_name
= "ldb.SearchIterator",
3300 .tp_repr
= (reprfunc
)py_ldb_search_iterator_repr
,
3301 .tp_dealloc
= (destructor
)py_ldb_search_iterator_dealloc
,
3302 .tp_iter
= PyObject_SelfIter
,
3303 .tp_iternext
= (iternextfunc
)py_ldb_search_iterator_next
,
3304 .tp_methods
= py_ldb_search_iterator_methods
,
3305 .tp_basicsize
= sizeof(PyLdbSearchIteratorObject
),
3306 .tp_doc
= "LDB search_iterator.",
3307 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
3311 * Create a ldb_message_element from a Python object.
3313 * This will accept any sequence objects that contains strings, or
3316 * A reference to set_obj might be borrowed.
3318 * @param mem_ctx Memory context
3319 * @param set_obj Python object to convert
3320 * @param flags ldb_message_element flags to set, if a new element is returned
3321 * @param attr_name Name of the attribute to set, if a new element is returned
3322 * @return New ldb_message_element, allocated as child of mem_ctx
3324 static struct ldb_message_element
*PyObject_AsMessageElement(
3325 TALLOC_CTX
*mem_ctx
,
3328 const char *attr_name
)
3330 struct ldb_message_element
*me
;
3331 const char *msg
= NULL
;
3335 if (pyldb_MessageElement_Check(set_obj
)) {
3336 PyLdbMessageElementObject
*set_obj_as_me
= (PyLdbMessageElementObject
*)set_obj
;
3337 /* We have to talloc_reference() the memory context, not the pointer
3338 * which may not actually be it's own context */
3339 if (talloc_reference(mem_ctx
, set_obj_as_me
->mem_ctx
)) {
3340 return pyldb_MessageElement_AsMessageElement(set_obj
);
3345 me
= talloc(mem_ctx
, struct ldb_message_element
);
3351 me
->name
= talloc_strdup(me
, attr_name
);
3352 if (me
->name
== NULL
) {
3358 if (PyBytes_Check(set_obj
) || PyUnicode_Check(set_obj
)) {
3360 me
->values
= talloc_array(me
, struct ldb_val
, me
->num_values
);
3361 if (PyBytes_Check(set_obj
)) {
3363 result
= PyBytes_AsStringAndSize(set_obj
, &_msg
, &size
);
3370 msg
= PyUnicode_AsUTF8AndSize(set_obj
, &size
);
3376 me
->values
[0].data
= talloc_memdup(me
,
3377 (const uint8_t *)msg
,
3379 me
->values
[0].length
= size
;
3380 } else if (PySequence_Check(set_obj
)) {
3382 me
->num_values
= PySequence_Size(set_obj
);
3383 me
->values
= talloc_array(me
, struct ldb_val
, me
->num_values
);
3384 for (i
= 0; i
< me
->num_values
; i
++) {
3385 PyObject
*obj
= PySequence_GetItem(set_obj
, i
);
3386 if (PyBytes_Check(obj
)) {
3388 result
= PyBytes_AsStringAndSize(obj
, &_msg
, &size
);
3394 } else if (PyUnicode_Check(obj
)) {
3395 msg
= PyUnicode_AsUTF8AndSize(obj
, &size
);
3401 PyErr_Format(PyExc_TypeError
,
3402 "Expected string as element %zd in list", i
);
3406 me
->values
[i
].data
= talloc_memdup(me
,
3407 (const uint8_t *)msg
,
3409 me
->values
[i
].length
= size
;
3412 PyErr_Format(PyExc_TypeError
,
3413 "String or List type expected for '%s' attribute", attr_name
);
3422 static PyObject
*ldb_msg_element_to_set(struct ldb_context
*ldb_ctx
,
3423 struct ldb_message_element
*me
)
3428 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
3429 result
= PyList_New(me
->num_values
);
3430 if (result
== NULL
) {
3434 for (i
= 0; i
< me
->num_values
; i
++) {
3435 PyObject
*obj
= NULL
;
3438 obj
= PyObject_FromLdbValue(&me
->values
[i
]);
3444 ret
= PyList_SetItem(result
, i
, obj
);
3455 static PyObject
*py_ldb_msg_element_get(PyLdbMessageElementObject
*self
, PyObject
*args
)
3458 if (!PyArg_ParseTuple(args
, "I", &i
))
3460 if (i
>= pyldb_MessageElement_AsMessageElement(self
)->num_values
)
3463 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self
)->values
[i
]));
3466 static PyObject
*py_ldb_msg_element_flags(PyLdbMessageElementObject
*self
, PyObject
*args
)
3468 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3469 return PyLong_FromLong(el
->flags
);
3472 static PyObject
*py_ldb_msg_element_set_flags(PyLdbMessageElementObject
*self
, PyObject
*args
)
3475 struct ldb_message_element
*el
;
3476 if (!PyArg_ParseTuple(args
, "I", &flags
))
3479 el
= pyldb_MessageElement_AsMessageElement(self
);
3484 static PyMethodDef py_ldb_msg_element_methods
[] = {
3485 { "get", (PyCFunction
)py_ldb_msg_element_get
, METH_VARARGS
, NULL
},
3486 { "set_flags", (PyCFunction
)py_ldb_msg_element_set_flags
, METH_VARARGS
, NULL
},
3487 { "flags", (PyCFunction
)py_ldb_msg_element_flags
, METH_NOARGS
, NULL
},
3491 static Py_ssize_t
py_ldb_msg_element_len(PyLdbMessageElementObject
*self
)
3493 return pyldb_MessageElement_AsMessageElement(self
)->num_values
;
3496 static PyObject
*py_ldb_msg_element_find(PyLdbMessageElementObject
*self
, Py_ssize_t idx
)
3498 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3499 if (idx
< 0 || idx
>= el
->num_values
) {
3500 PyErr_SetString(PyExc_IndexError
, "Out of range");
3503 return PyLdbBytes_FromStringAndSize((char *)el
->values
[idx
].data
, el
->values
[idx
].length
);
3506 static PySequenceMethods py_ldb_msg_element_seq
= {
3507 .sq_length
= (lenfunc
)py_ldb_msg_element_len
,
3508 .sq_item
= (ssizeargfunc
)py_ldb_msg_element_find
,
3511 static PyObject
*py_ldb_msg_element_richcmp(PyObject
*self
, PyObject
*other
, int op
)
3514 if (!pyldb_MessageElement_Check(other
)) {
3515 Py_INCREF(Py_NotImplemented
);
3516 return Py_NotImplemented
;
3518 ret
= ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self
),
3519 pyldb_MessageElement_AsMessageElement(other
));
3520 return richcmp(ret
, op
);
3523 static PyObject
*py_ldb_msg_element_iter(PyLdbMessageElementObject
*self
)
3525 PyObject
*el
= ldb_msg_element_to_set(NULL
,
3526 pyldb_MessageElement_AsMessageElement(self
));
3527 PyObject
*ret
= PyObject_GetIter(el
);
3532 static PyObject
*PyLdbMessageElement_FromMessageElement(struct ldb_message_element
*el
, TALLOC_CTX
*mem_ctx
)
3534 TALLOC_CTX
*ret_mem_ctx
= NULL
;
3535 PyLdbMessageElementObject
*ret
;
3537 ret_mem_ctx
= talloc_new(NULL
);
3538 if (ret_mem_ctx
== NULL
) {
3539 return PyErr_NoMemory();
3542 if (talloc_reference(ret_mem_ctx
, mem_ctx
) == NULL
) {
3543 talloc_free(ret_mem_ctx
);
3548 ret
= PyObject_New(PyLdbMessageElementObject
, &PyLdbMessageElement
);
3550 talloc_free(ret_mem_ctx
);
3554 ret
->mem_ctx
= ret_mem_ctx
;
3556 return (PyObject
*)ret
;
3559 static PyObject
*py_ldb_msg_element_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
3561 PyObject
*py_elements
= NULL
;
3562 struct ldb_message_element
*el
;
3563 unsigned int flags
= 0;
3565 const char * const kwnames
[] = { "elements", "flags", "name", NULL
};
3566 PyLdbMessageElementObject
*ret
;
3567 TALLOC_CTX
*mem_ctx
;
3568 const char *msg
= NULL
;
3572 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OIs",
3573 discard_const_p(char *, kwnames
),
3574 &py_elements
, &flags
, &name
))
3577 mem_ctx
= talloc_new(NULL
);
3578 if (mem_ctx
== NULL
) {
3583 el
= talloc_zero(mem_ctx
, struct ldb_message_element
);
3586 talloc_free(mem_ctx
);
3590 if (py_elements
!= NULL
) {
3592 if (PyBytes_Check(py_elements
) || PyUnicode_Check(py_elements
)) {
3595 el
->values
= talloc_array(el
, struct ldb_val
, 1);
3596 if (el
->values
== NULL
) {
3597 talloc_free(mem_ctx
);
3601 if (PyBytes_Check(py_elements
)) {
3602 result
= PyBytes_AsStringAndSize(py_elements
, &_msg
, &size
);
3605 msg
= PyUnicode_AsUTF8AndSize(py_elements
, &size
);
3606 result
= (msg
== NULL
) ? -1 : 0;
3609 talloc_free(mem_ctx
);
3612 el
->values
[0].data
= talloc_memdup(el
->values
,
3613 (const uint8_t *)msg
, size
+ 1);
3614 el
->values
[0].length
= size
;
3615 } else if (PySequence_Check(py_elements
)) {
3616 el
->num_values
= PySequence_Size(py_elements
);
3617 el
->values
= talloc_array(el
, struct ldb_val
, el
->num_values
);
3618 if (el
->values
== NULL
) {
3619 talloc_free(mem_ctx
);
3623 for (i
= 0; i
< el
->num_values
; i
++) {
3624 PyObject
*item
= PySequence_GetItem(py_elements
, i
);
3626 talloc_free(mem_ctx
);
3629 if (PyBytes_Check(item
)) {
3631 result
= PyBytes_AsStringAndSize(item
, &_msg
, &size
);
3633 } else if (PyUnicode_Check(item
)) {
3634 msg
= PyUnicode_AsUTF8AndSize(item
, &size
);
3635 result
= (msg
== NULL
) ? -1 : 0;
3637 PyErr_Format(PyExc_TypeError
,
3638 "Expected string as element %zd in list", i
);
3642 talloc_free(mem_ctx
);
3645 el
->values
[i
].data
= talloc_memdup(el
,
3646 (const uint8_t *)msg
, size
+1);
3647 el
->values
[i
].length
= size
;
3650 PyErr_SetString(PyExc_TypeError
,
3651 "Expected string or list");
3652 talloc_free(mem_ctx
);
3659 el
->name
= talloc_strdup(el
, name
);
3660 if (el
->name
== NULL
) {
3661 talloc_free(mem_ctx
);
3662 return PyErr_NoMemory();
3666 ret
= PyObject_New(PyLdbMessageElementObject
, type
);
3668 talloc_free(mem_ctx
);
3672 ret
->mem_ctx
= mem_ctx
;
3674 return (PyObject
*)ret
;
3677 static PyObject
*py_ldb_msg_element_repr(PyLdbMessageElementObject
*self
)
3679 char *element_str
= NULL
;
3681 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3682 PyObject
*ret
, *repr
;
3684 for (i
= 0; i
< el
->num_values
; i
++) {
3685 PyObject
*o
= py_ldb_msg_element_find(self
, i
);
3686 repr
= PyObject_Repr(o
);
3687 if (element_str
== NULL
)
3688 element_str
= talloc_strdup(NULL
, PyUnicode_AsUTF8(repr
));
3690 element_str
= talloc_asprintf_append(element_str
, ",%s", PyUnicode_AsUTF8(repr
));
3693 if (element_str
== NULL
) {
3694 return PyErr_NoMemory();
3698 if (element_str
!= NULL
) {
3699 ret
= PyUnicode_FromFormat("MessageElement([%s])", element_str
);
3700 talloc_free(element_str
);
3702 ret
= PyUnicode_FromString("MessageElement([])");
3708 static PyObject
*py_ldb_msg_element_str(PyLdbMessageElementObject
*self
)
3710 struct ldb_message_element
*el
= pyldb_MessageElement_AsMessageElement(self
);
3712 if (el
->num_values
== 1)
3713 return PyUnicode_FromStringAndSize((char *)el
->values
[0].data
, el
->values
[0].length
);
3718 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject
*self
)
3720 talloc_free(self
->mem_ctx
);
3724 static PyObject
*py_ldb_msg_element_get_text(PyObject
*self
, void *closure
)
3726 return wrap_text("MessageElementTextWrapper", self
);
3729 static PyGetSetDef py_ldb_msg_element_getset
[] = {
3731 .name
= discard_const_p(char, "text"),
3732 .get
= (getter
)py_ldb_msg_element_get_text
,
3737 static PyTypeObject PyLdbMessageElement
= {
3738 .tp_name
= "ldb.MessageElement",
3739 .tp_basicsize
= sizeof(PyLdbMessageElementObject
),
3740 .tp_dealloc
= (destructor
)py_ldb_msg_element_dealloc
,
3741 .tp_repr
= (reprfunc
)py_ldb_msg_element_repr
,
3742 .tp_str
= (reprfunc
)py_ldb_msg_element_str
,
3743 .tp_methods
= py_ldb_msg_element_methods
,
3744 .tp_getset
= py_ldb_msg_element_getset
,
3745 .tp_richcompare
= (richcmpfunc
)py_ldb_msg_element_richcmp
,
3746 .tp_iter
= (getiterfunc
)py_ldb_msg_element_iter
,
3747 .tp_as_sequence
= &py_ldb_msg_element_seq
,
3748 .tp_new
= py_ldb_msg_element_new
,
3749 .tp_flags
= Py_TPFLAGS_DEFAULT
,
3750 .tp_doc
= "An element of a Message",
3754 static PyObject
*py_ldb_msg_from_dict(PyTypeObject
*type
, PyObject
*args
)
3759 struct ldb_message
*msg
;
3760 struct ldb_context
*ldb_ctx
;
3761 unsigned int mod_flags
= LDB_FLAG_MOD_REPLACE
;
3763 if (!PyArg_ParseTuple(args
, "O!O!|I",
3764 &PyLdb
, &py_ldb
, &PyDict_Type
, &py_dict
,
3769 /* mask only flags we are going to use */
3770 mod_flags
= LDB_FLAG_MOD_TYPE(mod_flags
);
3772 PyErr_SetString(PyExc_ValueError
,
3773 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3774 " expected as mod_flag value");
3778 ldb_ctx
= pyldb_Ldb_AS_LDBCONTEXT(py_ldb
);
3780 msg
= PyDict_AsMessage(ldb_ctx
, py_dict
, ldb_ctx
, mod_flags
);
3785 py_ret
= PyLdbMessage_FromMessage(msg
, (PyLdbObject
*)py_ldb
);
3787 talloc_unlink(ldb_ctx
, msg
);
3793 #define pyldb_Message_as_message(pyobj) ((PyLdbMessageObject *)pyobj)->msg
3795 #define pyldb_Message_get_pyldb(pyobj) ((PyLdbMessageObject *)pyobj)->pyldb
3798 * PyErr_LDB_MESSAGE_OR_RAISE does 3 things:
3799 * 1. checks that a PyObject is really a PyLdbMessageObject.
3800 * 2. checks that the ldb that the PyLdbMessageObject knows is the ldb that
3801 * its dn knows -- but only if the underlying message has a DN.
3802 * 3. sets message to the relevant struct ldb_message *.
3804 * We need to do all this to ensure the message belongs to the right
3805 * ldb, lest it be freed before we are ready.
3807 #define PyErr_LDB_MESSAGE_OR_RAISE(_py_obj, message) do { \
3808 PyLdbMessageObject *_py_message = NULL; \
3809 struct ldb_dn *_dn = NULL; \
3810 if (_py_obj == NULL || !pyldb_Message_Check(_py_obj)) { \
3811 PyErr_SetString(PyExc_TypeError, \
3812 "ldb Message object required"); \
3815 _py_message = (PyLdbMessageObject *)_py_obj; \
3816 message = pyldb_Message_as_message(_py_message); \
3817 _dn = message->dn; \
3818 if (_dn != NULL && \
3819 (_py_message->pyldb->ldb_ctx != ldb_dn_get_ldb_context(_dn))) { \
3820 PyErr_SetString(PyExc_RuntimeError, \
3821 "Message has a stale LDB connection"); \
3827 static PyObject
*py_ldb_msg_remove_attr(PyObject
*self
, PyObject
*args
)
3830 struct ldb_message
*msg
= NULL
;
3831 PyErr_LDB_MESSAGE_OR_RAISE(self
, msg
);
3833 if (!PyArg_ParseTuple(args
, "s", &name
)) {
3837 ldb_msg_remove_attr(msg
, name
);
3842 static PyObject
*py_ldb_msg_keys(PyObject
*self
,
3843 PyObject
*Py_UNUSED(ignored
))
3845 struct ldb_message
*msg
= NULL
;
3846 Py_ssize_t i
, j
= 0;
3847 PyObject
*obj
= NULL
;
3849 PyErr_LDB_MESSAGE_OR_RAISE(self
, msg
);
3851 obj
= PyList_New(msg
->num_elements
+(msg
->dn
!= NULL
?1:0));
3856 if (msg
->dn
!= NULL
) {
3857 PyObject
*py_dn
= NULL
;
3860 py_dn
= PyUnicode_FromString("dn");
3861 if (py_dn
== NULL
) {
3866 ret
= PyList_SetItem(obj
, j
, py_dn
);
3875 for (i
= 0; i
< msg
->num_elements
; i
++) {
3876 PyObject
*py_name
= NULL
;
3879 py_name
= PyUnicode_FromString(msg
->elements
[i
].name
);
3880 if (py_name
== NULL
) {
3885 ret
= PyList_SetItem(obj
, j
, py_name
);
3897 static int py_ldb_msg_contains(PyLdbMessageObject
*self
, PyObject
*py_name
)
3899 struct ldb_message_element
*el
= NULL
;
3900 const char *name
= NULL
;
3901 struct ldb_message
*msg
= pyldb_Message_as_message(self
);
3902 struct ldb_dn
*dn
= msg
->dn
;
3904 if (dn
!= NULL
&& (self
->pyldb
->ldb_ctx
!= ldb_dn_get_ldb_context(dn
))) {
3908 name
= PyUnicode_AsUTF8(py_name
);
3912 if (!ldb_attr_cmp(name
, "dn")) {
3915 el
= ldb_msg_find_element(msg
, name
);
3916 return el
!= NULL
? 1 : 0;
3919 static PyObject
*py_ldb_msg_getitem(PyObject
*self
, PyObject
*py_name
)
3921 struct ldb_message_element
*el
= NULL
;
3922 const char *name
= NULL
;
3923 struct ldb_message
*msg
= NULL
;
3924 PyErr_LDB_MESSAGE_OR_RAISE(self
, msg
);
3926 name
= PyUnicode_AsUTF8(py_name
);
3930 if (!ldb_attr_cmp(name
, "dn")) {
3931 return pyldb_Dn_FromDn(msg
->dn
, pyldb_Message_get_pyldb(self
));
3933 el
= ldb_msg_find_element(msg
, name
);
3935 PyErr_SetString(PyExc_KeyError
, "No such element");
3939 return PyLdbMessageElement_FromMessageElement(el
, msg
->elements
);
3942 static PyObject
*py_ldb_msg_get(PyObject
*self
, PyObject
*args
, PyObject
*kwargs
)
3944 PyObject
*def
= NULL
;
3945 const char *kwnames
[] = { "name", "default", "idx", NULL
};
3946 const char *name
= NULL
;
3948 struct ldb_message_element
*el
;
3949 struct ldb_message
*msg
= NULL
;
3950 PyErr_LDB_MESSAGE_OR_RAISE(self
, msg
);
3952 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|Oi:msg",
3953 discard_const_p(char *, kwnames
), &name
, &def
, &idx
)) {
3957 if (strcasecmp(name
, "dn") == 0) {
3958 return pyldb_Dn_FromDn(msg
->dn
, pyldb_Message_get_pyldb(self
));
3961 el
= ldb_msg_find_element(msg
, name
);
3963 if (el
== NULL
|| (idx
!= -1 && el
->num_values
<= idx
)) {
3972 return (PyObject
*)PyLdbMessageElement_FromMessageElement(el
, msg
->elements
);
3975 return PyObject_FromLdbValue(&el
->values
[idx
]);
3978 static PyObject
*py_ldb_msg_items(PyObject
*self
,
3979 PyObject
*Py_UNUSED(ignored
))
3981 struct ldb_message
*msg
= NULL
;
3982 Py_ssize_t i
, j
= 0;
3985 PyErr_LDB_MESSAGE_OR_RAISE(self
, msg
);
3987 l
= PyList_New(msg
->num_elements
+ (msg
->dn
== NULL
?0:1));
3989 return PyErr_NoMemory();
3991 if (msg
->dn
!= NULL
) {
3992 PyObject
*value
= NULL
;
3994 PyObject
*obj
= pyldb_Dn_FromDn(msg
->dn
, pyldb_Message_get_pyldb(self
));
3999 value
= Py_BuildValue("(sO)", "dn", obj
);
4001 if (value
== NULL
) {
4005 res
= PyList_SetItem(l
, 0, value
);
4012 for (i
= 0; i
< msg
->num_elements
; i
++, j
++) {
4013 PyObject
*value
= NULL
;
4015 PyObject
*py_el
= PyLdbMessageElement_FromMessageElement(&msg
->elements
[i
],
4017 if (py_el
== NULL
) {
4021 value
= Py_BuildValue("(sO)", msg
->elements
[i
].name
, py_el
);
4023 if (value
== NULL
) {
4027 res
= PyList_SetItem(l
, j
, value
);
4036 static PyObject
*py_ldb_msg_elements(PyObject
*self
,
4037 PyObject
*Py_UNUSED(ignored
))
4041 struct ldb_message
*msg
= NULL
;
4042 PyErr_LDB_MESSAGE_OR_RAISE(self
, msg
);
4044 l
= PyList_New(msg
->num_elements
);
4048 for (i
= 0; i
< msg
->num_elements
; i
++) {
4049 PyObject
*msg_el
= NULL
;
4052 msg_el
= PyLdbMessageElement_FromMessageElement(&msg
->elements
[i
], msg
->elements
);
4053 if (msg_el
== NULL
) {
4058 ret
= PyList_SetItem(l
, i
, msg_el
);
4068 static PyObject
*py_ldb_msg_add(PyObject
*self
, PyObject
*args
)
4070 PyLdbMessageElementObject
*py_element
;
4072 struct ldb_message_element
*el
;
4073 struct ldb_message_element
*el_new
;
4074 struct ldb_message
*msg
= NULL
;
4075 PyErr_LDB_MESSAGE_OR_RAISE(self
, msg
);
4077 if (!PyArg_ParseTuple(args
, "O!", &PyLdbMessageElement
, &py_element
)) {
4081 el
= py_element
->el
;
4083 PyErr_SetString(PyExc_ValueError
, "Invalid MessageElement object");
4086 if (el
->name
== NULL
) {
4087 PyErr_SetString(PyExc_ValueError
,
4088 "The element has no name");
4091 ret
= ldb_msg_add_empty(msg
, el
->name
, el
->flags
, &el_new
);
4092 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError
, ret
, NULL
);
4094 /* now deep copy all attribute values */
4095 el_new
->values
= talloc_array(msg
->elements
, struct ldb_val
, el
->num_values
);
4096 if (el_new
->values
== NULL
) {
4100 el_new
->num_values
= el
->num_values
;
4102 for (i
= 0; i
< el
->num_values
; i
++) {
4103 el_new
->values
[i
] = ldb_val_dup(el_new
->values
, &el
->values
[i
]);
4104 if (el_new
->values
[i
].data
== NULL
4105 && el
->values
[i
].length
!= 0) {
4114 static PyMethodDef py_ldb_msg_methods
[] = {
4115 { "from_dict", (PyCFunction
)py_ldb_msg_from_dict
, METH_CLASS
| METH_VARARGS
,
4116 "Message.from_dict(ldb, dict, mod_flag) -> ldb.Message\n"
4117 "Class method to create ldb.Message object from Dictionary.\n"
4118 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
4119 { "keys", (PyCFunction
)py_ldb_msg_keys
, METH_NOARGS
,
4120 "S.keys() -> list\n\n"
4121 "Return sequence of all attribute names." },
4122 { "remove", (PyCFunction
)py_ldb_msg_remove_attr
, METH_VARARGS
,
4123 "S.remove(name)\n\n"
4124 "Remove all entries for attributes with the specified name."},
4125 { "get", PY_DISCARD_FUNC_SIG(PyCFunction
, py_ldb_msg_get
),
4126 METH_VARARGS
| METH_KEYWORDS
,
4127 "msg.get(name,default=None,idx=None) -> string\n"
4128 "idx is the index into the values array\n"
4129 "if idx is None, then a list is returned\n"
4130 "if idx is not None, then the element with that index is returned\n"
4131 "if you pass the special name 'dn' then the DN object is returned\n"},
4132 { "items", (PyCFunction
)py_ldb_msg_items
, METH_NOARGS
, NULL
},
4133 { "elements", (PyCFunction
)py_ldb_msg_elements
, METH_NOARGS
, NULL
},
4134 { "add", (PyCFunction
)py_ldb_msg_add
, METH_VARARGS
,
4135 "S.add(element)\n\n"
4136 "Add an element to this message." },
4140 static PyObject
*py_ldb_msg_iter(PyObject
*self
)
4142 PyObject
*list
, *iter
;
4144 list
= py_ldb_msg_keys(self
, NULL
);
4148 iter
= PyObject_GetIter(list
);
4153 static int py_ldb_msg_setitem(PyLdbMessageObject
*self
, PyObject
*name
, PyObject
*value
)
4155 const char *attr_name
;
4157 attr_name
= PyUnicode_AsUTF8(name
);
4158 if (attr_name
== NULL
) {
4159 PyErr_SetNone(PyExc_TypeError
);
4163 if (value
== NULL
) {
4165 ldb_msg_remove_attr(self
->msg
, attr_name
);
4168 struct ldb_message_element
*el
= PyObject_AsMessageElement(self
->msg
,
4169 value
, 0, attr_name
);
4173 if (el
->name
== NULL
) {
4175 * If ‘value’ is a MessageElement,
4176 * PyObject_AsMessageElement() will have returned a
4177 * reference to it without setting the name. We don’t
4178 * want to modify the original object to set the name
4179 * ourselves, but making a copy would result in
4180 * different behaviour for a caller relying on a
4181 * reference being kept. Rather than continue with a
4182 * NULL name (and probably fail later on), let’s catch
4183 * this potential mistake early.
4185 PyErr_SetString(PyExc_ValueError
, "MessageElement has no name set");
4186 talloc_unlink(self
->msg
, el
);
4189 ldb_msg_remove_attr(pyldb_Message_AsMessage(self
), attr_name
);
4190 ret
= ldb_msg_add(pyldb_Message_AsMessage(self
), el
, el
->flags
);
4191 if (ret
!= LDB_SUCCESS
) {
4192 PyErr_SetLdbError(PyExc_LdbError
, ret
, NULL
);
4193 talloc_unlink(self
->msg
, el
);
4200 static Py_ssize_t
py_ldb_msg_length(PyLdbMessageObject
*self
)
4202 return pyldb_Message_AsMessage(self
)->num_elements
;
4205 static PySequenceMethods py_ldb_msg_sequence
= {
4206 .sq_contains
= (objobjproc
)py_ldb_msg_contains
,
4209 static PyMappingMethods py_ldb_msg_mapping
= {
4210 .mp_length
= (lenfunc
)py_ldb_msg_length
,
4211 .mp_subscript
= (binaryfunc
)py_ldb_msg_getitem
,
4212 .mp_ass_subscript
= (objobjargproc
)py_ldb_msg_setitem
,
4215 static PyObject
*py_ldb_msg_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
4217 const char * const kwnames
[] = { "dn", NULL
};
4218 struct ldb_message
*ret
;
4219 TALLOC_CTX
*mem_ctx
;
4220 PyObject
*pydn
= NULL
;
4221 PyLdbMessageObject
*py_ret
;
4223 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|O",
4224 discard_const_p(char *, kwnames
),
4228 mem_ctx
= talloc_new(NULL
);
4229 if (mem_ctx
== NULL
) {
4234 ret
= ldb_msg_new(mem_ctx
);
4236 talloc_free(mem_ctx
);
4243 if (!pyldb_Object_AsDn(NULL
, pydn
, NULL
, &dn
)) {
4244 talloc_free(mem_ctx
);
4247 ret
->dn
= talloc_reference(ret
, dn
);
4248 if (ret
->dn
== NULL
) {
4249 talloc_free(mem_ctx
);
4250 return PyErr_NoMemory();
4254 py_ret
= (PyLdbMessageObject
*)type
->tp_alloc(type
, 0);
4255 if (py_ret
== NULL
) {
4257 talloc_free(mem_ctx
);
4261 py_ret
->mem_ctx
= mem_ctx
;
4264 py_ret
->pyldb
= ((PyLdbDnObject
*)pydn
)->pyldb
;
4265 Py_INCREF(py_ret
->pyldb
);
4267 return (PyObject
*)py_ret
;
4270 static PyObject
*PyLdbMessage_FromMessage(struct ldb_message
*msg
, PyLdbObject
*pyldb
)
4272 TALLOC_CTX
*mem_ctx
= NULL
;
4273 struct ldb_message
*msg_ref
= NULL
;
4274 PyLdbMessageObject
*ret
;
4276 mem_ctx
= talloc_new(NULL
);
4277 if (mem_ctx
== NULL
) {
4278 return PyErr_NoMemory();
4281 msg_ref
= talloc_reference(mem_ctx
, msg
);
4282 if (msg_ref
== NULL
) {
4283 talloc_free(mem_ctx
);
4284 return PyErr_NoMemory();
4287 ret
= (PyLdbMessageObject
*)PyLdbMessage
.tp_alloc(&PyLdbMessage
, 0);
4289 talloc_free(mem_ctx
);
4293 ret
->mem_ctx
= mem_ctx
;
4297 Py_INCREF(ret
->pyldb
);
4299 return (PyObject
*)ret
;
4302 static PyObject
*py_ldb_msg_get_dn(PyObject
*self
, void *closure
)
4304 struct ldb_message
*msg
= NULL
;
4305 PyErr_LDB_MESSAGE_OR_RAISE(self
, msg
);
4306 return pyldb_Dn_FromDn(msg
->dn
, pyldb_Message_get_pyldb(self
));
4309 static int py_ldb_msg_set_dn(PyObject
*self
, PyObject
*value
, void *closure
)
4312 * no PyErr_LDB_MESSAGE_OR_RAISE here, because this returns int.
4314 * Also, since this is trying to replace the dn, we don't need to
4315 * check the old one.
4317 struct ldb_message
*msg
= pyldb_Message_as_message(self
);
4318 struct ldb_dn
*dn
= NULL
;
4319 PyLdbObject
*pyldb
= pyldb_Message_get_pyldb(self
);
4320 PyLdbMessageObject
*self_as_msg
= (PyLdbMessageObject
*)self
;
4322 if (value
== NULL
) {
4323 PyErr_SetString(PyExc_AttributeError
, "cannot delete dn");
4326 if (!pyldb_Dn_Check(value
)) {
4327 PyErr_SetString(PyExc_TypeError
, "expected dn");
4331 dn
= talloc_reference(msg
, pyldb_Dn_AS_DN(value
));
4337 if (pyldb
!= NULL
) {
4338 if (pyldb
->ldb_ctx
!= ldb_dn_get_ldb_context(dn
)) {
4339 PyErr_SetString(PyExc_RuntimeError
,
4340 "DN is from the wrong LDB");
4348 self_as_msg
->pyldb
= ((PyLdbDnObject
*)value
)->pyldb
;
4349 Py_INCREF(self_as_msg
->pyldb
);
4354 static PyObject
*py_ldb_msg_get_text(PyObject
*self
, void *closure
)
4356 return wrap_text("MessageTextWrapper", self
);
4361 static PyObject
*py_ldb_msg_get_ldb(PyLdbMessageObject
*self
, void *closure
)
4363 if (self
->pyldb
== NULL
) {
4366 Py_INCREF(self
->pyldb
);
4367 return (PyObject
*)self
->pyldb
;
4371 static PyGetSetDef py_ldb_msg_getset
[] = {
4373 .name
= discard_const_p(char, "dn"),
4374 .get
= (getter
)py_ldb_msg_get_dn
,
4375 .set
= (setter
)py_ldb_msg_set_dn
,
4378 .name
= discard_const_p(char, "text"),
4379 .get
= (getter
)py_ldb_msg_get_text
,
4382 .name
= discard_const_p(char, "ldb"),
4383 .get
= (getter
)py_ldb_msg_get_ldb
,
4384 .doc
= discard_const_p(
4385 char, "returns the associated ldb object (or None)")
4390 static PyObject
*py_ldb_msg_repr(PyLdbMessageObject
*self
)
4392 PyObject
*dict
= PyDict_New(), *ret
, *repr
;
4393 const char *repr_str
= NULL
;
4397 if (PyDict_Update(dict
, (PyObject
*)self
) != 0) {
4401 repr
= PyObject_Repr(dict
);
4406 repr_str
= PyUnicode_AsUTF8(repr
);
4407 if (repr_str
== NULL
) {
4412 ret
= PyUnicode_FromFormat("Message(%s)", repr_str
);
4418 static void py_ldb_msg_dealloc(PyLdbMessageObject
*self
)
4420 talloc_free(self
->mem_ctx
);
4421 /* The pyldb element will only be present if a DN is assigned */
4423 Py_DECREF(self
->pyldb
);
4428 static PyObject
*py_ldb_msg_richcmp(PyLdbMessageObject
*py_msg1
,
4429 PyLdbMessageObject
*py_msg2
, int op
)
4431 struct ldb_message
*msg1
, *msg2
;
4435 if (!pyldb_Message_Check(py_msg2
)) {
4436 Py_INCREF(Py_NotImplemented
);
4437 return Py_NotImplemented
;
4440 PyErr_LDB_MESSAGE_OR_RAISE(py_msg1
, msg1
);
4441 PyErr_LDB_MESSAGE_OR_RAISE(py_msg2
, msg2
);
4443 * FIXME: this can be a non-transitive compare, unsuitable for
4446 * supposing msg1, msg2, and msg3 have 1, 2, and 3 elements
4447 * each. msg2 has a NULL DN, while msg1 has a DN that compares
4448 * higher than msg3. Then:
4450 * msg1 < msg2, due to num_elements.
4451 * msg2 < msg3, due to num_elements.
4452 * msg1 > msg3, due to DNs.
4454 if ((msg1
->dn
!= NULL
) || (msg2
->dn
!= NULL
)) {
4455 ret
= ldb_dn_compare(msg1
->dn
, msg2
->dn
);
4457 return richcmp(ret
, op
);
4461 if (msg1
->num_elements
> msg2
->num_elements
) {
4462 return richcmp(1, op
);
4464 if (msg1
->num_elements
< msg2
->num_elements
) {
4465 return richcmp(-1, op
);
4468 for (i
= 0; i
< msg1
->num_elements
; i
++) {
4469 ret
= ldb_msg_element_compare_name(&msg1
->elements
[i
],
4470 &msg2
->elements
[i
]);
4472 return richcmp(ret
, op
);
4475 ret
= ldb_msg_element_compare(&msg1
->elements
[i
],
4476 &msg2
->elements
[i
]);
4478 return richcmp(ret
, op
);
4482 return richcmp(0, op
);
4485 static PyTypeObject PyLdbMessage
= {
4486 .tp_name
= "ldb.Message",
4487 .tp_methods
= py_ldb_msg_methods
,
4488 .tp_getset
= py_ldb_msg_getset
,
4489 .tp_as_sequence
= &py_ldb_msg_sequence
,
4490 .tp_as_mapping
= &py_ldb_msg_mapping
,
4491 .tp_basicsize
= sizeof(PyLdbMessageObject
),
4492 .tp_dealloc
= (destructor
)py_ldb_msg_dealloc
,
4493 .tp_new
= py_ldb_msg_new
,
4494 .tp_repr
= (reprfunc
)py_ldb_msg_repr
,
4495 .tp_flags
= Py_TPFLAGS_DEFAULT
,
4496 .tp_iter
= (getiterfunc
)py_ldb_msg_iter
,
4497 .tp_richcompare
= (richcmpfunc
)py_ldb_msg_richcmp
,
4498 .tp_doc
= "A LDB Message",
4501 static void py_ldb_tree_dealloc(PyLdbTreeObject
*self
)
4503 talloc_free(self
->mem_ctx
);
4507 static PyTypeObject PyLdbTree
= {
4508 .tp_name
= "ldb.Tree",
4509 .tp_basicsize
= sizeof(PyLdbTreeObject
),
4510 .tp_dealloc
= (destructor
)py_ldb_tree_dealloc
,
4511 .tp_flags
= Py_TPFLAGS_DEFAULT
,
4512 .tp_doc
= "A search tree",
4515 static PyObject
*py_timestring(PyObject
*module
, PyObject
*args
)
4517 /* most times "time_t" is a signed integer type with 32 or 64 bit:
4518 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4522 if (!PyArg_ParseTuple(args
, "l", &t_val
))
4524 tresult
= ldb_timestring(NULL
, (time_t) t_val
);
4525 if (tresult
== NULL
) {
4527 * Most likely EOVERFLOW from gmtime()
4529 PyErr_SetFromErrno(PyExc_OSError
);
4532 ret
= PyUnicode_FromString(tresult
);
4533 talloc_free(tresult
);
4537 static PyObject
*py_string_to_time(PyObject
*module
, PyObject
*args
)
4541 if (!PyArg_ParseTuple(args
, "s", &str
)) {
4544 t
= ldb_string_to_time(str
);
4546 if (t
== 0 && errno
!= 0) {
4547 PyErr_SetFromErrno(PyExc_ValueError
);
4550 return PyLong_FromLong(t
);
4553 static PyObject
*py_valid_attr_name(PyObject
*self
, PyObject
*args
)
4556 if (!PyArg_ParseTuple(args
, "s", &name
))
4558 return PyBool_FromLong(ldb_valid_attr_name(name
));
4562 encode a string using RFC2254 rules
4564 static PyObject
*py_binary_encode(PyObject
*self
, PyObject
*args
)
4566 char *str
, *encoded
;
4567 Py_ssize_t size
= 0;
4571 if (!PyArg_ParseTuple(args
, "s#", &str
, &size
))
4573 val
.data
= (uint8_t *)str
;
4576 encoded
= ldb_binary_encode(NULL
, val
);
4577 if (encoded
== NULL
) {
4578 PyErr_SetString(PyExc_TypeError
, "unable to encode binary string");
4581 ret
= PyUnicode_FromString(encoded
);
4582 talloc_free(encoded
);
4587 decode a string using RFC2254 rules
4589 static PyObject
*py_binary_decode(PyObject
*self
, PyObject
*args
)
4595 if (!PyArg_ParseTuple(args
, "s", &str
))
4598 val
= ldb_binary_decode(NULL
, str
);
4599 if (val
.data
== NULL
) {
4600 PyErr_SetString(PyExc_TypeError
, "unable to decode binary string");
4603 ret
= PyBytes_FromStringAndSize((const char*)val
.data
, val
.length
);
4604 talloc_free(val
.data
);
4608 static PyMethodDef py_ldb_global_methods
[] = {
4609 { "timestring", py_timestring
, METH_VARARGS
,
4610 "S.timestring(int) -> string\n\n"
4611 "Generate a LDAP time string from a UNIX timestamp" },
4612 { "string_to_time", py_string_to_time
, METH_VARARGS
,
4613 "S.string_to_time(string) -> int\n\n"
4614 "Parse a LDAP time string into a UNIX timestamp." },
4615 { "valid_attr_name", py_valid_attr_name
, METH_VARARGS
,
4616 "S.valid_attr_name(name) -> bool\n\n"
4617 "Check whether the supplied name is a valid attribute name." },
4618 { "binary_encode", py_binary_encode
, METH_VARARGS
,
4619 "S.binary_encode(string) -> string\n\n"
4620 "Perform a RFC2254 binary encoding on a string" },
4621 { "binary_decode", py_binary_decode
, METH_VARARGS
,
4622 "S.binary_decode(string) -> string\n\n"
4623 "Perform a RFC2254 binary decode on a string" },
4627 #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."
4629 static struct PyModuleDef moduledef
= {
4630 PyModuleDef_HEAD_INIT
,
4632 .m_doc
= MODULE_DOC
,
4634 .m_methods
= py_ldb_global_methods
,
4637 static PyObject
* module_init(void)
4641 PyLdbBytesType
.tp_base
= &PyBytes_Type
;
4642 if (PyType_Ready(&PyLdbBytesType
) < 0) {
4646 if (PyType_Ready(&PyLdbDn
) < 0)
4649 if (PyType_Ready(&PyLdbMessage
) < 0)
4652 if (PyType_Ready(&PyLdbMessageElement
) < 0)
4655 if (PyType_Ready(&PyLdb
) < 0)
4658 if (PyType_Ready(&PyLdbTree
) < 0)
4661 if (PyType_Ready(&PyLdbResult
) < 0)
4664 if (PyType_Ready(&PyLdbSearchIterator
) < 0)
4667 if (PyType_Ready(&PyLdbControl
) < 0)
4670 m
= PyModule_Create(&moduledef
);
4674 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4676 ADD_LDB_INT(SEQ_HIGHEST_SEQ
);
4677 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP
);
4678 ADD_LDB_INT(SEQ_NEXT
);
4679 ADD_LDB_INT(SCOPE_DEFAULT
);
4680 ADD_LDB_INT(SCOPE_BASE
);
4681 ADD_LDB_INT(SCOPE_ONELEVEL
);
4682 ADD_LDB_INT(SCOPE_SUBTREE
);
4684 ADD_LDB_INT(CHANGETYPE_NONE
);
4685 ADD_LDB_INT(CHANGETYPE_ADD
);
4686 ADD_LDB_INT(CHANGETYPE_DELETE
);
4687 ADD_LDB_INT(CHANGETYPE_MODIFY
);
4688 ADD_LDB_INT(CHANGETYPE_MODRDN
);
4690 ADD_LDB_INT(FLAG_MOD_ADD
);
4691 ADD_LDB_INT(FLAG_MOD_REPLACE
);
4692 ADD_LDB_INT(FLAG_MOD_DELETE
);
4693 ADD_LDB_INT(FLAG_FORCE_NO_BASE64_LDIF
);
4695 ADD_LDB_INT(ATTR_FLAG_HIDDEN
);
4696 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX
);
4697 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE
);
4698 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF
);
4700 ADD_LDB_INT(SUCCESS
);
4701 ADD_LDB_INT(ERR_OPERATIONS_ERROR
);
4702 ADD_LDB_INT(ERR_PROTOCOL_ERROR
);
4703 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED
);
4704 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED
);
4705 ADD_LDB_INT(ERR_COMPARE_FALSE
);
4706 ADD_LDB_INT(ERR_COMPARE_TRUE
);
4707 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED
);
4708 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED
);
4709 ADD_LDB_INT(ERR_REFERRAL
);
4710 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED
);
4711 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION
);
4712 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED
);
4713 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS
);
4714 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE
);
4715 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE
);
4716 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING
);
4717 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION
);
4718 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS
);
4719 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX
);
4720 ADD_LDB_INT(ERR_NO_SUCH_OBJECT
);
4721 ADD_LDB_INT(ERR_ALIAS_PROBLEM
);
4722 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX
);
4723 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM
);
4724 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION
);
4725 ADD_LDB_INT(ERR_INVALID_CREDENTIALS
);
4726 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS
);
4727 ADD_LDB_INT(ERR_BUSY
);
4728 ADD_LDB_INT(ERR_UNAVAILABLE
);
4729 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM
);
4730 ADD_LDB_INT(ERR_LOOP_DETECT
);
4731 ADD_LDB_INT(ERR_NAMING_VIOLATION
);
4732 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION
);
4733 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF
);
4734 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN
);
4735 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS
);
4736 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED
);
4737 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS
);
4738 ADD_LDB_INT(ERR_OTHER
);
4740 ADD_LDB_INT(FLG_RDONLY
);
4741 ADD_LDB_INT(FLG_NOSYNC
);
4742 ADD_LDB_INT(FLG_RECONNECT
);
4743 ADD_LDB_INT(FLG_NOMMAP
);
4744 ADD_LDB_INT(FLG_SHOW_BINARY
);
4745 ADD_LDB_INT(FLG_ENABLE_TRACING
);
4746 ADD_LDB_INT(FLG_DONT_CREATE_DB
);
4748 ADD_LDB_INT(PACKING_FORMAT
);
4749 ADD_LDB_INT(PACKING_FORMAT_V2
);
4751 /* Historical misspelling */
4752 PyModule_AddIntConstant(m
, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM
);
4754 PyModule_AddStringConstant(m
, "__docformat__", "restructuredText");
4756 PyExc_LdbError
= PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL
, NULL
);
4757 PyModule_AddObject(m
, "LdbError", PyExc_LdbError
);
4760 Py_INCREF(&PyLdbDn
);
4761 Py_INCREF(&PyLdbMessage
);
4762 Py_INCREF(&PyLdbMessageElement
);
4763 Py_INCREF(&PyLdbTree
);
4764 Py_INCREF(&PyLdbResult
);
4765 Py_INCREF(&PyLdbControl
);
4767 PyModule_AddObject(m
, "Ldb", (PyObject
*)&PyLdb
);
4768 PyModule_AddObject(m
, "Dn", (PyObject
*)&PyLdbDn
);
4769 PyModule_AddObject(m
, "Message", (PyObject
*)&PyLdbMessage
);
4770 PyModule_AddObject(m
, "MessageElement", (PyObject
*)&PyLdbMessageElement
);
4771 PyModule_AddObject(m
, "Tree", (PyObject
*)&PyLdbTree
);
4772 PyModule_AddObject(m
, "Result", (PyObject
*)&PyLdbResult
);
4773 PyModule_AddObject(m
, "Control", (PyObject
*)&PyLdbControl
);
4775 PyModule_AddStringConstant(m
, "__version__", PACKAGE_VERSION
);
4777 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4779 ADD_LDB_STRING(SYNTAX_DN
);
4780 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING
);
4781 ADD_LDB_STRING(SYNTAX_INTEGER
);
4782 ADD_LDB_STRING(SYNTAX_ORDERED_INTEGER
);
4783 ADD_LDB_STRING(SYNTAX_BOOLEAN
);
4784 ADD_LDB_STRING(SYNTAX_OCTET_STRING
);
4785 ADD_LDB_STRING(SYNTAX_UTC_TIME
);
4786 ADD_LDB_STRING(OID_COMPARATOR_AND
);
4787 ADD_LDB_STRING(OID_COMPARATOR_OR
);
4792 PyMODINIT_FUNC
PyInit_ldb(void);
4793 PyMODINIT_FUNC
PyInit_ldb(void)
4795 return module_init();