From 1a48107cc4667f22b05fdfce952f9dcdcfaa0c7a Mon Sep 17 00:00:00 2001 From: Günther Deschner 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(-) 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; inum_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