summaryrefslogtreecommitdiff
path: root/source3/lib/ldb/swig
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib/ldb/swig')
-rw-r--r--source3/lib/ldb/swig/Ldb.py179
-rw-r--r--source3/lib/ldb/swig/ldb.i240
2 files changed, 419 insertions, 0 deletions
diff --git a/source3/lib/ldb/swig/Ldb.py b/source3/lib/ldb/swig/Ldb.py
new file mode 100644
index 0000000000..c7e6191c8a
--- /dev/null
+++ b/source3/lib/ldb/swig/Ldb.py
@@ -0,0 +1,179 @@
+"""Provide a more Pythonic and object-oriented interface to ldb."""
+
+#
+# Swig interface to Samba
+#
+# Copyright (C) Tim Potter 2006
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+#
+# Interface notes:
+#
+# - should an empty dn be represented as None, or an empty string?
+#
+# - should single-valued attributes be a string, or a list with one
+# element?
+#
+
+from ldb import *
+
+# Global initialisation
+
+result = ldb_global_init()
+
+if result != 0:
+ raise LdbError, (result, 'ldb_global_init failed')
+
+# Ldb exceptions
+
+class LdbError(Exception):
+ """An exception raised when a ldb error occurs.
+ The exception data is a tuple consisting of the ldb number and a
+ string description of the error."""
+ pass
+
+# Ldb classes
+
+class LdbMessage:
+ """A class representing a ldb message as a Python dictionary."""
+
+ def __init__(self):
+ self.mem_ctx = talloc_init(None)
+ self.msg = ldb_msg_new(self.mem_ctx)
+
+ def __del__(self):
+ if self.mem_ctx is not None:
+ talloc_free(self.mem_ctx)
+ self.mem_ctx = None
+ self.msg = None
+
+ # Make the dn attribute of the object dynamic
+
+ def __getattr__(self, attr):
+ if attr == 'dn':
+ return ldb_dn_linearize(None, self.msg.dn)
+ return self.__dict__[attr]
+
+ def __setattr__(self, attr, value):
+ if attr == 'dn':
+ self.msg.dn = ldb_dn_explode(self.msg, value)
+ if self.msg.dn == None:
+ err = LDB_ERR_INVALID_DN_SYNTAX
+ raise LdbError(err, ldb_strerror(err))
+ return
+ self.__dict__[attr] = value
+
+ # Get and set individual elements
+
+ def __getitem__(self, key):
+
+ elt = ldb_msg_find_element(self.msg, key)
+
+ if elt is None:
+ raise KeyError, "No such attribute '%s'" % key
+
+ return [ldb_val_array_getitem(elt.values, i)
+ for i in range(elt.num_values)]
+
+ def __setitem__(self, key, value):
+ ldb_msg_remove_attr(self.msg, key)
+ if type(value) in (list, tuple):
+ [ldb_msg_add_value(self.msg, key, v) for v in value]
+ else:
+ ldb_msg_add_value(self.msg, key, value)
+
+ # Dictionary interface
+ # TODO: move to iterator based interface
+
+ def len(self):
+ return self.msg.num_elements
+
+ def keys(self):
+ return [ldb_message_element_array_getitem(self.msg.elements, i).name
+ for i in range(self.msg.num_elements)]
+
+ def values(self):
+ return [self[k] for k in self.keys()]
+
+ def items(self):
+ return [(k, self[k]) for k in self.keys()]
+
+ # Misc stuff
+
+ def sanity_check(self):
+ return ldb_msg_sanity_check(self.msg)
+
+class Ldb:
+ """A class representing a binding to a ldb file."""
+
+ def __init__(self, url, flags = 0):
+ """Initialise underlying ldb."""
+
+ self.mem_ctx = talloc_init('mem_ctx for ldb 0x%x' % id(self))
+ self.ldb_ctx = ldb_init(self.mem_ctx)
+
+ result = ldb_connect(self.ldb_ctx, url, flags, None)
+
+ if result != LDB_SUCCESS:
+ raise LdbError, (result, ldb_strerror(result))
+
+ def __del__(self):
+ """Called when the object is to be garbage collected."""
+ self.close()
+
+ def close(self):
+ """Close down a ldb."""
+ if self.mem_ctx is not None:
+ talloc_free(self.mem_ctx)
+ self.mem_ctx = None
+ self.ldb_ctx = None
+
+ def _ldb_call(self, fn, *args):
+ """Call a ldb function with args. Raise a LdbError exception
+ if the function returns a non-zero return value."""
+
+ result = fn(*args)
+
+ if result != LDB_SUCCESS:
+ raise LdbError, (result, ldb_strerror(result))
+
+ def search(self, expression):
+ """Search a ldb for a given expression."""
+
+ self._ldb_call(ldb_search, self.ldb_ctx, None, LDB_SCOPE_DEFAULT,
+ expression, None);
+
+ return [LdbMessage(ldb_message_ptr_array_getitem(result.msgs, ndx))
+ for ndx in range(result.count)]
+
+ def delete(self, dn):
+ """Delete a dn."""
+
+ _dn = ldb_dn_explode(self.ldb_ctx, dn)
+
+ self._ldb_call(ldb_delete, self.ldb_ctx, _dn)
+
+ def rename(self, olddn, newdn):
+ """Rename a dn."""
+
+ _olddn = ldb_dn_explode(self.ldb_ctx, olddn)
+ _newdn = ldb_dn_explode(self.ldb_ctx, newdn)
+
+ self._ldb_call(ldb_rename, self.ldb_ctx, _olddn, _newdn)
+
+ def add(self, m):
+ self._ldb_call(ldb_add, self.ldb_ctx, m.msg)
diff --git a/source3/lib/ldb/swig/ldb.i b/source3/lib/ldb/swig/ldb.i
new file mode 100644
index 0000000000..09d3461c2a
--- /dev/null
+++ b/source3/lib/ldb/swig/ldb.i
@@ -0,0 +1,240 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Swig interface to ldb.
+
+ Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
+ Copyright (C) 2006 Simo Sorce <idra@samba.org>
+
+ ** NOTE! The following LGPL license applies to the ldb
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+%module ldb
+
+%{
+
+/* Some typedefs to help swig along */
+
+typedef unsigned char uint8_t;
+typedef unsigned long long uint64_t;
+typedef long long int64_t;
+
+/* Include headers */
+
+#include "lib/ldb/include/ldb.h"
+#include "lib/talloc/talloc.h"
+
+%}
+
+%include "carrays.i"
+%include "exception.i"
+
+/*
+ * Constants
+ */
+
+#define LDB_SUCCESS 0
+#define LDB_ERR_OPERATIONS_ERROR 1
+#define LDB_ERR_PROTOCOL_ERROR 2
+#define LDB_ERR_TIME_LIMIT_EXCEEDED 3
+#define LDB_ERR_SIZE_LIMIT_EXCEEDED 4
+#define LDB_ERR_COMPARE_FALSE 5
+#define LDB_ERR_COMPARE_TRUE 6
+#define LDB_ERR_AUTH_METHOD_NOT_SUPPORTED 7
+#define LDB_ERR_STRONG_AUTH_REQUIRED 8
+/* 9 RESERVED */
+#define LDB_ERR_REFERRAL 10
+#define LDB_ERR_ADMIN_LIMIT_EXCEEDED 11
+#define LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION 12
+#define LDB_ERR_CONFIDENTIALITY_REQUIRED 13
+#define LDB_ERR_SASL_BIND_IN_PROGRESS 14
+#define LDB_ERR_NO_SUCH_ATTRIBUTE 16
+#define LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE 17
+#define LDB_ERR_INAPPROPRIATE_MATCHING 18
+#define LDB_ERR_CONSTRAINT_VIOLATION 19
+#define LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS 20
+#define LDB_ERR_INVALID_ATTRIBUTE_SYNTAX 21
+/* 22-31 unused */
+#define LDB_ERR_NO_SUCH_OBJECT 32
+#define LDB_ERR_ALIAS_PROBLEM 33
+#define LDB_ERR_INVALID_DN_SYNTAX 34
+/* 35 RESERVED */
+#define LDB_ERR_ALIAS_DEREFERENCING_PROBLEM 36
+/* 37-47 unused */
+#define LDB_ERR_INAPPROPRIATE_AUTHENTICATION 48
+#define LDB_ERR_INVALID_CREDENTIALS 49
+#define LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS 50
+#define LDB_ERR_BUSY 51
+#define LDB_ERR_UNAVAILABLE 52
+#define LDB_ERR_UNWILLING_TO_PERFORM 53
+#define LDB_ERR_LOOP_DETECT 54
+/* 55-63 unused */
+#define LDB_ERR_NAMING_VIOLATION 64
+#define LDB_ERR_OBJECT_CLASS_VIOLATION 65
+#define LDB_ERR_NOT_ALLOWED_ON_NON_LEAF 66
+#define LDB_ERR_NOT_ALLOWED_ON_RDN 67
+#define LDB_ERR_ENTRY_ALREADY_EXISTS 68
+#define LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED 69
+/* 70 RESERVED FOR CLDAP */
+#define LDB_ERR_AFFECTS_MULTIPLE_DSAS 71
+/* 72-79 unused */
+#define LDB_ERR_OTHER 80
+
+enum ldb_scope {LDB_SCOPE_DEFAULT=-1,
+ LDB_SCOPE_BASE=0,
+ LDB_SCOPE_ONELEVEL=1,
+ LDB_SCOPE_SUBTREE=2};
+
+/*
+ * Wrap struct ldb_context
+ */
+
+/* The ldb functions will crash if a NULL ldb context is passed so
+ catch this before it happens. */
+
+%typemap(check) struct ldb_context* {
+ if ($1 == NULL)
+ SWIG_exception(SWIG_ValueError,
+ "ldb context must be non-NULL");
+}
+
+/*
+ * Wrap a small bit of talloc
+ */
+
+/* Use talloc_init() to create a parameter to pass to ldb_init(). Don't
+ forget to free it using talloc_free() afterwards. */
+
+TALLOC_CTX *talloc_init(char *name);
+int talloc_free(TALLOC_CTX *ptr);
+
+/*
+ * Wrap struct ldb_val
+ */
+
+%typemap(in) struct ldb_val *INPUT (struct ldb_val temp) {
+ $1 = &temp;
+ if (!PyString_Check($input)) {
+ PyErr_SetString(PyExc_TypeError, "string arg expected");
+ return NULL;
+ }
+ $1->length = PyString_Size($input);
+ $1->data = PyString_AsString($input);
+}
+
+%typemap(out) struct ldb_val {
+ $result = PyString_FromStringAndSize($1.data, $1.length);
+}
+
+/*
+ * Wrap struct ldb_result
+ */
+
+%typemap(in, numinputs=0) struct ldb_result **OUT (struct ldb_result *temp_ldb_result) {
+ $1 = &temp_ldb_result;
+}
+
+%typemap(argout) struct ldb_result ** {
+ resultobj = SWIG_NewPointerObj(*$1, SWIGTYPE_p_ldb_result, 0);
+}
+
+%types(struct ldb_result *);
+
+/*
+ * Wrap struct ldb_message_element
+ */
+
+%array_functions(struct ldb_val, ldb_val_array);
+
+struct ldb_message_element {
+ unsigned int flags;
+ const char *name;
+ unsigned int num_values;
+ struct ldb_val *values;
+};
+
+/*
+ * Wrap struct ldb_message
+ */
+
+%array_functions(struct ldb_message_element, ldb_message_element_array);
+
+struct ldb_message {
+ struct ldb_dn *dn;
+ unsigned int num_elements;
+ struct ldb_message_element *elements;
+ void *private_data;
+};
+
+/*
+ * Wrap struct ldb_result
+ */
+
+%array_functions(struct ldb_message *, ldb_message_ptr_array);
+
+struct ldb_result {
+ unsigned int count;
+ struct ldb_message **msgs;
+ char **refs;
+ struct ldb_control **controls;
+};
+
+/*
+ * Wrap ldb functions
+ */
+
+/* Initialisation */
+
+int ldb_global_init(void);
+struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx);
+
+/* Error handling */
+
+const char *ldb_errstring(struct ldb_context *ldb);
+const char *ldb_strerror(int ldb_err);
+
+/* Top-level ldb operations */
+
+int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[]);
+
+int ldb_search(struct ldb_context *ldb, const struct ldb_dn *base, enum ldb_scope scope, const char *expression, const char * const *attrs, struct ldb_result **OUT);
+
+int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn);
+
+int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct ldb_dn *newdn);
+
+int ldb_add(struct ldb_context *ldb, const struct ldb_message *message);
+
+/* Ldb message operations */
+
+struct ldb_message *ldb_msg_new(void *mem_ctx);
+
+struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, const char *attr_name);
+
+int ldb_msg_add_value(struct ldb_message *msg, const char *attr_name, const struct ldb_val *INPUT);
+
+void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr);
+
+int ldb_msg_sanity_check(struct ldb_message *msg);
+
+/* DN operations */
+
+struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn);
+
+char *ldb_dn_linearize(void *mem_ctx, const struct ldb_dn *dn);