[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-1943-gc021330

Andrew Tridgell tridge at samba.org
Mon Jun 1 06:44:01 GMT 2009


The branch, master has been updated
       via  c0213308bbde59270f681ce7c55a44bda34a980f (commit)
       via  ce1045983fd294b95dfe91524b5d8b80a35df448 (commit)
       via  5a39817212aa34ef181e9ed72851b077ba088260 (commit)
      from  ae1c2415e23b56db7ffb8dc96425a8588401b03d (commit)

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


- Log -----------------------------------------------------------------
commit c0213308bbde59270f681ce7c55a44bda34a980f
Author: Andrew Tridgell <tridge at samba.org>
Date:   Mon Jun 1 16:37:28 2009 +1000

    we don't need the unique checks in the samldb code now
    
    These attributes now use the unique indexing flag

commit ce1045983fd294b95dfe91524b5d8b80a35df448
Author: Andrew Tridgell <tridge at samba.org>
Date:   Mon Jun 1 16:36:56 2009 +1000

    mark samAccountName, objectGUID and objectSID as unique indexed

commit 5a39817212aa34ef181e9ed72851b077ba088260
Author: Andrew Tridgell <tridge at samba.org>
Date:   Mon Jun 1 16:36:21 2009 +1000

    added support for unique indexing in ldb
    
    When a attribute is marked as LDB_ATTR_FLAG_UNIQUE_INDEX then attempts
    to add a 2nd record that has the same attribute value for this
    attribute as another record will fail.
    
    This provides a much more efficient mechanism for ensuring that
    attributes like objectGUID are unique

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

Summary of changes:
 source4/dsdb/samdb/ldb_modules/samldb.c |  164 +------------------------------
 source4/dsdb/schema/schema_init.c       |   20 ++++
 source4/lib/ldb/include/ldb.h           |    6 +
 source4/lib/ldb/ldb_tdb/ldb_index.c     |   33 +++++--
 4 files changed, 54 insertions(+), 169 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 65e3641..dad5ff2 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -466,91 +466,19 @@ static int samldb_generate_samAccountName(struct ldb_message *msg)
 	return ldb_msg_add_steal_string(msg, "samAccountName", name);
 }
 
-static int samldb_check_samAccountName_callback(struct ldb_request *req,
-						struct ldb_reply *ares)
-{
-	struct samldb_ctx *ac;
-	int ret;
-
-	ac = talloc_get_type(req->context, struct samldb_ctx);
-
-	if (!ares) {
-		ret = LDB_ERR_OPERATIONS_ERROR;
-		goto done;
-	}
-	if (ares->error != LDB_SUCCESS) {
-		return ldb_module_done(ac->req, ares->controls,
-					ares->response, ares->error);
-	}
-
-	switch (ares->type) {
-	case LDB_REPLY_ENTRY:
-
-		/* if we get an entry it means this samAccountName
-		 * already exists */
-		return ldb_module_done(ac->req, NULL, NULL,
-					LDB_ERR_ENTRY_ALREADY_EXISTS);
-
-	case LDB_REPLY_REFERRAL:
-		/* ignore */
-		talloc_free(ares);
-		ret = LDB_SUCCESS;
-		break;
-
-	case LDB_REPLY_DONE:
-
-		/* not found, go on */
-		talloc_free(ares);
-		ret = samldb_next_step(ac);
-		break;
-	}
-
-done:
-	if (ret != LDB_SUCCESS) {
-		return ldb_module_done(ac->req, NULL, NULL, ret);
-	}
-
-	return LDB_SUCCESS;
-}
 
 static int samldb_check_samAccountName(struct samldb_ctx *ac)
 {
-	struct ldb_context *ldb;
-	struct ldb_request *req;
-	const char *name;
-	char *filter;
 	int ret;
 
-	ldb = ldb_module_get_ctx(ac->module);
-
 	if (ldb_msg_find_element(ac->msg, "samAccountName") == NULL) {
 		ret = samldb_generate_samAccountName(ac->msg);
 		if (ret != LDB_SUCCESS) {
 			return ret;
 		}
 	}
-
-	name = ldb_msg_find_attr_as_string(ac->msg, "samAccountName", NULL);
-	if (name == NULL) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-	filter = talloc_asprintf(ac, "samAccountName=%s", name);
-	if (filter == NULL) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-
-	ret = ldb_build_search_req(&req, ldb, ac,
-				ac->domain_dn, LDB_SCOPE_SUBTREE,
-				filter, NULL,
-				NULL,
-				ac, samldb_check_samAccountName_callback,
-				ac->req);
-	talloc_free(filter);
-	if (ret != LDB_SUCCESS) {
-		return ret;
-	}
-	ac->ares = NULL;
-	return ldb_next_request(ac->module, req);
+	
+	return samldb_next_step(ac);
 }
 
 static int samldb_check_samAccountType(struct samldb_ctx *ac)
@@ -768,87 +696,6 @@ static int samldb_new_sid(struct samldb_ctx *ac)
 	return samldb_next_step(ac);
 }
 
-static int samldb_check_sid_callback(struct ldb_request *req,
-				     struct ldb_reply *ares)
-{
-	struct samldb_ctx *ac;
-	int ret;
-
-	ac = talloc_get_type(req->context, struct samldb_ctx);
-
-	if (!ares) {
-		ret = LDB_ERR_OPERATIONS_ERROR;
-		goto done;
-	}
-	if (ares->error != LDB_SUCCESS) {
-		return ldb_module_done(ac->req, ares->controls,
-					ares->response, ares->error);
-	}
-
-	switch (ares->type) {
-	case LDB_REPLY_ENTRY:
-
-		/* if we get an entry it means an object with the
-		 * requested sid exists */
-		return ldb_module_done(ac->req, NULL, NULL,
-					LDB_ERR_CONSTRAINT_VIOLATION);
-
-	case LDB_REPLY_REFERRAL:
-		/* ignore */
-		talloc_free(ares);
-		break;
-
-	case LDB_REPLY_DONE:
-
-		/* not found, go on */
-		talloc_free(ares);
-		ret = samldb_next_step(ac);
-		break;
-	}
-
-done:
-	if (ret != LDB_SUCCESS) {
-		return ldb_module_done(ac->req, NULL, NULL, ret);
-	}
-
-	return LDB_SUCCESS;
-}
-
-static int samldb_check_sid(struct samldb_ctx *ac)
-{
-	struct ldb_context *ldb;
-	const char *const attrs[2] = { "objectSid", NULL };
-	struct ldb_request *req;
-	char *filter;
-	int ret;
-
-	if (ac->sid == NULL) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-
-	ldb = ldb_module_get_ctx(ac->module);
-
-	filter = talloc_asprintf(ac, "(objectSid=%s)",
-				 ldap_encode_ndr_dom_sid(ac, ac->sid));
-	if (filter == NULL) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-
-	ret = ldb_build_search_req(&req, ldb, ac,
-				   ldb_get_default_basedn(ldb),
-				   LDB_SCOPE_SUBTREE,
-				   filter, attrs,
-				   NULL,
-				   ac, samldb_check_sid_callback,
-				   ac->req);
-
-	if (ret != LDB_SUCCESS) {
-		return ret;
-	}
-
-	return ldb_next_request(ac->module, req);
-}
-
 static int samldb_notice_sid_callback(struct ldb_request *req,
 					struct ldb_reply *ares)
 {
@@ -1051,9 +898,6 @@ static int samldb_fill_object(struct samldb_ctx *ac, const char *type)
 		if (ret != LDB_SUCCESS) return ret;
 	}
 
-	ret = samldb_add_step(ac, samldb_check_sid);
-	if (ret != LDB_SUCCESS) return ret;
-
 	ret = samldb_add_step(ac, samldb_notice_sid);
 	if (ret != LDB_SUCCESS) return ret;
 
@@ -1228,10 +1072,6 @@ static int samldb_fill_foreignSecurityPrincipal_object(struct samldb_ctx *ac)
 	ret = samldb_add_step(ac, samldb_apply_template);
 	if (ret != LDB_SUCCESS) return ret;
 
-	/* check we do not already have this SID */
-	ret = samldb_add_step(ac, samldb_check_sid);
-	if (ret != LDB_SUCCESS) return ret;
-
 	/* check if we need to notice this SID */
 	ret = samldb_add_step(ac, samldb_foreign_notice_sid);
 	if (ret != LDB_SUCCESS) return ret;
diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c
index 3a65c47..76e7891 100644
--- a/source4/dsdb/schema/schema_init.c
+++ b/source4/dsdb/schema/schema_init.c
@@ -583,6 +583,22 @@ WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
 	return WERR_OK;
 }
 
+/*
+  this will be replaced with something that looks at the right part of
+  the schema once we know where unique indexing information is hidden
+ */
+static bool dsdb_schema_unique_attribute(const char *attr)
+{
+	const char *attrs[] = { "samAccountName", "objectGUID", "objectSID" , NULL };
+	int i;
+	for (i=0;attrs[i];i++) {
+		if (strcasecmp(attr, attrs[i]) == 0) {
+			return true;
+		}
+	}
+	return false;
+}
+
 
 /*
   setup the ldb_schema_attribute field for a dsdb_attribute
@@ -619,6 +635,10 @@ static int dsdb_schema_setup_ldb_schema_attribute(struct ldb_context *ldb,
 	a->name = attr->lDAPDisplayName;
 	a->flags = 0;
 	a->syntax = s;
+
+	if (dsdb_schema_unique_attribute(a->name)) {
+		a->flags |= LDB_ATTR_FLAG_UNIQUE_INDEX;
+	}
 	
 	return LDB_SUCCESS;
 }
diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h
index 1b6b41a..8e4e2e0 100644
--- a/source4/lib/ldb/include/ldb.h
+++ b/source4/lib/ldb/include/ldb.h
@@ -375,6 +375,12 @@ const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_c
 */
 #define LDB_ATTR_FLAG_FIXED        (1<<2) 
 
+/*
+  when this is set, attempts to create two records which have the same
+  value for this attribute will return LDB_ERR_ENTRY_ALREADY_EXISTS
+ */
+#define LDB_ATTR_FLAG_UNIQUE_INDEX (1<<3)
+
 /**
   LDAP attribute syntax for a DN
 
diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c
index db0c315..300cf7c 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_index.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_index.c
@@ -426,7 +426,8 @@ struct dn_list {
   caller frees
 */
 static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
-				     const char *attr, const struct ldb_val *value)
+				     const char *attr, const struct ldb_val *value,
+				     const struct ldb_schema_attribute **ap)
 {
 	struct ldb_dn *ret;
 	struct ldb_val v;
@@ -440,6 +441,9 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
 	}
 
 	a = ldb_schema_attribute_by_name(ldb, attr);
+	if (ap) {
+		*ap = a;
+	}
 	r = a->syntax->canonicalise_fn(ldb, ldb, value, &v);
 	if (r != LDB_SUCCESS) {
 		const char *errstr = ldb_errstring(ldb);
@@ -531,7 +535,7 @@ static int ltdb_index_dn_simple(struct ldb_module *module,
 
 	/* the attribute is indexed. Pull the list of DNs that match the 
 	   search criterion */
-	dn = ltdb_index_key(ldb, tree->u.equality.attr, &tree->u.equality.value);
+	dn = ltdb_index_key(ldb, tree->u.equality.attr, &tree->u.equality.value, NULL);
 	if (!dn) return LDB_ERR_OPERATIONS_ERROR;
 
 	msg = talloc(list, struct ldb_message);
@@ -851,6 +855,11 @@ static int ltdb_index_dn_and(struct ldb_module *module,
 			talloc_free(list->dn);
 			return LDB_ERR_NO_SUCH_OBJECT;
 		}
+
+		if (list->count == 1) {
+			/* it isn't worth loading the next part of the tree */
+			break;
+		}
 	}
 
 	return ret;
@@ -882,7 +891,7 @@ static int ltdb_index_dn_one(struct ldb_module *module,
 	   search criterion */
 	val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(parent_dn));
 	val.length = strlen((char *)val.data);
-	key = ltdb_index_key(ldb, LTDB_IDXONE, &val);
+	key = ltdb_index_key(ldb, LTDB_IDXONE, &val, NULL);
 	if (!key) {
 		talloc_free(list2);
 		return LDB_ERR_OPERATIONS_ERROR;
@@ -1181,7 +1190,8 @@ static int ltdb_index_add1_new(struct ldb_context *ldb,
 static int ltdb_index_add1_add(struct ldb_context *ldb,
 			       struct ldb_message *msg,
 			       int idx,
-			       const char *dn)
+			       const char *dn,
+			       const struct ldb_schema_attribute *a)
 {
 	struct ldb_val *v2;
 	unsigned int i;
@@ -1193,6 +1203,10 @@ static int ltdb_index_add1_add(struct ldb_context *ldb,
 		}
 	}
 
+	if (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) {
+		return LDB_ERR_ENTRY_ALREADY_EXISTS;
+	}
+
 	v2 = talloc_realloc(msg->elements, msg->elements[idx].values,
 			      struct ldb_val,
 			      msg->elements[idx].num_values+1);
@@ -1219,6 +1233,7 @@ static int ltdb_index_add1(struct ldb_module *module, const char *dn,
 	struct ldb_dn *dn_key;
 	int ret;
 	unsigned int i;
+	const struct ldb_schema_attribute *a;
 
 	ldb = ldb_module_get_ctx(module);
 
@@ -1228,7 +1243,7 @@ static int ltdb_index_add1(struct ldb_module *module, const char *dn,
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx]);
+	dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], &a);
 	if (!dn_key) {
 		talloc_free(msg);
 		return LDB_ERR_OPERATIONS_ERROR;
@@ -1256,7 +1271,7 @@ static int ltdb_index_add1(struct ldb_module *module, const char *dn,
 	if (i == msg->num_elements) {
 		ret = ltdb_index_add1_new(ldb, msg, dn);
 	} else {
-		ret = ltdb_index_add1_add(ldb, msg, i, dn);
+		ret = ltdb_index_add1_add(ldb, msg, i, dn, a);
 	}
 
 	if (ret == LDB_SUCCESS) {
@@ -1339,7 +1354,7 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn,
 		return LDB_SUCCESS;
 	}
 
-	dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx]);
+	dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], NULL);
 	if (!dn_key) {
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
@@ -1455,6 +1470,10 @@ int ltdb_index_one(struct ldb_module *module, const struct ldb_message *msg, int
 	const char *dn;
 	int ret;
 
+	if (ldb_dn_is_special(msg->dn)) {
+		return LDB_SUCCESS;
+	}
+
 	/* We index for ONE Level only if requested */
 	ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, NULL, LTDB_IDXONE);
 	if (ret != 0) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list