diff options
author | Andrew Bartlett <abartlet@samba.org> | 2005-05-03 14:38:14 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:16:29 -0500 |
commit | 35a05d1dc0c551656d9caeea87a9925182d717bc (patch) | |
tree | 24a0829aff6680175788ff6f87a3a5672bb6fc8f | |
parent | eb3b5f28d4686802070a770ef29bb71dd4d82d54 (diff) | |
download | samba-35a05d1dc0c551656d9caeea87a9925182d717bc.tar.gz samba-35a05d1dc0c551656d9caeea87a9925182d717bc.tar.bz2 samba-35a05d1dc0c551656d9caeea87a9925182d717bc.zip |
r6603: More work on the samdump puzzle. This implements a function pointer
callback interface, so we can start dumping into more than just stdout
soon.
Also use the enums instead of uint32 where possible and valid.
Andrew Bartlett
(This used to be commit f0c67a4a24dbd7fc32fc864d61a21eeee587178e)
-rw-r--r-- | source4/libnet/libnet_vampire.c | 145 | ||||
-rw-r--r-- | source4/libnet/libnet_vampire.h | 24 | ||||
-rw-r--r-- | source4/torture/rpc/samsync.c | 2 |
3 files changed, 125 insertions, 46 deletions
diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index daf7bdfaed..82209f3361 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -24,9 +24,9 @@ #include "librpc/gen_ndr/ndr_netlogon.h" #include "librpc/gen_ndr/ndr_samr.h" -static BOOL vampire_samdump_handle_user(TALLOC_CTX *mem_ctx, - struct creds_CredentialState *creds, - struct netr_DELTA_ENUM *delta) +static NTSTATUS vampire_samdump_handle_user(TALLOC_CTX *mem_ctx, + struct creds_CredentialState *creds, + struct netr_DELTA_ENUM *delta) { uint32_t rid = delta->delta_id_union.rid; struct netr_DELTA_USER *user = delta->delta_union.user; @@ -44,6 +44,7 @@ static BOOL vampire_samdump_handle_user(TALLOC_CTX *mem_ctx, sam_rid_crypt(rid, user->lmpassword.hash, lm_hash.hash, 0); lm_hash_p = &lm_hash; } + if (user->nt_password_present) { sam_rid_crypt(rid, user->ntpassword.hash, nt_hash.hash, 0); nt_hash_p = &nt_hash; @@ -66,9 +67,9 @@ static BOOL vampire_samdump_handle_user(TALLOC_CTX *mem_ctx, nt_hash_p = &nt_hash; } } else { - printf("Failed to parse Sensitive Data for %s:\n", username); + DEBUG(1, ("Failed to parse Sensitive Data for %s:\n", username)); dump_data(10, data.data, data.length); - return False; + return nt_status; } } @@ -80,20 +81,47 @@ static BOOL vampire_samdump_handle_user(TALLOC_CTX *mem_ctx, smbpasswd_encode_acb_info(mem_ctx, user->acct_flags), (unsigned int)nt_time_to_unix(user->last_password_change)); - return True; + return NT_STATUS_OK; } +static NTSTATUS libnet_samdump_fn(TALLOC_CTX *mem_ctx, + void *private, + struct creds_CredentialState *creds, + enum netr_SamDatabaseID database, + struct netr_DELTA_ENUM *delta, + char **error_string) +{ + NTSTATUS nt_status = NT_STATUS_OK; + *error_string = NULL; + switch (database) { + case SAM_DATABASE_DOMAIN: + { + switch (delta->delta_type) { + case NETR_DELTA_USER: + { + nt_status = vampire_samdump_handle_user(mem_ctx, + creds, + delta); + break; + } + } + break; + } + } + return nt_status; +} - -static NTSTATUS libnet_SamDump_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamDump *r) +static NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamSync *r) { - NTSTATUS nt_status; + NTSTATUS nt_status, dbsync_nt_status; TALLOC_CTX *loop_ctx, *delta_ctx; struct creds_CredentialState *creds; struct netr_DatabaseSync dbsync; struct cli_credentials *machine_account; struct dcerpc_binding *b; struct dcerpc_pipe *p; + const enum netr_SamDatabaseID database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; + int i; /* TODO: This is bogus */ const char **bindings = lp_passwordserver(); @@ -120,8 +148,9 @@ static NTSTATUS libnet_SamDump_netlogon(struct libnet_context *ctx, TALLOC_CTX * r->netlogon.error_string = talloc_asprintf(mem_ctx, "Our join to domain %s is not as a BDC (%d), please rejoin as a BDC", - cli_credentials_get_secure_channel_type(machine_account), - cli_credentials_get_domain(machine_account)); + + cli_credentials_get_domain(machine_account), + cli_credentials_get_secure_channel_type(machine_account)); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } @@ -147,10 +176,11 @@ static NTSTATUS libnet_SamDump_netlogon(struct libnet_context *ctx, TALLOC_CTX * return nt_status; } - /* call domain logon */ + /* get NETLOGON credentails */ nt_status = dcerpc_schannel_creds(p->conn->security_state.generic_state, mem_ctx, &creds); if (!NT_STATUS_IS_OK(nt_status)) { + r->netlogon.error_string = talloc_strdup(mem_ctx, "Could not obtain NETLOGON credentials from DCERPC/GENSEC layer"); return nt_status; } @@ -159,45 +189,70 @@ static NTSTATUS libnet_SamDump_netlogon(struct libnet_context *ctx, TALLOC_CTX * dbsync.in.preferredmaximumlength = (uint32_t)-1; ZERO_STRUCT(dbsync.in.return_authenticator); - dbsync.in.sync_context = 0; - dbsync.in.database_id = SAM_DATABASE_DOMAIN; - - do { - int d; - loop_ctx = talloc_named(mem_ctx, 0, "DatabaseSync loop context"); - creds_client_authenticator(creds, &dbsync.in.credential); - - nt_status = dcerpc_netr_DatabaseSync(p, loop_ctx, &dbsync); - if (!NT_STATUS_IS_OK(nt_status) && - !NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)) { - printf("DatabaseSync - %s\n", nt_errstr(nt_status)); - return nt_status; - } - - if (!creds_client_check(creds, &dbsync.out.return_authenticator.cred)) { - printf("Credential chaining failed\n"); - } + for (i=0;i< ARRAY_SIZE(database_ids); i++) { + dbsync.in.sync_context = 0; + dbsync.in.database_id = database_ids[i]; - dbsync.in.sync_context = dbsync.out.sync_context; - - for (d=0; d < dbsync.out.delta_enum_array->num_deltas; d++) { - delta_ctx = talloc_named(loop_ctx, 0, "DatabaseSync delta context"); - switch (dbsync.out.delta_enum_array->delta_enum[d].delta_type) { - case NETR_DELTA_USER: - if (!vampire_samdump_handle_user(delta_ctx, + do { + int d; + loop_ctx = talloc_named(mem_ctx, 0, "DatabaseSync loop context"); + creds_client_authenticator(creds, &dbsync.in.credential); + + dbsync_nt_status = dcerpc_netr_DatabaseSync(p, loop_ctx, &dbsync); + if (!NT_STATUS_IS_OK(dbsync_nt_status) && + !NT_STATUS_EQUAL(dbsync_nt_status, STATUS_MORE_ENTRIES)) { + r->netlogon.error_string = talloc_asprintf(mem_ctx, "DatabaseSync failed - %s", nt_errstr(nt_status)); + return nt_status; + } + + if (!creds_client_check(creds, &dbsync.out.return_authenticator.cred)) { + r->netlogon.error_string = talloc_strdup(mem_ctx, "Credential chaining failed"); + return NT_STATUS_ACCESS_DENIED; + } + + dbsync.in.sync_context = dbsync.out.sync_context; + + for (d=0; d < dbsync.out.delta_enum_array->num_deltas; d++) { + char *error_string = NULL; + delta_ctx = talloc_named(loop_ctx, 0, "DatabaseSync delta context"); + nt_status = r->netlogon.delta_fn(delta_ctx, + r->netlogon.fn_ctx, creds, - &dbsync.out.delta_enum_array->delta_enum[d])) { - return NT_STATUS_INVALID_PARAMETER; + dbsync.in.database_id, + &dbsync.out.delta_enum_array->delta_enum[d], + &error_string); + if (!NT_STATUS_IS_OK(nt_status)) { + r->netlogon.error_string = talloc_steal(mem_ctx, error_string); + talloc_free(delta_ctx); + return nt_status; } - break; + talloc_free(delta_ctx); } - talloc_free(delta_ctx); - } - talloc_free(loop_ctx); - } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); - return NT_STATUS_OK; + talloc_free(loop_ctx); + } while (NT_STATUS_EQUAL(dbsync_nt_status, STATUS_MORE_ENTRIES)); + nt_status = dbsync_nt_status; + } + return nt_status; +} + +NTSTATUS libnet_SamDump_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamDump *r) +{ + NTSTATUS nt_status; + union libnet_SamSync r2; + + r2.netlogon.level = LIBNET_SAMDUMP_NETLOGON; + r2.netlogon.error_string = NULL; + r2.netlogon.delta_fn = libnet_samdump_fn; + r2.netlogon.fn_ctx = NULL; + nt_status = libnet_SamSync_netlogon(ctx, mem_ctx, &r2); + r->generic.error_string = r2.netlogon.error_string; + + + return nt_status; } + + NTSTATUS libnet_SamDump_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamDump *r) { NTSTATUS nt_status; diff --git a/source4/libnet/libnet_vampire.h b/source4/libnet/libnet_vampire.h index 22ac1606bd..4777f51b0b 100644 --- a/source4/libnet/libnet_vampire.h +++ b/source4/libnet/libnet_vampire.h @@ -21,6 +21,30 @@ #include "librpc/gen_ndr/ndr_netlogon.h" /* struct and enum for doing a remote domain join */ +enum libnet_SamSync_level { + LIBNET_SAMSYNC_GENERIC, + LIBNET_SAMSYNC_NETLOGON, +}; + +union libnet_SamSync { + struct { + enum libnet_SamSync_level level; + char *error_string; + } generic; + + struct { + enum libnet_SamSync_level level; + NTSTATUS (*delta_fn)(TALLOC_CTX *mem_ctx, + void *private, + struct creds_CredentialState *creds, + enum netr_SamDatabaseID database, + struct netr_DELTA_ENUM *delta, + char **error_string); + void *fn_ctx; + char *error_string; + } netlogon; +}; + enum libnet_SamDump_level { LIBNET_SAMDUMP_GENERIC, LIBNET_SAMDUMP_NETLOGON, diff --git a/source4/torture/rpc/samsync.c b/source4/torture/rpc/samsync.c index 6b8b28c060..4690b18ead 100644 --- a/source4/torture/rpc/samsync.c +++ b/source4/torture/rpc/samsync.c @@ -1069,7 +1069,7 @@ static BOOL test_DatabaseSync(struct samsync_state *samsync_state, NTSTATUS status; TALLOC_CTX *loop_ctx, *delta_ctx, *trustdom_ctx; struct netr_DatabaseSync r; - const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; + const enum netr_SamDatabaseID database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; int i, d; BOOL ret = True; struct samsync_trusted_domain *t; |