diff options
Diffstat (limited to 'source4/libnet')
-rw-r--r-- | source4/libnet/libnet_vampire.c | 131 |
1 files changed, 96 insertions, 35 deletions
diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 82209f3361..fb6098ed17 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -30,24 +30,79 @@ static NTSTATUS vampire_samdump_handle_user(TALLOC_CTX *mem_ctx, { uint32_t rid = delta->delta_id_union.rid; struct netr_DELTA_USER *user = delta->delta_union.user; - struct samr_Password lm_hash; - struct samr_Password nt_hash; - struct samr_Password *lm_hash_p = NULL; - struct samr_Password *nt_hash_p = NULL; const char *username = user->account_name.string; char *hex_lm_password; char *hex_nt_password; + hex_lm_password = smbpasswd_sethexpwd(mem_ctx, + user->lm_password_present ? &user->lmpassword : NULL, + user->acct_flags); + hex_nt_password = smbpasswd_sethexpwd(mem_ctx, + user->nt_password_present ? &user->ntpassword : NULL, + user->acct_flags); + + printf("%s:%d:%s:%s:%s:LCT-%08X\n", username, + rid, hex_lm_password, hex_nt_password, + smbpasswd_encode_acb_info(mem_ctx, user->acct_flags), + (unsigned int)nt_time_to_unix(user->last_password_change)); + + 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; +} + +/** + * Decrypt and extract the user's passwords. + * + * The writes decrypted (no longer 'RID encrypted' or arcfour encrypted) passwords back into the structure + */ +static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, + struct creds_CredentialState *creds, + enum netr_SamDatabaseID database, + struct netr_DELTA_ENUM *delta, + char **error_string) +{ + + uint32_t rid = delta->delta_id_union.rid; + struct netr_DELTA_USER *user = delta->delta_union.user; + struct samr_Password lm_hash; + struct samr_Password nt_hash; + const char *username = user->account_name.string; NTSTATUS nt_status; if (user->lm_password_present) { sam_rid_crypt(rid, user->lmpassword.hash, lm_hash.hash, 0); - lm_hash_p = &lm_hash; + user->lmpassword = lm_hash; } if (user->nt_password_present) { sam_rid_crypt(rid, user->ntpassword.hash, nt_hash.hash, 0); - nt_hash_p = &nt_hash; + user->ntpassword = nt_hash; } if (user->user_private_info.SensitiveData) { @@ -56,55 +111,51 @@ static NTSTATUS vampire_samdump_handle_user(TALLOC_CTX *mem_ctx, data.data = user->user_private_info.SensitiveData; data.length = user->user_private_info.DataLength; creds_arcfour_crypt(creds, data.data, data.length); + user->user_private_info.SensitiveData = data.data; + user->user_private_info.DataLength = data.length; + nt_status = ndr_pull_struct_blob(&data, mem_ctx, &keys, (ndr_pull_flags_fn_t)ndr_pull_netr_USER_KEYS); if (NT_STATUS_IS_OK(nt_status)) { if (keys.keys.keys2.lmpassword.length == 16) { sam_rid_crypt(rid, keys.keys.keys2.lmpassword.pwd.hash, lm_hash.hash, 0); - lm_hash_p = &lm_hash; + user->lmpassword = lm_hash; + user->lm_password_present = True; } if (keys.keys.keys2.ntpassword.length == 16) { sam_rid_crypt(rid, keys.keys.keys2.ntpassword.pwd.hash, nt_hash.hash, 0); - nt_hash_p = &nt_hash; + user->ntpassword = nt_hash; + user->nt_password_present = True; } } else { - DEBUG(1, ("Failed to parse Sensitive Data for %s:\n", username)); + *error_string = talloc_asprintf(mem_ctx, "Failed to parse Sensitive Data for %s:\n", username); dump_data(10, data.data, data.length); return nt_status; } } - - hex_lm_password = smbpasswd_sethexpwd(mem_ctx, lm_hash_p, user->acct_flags); - hex_nt_password = smbpasswd_sethexpwd(mem_ctx, nt_hash_p, user->acct_flags); - - printf("%s:%d:%s:%s:%s:LCT-%08X\n", username, - rid, hex_lm_password, hex_nt_password, - smbpasswd_encode_acb_info(mem_ctx, user->acct_flags), - (unsigned int)nt_time_to_unix(user->last_password_change)); - 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) +/** + * Fix up the delta, dealing with encryption issues so that the final + * callback need only do the printing or application logic + */ + +static NTSTATUS fix_delta(TALLOC_CTX *mem_ctx, + 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: { - switch (delta->delta_type) { - case NETR_DELTA_USER: - { - nt_status = vampire_samdump_handle_user(mem_ctx, - creds, - delta); - break; - } - } + nt_status = fix_user(mem_ctx, + creds, + database, + delta, + error_string); break; } } @@ -215,6 +266,16 @@ static NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX * 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 = fix_delta(delta_ctx, + creds, + 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; + } nt_status = r->netlogon.delta_fn(delta_ctx, r->netlogon.fn_ctx, creds, |