[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Sun Apr 3 19:28:03 MDT 2011


The branch, master has been updated
       via  f00d258 s4-dsdb: implemented creation of conflict records
       via  bf3a75c s4-samba-tool: give a bit better error on user delete failure
       via  f0e7303 s4-rpc: improved error mapping for several RPC server calls
       via  81f2dda s4-dsdb: added a ldb err -> NTSTATUS mapping
       via  db03168 s4-krb5: be a bit less verbose about krb5 packets
       via  822e7e5 s4-loadparm: be a bit less verbose about smb.conf processing
       via  45e00ee s4-libnet: honour convention of DEBUGLEVEL>=10 for NDR print
       via  4a98d6c debug: default debug to stderr
      from  c6b93d2 Avoid uppercasing server role in error message.

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


- Log -----------------------------------------------------------------
commit f00d258a44073e5758c1b1785d98c79e75ba528b
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Apr 1 19:53:23 2011 +1100

    s4-dsdb: implemented creation of conflict records
    
    when a record with the same DN gets created on two DCs at the same
    time, this creates a replication conflict. To resolve this conflict
    one of the DCs needs to create a conflict record, which is a rename of
    one of the two DNs, based on which one is newer.
    
    This prevents replication from failing when DCs are temporarily
    disconnected and then have conflicts when they next replicate
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User: Andrew Tridgell <tridge at samba.org>
    Autobuild-Date: Mon Apr  4 03:27:07 CEST 2011 on sn-devel-104

commit bf3a75cf82f7ccdde14108d0d300b08d764277a3
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Apr 1 15:59:15 2011 +1100

    s4-samba-tool: give a bit better error on user delete failure

commit f0e73030239d29654eb54ebc95c636ff6385d575
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Apr 1 15:58:55 2011 +1100

    s4-rpc: improved error mapping for several RPC server calls
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 81f2dda62676b842cda5297390de290e5d1f5e81
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Apr 1 15:58:21 2011 +1100

    s4-dsdb: added a ldb err -> NTSTATUS mapping
    
    this is not perfect, but its better than always giving
    NT_STATUS_UNSUCCESSFUL in our RPC servers
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit db0316832aa13bdfcca7e3785a757945a2e6d62f
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Apr 1 15:57:39 2011 +1100

    s4-krb5: be a bit less verbose about krb5 packets
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 822e7e59678fe445e21152a4777fa9585cd376fe
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Apr 1 15:57:22 2011 +1100

    s4-loadparm: be a bit less verbose about smb.conf processing
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 45e00ee68683695ed22b97b6396083fedd70c06f
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Apr 1 15:56:58 2011 +1100

    s4-libnet: honour convention of DEBUGLEVEL>=10 for NDR print

commit 4a98d6ce96924e905ce87e9bec2ef29d25803aad
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Apr 1 14:55:37 2011 +1100

    debug: default debug to stderr
    
    if setup_logging() hasn't been called then default to sending debug to
    stderr
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 lib/util/debug.c                                |    3 +-
 source4/auth/kerberos/krb5_init_context.c       |    2 +-
 source4/dsdb/common/util.c                      |   78 +++++
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c |  404 ++++++++++++++++++++---
 source4/libnet/libnet_become_dc.c               |   12 +
 source4/libnet/libnet_unbecome_dc.c             |    4 +
 source4/param/loadparm.c                        |    4 +-
 source4/rpc_server/lsa/dcesrv_lsa.c             |    3 +-
 source4/rpc_server/netlogon/dcerpc_netlogon.c   |    2 +-
 source4/rpc_server/samr/dcesrv_samr.c           |   41 +--
 source4/rpc_server/winreg/rpc_winreg.c          |    2 +-
 source4/scripting/python/samba/netcmd/user.py   |    6 +-
 12 files changed, 482 insertions(+), 79 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/util/debug.c b/lib/util/debug.c
index 9a6d304..b0a7882 100644
--- a/lib/util/debug.c
+++ b/lib/util/debug.c
@@ -91,7 +91,8 @@ static struct {
 } state = {
 	.settings = {
 		.timestamp_logs = true
-	}
+	},
+	.fd = 2 /* stderr by default */
 };
 
 /* -------------------------------------------------------------------------- **
diff --git a/source4/auth/kerberos/krb5_init_context.c b/source4/auth/kerberos/krb5_init_context.c
index 78f3e1f..db3a537 100644
--- a/source4/auth/kerberos/krb5_init_context.c
+++ b/source4/auth/kerberos/krb5_init_context.c
@@ -104,7 +104,7 @@ static void smb_krb5_socket_recv(struct smb_krb5_socket *smb_krb5)
 		return;
 	}
 
-	DEBUG(2,("Received smb_krb5 packet of length %d\n",
+	DEBUG(4,("Received smb_krb5 packet of length %d\n",
 		 (int)blob.length));
 
 	talloc_steal(smb_krb5, blob.data);
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 2563b40..0c920d7 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -4216,3 +4216,81 @@ bool is_attr_in_list(const char * const * attrs, const char *attr)
 	return false;
 }
 
+
+/*
+  map an ldb error code to an approximate NTSTATUS code
+ */
+NTSTATUS dsdb_ldb_err_to_ntstatus(int err)
+{
+	switch (err) {
+	case LDB_SUCCESS:
+		return NT_STATUS_OK;
+
+	case LDB_ERR_PROTOCOL_ERROR:
+		return NT_STATUS_DEVICE_PROTOCOL_ERROR;
+
+	case LDB_ERR_TIME_LIMIT_EXCEEDED:
+		return NT_STATUS_IO_TIMEOUT;
+
+	case LDB_ERR_SIZE_LIMIT_EXCEEDED:
+		return NT_STATUS_BUFFER_TOO_SMALL;
+
+	case LDB_ERR_COMPARE_FALSE:
+	case LDB_ERR_COMPARE_TRUE:
+		return NT_STATUS_REVISION_MISMATCH;
+
+	case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED:
+		return NT_STATUS_NOT_SUPPORTED;
+
+	case LDB_ERR_STRONG_AUTH_REQUIRED:
+	case LDB_ERR_CONFIDENTIALITY_REQUIRED:
+	case LDB_ERR_SASL_BIND_IN_PROGRESS:
+	case LDB_ERR_INAPPROPRIATE_AUTHENTICATION:
+	case LDB_ERR_INVALID_CREDENTIALS:
+	case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
+	case LDB_ERR_UNWILLING_TO_PERFORM:
+		return NT_STATUS_ACCESS_DENIED;
+
+	case LDB_ERR_NO_SUCH_OBJECT:
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+	case LDB_ERR_REFERRAL:
+	case LDB_ERR_NO_SUCH_ATTRIBUTE:
+		return NT_STATUS_NOT_FOUND;
+
+	case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION:
+		return NT_STATUS_NOT_SUPPORTED;
+
+	case LDB_ERR_ADMIN_LIMIT_EXCEEDED:
+		return NT_STATUS_BUFFER_TOO_SMALL;
+
+	case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE:
+	case LDB_ERR_INAPPROPRIATE_MATCHING:
+	case LDB_ERR_CONSTRAINT_VIOLATION:
+	case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX:
+	case LDB_ERR_INVALID_DN_SYNTAX:
+	case LDB_ERR_NAMING_VIOLATION:
+	case LDB_ERR_OBJECT_CLASS_VIOLATION:
+	case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF:
+	case LDB_ERR_NOT_ALLOWED_ON_RDN:
+		return NT_STATUS_INVALID_PARAMETER;
+
+	case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS:
+	case LDB_ERR_ENTRY_ALREADY_EXISTS:
+		return NT_STATUS_ERROR_DS_OBJ_STRING_NAME_EXISTS;
+
+	case LDB_ERR_BUSY:
+		return NT_STATUS_NETWORK_BUSY;
+
+	case LDB_ERR_ALIAS_PROBLEM:
+	case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM:
+	case LDB_ERR_UNAVAILABLE:
+	case LDB_ERR_LOOP_DETECT:
+	case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED:
+	case LDB_ERR_AFFECTS_MULTIPLE_DSAS:
+	case LDB_ERR_OTHER:
+	case LDB_ERR_OPERATIONS_ERROR:
+		break;
+	}
+	return NT_STATUS_UNSUCCESSFUL;
+}
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index b38f45f..6180dfc 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -2884,6 +2884,361 @@ static int replmd_replicated_request_werror(struct replmd_replicated_request *ar
 	return ret;
 }
 
+
+static struct replPropertyMetaData1 *
+replmd_replPropertyMetaData1_find_attid(struct replPropertyMetaDataBlob *md_blob,
+                                        enum drsuapi_DsAttributeId attid)
+{
+	uint32_t i;
+	struct replPropertyMetaDataCtr1 *rpmd_ctr = &md_blob->ctr.ctr1;
+
+	for (i = 0; i < rpmd_ctr->count; i++) {
+		if (rpmd_ctr->array[i].attid == attid) {
+			return &rpmd_ctr->array[i];
+		}
+	}
+	return NULL;
+}
+
+
+/*
+   return true if an update is newer than an existing entry
+   see section 5.11 of MS-ADTS
+*/
+static bool replmd_update_is_newer(const struct GUID *current_invocation_id,
+				   const struct GUID *update_invocation_id,
+				   uint32_t current_version,
+				   uint32_t update_version,
+				   NTTIME current_change_time,
+				   NTTIME update_change_time)
+{
+	if (update_version != current_version) {
+		return update_version > current_version;
+	}
+	if (update_change_time != current_change_time) {
+		return update_change_time > current_change_time;
+	}
+	return GUID_compare(update_invocation_id, current_invocation_id) > 0;
+}
+
+static bool replmd_replPropertyMetaData1_is_newer(struct replPropertyMetaData1 *cur_m,
+						  struct replPropertyMetaData1 *new_m)
+{
+	return replmd_update_is_newer(&cur_m->originating_invocation_id,
+				      &new_m->originating_invocation_id,
+				      cur_m->version,
+				      new_m->version,
+				      cur_m->originating_change_time,
+				      new_m->originating_change_time);
+}
+
+
+/*
+  form a conflict DN
+ */
+static struct ldb_dn *replmd_conflict_dn(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, struct GUID *guid)
+{
+	const struct ldb_val *rdn_val;
+	const char *rdn_name;
+	struct ldb_dn *new_dn;
+
+	rdn_val = ldb_dn_get_rdn_val(dn);
+	rdn_name = ldb_dn_get_rdn_name(dn);
+	if (!rdn_val || !rdn_name) {
+		return NULL;
+	}
+
+	new_dn = ldb_dn_copy(mem_ctx, dn);
+	if (!new_dn) {
+		return NULL;
+	}
+
+	if (!ldb_dn_remove_child_components(new_dn, 1)) {
+		return NULL;
+	}
+
+	if (!ldb_dn_add_child_fmt(new_dn, "%s=%s\\0ACNF:%s",
+				  rdn_name,
+				  ldb_dn_escape_value(new_dn, *rdn_val),
+				  GUID_string(new_dn, guid))) {
+		return NULL;
+	}
+
+	return new_dn;
+}
+
+
+/*
+  perform a modify operation which sets the rDN and name attributes to
+  their current values. This has the effect of changing these
+  attributes to have been last updated by the current DC. This is
+  needed to ensure that renames performed as part of conflict
+  resolution are propogated to other DCs
+ */
+static int replmd_name_modify(struct ldb_module *module, struct ldb_request *req, struct ldb_dn *dn)
+{
+	struct ldb_message *msg;
+	const char *rdn_name;
+	const struct ldb_val *rdn_val;
+	int ret;
+
+	msg = ldb_msg_new(req);
+	if (msg == NULL) {
+		goto failed;
+	}
+	msg->dn = dn;
+
+	rdn_name = ldb_dn_get_rdn_name(dn);
+	if (rdn_name == NULL) {
+		goto failed;
+	}
+
+	rdn_val = ldb_dn_get_rdn_val(dn);
+	if (rdn_val == NULL) {
+		goto failed;
+	}
+
+	if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) {
+		goto failed;
+	}
+	if (ldb_msg_add_value(msg, rdn_name, rdn_val, NULL) != 0) {
+		goto failed;
+	}
+	if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) {
+		goto failed;
+	}
+	if (ldb_msg_add_value(msg, "name", rdn_val, NULL) != 0) {
+		goto failed;
+	}
+
+	ret = dsdb_module_modify(module, msg, DSDB_FLAG_OWN_MODULE, req);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(0,(__location__ ": Failed to modify rDN/name of conflict DN '%s' - %s",
+			 ldb_dn_get_linearized(dn), ldb_errstring(ldb_module_get_ctx(module))));
+		return ret;
+	}
+
+	talloc_free(msg);
+
+	return LDB_SUCCESS;
+
+failed:
+	talloc_free(msg);
+	DEBUG(0,(__location__ ": Failed to setup modify rDN/name of conflict DN '%s'",
+		 ldb_dn_get_linearized(dn)));
+	return LDB_ERR_OPERATIONS_ERROR;
+}
+
+
+/*
+  callback for conflict DN handling where we have renamed the incoming
+  record. After renaming it, we need to ensure the change of name and
+  rDN for the incoming record is seen as an originating update by this DC.
+ */
+static int replmd_op_name_modify_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+	struct replmd_replicated_request *ar =
+		talloc_get_type_abort(req->context, struct replmd_replicated_request);
+	int ret;
+
+	if (ares->error != LDB_SUCCESS) {
+		/* call the normal callback for everything except success */
+		return replmd_op_callback(req, ares);
+	}
+
+	/* perform a modify of the rDN and name of the record */
+	ret = replmd_name_modify(ar->module, req, req->op.add.message->dn);
+	if (ret != LDB_SUCCESS) {
+		ares->error = ret;
+		return replmd_op_callback(req, ares);
+	}
+
+	return replmd_op_callback(req, ares);
+}
+
+/*
+  callback for replmd_replicated_apply_add()
+  This copes with the creation of conflict records in the case where
+  the DN exists, but with a different objectGUID
+ */
+static int replmd_op_add_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+	struct ldb_dn *conflict_dn;
+	struct replmd_replicated_request *ar =
+		talloc_get_type_abort(req->context, struct replmd_replicated_request);
+	struct ldb_result *res;
+	const char *attrs[] = { "replPropertyMetaData", "objectGUID", NULL };
+	int ret;
+	const struct ldb_val *rmd_value, *omd_value;
+	struct replPropertyMetaDataBlob omd, rmd;
+	enum ndr_err_code ndr_err;
+	bool rename_incoming_record;
+	struct replPropertyMetaData1 *rmd_name, *omd_name;
+
+	if (ares->error != LDB_ERR_ENTRY_ALREADY_EXISTS) {
+		/* call the normal callback for everything except
+		   conflicts */
+		return replmd_op_callback(req, ares);
+	}
+
+	/*
+	 * we have a conflict, and need to decide if we will keep the
+	 * new record or the old record
+	 */
+	conflict_dn = req->op.add.message->dn;
+
+	/*
+	 * first we need the replPropertyMetaData attribute from the
+	 * old record
+	 */
+	ret = dsdb_module_search_dn(ar->module, req, &res, conflict_dn,
+				    attrs,
+				    DSDB_FLAG_NEXT_MODULE |
+				    DSDB_SEARCH_SHOW_DELETED |
+				    DSDB_SEARCH_SHOW_RECYCLED, req);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(0,(__location__ ": Unable to find object for conflicting record '%s'\n",
+			 ldb_dn_get_linearized(conflict_dn)));
+		goto failed;
+	}
+
+	omd_value = ldb_msg_find_ldb_val(res->msgs[0], "replPropertyMetaData");
+	if (omd_value == NULL) {
+		DEBUG(0,(__location__ ": Unable to find replPropertyMetaData for conflicting record '%s'\n",
+			 ldb_dn_get_linearized(conflict_dn)));
+		goto failed;
+	}
+
+	ndr_err = ndr_pull_struct_blob(omd_value, res->msgs[0], &omd,
+				       (ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaDataBlob);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		DEBUG(0,(__location__ ": Failed to parse old replPropertyMetaData for %s\n",
+			 ldb_dn_get_linearized(conflict_dn)));
+		goto failed;
+	}
+
+	/*
+	 * and the replPropertyMetaData attribute from the
+	 * new record
+	 */
+	rmd_value = ldb_msg_find_ldb_val(req->op.add.message, "replPropertyMetaData");
+	if (rmd_value == NULL) {
+		DEBUG(0,(__location__ ": Unable to find replPropertyMetaData for new record '%s'\n",
+			 ldb_dn_get_linearized(conflict_dn)));
+		goto failed;
+	}
+
+	ndr_err = ndr_pull_struct_blob(rmd_value, req, &rmd,
+				       (ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaDataBlob);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		DEBUG(0,(__location__ ": Failed to parse new replPropertyMetaData for %s\n",
+			 ldb_dn_get_linearized(conflict_dn)));
+		goto failed;
+	}
+
+	/* we decide which is newer based on the RPMD on the name
+	   attribute.  See [MS-DRSR] ResolveNameConflict */
+	rmd_name = replmd_replPropertyMetaData1_find_attid(&rmd, DRSUAPI_ATTID_name);
+	omd_name = replmd_replPropertyMetaData1_find_attid(&omd, DRSUAPI_ATTID_name);
+	if (!rmd_name || !omd_name) {
+		DEBUG(0,(__location__ ": Failed to find name attribute in replPropertyMetaData for %s\n",
+			 ldb_dn_get_linearized(conflict_dn)));
+		goto failed;
+	}
+
+	rename_incoming_record = !replmd_replPropertyMetaData1_is_newer(omd_name, rmd_name);
+
+	if (rename_incoming_record) {
+		struct GUID guid;
+		struct ldb_dn *new_dn;
+		struct ldb_message *new_msg;
+
+		guid = samdb_result_guid(req->op.add.message, "objectGUID");
+		if (GUID_all_zero(&guid)) {
+			DEBUG(0,(__location__ ": Failed to find objectGUID for conflicting incoming record %s\n",
+				 ldb_dn_get_linearized(conflict_dn)));
+			goto failed;
+		}
+		new_dn = replmd_conflict_dn(req, conflict_dn, &guid);
+		if (new_dn == NULL) {
+			DEBUG(0,(__location__ ": Failed to form conflict DN for %s\n",
+				 ldb_dn_get_linearized(conflict_dn)));
+			goto failed;
+		}
+
+		DEBUG(1,(__location__ ": Resolving conflict record via incoming rename '%s' -> '%s'\n",
+			 ldb_dn_get_linearized(conflict_dn), ldb_dn_get_linearized(new_dn)));
+
+		/* re-submit the request, but with a different
+		   callback, so we don't loop forever. */
+		new_msg = ldb_msg_copy_shallow(req, req->op.add.message);
+		if (!new_msg) {
+			goto failed;
+			DEBUG(0,(__location__ ": Failed to copy conflict DN message for %s\n",
+				 ldb_dn_get_linearized(conflict_dn)));
+		}
+		new_msg->dn = new_dn;
+		req->op.add.message = new_msg;
+		req->callback = replmd_op_name_modify_callback;
+
+		return ldb_next_request(ar->module, req);
+	} else {
+		/* we are renaming the existing record */
+		struct GUID guid;
+		struct ldb_dn *new_dn;
+
+		guid = samdb_result_guid(res->msgs[0], "objectGUID");
+		if (GUID_all_zero(&guid)) {
+			DEBUG(0,(__location__ ": Failed to find objectGUID for existing conflict record %s\n",
+				 ldb_dn_get_linearized(conflict_dn)));
+			goto failed;
+		}
+
+		new_dn = replmd_conflict_dn(req, conflict_dn, &guid);
+		if (new_dn == NULL) {
+			DEBUG(0,(__location__ ": Failed to form conflict DN for %s\n",
+				 ldb_dn_get_linearized(conflict_dn)));
+			goto failed;
+		}
+
+		DEBUG(1,(__location__ ": Resolving conflict record via existing rename '%s' -> '%s'\n",
+			 ldb_dn_get_linearized(conflict_dn), ldb_dn_get_linearized(new_dn)));
+
+		ret = dsdb_module_rename(ar->module, conflict_dn, new_dn,
+					 DSDB_FLAG_OWN_MODULE, req);
+		if (ret != LDB_SUCCESS) {
+			DEBUG(0,(__location__ ": Failed to rename conflict dn '%s' to '%s' - %s\n",
+				 ldb_dn_get_linearized(conflict_dn),
+				 ldb_dn_get_linearized(new_dn),
+				 ldb_errstring(ldb_module_get_ctx(ar->module))));
+			goto failed;
+		}
+
+		/*
+		 * now we need to ensure that the rename is seen as an
+		 * originating update. We do that with a modify.
+		 */
+		ret = replmd_name_modify(ar->module, req, new_dn);
+		if (ret != LDB_SUCCESS) {
+			goto failed;
+		}
+
+		req->callback = replmd_op_callback;
+
+		return ldb_next_request(ar->module, req);
+	}
+
+failed:
+	/* on failure do the original callback. This means replication
+	 * will stop with an error, but there is not much else we can
+	 * do
+	 */
+	return replmd_op_callback(req, ares);
+}
+
+/*
+  this is called when a new object comes in over DRS
+ */
 static int replmd_replicated_apply_add(struct replmd_replicated_request *ar)
 {
 	struct ldb_context *ldb;
@@ -2978,7 +3333,7 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar)
 				msg,
 				ar->controls,
 				ar,
-				replmd_op_callback,
+				replmd_op_add_callback,
 				ar->req);
 	LDB_REQ_SET_LOCATION(change_req);
 	if (ret != LDB_SUCCESS) return replmd_replicated_request_error(ar, ret);
@@ -2993,53 +3348,6 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar)
 }
 
 /*
-   return true if an update is newer than an existing entry
-   see section 5.11 of MS-ADTS
-*/
-static bool replmd_update_is_newer(const struct GUID *current_invocation_id,
-				   const struct GUID *update_invocation_id,
-				   uint32_t current_version,
-				   uint32_t update_version,
-				   NTTIME current_change_time,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list