From 8bf57cf8f57be28831023c2218d358b24b705256 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 2 May 2005 14:17:19 +0000 Subject: r6573: Start on my project to implement an NT4 compatible BDC in Samba4. This brings in a compatability layer for Samba3 in Samba4 - where we will start to define file formats and similar details. The 'net samdump' command uses 'password server = ' for now, and performs a similar task to Samba3's 'net rpc samsync'. Andrew Bartlett (This used to be commit 550f17f9924fe783917318753de7d1a388423908) --- source4/libnet/libnet_vampire.c | 225 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 source4/libnet/libnet_vampire.c (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c new file mode 100644 index 0000000000..daf7bdfaed --- /dev/null +++ b/source4/libnet/libnet_vampire.c @@ -0,0 +1,225 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Bartlett 2004-2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#include "includes.h" +#include "libnet/libnet.h" +#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) +{ + 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; + + NTSTATUS nt_status; + + if (user->lm_password_present) { + 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; + } + + if (user->user_private_info.SensitiveData) { + DATA_BLOB data; + struct netr_USER_KEYS keys; + data.data = user->user_private_info.SensitiveData; + data.length = user->user_private_info.DataLength; + creds_arcfour_crypt(creds, data.data, 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; + } + 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; + } + } else { + printf("Failed to parse Sensitive Data for %s:\n", username); + dump_data(10, data.data, data.length); + return False; + } + } + + 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 True; +} + + + +static NTSTATUS libnet_SamDump_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamDump *r) +{ + NTSTATUS 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; + + /* TODO: This is bogus */ + const char **bindings = lp_passwordserver(); + const char *binding; + + if (bindings && bindings[0]) { + binding = bindings[0]; + } + + machine_account = cli_credentials_init(mem_ctx); + if (!machine_account) { + return NT_STATUS_NO_MEMORY; + } + + cli_credentials_set_conf(machine_account); + nt_status = cli_credentials_set_machine_account(machine_account); + + if (!NT_STATUS_IS_OK(nt_status)) { + r->netlogon.error_string = talloc_strdup(mem_ctx, "Could not obtain machine account password - are we joined to the domain?"); + return nt_status; + } + + if (cli_credentials_get_secure_channel_type(machine_account) != SEC_CHAN_BDC) { + 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)); + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } + + /* Connect to DC (take a binding string for now) */ + + nt_status = dcerpc_parse_binding(mem_ctx, binding, &b); + if (!NT_STATUS_IS_OK(nt_status)) { + r->netlogon.error_string = talloc_asprintf(mem_ctx, "Bad binding string %s\n", binding); + return NT_STATUS_INVALID_PARAMETER; + } + + /* We like schannel */ + b->flags &= ~DCERPC_AUTH_OPTIONS; + b->flags |= DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_128; + + /* Setup schannel */ + nt_status = dcerpc_pipe_connect_b(mem_ctx, &p, b, + DCERPC_NETLOGON_UUID, + DCERPC_NETLOGON_VERSION, + machine_account); + + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + /* call domain logon */ + + nt_status = dcerpc_schannel_creds(p->conn->security_state.generic_state, mem_ctx, &creds); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + dbsync.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); + dbsync.in.computername = cli_credentials_get_workstation(machine_account); + 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"); + } + + 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, + creds, + &dbsync.out.delta_enum_array->delta_enum[d])) { + return NT_STATUS_INVALID_PARAMETER; + } + break; + } + talloc_free(delta_ctx); + } + talloc_free(loop_ctx); + } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); + return NT_STATUS_OK; +} + +NTSTATUS libnet_SamDump_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamDump *r) +{ + NTSTATUS nt_status; + union libnet_SamDump r2; + + r2.generic.level = LIBNET_SAMDUMP_NETLOGON; + r2.generic.error_string = NULL; + nt_status = libnet_SamDump(ctx, mem_ctx, &r2); + r->generic.error_string = r2.netlogon.error_string; + + + return nt_status; +} + +NTSTATUS libnet_SamDump(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamDump *r) +{ + switch (r->generic.level) { + case LIBNET_SAMDUMP_GENERIC: + return libnet_SamDump_generic(ctx, mem_ctx, r); + case LIBNET_SAMDUMP_NETLOGON: + return libnet_SamDump_netlogon(ctx, mem_ctx, r); + } + + return NT_STATUS_INVALID_LEVEL; +} -- cgit From 35a05d1dc0c551656d9caeea87a9925182d717bc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 3 May 2005 14:38:14 +0000 Subject: 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) --- source4/libnet/libnet_vampire.c | 145 +++++++++++++++++++++++++++------------- 1 file changed, 100 insertions(+), 45 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') 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; -- cgit From ed8144154ae91e588e6bee7350d1d831256803e9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 21 May 2005 05:05:44 +0000 Subject: r6927: Make it easier to program with the SamSync callback interface, perform the decryption seperate to the callback functions. Andrew Bartlett (This used to be commit 4209f813add258bf7d805494fc0220696880a0b0) --- source4/libnet/libnet_vampire.c | 131 +++++++++++++++++++++++++++++----------- 1 file changed, 96 insertions(+), 35 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') 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, -- cgit From c214a612dfd445970f4378ac0374f2a34907cb74 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 21 May 2005 06:31:02 +0000 Subject: r6928: Add support for printing trusted domain names, sids and passwords in the Samba4 'net samdump'. Andrew Bartlett (This used to be commit b7eeea53b2f0e7b3a25a739e6b4774e2505735d3) --- source4/libnet/libnet_vampire.c | 240 +++++++++++++++++++++++++++++++--------- 1 file changed, 188 insertions(+), 52 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index fb6098ed17..69bacb7951 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -1,6 +1,8 @@ /* Unix SMB/CIFS implementation. + Extract the user/system database from a remote SamSync server + Copyright (C) Andrew Bartlett 2004-2005 This program is free software; you can redistribute it and/or modify @@ -23,58 +25,26 @@ #include "libnet/libnet.h" #include "librpc/gen_ndr/ndr_netlogon.h" #include "librpc/gen_ndr/ndr_samr.h" +#include "dlinklist.h" -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; - const char *username = user->account_name.string; - char *hex_lm_password; - char *hex_nt_password; +struct samsync_secret { + struct samsync_secret *prev, *next; + DATA_BLOB secret; + char *name; + NTTIME mtime; +}; - 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); +struct samsync_trusted_domain { + struct samsync_trusted_domain *prev, *next; + struct dom_sid *sid; + char *name; +}; - 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; -} +struct samdump_state { + struct samsync_secret *secrets; + struct samsync_trusted_domain *trusted_domains; +}; -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. @@ -135,6 +105,27 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } +/** + * Decrypt and extract the secrets + * + * The writes decrypted secrets back into the structure + */ +static NTSTATUS fix_secret(TALLOC_CTX *mem_ctx, + struct creds_CredentialState *creds, + enum netr_SamDatabaseID database, + struct netr_DELTA_ENUM *delta, + char **error_string) +{ + struct netr_DELTA_SECRET *secret = delta->delta_union.secret; + creds_arcfour_crypt(creds, secret->current_cipher.cipher_data, + secret->current_cipher.maxlen); + + creds_arcfour_crypt(creds, secret->old_cipher.cipher_data, + secret->old_cipher.maxlen); + + return NT_STATUS_OK; +} + /** * Fix up the delta, dealing with encryption issues so that the final * callback need only do the printing or application logic @@ -158,6 +149,15 @@ static NTSTATUS fix_delta(TALLOC_CTX *mem_ctx, error_string); break; } + case NETR_DELTA_SECRET: + { + nt_status = fix_secret(mem_ctx, + creds, + database, + delta, + error_string); + break; + } } return nt_status; } @@ -215,7 +215,7 @@ static NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX * /* We like schannel */ b->flags &= ~DCERPC_AUTH_OPTIONS; - b->flags |= DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_128; + b->flags |= DCERPC_SCHANNEL | DCERPC_SEAL /* | DCERPC_SCHANNEL_128 */; /* Setup schannel */ nt_status = dcerpc_pipe_connect_b(mem_ctx, &p, b, @@ -296,19 +296,156 @@ static NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX * return nt_status; } +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; + 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 vampire_samdump_handle_secret(TALLOC_CTX *mem_ctx, + struct samdump_state *samdump_state, + struct creds_CredentialState *creds, + struct netr_DELTA_ENUM *delta) +{ + struct netr_DELTA_SECRET *secret = delta->delta_union.secret; + const char *name = delta->delta_id_union.name; + struct samsync_secret *new = talloc(samdump_state, struct samsync_secret); + + new->name = talloc_reference(new, name); + new->secret = data_blob_talloc(new, secret->current_cipher.cipher_data, secret->current_cipher.maxlen); + new->mtime = secret->current_cipher_set_time; + + DLIST_ADD(samdump_state->secrets, new); + + return NT_STATUS_OK; +} + +static NTSTATUS vampire_samdump_handle_trusted_domain(TALLOC_CTX *mem_ctx, + struct samdump_state *samdump_state, + struct creds_CredentialState *creds, + struct netr_DELTA_ENUM *delta) +{ + struct netr_DELTA_TRUSTED_DOMAIN *trusted_domain = delta->delta_union.trusted_domain; + struct dom_sid *dom_sid = delta->delta_id_union.sid; + + struct samsync_trusted_domain *new = talloc(samdump_state, struct samsync_trusted_domain); + + new->name = talloc_reference(new, trusted_domain->domain_name.string); + new->sid = talloc_reference(new, dom_sid); + + DLIST_ADD(samdump_state->trusted_domains, new); + + 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; + struct samdump_state *samdump_state = private; + + *error_string = NULL; + switch (delta->delta_type) { + case NETR_DELTA_USER: + { + /* not interested in builtin users */ + if (database == SAM_DATABASE_DOMAIN) { + nt_status = vampire_samdump_handle_user(mem_ctx, + creds, + delta); + break; + } + } + case NETR_DELTA_SECRET: + { + nt_status = vampire_samdump_handle_secret(mem_ctx, + samdump_state, + creds, + delta); + break; + } + case NETR_DELTA_TRUSTED_DOMAIN: + { + nt_status = vampire_samdump_handle_trusted_domain(mem_ctx, + samdump_state, + creds, + delta); + break; + } + } + 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; + struct samdump_state *samdump_state = talloc(mem_ctx, struct samdump_state); + + struct samsync_trusted_domain *t; + struct samsync_secret *s; + + if (!samdump_state) { + return NT_STATUS_NO_MEMORY; + } + + samdump_state->secrets = NULL; + samdump_state->trusted_domains = NULL; r2.netlogon.level = LIBNET_SAMDUMP_NETLOGON; r2.netlogon.error_string = NULL; r2.netlogon.delta_fn = libnet_samdump_fn; - r2.netlogon.fn_ctx = NULL; + r2.netlogon.fn_ctx = samdump_state; nt_status = libnet_SamSync_netlogon(ctx, mem_ctx, &r2); r->generic.error_string = r2.netlogon.error_string; - + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + printf("Trusted domains, sids and secrets:\n"); + for (t=samdump_state->trusted_domains; t; t=t->next) { + char *secret_name = talloc_asprintf(mem_ctx, "G$$%s", t->name); + for (s=samdump_state->secrets; s; s=s->next) { + if (StrCaseCmp(s->name, secret_name) == 0) { + char *secret_string; + if (convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, + s->secret.data, s->secret.length, + (void **)&secret_string) == -1) { + r->generic.error_string = talloc_asprintf(mem_ctx, + "Could not convert secret for domain %s to a string\n", + t->name); + return NT_STATUS_INVALID_PARAMETER; + } + printf("%s\t%s\t%s\n", + t->name, dom_sid_string(mem_ctx, t->sid), + secret_string); + } + } + } return nt_status; } @@ -318,7 +455,6 @@ NTSTATUS libnet_SamDump_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, { NTSTATUS nt_status; union libnet_SamDump r2; - r2.generic.level = LIBNET_SAMDUMP_NETLOGON; r2.generic.error_string = NULL; nt_status = libnet_SamDump(ctx, mem_ctx, &r2); -- cgit From af237084ecd4f9928c6c282b9c5c73598d5c73d6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 16 Jun 2005 11:36:09 +0000 Subject: r7633: this patch started as an attempt to make the dcerpc code use a given event_context for the socket_connect() call, so that when things that use dcerpc are running alongside anything else it doesn't block the whole process during a connect. Then of course I needed to change any code that created a dcerpc connection (such as the auth code) to also take an event context, and anything that called that and so on .... thus the size of the patch. There were 3 places where I punted: - abartlet wanted me to add a gensec_set_event_context() call instead of adding it to the gensec init calls. Andrew, my apologies for not doing this. I didn't do it as adding a new parameter allowed me to catch all the callers with the compiler. Now that its done, we could go back and use gensec_set_event_context() - the ejs code calls auth initialisation, which means it should pass in the event context from the web server. I punted on that. Needs fixing. - I used a NULL event context in dcom_get_pipe(). This is equivalent to what we did already, but should be fixed to use a callers event context. Jelmer, can you think of a clean way to do that? I also cleaned up a couple of things: - libnet_context_destroy() makes no sense. I removed it. - removed some unused vars in various places (This used to be commit 3a3025485bdb8f600ab528c0b4b4eef0c65e3fc9) --- source4/libnet/libnet_vampire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 69bacb7951..79f07c05f3 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -221,7 +221,7 @@ static NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX * nt_status = dcerpc_pipe_connect_b(mem_ctx, &p, b, DCERPC_NETLOGON_UUID, DCERPC_NETLOGON_VERSION, - machine_account); + machine_account, ctx->event_ctx); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; -- cgit From 44ff3305f8ddc2caa9962a48ce5d3f4e2bd883ef Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 25 Jul 2005 01:19:16 +0000 Subject: r8741: Kill warnings about enums not fully enumerated, as we will never use all the branches. Andrew Bartlett (This used to be commit 258e5e302e461d789e5c353e1a0d81ce33b52f6b) --- source4/libnet/libnet_vampire.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 79f07c05f3..2e93a45966 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -158,6 +158,8 @@ static NTSTATUS fix_delta(TALLOC_CTX *mem_ctx, error_string); break; } + default: + break; } return nt_status; } @@ -395,6 +397,9 @@ static NTSTATUS libnet_samdump_fn(TALLOC_CTX *mem_ctx, delta); break; } + default: + /* Can't dump them all right now */ + break; } return nt_status; } -- cgit From 82f96542fa457b57bd7e7a4db69b950f6f025cca Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 25 Jul 2005 02:23:41 +0000 Subject: r8744: Split 'net samdump' out into a separate file Work on the talloc memory tree, as I think talloc_reference and other things were biting me. Crush unions in the name of code reform. ;-) Andrew Bartlett (This used to be commit 2eadcf46699f1cc7adb2066e17096f70c7b73998) --- source4/libnet/libnet_vampire.c | 272 +++++++--------------------------------- 1 file changed, 42 insertions(+), 230 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 2e93a45966..f4be5013f1 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -25,25 +25,6 @@ #include "libnet/libnet.h" #include "librpc/gen_ndr/ndr_netlogon.h" #include "librpc/gen_ndr/ndr_samr.h" -#include "dlinklist.h" - -struct samsync_secret { - struct samsync_secret *prev, *next; - DATA_BLOB secret; - char *name; - NTTIME mtime; -}; - -struct samsync_trusted_domain { - struct samsync_trusted_domain *prev, *next; - struct dom_sid *sid; - char *name; -}; - -struct samdump_state { - struct samsync_secret *secrets; - struct samsync_trusted_domain *trusted_domains; -}; /** @@ -164,10 +145,10 @@ static NTSTATUS fix_delta(TALLOC_CTX *mem_ctx, return nt_status; } -static NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamSync *r) +NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_SamSync *r) { NTSTATUS nt_status, dbsync_nt_status; - TALLOC_CTX *loop_ctx, *delta_ctx; + TALLOC_CTX *samsync_ctx, *loop_ctx, *delta_ctx; struct creds_CredentialState *creds; struct netr_DatabaseSync dbsync; struct cli_credentials *machine_account; @@ -184,34 +165,42 @@ static NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX * binding = bindings[0]; } - machine_account = cli_credentials_init(mem_ctx); - if (!machine_account) { - return NT_STATUS_NO_MEMORY; - } + samsync_ctx = talloc_named(mem_ctx, 0, "SamSync top context"); - cli_credentials_set_conf(machine_account); - nt_status = cli_credentials_set_machine_account(machine_account); - - if (!NT_STATUS_IS_OK(nt_status)) { - r->netlogon.error_string = talloc_strdup(mem_ctx, "Could not obtain machine account password - are we joined to the domain?"); - return nt_status; + if (!r->machine_account) { + machine_account = cli_credentials_init(samsync_ctx); + if (!machine_account) { + talloc_free(samsync_ctx); + return NT_STATUS_NO_MEMORY; + } + cli_credentials_set_conf(machine_account); + nt_status = cli_credentials_set_machine_account(machine_account); + if (!NT_STATUS_IS_OK(nt_status)) { + r->error_string = talloc_strdup(mem_ctx, "Could not obtain machine account password - are we joined to the domain?"); + talloc_free(samsync_ctx); + return nt_status; + } + } else { + machine_account = r->machine_account; } - + if (cli_credentials_get_secure_channel_type(machine_account) != SEC_CHAN_BDC) { - r->netlogon.error_string + r->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_domain(machine_account), cli_credentials_get_secure_channel_type(machine_account)); + talloc_free(samsync_ctx); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } /* Connect to DC (take a binding string for now) */ - nt_status = dcerpc_parse_binding(mem_ctx, binding, &b); + nt_status = dcerpc_parse_binding(samsync_ctx, binding, &b); if (!NT_STATUS_IS_OK(nt_status)) { - r->netlogon.error_string = talloc_asprintf(mem_ctx, "Bad binding string %s\n", binding); + r->error_string = talloc_asprintf(mem_ctx, "Bad binding string %s\n", binding); + talloc_free(samsync_ctx); return NT_STATUS_INVALID_PARAMETER; } @@ -220,24 +209,26 @@ static NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX * b->flags |= DCERPC_SCHANNEL | DCERPC_SEAL /* | DCERPC_SCHANNEL_128 */; /* Setup schannel */ - nt_status = dcerpc_pipe_connect_b(mem_ctx, &p, b, + nt_status = dcerpc_pipe_connect_b(samsync_ctx, &p, b, DCERPC_NETLOGON_UUID, DCERPC_NETLOGON_VERSION, machine_account, ctx->event_ctx); if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(samsync_ctx); return nt_status; } /* get NETLOGON credentails */ - nt_status = dcerpc_schannel_creds(p->conn->security_state.generic_state, mem_ctx, &creds); + nt_status = dcerpc_schannel_creds(p->conn->security_state.generic_state, samsync_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"); + r->error_string = talloc_strdup(mem_ctx, "Could not obtain NETLOGON credentials from DCERPC/GENSEC layer"); + talloc_free(samsync_ctx); return nt_status; } - dbsync.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); + dbsync.in.logon_server = talloc_asprintf(samsync_ctx, "\\\\%s", dcerpc_server_name(p)); dbsync.in.computername = cli_credentials_get_workstation(machine_account); dbsync.in.preferredmaximumlength = (uint32_t)-1; ZERO_STRUCT(dbsync.in.return_authenticator); @@ -248,18 +239,20 @@ static NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX * do { int d; - loop_ctx = talloc_named(mem_ctx, 0, "DatabaseSync loop context"); + loop_ctx = talloc_named(samsync_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)); + r->error_string = talloc_asprintf(samsync_ctx, "DatabaseSync failed - %s", nt_errstr(nt_status)); + talloc_free(samsync_ctx); return nt_status; } if (!creds_client_check(creds, &dbsync.out.return_authenticator.cred)) { - r->netlogon.error_string = talloc_strdup(mem_ctx, "Credential chaining failed"); + r->error_string = talloc_strdup(samsync_ctx, "Credential chaining failed"); + talloc_free(samsync_ctx); return NT_STATUS_ACCESS_DENIED; } @@ -274,19 +267,19 @@ static NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX * &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); + r->error_string = talloc_steal(samsync_ctx, error_string); + talloc_free(samsync_ctx); return nt_status; } - nt_status = r->netlogon.delta_fn(delta_ctx, - r->netlogon.fn_ctx, + nt_status = r->delta_fn(delta_ctx, + r->fn_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); + r->error_string = talloc_steal(samsync_ctx, error_string); + talloc_free(samsync_ctx); return nt_status; } talloc_free(delta_ctx); @@ -295,188 +288,7 @@ static NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX * } while (NT_STATUS_EQUAL(dbsync_nt_status, STATUS_MORE_ENTRIES)); nt_status = dbsync_nt_status; } + talloc_free(samsync_ctx); return nt_status; } -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; - 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 vampire_samdump_handle_secret(TALLOC_CTX *mem_ctx, - struct samdump_state *samdump_state, - struct creds_CredentialState *creds, - struct netr_DELTA_ENUM *delta) -{ - struct netr_DELTA_SECRET *secret = delta->delta_union.secret; - const char *name = delta->delta_id_union.name; - struct samsync_secret *new = talloc(samdump_state, struct samsync_secret); - - new->name = talloc_reference(new, name); - new->secret = data_blob_talloc(new, secret->current_cipher.cipher_data, secret->current_cipher.maxlen); - new->mtime = secret->current_cipher_set_time; - - DLIST_ADD(samdump_state->secrets, new); - - return NT_STATUS_OK; -} - -static NTSTATUS vampire_samdump_handle_trusted_domain(TALLOC_CTX *mem_ctx, - struct samdump_state *samdump_state, - struct creds_CredentialState *creds, - struct netr_DELTA_ENUM *delta) -{ - struct netr_DELTA_TRUSTED_DOMAIN *trusted_domain = delta->delta_union.trusted_domain; - struct dom_sid *dom_sid = delta->delta_id_union.sid; - - struct samsync_trusted_domain *new = talloc(samdump_state, struct samsync_trusted_domain); - - new->name = talloc_reference(new, trusted_domain->domain_name.string); - new->sid = talloc_reference(new, dom_sid); - - DLIST_ADD(samdump_state->trusted_domains, new); - - 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; - struct samdump_state *samdump_state = private; - - *error_string = NULL; - switch (delta->delta_type) { - case NETR_DELTA_USER: - { - /* not interested in builtin users */ - if (database == SAM_DATABASE_DOMAIN) { - nt_status = vampire_samdump_handle_user(mem_ctx, - creds, - delta); - break; - } - } - case NETR_DELTA_SECRET: - { - nt_status = vampire_samdump_handle_secret(mem_ctx, - samdump_state, - creds, - delta); - break; - } - case NETR_DELTA_TRUSTED_DOMAIN: - { - nt_status = vampire_samdump_handle_trusted_domain(mem_ctx, - samdump_state, - creds, - delta); - break; - } - default: - /* Can't dump them all right now */ - break; - } - 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; - struct samdump_state *samdump_state = talloc(mem_ctx, struct samdump_state); - - struct samsync_trusted_domain *t; - struct samsync_secret *s; - - if (!samdump_state) { - return NT_STATUS_NO_MEMORY; - } - - samdump_state->secrets = NULL; - samdump_state->trusted_domains = NULL; - - r2.netlogon.level = LIBNET_SAMDUMP_NETLOGON; - r2.netlogon.error_string = NULL; - r2.netlogon.delta_fn = libnet_samdump_fn; - r2.netlogon.fn_ctx = samdump_state; - nt_status = libnet_SamSync_netlogon(ctx, mem_ctx, &r2); - r->generic.error_string = r2.netlogon.error_string; - - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - printf("Trusted domains, sids and secrets:\n"); - for (t=samdump_state->trusted_domains; t; t=t->next) { - char *secret_name = talloc_asprintf(mem_ctx, "G$$%s", t->name); - for (s=samdump_state->secrets; s; s=s->next) { - if (StrCaseCmp(s->name, secret_name) == 0) { - char *secret_string; - if (convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, - s->secret.data, s->secret.length, - (void **)&secret_string) == -1) { - r->generic.error_string = talloc_asprintf(mem_ctx, - "Could not convert secret for domain %s to a string\n", - t->name); - return NT_STATUS_INVALID_PARAMETER; - } - printf("%s\t%s\t%s\n", - t->name, dom_sid_string(mem_ctx, t->sid), - secret_string); - } - } - } - return nt_status; -} - - - -NTSTATUS libnet_SamDump_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamDump *r) -{ - NTSTATUS nt_status; - union libnet_SamDump r2; - r2.generic.level = LIBNET_SAMDUMP_NETLOGON; - r2.generic.error_string = NULL; - nt_status = libnet_SamDump(ctx, mem_ctx, &r2); - r->generic.error_string = r2.netlogon.error_string; - - - return nt_status; -} - -NTSTATUS libnet_SamDump(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamDump *r) -{ - switch (r->generic.level) { - case LIBNET_SAMDUMP_GENERIC: - return libnet_SamDump_generic(ctx, mem_ctx, r); - case LIBNET_SAMDUMP_NETLOGON: - return libnet_SamDump_netlogon(ctx, mem_ctx, r); - } - - return NT_STATUS_INVALID_LEVEL; -} -- cgit From 4e65f39ca95ee63cd07801578c49af9cb813e316 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 31 Oct 2005 03:06:13 +0000 Subject: r11409: The use of 'password server = ' here is still bogus, but for now at least don't allow binding to become uninitialised. Andrew Bartlett (This used to be commit e754234a17ebc601720caa66a229d9a842dfebda) --- source4/libnet/libnet_vampire.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index f4be5013f1..80da646200 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -163,6 +163,8 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx if (bindings && bindings[0]) { binding = bindings[0]; + } else { + return NT_STATUS_INVALID_PARAMETER; } samsync_ctx = talloc_named(mem_ctx, 0, "SamSync top context"); -- cgit From acd6a086b341096fcbea1775ce748587fcc8020a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Dec 2005 14:28:01 +0000 Subject: r12510: Change the DCE/RPC interfaces to take a pointer to a dcerpc_interface_table struct rather then a tuple of interface name, UUID and version. This removes the requirement for having a global list of DCE/RPC interfaces, except for these parts of the code that use that list explicitly (ndrdump and the scanner torture test). This should also allow us to remove the hack that put the authservice parameter in the dcerpc_binding struct as it can now be read directly from dcerpc_interface_table. I will now modify some of these functions to take a dcerpc_syntax_id structure rather then a full dcerpc_interface_table. (This used to be commit 8aae0f168e54c01d0866ad6e0da141dbd828574f) --- source4/libnet/libnet_vampire.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 80da646200..d0b7722c08 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -212,8 +212,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx /* Setup schannel */ nt_status = dcerpc_pipe_connect_b(samsync_ctx, &p, b, - DCERPC_NETLOGON_UUID, - DCERPC_NETLOGON_VERSION, + &dcerpc_table_netlogon, machine_account, ctx->event_ctx); if (!NT_STATUS_IS_OK(nt_status)) { -- cgit From d4de4c2d210d2e8c9b5aedf70695594809ad6a0b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 30 Dec 2005 13:16:54 +0000 Subject: r12608: Remove some unused #include lines. (This used to be commit 70e7449318aa0e9d2639c76730a7d1683b2f4981) --- source4/libnet/libnet_vampire.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index d0b7722c08..d9c25d053e 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -23,8 +23,6 @@ #include "includes.h" #include "libnet/libnet.h" -#include "librpc/gen_ndr/ndr_netlogon.h" -#include "librpc/gen_ndr/ndr_samr.h" /** -- cgit From b135f4467f8413f6ac44df54b8430305f6c26c0c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 12 Jan 2006 03:02:00 +0000 Subject: r12858: This moves the libnet_LookupPdc code to use a GetDC request to find the remote server's name, or in the absence of a local nbt_server to communicate with (or without root access), a node status request. The result is that we are in a better position to use kerberos, as well as to remove the 'password server' mandatory parameter for the samsync and samdump commands. (I need this to put these into SWAT). The only problem I have is that I must create a messaging context, which requires a server ID. As a client process, I don't expect to get messages, but it is currently required for replies, so I generate a random() number. We probably need the servers to accept connections on streamed sockets too, for client-only tasks that want IRPC. Because I wanted to test this code, I have put the NET-API-* tests into our test scripts, to ensure they pass and keep passing. They are good frontends onto the libnet system, and I see no reason not to test them. In doing so the NET-API-RPCCONNECT test was simplified to take a binding string on the command line, removing duplicate code, and testing the combinations in the scripts instead. (I have done a bit of work on the list shares code in libnet_share.c to make it pass 'make test') In the future, I would like to extend the libcli/findds.c code (based off volker's winbind/wb_async_helpers.c, which is why it shows up a bit odd in the patch) to handle getting multiple name replies, sending a getdc request to each in turn. (posted to samba-technical for review, and I'll happily update with any comments) Andrew Bartlett (This used to be commit 7ccddfd3515fc2c0d6f447c768ccbf7a220c3380) --- source4/libnet/libnet_vampire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index d9c25d053e..dc271ba577 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -210,7 +210,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx /* Setup schannel */ nt_status = dcerpc_pipe_connect_b(samsync_ctx, &p, b, - &dcerpc_table_netlogon, + &dcerpc_table_netlogon, machine_account, ctx->event_ctx); if (!NT_STATUS_IS_OK(nt_status)) { -- cgit From a5a79e8b8cbdf24d5c2db45ece4110ed5d85e58f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 12 Jan 2006 09:33:49 +0000 Subject: r12865: Upgrade the librpc and libnet code. In librpc, always try SMB level authentication, even if trying schannel, but allow fallback to anonymous. This should better function with servers that set restrict anonymous. There are too many parts of Samba that get, parse and modify the binding parameters. Avoid the extra work, and add a binding element to the struct dcerpc_pipe The libnet vampire code has been refactored, to reduce extra layers and to better conform with the standard argument pattern. Also, take advantage of the new libnet_Lookup code, so we don't require the silly 'password server' smb.conf parameter. To better support forcing traffic to be sealed for the vampire operation, the dcerpc_bind_auth() function now takes an auth level parameter. Andrew Bartlett (This used to be commit d65b354959842326fdd4bd7eb7fbeea0390f4afa) --- source4/libnet/libnet_vampire.c | 116 +++++++++++++++++++++++++++------------- 1 file changed, 79 insertions(+), 37 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index dc271ba577..26e3939205 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -150,24 +150,15 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx struct creds_CredentialState *creds; struct netr_DatabaseSync dbsync; struct cli_credentials *machine_account; - struct dcerpc_binding *b; struct dcerpc_pipe *p; + struct libnet_context *machine_net_ctx; + struct libnet_RpcConnect *c; 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(); - const char *binding; - - if (bindings && bindings[0]) { - binding = bindings[0]; - } else { - return NT_STATUS_INVALID_PARAMETER; - } - samsync_ctx = talloc_named(mem_ctx, 0, "SamSync top context"); - if (!r->machine_account) { + if (!r->in.machine_account) { machine_account = cli_credentials_init(samsync_ctx); if (!machine_account) { talloc_free(samsync_ctx); @@ -176,16 +167,17 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx cli_credentials_set_conf(machine_account); nt_status = cli_credentials_set_machine_account(machine_account); if (!NT_STATUS_IS_OK(nt_status)) { - r->error_string = talloc_strdup(mem_ctx, "Could not obtain machine account password - are we joined to the domain?"); + r->out.error_string = talloc_strdup(mem_ctx, "Could not obtain machine account password - are we joined to the domain?"); talloc_free(samsync_ctx); return nt_status; } } else { - machine_account = r->machine_account; + machine_account = r->in.machine_account; } + /* We cannot do this unless we are a BDC. Check, before we get odd errors later */ if (cli_credentials_get_secure_channel_type(machine_account) != SEC_CHAN_BDC) { - r->error_string + r->out.error_string = talloc_asprintf(mem_ctx, "Our join to domain %s is not as a BDC (%d), please rejoin as a BDC", @@ -195,25 +187,67 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } - /* Connect to DC (take a binding string for now) */ + c = talloc(samsync_ctx, struct libnet_RpcConnect); + if (!c) { + r->out.error_string = NULL; + talloc_free(samsync_ctx); + return NT_STATUS_NO_MEMORY; + } + + if (r->in.binding_string) { + c->level = LIBNET_RPC_CONNECT_BINDING; + c->in.binding = r->in.binding_string; + } else { + /* prepare connect to the NETLOGON pipe of PDC */ + c->level = LIBNET_RPC_CONNECT_PDC; + c->in.name = cli_credentials_get_domain(machine_account); + } + c->in.dcerpc_iface = &dcerpc_table_netlogon; + + /* We must do this as the machine, not as any command-line + * user. So we override the credentials in the + * libnet_context */ + machine_net_ctx = talloc(samsync_ctx, struct libnet_context); + if (!machine_net_ctx) { + r->out.error_string = NULL; + talloc_free(samsync_ctx); + return NT_STATUS_NO_MEMORY; + } + *machine_net_ctx = *ctx; + machine_net_ctx->cred = machine_account; - nt_status = dcerpc_parse_binding(samsync_ctx, binding, &b); + /* connect to the NETLOGON pipe of the PDC */ + nt_status = libnet_RpcConnect(machine_net_ctx, c, c); if (!NT_STATUS_IS_OK(nt_status)) { - r->error_string = talloc_asprintf(mem_ctx, "Bad binding string %s\n", binding); + r->out.error_string = talloc_asprintf(mem_ctx, + "Connection to NETLOGON pipe of DC failed: %s", + c->out.error_string); talloc_free(samsync_ctx); - return NT_STATUS_INVALID_PARAMETER; + return nt_status; } - /* We like schannel */ - b->flags &= ~DCERPC_AUTH_OPTIONS; - b->flags |= DCERPC_SCHANNEL | DCERPC_SEAL /* | DCERPC_SCHANNEL_128 */; + /* This makes a new pipe, on which we can do schannel. We + * should do this in the RpcConnect code, but the abstaction + * layers do not suit yet */ + + nt_status = dcerpc_secondary_connection(c->out.dcerpc_pipe, &p, + c->out.dcerpc_pipe->binding); + + if (!NT_STATUS_IS_OK(nt_status)) { + r->out.error_string = talloc_asprintf(mem_ctx, + "Secondary connection to NETLOGON pipe of DC %s failed: %s", + dcerpc_server_name(p), nt_errstr(nt_status)); + talloc_free(samsync_ctx); + return nt_status; + } - /* Setup schannel */ - nt_status = dcerpc_pipe_connect_b(samsync_ctx, &p, b, - &dcerpc_table_netlogon, - machine_account, ctx->event_ctx); + nt_status = dcerpc_bind_auth_schannel(samsync_ctx, p, &dcerpc_table_netlogon, + machine_account, DCERPC_AUTH_LEVEL_PRIVACY); if (!NT_STATUS_IS_OK(nt_status)) { + r->out.error_string = talloc_asprintf(mem_ctx, + "SCHANNEL authentication to NETLOGON pipe of DC %s failed: %s", + dcerpc_server_name(p), nt_errstr(nt_status)); talloc_free(samsync_ctx); return nt_status; } @@ -222,11 +256,12 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx nt_status = dcerpc_schannel_creds(p->conn->security_state.generic_state, samsync_ctx, &creds); if (!NT_STATUS_IS_OK(nt_status)) { - r->error_string = talloc_strdup(mem_ctx, "Could not obtain NETLOGON credentials from DCERPC/GENSEC layer"); + r->out.error_string = talloc_strdup(mem_ctx, "Could not obtain NETLOGON credentials from DCERPC/GENSEC layer"); talloc_free(samsync_ctx); return nt_status; } + /* Setup details for the syncronisation */ dbsync.in.logon_server = talloc_asprintf(samsync_ctx, "\\\\%s", dcerpc_server_name(p)); dbsync.in.computername = cli_credentials_get_workstation(machine_account); dbsync.in.preferredmaximumlength = (uint32_t)-1; @@ -244,40 +279,47 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx 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->error_string = talloc_asprintf(samsync_ctx, "DatabaseSync failed - %s", nt_errstr(nt_status)); + r->out.error_string = talloc_asprintf(samsync_ctx, "DatabaseSync failed - %s", nt_errstr(nt_status)); talloc_free(samsync_ctx); return nt_status; } if (!creds_client_check(creds, &dbsync.out.return_authenticator.cred)) { - r->error_string = talloc_strdup(samsync_ctx, "Credential chaining failed"); + r->out.error_string = talloc_strdup(samsync_ctx, "Credential chaining failed"); talloc_free(samsync_ctx); return NT_STATUS_ACCESS_DENIED; } dbsync.in.sync_context = dbsync.out.sync_context; + /* For every single remote 'delta' entry: */ 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"); + /* 'Fix' elements, by decrypting and + * de-obfustiating the data */ 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->error_string = talloc_steal(samsync_ctx, error_string); + r->out.error_string = talloc_steal(samsync_ctx, error_string); talloc_free(samsync_ctx); return nt_status; } - nt_status = r->delta_fn(delta_ctx, - r->fn_ctx, - creds, - dbsync.in.database_id, - &dbsync.out.delta_enum_array->delta_enum[d], - &error_string); + + /* Now call the callback. This will + * do something like print the data or + * write to an ldb */ + nt_status = r->in.delta_fn(delta_ctx, + r->in.fn_ctx, + creds, + dbsync.in.database_id, + &dbsync.out.delta_enum_array->delta_enum[d], + &error_string); if (!NT_STATUS_IS_OK(nt_status)) { - r->error_string = talloc_steal(samsync_ctx, error_string); + r->out.error_string = talloc_steal(samsync_ctx, error_string); talloc_free(samsync_ctx); return nt_status; } -- cgit From e0f69bf1d379d3026f4528f813adf96163738e58 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 12 Jan 2006 21:42:26 +0000 Subject: r12872: Add some more detail to debug message. Andrew Bartlett (This used to be commit cefba10bd5ed1f6d10a071e4239088d91f661a36) --- source4/libnet/libnet_vampire.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 26e3939205..da8c3b49d1 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -219,9 +219,15 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx /* connect to the NETLOGON pipe of the PDC */ nt_status = libnet_RpcConnect(machine_net_ctx, c, c); if (!NT_STATUS_IS_OK(nt_status)) { - r->out.error_string = talloc_asprintf(mem_ctx, - "Connection to NETLOGON pipe of DC failed: %s", - c->out.error_string); + if (r->in.binding_string) { + r->out.error_string = talloc_asprintf(mem_ctx, + "Connection to NETLOGON pipe of DC %s failed: %s", + r->in.binding_string, c->out.error_string); + } else { + r->out.error_string = talloc_asprintf(mem_ctx, + "Connection to NETLOGON pipe of DC for %s failed: %s", + c->in.name, c->out.error_string); + } talloc_free(samsync_ctx); return nt_status; } -- cgit From b15582ed816f3d477f978976f43b82cfa90bf6dc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 13 Jan 2006 12:52:56 +0000 Subject: r12903: Factor out a new routine libnet_RpcConnectDCInfo, to both connect to the remote sever, and to query it for domain information. Provide and use this information in the SamSync/Vampire callbacks, to allow a parallel connection to LDAP, if we are talking to AD. This allows us to get at some important attributes not exposed in the old protocol. With this, we are able to do a all-GUI vampire of a AD domain from SWAT, including getting all the SIDs, servicePrincipalNames and the like correct. Andrew Bartlett (This used to be commit 918358cee0b4a1b2c9bc9e68d9d53428a634281e) --- source4/libnet/libnet_vampire.c | 43 ++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index da8c3b49d1..b9fb37fea6 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -152,7 +152,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx struct cli_credentials *machine_account; struct dcerpc_pipe *p; struct libnet_context *machine_net_ctx; - struct libnet_RpcConnect *c; + struct libnet_RpcConnectDCInfo *c; const enum netr_SamDatabaseID database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; int i; @@ -187,7 +187,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } - c = talloc(samsync_ctx, struct libnet_RpcConnect); + c = talloc(samsync_ctx, struct libnet_RpcConnectDCInfo); if (!c) { r->out.error_string = NULL; talloc_free(samsync_ctx); @@ -217,7 +217,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx machine_net_ctx->cred = machine_account; /* connect to the NETLOGON pipe of the PDC */ - nt_status = libnet_RpcConnect(machine_net_ctx, c, c); + nt_status = libnet_RpcConnectDCInfo(machine_net_ctx, c); if (!NT_STATUS_IS_OK(nt_status)) { if (r->in.binding_string) { r->out.error_string = talloc_asprintf(mem_ctx, @@ -258,6 +258,26 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx return nt_status; } + /* initialise the callback layer. It may wish to contact the + * server with ldap, now we know the name */ + + if (r->in.init_fn) { + char *error_string; + nt_status = r->in.init_fn(samsync_ctx, + r->in.fn_ctx, + machine_net_ctx, + p, + c->out.domain_name, + c->out.domain_sid, + c->out.realm, + &error_string); + if (!NT_STATUS_IS_OK(nt_status)) { + r->out.error_string = talloc_steal(mem_ctx, error_string); + talloc_free(samsync_ctx); + return nt_status; + } + } + /* get NETLOGON credentails */ nt_status = dcerpc_schannel_creds(p->conn->security_state.generic_state, samsync_ctx, &creds); @@ -285,13 +305,13 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx 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->out.error_string = talloc_asprintf(samsync_ctx, "DatabaseSync failed - %s", nt_errstr(nt_status)); + r->out.error_string = talloc_asprintf(mem_ctx, "DatabaseSync failed - %s", nt_errstr(nt_status)); talloc_free(samsync_ctx); return nt_status; } if (!creds_client_check(creds, &dbsync.out.return_authenticator.cred)) { - r->out.error_string = talloc_strdup(samsync_ctx, "Credential chaining failed"); + r->out.error_string = talloc_strdup(mem_ctx, "Credential chaining on incoming DatabaseSync failed"); talloc_free(samsync_ctx); return NT_STATUS_ACCESS_DENIED; } @@ -310,7 +330,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx &dbsync.out.delta_enum_array->delta_enum[d], &error_string); if (!NT_STATUS_IS_OK(nt_status)) { - r->out.error_string = talloc_steal(samsync_ctx, error_string); + r->out.error_string = talloc_steal(mem_ctx, error_string); talloc_free(samsync_ctx); return nt_status; } @@ -320,12 +340,11 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx * write to an ldb */ nt_status = r->in.delta_fn(delta_ctx, r->in.fn_ctx, - creds, dbsync.in.database_id, &dbsync.out.delta_enum_array->delta_enum[d], &error_string); if (!NT_STATUS_IS_OK(nt_status)) { - r->out.error_string = talloc_steal(samsync_ctx, error_string); + r->out.error_string = talloc_steal(mem_ctx, error_string); talloc_free(samsync_ctx); return nt_status; } @@ -333,7 +352,13 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx } talloc_free(loop_ctx); } while (NT_STATUS_EQUAL(dbsync_nt_status, STATUS_MORE_ENTRIES)); - nt_status = dbsync_nt_status; + + if (!NT_STATUS_IS_OK(dbsync_nt_status)) { + r->out.error_string = talloc_asprintf(mem_ctx, "libnet_SamSync_netlogon failed: unexpected inconsistancy. Should not get error %s here", nt_errstr(nt_status)); + talloc_free(samsync_ctx); + return dbsync_nt_status; + } + nt_status = NT_STATUS_OK; } talloc_free(samsync_ctx); return nt_status; -- cgit From dcd63b97702fa5a5945a500acc4b65de0aa74927 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 14 Jan 2006 01:29:38 +0000 Subject: r12926: Syncronsise GUIDs on users and domains from the server. These also appear in DNS, so need to match. Andrew Bartlett (This used to be commit d092b0493d7c61112ef132c8fb259c15f189c5f6) --- source4/libnet/libnet_vampire.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index b9fb37fea6..ce65a6e460 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -153,6 +153,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx struct dcerpc_pipe *p; struct libnet_context *machine_net_ctx; struct libnet_RpcConnectDCInfo *c; + struct libnet_SamSync_state *state; const enum netr_SamDatabaseID database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; int i; @@ -258,6 +259,20 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx return nt_status; } + state = talloc(samsync_ctx, struct libnet_SamSync_state); + if (!state) { + r->out.error_string = NULL; + talloc_free(samsync_ctx); + return nt_status; + } + + state->domain_name = c->out.domain_name; + state->domain_sid = c->out.domain_sid; + state->realm = c->out.realm; + state->domain_guid = c->out.guid; + state->machine_net_ctx = machine_net_ctx; + state->netlogon_pipe = p; + /* initialise the callback layer. It may wish to contact the * server with ldap, now we know the name */ @@ -265,11 +280,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx char *error_string; nt_status = r->in.init_fn(samsync_ctx, r->in.fn_ctx, - machine_net_ctx, - p, - c->out.domain_name, - c->out.domain_sid, - c->out.realm, + state, &error_string); if (!NT_STATUS_IS_OK(nt_status)) { r->out.error_string = talloc_steal(mem_ctx, error_string); -- cgit From ba564a901e519b0f2cf2b7651bd260f618506b5c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 6 Mar 2006 23:28:18 +0000 Subject: r13903: Don't generate prototypes for modules and binaries in include/proto.h by default. (This used to be commit c80a8f1102caf744b66c13bebde38fba74983dc4) --- source4/libnet/libnet_vampire.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index ce65a6e460..c76f8f7cde 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libnet/libnet.h" +#include "auth/gensec/schannel_proto.h" /** -- cgit From 4ac2be99588b48b0652a524bf12fb1aa9c3f5fbb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 11:07:23 +0000 Subject: r13924: Split more prototypes out of include/proto.h + initial work on header file dependencies (This used to be commit 122835876748a3eaf5e8d31ad1abddab9acb8781) --- source4/libnet/libnet_vampire.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index c76f8f7cde..b425926e99 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -24,6 +24,7 @@ #include "includes.h" #include "libnet/libnet.h" #include "auth/gensec/schannel_proto.h" +#include "libcli/auth/proto.h" /** -- cgit From 3f16241a1d3243447d0244ebac05b447aec94df8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 14 Mar 2006 01:29:56 +0000 Subject: r14363: Remove credentials.h from the global includes. (This used to be commit 98c4c3051391c6f89df5d133665f51bef66b1563) --- source4/libnet/libnet_vampire.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index b425926e99..e92dbc281d 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libnet/libnet.h" +#include "auth/credentials/credentials.h" #include "auth/gensec/schannel_proto.h" #include "libcli/auth/proto.h" -- cgit From e3f2414cf9e582a4e4deecc662b64a7bb2679a34 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 14 Mar 2006 15:03:25 +0000 Subject: r14380: Reduce the size of structs.h (This used to be commit 1a16a6f1dfa66499af43a6b88b3ea69a6a75f1fe) --- source4/libnet/libnet_vampire.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index e92dbc281d..93e752311f 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -23,9 +23,8 @@ #include "includes.h" #include "libnet/libnet.h" -#include "auth/credentials/credentials.h" +#include "libcli/auth/libcli_auth.h" #include "auth/gensec/schannel_proto.h" -#include "libcli/auth/proto.h" /** -- cgit From 1060f6b3f621cb70b075a879f129e57f10fdbf8a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 14 Mar 2006 23:35:30 +0000 Subject: r14402: Generate seperate headers for RPC client functions. (This used to be commit 7054ebf0249930843a2baf4d023ae8f62cedb109) --- source4/libnet/libnet_vampire.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 93e752311f..352dde27e6 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -25,6 +25,7 @@ #include "libnet/libnet.h" #include "libcli/auth/libcli_auth.h" #include "auth/gensec/schannel_proto.h" +#include "librpc/gen_ndr/ndr_netlogon_c.h" /** -- cgit From 8528016978b084213ef53d66e1b6e831b1a01acc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 16 Mar 2006 00:23:11 +0000 Subject: r14464: Don't include ndr_BASENAME.h files unless strictly required, instead try to include just the BASENAME.h files (containing only structs) (This used to be commit 3dd477ca5147f28a962b8437e2611a8222d706bd) --- source4/libnet/libnet_vampire.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 352dde27e6..8f229c04e1 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -25,6 +25,7 @@ #include "libnet/libnet.h" #include "libcli/auth/libcli_auth.h" #include "auth/gensec/schannel_proto.h" +#include "librpc/gen_ndr/ndr_netlogon.h" #include "librpc/gen_ndr/ndr_netlogon_c.h" -- cgit From 35349a58df5b69446607fbd742a05f57f3515319 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 18 Mar 2006 15:42:57 +0000 Subject: r14542: Remove librpc, libndr and libnbt from includes.h (This used to be commit 51b4270513752d2eafbe77f9de598de16ef84a1f) --- source4/libnet/libnet_vampire.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 8f229c04e1..5c5407df3e 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -24,6 +24,7 @@ #include "includes.h" #include "libnet/libnet.h" #include "libcli/auth/libcli_auth.h" +#include "auth/gensec/gensec.h" #include "auth/gensec/schannel_proto.h" #include "librpc/gen_ndr/ndr_netlogon.h" #include "librpc/gen_ndr/ndr_netlogon_c.h" -- cgit From 538adbf677d225da8abc2adaefafa2a7c305ec17 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Thu, 4 May 2006 14:52:03 +0000 Subject: r15435: Turn libnet_RpcConnectDCInfo into another level of libnet_RpcConnect and make it async. Also, update any other usages of old function. Build goes fine and so do tests, comments to follow. rafal (This used to be commit aef0a2de9d2f01a6f619e3fccc8715288f5c37a3) --- source4/libnet/libnet_vampire.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 5c5407df3e..04f9e000f4 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -157,7 +157,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx struct cli_credentials *machine_account; struct dcerpc_pipe *p; struct libnet_context *machine_net_ctx; - struct libnet_RpcConnectDCInfo *c; + struct libnet_RpcConnect *c; struct libnet_SamSync_state *state; const enum netr_SamDatabaseID database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; int i; @@ -193,21 +193,22 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } - c = talloc(samsync_ctx, struct libnet_RpcConnectDCInfo); + c = talloc(samsync_ctx, struct libnet_RpcConnect); if (!c) { r->out.error_string = NULL; talloc_free(samsync_ctx); return NT_STATUS_NO_MEMORY; } + c->level = LIBNET_RPC_CONNECT_DC_INFO; if (r->in.binding_string) { - c->level = LIBNET_RPC_CONNECT_BINDING; c->in.binding = r->in.binding_string; + } else { - /* prepare connect to the NETLOGON pipe of PDC */ - c->level = LIBNET_RPC_CONNECT_PDC; c->in.name = cli_credentials_get_domain(machine_account); } + + /* prepare connect to the NETLOGON pipe of PDC */ c->in.dcerpc_iface = &dcerpc_table_netlogon; /* We must do this as the machine, not as any command-line @@ -223,7 +224,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx machine_net_ctx->cred = machine_account; /* connect to the NETLOGON pipe of the PDC */ - nt_status = libnet_RpcConnectDCInfo(machine_net_ctx, c); + nt_status = libnet_RpcConnect(machine_net_ctx, samsync_ctx, c); if (!NT_STATUS_IS_OK(nt_status)) { if (r->in.binding_string) { r->out.error_string = talloc_asprintf(mem_ctx, -- cgit From 4010a61fd85211bdee37874bf0bc27040ad70fff Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Sun, 7 May 2006 13:39:53 +0000 Subject: r15489: Typo fixes. rafal (This used to be commit 221907fc0d0141c6c73f10f2dc829879205b9bcb) --- source4/libnet/libnet_vampire.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 04f9e000f4..4becdc3c7d 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -304,7 +304,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx return nt_status; } - /* Setup details for the syncronisation */ + /* Setup details for the synchronisation */ dbsync.in.logon_server = talloc_asprintf(samsync_ctx, "\\\\%s", dcerpc_server_name(p)); dbsync.in.computername = cli_credentials_get_workstation(machine_account); dbsync.in.preferredmaximumlength = (uint32_t)-1; @@ -340,7 +340,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx char *error_string = NULL; delta_ctx = talloc_named(loop_ctx, 0, "DatabaseSync delta context"); /* 'Fix' elements, by decrypting and - * de-obfustiating the data */ + * de-obfuscating the data */ nt_status = fix_delta(delta_ctx, creds, dbsync.in.database_id, -- cgit From e7ede84c331b112efa5232d0f7dcc6732b95aebe Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 18 Sep 2006 09:54:44 +0000 Subject: r18609: error_string should not contain newlines. Guenther (This used to be commit 556666756418ad50c533199c736fe3696a7e20cb) --- source4/libnet/libnet_vampire.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 4becdc3c7d..7421f8943c 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -81,7 +81,7 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, user->nt_password_present = True; } } else { - *error_string = talloc_asprintf(mem_ctx, "Failed to parse Sensitive Data for %s:\n", username); + *error_string = talloc_asprintf(mem_ctx, "Failed to parse Sensitive Data for %s:", username); dump_data(10, data.data, data.length); return nt_status; } @@ -186,7 +186,6 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx r->out.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_domain(machine_account), cli_credentials_get_secure_channel_type(machine_account)); talloc_free(samsync_ctx); -- cgit From 9ce0de670bc3a19a189fe45442b929ad0f2ec3b5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 13 Oct 2006 07:25:51 +0000 Subject: r19261: Fix use of unitialised variables. (The binding string is used, if not NULL). This showed up in a manual pre-TP3 test of the 'net samdump' code, and shows the critical need for the windows testing infrustructure on the build farm. Andrew Bartlett (This used to be commit 9cef40779ad987b506b1f514a67b5b1c8aea9969) --- source4/libnet/libnet_vampire.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 7421f8943c..f5a326c676 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -202,8 +202,9 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx c->level = LIBNET_RPC_CONNECT_DC_INFO; if (r->in.binding_string) { c->in.binding = r->in.binding_string; - + c->in.name = NULL; } else { + c->in.binding = NULL; c->in.name = cli_credentials_get_domain(machine_account); } -- cgit From 13dbee3ffea6065a826f010e50c9b4eb2c6ad109 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 7 Nov 2006 00:48:36 +0000 Subject: r19598: Ahead of a merge to current lorikeet-heimdal: Break up auth/auth.h not to include the world. Add credentials_krb5.h with the kerberos dependent prototypes. Andrew Bartlett (This used to be commit 2b569c42e0fbb596ea82484d0e1cb22e193037b9) --- source4/libnet/libnet_vampire.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index f5a326c676..bda80db90f 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -25,6 +25,7 @@ #include "libnet/libnet.h" #include "libcli/auth/libcli_auth.h" #include "auth/gensec/gensec.h" +#include "auth/credentials/credentials.h" #include "auth/gensec/schannel_proto.h" #include "librpc/gen_ndr/ndr_netlogon.h" #include "librpc/gen_ndr/ndr_netlogon_c.h" -- cgit From 728ff99fe3b06794937f5398bb2512f0b03e7186 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 9 Feb 2007 01:49:26 +0000 Subject: r21255: Add a debugging option to avoid rid decryption in the samsync output. Andrew Bartlett (This used to be commit 9e15a51579157405b2013b9b948d279fefd0eda6) --- source4/libnet/libnet_vampire.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index bda80db90f..32879e7610 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -50,14 +50,16 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, 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); - user->lmpassword = lm_hash; - } - - if (user->nt_password_present) { - sam_rid_crypt(rid, user->ntpassword.hash, nt_hash.hash, 0); - user->ntpassword = nt_hash; + if (lp_parm_bool(-1, "vampire", "rid_decrypt", True)) { + if (user->lm_password_present) { + sam_rid_crypt(rid, user->lmpassword.hash, lm_hash.hash, 0); + user->lmpassword = lm_hash; + } + + if (user->nt_password_present) { + sam_rid_crypt(rid, user->ntpassword.hash, nt_hash.hash, 0); + user->ntpassword = nt_hash; + } } if (user->user_private_info.SensitiveData) { @@ -72,13 +74,21 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, 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); - user->lmpassword = lm_hash; + if (lp_parm_bool(-1, "vampire", "rid decrypt", True)) { + sam_rid_crypt(rid, keys.keys.keys2.lmpassword.pwd.hash, lm_hash.hash, 0); + user->lmpassword = lm_hash; + } else { + user->lmpassword = keys.keys.keys2.lmpassword.pwd; + } 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); - user->ntpassword = nt_hash; + if (lp_parm_bool(-1, "vampire", "rid decrypt", True)) { + sam_rid_crypt(rid, keys.keys.keys2.ntpassword.pwd.hash, nt_hash.hash, 0); + user->ntpassword = nt_hash; + } else { + user->ntpassword = keys.keys.keys2.ntpassword.pwd; + } user->nt_password_present = True; } } else { -- cgit From eee140d7da8088884c392ebefbef3ad3650aceb0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 12 Feb 2007 13:34:04 +0000 Subject: r21300: let the caller decide if it wants rid decrypted hashes or not metze (This used to be commit 8711d01ffd080c43512b88b995daf2d6b7c06ba1) --- source4/libnet/libnet_vampire.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 32879e7610..9b63f1b511 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -38,6 +38,7 @@ */ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, struct creds_CredentialState *creds, + bool rid_crypt, enum netr_SamDatabaseID database, struct netr_DELTA_ENUM *delta, char **error_string) @@ -50,7 +51,7 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, const char *username = user->account_name.string; NTSTATUS nt_status; - if (lp_parm_bool(-1, "vampire", "rid_decrypt", True)) { + if (rid_crypt) { if (user->lm_password_present) { sam_rid_crypt(rid, user->lmpassword.hash, lm_hash.hash, 0); user->lmpassword = lm_hash; @@ -74,7 +75,7 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, 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) { - if (lp_parm_bool(-1, "vampire", "rid decrypt", True)) { + if (rid_crypt) { sam_rid_crypt(rid, keys.keys.keys2.lmpassword.pwd.hash, lm_hash.hash, 0); user->lmpassword = lm_hash; } else { @@ -83,7 +84,7 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, user->lm_password_present = True; } if (keys.keys.keys2.ntpassword.length == 16) { - if (lp_parm_bool(-1, "vampire", "rid decrypt", True)) { + if (rid_crypt) { sam_rid_crypt(rid, keys.keys.keys2.ntpassword.pwd.hash, nt_hash.hash, 0); user->ntpassword = nt_hash; } else { @@ -91,6 +92,7 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, } user->nt_password_present = True; } + /* TODO: rid decrypt history fields */ } else { *error_string = talloc_asprintf(mem_ctx, "Failed to parse Sensitive Data for %s:", username); dump_data(10, data.data, data.length); @@ -128,6 +130,7 @@ static NTSTATUS fix_secret(TALLOC_CTX *mem_ctx, static NTSTATUS fix_delta(TALLOC_CTX *mem_ctx, struct creds_CredentialState *creds, + bool rid_crypt, enum netr_SamDatabaseID database, struct netr_DELTA_ENUM *delta, char **error_string) @@ -139,6 +142,7 @@ static NTSTATUS fix_delta(TALLOC_CTX *mem_ctx, { nt_status = fix_user(mem_ctx, creds, + rid_crypt, database, delta, error_string); @@ -354,6 +358,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx * de-obfuscating the data */ nt_status = fix_delta(delta_ctx, creds, + r->in.rid_crypt, dbsync.in.database_id, &dbsync.out.delta_enum_array->delta_enum[d], &error_string); -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/libnet/libnet_vampire.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 9b63f1b511..d015a07730 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ -- cgit From f14bd1a90ab47a418c0ec2492990a417a0bb3bf6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 19 Aug 2007 21:23:03 +0000 Subject: r24557: rename 'dcerpc_table_' -> 'ndr_table_' metze (This used to be commit 84651aee81aaabbebf52ffc3fbcbabb2eec6eed5) --- source4/libnet/libnet_vampire.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index d015a07730..e21976cb02 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -223,7 +223,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx } /* prepare connect to the NETLOGON pipe of PDC */ - c->in.dcerpc_iface = &dcerpc_table_netlogon; + c->in.dcerpc_iface = &ndr_table_netlogon; /* We must do this as the machine, not as any command-line * user. So we override the credentials in the @@ -268,7 +268,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx return nt_status; } - nt_status = dcerpc_bind_auth_schannel(samsync_ctx, p, &dcerpc_table_netlogon, + nt_status = dcerpc_bind_auth_schannel(samsync_ctx, p, &ndr_table_netlogon, machine_account, DCERPC_AUTH_LEVEL_PRIVACY); if (!NT_STATUS_IS_OK(nt_status)) { -- cgit From 37d53832a4623653f706e77985a79d84bd7c6694 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 28 Sep 2007 01:17:46 +0000 Subject: r25398: Parse loadparm context to all lp_*() functions. (This used to be commit 3fcc960839c6e5ca4de2c3c042f12f369ac5f238) --- source4/libnet/libnet_vampire.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index e21976cb02..c6f85d5b5f 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -28,6 +28,7 @@ #include "auth/gensec/schannel_proto.h" #include "librpc/gen_ndr/ndr_netlogon.h" #include "librpc/gen_ndr/ndr_netlogon_c.h" +#include "param/param.h" /** @@ -184,7 +185,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx talloc_free(samsync_ctx); return NT_STATUS_NO_MEMORY; } - cli_credentials_set_conf(machine_account); + cli_credentials_set_conf(machine_account, global_loadparm); nt_status = cli_credentials_set_machine_account(machine_account); if (!NT_STATUS_IS_OK(nt_status)) { r->out.error_string = talloc_strdup(mem_ctx, "Could not obtain machine account password - are we joined to the domain?"); -- cgit From 2151cde58014ea2e822c13d2f8a369b45dc19ca8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 6 Oct 2007 22:28:14 +0000 Subject: r25554: Convert last instances of BOOL, True and False to the standard types. (This used to be commit 566aa14139510788548a874e9213d91317f83ca9) --- source4/libnet/libnet_vampire.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index c6f85d5b5f..dff915df71 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -81,7 +81,7 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, } else { user->lmpassword = keys.keys.keys2.lmpassword.pwd; } - user->lm_password_present = True; + user->lm_password_present = true; } if (keys.keys.keys2.ntpassword.length == 16) { if (rid_crypt) { @@ -90,7 +90,7 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, } else { user->ntpassword = keys.keys.keys2.ntpassword.pwd; } - user->nt_password_present = True; + user->nt_password_present = true; } /* TODO: rid decrypt history fields */ } else { -- cgit From 1e14ad7cfeb6a416991da87b7d137dc9b89ef74f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Nov 2007 11:21:04 +0100 Subject: r25823: remove unneeded nesting by using error and out logic metze (This used to be commit 86db839382a6cf92e659abb9e8e51ef828e1e422) --- source4/libnet/libnet_vampire.c | 42 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index dff915df71..09163f6507 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -73,31 +73,31 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, 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) { - if (rid_crypt) { - sam_rid_crypt(rid, keys.keys.keys2.lmpassword.pwd.hash, lm_hash.hash, 0); - user->lmpassword = lm_hash; - } else { - user->lmpassword = keys.keys.keys2.lmpassword.pwd; - } - user->lm_password_present = true; - } - if (keys.keys.keys2.ntpassword.length == 16) { - if (rid_crypt) { - sam_rid_crypt(rid, keys.keys.keys2.ntpassword.pwd.hash, nt_hash.hash, 0); - user->ntpassword = nt_hash; - } else { - user->ntpassword = keys.keys.keys2.ntpassword.pwd; - } - user->nt_password_present = true; - } - /* TODO: rid decrypt history fields */ - } else { + if (!NT_STATUS_IS_OK(nt_status)) { *error_string = talloc_asprintf(mem_ctx, "Failed to parse Sensitive Data for %s:", username); dump_data(10, data.data, data.length); return nt_status; } + + if (keys.keys.keys2.lmpassword.length == 16) { + if (rid_crypt) { + sam_rid_crypt(rid, keys.keys.keys2.lmpassword.pwd.hash, lm_hash.hash, 0); + user->lmpassword = lm_hash; + } else { + user->lmpassword = keys.keys.keys2.lmpassword.pwd; + } + user->lm_password_present = true; + } + if (keys.keys.keys2.ntpassword.length == 16) { + if (rid_crypt) { + sam_rid_crypt(rid, keys.keys.keys2.ntpassword.pwd.hash, nt_hash.hash, 0); + user->ntpassword = nt_hash; + } else { + user->ntpassword = keys.keys.keys2.ntpassword.pwd; + } + user->nt_password_present = true; + } + /* TODO: rid decrypt history fields */ } return NT_STATUS_OK; } -- cgit From 529763a9aa192a6785ba878aceeb1683c2510913 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 9 Nov 2007 19:24:51 +0100 Subject: r25920: ndr: change NTSTAUS into enum ndr_err_code (samba4 callers) lib/messaging/ lib/registry/ lib/ldb-samba/ librpc/rpc/ auth/auth_winbind.c auth/gensec/ auth/kerberos/ dsdb/repl/ dsdb/samdb/ dsdb/schema/ torture/ cluster/ctdb/ kdc/ ntvfs/ipc/ torture/rap/ ntvfs/ utils/getntacl.c ntptr/ smb_server/ libcli/wrepl/ wrepl_server/ libcli/cldap/ libcli/dgram/ libcli/ldap/ libcli/raw/ libcli/nbt/ libnet/ winbind/ rpc_server/ metze (This used to be commit 6223c7fddc972687eb577e04fc1c8e0604c35435) --- source4/libnet/libnet_vampire.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 09163f6507..40693e6362 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -49,7 +49,6 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, struct samr_Password lm_hash; struct samr_Password nt_hash; const char *username = user->account_name.string; - NTSTATUS nt_status; if (rid_crypt) { if (user->lm_password_present) { @@ -66,17 +65,18 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, if (user->user_private_info.SensitiveData) { DATA_BLOB data; struct netr_USER_KEYS keys; + enum ndr_err_code ndr_err; 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)) { + ndr_err = ndr_pull_struct_blob(&data, mem_ctx, &keys, (ndr_pull_flags_fn_t)ndr_pull_netr_USER_KEYS); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { *error_string = talloc_asprintf(mem_ctx, "Failed to parse Sensitive Data for %s:", username); dump_data(10, data.data, data.length); - return nt_status; + return ndr_map_error2ntstatus(ndr_err); } if (keys.keys.keys2.lmpassword.length == 16) { -- cgit From fface33dd731a711688b56593bb703c38090e782 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 2 Dec 2007 19:31:14 +0100 Subject: r26231: Spell check: credentails -> credentials. (This used to be commit 4b46888bd0195ab12190f76868719fc018baafd6) --- source4/libnet/libnet_vampire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 40693e6362..fbb7c8b6e5 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -310,7 +310,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx } } - /* get NETLOGON credentails */ + /* get NETLOGON credentials */ nt_status = dcerpc_schannel_creds(p->conn->security_state.generic_state, samsync_ctx, &creds); if (!NT_STATUS_IS_OK(nt_status)) { -- cgit From 4c4323009fa83f00ed319de59a3aad48fcd65994 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Dec 2007 02:37:04 +0100 Subject: r26327: Explicit loadparm_context for RPC client functions. (This used to be commit eeb2251d22b3d6e0379444a73af69d1014692b07) --- source4/libnet/libnet_vampire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index fbb7c8b6e5..e4c8833156 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -270,7 +270,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx } nt_status = dcerpc_bind_auth_schannel(samsync_ctx, p, &ndr_table_netlogon, - machine_account, DCERPC_AUTH_LEVEL_PRIVACY); + machine_account, ctx->lp_ctx, DCERPC_AUTH_LEVEL_PRIVACY); if (!NT_STATUS_IS_OK(nt_status)) { r->out.error_string = talloc_asprintf(mem_ctx, -- cgit From 6c77f353d3d952b46b401ab29837ba5b75e353c2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Dec 2007 02:37:13 +0100 Subject: r26328: remove more uses of global_loadparm. (This used to be commit 40ae12c08647c47a9c504d39ee6f61c32b4e5748) --- source4/libnet/libnet_vampire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index e4c8833156..574b34c246 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -185,7 +185,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx talloc_free(samsync_ctx); return NT_STATUS_NO_MEMORY; } - cli_credentials_set_conf(machine_account, global_loadparm); + cli_credentials_set_conf(machine_account, ctx->lp_ctx); nt_status = cli_credentials_set_machine_account(machine_account); if (!NT_STATUS_IS_OK(nt_status)) { r->out.error_string = talloc_strdup(mem_ctx, "Could not obtain machine account password - are we joined to the domain?"); -- cgit From a2cea02584256e2cf59da5420e8e080e70c66939 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:17 +0100 Subject: r26430: require explicit specification of loadparm context. (This used to be commit 1b947fe0e6e16318e5a8127bb4932d6b5d20bcf6) --- source4/libnet/libnet_vampire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 574b34c246..df4cb4d657 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -186,7 +186,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx return NT_STATUS_NO_MEMORY; } cli_credentials_set_conf(machine_account, ctx->lp_ctx); - nt_status = cli_credentials_set_machine_account(machine_account); + nt_status = cli_credentials_set_machine_account(machine_account, ctx->lp_ctx); if (!NT_STATUS_IS_OK(nt_status)) { r->out.error_string = talloc_strdup(mem_ctx, "Could not obtain machine account password - are we joined to the domain?"); talloc_free(samsync_ctx); -- cgit From 7d5f0e0893d42b56145a3ffa34e3b4b9906cbd91 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 1 Jan 2008 22:05:13 -0600 Subject: r26639: librpc: Pass iconv convenience on from RPC connection to NDR library, so it can be overridden by OpenChange. (This used to be commit 2f29f80e07adef1f020173f2cd6d947d0ef505ce) --- source4/libnet/libnet_vampire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index df4cb4d657..c707f82744 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -72,7 +72,7 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, user->user_private_info.SensitiveData = data.data; user->user_private_info.DataLength = data.length; - ndr_err = ndr_pull_struct_blob(&data, mem_ctx, &keys, (ndr_pull_flags_fn_t)ndr_pull_netr_USER_KEYS); + ndr_err = ndr_pull_struct_blob(&data, mem_ctx, lp_iconv_convenience(global_loadparm), &keys, (ndr_pull_flags_fn_t)ndr_pull_netr_USER_KEYS); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { *error_string = talloc_asprintf(mem_ctx, "Failed to parse Sensitive Data for %s:", username); dump_data(10, data.data, data.length); -- cgit From 2c8c9a535500e40084c4810da1890df8d9415659 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Jan 2008 15:36:33 -0600 Subject: r26669: Janitorial: Remove uses of global_loadparm. (This used to be commit 50c46160d997e0448f51ae09e0f3c79e8519fa41) --- source4/libnet/libnet_vampire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index c707f82744..0f82d98673 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -72,7 +72,7 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, user->user_private_info.SensitiveData = data.data; user->user_private_info.DataLength = data.length; - ndr_err = ndr_pull_struct_blob(&data, mem_ctx, lp_iconv_convenience(global_loadparm), &keys, (ndr_pull_flags_fn_t)ndr_pull_netr_USER_KEYS); + ndr_err = ndr_pull_struct_blob(&data, mem_ctx, NULL, &keys, (ndr_pull_flags_fn_t)ndr_pull_netr_USER_KEYS); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { *error_string = talloc_asprintf(mem_ctx, "Failed to parse Sensitive Data for %s:", username); dump_data(10, data.data, data.length); -- cgit From 2f8ac9a4221e4b7731422bd2ce05e59b5d75fb0a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 9 Apr 2008 12:02:11 +1000 Subject: Start implementation of real 'net vampire' code. This will use DRS Replication (metze's thesis work) and possibly samsync, and will work outside the smbtorture process. Andrew Bartlett (This used to be commit 02a33165ca700f71cf09680ded35c87aa2e88552) --- source4/libnet/libnet_vampire.c | 943 ++++++++++++++++++++++++++-------------- 1 file changed, 625 insertions(+), 318 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 0f82d98673..cd9167f541 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -1,9 +1,11 @@ /* Unix SMB/CIFS implementation. - Extract the user/system database from a remote SamSync server + Extract the user/system database from a remote server - Copyright (C) Andrew Bartlett 2004-2005 + Copyright (C) Stefan Metzmacher 2004-2006 + Copyright (C) Brad Henry 2005 + Copyright (C) Andrew Bartlett 2005-2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,378 +24,683 @@ #include "includes.h" #include "libnet/libnet.h" -#include "libcli/auth/libcli_auth.h" -#include "auth/gensec/gensec.h" -#include "auth/credentials/credentials.h" -#include "auth/gensec/schannel_proto.h" -#include "librpc/gen_ndr/ndr_netlogon.h" -#include "librpc/gen_ndr/ndr_netlogon_c.h" +#include "lib/events/events.h" +#include "dsdb/samdb/samdb.h" +#include "lib/util/dlinklist.h" +#include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" +#include "librpc/ndr/libndr.h" +#include "librpc/gen_ndr/ndr_drsuapi.h" +#include "librpc/gen_ndr/ndr_drsblobs.h" +#include "librpc/gen_ndr/ndr_misc.h" +#include "system/time.h" +#include "lib/ldb_wrap.h" +#include "auth/auth.h" #include "param/param.h" +/* +List of tasks vampire.py must perform: +- Domain Join + - but don't write the secrets.ldb + - results for this should be enough to handle the provision +- if vampire method is samsync + - Provision using these results + - do we still want to support this NT4 technology? +- Start samsync with libnet code + - provision in the callback +- Write out the secrets database, using the code from libnet_Join + +*/ +struct vampire_state { + struct libnet_context *ctx; + const char *netbios_name; + struct libnet_JoinDomain *join; + struct cli_credentials *machine_account; + struct dsdb_schema *self_made_schema; + const struct dsdb_schema *schema; + + struct ldb_context *ldb; -/** - * 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, - bool rid_crypt, - enum netr_SamDatabaseID database, - struct netr_DELTA_ENUM *delta, - char **error_string) + struct { + uint32_t object_count; + struct drsuapi_DsReplicaObjectListItemEx *first_object; + struct drsuapi_DsReplicaObjectListItemEx *last_object; + } schema_part; + + const char *targetdir; + + struct loadparm_context *lp_ctx; +}; + +static NTSTATUS vampire_prepare_db(void *private_data, + const struct libnet_BecomeDC_PrepareDB *p) { + struct vampire_state *s = talloc_get_type(private_data, struct vampire_state); + struct provision_settings settings; + NTSTATUS status; + bool ok; + struct loadparm_context *lp_ctx = loadparm_init(s); + char *smbconf; + + if (!lp_ctx) { + return NT_STATUS_NO_MEMORY; + } - 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; + settings.site_name = p->dest_dsa->site_name; + settings.root_dn_str = p->forest->root_dn_str; + settings.domain_dn_str = p->domain->dn_str; + settings.config_dn_str = p->forest->config_dn_str; + settings.schema_dn_str = p->forest->schema_dn_str; + settings.netbios_name = p->dest_dsa->netbios_name; + settings.realm = s->join->out.realm; + settings.domain = s->join->out.domain; + settings.server_dn_str = p->dest_dsa->server_dn_str; + settings.machine_password = generate_random_str(s, 16); + settings.targetdir = s->targetdir; + + status = provision_bare(s, s->lp_ctx, &settings); + + smbconf = talloc_asprintf(lp_ctx, "%s/%s", s->targetdir, "/etc/smb.conf"); - if (rid_crypt) { - if (user->lm_password_present) { - sam_rid_crypt(rid, user->lmpassword.hash, lm_hash.hash, 0); - user->lmpassword = lm_hash; - } - - if (user->nt_password_present) { - sam_rid_crypt(rid, user->ntpassword.hash, nt_hash.hash, 0); - user->ntpassword = nt_hash; - } + ok = lp_load(lp_ctx, smbconf); + if (!ok) { + DEBUG(0,("Failed load freshly generated smb.conf '%s'\n", smbconf)); + return NT_STATUS_INVALID_PARAMETER; } - if (user->user_private_info.SensitiveData) { - DATA_BLOB data; - struct netr_USER_KEYS keys; - enum ndr_err_code ndr_err; - 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; - - ndr_err = ndr_pull_struct_blob(&data, mem_ctx, NULL, &keys, (ndr_pull_flags_fn_t)ndr_pull_netr_USER_KEYS); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - *error_string = talloc_asprintf(mem_ctx, "Failed to parse Sensitive Data for %s:", username); - dump_data(10, data.data, data.length); - return ndr_map_error2ntstatus(ndr_err); + s->ldb = samdb_connect(s, lp_ctx, + system_session(s, lp_ctx)); + if (!s->ldb) { + DEBUG(0,("Failed to open '%s'\n", lp_sam_url(lp_ctx))); + return NT_STATUS_INTERNAL_DB_ERROR; + } + + /* We must set these up to ensure the replMetaData is written correctly, before our NTDS Settings entry is replicated */ + ok = samdb_set_ntds_invocation_id(s->ldb, &p->dest_dsa->invocation_id); + if (!ok) { + DEBUG(0,("Failed to set cached ntds invocationId\n")); + return NT_STATUS_FOOBAR; + } + ok = samdb_set_ntds_objectGUID(s->ldb, &p->dest_dsa->ntds_guid); + if (!ok) { + DEBUG(0,("Failed to set cached ntds objectGUID\n")); + return NT_STATUS_FOOBAR; + } + + s->lp_ctx = lp_ctx; + + return NT_STATUS_OK; + + +} + +static NTSTATUS vampire_check_options(void *private_data, + const struct libnet_BecomeDC_CheckOptions *o) +{ + struct vampire_state *s = talloc_get_type(private_data, struct vampire_state); + + DEBUG(0,("Become DC [%s] of Domain[%s]/[%s]\n", + s->netbios_name, + o->domain->netbios_name, o->domain->dns_name)); + + DEBUG(0,("Promotion Partner is Server[%s] from Site[%s]\n", + o->source_dsa->dns_name, o->source_dsa->site_name)); + + DEBUG(0,("Options:crossRef behavior_version[%u]\n" + "\tschema object_version[%u]\n" + "\tdomain behavior_version[%u]\n" + "\tdomain w2k3_update_revision[%u]\n", + o->forest->crossref_behavior_version, + o->forest->schema_object_version, + o->domain->behavior_version, + o->domain->w2k3_update_revision)); + + return NT_STATUS_OK; +} + +static NTSTATUS vampire_apply_schema(struct vampire_state *s, + const struct libnet_BecomeDC_StoreChunk *c) +{ + WERROR status; + const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr; + uint32_t total_object_count; + uint32_t object_count; + struct drsuapi_DsReplicaObjectListItemEx *first_object; + struct drsuapi_DsReplicaObjectListItemEx *cur; + uint32_t linked_attributes_count; + struct drsuapi_DsReplicaLinkedAttribute *linked_attributes; + const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector; + struct dsdb_extended_replicated_objects *objs; + struct repsFromTo1 *s_dsa; + char *tmp_dns_name; + struct ldb_message *msg; + struct ldb_val prefixMap_val; + struct ldb_message_element *prefixMap_el; + struct ldb_val schemaInfo_val; + uint32_t i; + int ret; + bool ok; + + DEBUG(0,("Analyze and apply schema objects\n")); + + s_dsa = talloc_zero(s, struct repsFromTo1); + NT_STATUS_HAVE_NO_MEMORY(s_dsa); + s_dsa->other_info = talloc(s_dsa, struct repsFromTo1OtherInfo); + NT_STATUS_HAVE_NO_MEMORY(s_dsa->other_info); + + switch (c->ctr_level) { + case 1: + mapping_ctr = &c->ctr1->mapping_ctr; + total_object_count = c->ctr1->total_object_count; + object_count = s->schema_part.object_count; + first_object = s->schema_part.first_object; + linked_attributes_count = 0; + linked_attributes = NULL; + s_dsa->highwatermark = c->ctr1->new_highwatermark; + s_dsa->source_dsa_obj_guid = c->ctr1->source_dsa_guid; + s_dsa->source_dsa_invocation_id = c->ctr1->source_dsa_invocation_id; + uptodateness_vector = NULL; /* TODO: map it */ + break; + case 6: + mapping_ctr = &c->ctr6->mapping_ctr; + total_object_count = c->ctr6->total_object_count; + object_count = s->schema_part.object_count; + first_object = s->schema_part.first_object; + linked_attributes_count = 0; /* TODO: ! */ + linked_attributes = NULL; /* TODO: ! */; + s_dsa->highwatermark = c->ctr6->new_highwatermark; + s_dsa->source_dsa_obj_guid = c->ctr6->source_dsa_guid; + s_dsa->source_dsa_invocation_id = c->ctr6->source_dsa_invocation_id; + uptodateness_vector = c->ctr6->uptodateness_vector; + break; + default: + return NT_STATUS_INVALID_PARAMETER; + } + + s_dsa->replica_flags = DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE + | DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP + | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS; + memset(s_dsa->schedule, 0x11, sizeof(s_dsa->schedule)); + + tmp_dns_name = GUID_string(s_dsa->other_info, &s_dsa->source_dsa_obj_guid); + NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name); + tmp_dns_name = talloc_asprintf_append_buffer(tmp_dns_name, "._msdcs.%s", c->forest->dns_name); + NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name); + s_dsa->other_info->dns_name = tmp_dns_name; + + for (cur = first_object; cur; cur = cur->next_object) { + bool is_attr = false; + bool is_class = false; + + for (i=0; i < cur->object.attribute_ctr.num_attributes; i++) { + struct drsuapi_DsReplicaAttribute *a; + uint32_t j; + const char *oid = NULL; + + a = &cur->object.attribute_ctr.attributes[i]; + status = dsdb_map_int2oid(s->self_made_schema, a->attid, s, &oid); + if (!W_ERROR_IS_OK(status)) { + return werror_to_ntstatus(status); + } + + switch (a->attid) { + case DRSUAPI_ATTRIBUTE_objectClass: + for (j=0; j < a->value_ctr.num_values; j++) { + uint32_t val = 0xFFFFFFFF; + + if (a->value_ctr.values[i].blob + && a->value_ctr.values[i].blob->length == 4) { + val = IVAL(a->value_ctr.values[i].blob->data,0); + } + + if (val == DRSUAPI_OBJECTCLASS_attributeSchema) { + is_attr = true; + } + if (val == DRSUAPI_OBJECTCLASS_classSchema) { + is_class = true; + } + } + + break; + default: + break; + } } - if (keys.keys.keys2.lmpassword.length == 16) { - if (rid_crypt) { - sam_rid_crypt(rid, keys.keys.keys2.lmpassword.pwd.hash, lm_hash.hash, 0); - user->lmpassword = lm_hash; - } else { - user->lmpassword = keys.keys.keys2.lmpassword.pwd; + if (is_attr) { + struct dsdb_attribute *sa; + + sa = talloc_zero(s->self_made_schema, struct dsdb_attribute); + NT_STATUS_HAVE_NO_MEMORY(sa); + + status = dsdb_attribute_from_drsuapi(s->self_made_schema, &cur->object, s, sa); + if (!W_ERROR_IS_OK(status)) { + return werror_to_ntstatus(status); } - user->lm_password_present = true; + + DLIST_ADD_END(s->self_made_schema->attributes, sa, struct dsdb_attribute *); } - if (keys.keys.keys2.ntpassword.length == 16) { - if (rid_crypt) { - sam_rid_crypt(rid, keys.keys.keys2.ntpassword.pwd.hash, nt_hash.hash, 0); - user->ntpassword = nt_hash; - } else { - user->ntpassword = keys.keys.keys2.ntpassword.pwd; + + if (is_class) { + struct dsdb_class *sc; + + sc = talloc_zero(s->self_made_schema, struct dsdb_class); + NT_STATUS_HAVE_NO_MEMORY(sc); + + status = dsdb_class_from_drsuapi(s->self_made_schema, &cur->object, s, sc); + if (!W_ERROR_IS_OK(status)) { + return werror_to_ntstatus(status); } - user->nt_password_present = true; + + DLIST_ADD_END(s->self_made_schema->classes, sc, struct dsdb_class *); } - /* TODO: rid decrypt history fields */ } - return NT_STATUS_OK; -} -/** - * Decrypt and extract the secrets - * - * The writes decrypted secrets back into the structure - */ -static NTSTATUS fix_secret(TALLOC_CTX *mem_ctx, - struct creds_CredentialState *creds, - enum netr_SamDatabaseID database, - struct netr_DELTA_ENUM *delta, - char **error_string) -{ - struct netr_DELTA_SECRET *secret = delta->delta_union.secret; - creds_arcfour_crypt(creds, secret->current_cipher.cipher_data, - secret->current_cipher.maxlen); + /* attach the schema to the ldb */ + ret = dsdb_set_schema(s->ldb, s->self_made_schema); + if (ret != LDB_SUCCESS) { + return NT_STATUS_FOOBAR; + } + /* we don't want to access the self made schema anymore */ + s->self_made_schema = NULL; + s->schema = dsdb_get_schema(s->ldb); + + status = dsdb_extended_replicated_objects_commit(s->ldb, + c->partition->nc.dn, + mapping_ctr, + object_count, + first_object, + linked_attributes_count, + linked_attributes, + s_dsa, + uptodateness_vector, + c->gensec_skey, + s, &objs); + if (!W_ERROR_IS_OK(status)) { + DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status))); + return werror_to_ntstatus(status); + } - creds_arcfour_crypt(creds, secret->old_cipher.cipher_data, - secret->old_cipher.maxlen); + if (lp_parm_bool(s->lp_ctx, NULL, "become dc", "dump objects", false)) { + for (i=0; i < objs->num_objects; i++) { + struct ldb_ldif ldif; + fprintf(stdout, "#\n"); + ldif.changetype = LDB_CHANGETYPE_NONE; + ldif.msg = objs->objects[i].msg; + ldb_ldif_write_file(s->ldb, stdout, &ldif); + NDR_PRINT_DEBUG(replPropertyMetaDataBlob, objs->objects[i].meta_data); + } + } + + msg = ldb_msg_new(objs); + NT_STATUS_HAVE_NO_MEMORY(msg); + msg->dn = objs->partition_dn; + + status = dsdb_get_oid_mappings_ldb(s->schema, msg, &prefixMap_val, &schemaInfo_val); + if (!W_ERROR_IS_OK(status)) { + DEBUG(0,("Failed dsdb_get_oid_mappings_ldb(%s)\n", win_errstr(status))); + return werror_to_ntstatus(status); + } + + /* we only add prefixMap here, because schemaInfo is a replicated attribute and already applied */ + ret = ldb_msg_add_value(msg, "prefixMap", &prefixMap_val, &prefixMap_el); + if (ret != LDB_SUCCESS) { + return NT_STATUS_FOOBAR; + } + prefixMap_el->flags = LDB_FLAG_MOD_REPLACE; + + ret = ldb_modify(s->ldb, msg); + if (ret != LDB_SUCCESS) { + DEBUG(0,("Failed to add prefixMap and schemaInfo %s\n", ldb_strerror(ret))); + return NT_STATUS_FOOBAR; + } + + talloc_free(s_dsa); + talloc_free(objs); + + /* reopen the ldb */ + talloc_free(s->ldb); /* this also free's the s->schema, because dsdb_set_schema() steals it */ + s->schema = NULL; + + DEBUG(0,("Reopen the SAM LDB with system credentials and a already stored schema\n")); + s->ldb = samdb_connect(s, s->lp_ctx, + system_session(s, s->lp_ctx)); + if (!s->ldb) { + DEBUG(0,("Failed to reopen sam.ldb\n")); + return NT_STATUS_INTERNAL_DB_ERROR; + } + + /* We must set these up to ensure the replMetaData is written correctly, before our NTDS Settings entry is replicated */ + ok = samdb_set_ntds_invocation_id(s->ldb, &c->dest_dsa->invocation_id); + if (!ok) { + DEBUG(0,("Failed to set cached ntds invocationId\n")); + return NT_STATUS_FOOBAR; + } + ok = samdb_set_ntds_objectGUID(s->ldb, &c->dest_dsa->ntds_guid); + if (!ok) { + DEBUG(0,("Failed to set cached ntds objectGUID\n")); + return NT_STATUS_FOOBAR; + } + + s->schema = dsdb_get_schema(s->ldb); + if (!s->schema) { + DEBUG(0,("Failed to get loaded dsdb_schema\n")); + return NT_STATUS_FOOBAR; + } return NT_STATUS_OK; } -/** - * 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, - bool rid_crypt, - enum netr_SamDatabaseID database, - struct netr_DELTA_ENUM *delta, - char **error_string) +static NTSTATUS vampire_schema_chunk(void *private_data, + const struct libnet_BecomeDC_StoreChunk *c) { - NTSTATUS nt_status = NT_STATUS_OK; - *error_string = NULL; - switch (delta->delta_type) { - case NETR_DELTA_USER: - { - nt_status = fix_user(mem_ctx, - creds, - rid_crypt, - database, - delta, - error_string); + struct vampire_state *s = talloc_get_type(private_data, struct vampire_state); + WERROR status; + const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr; + uint32_t total_object_count; + uint32_t object_count; + struct drsuapi_DsReplicaObjectListItemEx *first_object; + struct drsuapi_DsReplicaObjectListItemEx *cur; + + switch (c->ctr_level) { + case 1: + mapping_ctr = &c->ctr1->mapping_ctr; + total_object_count = c->ctr1->total_object_count; + object_count = c->ctr1->object_count; + first_object = c->ctr1->first_object; break; - } - case NETR_DELTA_SECRET: - { - nt_status = fix_secret(mem_ctx, - creds, - database, - delta, - error_string); + case 6: + mapping_ctr = &c->ctr6->mapping_ctr; + total_object_count = c->ctr6->total_object_count; + object_count = c->ctr6->object_count; + first_object = c->ctr6->first_object; break; - } default: - break; + return NT_STATUS_INVALID_PARAMETER; } - return nt_status; -} -NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_SamSync *r) -{ - NTSTATUS nt_status, dbsync_nt_status; - TALLOC_CTX *samsync_ctx, *loop_ctx, *delta_ctx; - struct creds_CredentialState *creds; - struct netr_DatabaseSync dbsync; - struct cli_credentials *machine_account; - struct dcerpc_pipe *p; - struct libnet_context *machine_net_ctx; - struct libnet_RpcConnect *c; - struct libnet_SamSync_state *state; - const enum netr_SamDatabaseID database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; - int i; - - samsync_ctx = talloc_named(mem_ctx, 0, "SamSync top context"); - - if (!r->in.machine_account) { - machine_account = cli_credentials_init(samsync_ctx); - if (!machine_account) { - talloc_free(samsync_ctx); - return NT_STATUS_NO_MEMORY; + if (total_object_count) { + DEBUG(0,("Schema-DN[%s] objects[%u/%u]\n", + c->partition->nc.dn, object_count, total_object_count)); + } else { + DEBUG(0,("Schema-DN[%s] objects[%u]\n", + c->partition->nc.dn, object_count)); + } + + if (!s->schema) { + s->self_made_schema = dsdb_new_schema(s, lp_iconv_convenience(s->lp_ctx)); + + NT_STATUS_HAVE_NO_MEMORY(s->self_made_schema); + + status = dsdb_load_oid_mappings_drsuapi(s->self_made_schema, mapping_ctr); + if (!W_ERROR_IS_OK(status)) { + return werror_to_ntstatus(status); } - cli_credentials_set_conf(machine_account, ctx->lp_ctx); - nt_status = cli_credentials_set_machine_account(machine_account, ctx->lp_ctx); - if (!NT_STATUS_IS_OK(nt_status)) { - r->out.error_string = talloc_strdup(mem_ctx, "Could not obtain machine account password - are we joined to the domain?"); - talloc_free(samsync_ctx); - return nt_status; + + s->schema = s->self_made_schema; + } else { + status = dsdb_verify_oid_mappings_drsuapi(s->schema, mapping_ctr); + if (!W_ERROR_IS_OK(status)) { + return werror_to_ntstatus(status); } + } + + if (!s->schema_part.first_object) { + s->schema_part.object_count = object_count; + s->schema_part.first_object = talloc_steal(s, first_object); } else { - machine_account = r->in.machine_account; + s->schema_part.object_count += object_count; + s->schema_part.last_object->next_object = talloc_steal(s->schema_part.last_object, + first_object); } + for (cur = first_object; cur->next_object; cur = cur->next_object) {} + s->schema_part.last_object = cur; - /* We cannot do this unless we are a BDC. Check, before we get odd errors later */ - if (cli_credentials_get_secure_channel_type(machine_account) != SEC_CHAN_BDC) { - r->out.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_domain(machine_account), - cli_credentials_get_secure_channel_type(machine_account)); - talloc_free(samsync_ctx); - return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + if (c->partition->highwatermark.tmp_highest_usn == c->partition->highwatermark.highest_usn) { + return vampire_apply_schema(s, c); } - c = talloc(samsync_ctx, struct libnet_RpcConnect); - if (!c) { - r->out.error_string = NULL; - talloc_free(samsync_ctx); - return NT_STATUS_NO_MEMORY; + return NT_STATUS_OK; +} + +static NTSTATUS vampire_store_chunk(void *private_data, + const struct libnet_BecomeDC_StoreChunk *c) +{ + struct vampire_state *s = talloc_get_type(private_data, struct vampire_state); + WERROR status; + const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr; + uint32_t total_object_count; + uint32_t object_count; + struct drsuapi_DsReplicaObjectListItemEx *first_object; + uint32_t linked_attributes_count; + struct drsuapi_DsReplicaLinkedAttribute *linked_attributes; + const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector; + struct dsdb_extended_replicated_objects *objs; + struct repsFromTo1 *s_dsa; + char *tmp_dns_name; + uint32_t i; + + s_dsa = talloc_zero(s, struct repsFromTo1); + NT_STATUS_HAVE_NO_MEMORY(s_dsa); + s_dsa->other_info = talloc(s_dsa, struct repsFromTo1OtherInfo); + NT_STATUS_HAVE_NO_MEMORY(s_dsa->other_info); + + switch (c->ctr_level) { + case 1: + mapping_ctr = &c->ctr1->mapping_ctr; + total_object_count = c->ctr1->total_object_count; + object_count = c->ctr1->object_count; + first_object = c->ctr1->first_object; + linked_attributes_count = 0; + linked_attributes = NULL; + s_dsa->highwatermark = c->ctr1->new_highwatermark; + s_dsa->source_dsa_obj_guid = c->ctr1->source_dsa_guid; + s_dsa->source_dsa_invocation_id = c->ctr1->source_dsa_invocation_id; + uptodateness_vector = NULL; /* TODO: map it */ + break; + case 6: + mapping_ctr = &c->ctr6->mapping_ctr; + total_object_count = c->ctr6->total_object_count; + object_count = c->ctr6->object_count; + first_object = c->ctr6->first_object; + linked_attributes_count = c->ctr6->linked_attributes_count; + linked_attributes = c->ctr6->linked_attributes; + s_dsa->highwatermark = c->ctr6->new_highwatermark; + s_dsa->source_dsa_obj_guid = c->ctr6->source_dsa_guid; + s_dsa->source_dsa_invocation_id = c->ctr6->source_dsa_invocation_id; + uptodateness_vector = c->ctr6->uptodateness_vector; + break; + default: + return NT_STATUS_INVALID_PARAMETER; } - c->level = LIBNET_RPC_CONNECT_DC_INFO; - if (r->in.binding_string) { - c->in.binding = r->in.binding_string; - c->in.name = NULL; + s_dsa->replica_flags = DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE + | DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP + | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS; + memset(s_dsa->schedule, 0x11, sizeof(s_dsa->schedule)); + + tmp_dns_name = GUID_string(s_dsa->other_info, &s_dsa->source_dsa_obj_guid); + NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name); + tmp_dns_name = talloc_asprintf_append_buffer(tmp_dns_name, "._msdcs.%s", c->forest->dns_name); + NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name); + s_dsa->other_info->dns_name = tmp_dns_name; + + if (total_object_count) { + DEBUG(0,("Partition[%s] objects[%u/%u]\n", + c->partition->nc.dn, object_count, total_object_count)); } else { - c->in.binding = NULL; - c->in.name = cli_credentials_get_domain(machine_account); + DEBUG(0,("Partition[%s] objects[%u]\n", + c->partition->nc.dn, object_count)); } - - /* prepare connect to the NETLOGON pipe of PDC */ - c->in.dcerpc_iface = &ndr_table_netlogon; - - /* We must do this as the machine, not as any command-line - * user. So we override the credentials in the - * libnet_context */ - machine_net_ctx = talloc(samsync_ctx, struct libnet_context); - if (!machine_net_ctx) { - r->out.error_string = NULL; - talloc_free(samsync_ctx); - return NT_STATUS_NO_MEMORY; + + status = dsdb_extended_replicated_objects_commit(s->ldb, + c->partition->nc.dn, + mapping_ctr, + object_count, + first_object, + linked_attributes_count, + linked_attributes, + s_dsa, + uptodateness_vector, + c->gensec_skey, + s, &objs); + if (!W_ERROR_IS_OK(status)) { + DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status))); + return werror_to_ntstatus(status); } - *machine_net_ctx = *ctx; - machine_net_ctx->cred = machine_account; - - /* connect to the NETLOGON pipe of the PDC */ - nt_status = libnet_RpcConnect(machine_net_ctx, samsync_ctx, c); - if (!NT_STATUS_IS_OK(nt_status)) { - if (r->in.binding_string) { - r->out.error_string = talloc_asprintf(mem_ctx, - "Connection to NETLOGON pipe of DC %s failed: %s", - r->in.binding_string, c->out.error_string); - } else { - r->out.error_string = talloc_asprintf(mem_ctx, - "Connection to NETLOGON pipe of DC for %s failed: %s", - c->in.name, c->out.error_string); + + if (lp_parm_bool(s->lp_ctx, NULL, "become dc", "dump objects", false)) { + for (i=0; i < objs->num_objects; i++) { + struct ldb_ldif ldif; + fprintf(stdout, "#\n"); + ldif.changetype = LDB_CHANGETYPE_NONE; + ldif.msg = objs->objects[i].msg; + ldb_ldif_write_file(s->ldb, stdout, &ldif); + NDR_PRINT_DEBUG(replPropertyMetaDataBlob, objs->objects[i].meta_data); } - talloc_free(samsync_ctx); - return nt_status; } + talloc_free(s_dsa); + talloc_free(objs); - /* This makes a new pipe, on which we can do schannel. We - * should do this in the RpcConnect code, but the abstaction - * layers do not suit yet */ + for (i=0; i < linked_attributes_count; i++) { + const struct dsdb_attribute *sa; - nt_status = dcerpc_secondary_connection(c->out.dcerpc_pipe, &p, - c->out.dcerpc_pipe->binding); + if (!linked_attributes[i].identifier) { + return NT_STATUS_FOOBAR; + } - if (!NT_STATUS_IS_OK(nt_status)) { - r->out.error_string = talloc_asprintf(mem_ctx, - "Secondary connection to NETLOGON pipe of DC %s failed: %s", - dcerpc_server_name(p), nt_errstr(nt_status)); - talloc_free(samsync_ctx); - return nt_status; - } + if (!linked_attributes[i].value.blob) { + return NT_STATUS_FOOBAR; + } - nt_status = dcerpc_bind_auth_schannel(samsync_ctx, p, &ndr_table_netlogon, - machine_account, ctx->lp_ctx, DCERPC_AUTH_LEVEL_PRIVACY); + sa = dsdb_attribute_by_attributeID_id(s->schema, + linked_attributes[i].attid); + if (!sa) { + return NT_STATUS_FOOBAR; + } - if (!NT_STATUS_IS_OK(nt_status)) { - r->out.error_string = talloc_asprintf(mem_ctx, - "SCHANNEL authentication to NETLOGON pipe of DC %s failed: %s", - dcerpc_server_name(p), nt_errstr(nt_status)); - talloc_free(samsync_ctx); - return nt_status; + if (lp_parm_bool(s->lp_ctx, NULL, "become dc", "dump objects", false)) { + DEBUG(0,("# %s\n", sa->lDAPDisplayName)); + NDR_PRINT_DEBUG(drsuapi_DsReplicaLinkedAttribute, &linked_attributes[i]); + dump_data(0, + linked_attributes[i].value.blob->data, + linked_attributes[i].value.blob->length); + } } - state = talloc(samsync_ctx, struct libnet_SamSync_state); - if (!state) { - r->out.error_string = NULL; - talloc_free(samsync_ctx); - return nt_status; - } - - state->domain_name = c->out.domain_name; - state->domain_sid = c->out.domain_sid; - state->realm = c->out.realm; - state->domain_guid = c->out.guid; - state->machine_net_ctx = machine_net_ctx; - state->netlogon_pipe = p; - - /* initialise the callback layer. It may wish to contact the - * server with ldap, now we know the name */ + return NT_STATUS_OK; +} + +NTSTATUS libnet_vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, + struct libnet_vampire *r) +{ + struct libnet_JoinDomain *join; + struct libnet_BecomeDC b; + struct libnet_UnbecomeDC u; + struct vampire_state *s; + struct ldb_message *msg; + int ldb_ret; + uint32_t i; + NTSTATUS status; + + const char *account_name; + const char *netbios_name; - if (r->in.init_fn) { - char *error_string; - nt_status = r->in.init_fn(samsync_ctx, - r->in.fn_ctx, - state, - &error_string); - if (!NT_STATUS_IS_OK(nt_status)) { - r->out.error_string = talloc_steal(mem_ctx, error_string); - talloc_free(samsync_ctx); - return nt_status; + r->out.error_string = NULL; + + s = talloc_zero(mem_ctx , struct vampire_state); + if (!s) { + return NT_STATUS_NO_MEMORY; + } + + join = talloc_zero(s, struct libnet_JoinDomain); + if (!join) { + return NT_STATUS_NO_MEMORY; + } + + if (r->in.netbios_name != NULL) { + netbios_name = r->in.netbios_name; + } else { + netbios_name = talloc_reference(join, lp_netbios_name(ctx->lp_ctx)); + if (!netbios_name) { + r->out.error_string = NULL; + talloc_free(s); + return NT_STATUS_NO_MEMORY; } } - /* get NETLOGON credentials */ + account_name = talloc_asprintf(join, "%s$", netbios_name); + if (!account_name) { + r->out.error_string = NULL; + talloc_free(s); + return NT_STATUS_NO_MEMORY; + } + + join->in.domain_name = r->in.domain_name; + join->in.account_name = account_name; + join->in.netbios_name = netbios_name; + join->in.level = LIBNET_JOINDOMAIN_AUTOMATIC; + join->in.acct_type = ACB_WSTRUST; + join->in.recreate_account = false; + status = libnet_JoinDomain(ctx, join, join); + if (!NT_STATUS_IS_OK(status)) { + r->out.error_string = talloc_steal(mem_ctx, join->out.error_string); + talloc_free(s); + return status; + } + + s->join = join; + + ZERO_STRUCT(b); + b.in.domain_dns_name = join->out.realm; + b.in.domain_netbios_name = join->out.domain_name; + b.in.domain_sid = join->out.domain_sid; + b.in.source_dsa_address = join->out.samr_binding->host; + b.in.dest_dsa_netbios_name = netbios_name; + + b.in.callbacks.private_data = s; + b.in.callbacks.check_options = vampire_check_options; + b.in.callbacks.prepare_db = vampire_prepare_db; + b.in.callbacks.schema_chunk = vampire_schema_chunk; + b.in.callbacks.config_chunk = vampire_store_chunk; + b.in.callbacks.domain_chunk = vampire_store_chunk; + + status = libnet_BecomeDC(s->ctx, s, &b); + if (!NT_STATUS_IS_OK(status)) { + printf("libnet_BecomeDC() failed - %s\n", nt_errstr(status)); + talloc_free(s); + return status; + } - nt_status = dcerpc_schannel_creds(p->conn->security_state.generic_state, samsync_ctx, &creds); - if (!NT_STATUS_IS_OK(nt_status)) { - r->out.error_string = talloc_strdup(mem_ctx, "Could not obtain NETLOGON credentials from DCERPC/GENSEC layer"); - talloc_free(samsync_ctx); - return nt_status; + msg = ldb_msg_new(s); + if (!msg) { + printf("ldb_msg_new() failed\n"); + talloc_free(s); + return NT_STATUS_NO_MEMORY; + } + msg->dn = ldb_dn_new(msg, s->ldb, "@ROOTDSE"); + if (!msg->dn) { + printf("ldb_msg_new(@ROOTDSE) failed\n"); + talloc_free(s); + return NT_STATUS_NO_MEMORY; } - /* Setup details for the synchronisation */ - dbsync.in.logon_server = talloc_asprintf(samsync_ctx, "\\\\%s", dcerpc_server_name(p)); - dbsync.in.computername = cli_credentials_get_workstation(machine_account); - dbsync.in.preferredmaximumlength = (uint32_t)-1; - ZERO_STRUCT(dbsync.in.return_authenticator); + ldb_ret = ldb_msg_add_string(msg, "isSynchronized", "TRUE"); + if (ldb_ret != LDB_SUCCESS) { + printf("ldb_msg_add_string(msg, isSynchronized, TRUE) failed: %d\n", ldb_ret); + talloc_free(s); + return NT_STATUS_NO_MEMORY; + } - for (i=0;i< ARRAY_SIZE(database_ids); i++) { - dbsync.in.sync_context = 0; - dbsync.in.database_id = database_ids[i]; - - do { - int d; - loop_ctx = talloc_named(samsync_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->out.error_string = talloc_asprintf(mem_ctx, "DatabaseSync failed - %s", nt_errstr(nt_status)); - talloc_free(samsync_ctx); - return nt_status; - } - - if (!creds_client_check(creds, &dbsync.out.return_authenticator.cred)) { - r->out.error_string = talloc_strdup(mem_ctx, "Credential chaining on incoming DatabaseSync failed"); - talloc_free(samsync_ctx); - return NT_STATUS_ACCESS_DENIED; - } - - dbsync.in.sync_context = dbsync.out.sync_context; - - /* For every single remote 'delta' entry: */ - 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"); - /* 'Fix' elements, by decrypting and - * de-obfuscating the data */ - nt_status = fix_delta(delta_ctx, - creds, - r->in.rid_crypt, - dbsync.in.database_id, - &dbsync.out.delta_enum_array->delta_enum[d], - &error_string); - if (!NT_STATUS_IS_OK(nt_status)) { - r->out.error_string = talloc_steal(mem_ctx, error_string); - talloc_free(samsync_ctx); - return nt_status; - } + for (i=0; i < msg->num_elements; i++) { + msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; + } - /* Now call the callback. This will - * do something like print the data or - * write to an ldb */ - nt_status = r->in.delta_fn(delta_ctx, - r->in.fn_ctx, - dbsync.in.database_id, - &dbsync.out.delta_enum_array->delta_enum[d], - &error_string); - if (!NT_STATUS_IS_OK(nt_status)) { - r->out.error_string = talloc_steal(mem_ctx, error_string); - talloc_free(samsync_ctx); - return nt_status; - } - talloc_free(delta_ctx); - } - talloc_free(loop_ctx); - } while (NT_STATUS_EQUAL(dbsync_nt_status, STATUS_MORE_ENTRIES)); - - if (!NT_STATUS_IS_OK(dbsync_nt_status)) { - r->out.error_string = talloc_asprintf(mem_ctx, "libnet_SamSync_netlogon failed: unexpected inconsistancy. Should not get error %s here", nt_errstr(nt_status)); - talloc_free(samsync_ctx); - return dbsync_nt_status; - } - nt_status = NT_STATUS_OK; + printf("mark ROOTDSE with isSynchronized=TRUE\n"); + ldb_ret = ldb_modify(s->ldb, msg); + if (ldb_ret != LDB_SUCCESS) { + printf("ldb_modify() failed: %d\n", ldb_ret); + talloc_free(s); + return NT_STATUS_INTERNAL_DB_ERROR; } - talloc_free(samsync_ctx); - return nt_status; } - -- cgit From 8a982108a4f115e350c4246276f2ec886934c7fe Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 9 Apr 2008 14:59:32 +1000 Subject: Link the new vampire code togeather. This adds in the newly attached secrets handling, as well as an interface to the command line 'net' tool. Andrew Bartlett (This used to be commit 1282e3c39479aa580124206814b493370d10690a) --- source4/libnet/libnet_vampire.c | 50 +++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 12 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index cd9167f541..476b97954f 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -37,6 +37,7 @@ #include "lib/ldb_wrap.h" #include "auth/auth.h" #include "param/param.h" +#include "param/provision.h" /* List of tasks vampire.py must perform: @@ -52,7 +53,6 @@ List of tasks vampire.py must perform: */ struct vampire_state { - struct libnet_context *ctx; const char *netbios_name; struct libnet_JoinDomain *join; struct cli_credentials *machine_account; @@ -93,7 +93,7 @@ static NTSTATUS vampire_prepare_db(void *private_data, settings.schema_dn_str = p->forest->schema_dn_str; settings.netbios_name = p->dest_dsa->netbios_name; settings.realm = s->join->out.realm; - settings.domain = s->join->out.domain; + settings.domain = s->join->out.domain_name; settings.server_dn_str = p->dest_dsa->server_dn_str; settings.machine_password = generate_random_str(s, 16); settings.targetdir = s->targetdir; @@ -115,18 +115,13 @@ static NTSTATUS vampire_prepare_db(void *private_data, return NT_STATUS_INTERNAL_DB_ERROR; } - /* We must set these up to ensure the replMetaData is written correctly, before our NTDS Settings entry is replicated */ + /* We must set these up to ensure the replMetaData is written correctly, + before our NTDS Settings entry is replicated */ ok = samdb_set_ntds_invocation_id(s->ldb, &p->dest_dsa->invocation_id); if (!ok) { DEBUG(0,("Failed to set cached ntds invocationId\n")); return NT_STATUS_FOOBAR; } - ok = samdb_set_ntds_objectGUID(s->ldb, &p->dest_dsa->ntds_guid); - if (!ok) { - DEBUG(0,("Failed to set cached ntds objectGUID\n")); - return NT_STATUS_FOOBAR; - } - s->lp_ctx = lp_ctx; return NT_STATUS_OK; @@ -591,10 +586,11 @@ static NTSTATUS vampire_store_chunk(void *private_data, return NT_STATUS_OK; } -NTSTATUS libnet_vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, - struct libnet_vampire *r) +NTSTATUS libnet_Vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, + struct libnet_Vampire *r) { struct libnet_JoinDomain *join; + struct libnet_set_join_secrets *set_secrets; struct libnet_BecomeDC b; struct libnet_UnbecomeDC u; struct vampire_state *s; @@ -651,6 +647,8 @@ NTSTATUS libnet_vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, s->join = join; + s->targetdir = r->in.targetdir; + ZERO_STRUCT(b); b.in.domain_dns_name = join->out.realm; b.in.domain_netbios_name = join->out.domain_name; @@ -665,7 +663,7 @@ NTSTATUS libnet_vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, b.in.callbacks.config_chunk = vampire_store_chunk; b.in.callbacks.domain_chunk = vampire_store_chunk; - status = libnet_BecomeDC(s->ctx, s, &b); + status = libnet_BecomeDC(ctx, s, &b); if (!NT_STATUS_IS_OK(status)) { printf("libnet_BecomeDC() failed - %s\n", nt_errstr(status)); talloc_free(s); @@ -703,4 +701,32 @@ NTSTATUS libnet_vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, talloc_free(s); return NT_STATUS_INTERNAL_DB_ERROR; } + + set_secrets = talloc_zero(s, struct libnet_set_join_secrets); + if (!set_secrets) { + return NT_STATUS_NO_MEMORY; + } + + set_secrets->in.domain_name = join->out.domain_name; + set_secrets->in.realm = join->out.realm; + set_secrets->in.account_name = account_name; + set_secrets->in.netbios_name = netbios_name; + set_secrets->in.join_type = SEC_CHAN_BDC; + set_secrets->in.join_password = join->out.join_password; + set_secrets->in.kvno = join->out.kvno; + set_secrets->in.domain_sid = join->out.domain_sid; + + status = libnet_set_join_secrets(ctx, set_secrets, set_secrets); + if (!NT_STATUS_IS_OK(status)) { + r->out.error_string = talloc_steal(mem_ctx, set_secrets->out.error_string); + talloc_free(s); + return status; + } + + r->out.domain_name = talloc_steal(r, join->out.domain_name); + r->out.domain_sid = talloc_steal(r, join->out.domain_sid); + talloc_free(s); + + return NT_STATUS_OK; + } -- cgit From a1a3089199d9ad523e63148a5a2afcca8db39bdf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 11 Apr 2008 19:15:24 +1000 Subject: Use the python-provided ldb and lp_ctx pointers in libnet_vampire.c By using the already open smb.conf and sam.ldb, we not only avoid overhead, but also remove the risk we could touch a different database. Andrew Bartlett (This used to be commit 38634183a074556c8dfdcb6affc60f4bcc15a3f0) --- source4/libnet/libnet_vampire.c | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 476b97954f..9d32088fe6 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -77,14 +77,8 @@ static NTSTATUS vampire_prepare_db(void *private_data, { struct vampire_state *s = talloc_get_type(private_data, struct vampire_state); struct provision_settings settings; + struct provision_result result; NTSTATUS status; - bool ok; - struct loadparm_context *lp_ctx = loadparm_init(s); - char *smbconf; - - if (!lp_ctx) { - return NT_STATUS_NO_MEMORY; - } settings.site_name = p->dest_dsa->site_name; settings.root_dn_str = p->forest->root_dn_str; @@ -98,31 +92,14 @@ static NTSTATUS vampire_prepare_db(void *private_data, settings.machine_password = generate_random_str(s, 16); settings.targetdir = s->targetdir; - status = provision_bare(s, s->lp_ctx, &settings); - - smbconf = talloc_asprintf(lp_ctx, "%s/%s", s->targetdir, "/etc/smb.conf"); + status = provision_bare(s, s->lp_ctx, &settings, &result); - ok = lp_load(lp_ctx, smbconf); - if (!ok) { - DEBUG(0,("Failed load freshly generated smb.conf '%s'\n", smbconf)); - return NT_STATUS_INVALID_PARAMETER; + if (!NT_STATUS_IS_OK(status)) { + return status; } - s->ldb = samdb_connect(s, lp_ctx, - system_session(s, lp_ctx)); - if (!s->ldb) { - DEBUG(0,("Failed to open '%s'\n", lp_sam_url(lp_ctx))); - return NT_STATUS_INTERNAL_DB_ERROR; - } - - /* We must set these up to ensure the replMetaData is written correctly, - before our NTDS Settings entry is replicated */ - ok = samdb_set_ntds_invocation_id(s->ldb, &p->dest_dsa->invocation_id); - if (!ok) { - DEBUG(0,("Failed to set cached ntds invocationId\n")); - return NT_STATUS_FOOBAR; - } - s->lp_ctx = lp_ctx; + s->ldb = result.samdb; + s->lp_ctx = result.lp_ctx; return NT_STATUS_OK; -- cgit From b54e6a815514ef1e5a0a5d11ca43f85e0366b8dc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 14 Apr 2008 17:58:09 +0200 Subject: Ensure we initialise s->lp_ctx for the way into the provision. Andrew Bartlett (This used to be commit b191a1953c24545e9dc1869fc33cb29343d4e3f2) --- source4/libnet/libnet_vampire.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 9d32088fe6..1cc63a3fb0 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -586,6 +586,8 @@ NTSTATUS libnet_Vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } + s->lp_ctx = ctx->lp_ctx; + join = talloc_zero(s, struct libnet_JoinDomain); if (!join) { return NT_STATUS_NO_MEMORY; -- cgit From 21fc7673780aa1d7c0caab7b17ff9171238913ba Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Apr 2008 12:23:44 +0200 Subject: Specify event_context to ldb_wrap_connect explicitly. (This used to be commit b4e1ae07a284c044704322446c94351c2decff91) --- source4/libnet/libnet_vampire.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 1cc63a3fb0..56a8ebe034 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -70,6 +70,7 @@ struct vampire_state { const char *targetdir; struct loadparm_context *lp_ctx; + struct event_context *event_ctx; }; static NTSTATUS vampire_prepare_db(void *private_data, @@ -335,7 +336,7 @@ static NTSTATUS vampire_apply_schema(struct vampire_state *s, s->schema = NULL; DEBUG(0,("Reopen the SAM LDB with system credentials and a already stored schema\n")); - s->ldb = samdb_connect(s, s->lp_ctx, + s->ldb = samdb_connect(s, s->event_ctx, s->lp_ctx, system_session(s, s->lp_ctx)); if (!s->ldb) { DEBUG(0,("Failed to reopen sam.ldb\n")); @@ -569,7 +570,6 @@ NTSTATUS libnet_Vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_JoinDomain *join; struct libnet_set_join_secrets *set_secrets; struct libnet_BecomeDC b; - struct libnet_UnbecomeDC u; struct vampire_state *s; struct ldb_message *msg; int ldb_ret; @@ -581,12 +581,13 @@ NTSTATUS libnet_Vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, r->out.error_string = NULL; - s = talloc_zero(mem_ctx , struct vampire_state); + s = talloc_zero(mem_ctx, struct vampire_state); if (!s) { return NT_STATUS_NO_MEMORY; } s->lp_ctx = ctx->lp_ctx; + s->event_ctx = ctx->event_ctx; join = talloc_zero(s, struct libnet_JoinDomain); if (!join) { -- cgit From c6ea7f02217fc28dc30882d3f9d543b805de2d74 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Jul 2008 16:59:09 +0200 Subject: drsuapi: total_object_count was the wrong guess The total_object_count member of DsGetNCChangesCtr[1|6] was wrong it's the error code of an extended operation. DsGetNCChangesCtr6 has a nc_object_count value which contains the estimated amount of objects in the naming_context. W2k seems to have a bug and sends this number of objects in the extended_ret field. Maybe it's just a bug and not a feature:-) metze (This used to be commit 67931092128ce89aadf689a54e20d6e4a9d7fe2c) --- source4/libnet/libnet_vampire.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 56a8ebe034..c9975c8a29 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -136,7 +136,6 @@ static NTSTATUS vampire_apply_schema(struct vampire_state *s, { WERROR status; const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr; - uint32_t total_object_count; uint32_t object_count; struct drsuapi_DsReplicaObjectListItemEx *first_object; struct drsuapi_DsReplicaObjectListItemEx *cur; @@ -164,7 +163,6 @@ static NTSTATUS vampire_apply_schema(struct vampire_state *s, switch (c->ctr_level) { case 1: mapping_ctr = &c->ctr1->mapping_ctr; - total_object_count = c->ctr1->total_object_count; object_count = s->schema_part.object_count; first_object = s->schema_part.first_object; linked_attributes_count = 0; @@ -176,7 +174,6 @@ static NTSTATUS vampire_apply_schema(struct vampire_state *s, break; case 6: mapping_ctr = &c->ctr6->mapping_ctr; - total_object_count = c->ctr6->total_object_count; object_count = s->schema_part.object_count; first_object = s->schema_part.first_object; linked_attributes_count = 0; /* TODO: ! */ @@ -370,7 +367,7 @@ static NTSTATUS vampire_schema_chunk(void *private_data, struct vampire_state *s = talloc_get_type(private_data, struct vampire_state); WERROR status; const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr; - uint32_t total_object_count; + uint32_t nc_object_count; uint32_t object_count; struct drsuapi_DsReplicaObjectListItemEx *first_object; struct drsuapi_DsReplicaObjectListItemEx *cur; @@ -378,13 +375,13 @@ static NTSTATUS vampire_schema_chunk(void *private_data, switch (c->ctr_level) { case 1: mapping_ctr = &c->ctr1->mapping_ctr; - total_object_count = c->ctr1->total_object_count; + nc_object_count = c->ctr1->extended_ret; /* maybe w2k send this unexpected? */ object_count = c->ctr1->object_count; first_object = c->ctr1->first_object; break; case 6: mapping_ctr = &c->ctr6->mapping_ctr; - total_object_count = c->ctr6->total_object_count; + nc_object_count = c->ctr6->nc_object_count; object_count = c->ctr6->object_count; first_object = c->ctr6->first_object; break; @@ -392,9 +389,9 @@ static NTSTATUS vampire_schema_chunk(void *private_data, return NT_STATUS_INVALID_PARAMETER; } - if (total_object_count) { + if (nc_object_count) { DEBUG(0,("Schema-DN[%s] objects[%u/%u]\n", - c->partition->nc.dn, object_count, total_object_count)); + c->partition->nc.dn, object_count, nc_object_count)); } else { DEBUG(0,("Schema-DN[%s] objects[%u]\n", c->partition->nc.dn, object_count)); @@ -442,7 +439,7 @@ static NTSTATUS vampire_store_chunk(void *private_data, struct vampire_state *s = talloc_get_type(private_data, struct vampire_state); WERROR status; const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr; - uint32_t total_object_count; + uint32_t nc_object_count; uint32_t object_count; struct drsuapi_DsReplicaObjectListItemEx *first_object; uint32_t linked_attributes_count; @@ -461,7 +458,7 @@ static NTSTATUS vampire_store_chunk(void *private_data, switch (c->ctr_level) { case 1: mapping_ctr = &c->ctr1->mapping_ctr; - total_object_count = c->ctr1->total_object_count; + nc_object_count = c->ctr1->extended_ret; /* maybe w2k send this unexpected? */ object_count = c->ctr1->object_count; first_object = c->ctr1->first_object; linked_attributes_count = 0; @@ -473,7 +470,7 @@ static NTSTATUS vampire_store_chunk(void *private_data, break; case 6: mapping_ctr = &c->ctr6->mapping_ctr; - total_object_count = c->ctr6->total_object_count; + nc_object_count = c->ctr6->nc_object_count; object_count = c->ctr6->object_count; first_object = c->ctr6->first_object; linked_attributes_count = c->ctr6->linked_attributes_count; @@ -498,9 +495,9 @@ static NTSTATUS vampire_store_chunk(void *private_data, NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name); s_dsa->other_info->dns_name = tmp_dns_name; - if (total_object_count) { + if (nc_object_count) { DEBUG(0,("Partition[%s] objects[%u/%u]\n", - c->partition->nc.dn, object_count, total_object_count)); + c->partition->nc.dn, object_count, nc_object_count)); } else { DEBUG(0,("Partition[%s] objects[%u]\n", c->partition->nc.dn, object_count)); -- cgit From f0e44c35afce5ceec5d247dbd4205301251e403c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Jul 2008 13:01:56 +0200 Subject: drsuapi: make use of the 'more_data' field in DsGetNCChangesCtr[1|6] metze (This used to be commit 35c7fa470a7433d081403b2b57a331c7dc287aef) --- source4/libnet/libnet_vampire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index c9975c8a29..fed57dbdcf 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -426,7 +426,7 @@ static NTSTATUS vampire_schema_chunk(void *private_data, for (cur = first_object; cur->next_object; cur = cur->next_object) {} s->schema_part.last_object = cur; - if (c->partition->highwatermark.tmp_highest_usn == c->partition->highwatermark.highest_usn) { + if (!c->partition->more_data) { return vampire_apply_schema(s, c); } -- cgit From 29049aa67085fb7f7059a2a2f5f89b558155d6f5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Jul 2008 13:02:54 +0200 Subject: drsuapi: print out the number of linked attribute values we got metze (This used to be commit 34f8b2abdd546f6b60ddae2ad839119f211c995c) --- source4/libnet/libnet_vampire.c | 43 ++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 16 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index fed57dbdcf..42d6f72dd1 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -371,30 +371,37 @@ static NTSTATUS vampire_schema_chunk(void *private_data, uint32_t object_count; struct drsuapi_DsReplicaObjectListItemEx *first_object; struct drsuapi_DsReplicaObjectListItemEx *cur; + uint32_t nc_linked_attributes_count; + uint32_t linked_attributes_count; switch (c->ctr_level) { case 1: - mapping_ctr = &c->ctr1->mapping_ctr; - nc_object_count = c->ctr1->extended_ret; /* maybe w2k send this unexpected? */ - object_count = c->ctr1->object_count; - first_object = c->ctr1->first_object; + mapping_ctr = &c->ctr1->mapping_ctr; + nc_object_count = c->ctr1->extended_ret; /* maybe w2k send this unexpected? */ + object_count = c->ctr1->object_count; + first_object = c->ctr1->first_object; + nc_linked_attributes_count = 0; + linked_attributes_count = 0; break; case 6: - mapping_ctr = &c->ctr6->mapping_ctr; - nc_object_count = c->ctr6->nc_object_count; - object_count = c->ctr6->object_count; - first_object = c->ctr6->first_object; + mapping_ctr = &c->ctr6->mapping_ctr; + nc_object_count = c->ctr6->nc_object_count; + object_count = c->ctr6->object_count; + first_object = c->ctr6->first_object; + nc_linked_attributes_count = c->ctr6->nc_linked_attributes_count; + linked_attributes_count = c->ctr6->linked_attributes_count; break; default: return NT_STATUS_INVALID_PARAMETER; } if (nc_object_count) { - DEBUG(0,("Schema-DN[%s] objects[%u/%u]\n", - c->partition->nc.dn, object_count, nc_object_count)); + DEBUG(0,("Schema-DN[%s] objects[%u/%u] linked_values[%u/%u]\n", + c->partition->nc.dn, object_count, nc_object_count, + linked_attributes_count, nc_linked_attributes_count)); } else { - DEBUG(0,("Schema-DN[%s] objects[%u]\n", - c->partition->nc.dn, object_count)); + DEBUG(0,("Schema-DN[%s] objects[%u] linked_values[%u\n", + c->partition->nc.dn, object_count, linked_attributes_count)); } if (!s->schema) { @@ -442,6 +449,7 @@ static NTSTATUS vampire_store_chunk(void *private_data, uint32_t nc_object_count; uint32_t object_count; struct drsuapi_DsReplicaObjectListItemEx *first_object; + uint32_t nc_linked_attributes_count; uint32_t linked_attributes_count; struct drsuapi_DsReplicaLinkedAttribute *linked_attributes; const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector; @@ -461,6 +469,7 @@ static NTSTATUS vampire_store_chunk(void *private_data, nc_object_count = c->ctr1->extended_ret; /* maybe w2k send this unexpected? */ object_count = c->ctr1->object_count; first_object = c->ctr1->first_object; + nc_linked_attributes_count = 0; linked_attributes_count = 0; linked_attributes = NULL; s_dsa->highwatermark = c->ctr1->new_highwatermark; @@ -473,6 +482,7 @@ static NTSTATUS vampire_store_chunk(void *private_data, nc_object_count = c->ctr6->nc_object_count; object_count = c->ctr6->object_count; first_object = c->ctr6->first_object; + nc_linked_attributes_count = c->ctr6->nc_linked_attributes_count; linked_attributes_count = c->ctr6->linked_attributes_count; linked_attributes = c->ctr6->linked_attributes; s_dsa->highwatermark = c->ctr6->new_highwatermark; @@ -496,11 +506,12 @@ static NTSTATUS vampire_store_chunk(void *private_data, s_dsa->other_info->dns_name = tmp_dns_name; if (nc_object_count) { - DEBUG(0,("Partition[%s] objects[%u/%u]\n", - c->partition->nc.dn, object_count, nc_object_count)); + DEBUG(0,("Partition[%s] objects[%u/%u] linked_values[%u/%u]\n", + c->partition->nc.dn, object_count, nc_object_count, + linked_attributes_count, nc_linked_attributes_count)); } else { - DEBUG(0,("Partition[%s] objects[%u]\n", - c->partition->nc.dn, object_count)); + DEBUG(0,("Partition[%s] objects[%u] linked_values[%u\n", + c->partition->nc.dn, object_count, linked_attributes_count)); } status = dsdb_extended_replicated_objects_commit(s->ldb, -- cgit