2 Unix SMB/CIFS implementation.
6 Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7 Copyright (C) 2006 Simo Sorce <idra@samba.org>
8 Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
10 ** NOTE! The following LGPL license applies to the ldb
11 ** library. This does NOT imply that all of Samba is released
14 This library is free software; you can redistribute it and/or
15 modify it under the terms of the GNU Lesser General Public
16 License as published by the Free Software Foundation; either
17 version 3 of the License, or (at your option) any later version.
19 This library is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 Lesser General Public License for more details.
24 You should have received a copy of the GNU Lesser General Public
25 License along with this library; if not, see <http://www.gnu.org/licenses/>.
36 #include "ldb_errors.h"
38 typedef struct ldb_message ldb_msg;
39 typedef struct ldb_context ldb;
40 typedef struct ldb_dn ldb_dn;
41 typedef struct ldb_ldif ldb_ldif;
42 typedef struct ldb_message_element ldb_msg_element;
43 typedef int ldb_error;
49 %include "exception.i"
52 %constant int SCOPE_DEFAULT = LDB_SCOPE_DEFAULT;
53 %constant int SCOPE_BASE = LDB_SCOPE_BASE;
54 %constant int SCOPE_ONELEVEL = LDB_SCOPE_ONELEVEL;
55 %constant int SCOPE_SUBTREE = LDB_SCOPE_SUBTREE;
57 %constant int CHANGETYPE_NONE = LDB_CHANGETYPE_NONE;
58 %constant int CHANGETYPE_ADD = LDB_CHANGETYPE_ADD;
59 %constant int CHANGETYPE_DELETE = LDB_CHANGETYPE_DELETE;
60 %constant int CHANGETYPE_MODIFY = LDB_CHANGETYPE_MODIFY;
63 * Wrap struct ldb_context
66 /* The ldb functions will crash if a NULL ldb context is passed so
67 catch this before it happens. */
69 %typemap(check) struct ldb_context* {
71 SWIG_exception(SWIG_ValueError,
72 "ldb context must be non-NULL");
75 %typemap(check) ldb_msg * {
77 SWIG_exception(SWIG_ValueError,
78 "Message can not be None");
85 %typemap(in) struct ldb_val *INPUT (struct ldb_val temp) {
87 if (!PyString_Check($input)) {
88 PyErr_SetString(PyExc_TypeError, "string arg expected");
91 $1->length = PyString_Size($input);
92 $1->data = PyString_AsString($input);
95 %typemap(out) struct ldb_val {
96 $result = PyString_FromStringAndSize((const char *)$1.data, $1.length);
100 * Wrap struct ldb_result
103 %typemap(in, numinputs=0) struct ldb_result **OUT (struct ldb_result *temp_ldb_result) {
104 $1 = &temp_ldb_result;
108 %typemap(argout) struct ldb_result ** (int i) {
109 $result = PyList_New((*$1)->count);
110 for (i = 0; i < (*$1)->count; i++) {
111 PyList_SetItem($result, i,
112 SWIG_NewPointerObj((*$1)->msgs[i], SWIGTYPE_p_ldb_message, 0)
117 %typemap(in, numinputs=1) const char * const *attrs {
118 if ($input == Py_None) {
120 } else if (PySequence_Check($input)) {
122 $1 = talloc_array(NULL, char *, PySequence_Size($input)+1);
123 for(i = 0; i < PySequence_Size($input); i++)
124 $1[i] = PyString_AsString(PySequence_GetItem($input, i));
127 SWIG_exception(SWIG_TypeError, "expected sequence");
131 %typemap(freearg) const char * const *attrs {
136 %types(struct ldb_result *);
142 %rename(__str__) ldb_dn::get_linearized;
143 %rename(__cmp__) ldb_dn::compare;
144 %rename(__len__) ldb_dn::get_comp_num;
146 typedef struct ldb_dn {
148 ldb_dn(ldb *ldb, const char *str)
150 ldb_dn *ret = ldb_dn_new(ldb, ldb, str);
151 /* ldb_dn_new() doesn't accept NULL as memory context, so
152 we do it this way... */
153 talloc_steal(NULL, ret);
156 SWIG_exception(SWIG_ValueError,
157 "unable to parse dn string");
161 ~ldb_dn() { talloc_free($self); }
163 const char *get_casefold();
164 const char *get_linearized();
165 ldb_dn *parent() { return ldb_dn_get_parent(NULL, $self); }
166 int compare(ldb_dn *other);
170 bool check_special(const char *name);
172 bool add_child(ldb_dn *child);
173 bool add_base(ldb_dn *base);
174 const char *canonical_str() {
175 return ldb_dn_canonical_string($self, $self);
177 const char *canonical_ex_str() {
178 return ldb_dn_canonical_ex_string($self, $self);
181 ldb_dn *__add__(ldb_dn *other)
183 ldb_dn *ret = ldb_dn_copy(NULL, $self);
184 ldb_dn_add_child(ret, other);
188 /* FIXME: implement __getslice__ */
195 int ldb_dn_from_pyobject(TALLOC_CTX *mem_ctx, PyObject *object,
196 struct ldb_context *ldb, ldb_dn **dn)
198 if (ldb != NULL && PyString_Check(object)) {
199 *dn = ldb_dn_new(mem_ctx, ldb, PyString_AsString(object));
202 return SWIG_ConvertPtr(object, (void **)dn, SWIGTYPE_p_ldb_dn,
203 SWIG_POINTER_EXCEPTION);
206 ldb_msg_element *ldb_msg_element_from_pyobject(PyObject *set_obj, int flags,
207 const char *attr_name)
209 struct ldb_message_element *me = talloc(NULL, struct ldb_message_element);
210 me->name = attr_name;
212 if (PyString_Check(set_obj)) {
214 me->values = talloc_array(me, struct ldb_val, me->num_values);
215 me->values[0].length = PyString_Size(set_obj);
216 me->values[0].data = (uint8_t *)talloc_strdup(me->values,
217 PyString_AsString(set_obj));
218 } else if (PySequence_Check(set_obj)) {
220 me->num_values = PySequence_Size(set_obj);
221 me->values = talloc_array(me, struct ldb_val, me->num_values);
222 for (i = 0; i < me->num_values; i++) {
223 PyObject *obj = PySequence_GetItem(set_obj, i);
224 me->values[i].length = PyString_Size(obj);
225 me->values[i].data = (uint8_t *)PyString_AsString(obj);
235 PyObject *ldb_msg_element_to_set(ldb_msg_element *me)
240 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
241 result = PyList_New(me->num_values);
243 for (i = 0; i < me->num_values; i++) {
244 PyList_SetItem(result, i,
245 PyString_FromStringAndSize((const char *)me->values[i].data,
246 me->values[i].length));
255 /* ldb_message_element */
256 %rename(__cmp__) ldb_message_element::compare;
257 %rename(MessageElement) ldb_msg_element;
258 typedef struct ldb_message_element {
261 PyObject *__iter__(void)
263 return PyObject_GetIter(ldb_msg_element_to_set($self));
266 PyObject *__set__(void)
268 return ldb_msg_element_to_set($self);
271 ldb_msg_element(PyObject *set_obj, int flags=0, const char *name = NULL)
273 return ldb_msg_element_from_pyobject(set_obj, flags, name);
276 ~ldb_msg_element() { talloc_free($self); }
277 int compare(ldb_msg_element *);
283 %rename(Message) ldb_message;
285 %rename(__delitem__) ldb_message::remove_attr;
286 %typemap(out) ldb_msg_element * {
288 PyErr_SetString(PyExc_KeyError, "no such element");
290 $result = SWIG_NewPointerObj($1, SWIGTYPE_p_ldb_message_element, 0);
292 %rename(__getitem__) ldb_message::find_element;
293 //%typemap(out) ldb_msg_element *;
297 PyObject *ldb_msg_list_elements(ldb_msg *msg)
300 PyObject *obj = PyList_New(msg->num_elements);
301 for (i = 0; i < msg->num_elements; i++)
302 PyList_SetItem(obj, i, PyString_FromString(msg->elements[i].name));
309 typedef struct ldb_message {
313 ldb_msg(ldb_dn *dn = NULL) {
314 ldb_msg *ret = ldb_msg_new(NULL);
315 ret->dn = talloc_reference(ret, dn);
318 ~ldb_msg() { talloc_free($self); }
320 ldb_msg_element *find_element(const char *name);
323 void __setitem__(const char *attr_name, ldb_msg_element *val)
325 struct ldb_message_element *el;
327 ldb_msg_remove_attr($self, attr_name);
329 el = talloc($self, struct ldb_message_element);
330 el->name = talloc_strdup(el, attr_name);
331 el->num_values = val->num_values;
332 el->values = talloc_reference(el, val->values);
334 ldb_msg_add($self, el, val->flags);
337 void __setitem__(const char *attr_name, PyObject *val)
339 struct ldb_message_element *el = ldb_msg_element_from_pyobject(
341 talloc_steal($self, el);
342 ldb_msg_remove_attr($self, attr_name);
343 ldb_msg_add($self, el, el->flags);
346 unsigned int __len__() { return $self->num_elements; }
350 return ldb_msg_list_elements($self);
353 PyObject *__iter__(void)
355 return PyObject_GetIter(ldb_msg_list_elements($self));
358 void remove_attr(const char *name);
362 /* FIXME: Convert ldb_result to 3-tuple:
363 (msgs, refs, controls)
366 typedef struct ldb_ldif ldb_ldif;
370 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
373 PyObject *fn = context;
375 vasprintf(&text, fmt, ap);
376 PyObject_CallFunction(fn, "(i,s)", level, text);
381 %typemap(in,numinputs=1) (void (*debug)(void *context, enum ldb_debug_level level, const char *fmt, va_list ap),
384 /* FIXME: Should be decreased somewhere as well. Perhaps register a
385 destructor and tie it to the ldb context ? */
392 static PyObject *ldb_ldif_to_pyobject(ldb_ldif *ldif)
397 return Py_BuildValue("(iO)", ldif->changetype,
398 SWIG_NewPointerObj(ldif->msg, SWIGTYPE_p_ldb_message, 0));
408 PyObject *PyExc_LdbError;
412 LdbError = _ldb.LdbError
416 PyExc_LdbError = PyErr_NewException("_ldb.LdbError", NULL, NULL);
417 PyDict_SetItemString(d, "LdbError", PyExc_LdbError);
420 %ignore _LDB_ERRORS_H_;
422 %include "include/ldb_errors.h"
428 %rename(Ldb) ldb_context;
429 /* Top-level ldb operations */
430 typedef struct ldb_context {
431 %typemap(out) ldb_error {
432 if ($1 != LDB_SUCCESS) {
433 PyErr_SetObject(PyExc_LdbError, Py_BuildValue("(i,s)", $1, ldb_strerror($1)));
439 ldb(const char *url=NULL, unsigned int flags = 0,
440 const char *options[] = NULL)
442 ldb *ldb = ldb_init(NULL);
447 ret = ldb_connect(ldb, url, flags, options);
448 if (ret != LDB_SUCCESS)
449 SWIG_exception(SWIG_ValueError, ldb_errstring(ldb));
459 ldb_error connect(const char *url, unsigned int flags = 0,
460 const char *options[] = NULL);
462 ~ldb() { talloc_free($self); }
463 ldb_error search(ldb_dn *base = NULL,
464 enum ldb_scope scope = LDB_SCOPE_DEFAULT,
465 const char *expression = NULL,
466 const char * const *attrs = NULL,
467 struct ldb_result **OUT);
468 ldb_error delete(ldb_dn *dn);
469 ldb_error rename(ldb_dn *olddn, ldb_dn *newdn);
470 ldb_error add(ldb_msg *add_msg);
471 ldb_error add(PyObject *py_msg)
474 int dict_pos, msg_pos;
475 PyObject *key, *value;
476 ldb_msg_element *msgel;
478 if (PyDict_Check(py_msg)) {
479 msg = ldb_msg_new(NULL);
480 msg->num_elements = PyDict_Size(py_msg) - 1; /* dn isn't in there */
481 msg->elements = talloc_zero_array(msg, struct ldb_message_element, msg->num_elements+1);
482 msg_pos = dict_pos = 0;
483 while (PyDict_Next(py_msg, &dict_pos, &key, &value)) {
484 if (!strcmp(PyString_AsString(key), "dn")) {
485 if (ldb_dn_from_pyobject(msg, value, $self, &msg->dn) != 0) {
486 return LDB_ERR_OTHER;
489 msgel = ldb_msg_element_from_pyobject(value, 0, PyString_AsString(key));
490 memcpy(&msg->elements[msg_pos], msgel, sizeof(*msgel));
496 if (msg->dn == NULL) {
497 SWIG_exception(SWIG_TypeError, "no dn set");
498 return LDB_ERR_OTHER;
501 if (SWIG_ConvertPtr(py_msg, (void **)&msg, SWIGTYPE_p_ldb_message, 0) != 0)
502 return LDB_ERR_OTHER;
505 ret = ldb_add($self,msg);
511 return LDB_ERR_OTHER;
513 ldb_error modify(ldb_msg *message);
514 ldb_dn *get_config_basedn();
515 ldb_dn *get_root_basedn();
516 ldb_dn *get_schema_basedn();
517 ldb_dn *get_default_basedn();
518 const char *errstring();
519 void set_create_perms(unsigned int perms);
520 void set_modules_dir(const char *path);
521 ldb_error set_debug(void (*debug)(void *context, enum ldb_debug_level level,
522 const char *fmt, va_list ap),
524 ldb_error set_opaque(const char *name, void *value);
525 void *get_opaque(const char *name);
526 ldb_error transaction_start();
527 ldb_error transaction_commit();
528 ldb_error transaction_cancel();
531 %typemap(in,numinputs=0) struct ldb_result **result_as_bool (struct ldb_result *tmp) { $1 = &tmp; }
532 %typemap(argout) struct ldb_result **result_as_bool { $result = ((*$1)->count > 0)?Py_True:Py_False; }
533 %typemap(freearg) struct ldb_result **result_as_bool { talloc_free(*$1); }
534 ldb_error __contains__(ldb_dn *dn, struct ldb_result **result_as_bool)
536 return ldb_search($self, dn, LDB_SCOPE_BASE, NULL, NULL,
540 PyObject *parse_ldif(const char *s)
542 PyObject *list = PyList_New(0);
543 struct ldb_ldif *ldif;
544 while ((ldif = ldb_ldif_read_string($self, &s)) != NULL) {
545 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
547 return PyObject_GetIter(list);
554 %nodefault ldb_message;
555 %nodefault ldb_context;
558 %rename(valid_attr_name) ldb_valid_attr_name;
559 int ldb_valid_attr_name(const char *s);
561 typedef unsigned long time_t;
564 static char *timestring(time_t t)
566 char *tresult = ldb_timestring(NULL, t);
567 char *result = strdup(tresult);
568 talloc_free(tresult);
573 %rename(string_to_time) ldb_string_to_time;
574 time_t ldb_string_to_time(const char *s);