[SCM] Samba Shared Repository - branch master updated - 6ef719bf92f6a6b9cdbd35d6b9c6e9d4d4f0dde5

Günther Deschner gd at samba.org
Tue Nov 18 15:06:28 GMT 2008


The branch, master has been updated
       via  6ef719bf92f6a6b9cdbd35d6b9c6e9d4d4f0dde5 (commit)
       via  b8769141e65dd640b9ab4fca409579ec8fcfe8f7 (commit)
       via  a079c500a6491aa2e2e9fed265096ebee7de1c8b (commit)
       via  6aaf220f9e20815a32d166c1c5953e41152e1c99 (commit)
       via  90513515096f0b82d3e9d1cb23df73aa26f267a8 (commit)
       via  8c671597550d4fde385f6ef011dfdc7b3695f9f4 (commit)
       via  677921b9a3176c3feb9f07b8a0ed9e887c3c46fc (commit)
       via  eef8de5c887e013f5b05742a74fbb130596c62d3 (commit)
       via  d10293dfdc1c2aded1305191161dbd31521557bf (commit)
       via  10572d1bf46da4e5dce2e9744778d8cffa312cb0 (commit)
      from  0861a7122e5772d4a987afb3e77baa2faa99fb32 (commit)

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


- Log -----------------------------------------------------------------
commit 6ef719bf92f6a6b9cdbd35d6b9c6e9d4d4f0dde5
Author: Günther Deschner <gd at samba.org>
Date:   Tue Nov 18 09:52:35 2008 +0100

    s3-libnet-samsync: store samsync sequence number state in keytab.
    
    Guenther

commit b8769141e65dd640b9ab4fca409579ec8fcfe8f7
Author: Günther Deschner <gd at samba.org>
Date:   Tue Nov 18 09:49:37 2008 +0100

    s3-libnet-samsync: refactor libnet_samsync.
    
    Guenther

commit a079c500a6491aa2e2e9fed265096ebee7de1c8b
Author: Günther Deschner <gd at samba.org>
Date:   Tue Nov 18 09:42:59 2008 +0100

    s3-libnet-samsync: pass back sequence number from fetch_sam_entries_keytab.
    
    Guenther

commit 6aaf220f9e20815a32d166c1c5953e41152e1c99
Author: Günther Deschner <gd at samba.org>
Date:   Tue Nov 18 03:45:38 2008 +0100

    s3-libnet-samsync: use netr_DatabaseDeltas unless full replication enforced.
    
    Guenther

commit 90513515096f0b82d3e9d1cb23df73aa26f267a8
Author: Günther Deschner <gd at samba.org>
Date:   Tue Nov 18 02:01:03 2008 +0100

    s3-libnet-samsync: pass sequence number pointer to process routine.
    
    Guenther

commit 8c671597550d4fde385f6ef011dfdc7b3695f9f4
Author: Günther Deschner <gd at samba.org>
Date:   Mon Nov 17 19:34:56 2008 +0100

    s3-libnet-samsync: move all modules to startup,process,finish callbacks.
    
    Guenther

commit 677921b9a3176c3feb9f07b8a0ed9e887c3c46fc
Author: Günther Deschner <gd at samba.org>
Date:   Mon Nov 17 17:14:19 2008 +0100

    s3-libnet-samsync: call init and close ops function where appropriate.
    
    Guenther

commit eef8de5c887e013f5b05742a74fbb130596c62d3
Author: Günther Deschner <gd at samba.org>
Date:   Mon Nov 17 16:31:59 2008 +0100

    s3-libnet-samsync: use samsync_ops.
    
    Guenther

commit d10293dfdc1c2aded1305191161dbd31521557bf
Author: Günther Deschner <gd at samba.org>
Date:   Mon Nov 17 16:29:11 2008 +0100

    s3-libnet-samsync: add samsync_ops to all samsync modules.
    
    Guenther

commit 10572d1bf46da4e5dce2e9744778d8cffa312cb0
Author: Günther Deschner <gd at samba.org>
Date:   Mon Nov 17 16:28:34 2008 +0100

    s3-libnet-samsync: add samsync_ops.
    
    Guenther

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

Summary of changes:
 source3/libnet/libnet_samsync.c         |  117 +++++++++++++------
 source3/libnet/libnet_samsync.h         |   48 ++++----
 source3/libnet/libnet_samsync_display.c |   17 ++-
 source3/libnet/libnet_samsync_keytab.c  |  192 ++++++++++++++++++++++++-------
 source3/libnet/libnet_samsync_ldif.c    |  119 ++++++++++++++------
 source3/libnet/libnet_samsync_passdb.c  |   14 ++-
 source3/utils/net_rpc_samsync.c         |    8 +-
 7 files changed, 363 insertions(+), 152 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c
index 2e7063e..4351810 100644
--- a/source3/libnet/libnet_samsync.c
+++ b/source3/libnet/libnet_samsync.c
@@ -331,39 +331,31 @@ 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;
-	TALLOC_CTX *mem_ctx;
+	NTSTATUS callback_status;
 	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;
 
 	ZERO_STRUCT(return_authenticator);
 
-	if (!(mem_ctx = talloc_init("libnet_samsync"))) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	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;
-		NTSTATUS callback_status;
 
 		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,
@@ -372,6 +364,17 @@ static NTSTATUS libnet_samsync_delta(enum netr_SamDatabaseID database_id,
 							  *e,
 							  0,
 							  &delta_enum_array);
+		} 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,
+							    &delta_enum_array,
+							    0xffff);
 		} else {
 			result = rpccli_netr_DatabaseSync2(ctx->cli, mem_ctx,
 							   logon_server,
@@ -408,9 +411,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,
+							    sequence_num,
+							    ctx);
 		if (!NT_STATUS_IS_OK(callback_status)) {
 			result = callback_status;
 			goto out;
@@ -424,23 +428,6 @@ static NTSTATUS libnet_samsync_delta(enum netr_SamDatabaseID database_id,
 	} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
 
  out:
-	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;
 }
@@ -453,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++) {
@@ -469,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;
 }
 
diff --git a/source3/libnet/libnet_samsync.h b/source3/libnet/libnet_samsync.h
index 4a356e2..3a686a7 100644
--- a/source3/libnet/libnet_samsync.h
+++ b/source3/libnet/libnet_samsync.h
@@ -27,11 +27,21 @@ 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,
+			    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,
+				    uint64_t *sequence_num,
+				    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,27 +74,13 @@ struct samsync_context {
 	struct samsync_object *objects;
 
 	struct rpc_pipe_client *cli;
-	samsync_delta_fn_t delta_fn;
+
+	const struct samsync_ops *ops;
+
 	void *private_data;
 };
 
-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);
+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;
diff --git a/source3/libnet/libnet_samsync_display.c b/source3/libnet/libnet_samsync_display.c
index 1dd9a1a..c8d9ec6 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;
@@ -285,18 +284,22 @@ 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,
+				    uint64_t *sequence_num,
+				    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;
 }
+
+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 5c17d01..cdb3446 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,72 +104,163 @@ 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 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;
-
-	if (!keytab_ctx) {
-		ret = libnet_keytab_init(mem_ctx, ctx->output_filename,
-					 &keytab_ctx);
-		if (ret) {
-			status = krb5_to_nt_status(ret);
-			goto out;
-		}
+	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) {
+		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;
+	}
+
+	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;
+}
+
+/****************************************************************
+****************************************************************/
+
+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 =
+		(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) {
+		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;
 		}
 
 		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) {
+/****************************************************************
+****************************************************************/
+
+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;
+	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);
 
-		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);
+	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) {
+		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);
+


-- 
Samba Shared Repository


More information about the samba-cvs mailing list