From 06ae42483582ee76c3f6848697cf61cc142dd86a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Dec 2003 00:31:54 +0000 Subject: * netr_ServerPasswordSet() now works - the test suite changes the machine account password. * neater handling on value() options in IDL. The auto-print code will now display the right value so you don't need to initialise it in your C code (This used to be commit 3dd978b12bb5571fba4e1839c0f7ee60cf729aa2) --- source4/build/pidl/parser.pm | 12 ++++- source4/libcli/auth/credentials.c | 11 ++++ source4/librpc/idl/netlogon.idl | 25 +++++----- source4/librpc/ndr/libndr.h | 4 +- source4/passdb/secrets.c | 2 +- source4/torture/rpc/lsa.c | 5 -- source4/torture/rpc/netlogon.c | 102 +++++++++++++++++++++++++++++++------- source4/torture/rpc/samr.c | 11 +--- 8 files changed, 122 insertions(+), 50 deletions(-) (limited to 'source4') diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm index 095c083514..1ba1a57cab 100644 --- a/source4/build/pidl/parser.pm +++ b/source4/build/pidl/parser.pm @@ -405,6 +405,12 @@ sub ParseElementPrintScalar($$) return; } + if (my $value = util::has_property($e, "value")) { + pidl "\tif (ndr->flags & LIBNDR_PRINT_SET_VALUES) {\n"; + pidl "\t\t$cprefix$var_prefix$e->{NAME} = $value;\n"; + pidl "\t}\n"; + } + if (util::is_fixed_array($e)) { ParseElementPrintBuffer($e, $var_prefix); } elsif (util::has_direct_buffers($e)) { @@ -1100,7 +1106,11 @@ sub ParseFunctionPrint($) pidl "\n{\n"; pidl "\tndr_print_struct(ndr, name, \"$fn->{NAME}\");\n"; pidl "\tndr->depth++;\n"; - + + pidl "\tif (flags & NDR_SET_VALUES) {\n"; + pidl "\t\tndr->flags |= LIBNDR_PRINT_SET_VALUES;\n"; + pidl "}\n"; + pidl "\tif (flags & NDR_IN) {\n"; pidl "\t\tndr_print_struct(ndr, \"in\", \"$fn->{NAME}\");\n"; pidl "\tndr->depth++;\n"; diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 80ea2e9583..1749037e8f 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -109,3 +109,14 @@ void creds_authenticator(struct netr_CredentialState *creds, next->cred = creds->cred2; next->timestamp = creds->sequence; } + + +/* + encrypt a 16 byte password buffer using the session key +*/ +void creds_encrypt(struct netr_CredentialState *creds, struct netr_Password *pass) +{ + struct netr_Password tmp; + cred_hash3(tmp.data, pass->data, creds->session_key, 1); + *pass = tmp; +} diff --git a/source4/librpc/idl/netlogon.idl b/source4/librpc/idl/netlogon.idl index efdbed34be..6dd7ae3fe5 100644 --- a/source4/librpc/idl/netlogon.idl +++ b/source4/librpc/idl/netlogon.idl @@ -91,7 +91,7 @@ interface netlogon } netr_IdentityInfo; typedef [flag(NDR_PAHEX)] struct { - uint8 password[16]; + uint8 data[16]; } netr_Password; typedef struct { @@ -252,19 +252,18 @@ interface netlogon [in,out] netr_Credential credentials ); -#if 0 - typedef struct { - uint8 encrypted_password[16]; - } ENCRYPTED_LM_OWF_PASSWORD; - WERROR netr_ServerPasswordSet( - [in] unistr *server_name, - [in] unistr username, - [in] uint16 secure_challenge_type, - [in] unistr ComputerName, - [in][ref] AUTHENTICATOR credential, - [in][ref] LM_OWF_PASSWORD UasNewPassword, - [out][ref] AUTHENTICATOR return_authenticator + + NTSTATUS netr_ServerPasswordSet( + [in] unistr *server_name, + [in] unistr username, + [in] uint16 secure_challenge_type, + [in] unistr computer_name, + [in] netr_Authenticator credential, + [in] netr_Password new_password, + [out] netr_Authenticator return_authenticator ); + +#if 0 typedef struct { unistr *username; netr_String dummy1; diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h index cce0b12b73..8e57d0fb73 100644 --- a/source4/librpc/ndr/libndr.h +++ b/source4/librpc/ndr/libndr.h @@ -111,6 +111,7 @@ struct ndr_print { #define LIBNDR_ALIGN_FLAGS (LIBNDR_FLAG_ALIGN2|LIBNDR_FLAG_ALIGN4|LIBNDR_FLAG_ALIGN8) #define LIBNDR_PRINT_ARRAY_HEX (1<<15) +#define LIBNDR_PRINT_SET_VALUES (1<<16) /* useful macro for debugging */ @@ -119,7 +120,7 @@ struct ndr_print { #define NDR_PRINT_FUNCTION_DEBUG(type, flags, p) ndr_print_function_debug((ndr_print_function_t)ndr_print_ ##type, #type, flags, p) #define NDR_PRINT_BOTH_DEBUG(type, p) NDR_PRINT_FUNCTION_DEBUG(type, NDR_BOTH, p) #define NDR_PRINT_OUT_DEBUG(type, p) NDR_PRINT_FUNCTION_DEBUG(type, NDR_OUT, p) -#define NDR_PRINT_IN_DEBUG(type, p) NDR_PRINT_FUNCTION_DEBUG(type, NDR_IN, p) +#define NDR_PRINT_IN_DEBUG(type, p) NDR_PRINT_FUNCTION_DEBUG(type, NDR_IN | NDR_SET_VALUES, p) enum ndr_err_code { @@ -149,6 +150,7 @@ enum ndr_err_code { #define NDR_IN 1 #define NDR_OUT 2 #define NDR_BOTH 3 +#define NDR_SET_VALUES 4 #define NDR_PULL_NEED_BYTES(ndr, n) do { \ if ((n) > ndr->data_size || ndr->offset + (n) > ndr->data_size) { \ diff --git a/source4/passdb/secrets.c b/source4/passdb/secrets.c index 01eb82f414..60e211e66f 100644 --- a/source4/passdb/secrets.c +++ b/source4/passdb/secrets.c @@ -82,7 +82,7 @@ BOOL secrets_store(const char *key, const void *data, size_t size) dbuf.dptr = memdup(data, size); dbuf.dsize = size; - ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) == 0; + ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); free(kbuf.dptr); free(dbuf.dptr); diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index c98b7ec60a..84b29281e5 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -21,14 +21,9 @@ #include "includes.h" -/* - this makes the debug code display the right thing -*/ static void init_lsa_Name(struct lsa_Name *name, const char *s) { name->name = s; - name->name_len = strlen_m(s)*2; - name->name_size = name->name_len; } static BOOL test_OpenPolicy(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index 50b72dfec1..bef658e92f 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -65,20 +65,14 @@ static BOOL test_LogonUasLogoff(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) } -static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) +static BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, + struct netr_CredentialState *creds) { NTSTATUS status; struct netr_ServerReqChallenge r; struct netr_ServerAuthenticate a; - struct netr_LogonSamLogon l; - struct netr_LogonSamLogoff lo; const char *plain_pass; uint8 mach_pwd[16]; - struct netr_Authenticator auth, auth2; - struct netr_NetworkInfo ninfo; - const char *username = lp_parm_string(-1, "torture", "username"); - const char *password = lp_parm_string(-1, "torture", "password"); - struct netr_CredentialState creds; printf("Testing ServerReqChallenge\n"); @@ -100,7 +94,7 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) E_md4hash(plain_pass, mach_pwd); - creds_init(&creds, &r.in.credentials, &r.out.credentials, mach_pwd, + creds_init(creds, &r.in.credentials, &r.out.credentials, mach_pwd, &a.in.credentials); a.in.server_name = NULL; @@ -116,11 +110,31 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) return False; } - if (!creds_check(&creds, &a.out.credentials)) { + if (!creds_check(creds, &a.out.credentials)) { printf("Credential chaining failed\n"); return False; } + return True; +} + +/* + try a netlogon SamLogon +*/ +static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + struct netr_LogonSamLogon r; + struct netr_Authenticator auth, auth2; + struct netr_NetworkInfo ninfo; + const char *username = lp_parm_string(-1, "torture", "username"); + const char *password = lp_parm_string(-1, "torture", "password"); + struct netr_CredentialState creds; + + if (!test_SetupCredentials(p, mem_ctx, &creds)) { + return False; + } + ninfo.logon_info.domain_name.string = lp_workgroup(); ninfo.logon_info.parameter_control = 0; ninfo.logon_info.logon_id_low = 0; @@ -140,23 +154,69 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) creds_authenticator(&creds, &auth); - l.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); - l.in.workstation = lp_netbios_name(); - l.in.credential = &auth; - l.in.authenticator = &auth2; - l.in.logon_level = 2; - l.in.logon.network = &ninfo; - l.in.validation_level = 2; + r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); + r.in.workstation = lp_netbios_name(); + r.in.credential = &auth; + r.in.authenticator = &auth2; + r.in.logon_level = 2; + r.in.logon.network = &ninfo; + r.in.validation_level = 2; printf("Testing SamLogon\n"); - status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &l); + status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("LogonSamLogon - %s\n", nt_errstr(status)); return False; } - if (!creds_check(&creds, &l.out.authenticator->cred)) { + if (!creds_check(&creds, &r.out.authenticator->cred)) { + printf("Credential chaining failed\n"); + } + + return True; +} + + +/* + try a change password for our machine account +*/ +static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + struct netr_ServerPasswordSet r; + const char *password; + struct netr_CredentialState creds; + + if (!test_SetupCredentials(p, mem_ctx, &creds)) { + return False; + } + + creds_authenticator(&creds, &r.in.credential); + + r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); + r.in.username = talloc_asprintf(mem_ctx, "%s$", lp_netbios_name()); + r.in.secure_challenge_type = 2; + r.in.computer_name = lp_netbios_name(); + + password = generate_random_str(8); + E_md4hash(password, r.in.new_password.data); + + creds_encrypt(&creds, &r.in.new_password); + + printf("Testing ServerPasswordSet on machine account\n"); + + status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r); + if (!NT_STATUS_IS_OK(status)) { + printf("ServerPasswordSet - %s\n", nt_errstr(status)); + return False; + } + + if (!secrets_store_machine_password(password)) { + printf("Failed to save machine password\n"); + } + + if (!creds_check(&creds, &r.out.return_authenticator.cred)) { printf("Credential chaining failed\n"); } @@ -191,6 +251,10 @@ BOOL torture_rpc_netlogon(int dummy) ret = False; } + if (!test_SetPassword(p, mem_ctx)) { + ret = False; + } + if (!test_SamLogon(p, mem_ctx)) { ret = False; } diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index f7006241b5..45a0c4f02d 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -26,18 +26,9 @@ static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle); -/* - this makes the debug code display the right thing -*/ static void init_samr_Name(struct samr_Name *name, const char *s) { - name->name_len = strlen_m(s)*2; - name->name_size = name->name_len; - if (name->name_len == 0) { - name->name = NULL; - } else { - name->name = s; - } + name->name = s; } static BOOL test_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, -- cgit