[SCM] Samba Shared Repository - branch master updated

Anatoliy Atanasov anatoliy at samba.org
Tue May 4 11:18:59 MDT 2010


The branch, master has been updated
       via  efb1aea... s4/waf: ABI update for lib/ldb
       via  f84aeea... s4/rodc: Support read-only database
       via  bcdaa23... s4/rodc: Fix the callbacks up the stack to handle referrals on modify requests
      from  b57d11f... s4:py_nttime2string - removed unused variable "nt2"

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


- Log -----------------------------------------------------------------
commit efb1aea909fc088cc08b6d892d7dd1031fb79fdf
Author: Anatoliy Atanasov <anatoliy.atanasov at postpath.com>
Date:   Tue May 4 11:49:52 2010 +0200

    s4/waf: ABI update for lib/ldb

commit f84aeea7399eec38f7906dedaf3652af48c3d184
Author: Anatoliy Atanasov <anatoliy.atanasov at postpath.com>
Date:   Tue May 4 11:49:18 2010 +0200

    s4/rodc: Support read-only database
    
    Check on modify if we are RODC and return referral.
    On the ldap backend side now we pass context and ldb_modify_default_callback
    to propagate the referral error to the client.

commit bcdaa23798f74cdec8973201a849f562929ea416
Author: Anatoliy Atanasov <anatoliy.atanasov at postpath.com>
Date:   Tue May 4 11:48:18 2010 +0200

    s4/rodc: Fix the callbacks up the stack to handle referrals on modify requests

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

Summary of changes:
 source4/dsdb/common/util.c                         |    1 +
 source4/dsdb/samdb/ldb_modules/descriptor.c        |    5 +
 source4/dsdb/samdb/ldb_modules/instancetype.c      |    4 +
 source4/dsdb/samdb/ldb_modules/objectclass.c       |   10 +
 source4/dsdb/samdb/ldb_modules/partition.c         |    3 +-
 source4/dsdb/samdb/ldb_modules/password_hash.c     |   10 +
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c    |   33 ++++-
 source4/dsdb/samdb/ldb_modules/samldb.c            |   15 ++
 source4/dsdb/samdb/ldb_modules/schema_data.c       |    9 +-
 source4/dsdb/samdb/ldb_modules/subtree_rename.c    |    4 +
 source4/dsdb/samdb/ldb_modules/util.c              |   43 ++++-
 source4/ldap_server/ldap_backend.c                 |  194 ++++++++++++++++++--
 ...b-samba4-0.9.10.sigs => ldb-samba4-0.9.11.sigs} |    1 +
 source4/lib/ldb/common/ldb.c                       |   48 +++++
 source4/lib/ldb/include/ldb.h                      |    1 +
 source4/lib/ldb/modules/rdn_name.c                 |   15 ++
 source4/lib/ldb/wscript                            |    2 +-
 17 files changed, 364 insertions(+), 34 deletions(-)
 copy source4/lib/ldb/ABI/{ldb-samba4-0.9.10.sigs => ldb-samba4-0.9.11.sigs} (99%)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 771d30a..7064fcf 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -2751,6 +2751,7 @@ int samdb_is_rodc(struct ldb_context *sam_ctx, const struct GUID *objectGUID, bo
 	if (ret != LDB_SUCCESS) {
 		DEBUG(1,(("Failed to find our own NTDS Settings object by objectGUID=%s!\n"),
 			 GUID_string(tmp_ctx, objectGUID)));
+		*is_rodc = false;
 		talloc_free(tmp_ctx);
 		return ret;
 	}
diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c
index 70b02e8..8fc5e3a 100644
--- a/source4/dsdb/samdb/ldb_modules/descriptor.c
+++ b/source4/dsdb/samdb/ldb_modules/descriptor.c
@@ -490,6 +490,11 @@ static int descriptor_op_callback(struct ldb_request *req, struct ldb_reply *are
 		return ldb_module_done(ac->req, NULL, NULL,
 					LDB_ERR_OPERATIONS_ERROR);
 	}
+
+	if (ares->type == LDB_REPLY_REFERRAL) {
+		return ldb_module_send_referral(ac->req, ares->referral);
+	}
+
 	if (ares->error != LDB_SUCCESS) {
 		return ldb_module_done(ac->req, ares->controls,
 					ares->response, ares->error);
diff --git a/source4/dsdb/samdb/ldb_modules/instancetype.c b/source4/dsdb/samdb/ldb_modules/instancetype.c
index 0a297d5..7828ce1 100644
--- a/source4/dsdb/samdb/ldb_modules/instancetype.c
+++ b/source4/dsdb/samdb/ldb_modules/instancetype.c
@@ -57,6 +57,10 @@ static int it_add_callback(struct ldb_request *req, struct ldb_reply *ares)
 					LDB_ERR_OPERATIONS_ERROR);
 	}
 
+	if (ares->type == LDB_REPLY_REFERRAL) {
+		return ldb_module_send_referral(ac->req, ares->referral);
+	}
+
 	if (ares->error != LDB_SUCCESS) {
 		return ldb_module_done(ac->req, ares->controls,
 					ares->response, ares->error);
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index 329bd81..fdff3a8 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -274,6 +274,11 @@ static int oc_op_callback(struct ldb_request *req, struct ldb_reply *ares)
 		return ldb_module_done(ac->req, NULL, NULL,
 					LDB_ERR_OPERATIONS_ERROR);
 	}
+
+	if (ares->type == LDB_REPLY_REFERRAL) {
+		return ldb_module_send_referral(ac->req, ares->referral);
+	}
+
 	if (ares->error != LDB_SUCCESS) {
 		return ldb_module_done(ac->req, ares->controls,
 					ares->response, ares->error);
@@ -891,6 +896,11 @@ static int oc_modify_callback(struct ldb_request *req, struct ldb_reply *ares)
 		return ldb_module_done(ac->req, NULL, NULL,
 					LDB_ERR_OPERATIONS_ERROR);
 	}
+
+	if (ares->type == LDB_REPLY_REFERRAL) {
+		return ldb_module_send_referral(ac->req, ares->referral);
+	}
+
 	if (ares->error != LDB_SUCCESS) {
 		return ldb_module_done(ac->req, ares->controls,
 					ares->response, ares->error);
diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c
index 19bd036..6c0d9cd 100644
--- a/source4/dsdb/samdb/ldb_modules/partition.c
+++ b/source4/dsdb/samdb/ldb_modules/partition.c
@@ -167,8 +167,7 @@ static int partition_req_callback(struct ldb_request *req,
 
 	switch (ares->type) {
 	case LDB_REPLY_REFERRAL:
-		/* ignore referrals for now */
-		break;
+		return ldb_module_send_referral(ac->req, ares->referral);
 
 	case LDB_REPLY_ENTRY:
 		if (ac->req->operation != LDB_SEARCH) {
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index 3cefa18..53b2a47 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -1527,6 +1527,11 @@ static int ph_op_callback(struct ldb_request *req, struct ldb_reply *ares)
 		return ldb_module_done(ac->req, NULL, NULL,
 					LDB_ERR_OPERATIONS_ERROR);
 	}
+
+	if (ares->type == LDB_REPLY_REFERRAL) {
+		return ldb_module_send_referral(ac->req, ares->referral);
+	}
+
 	if (ares->error != LDB_SUCCESS) {
 		return ldb_module_done(ac->req, ares->controls,
 					ares->response, ares->error);
@@ -1975,6 +1980,11 @@ static int ph_modify_callback(struct ldb_request *req, struct ldb_reply *ares)
 		return ldb_module_done(ac->req, NULL, NULL,
 					LDB_ERR_OPERATIONS_ERROR);
 	}
+
+	if (ares->type == LDB_REPLY_REFERRAL) {
+		return ldb_module_send_referral(ac->req, ares->referral);
+	}
+
 	if (ares->error != LDB_SUCCESS) {
 		return ldb_module_done(ac->req, ares->controls,
 					ares->response, ares->error);
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 11e043f..374467c 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -1076,6 +1076,7 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb,
  */
 static int replmd_update_rpmd(struct ldb_module *module, 
 			      const struct dsdb_schema *schema, 
+			      struct ldb_request *req,
 			      struct ldb_message *msg, uint64_t *seq_num,
 			      time_t t,
 			      bool *is_urgent)
@@ -1092,6 +1093,7 @@ static int replmd_update_rpmd(struct ldb_module *module,
 	struct ldb_context *ldb;
 	struct ldb_message_element *objectclass_el;
 	enum urgent_situation situation;
+	bool rodc;
 
 	ldb = ldb_module_get_ctx(module);
 
@@ -1157,6 +1159,20 @@ static int replmd_update_rpmd(struct ldb_module *module,
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
+	/*we have elements that will be modified*/
+	if (msg->num_elements > 0) {
+		/*if we are RODC and this is a DRSR update then its ok*/
+		if (!ldb_request_get_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) {
+			ret = samdb_rodc(ldb, &rodc);
+			if (ret != LDB_SUCCESS) {
+				DEBUG(4, (__location__ ": unable to tell if we are an RODC\n"));
+			} else if (rodc) {
+				ldb_asprintf_errstring(ldb, "RODC modify is forbidden\n");
+				return LDB_ERR_REFERRAL;
+			}
+		}
+	}
+
 	for (i=0; i<msg->num_elements; i++) {
 		struct ldb_message_element *old_el;
 		old_el = ldb_msg_find_element(res->msgs[0], msg->elements[i].name);
@@ -2043,6 +2059,8 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
 	time_t t = time(NULL);
 	int ret;
 	bool is_urgent = false;
+	struct loadparm_context *lp_ctx;
+	char *referral;
 
 	/* do not manipulate our control entries */
 	if (ldb_dn_is_special(req->op.mod.message->dn)) {
@@ -2050,6 +2068,8 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
 	}
 
 	ldb = ldb_module_get_ctx(module);
+	lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
+				 struct loadparm_context);
 
 	ldb_debug(ldb, LDB_DEBUG_TRACE, "replmd_modify\n");
 
@@ -2069,7 +2089,18 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
 	ldb_msg_remove_attr(msg, "whenChanged");
 	ldb_msg_remove_attr(msg, "uSNChanged");
 
-	ret = replmd_update_rpmd(module, ac->schema, msg, &ac->seq_num, t, &is_urgent);
+	ret = replmd_update_rpmd(module, ac->schema, req, msg, &ac->seq_num, t, &is_urgent);
+	if (ret == LDB_ERR_REFERRAL) {
+		talloc_free(ac);
+
+		referral = talloc_asprintf(req,
+					   "ldap://%s/%s",
+					   lp_dnsdomain(lp_ctx),
+					   ldb_dn_get_linearized(msg->dn));
+		ret = ldb_module_send_referral(req, referral);
+		return ldb_module_done(req, NULL, NULL, ret);
+	}
+
 	if (ret != LDB_SUCCESS) {
 		talloc_free(ac);
 		return ret;
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 375b624..4737791 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -514,6 +514,11 @@ static int samldb_set_defaultObjectCategory_callback(struct ldb_request *req,
 		ret = LDB_ERR_OPERATIONS_ERROR;
 		goto done;
 	}
+
+	if (ares->type == LDB_REPLY_REFERRAL) {
+		return ldb_module_send_referral(ac->req, ares->referral);
+	}
+
 	if (ares->error != LDB_SUCCESS) {
 		return ldb_module_done(ac->req, ares->controls,
 					ares->response, ares->error);
@@ -785,6 +790,11 @@ static int samldb_add_entry_callback(struct ldb_request *req,
 		return ldb_module_done(ac->req, NULL, NULL,
 					LDB_ERR_OPERATIONS_ERROR);
 	}
+
+	if (ares->type == LDB_REPLY_REFERRAL) {
+		return ldb_module_send_referral(ac->req, ares->referral);
+	}
+
 	if (ares->error != LDB_SUCCESS) {
 		return ldb_module_done(ac->req, ares->controls,
 					ares->response, ares->error);
@@ -1428,6 +1438,11 @@ static int samldb_group_add_del_member_callback(struct ldb_request *req,
 		ret = LDB_ERR_OPERATIONS_ERROR;
 		goto done;
 	}
+
+	if (ares->type == LDB_REPLY_REFERRAL) {
+		return ldb_module_send_referral(ac->req, ares->referral);
+	}
+
 	if (ares->error != LDB_SUCCESS) {
 		if (ares->error == LDB_ERR_NO_SUCH_ATTRIBUTE) {
 			/* On error "NO_SUCH_ATTRIBUTE" (delete of an invalid
diff --git a/source4/dsdb/samdb/ldb_modules/schema_data.c b/source4/dsdb/samdb/ldb_modules/schema_data.c
index 655b489..a648744 100644
--- a/source4/dsdb/samdb/ldb_modules/schema_data.c
+++ b/source4/dsdb/samdb/ldb_modules/schema_data.c
@@ -141,6 +141,8 @@ static int schema_data_add(struct ldb_module *module, struct ldb_request *req)
 	const char *oid_attr = NULL;
 	const char *oid = NULL;
 	WERROR status;
+	bool rodc;
+	int ret;
 
 	ldb = ldb_module_get_ctx(module);
 
@@ -159,7 +161,12 @@ static int schema_data_add(struct ldb_module *module, struct ldb_request *req)
 		return ldb_next_request(module, req);
 	}
 
-	if (!schema->fsmo.we_are_master) {
+	ret = samdb_rodc(ldb, &rodc);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(4, (__location__ ": unable to tell if we are an RODC \n"));
+	}
+
+	if (!schema->fsmo.we_are_master && !rodc) {
 		ldb_debug_set(ldb, LDB_DEBUG_ERROR,
 			  "schema_data_add: we are not master: reject request\n");
 		return LDB_ERR_UNWILLING_TO_PERFORM;
diff --git a/source4/dsdb/samdb/ldb_modules/subtree_rename.c b/source4/dsdb/samdb/ldb_modules/subtree_rename.c
index e2f6b1d..df211e5 100644
--- a/source4/dsdb/samdb/ldb_modules/subtree_rename.c
+++ b/source4/dsdb/samdb/ldb_modules/subtree_rename.c
@@ -81,6 +81,10 @@ static int subtree_rename_callback(struct ldb_request *req,
 					LDB_ERR_OPERATIONS_ERROR);
 	}
 
+	if (ares->type == LDB_REPLY_REFERRAL) {
+		return ldb_module_send_referral(ac->req, ares->referral);
+	}
+
 	if (ares->error != LDB_SUCCESS) {
 		return ldb_module_done(ac->req, ares->controls,
 					ares->response, ares->error);
diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c
index 18631c4..c233df7 100644
--- a/source4/dsdb/samdb/ldb_modules/util.c
+++ b/source4/dsdb/samdb/ldb_modules/util.c
@@ -243,12 +243,18 @@ int dsdb_module_modify(struct ldb_module *module,
 	int ret;
 	struct ldb_context *ldb = ldb_module_get_ctx(module);
 	TALLOC_CTX *tmp_ctx = talloc_new(module);
+	struct ldb_result *res;
+
+	res = talloc_zero(tmp_ctx, struct ldb_result);
+	if (!res) {
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
 
 	ret = ldb_build_mod_req(&mod_req, ldb, tmp_ctx,
 				message,
 				NULL,
-				NULL,
-				ldb_op_default_callback,
+				res,
+				ldb_modify_default_callback,
 				NULL);
 	if (ret != LDB_SUCCESS) {
 		talloc_free(tmp_ctx);
@@ -292,13 +298,19 @@ int dsdb_module_rename(struct ldb_module *module,
 	int ret;
 	struct ldb_context *ldb = ldb_module_get_ctx(module);
 	TALLOC_CTX *tmp_ctx = talloc_new(module);
+	struct ldb_result *res;
+
+	res = talloc_zero(tmp_ctx, struct ldb_result);
+	if (!res) {
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
 
 	ret = ldb_build_rename_req(&req, ldb, tmp_ctx,
 				   olddn,
 				   newdn,
 				   NULL,
-				   NULL,
-				   ldb_op_default_callback,
+				   res,
+				   ldb_modify_default_callback,
 				   NULL);
 	if (ret != LDB_SUCCESS) {
 		talloc_free(tmp_ctx);
@@ -340,12 +352,18 @@ int dsdb_module_add(struct ldb_module *module,
 	int ret;
 	struct ldb_context *ldb = ldb_module_get_ctx(module);
 	TALLOC_CTX *tmp_ctx = talloc_new(module);
+	struct ldb_result *res;
+
+	res = talloc_zero(tmp_ctx, struct ldb_result);
+	if (!res) {
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
 
 	ret = ldb_build_add_req(&req, ldb, tmp_ctx,
 				message,
 				NULL,
-				NULL,
-				ldb_op_default_callback,
+				res,
+				ldb_modify_default_callback,
 				NULL);
 	if (ret != LDB_SUCCESS) {
 		talloc_free(tmp_ctx);
@@ -717,6 +735,7 @@ int dsdb_module_save_partition_usn(struct ldb_module *module, struct ldb_dn *dn,
 	struct ldb_message *msg;
 	struct dsdb_control_current_partition *p_ctrl;
 	int ret;
+	struct ldb_result *res;
 
 	msg = ldb_msg_new(module);
 	if (msg == NULL) {
@@ -729,6 +748,11 @@ int dsdb_module_save_partition_usn(struct ldb_module *module, struct ldb_dn *dn,
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
+	res = talloc_zero(msg, struct ldb_result);
+	if (!res) {
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
 	ret = ldb_msg_add_fmt(msg, "uSNHighest", "%llu", (unsigned long long)uSN);
 	if (ret != LDB_SUCCESS) {
 		talloc_free(msg);
@@ -754,11 +778,11 @@ int dsdb_module_save_partition_usn(struct ldb_module *module, struct ldb_dn *dn,
 	}
 	p_ctrl->version = DSDB_CONTROL_CURRENT_PARTITION_VERSION;
 	p_ctrl->dn = dn;
-
 	ret = ldb_build_mod_req(&req, ldb, msg,
 				msg,
 				NULL,
-				NULL, ldb_op_default_callback,
+				res,
+				ldb_modify_default_callback,
 				NULL);
 again:
 	if (ret != LDB_SUCCESS) {
@@ -784,7 +808,8 @@ again:
 		ret = ldb_build_add_req(&req, ldb, msg,
 					msg,
 					NULL,
-					NULL, ldb_op_default_callback,
+					res,
+					ldb_modify_default_callback,
 					NULL);
 		goto again;
 	}
diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c
index 3e802a7..e6f6c66 100644
--- a/source4/ldap_server/ldap_backend.c
+++ b/source4/ldap_server/ldap_backend.c
@@ -174,7 +174,8 @@ static int map_ldb_error(TALLOC_CTX *mem_ctx, int ldb_err,
 /* create and execute a modify request */
 static int ldb_mod_req_with_controls(struct ldb_context *ldb,
 				     const struct ldb_message *message,
-				     struct ldb_control **controls)
+				     struct ldb_control **controls,
+				     void *context)
 {
 	struct ldb_request *req;
 	int ret;
@@ -187,8 +188,8 @@ static int ldb_mod_req_with_controls(struct ldb_context *ldb,
 	ret = ldb_build_mod_req(&req, ldb, ldb,
 					message,
 					controls,
-					NULL,
-					ldb_op_default_callback,
+					context,
+					ldb_modify_default_callback,
 					NULL);
 
 	if (ret != LDB_SUCCESS) {
@@ -315,6 +316,124 @@ static NTSTATUS ldapsrv_unwilling(struct ldapsrv_call *call, int error)
 	return NT_STATUS_OK;
 }
 
+int ldb_add_with_context(struct ldb_context *ldb,
+			 const struct ldb_message *message,
+			 void *context)
+{
+	struct ldb_request *req;
+	int ret;
+
+	ret = ldb_msg_sanity_check(ldb, message);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	ret = ldb_build_add_req(&req, ldb, ldb,
+					message,
+					NULL,
+					context,
+					ldb_modify_default_callback,
+					NULL);
+
+	if (ret != LDB_SUCCESS) return ret;
+
+	ret = ldb_transaction_start(ldb);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	ret = ldb_request(ldb, req);
+	if (ret == LDB_SUCCESS) {
+		ret = ldb_wait(req->handle, LDB_WAIT_ALL);
+	}
+
+	if (ret == LDB_SUCCESS) {
+		ret = ldb_transaction_commit(ldb);
+	}
+	else {
+		ldb_transaction_cancel(ldb);
+	}
+
+	talloc_free(req);
+	return ret;
+}
+
+int ldb_delete_with_context(struct ldb_context *ldb,
+			    struct ldb_dn *dn,
+			    void *context)
+{
+	struct ldb_request *req;
+	int ret;
+
+	ret = ldb_build_del_req(&req, ldb, ldb,
+					dn,
+					NULL,
+					context,
+					ldb_modify_default_callback,
+					NULL);
+
+	if (ret != LDB_SUCCESS) return ret;
+
+	ret = ldb_transaction_start(ldb);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	ret = ldb_request(ldb, req);
+	if (ret == LDB_SUCCESS) {
+		ret = ldb_wait(req->handle, LDB_WAIT_ALL);
+	}
+
+	if (ret == LDB_SUCCESS) {
+		ret = ldb_transaction_commit(ldb);
+	}
+	else {
+		ldb_transaction_cancel(ldb);
+	}
+
+	talloc_free(req);
+	return ret;
+}
+
+int ldb_rename_with_context(struct ldb_context *ldb,
+	       struct ldb_dn *olddn,
+	       struct ldb_dn *newdn,
+	       void *context)
+{
+	struct ldb_request *req;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list