Merge branch 'v4-0-test' of git://git.samba.org/samba into 4-0-abartlet
[kai/samba.git] / source / lib / ldb / ldb.i
1 /*
2    Unix SMB/CIFS implementation.
3
4    Swig interface to ldb.
5
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>
9
10      ** NOTE! The following LGPL license applies to the ldb
11      ** library. This does NOT imply that all of Samba is released
12      ** under the LGPL
13    
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.
18
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.
23
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/>.
26 */
27
28 %module ldb
29
30 %{
31
32 #include <stdint.h>
33 #include <stdbool.h>
34 #include "talloc.h"
35 #include "ldb.h"
36 #include "ldb_errors.h"
37 #include "ldb_private.h"
38
39 typedef struct ldb_message ldb_msg;
40 typedef struct ldb_context ldb;
41 typedef struct ldb_dn ldb_dn;
42 typedef struct ldb_ldif ldb_ldif;
43 typedef struct ldb_message_element ldb_msg_element;
44 typedef int ldb_error;
45
46 %}
47
48 %import "carrays.i"
49 %import "typemaps.i"
50 %include "exception.i"
51 %import "stdint.i"
52
53 /* Don't expose talloc contexts in Python code. Python does reference 
54    counting for us, so just create a new top-level talloc context.
55  */
56 %typemap(in, numinputs=0, noblock=1) TALLOC_CTX * {
57     $1 = NULL;
58 }
59
60
61
62 %constant int SCOPE_DEFAULT = LDB_SCOPE_DEFAULT;
63 %constant int SCOPE_BASE = LDB_SCOPE_BASE;
64 %constant int SCOPE_ONELEVEL = LDB_SCOPE_ONELEVEL;
65 %constant int SCOPE_SUBTREE = LDB_SCOPE_SUBTREE;
66
67 %constant int CHANGETYPE_NONE = LDB_CHANGETYPE_NONE;
68 %constant int CHANGETYPE_ADD = LDB_CHANGETYPE_ADD;
69 %constant int CHANGETYPE_DELETE = LDB_CHANGETYPE_DELETE;
70 %constant int CHANGETYPE_MODIFY = LDB_CHANGETYPE_MODIFY;
71
72 /* 
73  * Wrap struct ldb_context
74  */
75
76 /* The ldb functions will crash if a NULL ldb context is passed so
77    catch this before it happens. */
78
79 %typemap(check,noblock=1) struct ldb_context* {
80         if ($1 == NULL)
81                 SWIG_exception(SWIG_ValueError, 
82                         "ldb context must be non-NULL");
83 }
84
85 %typemap(check,noblock=1) ldb_msg * {
86         if ($1 == NULL)
87                 SWIG_exception(SWIG_ValueError, 
88                         "Message can not be None");
89 }
90
91 /*
92  * Wrap struct ldb_val
93  */
94
95 %typemap(in,noblock=1) struct ldb_val *INPUT (struct ldb_val temp) {
96         $1 = &temp;
97         if (!PyString_Check($input)) {
98                 PyErr_SetString(PyExc_TypeError, "string arg expected");
99                 return NULL;
100         }
101         $1->length = PyString_Size($input);
102         $1->data = PyString_AsString($input);
103 }
104
105 %typemap(out,noblock=1) struct ldb_val {
106         $result = PyString_FromStringAndSize((const char *)$1.data, $1.length);
107 }
108
109 /*
110  * Wrap struct ldb_result
111  */
112
113 %typemap(in,noblock=1,numinputs=0) struct ldb_result **OUT (struct ldb_result *temp_ldb_result) {
114         $1 = &temp_ldb_result;
115 }
116
117 #ifdef SWIGPYTHON
118 %typemap(argout,noblock=1) struct ldb_result ** (int i) {
119         $result = PyList_New((*$1)->count);
120     for (i = 0; i < (*$1)->count; i++) {
121         PyList_SetItem($result, i, 
122             SWIG_NewPointerObj((*$1)->msgs[i], SWIGTYPE_p_ldb_message, 0)
123         );
124     }
125 }
126
127 %typemap(in,noblock=1,numinputs=1) const char * const *NULL_STR_LIST {
128     if ($input == Py_None) {
129         $1 = NULL;
130     } else if (PySequence_Check($input)) {
131         int i;
132         $1 = talloc_array(NULL, char *, PySequence_Size($input)+1);
133         for(i = 0; i < PySequence_Size($input); i++)
134             $1[i] = PyString_AsString(PySequence_GetItem($input, i));
135         $1[i] = NULL;
136     } else {
137         SWIG_exception(SWIG_TypeError, "expected sequence");
138     }
139 }
140
141 %typemap(freearg,noblock=1) const char * const *NULL_STR_LIST {
142     talloc_free($1);
143 }
144
145 %apply const char * const *NULL_STR_LIST { const char * const *attrs }
146 %apply const char * const *NULL_STR_LIST { const char * const *control_strings }
147
148 #endif
149
150 %types(struct ldb_result *);
151
152 /*
153  * Wrap struct ldb_dn
154  */
155
156 %rename(__str__) ldb_dn::get_linearized;
157 %rename(__cmp__) ldb_dn::compare;
158 %rename(__len__) ldb_dn::get_comp_num;
159 %rename(Dn) ldb_dn;
160 typedef struct ldb_dn {
161     %extend {
162         ldb_dn(ldb *ldb_ctx, const char *str)
163         {
164             ldb_dn *ret = ldb_dn_new(ldb_ctx, ldb_ctx, str);
165             /* ldb_dn_new() doesn't accept NULL as memory context, so 
166                we do it this way... */
167             talloc_steal(NULL, ret);
168
169             if (ret == NULL)
170                 SWIG_exception(SWIG_ValueError, 
171                                 "unable to parse dn string");
172 fail:
173             return ret;
174         }
175         ~ldb_dn() { talloc_free($self); }
176         bool validate();
177         const char *get_casefold();
178         const char *get_linearized();
179         ldb_dn *parent() { return ldb_dn_get_parent(NULL, $self); }
180         int compare(ldb_dn *other);
181         bool is_valid();
182         bool is_special();
183         bool is_null();
184         bool check_special(const char *name);
185         int get_comp_num();
186         bool add_child(ldb_dn *child);
187         bool add_base(ldb_dn *base);
188         const char *canonical_str() {
189             return ldb_dn_canonical_string($self, $self);
190         }
191         const char *canonical_ex_str() {
192             return ldb_dn_canonical_ex_string($self, $self);
193         }
194 #ifdef SWIGPYTHON
195         ldb_dn *__add__(ldb_dn *other)
196         {
197             ldb_dn *ret = ldb_dn_copy(NULL, $self);
198             ldb_dn_add_child(ret, other);
199             return ret;
200         }
201
202         /* FIXME: implement __getslice__ */
203 #endif
204     %pythoncode {
205         def __eq__(self, other):
206             if isinstance(other, self.__class__):
207                 return self.__cmp__(other) == 0
208             if isinstance(other, str):
209                 return str(self) == other
210             return False
211     }
212     }
213 } ldb_dn;
214
215 #ifdef SWIGPYTHON
216 %{
217 int ldb_dn_from_pyobject(TALLOC_CTX *mem_ctx, PyObject *object, 
218                          struct ldb_context *ldb_ctx, ldb_dn **dn)
219 {
220     int ret;
221     struct ldb_dn *odn;
222     if (ldb_ctx != NULL && PyString_Check(object)) {
223         *dn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object));
224         return 0;
225     }
226     ret = SWIG_ConvertPtr(object, (void **)&odn, SWIGTYPE_p_ldb_dn, 
227                            SWIG_POINTER_EXCEPTION);
228     *dn = ldb_dn_copy(mem_ctx, odn);
229     return ret;
230 }
231
232 ldb_msg_element *ldb_msg_element_from_pyobject(TALLOC_CTX *mem_ctx,
233                                                PyObject *set_obj, int flags,
234                                                const char *attr_name)
235 {
236     struct ldb_message_element *me = talloc(mem_ctx, struct ldb_message_element);
237     me->name = attr_name;
238     me->flags = flags;
239     if (PyString_Check(set_obj)) {
240         me->num_values = 1;
241         me->values = talloc_array(me, struct ldb_val, me->num_values);
242         me->values[0].length = PyString_Size(set_obj);
243         me->values[0].data = (uint8_t *)talloc_strdup(me->values, 
244                                            PyString_AsString(set_obj));
245     } else if (PySequence_Check(set_obj)) {
246         int i;
247         me->num_values = PySequence_Size(set_obj);
248         me->values = talloc_array(me, struct ldb_val, me->num_values);
249         for (i = 0; i < me->num_values; i++) {
250             PyObject *obj = PySequence_GetItem(set_obj, i);
251             me->values[i].length = PyString_Size(obj);
252             me->values[i].data = (uint8_t *)PyString_AsString(obj);
253         }
254     } else {
255         talloc_free(me);
256         me = NULL;
257     }
258
259     return me;
260 }
261
262 PyObject *ldb_msg_element_to_set(ldb_msg_element *me)
263 {
264     int i;
265     PyObject *result;
266
267     /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
268     result = PyList_New(me->num_values);
269
270     for (i = 0; i < me->num_values; i++) {
271         PyList_SetItem(result, i,
272             PyString_FromStringAndSize((const char *)me->values[i].data, 
273                                        me->values[i].length));
274     }
275
276     return result;
277 }
278
279 %}
280 #endif
281
282 /* ldb_message_element */
283 %rename(__cmp__) ldb_message_element::compare;
284 %rename(MessageElement) ldb_msg_element;
285 typedef struct ldb_message_element {
286     %extend {
287 #ifdef SWIGPYTHON
288         PyObject *__iter__(void)
289         {
290             return PyObject_GetIter(ldb_msg_element_to_set($self));
291         }
292
293         PyObject *__set__(void)
294         {
295             return ldb_msg_element_to_set($self);
296         }
297
298         ldb_msg_element(PyObject *set_obj, int flags=0, const char *name = NULL)
299         {
300             return ldb_msg_element_from_pyobject(NULL, set_obj, flags, name);
301         }
302
303         int __len__()
304         {
305             return $self->num_values;
306         }
307 #endif
308
309         PyObject *get(int i)
310         {
311             if (i < 0 || i >= $self->num_values)
312                 return Py_None;
313
314             return PyString_FromStringAndSize(
315                         (const char *)$self->values[i].data, 
316                         $self->values[i].length);
317         }
318
319         ~ldb_msg_element() { talloc_free($self); }
320         int compare(ldb_msg_element *);
321     }
322     %pythoncode {
323         def __getitem__(self, i):
324             ret = self.get(i)
325             if ret is None:
326                 raise KeyError("no such value")
327             return ret
328
329         def __eq__(self, other):
330             if (len(self) == 1 and self.get(0) == other):
331                 return True
332             if isinstance(other, self.__class__):
333                 return self.__cmp__(other) == 0
334             o = iter(other)
335             for i in range(len(self)):
336                 if self.get(i) != o.next():
337                     return False
338             return True
339     }
340 } ldb_msg_element;
341
342 /* ldb_message */
343
344 %rename(Message) ldb_message;
345 #ifdef SWIGPYTHON
346 %rename(__delitem__) ldb_message::remove_attr;
347 %typemap(out) ldb_msg_element * {
348         if ($1 == NULL)
349                 PyErr_SetString(PyExc_KeyError, "no such element");
350     else
351         $result = SWIG_NewPointerObj($1, SWIGTYPE_p_ldb_message_element, 0);
352 }
353 %rename(__getitem__) ldb_message::find_element;
354 //%typemap(out) ldb_msg_element *;
355
356
357 %inline {
358     PyObject *ldb_msg_list_elements(ldb_msg *msg)
359     {
360         int i;
361         PyObject *obj = PyList_New(msg->num_elements);
362         for (i = 0; i < msg->num_elements; i++)
363             PyList_SetItem(obj, i, PyString_FromString(msg->elements[i].name));
364         return obj;
365     }
366 }
367
368 #endif
369
370 typedef struct ldb_message {
371         ldb_dn *dn;
372
373     %extend {
374         ldb_msg(ldb_dn *dn = NULL) { 
375             ldb_msg *ret = ldb_msg_new(NULL); 
376             ret->dn = talloc_reference(ret, dn);
377             return ret;
378         }
379         ~ldb_msg() { talloc_free($self); }
380         ldb_msg_element *find_element(const char *name);
381         
382 #ifdef SWIGPYTHON
383         void __setitem__(const char *attr_name, ldb_msg_element *val)
384         {
385             struct ldb_message_element *el;
386             
387             ldb_msg_remove_attr($self, attr_name);
388
389             el = talloc($self, struct ldb_message_element);
390             el->name = talloc_strdup(el, attr_name);
391             el->num_values = val->num_values;
392             el->values = talloc_reference(el, val->values);
393
394             ldb_msg_add($self, el, val->flags);
395         }
396
397         void __setitem__(const char *attr_name, PyObject *val)
398         {
399             struct ldb_message_element *el = ldb_msg_element_from_pyobject(NULL,
400                                                 val, 0, attr_name);
401             talloc_steal($self, el);
402             ldb_msg_remove_attr($self, attr_name);
403             ldb_msg_add($self, el, el->flags);
404         }
405
406         unsigned int __len__() { return $self->num_elements; }
407
408         PyObject *keys(void)
409         {
410             return ldb_msg_list_elements($self);
411         }
412
413         PyObject *__iter__(void)
414         {
415             return PyObject_GetIter(ldb_msg_list_elements($self));
416         }
417 #endif
418         void remove_attr(const char *name);
419     }
420 } ldb_msg;
421
422 /* FIXME: Convert ldb_result to 3-tuple:
423    (msgs, refs, controls)
424  */
425
426 typedef struct ldb_ldif ldb_ldif;
427
428 #ifdef SWIGPYTHON
429 %{
430 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
431 {
432     char *text;
433     PyObject *fn = context;
434
435     vasprintf(&text, fmt, ap);
436     PyObject_CallFunction(fn, (char *)"(i,s)", level, text);
437     free(text);
438 }
439 %}
440
441 %typemap(in,numinputs=1,noblock=1) (void (*debug)(void *context, enum ldb_debug_level level, const char *fmt, va_list ap), void *context) {
442     $1 = py_ldb_debug;
443     /* FIXME: Should be decreased somewhere as well. Perhaps register a 
444        destructor and tie it to the ldb context ? */
445     Py_INCREF($input);
446     $2 = $input;
447 }
448 #endif
449
450 %inline {
451     static PyObject *ldb_ldif_to_pyobject(ldb_ldif *ldif)
452     {
453         if (ldif == NULL) {
454             return Py_None;
455         } else {
456             return Py_BuildValue((char *)"(iO)", ldif->changetype, 
457                    SWIG_NewPointerObj(ldif->msg, SWIGTYPE_p_ldb_message, 0));
458         }
459     }
460 }
461
462 /*
463  * Wrap ldb errors
464  */
465
466 %{
467 PyObject *PyExc_LdbError;
468 %}
469
470 %pythoncode %{
471     LdbError = _ldb.LdbError
472 %}
473
474 %init %{
475     PyExc_LdbError = PyErr_NewException((char *)"_ldb.LdbError", NULL, NULL);
476     PyDict_SetItemString(d, "LdbError", PyExc_LdbError);
477 %}
478
479 %ignore _LDB_ERRORS_H_;
480 %ignore LDB_SUCCESS;
481 %include "include/ldb_errors.h"
482
483 /*
484  * Wrap ldb functions 
485  */
486
487
488 %typemap(out,noblock=1) ldb_error {
489     if ($1 != LDB_SUCCESS) {
490         PyErr_SetObject(PyExc_LdbError, Py_BuildValue((char *)"(i,s)", $1, ldb_strerror($1)));
491         SWIG_fail;
492     }
493     $result = Py_None;
494 };
495
496 %typemap(out,noblock=1) struct ldb_control ** {
497     if ($1 == NULL) {
498         PyErr_SetObject(PyExc_LdbError, Py_BuildValue((char *)"(s)", ldb_errstring(arg1)));
499         SWIG_fail;
500     }
501     $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
502 }
503
504 %rename(Ldb) ldb_context;
505
506 %typemap(in,noblock=1) struct ldb_dn * {
507     if (ldb_dn_from_pyobject(NULL, $input, arg1, &$1) != 0) {
508         SWIG_fail;
509     }
510 };
511
512 %typemap(freearg,noblock=1) struct ldb_dn * {
513     talloc_free($1);
514 };
515
516 /* Top-level ldb operations */
517 typedef struct ldb_context {
518     %extend {
519         ldb(void) { return ldb_init(NULL); }
520
521         ldb_error connect(const char *url, unsigned int flags = 0, 
522             const char *options[] = NULL);
523
524         ~ldb() { talloc_free($self); }
525         ldb_error search_ex(TALLOC_CTX *mem_ctx,
526                    ldb_dn *base = NULL, 
527                    enum ldb_scope scope = LDB_SCOPE_DEFAULT, 
528                    const char *expression = NULL, 
529                    const char *const *attrs = NULL, 
530                    struct ldb_control **controls = NULL,
531                    struct ldb_result **OUT) {
532             int ret;
533             struct ldb_result *res;
534             struct ldb_request *req;
535             res = talloc_zero(mem_ctx, struct ldb_result);
536             if (!res) {
537                 return LDB_ERR_OPERATIONS_ERROR;
538             }
539
540             ret = ldb_build_search_req(&req, $self, mem_ctx,
541                            base?base:ldb_get_default_basedn($self),
542                            scope,
543                            expression,
544                            attrs,
545                            controls,
546                            res,
547                            ldb_search_default_callback);
548
549             if (ret != LDB_SUCCESS) {
550                 talloc_free(res);
551                 return ret;
552             }
553
554             ldb_set_timeout($self, req, 0); /* use default timeout */
555                 
556             ret = ldb_request($self, req);
557                 
558             if (ret == LDB_SUCCESS) {
559                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
560             }
561
562             talloc_free(req);
563
564             *OUT = res;
565             return ret;
566         }
567
568         ldb_error delete(ldb_dn *dn);
569         ldb_error rename(ldb_dn *olddn, ldb_dn *newdn);
570         struct ldb_control **parse_control_strings(TALLOC_CTX *mem_ctx, 
571                                                    const char * const*control_strings);
572         ldb_error add(ldb_msg *add_msg);
573         ldb_error add(PyObject *py_msg) 
574         {
575             ldb_error ret;
576             int dict_pos, msg_pos;
577             PyObject *key, *value;
578             ldb_msg_element *msgel;
579             ldb_msg *msg = NULL;
580
581             if (PyDict_Check(py_msg)) {
582                 msg = ldb_msg_new(NULL);
583                 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_msg));
584                 msg_pos = dict_pos = 0;
585                 while (PyDict_Next(py_msg, &dict_pos, &key, &value)) {
586                     if (!strcmp(PyString_AsString(key), "dn")) {
587                         if (ldb_dn_from_pyobject(msg, value, $self, &msg->dn) != 0) {
588                             return LDB_ERR_OTHER;
589                         }
590                     } else {
591                         msgel = ldb_msg_element_from_pyobject(msg->elements, value, 0, PyString_AsString(key));
592                         if (msgel == NULL) {
593                             SWIG_exception(SWIG_TypeError, "unable to import element");
594                             return LDB_ERR_OTHER;
595                         }
596                         memcpy(&msg->elements[msg_pos], msgel, sizeof(*msgel));
597                         msg_pos++;
598                     }
599                 }
600
601                 if (msg->dn == NULL) {
602                     SWIG_exception(SWIG_TypeError, "no dn set");
603                     return LDB_ERR_OTHER;
604                 }
605
606                 msg->num_elements = msg_pos;
607             } else {
608                 if (SWIG_ConvertPtr(py_msg, (void **)&msg, SWIGTYPE_p_ldb_message, 0) != 0)
609                     return LDB_ERR_OTHER;
610             }
611
612             ret = ldb_add($self, msg);
613
614             talloc_free(msg);
615             return ret;
616
617             fail:
618             return LDB_ERR_OTHER;
619         }
620         ldb_error modify(ldb_msg *message);
621         ldb_dn *get_config_basedn();
622         ldb_dn *get_root_basedn();
623         ldb_dn *get_schema_basedn();
624         ldb_dn *get_default_basedn();
625         const char *errstring();
626         void set_create_perms(unsigned int perms);
627         void set_modules_dir(const char *path);
628         ldb_error set_debug(void (*debug)(void *context, enum ldb_debug_level level, 
629                                           const char *fmt, va_list ap),
630                             void *context);
631         ldb_error set_opaque(const char *name, void *value);
632         void *get_opaque(const char *name);
633         ldb_error transaction_start();
634         ldb_error transaction_commit();
635         ldb_error transaction_cancel();
636
637 #ifdef SWIGPYTHON
638         %typemap(in,numinputs=0,noblock=1) struct ldb_result **result_as_bool (struct ldb_result *tmp) { $1 = &tmp; }
639         %typemap(argout,noblock=1) struct ldb_result **result_as_bool { $result = ((*$1)->count > 0)?Py_True:Py_False; }
640         %typemap(freearg,noblock=1) struct ldb_result **result_as_bool { talloc_free(*$1); }
641         ldb_error __contains__(ldb_dn *dn, struct ldb_result **result_as_bool)
642         {
643             return ldb_search($self, dn, LDB_SCOPE_BASE, NULL, NULL, 
644                              result_as_bool);
645         }
646
647         PyObject *parse_ldif(const char *s)
648         {
649             PyObject *list = PyList_New(0);
650             struct ldb_ldif *ldif;
651             while ((ldif = ldb_ldif_read_string($self, &s)) != NULL) {
652                 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
653             }
654             return PyObject_GetIter(list);
655         }
656
657 #endif
658     }
659     %pythoncode {
660         def __init__(self, url=None, flags=0, options=None):
661             _ldb.Ldb_swiginit(self,_ldb.new_Ldb())
662             if url is not None:
663                 self.connect(url, flags, options)
664
665         def search(self, base=None, scope=SCOPE_DEFAULT, expression=None, 
666                    attrs=None, controls=None):
667             parsed_controls = None
668             if controls is not None:
669                 parsed_controls = self.parse_control_strings(controls)
670             return self.search_ex(base, scope, expression, attrs, 
671                                   parsed_controls)
672     }
673
674 } ldb;
675
676 %typemap(in,noblock=1) struct ldb_dn *;
677 %typemap(freearg,noblock=1) struct ldb_dn *;
678
679 %nodefault ldb_message;
680 %nodefault ldb_context;
681 %nodefault Dn;
682
683 %rename(valid_attr_name) ldb_valid_attr_name;
684 int ldb_valid_attr_name(const char *s);
685
686 typedef unsigned long time_t;
687
688 %inline %{
689 static char *timestring(time_t t)
690 {
691     char *tresult = ldb_timestring(NULL, t);
692     char *result = strdup(tresult);
693     talloc_free(tresult);
694     return result; 
695 }
696 %}
697
698 %rename(string_to_time) ldb_string_to_time;
699 time_t ldb_string_to_time(const char *s);
700
701 %typemap(in,noblock=1) const struct ldb_module_ops * {
702     $1 = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
703
704     $1->name = (char *)PyObject_GetAttrString($input, (char *)"name");
705 }
706
707 %rename(register_module) ldb_register_module;
708 ldb_error ldb_register_module(const struct ldb_module_ops *);