[SCM] Samba Shared Repository - branch master updated - tevent-0-9-8-566-gc5d38fd

Stefan Metzmacher metze at samba.org
Sat Sep 19 23:12:58 MDT 2009


The branch, master has been updated
       via  c5d38fd45abb037ff03dfb196c7fd0e2f59b1f28 (commit)
       via  93e1e8bec92a828ab343c6a4cc53f3759de557ba (commit)
       via  7fbd18a9dd0fb07aceffd2494de8fc9710a427ce (commit)
       via  d80058f64edde55a4543d79475bb2a5730c2ab98 (commit)
       via  46dab92a2ddb4af3706de15894acc54b0b2b8d7b (commit)
      from  c14b2eb8ddba17b6e349038671124e70a66e6723 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit c5d38fd45abb037ff03dfb196c7fd0e2f59b1f28
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sun Sep 20 06:05:59 2009 +0200

    blackbox/test_ldb.sh: test searching using OIDs instead of names for attributes and classes
    
    metze

commit 93e1e8bec92a828ab343c6a4cc53f3759de557ba
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Sep 19 07:54:59 2009 +0200

    s4:provision: add the 'resolve_oids' on the top of the module stack
    
    metze

commit 7fbd18a9dd0fb07aceffd2494de8fc9710a427ce
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Sep 19 07:01:26 2009 +0200

    dsdb/samdb: add resolve_oids module
    
    Windows Servers allow OID strings to be used instead of
    attribute/class names.
    
    For now we only resolve the OIDs in the search expressions,
    the rest will follow.
    
    metze

commit d80058f64edde55a4543d79475bb2a5730c2ab98
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sun Sep 20 05:42:27 2009 +0200

    s4:build: require ldb 0.9.7
    
    metze

commit 46dab92a2ddb4af3706de15894acc54b0b2b8d7b
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sun Sep 20 05:41:42 2009 +0200

    s4:ldb: add ldb_parse_tree_copy_shallow() and change version to 0.9.7
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 source4/dsdb/samdb/ldb_modules/config.mk      |   11 +
 source4/dsdb/samdb/ldb_modules/resolve_oids.c |  427 +++++++++++++++++++++++++
 source4/lib/ldb/common/ldb_parse.c            |   58 ++++
 source4/lib/ldb/configure.ac                  |    2 +-
 source4/lib/ldb/include/ldb.h                 |    6 +
 source4/min_versions.m4                       |    2 +-
 source4/scripting/python/samba/provision.py   |    3 +-
 testprogs/blackbox/test_ldb.sh                |   16 +
 8 files changed, 522 insertions(+), 3 deletions(-)
 create mode 100644 source4/dsdb/samdb/ldb_modules/resolve_oids.c


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk
index f868f8a..9384d06 100644
--- a/source4/dsdb/samdb/ldb_modules/config.mk
+++ b/source4/dsdb/samdb/ldb_modules/config.mk
@@ -346,3 +346,14 @@ SUBSYSTEM = LIBLDB
 ################################################
 
 ldb_descriptor_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/descriptor.o
+
+################################################
+# Start MODULE ldb_resolve_oids
+[MODULE::ldb_resolve_oids]
+SUBSYSTEM = LIBLDB
+PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS LIBNDR
+INIT_FUNCTION = LDB_MODULE(resolve_oids)
+# End MODULE ldb_resolve_oids
+################################################
+
+ldb_resolve_oids_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/resolve_oids.o
diff --git a/source4/dsdb/samdb/ldb_modules/resolve_oids.c b/source4/dsdb/samdb/ldb_modules/resolve_oids.c
new file mode 100644
index 0000000..f4d9eba
--- /dev/null
+++ b/source4/dsdb/samdb/ldb_modules/resolve_oids.c
@@ -0,0 +1,427 @@
+/*
+   ldb database library
+
+   Copyright (C) Stefan Metzmacher <metze at samba.org> 2009
+
+   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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "ldb_module.h"
+#include "dsdb/samdb/samdb.h"
+
+static int resolve_oids_replace_value(struct ldb_context *ldb,
+				      struct dsdb_schema *schema,
+				      const struct dsdb_attribute *a,
+				      struct ldb_val *valp)
+{
+	const struct dsdb_attribute *va = NULL;
+	const struct dsdb_class *vo = NULL;
+	const void *p2;
+	char *str = NULL;
+
+	if (a->syntax->oMSyntax != 6) {
+		return LDB_SUCCESS;
+	}
+
+	if (valp) {
+		p2 = memchr(valp->data, '.', valp->length);
+	} else {
+		p2 = NULL;
+	}
+
+	if (!p2) {
+		return LDB_SUCCESS;
+	}
+
+	switch (a->attributeID_id) {
+	case DRSUAPI_ATTRIBUTE_objectClass:
+	case DRSUAPI_ATTRIBUTE_subClassOf:
+	case DRSUAPI_ATTRIBUTE_auxiliaryClass:
+	case DRSUAPI_ATTRIBUTE_systemPossSuperiors:
+	case DRSUAPI_ATTRIBUTE_possSuperiors:
+		str = talloc_strndup(schema, (char *)valp->data, valp->length);
+		if (!str) {
+			ldb_oom(ldb);
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
+		vo = dsdb_class_by_governsID_oid(schema, str);
+		talloc_free(str);
+		if (!vo) {
+			return LDB_SUCCESS;
+		}
+		*valp = data_blob_string_const(vo->lDAPDisplayName);
+		return LDB_SUCCESS;
+	case DRSUAPI_ATTRIBUTE_systemMustContain:
+	case DRSUAPI_ATTRIBUTE_systemMayContain:
+	case DRSUAPI_ATTRIBUTE_mustContain:
+	case DRSUAPI_ATTRIBUTE_mayContain:
+		str = talloc_strndup(schema, (char *)valp->data, valp->length);
+		if (!str) {
+			ldb_oom(ldb);
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
+		va = dsdb_attribute_by_attributeID_oid(schema, str);
+		talloc_free(str);
+		if (!va) {
+			return LDB_SUCCESS;
+		}
+		*valp = data_blob_string_const(va->lDAPDisplayName);
+		return LDB_SUCCESS;
+	case DRSUAPI_ATTRIBUTE_governsID:
+	case DRSUAPI_ATTRIBUTE_attributeID:
+	case DRSUAPI_ATTRIBUTE_attributeSyntax:
+		return LDB_SUCCESS;
+	}
+
+	return LDB_SUCCESS;
+}
+
+static int resolve_oids_parse_tree_replace(struct ldb_context *ldb,
+					   struct dsdb_schema *schema,
+					   struct ldb_parse_tree *tree)
+{
+	int i;
+	const struct dsdb_attribute *a = NULL;
+	const char **attrp;
+	const char *p1;
+	const void *p2;
+	struct ldb_val *valp = NULL;
+
+	switch (tree->operation) {
+	case LDB_OP_AND:
+	case LDB_OP_OR:
+		for (i=0;i<tree->u.list.num_elements;i++) {
+			resolve_oids_parse_tree_replace(ldb, schema,
+							tree->u.list.elements[i]);
+		}
+		return LDB_SUCCESS;
+	case LDB_OP_NOT:
+		resolve_oids_parse_tree_replace(ldb, schema,
+						tree->u.isnot.child);
+		return LDB_SUCCESS;
+	case LDB_OP_EQUALITY:
+	case LDB_OP_GREATER:
+	case LDB_OP_LESS:
+	case LDB_OP_APPROX:
+		attrp = &tree->u.equality.attr;
+		valp = &tree->u.equality.value;
+		break;
+	case LDB_OP_SUBSTRING:
+		attrp = &tree->u.substring.attr;
+		break;
+	case LDB_OP_PRESENT:
+		attrp = &tree->u.present.attr;
+		break;
+	case LDB_OP_EXTENDED:
+		attrp = &tree->u.extended.attr;
+		valp = &tree->u.extended.value;
+		break;
+	default:
+		return LDB_SUCCESS;
+	}
+
+	p1 = strchr(*attrp, '.');
+
+	if (valp) {
+		p2 = memchr(valp->data, '.', valp->length);
+	} else {
+		p2 = NULL;
+	}
+
+	if (!p1 && !p2) {
+		return LDB_SUCCESS;
+	}
+
+	if (p1) {
+		a = dsdb_attribute_by_attributeID_oid(schema, *attrp);
+	} else {
+		a = dsdb_attribute_by_lDAPDisplayName(schema, *attrp);
+	}
+	if (!a) {
+		return LDB_SUCCESS;
+	}
+
+	*attrp = a->lDAPDisplayName;
+
+	if (!p2) {
+		return LDB_SUCCESS;
+	}
+
+	if (a->syntax->oMSyntax != 6) {
+		return LDB_SUCCESS;
+	}
+
+	return resolve_oids_replace_value(ldb, schema, a, valp);
+}
+
+static int resolve_oids_element_replace(struct ldb_context *ldb,
+					struct dsdb_schema *schema,
+					struct ldb_message_element *el)
+{
+	int i;
+	const struct dsdb_attribute *a = NULL;
+	const char *p1;
+
+	p1 = strchr(el->name, '.');
+
+	if (p1) {
+		a = dsdb_attribute_by_attributeID_oid(schema, el->name);
+	} else {
+		a = dsdb_attribute_by_lDAPDisplayName(schema, el->name);
+	}
+	if (!a) {
+		return LDB_SUCCESS;
+	}
+
+	el->name = a->lDAPDisplayName;
+
+	for (i=0; i < el->num_values; i++) {
+		int ret;
+		ret = resolve_oids_replace_value(ldb, schema, a,
+						 &el->values[i]);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+	}
+
+	return LDB_SUCCESS;
+}
+
+static int resolve_oids_message_replace(struct ldb_context *ldb,
+					struct dsdb_schema *schema,
+					struct ldb_message *msg)
+{
+	int i;
+
+	for (i=0; i < msg->num_elements; i++) {
+		int ret;
+		ret = resolve_oids_element_replace(ldb, schema,
+						   &msg->elements[i]);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+	}
+
+	return LDB_SUCCESS;
+}
+
+struct resolve_oids_context {
+	struct ldb_module *module;
+	struct ldb_request *req;
+};
+
+static int resolve_oids_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+	struct ldb_context *ldb;
+	struct resolve_oids_context *ac;
+
+	ac = talloc_get_type_abort(req->context, struct resolve_oids_context);
+	ldb = ldb_module_get_ctx(ac->module);
+
+	if (!ares) {
+		return ldb_module_done(ac->req, NULL, NULL,
+					LDB_ERR_OPERATIONS_ERROR);
+	}
+	if (ares->error != LDB_SUCCESS) {
+		return ldb_module_done(ac->req, ares->controls,
+					ares->response, ares->error);
+	}
+
+	switch (ares->type) {
+	case LDB_REPLY_ENTRY:
+		return ldb_module_send_entry(ac->req, ares->message, ares->controls);
+
+	case LDB_REPLY_REFERRAL:
+		return ldb_module_send_referral(ac->req, ares->referral);
+
+	case LDB_REPLY_DONE:
+		return ldb_module_done(ac->req, ares->controls,
+				       ares->response, LDB_SUCCESS);
+
+	}
+	return LDB_SUCCESS;
+}
+
+static int resolve_oids_search(struct ldb_module *module, struct ldb_request *req)
+{
+	struct ldb_context *ldb;
+	struct dsdb_schema *schema;
+	struct ldb_parse_tree *tree;
+	struct ldb_request *down_req;
+	struct resolve_oids_context *ac;
+	int ret;
+
+	ldb = ldb_module_get_ctx(module);
+	schema = dsdb_get_schema(ldb);
+
+	if (!schema) {
+		return ldb_next_request(module, req);
+	}
+
+	/* do not manipulate our control entries */
+	if (ldb_dn_is_special(req->op.search.base)) {
+		return ldb_next_request(module, req);
+	}
+
+	ac = talloc(req, struct resolve_oids_context);
+	if (ac == NULL) {
+		ldb_oom(ldb);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+	ac->module = module;
+	ac->req = req;
+
+	tree = ldb_parse_tree_copy_shallow(ac, req->op.search.tree);
+	if (!tree) {
+		ldb_oom(ldb);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	ret = resolve_oids_parse_tree_replace(ldb, schema,
+					      tree);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	ret = ldb_build_search_req_ex(&down_req, ldb, ac,
+				      req->op.search.base,
+				      req->op.search.scope,
+				      tree,
+				      req->op.search.attrs,
+				      req->controls,
+				      ac, resolve_oids_callback,
+				      req);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	/* go on with the call chain */
+	return ldb_next_request(module, down_req);
+}
+
+static int resolve_oids_add(struct ldb_module *module, struct ldb_request *req)
+{
+	struct ldb_context *ldb;
+	struct dsdb_schema *schema;
+	int ret;
+	struct ldb_message *msg;
+	struct ldb_request *down_req;
+	struct resolve_oids_context *ac;
+
+	ldb = ldb_module_get_ctx(module);
+	schema = dsdb_get_schema(ldb);
+
+	if (!schema) {
+		return ldb_next_request(module, req);
+	}
+
+	/* do not manipulate our control entries */
+	if (ldb_dn_is_special(req->op.add.message->dn)) {
+		return ldb_next_request(module, req);
+	}
+
+	ac = talloc(req, struct resolve_oids_context);
+	if (ac == NULL) {
+		ldb_oom(ldb);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+	ac->module = module;
+	ac->req = req;
+
+	msg = ldb_msg_copy_shallow(ac, ac->req->op.add.message);
+	if (!msg) {
+		ldb_oom(ldb);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	ret = resolve_oids_message_replace(ldb, schema, msg);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	ret = ldb_build_add_req(&down_req, ldb, ac,
+				msg,
+				req->controls,
+				ac, resolve_oids_callback,
+				req);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	/* go on with the call chain */
+	return ldb_next_request(module, down_req);
+}
+
+static int resolve_oids_modify(struct ldb_module *module, struct ldb_request *req)
+{
+	struct ldb_context *ldb;
+	struct dsdb_schema *schema;
+	int ret;
+	struct ldb_message *msg;
+	struct ldb_request *down_req;
+	struct resolve_oids_context *ac;
+
+	ldb = ldb_module_get_ctx(module);
+	schema = dsdb_get_schema(ldb);
+
+	if (!schema) {
+		return ldb_next_request(module, req);
+	}
+
+	/* do not manipulate our control entries */
+	if (ldb_dn_is_special(req->op.mod.message->dn)) {
+		return ldb_next_request(module, req);
+	}
+
+	ac = talloc(req, struct resolve_oids_context);
+	if (ac == NULL) {
+		ldb_oom(ldb);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+	ac->module = module;
+	ac->req = req;
+
+	/* we have to copy the message as the caller might have it as a const */
+	msg = ldb_msg_copy_shallow(ac, req->op.mod.message);
+	if (msg == NULL) {
+		ldb_oom(ldb);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	ret = resolve_oids_message_replace(ldb, schema, msg);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	ret = ldb_build_mod_req(&down_req, ldb, ac,
+				msg,
+				req->controls,
+				ac, resolve_oids_callback,
+				req);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	/* go on with the call chain */
+	return ldb_next_request(module, down_req);
+}
+
+_PUBLIC_ const struct ldb_module_ops ldb_resolve_oids_module_ops = {
+	.name		= "resolve_oids",
+	.search		= resolve_oids_search,
+	.add		= resolve_oids_add,
+	.modify		= resolve_oids_modify,
+};
+
diff --git a/source4/lib/ldb/common/ldb_parse.c b/source4/lib/ldb/common/ldb_parse.c
index 0fab002..7f347c5 100644
--- a/source4/lib/ldb/common/ldb_parse.c
+++ b/source4/lib/ldb/common/ldb_parse.c
@@ -818,3 +818,61 @@ void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree,
 		break;
 	}
 }
+
+/*
+  shallow copy a tree - copying only the elements array so that the caller
+  can safely add new elements without changing the message
+*/
+struct ldb_parse_tree *ldb_parse_tree_copy_shallow(TALLOC_CTX *mem_ctx,
+						   const struct ldb_parse_tree *ot)
+{
+	int i;
+	struct ldb_parse_tree *nt;
+
+	nt = talloc(mem_ctx, struct ldb_parse_tree);
+	if (!nt) {
+		return NULL;
+	}
+
+	*nt = *ot;
+
+	switch (ot->operation) {
+	case LDB_OP_AND:
+	case LDB_OP_OR:
+		nt->u.list.elements = talloc_array(nt, struct ldb_parse_tree,
+						   ot->u.list.num_elements);
+		if (!nt->u.list.elements) {
+			talloc_free(nt);
+			return NULL;
+		}
+
+		for (i=0;i<ot->u.list.num_elements;i++) {
+			nt->u.list.elements[i] =
+				ldb_parse_tree_copy_shallow(nt->u.list.elements,
+						ot->u.list.elements[i]);
+			if (!nt->u.list.elements[i]) {
+				talloc_free(nt);
+				return NULL;
+			}
+		}
+		break;
+	case LDB_OP_NOT:
+		nt->u.isnot.child = ldb_parse_tree_copy_shallow(nt,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list