From fdc28cf8a57f652c2ff897f1624b43bb96e5b8cd Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Mon, 10 Nov 2008 12:32:26 +0100
Subject: s3-netlogon: fix type of parameters string in user delta.

Guenther
---
 source3/libnet/libnet_samsync_passdb.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_samsync_passdb.c b/source3/libnet/libnet_samsync_passdb.c
index 1faef7b3eb..7ace77cace 100644
--- a/source3/libnet/libnet_samsync_passdb.c
+++ b/source3/libnet/libnet_samsync_passdb.c
@@ -118,12 +118,12 @@ static NTSTATUS sam_account_from_delta(struct samu *account,
 			pdb_set_profile_path(account, new_string, PDB_CHANGED);
 	}
 
-	if (r->parameters.string) {
+	if (r->parameters.array) {
 		DATA_BLOB mung;
 		char *newstr;
 		old_string = pdb_get_munged_dial(account);
-		mung.length = r->parameters.length;
-		mung.data = (uint8 *) r->parameters.string;
+		mung.length = r->parameters.length * 2;
+		mung.data = (uint8_t *) r->parameters.array;
 		newstr = (mung.length == 0) ? NULL :
 			base64_encode_data_blob(talloc_tos(), mung);
 
-- 
cgit 


From a48abdaa811c76e64a3383fe970e62b7bbb3582c Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Mon, 17 Nov 2008 18:25:01 +0100
Subject: s3-libnet-samsync: use enctype 23 for vampired keytab entries.

Guenther
---
 source3/libnet/libnet_samsync_keytab.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_samsync_keytab.c b/source3/libnet/libnet_samsync_keytab.c
index 4b0cc06d94..0341641a4c 100644
--- a/source3/libnet/libnet_samsync_keytab.c
+++ b/source3/libnet/libnet_samsync_keytab.c
@@ -90,7 +90,7 @@ static NTSTATUS fetch_sam_entry_keytab(TALLOC_CTX *mem_ctx,
 					  ctx->dns_domain_name);
 	entry.password = data_blob_talloc(mem_ctx, r->ntpassword.hash, 16);
 	entry.kvno = ads_get_kvno(ctx->ads, entry.name);
-	entry.enctype = ENCTYPE_NULL;
+	entry.enctype = ENCTYPE_ARCFOUR_HMAC;
 
 	NT_STATUS_HAVE_NO_MEMORY(entry.name);
 	NT_STATUS_HAVE_NO_MEMORY(entry.principal);
-- 
cgit 


From 1a48107cc4667f22b05fdfce952f9dcdcfaa0c7a Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Tue, 4 Nov 2008 15:49:27 +0100
Subject: s3-libnet-samsync: add support for partial replication.

Guenther
---
 source3/libnet/libnet_samsync.c | 119 ++++++++++++++++++++++++++++++++++++----
 source3/libnet/libnet_samsync.h |  17 ++++++
 2 files changed, 124 insertions(+), 12 deletions(-)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c
index 00caf2b8c1..2e7063e4ea 100644
--- a/source3/libnet/libnet_samsync.c
+++ b/source3/libnet/libnet_samsync.c
@@ -282,8 +282,58 @@ static const char *samsync_debug_str(TALLOC_CTX *mem_ctx,
  * libnet_samsync
  */
 
-NTSTATUS libnet_samsync(enum netr_SamDatabaseID database_id,
-			struct samsync_context *ctx)
+void libnet_init_netr_ChangeLogEntry(struct samsync_object *o,
+				     struct netr_ChangeLogEntry *e)
+{
+	ZERO_STRUCTP(e);
+
+	e->db_index		= o->database_id;
+	e->delta_type		= o->object_type;
+
+	switch (e->delta_type) {
+		case NETR_DELTA_DOMAIN:
+		case NETR_DELTA_DELETE_GROUP:
+		case NETR_DELTA_RENAME_GROUP:
+		case NETR_DELTA_DELETE_USER:
+		case NETR_DELTA_RENAME_USER:
+		case NETR_DELTA_DELETE_ALIAS:
+		case NETR_DELTA_RENAME_ALIAS:
+		case NETR_DELTA_DELETE_TRUST:
+		case NETR_DELTA_DELETE_ACCOUNT:
+		case NETR_DELTA_DELETE_SECRET:
+		case NETR_DELTA_DELETE_GROUP2:
+		case NETR_DELTA_DELETE_USER2:
+		case NETR_DELTA_MODIFY_COUNT:
+			break;
+		case NETR_DELTA_USER:
+		case NETR_DELTA_GROUP:
+		case NETR_DELTA_GROUP_MEMBER:
+		case NETR_DELTA_ALIAS:
+		case NETR_DELTA_ALIAS_MEMBER:
+			e->object_rid = o->object_identifier.rid;
+			break;
+		case NETR_DELTA_SECRET:
+			e->object.object_name = o->object_identifier.name;
+			e->flags = NETR_CHANGELOG_NAME_INCLUDED;
+			break;
+		case NETR_DELTA_TRUSTED_DOMAIN:
+		case NETR_DELTA_ACCOUNT:
+		case NETR_DELTA_POLICY:
+			e->object.object_sid = o->object_identifier.sid;
+			e->flags = NETR_CHANGELOG_SID_INCLUDED;
+			break;
+		default:
+			break;
+	}
+}
+
+/**
+ * libnet_samsync_delta
+ */
+
+static NTSTATUS libnet_samsync_delta(enum netr_SamDatabaseID database_id,
+				     struct samsync_context *ctx,
+				     struct netr_ChangeLogEntry *e)
 {
 	NTSTATUS result;
 	TALLOC_CTX *mem_ctx;
@@ -313,16 +363,28 @@ NTSTATUS libnet_samsync(enum netr_SamDatabaseID database_id,
 
 		netlogon_creds_client_step(ctx->cli->dc, &credential);
 
-		result = rpccli_netr_DatabaseSync2(ctx->cli, mem_ctx,
-						   logon_server,
-						   computername,
-						   &credential,
-						   &return_authenticator,
-						   database_id,
-						   restart_state,
-						   &sync_context,
-						   &delta_enum_array,
-						   0xffff);
+		if (ctx->single_object_replication) {
+			result = rpccli_netr_DatabaseRedo(ctx->cli, mem_ctx,
+							  logon_server,
+							  computername,
+							  &credential,
+							  &return_authenticator,
+							  *e,
+							  0,
+							  &delta_enum_array);
+		} else {
+			result = rpccli_netr_DatabaseSync2(ctx->cli, mem_ctx,
+							   logon_server,
+							   computername,
+							   &credential,
+							   &return_authenticator,
+							   database_id,
+							   restart_state,
+							   &sync_context,
+							   &delta_enum_array,
+							   0xffff);
+		}
+
 		if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) {
 			return result;
 		}
@@ -383,6 +445,39 @@ NTSTATUS libnet_samsync(enum netr_SamDatabaseID database_id,
 	return result;
 }
 
+/**
+ * libnet_samsync
+ */
+
+NTSTATUS libnet_samsync(enum netr_SamDatabaseID database_id,
+			struct samsync_context *ctx)
+{
+	NTSTATUS status = NT_STATUS_OK;
+	int i = 0;
+
+	if (!ctx->single_object_replication) {
+		return libnet_samsync_delta(database_id, ctx, NULL);
+	}
+
+	for (i=0; i<ctx->num_objects; i++) {
+
+		struct netr_ChangeLogEntry e;
+
+		if (ctx->objects[i].database_id != database_id) {
+			continue;
+		}
+
+		libnet_init_netr_ChangeLogEntry(&ctx->objects[i], &e);
+
+		status = libnet_samsync_delta(database_id, ctx, &e);
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+	}
+
+	return status;
+}
+
 /**
  * pull_netr_AcctLockStr
  */
diff --git a/source3/libnet/libnet_samsync.h b/source3/libnet/libnet_samsync.h
index 1f10d2c1c0..4a356e2eed 100644
--- a/source3/libnet/libnet_samsync.h
+++ b/source3/libnet/libnet_samsync.h
@@ -33,6 +33,16 @@ typedef NTSTATUS (*samsync_delta_fn_t)(TALLOC_CTX *,
 				       bool,
 				       struct samsync_context *);
 
+struct samsync_object {
+	uint16_t database_id;
+	uint16_t object_type;
+	union {
+		uint32_t rid;
+		const char *name;
+		struct dom_sid sid;
+	} object_identifier;
+};
+
 struct samsync_context {
 	enum net_samsync_mode mode;
 	const struct dom_sid *domain_sid;
@@ -46,6 +56,13 @@ struct samsync_context {
 	char *result_message;
 	char *error_message;
 
+	bool single_object_replication;
+	bool force_full_replication;
+	bool clean_old_entries;
+
+	uint32_t num_objects;
+	struct samsync_object *objects;
+
 	struct rpc_pipe_client *cli;
 	samsync_delta_fn_t delta_fn;
 	void *private_data;
-- 
cgit 


From 0861a7122e5772d4a987afb3e77baa2faa99fb32 Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Tue, 18 Nov 2008 01:16:53 +0100
Subject: s3-libnet: move add_to_keytab_entries to libnet_keytab.

Guenther
---
 source3/libnet/libnet_dssync_keytab.c  | 111 ++++++++++++---------------------
 source3/libnet/libnet_keytab.c         |  33 ++++++++++
 source3/libnet/libnet_proto.h          |   7 +++
 source3/libnet/libnet_samsync_keytab.c |  29 +++++----
 4 files changed, 93 insertions(+), 87 deletions(-)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_dssync_keytab.c b/source3/libnet/libnet_dssync_keytab.c
index 6a3139d6ad..a05bfdcbe2 100644
--- a/source3/libnet/libnet_dssync_keytab.c
+++ b/source3/libnet/libnet_dssync_keytab.c
@@ -24,39 +24,6 @@
 
 #if defined(HAVE_ADS) && defined(ENCTYPE_ARCFOUR_HMAC)
 
-/**
- * Internal helper function to add data to the list
- * of keytab entries. It builds the prefix from the input.
- */
-static NTSTATUS add_to_keytab_entries(TALLOC_CTX *mem_ctx,
-				      struct libnet_keytab_context *ctx,
-				      uint32_t kvno,
-				      const char *name,
-				      const char *prefix,
-				      const krb5_enctype enctype,
-				      DATA_BLOB blob)
-{
-	struct libnet_keytab_entry entry;
-
-	entry.kvno = kvno;
-	entry.name = talloc_strdup(mem_ctx, name);
-	entry.principal = talloc_asprintf(mem_ctx, "%s%s%s@%s",
-					  prefix ? prefix : "",
-					  prefix ? "/" : "",
-					  name, ctx->dns_domain_name);
-	entry.enctype = enctype;
-	entry.password = blob;
-	NT_STATUS_HAVE_NO_MEMORY(entry.name);
-	NT_STATUS_HAVE_NO_MEMORY(entry.principal);
-	NT_STATUS_HAVE_NO_MEMORY(entry.password.data);
-
-	ADD_TO_ARRAY(mem_ctx, struct libnet_keytab_entry, entry,
-		     &ctx->entries, &ctx->count);
-	NT_STATUS_HAVE_NO_MEMORY(ctx->entries);
-
-	return NT_STATUS_OK;
-}
-
 static NTSTATUS keytab_startup(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
 			       struct replUpToDateVectorBlob **pold_utdv)
 {
@@ -134,10 +101,10 @@ static NTSTATUS keytab_finish(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
 			goto done;
 		}
 
-		status = add_to_keytab_entries(mem_ctx, keytab_ctx, 0,
-					       ctx->nc_dn, "UTDV",
-					       ENCTYPE_NULL,
-					       blob);
+		status = libnet_keytab_add_to_keytab_entries(mem_ctx, keytab_ctx, 0,
+							     ctx->nc_dn, "UTDV",
+							     ENCTYPE_NULL,
+							     blob);
 		if (!NT_STATUS_IS_OK(status)) {
 			goto done;
 		}
@@ -391,11 +358,11 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
 	}
 
 	if (name) {
-		status = add_to_keytab_entries(mem_ctx, ctx, 0, object_dn,
-					       "SAMACCOUNTNAME",
-					       ENCTYPE_NULL,
-					       data_blob_talloc(mem_ctx, name,
-							strlen(name) + 1));
+		status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, 0, object_dn,
+							     "SAMACCOUNTNAME",
+							     ENCTYPE_NULL,
+							     data_blob_talloc(mem_ctx, name,
+							     strlen(name) + 1));
 		if (!NT_STATUS_IS_OK(status)) {
 			return status;
 		}
@@ -454,9 +421,9 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
 	}
 	DEBUGADD(1,("\n"));
 
-	status = add_to_keytab_entries(mem_ctx, ctx, kvno, name, NULL,
-				       ENCTYPE_ARCFOUR_HMAC,
-				       data_blob_talloc(mem_ctx, nt_passwd, 16));
+	status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno, name, NULL,
+						     ENCTYPE_ARCFOUR_HMAC,
+						     data_blob_talloc(mem_ctx, nt_passwd, 16));
 
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
@@ -469,11 +436,11 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
 			if (!pkb4->keys[i].value) {
 				continue;
 			}
-			status = add_to_keytab_entries(mem_ctx, ctx, kvno,
-						       name,
-						       NULL,
-						       pkb4->keys[i].keytype,
-						       *pkb4->keys[i].value);
+			status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno,
+								     name,
+								     NULL,
+								     pkb4->keys[i].keytype,
+								     *pkb4->keys[i].value);
 			if (!NT_STATUS_IS_OK(status)) {
 				return status;
 			}
@@ -482,11 +449,11 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
 			if (!pkb4->old_keys[i].value) {
 				continue;
 			}
-			status = add_to_keytab_entries(mem_ctx, ctx, kvno - 1,
-						       name,
-						       NULL,
-						       pkb4->old_keys[i].keytype,
-						       *pkb4->old_keys[i].value);
+			status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno - 1,
+								     name,
+								     NULL,
+								     pkb4->old_keys[i].keytype,
+								     *pkb4->old_keys[i].value);
 			if (!NT_STATUS_IS_OK(status)) {
 				return status;
 			}
@@ -495,11 +462,11 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
 			if (!pkb4->older_keys[i].value) {
 				continue;
 			}
-			status = add_to_keytab_entries(mem_ctx, ctx, kvno - 2,
-						       name,
-						       NULL,
-						       pkb4->older_keys[i].keytype,
-						       *pkb4->older_keys[i].value);
+			status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno - 2,
+								     name,
+								     NULL,
+								     pkb4->older_keys[i].keytype,
+								     *pkb4->older_keys[i].value);
 			if (!NT_STATUS_IS_OK(status)) {
 				return status;
 			}
@@ -511,10 +478,10 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
 			if (!pkb3->keys[i].value) {
 				continue;
 			}
-			status = add_to_keytab_entries(mem_ctx, ctx, kvno, name,
-						       NULL,
-						       pkb3->keys[i].keytype,
-						       *pkb3->keys[i].value);
+			status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno, name,
+								     NULL,
+								     pkb3->keys[i].keytype,
+								     *pkb3->keys[i].value);
 			if (!NT_STATUS_IS_OK(status)) {
 				return status;
 			}
@@ -523,11 +490,11 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
 			if (!pkb3->old_keys[i].value) {
 				continue;
 			}
-			status = add_to_keytab_entries(mem_ctx, ctx, kvno - 1,
-						       name,
-						       NULL,
-						       pkb3->old_keys[i].keytype,
-						       *pkb3->old_keys[i].value);
+			status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno - 1,
+								     name,
+								     NULL,
+								     pkb3->old_keys[i].keytype,
+								     *pkb3->old_keys[i].value);
 			if (!NT_STATUS_IS_OK(status)) {
 				return status;
 			}
@@ -549,9 +516,9 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
 	}
 
 	for (; i<pwd_history_len; i++) {
-		status = add_to_keytab_entries(mem_ctx, ctx, kvno--, name, NULL,
-				ENCTYPE_ARCFOUR_HMAC,
-				data_blob_talloc(mem_ctx, &pwd_history[i*16], 16));
+		status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno--, name, NULL,
+							     ENCTYPE_ARCFOUR_HMAC,
+							     data_blob_talloc(mem_ctx, &pwd_history[i*16], 16));
 		if (!NT_STATUS_IS_OK(status)) {
 			break;
 		}
diff --git a/source3/libnet/libnet_keytab.c b/source3/libnet/libnet_keytab.c
index 46c17b219c..990f6f6a63 100644
--- a/source3/libnet/libnet_keytab.c
+++ b/source3/libnet/libnet_keytab.c
@@ -401,4 +401,37 @@ cont:
 	return entry;
 }
 
+/**
+ * Helper function to add data to the list
+ * of keytab entries. It builds the prefix from the input.
+ */
+NTSTATUS libnet_keytab_add_to_keytab_entries(TALLOC_CTX *mem_ctx,
+					     struct libnet_keytab_context *ctx,
+					     uint32_t kvno,
+					     const char *name,
+					     const char *prefix,
+					     const krb5_enctype enctype,
+					     DATA_BLOB blob)
+{
+	struct libnet_keytab_entry entry;
+
+	entry.kvno = kvno;
+	entry.name = talloc_strdup(mem_ctx, name);
+	entry.principal = talloc_asprintf(mem_ctx, "%s%s%s@%s",
+					  prefix ? prefix : "",
+					  prefix ? "/" : "",
+					  name, ctx->dns_domain_name);
+	entry.enctype = enctype;
+	entry.password = blob;
+	NT_STATUS_HAVE_NO_MEMORY(entry.name);
+	NT_STATUS_HAVE_NO_MEMORY(entry.principal);
+	NT_STATUS_HAVE_NO_MEMORY(entry.password.data);
+
+	ADD_TO_ARRAY(mem_ctx, struct libnet_keytab_entry, entry,
+		     &ctx->entries, &ctx->count);
+	NT_STATUS_HAVE_NO_MEMORY(ctx->entries);
+
+	return NT_STATUS_OK;
+}
+
 #endif /* HAVE_KRB5 */
diff --git a/source3/libnet/libnet_proto.h b/source3/libnet/libnet_proto.h
index 69a16c1c7d..9a193b724d 100644
--- a/source3/libnet/libnet_proto.h
+++ b/source3/libnet/libnet_proto.h
@@ -55,6 +55,13 @@ struct libnet_keytab_entry *libnet_keytab_search(struct libnet_keytab_context *c
 						 const char *principal, int kvno,
 						 const krb5_enctype enctype,
 						 TALLOC_CTX *mem_ctx);
+NTSTATUS libnet_keytab_add_to_keytab_entries(TALLOC_CTX *mem_ctx,
+					     struct libnet_keytab_context *ctx,
+					     uint32_t kvno,
+					     const char *name,
+					     const char *prefix,
+					     const krb5_enctype enctype,
+					     DATA_BLOB blob);
 #endif
 
 /* The following definitions come from libnet/libnet_samsync.c  */
diff --git a/source3/libnet/libnet_samsync_keytab.c b/source3/libnet/libnet_samsync_keytab.c
index 0341641a4c..5c17d010aa 100644
--- a/source3/libnet/libnet_samsync_keytab.c
+++ b/source3/libnet/libnet_samsync_keytab.c
@@ -78,27 +78,26 @@ static NTSTATUS fetch_sam_entry_keytab(TALLOC_CTX *mem_ctx,
 				       bool last_query,
 				       struct libnet_keytab_context *ctx)
 {
-	struct libnet_keytab_entry entry;
+	NTSTATUS status;
+	uint32_t kvno = 0;
+	DATA_BLOB blob;
 
 	if (memcmp(r->ntpassword.hash, ctx->zero_buf, 16) == 0) {
 		return NT_STATUS_OK;
 	}
 
-	entry.name = talloc_strdup(mem_ctx, r->account_name.string);
-	entry.principal = talloc_asprintf(mem_ctx, "%s@%s",
-					  r->account_name.string,
-					  ctx->dns_domain_name);
-	entry.password = data_blob_talloc(mem_ctx, r->ntpassword.hash, 16);
-	entry.kvno = ads_get_kvno(ctx->ads, entry.name);
-	entry.enctype = ENCTYPE_ARCFOUR_HMAC;
-
-	NT_STATUS_HAVE_NO_MEMORY(entry.name);
-	NT_STATUS_HAVE_NO_MEMORY(entry.principal);
-	NT_STATUS_HAVE_NO_MEMORY(entry.password.data);
-
+	kvno = ads_get_kvno(ctx->ads, r->account_name.string);
+	blob = data_blob_const(r->ntpassword.hash, 16);
 
-	ADD_TO_ARRAY(mem_ctx, struct libnet_keytab_entry, entry,
-		     &ctx->entries, &ctx->count);
+	status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx,
+						     kvno,
+						     r->account_name.string,
+						     NULL,
+						     ENCTYPE_ARCFOUR_HMAC,
+						     blob);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
 
 	return NT_STATUS_OK;
 }
-- 
cgit 


From 10572d1bf46da4e5dce2e9744778d8cffa312cb0 Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Mon, 17 Nov 2008 16:28:34 +0100
Subject: s3-libnet-samsync: add samsync_ops.

Guenther
---
 source3/libnet/libnet_samsync.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_samsync.h b/source3/libnet/libnet_samsync.h
index 4a356e2eed..42bf8d1537 100644
--- a/source3/libnet/libnet_samsync.h
+++ b/source3/libnet/libnet_samsync.h
@@ -32,6 +32,21 @@ typedef NTSTATUS (*samsync_delta_fn_t)(TALLOC_CTX *,
 				       struct netr_DELTA_ENUM_ARRAY *,
 				       bool,
 				       struct samsync_context *);
+struct samsync_ops {
+	NTSTATUS (*startup)(TALLOC_CTX *mem_ctx,
+			    struct samsync_context *ctx,
+			    enum netr_SamDatabaseID id,
+			    uint64_t *sequence_num);
+	NTSTATUS (*process_objects)(TALLOC_CTX *mem_ctx,
+				    enum netr_SamDatabaseID id,
+				    struct netr_DELTA_ENUM_ARRAY *array,
+				    bool last_query,
+				    struct samsync_context *ctx);
+	NTSTATUS (*finish)(TALLOC_CTX *mem_ctx,
+			   struct samsync_context *ctx,
+			   enum netr_SamDatabaseID id,
+			   uint64_t sequence_num);
+};
 
 struct samsync_object {
 	uint16_t database_id;
@@ -64,6 +79,9 @@ struct samsync_context {
 	struct samsync_object *objects;
 
 	struct rpc_pipe_client *cli;
+
+	const struct samsync_ops *ops;
+
 	samsync_delta_fn_t delta_fn;
 	void *private_data;
 };
-- 
cgit 


From d10293dfdc1c2aded1305191161dbd31521557bf Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Mon, 17 Nov 2008 16:29:11 +0100
Subject: s3-libnet-samsync: add samsync_ops to all samsync modules.

Guenther
---
 source3/libnet/libnet_samsync.h         | 5 +++++
 source3/libnet/libnet_samsync_display.c | 4 ++++
 source3/libnet/libnet_samsync_keytab.c  | 4 ++++
 source3/libnet/libnet_samsync_ldif.c    | 4 ++++
 source3/libnet/libnet_samsync_passdb.c  | 4 ++++
 5 files changed, 21 insertions(+)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_samsync.h b/source3/libnet/libnet_samsync.h
index 42bf8d1537..2f0f049fb9 100644
--- a/source3/libnet/libnet_samsync.h
+++ b/source3/libnet/libnet_samsync.h
@@ -86,6 +86,11 @@ struct samsync_context {
 	void *private_data;
 };
 
+extern const struct samsync_ops libnet_samsync_ldif_ops;
+extern const struct samsync_ops libnet_samsync_keytab_ops;
+extern const struct samsync_ops libnet_samsync_display_ops;
+extern const struct samsync_ops libnet_samsync_passdb_ops;
+
 NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
 				enum netr_SamDatabaseID database_id,
 				struct netr_DELTA_ENUM_ARRAY *r,
diff --git a/source3/libnet/libnet_samsync_display.c b/source3/libnet/libnet_samsync_display.c
index 1dd9a1add5..5a0c3088cf 100644
--- a/source3/libnet/libnet_samsync_display.c
+++ b/source3/libnet/libnet_samsync_display.c
@@ -300,3 +300,7 @@ NTSTATUS display_sam_entries(TALLOC_CTX *mem_ctx,
 
 	return NT_STATUS_OK;
 }
+
+const struct samsync_ops libnet_samsync_display_ops = {
+	.process_objects	= display_sam_entries,
+};
diff --git a/source3/libnet/libnet_samsync_keytab.c b/source3/libnet/libnet_samsync_keytab.c
index 5c17d010aa..b68d70145c 100644
--- a/source3/libnet/libnet_samsync_keytab.c
+++ b/source3/libnet/libnet_samsync_keytab.c
@@ -188,3 +188,7 @@ NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
 }
 
 #endif /* defined(HAVE_ADS) && defined(ENCTYPE_ARCFOUR_HMAC) */
+
+const struct samsync_ops libnet_samsync_keytab_ops = {
+	.process_objects	= fetch_sam_entries_keytab,
+};
diff --git a/source3/libnet/libnet_samsync_ldif.c b/source3/libnet/libnet_samsync_ldif.c
index dd5380b6b8..245ebe0b9f 100644
--- a/source3/libnet/libnet_samsync_ldif.c
+++ b/source3/libnet/libnet_samsync_ldif.c
@@ -1226,3 +1226,7 @@ NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
 }
 
 #endif
+
+const struct samsync_ops libnet_samsync_ldif_ops = {
+	.process_objects	= fetch_sam_entries_ldif,
+};
diff --git a/source3/libnet/libnet_samsync_passdb.c b/source3/libnet/libnet_samsync_passdb.c
index 7ace77cace..6e068e0f41 100644
--- a/source3/libnet/libnet_samsync_passdb.c
+++ b/source3/libnet/libnet_samsync_passdb.c
@@ -786,3 +786,7 @@ NTSTATUS fetch_sam_entries(TALLOC_CTX *mem_ctx,
 
 	return NT_STATUS_OK;
 }
+
+const struct samsync_ops libnet_samsync_passdb_ops = {
+	.process_objects	= fetch_sam_entries,
+};
-- 
cgit 


From eef8de5c887e013f5b05742a74fbb130596c62d3 Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Mon, 17 Nov 2008 16:31:59 +0100
Subject: s3-libnet-samsync: use samsync_ops.

Guenther
---
 source3/libnet/libnet_samsync.c         |  7 ++++---
 source3/libnet/libnet_samsync.h         | 27 ---------------------------
 source3/libnet/libnet_samsync_display.c | 10 +++++-----
 source3/libnet/libnet_samsync_keytab.c  | 20 ++++++++++----------
 source3/libnet/libnet_samsync_ldif.c    | 20 ++++++++++----------
 source3/libnet/libnet_samsync_passdb.c  | 10 +++++-----
 6 files changed, 34 insertions(+), 60 deletions(-)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c
index 2e7063e4ea..e57c2a5e11 100644
--- a/source3/libnet/libnet_samsync.c
+++ b/source3/libnet/libnet_samsync.c
@@ -408,9 +408,10 @@ static NTSTATUS libnet_samsync_delta(enum netr_SamDatabaseID database_id,
 					delta_enum_array);
 
 		/* Process results */
-		callback_status = ctx->delta_fn(mem_ctx, database_id,
-						delta_enum_array,
-						NT_STATUS_IS_OK(result), ctx);
+		callback_status = ctx->ops->process_objects(mem_ctx, database_id,
+							    delta_enum_array,
+							    NT_STATUS_IS_OK(result),
+							    ctx);
 		if (!NT_STATUS_IS_OK(callback_status)) {
 			result = callback_status;
 			goto out;
diff --git a/source3/libnet/libnet_samsync.h b/source3/libnet/libnet_samsync.h
index 2f0f049fb9..23a3746fc9 100644
--- a/source3/libnet/libnet_samsync.h
+++ b/source3/libnet/libnet_samsync.h
@@ -27,11 +27,6 @@ enum net_samsync_mode {
 
 struct samsync_context;
 
-typedef NTSTATUS (*samsync_delta_fn_t)(TALLOC_CTX *,
-				       enum netr_SamDatabaseID,
-				       struct netr_DELTA_ENUM_ARRAY *,
-				       bool,
-				       struct samsync_context *);
 struct samsync_ops {
 	NTSTATUS (*startup)(TALLOC_CTX *mem_ctx,
 			    struct samsync_context *ctx,
@@ -82,7 +77,6 @@ struct samsync_context {
 
 	const struct samsync_ops *ops;
 
-	samsync_delta_fn_t delta_fn;
 	void *private_data;
 };
 
@@ -90,24 +84,3 @@ extern const struct samsync_ops libnet_samsync_ldif_ops;
 extern const struct samsync_ops libnet_samsync_keytab_ops;
 extern const struct samsync_ops libnet_samsync_display_ops;
 extern const struct samsync_ops libnet_samsync_passdb_ops;
-
-NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
-				enum netr_SamDatabaseID database_id,
-				struct netr_DELTA_ENUM_ARRAY *r,
-				bool last_query,
-				struct samsync_context *ctx);
-NTSTATUS fetch_sam_entries(TALLOC_CTX *mem_ctx,
-			   enum netr_SamDatabaseID database_id,
-			   struct netr_DELTA_ENUM_ARRAY *r,
-			   bool last_query,
-			   struct samsync_context *ctx);
-NTSTATUS display_sam_entries(TALLOC_CTX *mem_ctx,
-			     enum netr_SamDatabaseID database_id,
-			     struct netr_DELTA_ENUM_ARRAY *r,
-			     bool last_query,
-			     struct samsync_context *ctx);
-NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
-				  enum netr_SamDatabaseID database_id,
-				  struct netr_DELTA_ENUM_ARRAY *r,
-				  bool last_query,
-				  struct samsync_context *ctx);
diff --git a/source3/libnet/libnet_samsync_display.c b/source3/libnet/libnet_samsync_display.c
index 5a0c3088cf..5fdf327b74 100644
--- a/source3/libnet/libnet_samsync_display.c
+++ b/source3/libnet/libnet_samsync_display.c
@@ -285,11 +285,11 @@ static NTSTATUS display_sam_entry(TALLOC_CTX *mem_ctx,
 	return NT_STATUS_OK;
 }
 
-NTSTATUS display_sam_entries(TALLOC_CTX *mem_ctx,
-			     enum netr_SamDatabaseID database_id,
-			     struct netr_DELTA_ENUM_ARRAY *r,
-			     bool last_query,
-			     struct samsync_context *ctx)
+static NTSTATUS display_sam_entries(TALLOC_CTX *mem_ctx,
+				    enum netr_SamDatabaseID database_id,
+				    struct netr_DELTA_ENUM_ARRAY *r,
+				    bool last_query,
+				    struct samsync_context *ctx)
 {
 	int i;
 
diff --git a/source3/libnet/libnet_samsync_keytab.c b/source3/libnet/libnet_samsync_keytab.c
index b68d70145c..679f9df480 100644
--- a/source3/libnet/libnet_samsync_keytab.c
+++ b/source3/libnet/libnet_samsync_keytab.c
@@ -105,11 +105,11 @@ static NTSTATUS fetch_sam_entry_keytab(TALLOC_CTX *mem_ctx,
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
-				  enum netr_SamDatabaseID database_id,
-				  struct netr_DELTA_ENUM_ARRAY *r,
-				  bool last_query,
-				  struct samsync_context *ctx)
+static NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
+					 enum netr_SamDatabaseID database_id,
+					 struct netr_DELTA_ENUM_ARRAY *r,
+					 bool last_query,
+					 struct samsync_context *ctx)
 {
 	NTSTATUS status = NT_STATUS_OK;
 	krb5_error_code ret = 0;
@@ -178,11 +178,11 @@ NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
 
 #else
 
-NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
-				  enum netr_SamDatabaseID database_id,
-				  struct netr_DELTA_ENUM_ARRAY *r,
-				  bool last_query,
-				  struct samsync_context *ctx)
+static NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
+					 enum netr_SamDatabaseID database_id,
+					 struct netr_DELTA_ENUM_ARRAY *r,
+					 bool last_query,
+					 struct samsync_context *ctx)
 {
 	return NT_STATUS_NOT_SUPPORTED;
 }
diff --git a/source3/libnet/libnet_samsync_ldif.c b/source3/libnet/libnet_samsync_ldif.c
index 245ebe0b9f..7f794e7d8c 100644
--- a/source3/libnet/libnet_samsync_ldif.c
+++ b/source3/libnet/libnet_samsync_ldif.c
@@ -1156,11 +1156,11 @@ static NTSTATUS ldif_realloc_maps(TALLOC_CTX *mem_ctx,
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
-				enum netr_SamDatabaseID database_id,
-				struct netr_DELTA_ENUM_ARRAY *r,
-				bool last_query,
-				struct samsync_context *ctx)
+static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
+				       enum netr_SamDatabaseID database_id,
+				       struct netr_DELTA_ENUM_ARRAY *r,
+				       bool last_query,
+				       struct samsync_context *ctx)
 {
 	NTSTATUS status;
 	int i;
@@ -1216,11 +1216,11 @@ NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
 
 #else /* HAVE_LDAP */
 
-NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
-				enum netr_SamDatabaseID database_id,
-				struct netr_DELTA_ENUM_ARRAY *r,
-				bool last_query,
-				struct samsync_context *ctx)
+static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
+				       enum netr_SamDatabaseID database_id,
+				       struct netr_DELTA_ENUM_ARRAY *r,
+				       bool last_query,
+				       struct samsync_context *ctx)
 {
 	return NT_STATUS_NOT_SUPPORTED;
 }
diff --git a/source3/libnet/libnet_samsync_passdb.c b/source3/libnet/libnet_samsync_passdb.c
index 6e068e0f41..10c7ff110f 100644
--- a/source3/libnet/libnet_samsync_passdb.c
+++ b/source3/libnet/libnet_samsync_passdb.c
@@ -772,11 +772,11 @@ static NTSTATUS fetch_sam_entry(TALLOC_CTX *mem_ctx,
 	return NT_STATUS_OK;
 }
 
-NTSTATUS fetch_sam_entries(TALLOC_CTX *mem_ctx,
-			   enum netr_SamDatabaseID database_id,
-			   struct netr_DELTA_ENUM_ARRAY *r,
-			   bool last_query,
-			   struct samsync_context *ctx)
+static NTSTATUS fetch_sam_entries(TALLOC_CTX *mem_ctx,
+				  enum netr_SamDatabaseID database_id,
+				  struct netr_DELTA_ENUM_ARRAY *r,
+				  bool last_query,
+				  struct samsync_context *ctx)
 {
 	int i;
 
-- 
cgit 


From 677921b9a3176c3feb9f07b8a0ed9e887c3c46fc Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Mon, 17 Nov 2008 17:14:19 +0100
Subject: s3-libnet-samsync: call init and close ops function where
 appropriate.

Guenther
---
 source3/libnet/libnet_samsync.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c
index e57c2a5e11..ab7ca21bda 100644
--- a/source3/libnet/libnet_samsync.c
+++ b/source3/libnet/libnet_samsync.c
@@ -336,6 +336,7 @@ static NTSTATUS libnet_samsync_delta(enum netr_SamDatabaseID database_id,
 				     struct netr_ChangeLogEntry *e)
 {
 	NTSTATUS result;
+	NTSTATUS callback_status;
 	TALLOC_CTX *mem_ctx;
 	const char *logon_server = ctx->cli->desthost;
 	const char *computername = global_myname();
@@ -345,13 +346,26 @@ static NTSTATUS libnet_samsync_delta(enum netr_SamDatabaseID database_id,
 	uint32_t sync_context = 0;
 	const char *debug_str;
 	DATA_BLOB session_key;
+	uint64_t sequence_num = 0;
 
 	ZERO_STRUCT(return_authenticator);
 
+	if (!ctx->ops) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
 	if (!(mem_ctx = talloc_init("libnet_samsync"))) {
 		return NT_STATUS_NO_MEMORY;
 	}
 
+	if (ctx->ops->startup) {
+		result = ctx->ops->startup(mem_ctx, ctx,
+					   database_id, &sequence_num);
+		if (!NT_STATUS_IS_OK(result)) {
+			goto out;
+		}
+	}
+
 	debug_str = samsync_debug_str(mem_ctx, ctx->mode, database_id);
 	if (debug_str) {
 		d_fprintf(stderr, "%s\n", debug_str);
@@ -359,7 +373,6 @@ static NTSTATUS libnet_samsync_delta(enum netr_SamDatabaseID database_id,
 
 	do {
 		struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
-		NTSTATUS callback_status;
 
 		netlogon_creds_client_step(ctx->cli->dc, &credential);
 
@@ -425,6 +438,15 @@ static NTSTATUS libnet_samsync_delta(enum netr_SamDatabaseID database_id,
 	} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
 
  out:
+
+	if (NT_STATUS_IS_OK(result) && ctx->ops->finish) {
+		callback_status = ctx->ops->finish(mem_ctx, ctx,
+						   database_id, sequence_num);
+		if (!NT_STATUS_IS_OK(callback_status)) {
+			result = callback_status;
+		}
+	}
+
 	if (NT_STATUS_IS_ERR(result) && !ctx->error_message) {
 
 		ctx->error_message = talloc_asprintf(ctx,
-- 
cgit 


From 8c671597550d4fde385f6ef011dfdc7b3695f9f4 Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Mon, 17 Nov 2008 19:34:56 +0100
Subject: s3-libnet-samsync: move all modules to startup,process,finish
 callbacks.

Guenther
---
 source3/libnet/libnet_samsync.c         |   1 -
 source3/libnet/libnet_samsync.h         |   1 -
 source3/libnet/libnet_samsync_display.c |   4 +-
 source3/libnet/libnet_samsync_keytab.c  | 112 ++++++++++++++++++++++----------
 source3/libnet/libnet_samsync_ldif.c    | 105 +++++++++++++++++++++---------
 source3/libnet/libnet_samsync_passdb.c  |   1 -
 6 files changed, 153 insertions(+), 71 deletions(-)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c
index ab7ca21bda..ff2ba951bf 100644
--- a/source3/libnet/libnet_samsync.c
+++ b/source3/libnet/libnet_samsync.c
@@ -423,7 +423,6 @@ static NTSTATUS libnet_samsync_delta(enum netr_SamDatabaseID database_id,
 		/* Process results */
 		callback_status = ctx->ops->process_objects(mem_ctx, database_id,
 							    delta_enum_array,
-							    NT_STATUS_IS_OK(result),
 							    ctx);
 		if (!NT_STATUS_IS_OK(callback_status)) {
 			result = callback_status;
diff --git a/source3/libnet/libnet_samsync.h b/source3/libnet/libnet_samsync.h
index 23a3746fc9..cbd35fa327 100644
--- a/source3/libnet/libnet_samsync.h
+++ b/source3/libnet/libnet_samsync.h
@@ -35,7 +35,6 @@ struct samsync_ops {
 	NTSTATUS (*process_objects)(TALLOC_CTX *mem_ctx,
 				    enum netr_SamDatabaseID id,
 				    struct netr_DELTA_ENUM_ARRAY *array,
-				    bool last_query,
 				    struct samsync_context *ctx);
 	NTSTATUS (*finish)(TALLOC_CTX *mem_ctx,
 			   struct samsync_context *ctx,
diff --git a/source3/libnet/libnet_samsync_display.c b/source3/libnet/libnet_samsync_display.c
index 5fdf327b74..675fcd5a0d 100644
--- a/source3/libnet/libnet_samsync_display.c
+++ b/source3/libnet/libnet_samsync_display.c
@@ -163,7 +163,6 @@ static void display_rename_alias(uint32_t rid, struct netr_DELTA_RENAME *r)
 static NTSTATUS display_sam_entry(TALLOC_CTX *mem_ctx,
 				  enum netr_SamDatabaseID database_id,
 				  struct netr_DELTA_ENUM *r,
-				  bool last_query,
 				  struct samsync_context *ctx)
 {
 	union netr_DELTA_UNION u = r->delta_union;
@@ -288,14 +287,13 @@ static NTSTATUS display_sam_entry(TALLOC_CTX *mem_ctx,
 static NTSTATUS display_sam_entries(TALLOC_CTX *mem_ctx,
 				    enum netr_SamDatabaseID database_id,
 				    struct netr_DELTA_ENUM_ARRAY *r,
-				    bool last_query,
 				    struct samsync_context *ctx)
 {
 	int i;
 
 	for (i = 0; i < r->num_deltas; i++) {
 		display_sam_entry(mem_ctx, database_id, &r->delta_enum[i],
-				  last_query, ctx);
+				  ctx);
 	}
 
 	return NT_STATUS_OK;
diff --git a/source3/libnet/libnet_samsync_keytab.c b/source3/libnet/libnet_samsync_keytab.c
index 679f9df480..4ec03af886 100644
--- a/source3/libnet/libnet_samsync_keytab.c
+++ b/source3/libnet/libnet_samsync_keytab.c
@@ -75,7 +75,6 @@ static NTSTATUS fetch_sam_entry_keytab(TALLOC_CTX *mem_ctx,
 				       enum netr_SamDatabaseID database_id,
 				       uint32_t rid,
 				       struct netr_DELTA_USER *r,
-				       bool last_query,
 				       struct libnet_keytab_context *ctx)
 {
 	NTSTATUS status;
@@ -105,35 +104,50 @@ static NTSTATUS fetch_sam_entry_keytab(TALLOC_CTX *mem_ctx,
 /****************************************************************
 ****************************************************************/
 
-static NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
-					 enum netr_SamDatabaseID database_id,
-					 struct netr_DELTA_ENUM_ARRAY *r,
-					 bool last_query,
-					 struct samsync_context *ctx)
+static NTSTATUS init_keytab(TALLOC_CTX *mem_ctx,
+			    struct samsync_context *ctx,
+			    enum netr_SamDatabaseID database_id,
+			    uint64_t *sequence_num)
 {
-	NTSTATUS status = NT_STATUS_OK;
 	krb5_error_code ret = 0;
-	static struct libnet_keytab_context *keytab_ctx = NULL;
-	int i;
+	NTSTATUS status;
+	struct libnet_keytab_context *keytab_ctx;
 
-	if (!keytab_ctx) {
-		ret = libnet_keytab_init(mem_ctx, ctx->output_filename,
-					 &keytab_ctx);
-		if (ret) {
-			status = krb5_to_nt_status(ret);
-			goto out;
-		}
+	ret = libnet_keytab_init(mem_ctx, ctx->output_filename, &keytab_ctx);
+	if (ret) {
+		return krb5_to_nt_status(ret);
 	}
 
+	keytab_ctx->clean_old_entries = ctx->clean_old_entries;
+	ctx->private_data = keytab_ctx;
+
 	status = keytab_ad_connect(mem_ctx,
 				   ctx->domain_name,
 				   ctx->username,
 				   ctx->password,
 				   keytab_ctx);
 	if (!NT_STATUS_IS_OK(status)) {
-		goto out;
+		TALLOC_FREE(keytab_ctx);
+		return status;
 	}
 
+	return status;
+}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
+					 enum netr_SamDatabaseID database_id,
+					 struct netr_DELTA_ENUM_ARRAY *r,
+					 struct samsync_context *ctx)
+{
+	struct libnet_keytab_context *keytab_ctx =
+		(struct libnet_keytab_context *)ctx->private_data;
+
+	NTSTATUS status = NT_STATUS_OK;
+	int i;
+
 	for (i = 0; i < r->num_deltas; i++) {
 
 		if (r->delta_enum[i].delta_type != NETR_DELTA_USER) {
@@ -143,52 +157,78 @@ static NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
 		status = fetch_sam_entry_keytab(mem_ctx, database_id,
 						r->delta_enum[i].delta_id_union.rid,
 						r->delta_enum[i].delta_union.user,
-						last_query,
 						keytab_ctx);
 		if (!NT_STATUS_IS_OK(status)) {
 			goto out;
 		}
 	}
+ out:
+	return status;
+}
 
-	if (last_query) {
-
-		ret = libnet_keytab_add(keytab_ctx);
-		if (ret) {
-			status = krb5_to_nt_status(ret);
-			ctx->error_message = talloc_asprintf(mem_ctx,
-				"Failed to add entries to keytab %s: %s",
-				keytab_ctx->keytab_name, error_message(ret));
-			goto out;
-		}
+/****************************************************************
+****************************************************************/
 
-		ctx->result_message = talloc_asprintf(mem_ctx,
-			"Vampired %d accounts to keytab %s",
-			keytab_ctx->count,
-			keytab_ctx->keytab_name);
+static NTSTATUS close_keytab(TALLOC_CTX *mem_ctx,
+			     struct samsync_context *ctx,
+			     enum netr_SamDatabaseID database_id,
+			     uint64_t sequence_num)
+{
+	struct libnet_keytab_context *keytab_ctx =
+		(struct libnet_keytab_context *)ctx->private_data;
+	krb5_error_code ret;
+	NTSTATUS status;
 
+	ret = libnet_keytab_add(keytab_ctx);
+	if (ret) {
+		status = krb5_to_nt_status(ret);
+		ctx->error_message = talloc_asprintf(ctx,
+			"Failed to add entries to keytab %s: %s",
+			keytab_ctx->keytab_name, error_message(ret));
 		TALLOC_FREE(keytab_ctx);
+		return status;
 	}
 
-	return NT_STATUS_OK;
- out:
+	ctx->result_message = talloc_asprintf(ctx,
+		"Vampired %d accounts to keytab %s",
+		keytab_ctx->count,
+		keytab_ctx->keytab_name);
+
 	TALLOC_FREE(keytab_ctx);
 
-	return status;
+	return NT_STATUS_OK;
 }
 
 #else
 
+static NTSTATUS init_keytab(TALLOC_CTX *mem_ctx,
+			    struct samsync_context *ctx,
+			    enum netr_SamDatabaseID database_id,
+			    uint64_t *sequence_num)
+{
+	return NT_STATUS_NOT_SUPPORTED;
+}
+
 static NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
 					 enum netr_SamDatabaseID database_id,
 					 struct netr_DELTA_ENUM_ARRAY *r,
-					 bool last_query,
 					 struct samsync_context *ctx)
 {
 	return NT_STATUS_NOT_SUPPORTED;
 }
 
+static NTSTATUS close_keytab(TALLOC_CTX *mem_ctx,
+			     struct samsync_context *ctx,
+			     enum netr_SamDatabaseID database_id,
+			     uint64_t sequence_num)
+{
+	return NT_STATUS_NOT_SUPPORTED;
+}
+
 #endif /* defined(HAVE_ADS) && defined(ENCTYPE_ARCFOUR_HMAC) */
 
 const struct samsync_ops libnet_samsync_keytab_ops = {
+	.startup		= init_keytab,
 	.process_objects	= fetch_sam_entries_keytab,
+	.finish			= close_keytab
 };
diff --git a/source3/libnet/libnet_samsync_ldif.c b/source3/libnet/libnet_samsync_ldif.c
index 7f794e7d8c..495a828749 100644
--- a/source3/libnet/libnet_samsync_ldif.c
+++ b/source3/libnet/libnet_samsync_ldif.c
@@ -32,6 +32,10 @@
 static uint32 ldif_gid = 999;
 static uint32 ldif_uid = 999;
 
+/* global counters */
+static uint32_t g_index = 0;
+static uint32_t a_index = 0;
+
 /* Structure for mapping accounts to groups */
 /* Array element is the group rid */
 typedef struct _groupmap {
@@ -1046,8 +1050,8 @@ static NTSTATUS fetch_sam_entry_ldif(TALLOC_CTX *mem_ctx,
 				     enum netr_SamDatabaseID database_id,
 				     struct netr_DELTA_ENUM *r,
 				     struct samsync_context *ctx,
-				     uint32_t *a_index,
-				     uint32_t *g_index)
+				     uint32_t *a_index_p,
+				     uint32_t *g_index_p)
 {
 	union netr_DELTA_UNION u = r->delta_union;
 	union netr_DELTA_ID_UNION id = r->delta_id_union;
@@ -1061,34 +1065,34 @@ static NTSTATUS fetch_sam_entry_ldif(TALLOC_CTX *mem_ctx,
 		case NETR_DELTA_GROUP:
 			fetch_group_info_to_ldif(mem_ctx,
 						 u.group,
-						 &l->groupmap[*g_index],
+						 &l->groupmap[*g_index_p],
 						 l->add_file,
 						 ctx->domain_sid_str,
 						 l->suffix);
-			(*g_index)++;
+			(*g_index_p)++;
 			break;
 
 		case NETR_DELTA_USER:
 			fetch_account_info_to_ldif(mem_ctx,
 						   u.user,
 						   l->groupmap,
-						   &l->accountmap[*a_index],
+						   &l->accountmap[*a_index_p],
 						   l->add_file,
 						   ctx->domain_sid_str,
 						   l->suffix,
 						   l->num_alloced);
-			(*a_index)++;
+			(*a_index_p)++;
 			break;
 
 		case NETR_DELTA_ALIAS:
 			fetch_alias_info_to_ldif(mem_ctx,
 						 u.alias,
-						 &l->groupmap[*g_index],
+						 &l->groupmap[*g_index_p],
 						 l->add_file,
 						 ctx->domain_sid_str,
 						 l->suffix,
 						 database_id);
-			(*g_index)++;
+			(*g_index_p)++;
 			break;
 
 		case NETR_DELTA_GROUP_MEMBER:
@@ -1156,15 +1160,12 @@ static NTSTATUS ldif_realloc_maps(TALLOC_CTX *mem_ctx,
 /****************************************************************
 ****************************************************************/
 
-static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
-				       enum netr_SamDatabaseID database_id,
-				       struct netr_DELTA_ENUM_ARRAY *r,
-				       bool last_query,
-				       struct samsync_context *ctx)
+static NTSTATUS init_ldif(TALLOC_CTX *mem_ctx,
+			  struct samsync_context *ctx,
+			  enum netr_SamDatabaseID database_id,
+			  uint64_t *sequence_num)
 {
 	NTSTATUS status;
-	int i;
-	uint32_t g_index = 0, a_index = 0;
 	struct samsync_ldif_context *ldif_ctx =
 		(struct samsync_ldif_context *)ctx->private_data;
 
@@ -1174,11 +1175,27 @@ static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
 				   ctx->domain_sid_str,
 				   &ldif_ctx);
 	if (!NT_STATUS_IS_OK(status)) {
-		goto failed;
+		return status;
 	}
 
 	ctx->private_data = ldif_ctx;
 
+	return NT_STATUS_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
+				       enum netr_SamDatabaseID database_id,
+				       struct netr_DELTA_ENUM_ARRAY *r,
+				       struct samsync_context *ctx)
+{
+	NTSTATUS status;
+	int i;
+	struct samsync_ldif_context *ldif_ctx =
+		(struct samsync_ldif_context *)ctx->private_data;
+
 	status = ldif_realloc_maps(mem_ctx, ldif_ctx, r->num_deltas);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto failed;
@@ -1193,18 +1210,6 @@ static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
 		}
 	}
 
-	/* This was the last query */
-	if (last_query) {
-		ldif_write_output(database_id, ldif_ctx);
-		if (ldif_ctx->ldif_file != stdout) {
-			ctx->result_message = talloc_asprintf(mem_ctx,
-				"Vampired %d accounts and %d groups to %s",
-				a_index, g_index, ctx->output_filename);
-		}
-		ldif_free_context(ldif_ctx);
-		ctx->private_data = NULL;
-	}
-
 	return NT_STATUS_OK;
 
  failed:
@@ -1214,19 +1219,61 @@ static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
 	return status;
 }
 
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS close_ldif(TALLOC_CTX *mem_ctx,
+			   struct samsync_context *ctx,
+			   enum netr_SamDatabaseID database_id,
+			   uint64_t sequence_num)
+{
+	struct samsync_ldif_context *ldif_ctx =
+		(struct samsync_ldif_context *)ctx->private_data;
+
+	/* This was the last query */
+	ldif_write_output(database_id, ldif_ctx);
+	if (ldif_ctx->ldif_file != stdout) {
+		ctx->result_message = talloc_asprintf(ctx,
+			"Vampired %d accounts and %d groups to %s",
+			a_index, g_index, ctx->output_filename);
+	}
+
+	ldif_free_context(ldif_ctx);
+	ctx->private_data = NULL;
+
+	return NT_STATUS_OK;
+}
+
 #else /* HAVE_LDAP */
 
+static NTSTATUS init_ldif(TALLOC_CTX *mem_ctx,
+			  struct samsync_context *ctx,
+			  enum netr_SamDatabaseID database_id,
+			  uint64_t *sequence_num)
+{
+	return NT_STATUS_NOT_SUPPORTED;
+}
+
 static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
 				       enum netr_SamDatabaseID database_id,
 				       struct netr_DELTA_ENUM_ARRAY *r,
-				       bool last_query,
 				       struct samsync_context *ctx)
 {
 	return NT_STATUS_NOT_SUPPORTED;
 }
 
+static NTSTATUS close_ldif(TALLOC_CTX *mem_ctx,
+			   struct samsync_context *ctx,
+			   enum netr_SamDatabaseID database_id,
+			   uint64_t sequence_num)
+{
+	return NT_STATUS_NOT_SUPPORTED;
+}
+
 #endif
 
 const struct samsync_ops libnet_samsync_ldif_ops = {
+	.startup		= init_ldif,
 	.process_objects	= fetch_sam_entries_ldif,
+	.finish			= close_ldif,
 };
diff --git a/source3/libnet/libnet_samsync_passdb.c b/source3/libnet/libnet_samsync_passdb.c
index 10c7ff110f..08c8190d41 100644
--- a/source3/libnet/libnet_samsync_passdb.c
+++ b/source3/libnet/libnet_samsync_passdb.c
@@ -775,7 +775,6 @@ static NTSTATUS fetch_sam_entry(TALLOC_CTX *mem_ctx,
 static NTSTATUS fetch_sam_entries(TALLOC_CTX *mem_ctx,
 				  enum netr_SamDatabaseID database_id,
 				  struct netr_DELTA_ENUM_ARRAY *r,
-				  bool last_query,
 				  struct samsync_context *ctx)
 {
 	int i;
-- 
cgit 


From 90513515096f0b82d3e9d1cb23df73aa26f267a8 Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Tue, 18 Nov 2008 02:01:03 +0100
Subject: s3-libnet-samsync: pass sequence number pointer to process routine.

Guenther
---
 source3/libnet/libnet_samsync.c         | 1 +
 source3/libnet/libnet_samsync.h         | 1 +
 source3/libnet/libnet_samsync_display.c | 1 +
 source3/libnet/libnet_samsync_keytab.c  | 2 ++
 source3/libnet/libnet_samsync_ldif.c    | 2 ++
 source3/libnet/libnet_samsync_passdb.c  | 1 +
 6 files changed, 8 insertions(+)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c
index ff2ba951bf..43891ce829 100644
--- a/source3/libnet/libnet_samsync.c
+++ b/source3/libnet/libnet_samsync.c
@@ -423,6 +423,7 @@ static NTSTATUS libnet_samsync_delta(enum netr_SamDatabaseID database_id,
 		/* Process results */
 		callback_status = ctx->ops->process_objects(mem_ctx, database_id,
 							    delta_enum_array,
+							    &sequence_num,
 							    ctx);
 		if (!NT_STATUS_IS_OK(callback_status)) {
 			result = callback_status;
diff --git a/source3/libnet/libnet_samsync.h b/source3/libnet/libnet_samsync.h
index cbd35fa327..3a686a7f45 100644
--- a/source3/libnet/libnet_samsync.h
+++ b/source3/libnet/libnet_samsync.h
@@ -35,6 +35,7 @@ struct samsync_ops {
 	NTSTATUS (*process_objects)(TALLOC_CTX *mem_ctx,
 				    enum netr_SamDatabaseID id,
 				    struct netr_DELTA_ENUM_ARRAY *array,
+				    uint64_t *sequence_num,
 				    struct samsync_context *ctx);
 	NTSTATUS (*finish)(TALLOC_CTX *mem_ctx,
 			   struct samsync_context *ctx,
diff --git a/source3/libnet/libnet_samsync_display.c b/source3/libnet/libnet_samsync_display.c
index 675fcd5a0d..c8d9ec6f09 100644
--- a/source3/libnet/libnet_samsync_display.c
+++ b/source3/libnet/libnet_samsync_display.c
@@ -287,6 +287,7 @@ static NTSTATUS display_sam_entry(TALLOC_CTX *mem_ctx,
 static NTSTATUS display_sam_entries(TALLOC_CTX *mem_ctx,
 				    enum netr_SamDatabaseID database_id,
 				    struct netr_DELTA_ENUM_ARRAY *r,
+				    uint64_t *sequence_num,
 				    struct samsync_context *ctx)
 {
 	int i;
diff --git a/source3/libnet/libnet_samsync_keytab.c b/source3/libnet/libnet_samsync_keytab.c
index 4ec03af886..7eeae3a1a0 100644
--- a/source3/libnet/libnet_samsync_keytab.c
+++ b/source3/libnet/libnet_samsync_keytab.c
@@ -140,6 +140,7 @@ static NTSTATUS init_keytab(TALLOC_CTX *mem_ctx,
 static NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
 					 enum netr_SamDatabaseID database_id,
 					 struct netr_DELTA_ENUM_ARRAY *r,
+					 uint64_t *sequence_num,
 					 struct samsync_context *ctx)
 {
 	struct libnet_keytab_context *keytab_ctx =
@@ -212,6 +213,7 @@ static NTSTATUS init_keytab(TALLOC_CTX *mem_ctx,
 static NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
 					 enum netr_SamDatabaseID database_id,
 					 struct netr_DELTA_ENUM_ARRAY *r,
+					 uint64_t *sequence_num,
 					 struct samsync_context *ctx)
 {
 	return NT_STATUS_NOT_SUPPORTED;
diff --git a/source3/libnet/libnet_samsync_ldif.c b/source3/libnet/libnet_samsync_ldif.c
index 495a828749..c72eadf03f 100644
--- a/source3/libnet/libnet_samsync_ldif.c
+++ b/source3/libnet/libnet_samsync_ldif.c
@@ -1189,6 +1189,7 @@ static NTSTATUS init_ldif(TALLOC_CTX *mem_ctx,
 static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
 				       enum netr_SamDatabaseID database_id,
 				       struct netr_DELTA_ENUM_ARRAY *r,
+				       uint64_t *sequence_num,
 				       struct samsync_context *ctx)
 {
 	NTSTATUS status;
@@ -1257,6 +1258,7 @@ static NTSTATUS init_ldif(TALLOC_CTX *mem_ctx,
 static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
 				       enum netr_SamDatabaseID database_id,
 				       struct netr_DELTA_ENUM_ARRAY *r,
+				       uint64_t *sequence_num,
 				       struct samsync_context *ctx)
 {
 	return NT_STATUS_NOT_SUPPORTED;
diff --git a/source3/libnet/libnet_samsync_passdb.c b/source3/libnet/libnet_samsync_passdb.c
index 08c8190d41..388b10a0fa 100644
--- a/source3/libnet/libnet_samsync_passdb.c
+++ b/source3/libnet/libnet_samsync_passdb.c
@@ -775,6 +775,7 @@ static NTSTATUS fetch_sam_entry(TALLOC_CTX *mem_ctx,
 static NTSTATUS fetch_sam_entries(TALLOC_CTX *mem_ctx,
 				  enum netr_SamDatabaseID database_id,
 				  struct netr_DELTA_ENUM_ARRAY *r,
+				  uint64_t *sequence_num,
 				  struct samsync_context *ctx)
 {
 	int i;
-- 
cgit 


From 6aaf220f9e20815a32d166c1c5953e41152e1c99 Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Tue, 18 Nov 2008 03:45:38 +0100
Subject: s3-libnet-samsync: use netr_DatabaseDeltas unless full replication
 enforced.

Guenther
---
 source3/libnet/libnet_samsync.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c
index 43891ce829..5711b231c7 100644
--- a/source3/libnet/libnet_samsync.c
+++ b/source3/libnet/libnet_samsync.c
@@ -376,7 +376,8 @@ static NTSTATUS libnet_samsync_delta(enum netr_SamDatabaseID database_id,
 
 		netlogon_creds_client_step(ctx->cli->dc, &credential);
 
-		if (ctx->single_object_replication) {
+		if (ctx->single_object_replication &&
+		    !ctx->force_full_replication) {
 			result = rpccli_netr_DatabaseRedo(ctx->cli, mem_ctx,
 							  logon_server,
 							  computername,
@@ -385,6 +386,16 @@ static NTSTATUS libnet_samsync_delta(enum netr_SamDatabaseID database_id,
 							  *e,
 							  0,
 							  &delta_enum_array);
+		} else if (!ctx->force_full_replication && (sequence_num > 0)) {
+			result = rpccli_netr_DatabaseDeltas(ctx->cli, mem_ctx,
+							    logon_server,
+							    computername,
+							    &credential,
+							    &return_authenticator,
+							    database_id,
+							    &sequence_num,
+							    &delta_enum_array,
+							    0xffff);
 		} else {
 			result = rpccli_netr_DatabaseSync2(ctx->cli, mem_ctx,
 							   logon_server,
-- 
cgit 


From a079c500a6491aa2e2e9fed265096ebee7de1c8b Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Tue, 18 Nov 2008 09:42:59 +0100
Subject: s3-libnet-samsync: pass back sequence number from
 fetch_sam_entries_keytab.

Guenther
---
 source3/libnet/libnet_samsync_keytab.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_samsync_keytab.c b/source3/libnet/libnet_samsync_keytab.c
index 7eeae3a1a0..7bafad9b0b 100644
--- a/source3/libnet/libnet_samsync_keytab.c
+++ b/source3/libnet/libnet_samsync_keytab.c
@@ -151,7 +151,22 @@ static NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
 
 	for (i = 0; i < r->num_deltas; i++) {
 
-		if (r->delta_enum[i].delta_type != NETR_DELTA_USER) {
+		switch (r->delta_enum[i].delta_type) {
+		case NETR_DELTA_USER:
+			break;
+		case NETR_DELTA_DOMAIN:
+			if (sequence_num) {
+				*sequence_num =
+					r->delta_enum[i].delta_union.domain->sequence_num;
+			}
+			continue;
+		case NETR_DELTA_MODIFY_COUNT:
+			if (sequence_num) {
+				*sequence_num =
+					*r->delta_enum[i].delta_union.modified_count;
+			}
+			continue;
+		default:
 			continue;
 		}
 
-- 
cgit 


From b8769141e65dd640b9ab4fca409579ec8fcfe8f7 Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Tue, 18 Nov 2008 09:49:37 +0100
Subject: s3-libnet-samsync: refactor libnet_samsync.

Guenther
---
 source3/libnet/libnet_samsync.c | 123 +++++++++++++++++++++-------------------
 1 file changed, 66 insertions(+), 57 deletions(-)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c
index 5711b231c7..4351810169 100644
--- a/source3/libnet/libnet_samsync.c
+++ b/source3/libnet/libnet_samsync.c
@@ -331,46 +331,24 @@ void libnet_init_netr_ChangeLogEntry(struct samsync_object *o,
  * libnet_samsync_delta
  */
 
-static NTSTATUS libnet_samsync_delta(enum netr_SamDatabaseID database_id,
+static NTSTATUS libnet_samsync_delta(TALLOC_CTX *mem_ctx,
+				     enum netr_SamDatabaseID database_id,
+				     uint64_t *sequence_num,
 				     struct samsync_context *ctx,
 				     struct netr_ChangeLogEntry *e)
 {
 	NTSTATUS result;
 	NTSTATUS callback_status;
-	TALLOC_CTX *mem_ctx;
 	const char *logon_server = ctx->cli->desthost;
 	const char *computername = global_myname();
 	struct netr_Authenticator credential;
 	struct netr_Authenticator return_authenticator;
 	uint16_t restart_state = 0;
 	uint32_t sync_context = 0;
-	const char *debug_str;
 	DATA_BLOB session_key;
-	uint64_t sequence_num = 0;
 
 	ZERO_STRUCT(return_authenticator);
 
-	if (!ctx->ops) {
-		return NT_STATUS_INVALID_PARAMETER;
-	}
-
-	if (!(mem_ctx = talloc_init("libnet_samsync"))) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	if (ctx->ops->startup) {
-		result = ctx->ops->startup(mem_ctx, ctx,
-					   database_id, &sequence_num);
-		if (!NT_STATUS_IS_OK(result)) {
-			goto out;
-		}
-	}
-
-	debug_str = samsync_debug_str(mem_ctx, ctx->mode, database_id);
-	if (debug_str) {
-		d_fprintf(stderr, "%s\n", debug_str);
-	}
-
 	do {
 		struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
 
@@ -386,14 +364,15 @@ static NTSTATUS libnet_samsync_delta(enum netr_SamDatabaseID database_id,
 							  *e,
 							  0,
 							  &delta_enum_array);
-		} else if (!ctx->force_full_replication && (sequence_num > 0)) {
+		} else if (!ctx->force_full_replication &&
+		           sequence_num && (*sequence_num > 0)) {
 			result = rpccli_netr_DatabaseDeltas(ctx->cli, mem_ctx,
 							    logon_server,
 							    computername,
 							    &credential,
 							    &return_authenticator,
 							    database_id,
-							    &sequence_num,
+							    sequence_num,
 							    &delta_enum_array,
 							    0xffff);
 		} else {
@@ -434,7 +413,7 @@ static NTSTATUS libnet_samsync_delta(enum netr_SamDatabaseID database_id,
 		/* Process results */
 		callback_status = ctx->ops->process_objects(mem_ctx, database_id,
 							    delta_enum_array,
-							    &sequence_num,
+							    sequence_num,
 							    ctx);
 		if (!NT_STATUS_IS_OK(callback_status)) {
 			result = callback_status;
@@ -450,32 +429,6 @@ static NTSTATUS libnet_samsync_delta(enum netr_SamDatabaseID database_id,
 
  out:
 
-	if (NT_STATUS_IS_OK(result) && ctx->ops->finish) {
-		callback_status = ctx->ops->finish(mem_ctx, ctx,
-						   database_id, sequence_num);
-		if (!NT_STATUS_IS_OK(callback_status)) {
-			result = callback_status;
-		}
-	}
-
-	if (NT_STATUS_IS_ERR(result) && !ctx->error_message) {
-
-		ctx->error_message = talloc_asprintf(ctx,
-			"Failed to fetch %s database: %s",
-			samsync_database_str(database_id),
-			nt_errstr(result));
-
-		if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) {
-
-			ctx->error_message =
-				talloc_asprintf_append(ctx->error_message,
-					"\nPerhaps %s is a Windows native mode domain?",
-					ctx->domain_name);
-		}
-	}
-
-	talloc_destroy(mem_ctx);
-
 	return result;
 }
 
@@ -487,10 +440,37 @@ NTSTATUS libnet_samsync(enum netr_SamDatabaseID database_id,
 			struct samsync_context *ctx)
 {
 	NTSTATUS status = NT_STATUS_OK;
+	NTSTATUS callback_status;
+	TALLOC_CTX *mem_ctx;
+	const char *debug_str;
+	uint64_t sequence_num = 0;
 	int i = 0;
 
+	if (!(mem_ctx = talloc_new(ctx))) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (!ctx->ops) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (ctx->ops->startup) {
+		status = ctx->ops->startup(mem_ctx, ctx,
+					   database_id, &sequence_num);
+		if (!NT_STATUS_IS_OK(status)) {
+			goto done;
+		}
+	}
+
+	debug_str = samsync_debug_str(mem_ctx, ctx->mode, database_id);
+	if (debug_str) {
+		d_fprintf(stderr, "%s\n", debug_str);
+	}
+
 	if (!ctx->single_object_replication) {
-		return libnet_samsync_delta(database_id, ctx, NULL);
+		status = libnet_samsync_delta(mem_ctx, database_id,
+					      &sequence_num, ctx, NULL);
+		goto done;
 	}
 
 	for (i=0; i<ctx->num_objects; i++) {
@@ -503,12 +483,41 @@ NTSTATUS libnet_samsync(enum netr_SamDatabaseID database_id,
 
 		libnet_init_netr_ChangeLogEntry(&ctx->objects[i], &e);
 
-		status = libnet_samsync_delta(database_id, ctx, &e);
+		status = libnet_samsync_delta(mem_ctx, database_id,
+					      &sequence_num, ctx, &e);
 		if (!NT_STATUS_IS_OK(status)) {
-			return status;
+			goto done;
 		}
 	}
 
+ done:
+
+	if (NT_STATUS_IS_OK(status) && ctx->ops->finish) {
+		callback_status = ctx->ops->finish(mem_ctx, ctx,
+						   database_id, sequence_num);
+		if (!NT_STATUS_IS_OK(callback_status)) {
+			status = callback_status;
+		}
+	}
+
+	if (NT_STATUS_IS_ERR(status) && !ctx->error_message) {
+
+		ctx->error_message = talloc_asprintf(ctx,
+			"Failed to fetch %s database: %s",
+			samsync_database_str(database_id),
+			nt_errstr(status));
+
+		if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
+
+			ctx->error_message =
+				talloc_asprintf_append(ctx->error_message,
+					"\nPerhaps %s is a Windows native mode domain?",
+					ctx->domain_name);
+		}
+	}
+
+	talloc_destroy(mem_ctx);
+
 	return status;
 }
 
-- 
cgit 


From 6ef719bf92f6a6b9cdbd35d6b9c6e9d4d4f0dde5 Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Tue, 18 Nov 2008 09:52:35 +0100
Subject: s3-libnet-samsync: store samsync sequence number state in keytab.

Guenther
---
 source3/libnet/libnet_samsync_keytab.c | 53 +++++++++++++++++++++++++++++++++-
 1 file changed, 52 insertions(+), 1 deletion(-)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_samsync_keytab.c b/source3/libnet/libnet_samsync_keytab.c
index 7bafad9b0b..cdb344604d 100644
--- a/source3/libnet/libnet_samsync_keytab.c
+++ b/source3/libnet/libnet_samsync_keytab.c
@@ -112,6 +112,9 @@ static NTSTATUS init_keytab(TALLOC_CTX *mem_ctx,
 	krb5_error_code ret = 0;
 	NTSTATUS status;
 	struct libnet_keytab_context *keytab_ctx;
+	struct libnet_keytab_entry *entry;
+	uint64_t old_sequence_num = 0;
+	const char *principal = NULL;
 
 	ret = libnet_keytab_init(mem_ctx, ctx->output_filename, &keytab_ctx);
 	if (ret) {
@@ -131,6 +134,20 @@ static NTSTATUS init_keytab(TALLOC_CTX *mem_ctx,
 		return status;
 	}
 
+	principal = talloc_asprintf(mem_ctx, "SEQUENCE_NUM@%s",
+				    keytab_ctx->dns_domain_name);
+	NT_STATUS_HAVE_NO_MEMORY(principal);
+
+	entry = libnet_keytab_search(keytab_ctx, principal, 0, ENCTYPE_NULL,
+				     mem_ctx);
+	if (entry && (entry->password.length == 8)) {
+		old_sequence_num = BVAL(entry->password.data, 0);
+	}
+
+	if (sequence_num) {
+		*sequence_num = old_sequence_num;
+	}
+
 	return status;
 }
 
@@ -194,6 +211,37 @@ static NTSTATUS close_keytab(TALLOC_CTX *mem_ctx,
 		(struct libnet_keytab_context *)ctx->private_data;
 	krb5_error_code ret;
 	NTSTATUS status;
+	struct libnet_keytab_entry *entry;
+	uint64_t old_sequence_num = 0;
+	const char *principal = NULL;
+
+	principal = talloc_asprintf(mem_ctx, "SEQUENCE_NUM@%s",
+				    keytab_ctx->dns_domain_name);
+	NT_STATUS_HAVE_NO_MEMORY(principal);
+
+
+	entry = libnet_keytab_search(keytab_ctx, principal, 0, ENCTYPE_NULL,
+				     mem_ctx);
+	if (entry && (entry->password.length == 8)) {
+		old_sequence_num = BVAL(entry->password.data, 0);
+	}
+
+
+	if (sequence_num > old_sequence_num) {
+		DATA_BLOB blob;
+		blob = data_blob_talloc_zero(mem_ctx, 8);
+		SBVAL(blob.data, 0, sequence_num);
+
+		status = libnet_keytab_add_to_keytab_entries(mem_ctx, keytab_ctx,
+							     0,
+							     "SEQUENCE_NUM",
+							     NULL,
+							     ENCTYPE_NULL,
+							     blob);
+		if (!NT_STATUS_IS_OK(status)) {
+			goto done;
+		}
+	}
 
 	ret = libnet_keytab_add(keytab_ctx);
 	if (ret) {
@@ -210,9 +258,12 @@ static NTSTATUS close_keytab(TALLOC_CTX *mem_ctx,
 		keytab_ctx->count,
 		keytab_ctx->keytab_name);
 
+	status = NT_STATUS_OK;
+
+ done:
 	TALLOC_FREE(keytab_ctx);
 
-	return NT_STATUS_OK;
+	return status;
 }
 
 #else
-- 
cgit 


From 35ac6236bdf560f8ea3e4c2e268cdb0c9c71e1cd Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Thu, 6 Nov 2008 13:37:03 +0100
Subject: s3-libnetjoin: try to show a better error message upon invalid
 configuration.

Guenther
---
 source3/libnet/libnet_join.c | 61 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 50 insertions(+), 11 deletions(-)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index 6935e000dc..bb59a2b0a2 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -1638,24 +1638,31 @@ WERROR libnet_init_UnjoinCtx(TALLOC_CTX *mem_ctx,
 static WERROR libnet_join_check_config(TALLOC_CTX *mem_ctx,
 				       struct libnet_JoinCtx *r)
 {
+	bool valid_security = false;
+	bool valid_workgroup = false;
+	bool valid_realm = false;
+
 	/* check if configuration is already set correctly */
 
+	valid_workgroup = strequal(lp_workgroup(), r->out.netbios_domain_name);
+
 	switch (r->out.domain_is_ad) {
 		case false:
-			if ((strequal(lp_workgroup(),
-				      r->out.netbios_domain_name)) &&
-			    (lp_security() == SEC_DOMAIN)) {
+			valid_security = (lp_security() == SEC_DOMAIN);
+			if (valid_workgroup && valid_security) {
 				/* nothing to be done */
 				return WERR_OK;
 			}
 			break;
 		case true:
-			if ((strequal(lp_workgroup(),
-				      r->out.netbios_domain_name)) &&
-			    (strequal(lp_realm(),
-				      r->out.dns_domain_name)) &&
-			    ((lp_security() == SEC_ADS) ||
-			     (lp_security() == SEC_DOMAIN))) {
+			valid_realm = strequal(lp_realm(), r->out.dns_domain_name);
+			switch (lp_security()) {
+			case SEC_DOMAIN:
+			case SEC_ADS:
+				valid_security = true;
+			}
+
+			if (valid_workgroup && valid_realm && valid_security) {
 				/* nothing to be done */
 				return WERR_OK;
 			}
@@ -1665,9 +1672,41 @@ static WERROR libnet_join_check_config(TALLOC_CTX *mem_ctx,
 	/* check if we are supposed to manipulate configuration */
 
 	if (!r->in.modify_config) {
+
+		char *wrong_conf = talloc_strdup(mem_ctx, "");
+
+		if (!valid_workgroup) {
+			wrong_conf = talloc_asprintf_append(wrong_conf,
+				"\"workgroup\" set to '%s', should be '%s'",
+				lp_workgroup(), r->out.netbios_domain_name);
+			W_ERROR_HAVE_NO_MEMORY(wrong_conf);
+		}
+
+		if (!valid_realm) {
+			wrong_conf = talloc_asprintf_append(wrong_conf,
+				"\"realm\" set to '%s', should be '%s'",
+				lp_realm(), r->out.dns_domain_name);
+			W_ERROR_HAVE_NO_MEMORY(wrong_conf);
+		}
+
+		if (!valid_security) {
+			const char *sec;
+			switch (lp_security()) {
+			case SEC_SHARE: sec = "share"; break;
+			case SEC_USER:  sec = "user"; break;
+			case SEC_DOMAIN: sec = "domain"; break;
+			case SEC_ADS: sec = "ads"; break;
+			}
+			wrong_conf = talloc_asprintf_append(wrong_conf,
+				"\"security\" set to '%s', should be %s",
+				sec, r->out.domain_is_ad ?
+				"either 'domain' or 'ads'" : "'domain'");
+			W_ERROR_HAVE_NO_MEMORY(wrong_conf);
+		}
+
 		libnet_join_set_error_string(mem_ctx, r,
-			"Invalid configuration and configuration modification "
-			"was not requested");
+			"Invalid configuration (%s) and configuration modification "
+			"was not requested", wrong_conf);
 		return WERR_CAN_NOT_COMPLETE;
 	}
 
-- 
cgit 


From 98e1dd64ab5a5a0f9298684e09ab4637606b5b7c Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Fri, 21 Nov 2008 15:56:30 +0100
Subject: s3-libnetjoin: fix build warning.

Guenther
---
 source3/libnet/libnet_join.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index bb59a2b0a2..bd127f8607 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -1690,7 +1690,7 @@ static WERROR libnet_join_check_config(TALLOC_CTX *mem_ctx,
 		}
 
 		if (!valid_security) {
-			const char *sec;
+			const char *sec = NULL;
 			switch (lp_security()) {
 			case SEC_SHARE: sec = "share"; break;
 			case SEC_USER:  sec = "user"; break;
-- 
cgit 


From 4d7485df96b45054aa8f4fcac38b25847f34ca87 Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Mon, 24 Nov 2008 18:49:37 +0100
Subject: s3-samr: fix init_samr_user_info{23,24} callers.

Guenther
---
 source3/libnet/libnet_join.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index bd127f8607..498c7af3f0 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -941,7 +941,8 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
 					&cli->user_session_key,
 					&crypt_pwd);
 
-		init_samr_user_info24(&user_info.info24, crypt_pwd.data, 24);
+		init_samr_user_info24(&user_info.info24, &crypt_pwd,
+				      PASS_DONT_CHANGE_AT_NEXT_LOGON);
 
 		status = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx,
 						  &user_pol,
-- 
cgit 


From 42adfd1be2237bbe5430fe972143b548b42f6edb Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Sat, 29 Nov 2008 00:10:18 +0100
Subject: s3-libnetjoin: remove unused md4_trust_password, found by metze.

Guenther
---
 source3/libnet/libnet_join.c | 5 -----
 1 file changed, 5 deletions(-)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index 498c7af3f0..d9335b6a4b 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -762,7 +762,6 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
 	struct lsa_String lsa_acct_name;
 	uint32_t user_rid;
 	uint32_t acct_flags = ACB_WSTRUST;
-	uchar md4_trust_password[16];
 	struct samr_Ids user_rids;
 	struct samr_Ids name_types;
 	union samr_UserInfo user_info;
@@ -898,10 +897,6 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
 		goto done;
 	}
 
-	/* Create a random machine account password and generate the hash */
-
-	E_md4hash(r->in.machine_password, md4_trust_password);
-
 	init_samr_CryptPasswordEx(r->in.machine_password,
 				  &cli->user_session_key,
 				  &crypt_pwd_ex);
-- 
cgit 


From 28099876f9a39f56a54fd2540532309c0d1e2877 Mon Sep 17 00:00:00 2001
From: Günther Deschner <gd@samba.org>
Date: Sat, 29 Nov 2008 00:12:26 +0100
Subject: s3-libnetjoin: Fix bug #5749. Re-set acctflags while joining. fix
 from metze.

Guenther
---
 source3/libnet/libnet_join.c | 45 ++++++++++++++++++++++++++++----------------
 1 file changed, 29 insertions(+), 16 deletions(-)

(limited to 'source3/libnet')

diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index d9335b6a4b..908fb78ab4 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -897,10 +897,6 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
 		goto done;
 	}
 
-	init_samr_CryptPasswordEx(r->in.machine_password,
-				  &cli->user_session_key,
-				  &crypt_pwd_ex);
-
 	/* Fill in the additional account flags now */
 
 	acct_flags |= ACB_PWNOEXP;
@@ -911,23 +907,40 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
 		;;
 	}
 
-	/* Set password and account flags on machine account */
-
-	ZERO_STRUCT(user_info.info25);
-
-	user_info.info25.info.fields_present = ACCT_NT_PWD_SET |
-					       ACCT_LM_PWD_SET |
-					       SAMR_FIELD_ACCT_FLAGS;
-
-	user_info.info25.info.acct_flags = acct_flags;
-	memcpy(&user_info.info25.password.data, crypt_pwd_ex.data,
-	       sizeof(crypt_pwd_ex.data));
+	/* Set account flags on machine account */
+	ZERO_STRUCT(user_info.info16);
+	user_info.info16.acct_flags = acct_flags;
 
 	status = rpccli_samr_SetUserInfo(pipe_hnd, mem_ctx,
 					 &user_pol,
-					 25,
+					 16,
 					 &user_info);
 
+	if (!NT_STATUS_IS_OK(status)) {
+
+		rpccli_samr_DeleteUser(pipe_hnd, mem_ctx,
+				       &user_pol);
+
+		libnet_join_set_error_string(mem_ctx, r,
+			"Failed to set account flags for machine account (%s)\n",
+			nt_errstr(status));
+		goto done;
+	}
+
+	/* Set password on machine account - first try level 26 */
+
+	init_samr_CryptPasswordEx(r->in.machine_password,
+				  &cli->user_session_key,
+				  &crypt_pwd_ex);
+
+	init_samr_user_info26(&user_info.info26, &crypt_pwd_ex,
+			      PASS_DONT_CHANGE_AT_NEXT_LOGON);
+
+	status = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx,
+					  &user_pol,
+					  26,
+					  &user_info);
+
 	if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) {
 
 		/* retry with level 24 */
-- 
cgit