Return SAM ldb context and loadparm context as part of C provision
[ira/wip.git] / source4 / lib / ldb / ldb.i
index 560142eb6deb0822a566501d32a499cd4b642616..6b94f19cb5b565f68e07cb87abc68f9e63ba618e 100644 (file)
@@ -5,7 +5,7 @@
 
    Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
    Copyright (C) 2006 Simo Sorce <idra@samba.org>
-   Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
+   Copyright (C) 2007-2008 Jelmer Vernooij <jelmer@samba.org>
 
      ** NOTE! The following LGPL license applies to the ldb
      ** library. This does NOT imply that all of Samba is released
@@ -42,6 +42,7 @@ typedef struct ldb_dn ldb_dn;
 typedef struct ldb_ldif ldb_ldif;
 typedef struct ldb_message_element ldb_msg_element;
 typedef int ldb_error;
+typedef int ldb_int_error;
 
 %}
 
@@ -102,8 +103,44 @@ typedef int ldb_error;
        $1->data = PyString_AsString($input);
 }
 
+%inline %{
+PyObject *ldb_val_to_py_object(struct ldb_context *ldb_ctx, 
+                               struct ldb_message_element *el, 
+                               struct ldb_val *val)
+{
+        const struct ldb_schema_attribute *a;
+        struct ldb_val new_val;
+        TALLOC_CTX *mem_ctx = talloc_new(NULL);
+        PyObject *ret;
+        
+        new_val = *val;
+        
+        if (ldb_ctx != NULL) {        
+               a = ldb_schema_attribute_by_name(ldb_ctx, el->name);
+        
+               if (a != NULL) {
+                       if (a->syntax->ldif_write_fn(ldb_ctx, mem_ctx, val, &new_val) != 0) {
+                               talloc_free(mem_ctx);
+                               return NULL;
+                       }
+               }
+        } 
+        
+       ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
+       
+       talloc_free(mem_ctx);
+       
+       return ret;
+}
+
+%}
+
+%typemap(out,noblock=1) struct ldb_val * {
+       $result = PyString_FromStringAndSize((const char *)$1->data, $1->length)
+}
+
 %typemap(out,noblock=1) struct ldb_val {
-       $result = PyString_FromStringAndSize((const char *)$1.data, $1.length);
+       $result = PyString_FromStringAndSize((const char *)$1.data, $1.length)
 }
 
 /*
@@ -214,18 +251,33 @@ fail:
 
 #ifdef SWIGPYTHON
 %{
+struct ldb_context *ldb_context_from_py_object(PyObject *py_obj)
+{
+        struct ldb_context *ldb_ctx;
+    if (SWIG_ConvertPtr(py_obj, (void *)&ldb_ctx, SWIGTYPE_p_ldb_context, 0 |  0 ) < 0)
+        return NULL;
+    return ldb_ctx;
+}
+
 int ldb_dn_from_pyobject(TALLOC_CTX *mem_ctx, PyObject *object, 
                          struct ldb_context *ldb_ctx, ldb_dn **dn)
 {
     int ret;
     struct ldb_dn *odn;
     if (ldb_ctx != NULL && PyString_Check(object)) {
-        *dn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object));
+        odn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object));
+       if (!odn) {
+               return SWIG_ERROR;
+       }
+       *dn = odn;
         return 0;
     }
     ret = SWIG_ConvertPtr(object, (void **)&odn, SWIGTYPE_p_ldb_dn, 
                            SWIG_POINTER_EXCEPTION);
     *dn = ldb_dn_copy(mem_ctx, odn);
+    if (odn && !*dn) {
+       return SWIG_ERROR;
+    }
     return ret;
 }
 
@@ -259,7 +311,8 @@ ldb_msg_element *ldb_msg_element_from_pyobject(TALLOC_CTX *mem_ctx,
     return me;
 }
 
-PyObject *ldb_msg_element_to_set(ldb_msg_element *me)
+PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, 
+                                 ldb_msg_element *me)
 {
     int i;
     PyObject *result;
@@ -269,8 +322,7 @@ PyObject *ldb_msg_element_to_set(ldb_msg_element *me)
 
     for (i = 0; i < me->num_values; i++) {
         PyList_SetItem(result, i,
-            PyString_FromStringAndSize((const char *)me->values[i].data, 
-                                       me->values[i].length));
+            ldb_val_to_py_object(ldb_ctx, me, &me->values[i]));
     }
 
     return result;
@@ -287,12 +339,12 @@ typedef struct ldb_message_element {
 #ifdef SWIGPYTHON
         PyObject *__iter__(void)
         {
-            return PyObject_GetIter(ldb_msg_element_to_set($self));
+            return PyObject_GetIter(ldb_msg_element_to_set(NULL, $self));
         }
 
         PyObject *__set__(void)
         {
-            return ldb_msg_element_to_set($self);
+            return ldb_msg_element_to_set(NULL, $self);
         }
 
         ldb_msg_element(PyObject *set_obj, int flags=0, const char *name = NULL)
@@ -311,9 +363,7 @@ typedef struct ldb_message_element {
             if (i < 0 || i >= $self->num_values)
                 return Py_None;
 
-            return PyString_FromStringAndSize(
-                        (const char *)$self->values[i].data, 
-                        $self->values[i].length);
+            return ldb_val_to_py_object(NULL, $self, &$self->values[i]);
         }
 
         ~ldb_msg_element() { talloc_free($self); }
@@ -427,6 +477,8 @@ typedef struct ldb_ldif ldb_ldif;
 
 #ifdef SWIGPYTHON
 %{
+static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
+
 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
 {
     char *text;
@@ -486,6 +538,14 @@ PyObject *PyExc_LdbError;
 
 
 %typemap(out,noblock=1) ldb_error {
+    if ($1 != LDB_SUCCESS) {
+        PyErr_SetObject(PyExc_LdbError, Py_BuildValue((char *)"(i,s)", $1, ldb_errstring(arg1)));
+        SWIG_fail;
+    }
+    $result = Py_None;
+};
+
+%typemap(out,noblock=1) ldb_int_error {
     if ($1 != LDB_SUCCESS) {
         PyErr_SetObject(PyExc_LdbError, Py_BuildValue((char *)"(i,s)", $1, ldb_strerror($1)));
         SWIG_fail;
@@ -513,6 +573,50 @@ PyObject *PyExc_LdbError;
     talloc_free($1);
 };
 
+%typemap(in,numinputs=1) ldb_msg *add_msg {
+    Py_ssize_t dict_pos, msg_pos;
+    ldb_msg_element *msgel;
+    PyObject *key, *value;
+
+    if (PyDict_Check($input)) {
+       PyObject *dn_value = PyDict_GetItemString($input, "dn");
+        $1 = ldb_msg_new(NULL);
+        $1->elements = talloc_zero_array($1, struct ldb_message_element, PyDict_Size($input));
+        msg_pos = dict_pos = 0;
+       if (dn_value) {
+                /* using argp1 (magic SWIG value) here is a hack */
+                if (ldb_dn_from_pyobject($1, dn_value, argp1, &$1->dn) != 0) {
+                    SWIG_exception(SWIG_TypeError, "unable to import dn object");
+                }
+               if ($1->dn == NULL) {
+                   SWIG_exception(SWIG_TypeError, "dn set but not found");
+               }
+       }
+
+       while (PyDict_Next($input, &dict_pos, &key, &value)) {
+           char *key_str = PyString_AsString(key);
+            if (strcmp(key_str, "dn") != 0) {
+                msgel = ldb_msg_element_from_pyobject($1->elements, value, 0, key_str);
+                if (msgel == NULL) {
+                    SWIG_exception(SWIG_TypeError, "unable to import element");
+                }
+                memcpy(&$1->elements[msg_pos], msgel, sizeof(*msgel));
+                msg_pos++;
+            }
+        }
+
+        if ($1->dn == NULL) {
+            SWIG_exception(SWIG_TypeError, "no dn set");
+        }
+
+        $1->num_elements = msg_pos;
+    } else {
+        if (SWIG_ConvertPtr($input, (void **)&$1, SWIGTYPE_p_ldb_message, 0) != 0) {
+            SWIG_exception(SWIG_TypeError, "unable to convert ldb message");
+        }
+    }
+}
+
 /* Top-level ldb operations */
 typedef struct ldb_context {
     %extend {
@@ -570,58 +674,40 @@ typedef struct ldb_context {
         struct ldb_control **parse_control_strings(TALLOC_CTX *mem_ctx, 
                                                    const char * const*control_strings);
         ldb_error add(ldb_msg *add_msg);
-        ldb_error add(PyObject *py_msg) 
-        {
-            ldb_error ret;
-            int dict_pos, msg_pos;
-            PyObject *key, *value;
-            ldb_msg_element *msgel;
-            ldb_msg *msg = NULL;
-
-            if (PyDict_Check(py_msg)) {
-                msg = ldb_msg_new(NULL);
-                msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_msg));
-                msg_pos = dict_pos = 0;
-                while (PyDict_Next(py_msg, &dict_pos, &key, &value)) {
-                    if (!strcmp(PyString_AsString(key), "dn")) {
-                        if (ldb_dn_from_pyobject(msg, value, $self, &msg->dn) != 0) {
-                            return LDB_ERR_OTHER;
-                        }
-                    } else {
-                        msgel = ldb_msg_element_from_pyobject(msg->elements, value, 0, PyString_AsString(key));
-                        if (msgel == NULL) {
-                            SWIG_exception(SWIG_TypeError, "unable to import element");
-                            return LDB_ERR_OTHER;
-                        }
-                        memcpy(&msg->elements[msg_pos], msgel, sizeof(*msgel));
-                        msg_pos++;
-                    }
-                }
-
-                if (msg->dn == NULL) {
-                    SWIG_exception(SWIG_TypeError, "no dn set");
-                    return LDB_ERR_OTHER;
-                }
-
-                msg->num_elements = msg_pos;
-            } else {
-                if (SWIG_ConvertPtr(py_msg, (void **)&msg, SWIGTYPE_p_ldb_message, 0) != 0)
-                    return LDB_ERR_OTHER;
-            }
-
-            ret = ldb_add($self, msg);
-
-            talloc_free(msg);
-            return ret;
-
-            fail:
-            return LDB_ERR_OTHER;
-        }
         ldb_error modify(ldb_msg *message);
         ldb_dn *get_config_basedn();
         ldb_dn *get_root_basedn();
         ldb_dn *get_schema_basedn();
         ldb_dn *get_default_basedn();
+        PyObject *schema_format_value(const char *element_name, PyObject *val)
+        {
+               const struct ldb_schema_attribute *a;
+               struct ldb_val old_val;
+               struct ldb_val new_val;
+               TALLOC_CTX *mem_ctx = talloc_new(NULL);
+               PyObject *ret;
+               
+               old_val.data = PyString_AsString(val);
+               old_val.length = PyString_Size(val);
+                
+               a = ldb_schema_attribute_by_name($self, element_name);
+        
+               if (a == NULL) {
+                       return Py_None;
+               }
+               
+               if (a->syntax->ldif_write_fn($self, mem_ctx, &old_val, &new_val) != 0) {
+                       talloc_free(mem_ctx);
+                       return Py_None;
+                }
+        
+               ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
+               
+               talloc_free(mem_ctx);
+               
+               return ret;
+        }
+
         const char *errstring();
         void set_create_perms(unsigned int perms);
         void set_modules_dir(const char *path);
@@ -633,7 +719,10 @@ typedef struct ldb_context {
         ldb_error transaction_start();
         ldb_error transaction_commit();
         ldb_error transaction_cancel();
-
+        void schema_attribute_remove(const char *name);
+        ldb_error schema_attribute_add(const char *attribute, unsigned flags, const char *syntax);
+       ldb_error setup_wellknown_attributes(void);
+       
 #ifdef SWIGPYTHON
         %typemap(in,numinputs=0,noblock=1) struct ldb_result **result_as_bool (struct ldb_result *tmp) { $1 = &tmp; }
         %typemap(argout,noblock=1) struct ldb_result **result_as_bool { $result = ((*$1)->count > 0)?Py_True:Py_False; }
@@ -705,4 +794,4 @@ time_t ldb_string_to_time(const char *s);
 }
 
 %rename(register_module) ldb_register_module;
-ldb_error ldb_register_module(const struct ldb_module_ops *);
+ldb_int_error ldb_register_module(const struct ldb_module_ops *);