[SCM] Samba Shared Repository - branch master updated - tevent-0-9-8-623-gf54ef5f

Andrew Bartlett abartlet at samba.org
Mon Sep 21 23:36:38 MDT 2009


The branch, master has been updated
       via  f54ef5f20fa4809847c89ce0c393111807ca31a2 (commit)
       via  399c7160d56866725d8931a2f816de3b6a995704 (commit)
      from  9e85192e6415fbaacf394330f6e61759190485ad (commit)

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


- Log -----------------------------------------------------------------
commit f54ef5f20fa4809847c89ce0c393111807ca31a2
Author: Nadezhda Ivanova <nadezhda.ivanova at postpath.com>
Date:   Mon Sep 21 20:08:52 2009 -0700

    s4:dsdb Fix of double addition of SD-s
    
    Also add error strings in descriptor module

commit 399c7160d56866725d8931a2f816de3b6a995704
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Sep 21 19:26:59 2009 -0700

    s4:ldb Add 'single-value' support to LDB.
    
    This is currently only triggered via Samba4's schema code.

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

Summary of changes:
 source4/dsdb/samdb/ldb_modules/descriptor.c  |   34 ++++++++++++------
 source4/dsdb/samdb/ldb_modules/objectclass.c |    2 +
 source4/dsdb/schema/schema_init.c            |    4 ++
 source4/lib/ldb/include/ldb.h                |    5 +++
 source4/lib/ldb/ldb_tdb/ldb_tdb.c            |   49 ++++++++++++++++++++++++-
 5 files changed, 81 insertions(+), 13 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c
index b0a5467..544fb8c 100644
--- a/source4/dsdb/samdb/ldb_modules/descriptor.c
+++ b/source4/dsdb/samdb/ldb_modules/descriptor.c
@@ -57,9 +57,9 @@ static const struct dsdb_class * get_last_structural_class(const struct dsdb_sch
 	const struct dsdb_class *last_class = NULL;
 	int i;
 	for (i = 0; i < element->num_values; i++){
-		if (!last_class)
+		if (!last_class) {
 			last_class = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &element->values[i]);
-		else {
+		} else {
 			const struct dsdb_class *tmp_class = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &element->values[i]);
 			if (tmp_class->subClass_order > last_class->subClass_order)
 				last_class = tmp_class;
@@ -169,7 +169,7 @@ static DATA_BLOB *get_new_descriptor(struct ldb_module *module,
 	struct dom_sid *default_owner;
 	struct dom_sid *default_group;
 
-	if (object){
+	if (object) {
 		user_descriptor = talloc(mem_ctx, struct security_descriptor);
 		if(!user_descriptor)
 			return NULL;
@@ -181,9 +181,9 @@ static DATA_BLOB *get_new_descriptor(struct ldb_module *module,
 			talloc_free(user_descriptor);
 			return NULL;
 		}
-	}
-	else
+	} else {
 		user_descriptor = get_sd_unpacked(module, mem_ctx, objectclass);
+	}
 
 	if (parent){
 		parent_descriptor = talloc(mem_ctx, struct security_descriptor);
@@ -267,6 +267,8 @@ static int get_search_callback(struct ldb_request *req, struct ldb_reply *ares)
 					ares->response, ares->error);
 	}
 
+	ldb_reset_err_string(ldb);
+
 	switch (ares->type) {
 	case LDB_REPLY_ENTRY:
 		if (ac->search_res != NULL) {
@@ -349,32 +351,42 @@ static int descriptor_do_add(struct descriptor_context *ac)
 	objectclass_element = ldb_msg_find_element(msg, "objectClass");
 	objectclass = get_last_structural_class(schema, objectclass_element);
 
-	if (!objectclass)
+	if (!objectclass) {
+		ldb_asprintf_errstring(ldb, "No last structural objectclass found on %s", ldb_dn_get_linearized(msg->dn));
 		return LDB_ERR_OPERATIONS_ERROR;
+	}
 
 	if (sd_element)
 		sd_val = &sd_element->values[0];
 	/* NC's have no parent */
 	if ((ldb_dn_compare(msg->dn, (ldb_get_schema_basedn(ldb))) == 0) ||
-			(ldb_dn_compare(msg->dn, (ldb_get_config_basedn(ldb))) == 0) ||
-			(ldb_dn_compare(msg->dn, (ldb_get_root_basedn(ldb))) == 0))
+	    (ldb_dn_compare(msg->dn, (ldb_get_config_basedn(ldb))) == 0) ||
+	    (ldb_dn_compare(msg->dn, (ldb_get_root_basedn(ldb))) == 0)) {
 		parentsd_val = NULL;
-	else if (ac->search_res != NULL)
+	} else if (ac->search_res != NULL){
 		parentsd_val = ldb_msg_find_ldb_val(ac->search_res->message, "nTSecurityDescriptor");
-
+	}
 
 	/* get the parent descriptor and the one provided. If not provided, get the default.*/
 	/* convert to security descriptor and calculate */
 	sd = get_new_descriptor(ac->module, msg->dn, mem_ctx, objectclass,
 			parentsd_val, sd_val);
+	if (sd_val) {
+		ldb_msg_remove_attr(msg, "nTSecurityDescriptor");
+	}
+
 	if (sd) {
-		ldb_msg_add_steal_value(msg, "nTSecurityDescriptor", sd);
+		ret = ldb_msg_add_steal_value(msg, "nTSecurityDescriptor", sd);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
 	}
 
 	talloc_free(mem_ctx);
 	ret = ldb_msg_sanity_check(ldb, msg);
 
 	if (ret != LDB_SUCCESS) {
+		ldb_asprintf_errstring(ldb, "No last structural objectclass found on %s", ldb_dn_get_linearized(msg->dn));
 		return ret;
 	}
 
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index 0246de1..3cf252c 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -250,6 +250,8 @@ static int get_search_callback(struct ldb_request *req, struct ldb_reply *ares)
 					ares->response, ares->error);
 	}
 
+	ldb_reset_err_string(ldb);
+
 	switch (ares->type) {
 	case LDB_REPLY_ENTRY:
 		if (ac->search_res != NULL) {
diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c
index fa1953a..8bb54f4 100644
--- a/source4/dsdb/schema/schema_init.c
+++ b/source4/dsdb/schema/schema_init.c
@@ -653,6 +653,10 @@ static int dsdb_schema_setup_ldb_schema_attribute(struct ldb_context *ldb,
 	if (dsdb_schema_unique_attribute(a->name)) {
 		a->flags |= LDB_ATTR_FLAG_UNIQUE_INDEX;
 	}
+	if (attr->isSingleValued) {
+		a->flags |= LDB_ATTR_FLAG_SINGLE_VALUE;
+	}
+	
 	
 	return LDB_SUCCESS;
 }
diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h
index 0378697..fa531b2 100644
--- a/source4/lib/ldb/include/ldb.h
+++ b/source4/lib/ldb/include/ldb.h
@@ -392,6 +392,11 @@ const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_c
  */
 #define LDB_ATTR_FLAG_UNIQUE_INDEX (1<<3)
 
+/*
+  when this is set, attempts to create two attribute values for this attribute on a single DN will return LDB_ERR_CONSTRAINT_VIOLATION
+ */
+#define LDB_ATTR_FLAG_SINGLE_VALUE (1<<4)
+
 /**
   LDAP attribute syntax for a DN
 
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index d4f7b45..e569a5a 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -254,7 +254,7 @@ static int ltdb_add_internal(struct ldb_module *module,
 			     const struct ldb_message *msg)
 {
 	struct ldb_context *ldb = ldb_module_get_ctx(module);
-	int ret;
+	int ret, i;
 
 	ret = ltdb_check_special_dn(module, msg);
 	if (ret != LDB_SUCCESS) {
@@ -265,6 +265,24 @@ static int ltdb_add_internal(struct ldb_module *module,
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
+	for (i=0;i<msg->num_elements;i++) {
+		struct ldb_message_element *el = &msg->elements[i];
+		const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
+
+		if (el->num_values == 0) {
+			ldb_asprintf_errstring(ldb, "attribute %s on %s speicified, but with 0 values (illigal)", 
+					       el->name, ldb_dn_get_linearized(msg->dn));
+			return LDB_ERR_CONSTRAINT_VIOLATION;
+		}
+		if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
+			if (el->num_values > 1) {
+				ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once", 
+						       el->name, ldb_dn_get_linearized(msg->dn));
+				return LDB_ERR_CONSTRAINT_VIOLATION;
+			}
+		}
+	}
+
 	ret = ltdb_store(module, msg, TDB_INSERT);
 
 	if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
@@ -602,15 +620,28 @@ int ltdb_modify_internal(struct ldb_module *module,
 		struct ldb_message_element *el2;
 		struct ldb_val *vals;
 		const char *dn;
-
+		const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
 		switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
 
 		case LDB_FLAG_MOD_ADD:
+			
 			/* add this element to the message. fail if it
 			   already exists */
 			idx = find_element(msg2, el->name);
 
+			if (el->num_values == 0) {
+				ldb_asprintf_errstring(ldb, "attribute %s on %s speicified, but with 0 values (illigal)", 
+						  el->name, ldb_dn_get_linearized(msg->dn));
+				return LDB_ERR_CONSTRAINT_VIOLATION;
+			}
 			if (idx == -1) {
+				if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
+					if (el->num_values > 1) {
+						ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once", 
+							       el->name, ldb_dn_get_linearized(msg->dn));
+						return LDB_ERR_CONSTRAINT_VIOLATION;
+					}
+				}
 				if (msg_add_element(ldb, msg2, el) != 0) {
 					ret = LDB_ERR_OTHER;
 					goto failed;
@@ -618,6 +649,13 @@ int ltdb_modify_internal(struct ldb_module *module,
 				continue;
 			}
 
+			/* If this is an add, then if it already
+			 * exists in the object, then we violoate the
+			 * single-value rule */
+			if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
+				return LDB_ERR_CONSTRAINT_VIOLATION;
+			}
+
 			el2 = &msg2->elements[idx];
 
 			/* An attribute with this name already exists,
@@ -657,6 +695,13 @@ int ltdb_modify_internal(struct ldb_module *module,
 			break;
 
 		case LDB_FLAG_MOD_REPLACE:
+			if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
+				if (el->num_values > 1) {
+					ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once", 
+							       el->name, ldb_dn_get_linearized(msg->dn));
+					return LDB_ERR_CONSTRAINT_VIOLATION;
+				}
+			}
 			/* replace all elements of this attribute name with the elements
 			   listed. The attribute not existing is not an error */
 			msg_delete_attribute(module, ldb, msg2, el->name);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list