diff options
Diffstat (limited to 'source3/libnet/libnet_samsync.c')
-rw-r--r-- | source3/libnet/libnet_samsync.c | 200 |
1 files changed, 169 insertions, 31 deletions
diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c index 00caf2b8c1..4351810169 100644 --- a/source3/libnet/libnet_samsync.c +++ b/source3/libnet/libnet_samsync.c @@ -282,47 +282,112 @@ 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(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); - 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 && + !ctx->force_full_replication) { + result = rpccli_netr_DatabaseRedo(ctx->cli, mem_ctx, + logon_server, + computername, + &credential, + &return_authenticator, + *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, + 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; } @@ -346,9 +411,10 @@ NTSTATUS libnet_samsync(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; @@ -362,14 +428,86 @@ NTSTATUS libnet_samsync(enum netr_SamDatabaseID database_id, } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); out: - if (NT_STATUS_IS_ERR(result) && !ctx->error_message) { + + return result; +} + +/** + * libnet_samsync + */ + +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) { + status = libnet_samsync_delta(mem_ctx, database_id, + &sequence_num, ctx, NULL); + goto done; + } + + 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(mem_ctx, database_id, + &sequence_num, ctx, &e); + if (!NT_STATUS_IS_OK(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(result)); + nt_errstr(status)); - if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { ctx->error_message = talloc_asprintf_append(ctx->error_message, @@ -380,7 +518,7 @@ NTSTATUS libnet_samsync(enum netr_SamDatabaseID database_id, talloc_destroy(mem_ctx); - return result; + return status; } /** |