[PATCH] ldb: add relax control to allow to specify objectGUID on ldb_add

Matthieu Patou mat at matws.net
Tue Sep 22 14:49:46 MDT 2009


---
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c |   43 ++++++++++++++++++++---
 source4/lib/ldb/common/ldb_controls.c           |   27 ++++++++++++++
 source4/lib/ldb/include/ldb.h                   |    8 ++++
 3 files changed, 73 insertions(+), 5 deletions(-)

diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index fa8bd64..cf148ec 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -435,12 +435,15 @@ static int replmd_op_callback(struct ldb_request *req, struct ldb_reply *ares)
 static int replmd_add(struct ldb_module *module, struct ldb_request *req)
 {
 	struct ldb_context *ldb;
+        struct ldb_control *control;
+        struct ldb_control **saved_controls;
 	struct replmd_replicated_request *ac;
 	const struct dsdb_schema *schema;
 	enum ndr_err_code ndr_err;
 	struct ldb_request *down_req;
 	struct ldb_message *msg;
 	const struct dsdb_attribute *rdn_attr = NULL;
+        const DATA_BLOB *guid_blob;
 	struct GUID guid;
 	struct ldb_val guid_value;
 	struct replPropertyMetaDataBlob nmd;
@@ -452,6 +455,14 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
 	char *time_str;
 	int ret;
 	uint32_t i, ni=0;
+	int allow_add_guid=0;
+	int remove_current_guid=0;
+
+        /* check if there's a show deleted control */
+        control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID);
+	if (control) {
+		allow_add_guid = 1;
+	}
 
 	/* do not manipulate our control entries */
 	if (ldb_dn_is_special(req->op.add.message->dn)) {
@@ -476,10 +487,26 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
 
 	ac->schema = schema;
 
-	if (ldb_msg_find_element(req->op.add.message, "objectGUID") != NULL) {
-		ldb_debug_set(ldb, LDB_DEBUG_ERROR,
+        guid_blob = ldb_msg_find_ldb_val(req->op.add.message, "objectGUID");
+	if ( guid_blob != NULL ) {
+		if( !allow_add_guid ) {
+			ldb_debug_set(ldb, LDB_DEBUG_ERROR,
 			      "replmd_add: it's not allowed to add an object with objectGUID\n");
-		return LDB_ERR_UNWILLING_TO_PERFORM;
+			return LDB_ERR_UNWILLING_TO_PERFORM;
+		} else {
+			NTSTATUS status = GUID_from_data_blob(guid_blob,&guid);
+		        if ( !NT_STATUS_IS_OK(status)) {
+       				ldb_debug_set(ldb, LDB_DEBUG_ERROR,
+				      "replmd_add: Unable to parse as a GUID the attribute objectGUID\n");
+				return LDB_ERR_UNWILLING_TO_PERFORM;
+			}
+			/* we remove this attribute as it can be a string and will not be treated 
+			correctly and then we will readd it latter on in the good format*/
+			remove_current_guid = 1;
+		}
+	} else {
+		/* a new GUID */
+		guid = GUID_random();
 	}
 
 	/* Get a sequence number from the backend */
@@ -488,8 +515,6 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
 		return ret;
 	}
 
-	/* a new GUID */
-	guid = GUID_random();
 
 	/* get our invocationId */
 	our_invocation_id = samdb_ntds_invocation_id(ldb);
@@ -512,6 +537,9 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
 	if (!time_str) {
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
+	if (remove_current_guid) {
+		ldb_msg_remove_attr(msg,"objectGUID");
+	}
 
 	/* 
 	 * remove autogenerated attributes
@@ -652,6 +680,11 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
 		return ret;
 	}
 
+       	/* if a control is there remove if from the modified request */
+	if (control && !save_controls(control, down_req, &saved_controls)) {
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
 	/* go on with the call chain */
 	return ldb_next_request(module, down_req);
 }
diff --git a/source4/lib/ldb/common/ldb_controls.c b/source4/lib/ldb/common/ldb_controls.c
index b38373e..32b2c0f 100644
--- a/source4/lib/ldb/common/ldb_controls.c
+++ b/source4/lib/ldb/common/ldb_controls.c
@@ -407,6 +407,33 @@ struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, void *me
 			continue;
 		}
 
+		if (strncmp(control_strings[i], "relax:", 6) == 0) {
+			const char *p;
+			int crit, ret;
+
+			p = &(control_strings[i][6]);
+			ret = sscanf(p, "%d", &crit);
+			if ((ret != 1) || (crit < 0) || (crit > 1)) {
+				error_string = talloc_asprintf(mem_ctx, "invalid relax control syntax\n");
+				error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
+				error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
+				ldb_set_errstring(ldb, error_string);
+				talloc_free(error_string);
+				return NULL;
+			}
+
+			ctrl[i] = talloc(ctrl, struct ldb_control);
+			if (!ctrl[i]) {
+				ldb_oom(ldb);
+				return NULL;
+			}
+			ctrl[i]->oid = LDB_CONTROL_RELAX_OID;
+			ctrl[i]->critical = crit;
+			ctrl[i]->data = NULL;
+
+			continue;
+		}
+
 		if (strncmp(control_strings[i], "domain_scope:", 13) == 0) {
 			const char *p;
 			int crit, ret;
diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h
index fa531b2..6cf2de3 100644
--- a/source4/lib/ldb/include/ldb.h
+++ b/source4/lib/ldb/include/ldb.h
@@ -457,6 +457,14 @@ const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_c
 typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
 
 /**
+   OID for the allowing client to request temporary relaxed 
+   enforcement of constraints of the x.500 model.
+
+   \sa <a href="http://opends.dev.java.net/public/standards/draft-zeilenga-ldap-managedit.txt">draft managedit</a>.
+*/
+
+#define LDB_CONTROL_RELAX_OID "1.3.6.1.4.1.4203.666.5.12"
+/**
    OID for the paged results control. This control is included in the
    searchRequest and searchResultDone messages as part of the controls
    field of the LDAPMessage, as defined in Section 4.1.12 of
-- 
1.6.0.4


--------------000309000708070802080304--


More information about the samba-technical mailing list