diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/libcli/auth/credentials.h | 6 | ||||
-rw-r--r-- | source4/libcli/auth/gensec.h | 1 | ||||
-rw-r--r-- | source4/libcli/util/smbdes.c | 2 | ||||
-rw-r--r-- | source4/libcli/util/smbencrypt.c | 25 | ||||
-rw-r--r-- | source4/librpc/idl/netlogon.idl | 32 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc_schannel.c | 67 | ||||
-rw-r--r-- | source4/rpc_server/netlogon/schannel_state.c | 11 | ||||
-rw-r--r-- | source4/torture/config.mk | 1 | ||||
-rw-r--r-- | source4/torture/rpc/netlogon.c | 76 | ||||
-rw-r--r-- | source4/torture/rpc/schannel.c | 98 | ||||
-rw-r--r-- | source4/torture/rpc/xplogin.c | 15 | ||||
-rw-r--r-- | source4/torture/torture.c | 1 |
12 files changed, 260 insertions, 75 deletions
diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index a6e119e1ad..30114fe7fa 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/libcli/auth/credentials.h @@ -36,12 +36,6 @@ struct creds_CredentialState { to NT4. Actually, anything other than 1ff would seem to do... */ #define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff - -#define NETLOGON_NEG_ARCFOUR 0x00000004 -#define NETLOGON_NEG_128BIT 0x00004000 - -#define NETLOGON_NEG_SCHANNEL 0x40000000 - /* these are the flags that ADS clients use */ #define NETLOGON_NEG_AUTH2_ADS_FLAGS (0x200fbffb | NETLOGON_NEG_ARCFOUR | NETLOGON_NEG_128BIT | NETLOGON_NEG_SCHANNEL) diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index b2c685332b..23d9861cb7 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -28,7 +28,6 @@ struct gensec_user { const char *realm; const char *name; const char *password; - char schan_session_key[16]; }; struct gensec_target { const char *principal; diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index a7c8f760ea..4e4222b9e6 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -439,7 +439,7 @@ void arcfour_crypt(uint8_t *data, const uint8_t keystr[16], int len) /* Decode a sam password hash into a password. The password hash is the same method used to store passwords in the NT registry. The DES key used is based on the RID of the user. */ -void sam_pwd_hash(uint_t rid, const uint8_t *in, uint8_t *out, int forw) +void sam_rid_crypt(uint_t rid, const uint8_t *in, uint8_t *out, int forw) { uint8_t s[14]; diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index d327b53f9d..dac8674f03 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -374,15 +374,13 @@ static DATA_BLOB LMv2_generate_response(const uint8_t ntlm_v2_hash[16], return final_response; } -BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, - const DATA_BLOB *server_chal, - const DATA_BLOB *names_blob, - DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) +BOOL SMBNTLMv2encrypt_hash(const char *user, const char *domain, const char nt_hash[16], + const DATA_BLOB *server_chal, + const DATA_BLOB *names_blob, + DATA_BLOB *lm_response, DATA_BLOB *nt_response, + DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) { - uint8_t nt_hash[16]; uint8_t ntlm_v2_hash[16]; - E_md4hash(password, nt_hash); /* We don't use the NT# directly. Instead we use it mashed up with the username and domain. @@ -420,6 +418,19 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password return True; } +BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, + const DATA_BLOB *server_chal, + const DATA_BLOB *names_blob, + DATA_BLOB *lm_response, DATA_BLOB *nt_response, + DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) +{ + uint8_t nt_hash[16]; + E_md4hash(password, nt_hash); + + return SMBNTLMv2encrypt_hash(user, domain, nt_hash, server_chal, names_blob, + lm_response, nt_response, lm_session_key, user_session_key); +} + /*********************************************************** encode a password buffer with a unicode password. The buffer is filled with random data to make it harder to attack. diff --git a/source4/librpc/idl/netlogon.idl b/source4/librpc/idl/netlogon.idl index f6677d9621..f55049d30e 100644 --- a/source4/librpc/idl/netlogon.idl +++ b/source4/librpc/idl/netlogon.idl @@ -285,6 +285,11 @@ interface netlogon /*****************/ /* Function 0x07 */ + /* SAM database types */ + const int SAM_DATABASE_DOMAIN = 0x00; /* Domain users and groups */ + const int SAM_DATABASE_BUILTIN = 0x01; /* BUILTIN users and groups */ + const int SAM_DATABASE_PRIVS = 0x02; /* Privileges */ + typedef struct { unistr *account_name; netr_String unknown1; @@ -313,19 +318,19 @@ interface netlogon netr_String logon_script; netr_String description; netr_String workstations; - NTTIME LastLogon; - NTTIME LastLogoff; + NTTIME last_logon; + NTTIME last_logoff; samr_LogonHours logon_hours; uint16 bad_pw_count; uint16 logon_count; - NTTIME PwLastSet; - NTTIME AccountExpires; - uint32 AccountControl; - samr_Password lmpw; - samr_Password ntpw; - bool8 NTPwPresent; - bool8 LMPwPresent; - bool8 PwExpired; + NTTIME last_password_change; + NTTIME acct_expiry; + uint32 acct_flags; + samr_Password lmpassword; + samr_Password ntpassword; + bool8 ntpassword_present; + bool8 lmpassword_present; + bool8 password_expired; netr_String UserComment; netr_String Parameters; uint16 CountryCode; @@ -778,6 +783,13 @@ interface netlogon ); + /* If this flag is not set, then the passwords and LM session keys are + * encrypted with DES calls. (And the user session key is + * unencrypted) */ + const int NETLOGON_NEG_ARCFOUR = 0x00000004; + const int NETLOGON_NEG_128BIT = 0x00004000; + const int NETLOGON_NEG_SCHANNEL = 0x40000000; + /*****************/ /* Function 0x0F */ diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c index c0db63e8b8..1e1bdb8227 100644 --- a/source4/librpc/rpc/dcerpc_schannel.c +++ b/source4/librpc/rpc/dcerpc_schannel.c @@ -32,7 +32,7 @@ enum schannel_position { struct dcerpc_schannel_state { enum schannel_position state; struct schannel_state *schannel_state; - struct creds_CredentialState creds; + struct creds_CredentialState *creds; char *account_name; }; @@ -41,7 +41,7 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p, const char *username, const char *password, int chan_type, - uint8_t new_session_key[16]); + struct creds_CredentialState *creds); /* wrappers for the schannel_*() functions @@ -121,6 +121,15 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security, return NT_STATUS_OK; } + status = schannel_start(&dce_schan_state->schannel_state, + dce_schan_state->creds->session_key, + True); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start schannel client\n")); + return status; + } + talloc_steal(dce_schan_state, dce_schan_state->schannel_state); + bind_schannel.unknown1 = 0; #if 0 /* to support this we'd need to have access to the full domain name */ @@ -178,7 +187,7 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security, /* start up the schannel server code */ status = schannel_start(&dce_schan_state->schannel_state, - dce_schan_state->creds.session_key, False); + dce_schan_state->creds->session_key, False); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("Could not initialise schannel state for account %s: %s\n", account_name, nt_errstr(status))); @@ -249,12 +258,7 @@ NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security, { struct dcerpc_schannel_state *dce_schan_state = gensec_security->private_data; - *creds = talloc_p(mem_ctx, struct creds_CredentialState); - if (!*creds) { - return NT_STATUS_NO_MEMORY; - } - - **creds = dce_schan_state->creds; + *creds = dce_schan_state->creds; return NT_STATUS_OK; } @@ -277,38 +281,23 @@ static NTSTATUS dcerpc_schannel_start(struct gensec_security *gensec_security) static NTSTATUS dcerpc_schannel_server_start(struct gensec_security *gensec_security) { NTSTATUS status; - struct dcerpc_schannel_state *dce_schan_state; status = dcerpc_schannel_start(gensec_security); - - dce_schan_state = gensec_security->private_data; - dce_schan_state->schannel_state = NULL; - if (!NT_STATUS_IS_OK(status)) { return status; } + return NT_STATUS_OK; } static NTSTATUS dcerpc_schannel_client_start(struct gensec_security *gensec_security) { NTSTATUS status; - struct dcerpc_schannel_state *dce_schan_state; status = dcerpc_schannel_start(gensec_security); if (!NT_STATUS_IS_OK(status)) { return status; } - dce_schan_state = gensec_security->private_data; - - status = schannel_start(&dce_schan_state->schannel_state, - gensec_security->user.schan_session_key, - True); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start schannel client\n")); - return status; - } - talloc_steal(dce_schan_state, dce_schan_state->schannel_state); return NT_STATUS_OK; } @@ -336,7 +325,7 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p, const char *username, const char *password, int chan_type, - uint8_t new_session_key[16]) + struct creds_CredentialState *creds) { NTSTATUS status; struct dcerpc_pipe *p2; @@ -344,7 +333,6 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p, struct netr_ServerAuthenticate2 a; struct netr_Credential credentials1, credentials2, credentials3; struct samr_Password mach_pwd; - struct creds_CredentialState creds; const char *workgroup, *workstation; uint32_t negotiate_flags; @@ -388,7 +376,7 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p, step 3 - authenticate on the netlogon pipe */ E_md4hash(password, mach_pwd.hash); - creds_client_init(&creds, &credentials1, &credentials2, &mach_pwd, &credentials3, + creds_client_init(creds, &credentials1, &credentials2, &mach_pwd, &credentials3, negotiate_flags); a.in.server_name = r.in.server_name; @@ -405,7 +393,7 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p, return status; } - if (!creds_client_check(&creds, a.out.credentials)) { + if (!creds_client_check(creds, a.out.credentials)) { return NT_STATUS_UNSUCCESSFUL; } @@ -416,8 +404,6 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p, */ dcerpc_pipe_close(p2); - memcpy(new_session_key, creds.session_key, 16); - return NT_STATUS_OK; } @@ -430,18 +416,16 @@ NTSTATUS dcerpc_bind_auth_schannel_withkey(struct dcerpc_pipe *p, const char *domain, const char *username, const char *password, - uint8_t session_key[16]) + struct creds_CredentialState *creds) { NTSTATUS status; + struct dcerpc_schannel_state *dce_schan_state; status = gensec_client_start(p, &p->security_state.generic_state); if (!NT_STATUS_IS_OK(status)) { return status; } - memcpy(p->security_state.generic_state->user.schan_session_key, - session_key, 16); - status = gensec_set_username(p->security_state.generic_state, username); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to set schannel username to %s: %s\n", username, nt_errstr(status))); @@ -464,6 +448,9 @@ NTSTATUS dcerpc_bind_auth_schannel_withkey(struct dcerpc_pipe *p, return status; } + dce_schan_state = p->security_state.generic_state->private_data; + dce_schan_state->creds = talloc_reference(dce_schan_state, creds); + status = dcerpc_bind_auth3(p, DCERPC_AUTH_TYPE_SCHANNEL, dcerpc_auth_level(p), uuid, version); @@ -484,7 +471,11 @@ NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p, { NTSTATUS status; int chan_type = 0; - uint8_t new_session_key[16]; + struct creds_CredentialState *creds; + creds = talloc_p(p, struct creds_CredentialState); + if (!creds) { + return NT_STATUS_NO_MEMORY; + } if (p->flags & DCERPC_SCHANNEL_BDC) { chan_type = SEC_CHAN_BDC; @@ -498,7 +489,7 @@ NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p, username, password, chan_type, - new_session_key); + creds); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to fetch schannel session key: %s\n", @@ -508,7 +499,7 @@ NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p, return dcerpc_bind_auth_schannel_withkey(p, uuid, version, domain, username, password, - new_session_key); + creds); } static const struct gensec_security_ops gensec_dcerpc_schannel_security_ops = { diff --git a/source4/rpc_server/netlogon/schannel_state.c b/source4/rpc_server/netlogon/schannel_state.c index 8797ffa120..61e755bc0f 100644 --- a/source4/rpc_server/netlogon/schannel_state.c +++ b/source4/rpc_server/netlogon/schannel_state.c @@ -120,7 +120,7 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, */ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, const char *computer_name, - struct creds_CredentialState *creds) + struct creds_CredentialState **creds) { struct ldb_wrap *ldb; time_t expiry; @@ -129,7 +129,10 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, const struct ldb_val *val; char *expr=NULL; - ZERO_STRUCTP(creds); + *creds = talloc_zero_p(mem_ctx, struct creds_CredentialState); + if (!*creds) { + return NT_STATUS_NO_MEMORY; + } ldb = schannel_db_connect(mem_ctx); if (ldb == NULL) { @@ -161,7 +164,7 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, return NT_STATUS_INVALID_HANDLE; } - memcpy(creds->session_key, val->data, 16); + memcpy((*creds)->session_key, val->data, 16); val = ldb_msg_find_ldb_val(res[0], "seed"); if (val == NULL || val->length != 8) { @@ -169,7 +172,7 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, return NT_STATUS_INVALID_HANDLE; } - memcpy(creds->seed.data, val->data, 8); + memcpy((*creds)->seed.data, val->data, 8); talloc_free(ldb); diff --git a/source4/torture/config.mk b/source4/torture/config.mk index cef76baac4..d939175bb3 100644 --- a/source4/torture/config.mk +++ b/source4/torture/config.mk @@ -90,6 +90,7 @@ ADD_OBJ_FILES = \ torture/rpc/schannel.o \ torture/rpc/netlogon.o \ torture/rpc/samlogon.o \ + torture/rpc/samsync.o \ torture/rpc/bind.o REQUIRED_SUBSYSTEMS = \ LIBSMB diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index fe64727d79..9c87106550 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -316,6 +316,72 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) 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 creds_CredentialState creds; + + int i; + BOOL ret = True; + + if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, + machine_password, &creds)) { + return False; + } + + ninfo.identity_info.domain_name.string = lp_workgroup(); + ninfo.identity_info.parameter_control = 0; + ninfo.identity_info.logon_id_low = 0; + ninfo.identity_info.logon_id_high = 0; + ninfo.identity_info.account_name.string = username; + ninfo.identity_info.workstation.string = TEST_MACHINE_NAME; + generate_random_buffer(ninfo.challenge, + sizeof(ninfo.challenge)); + ninfo.nt.length = 24; + ninfo.nt.data = talloc(mem_ctx, 24); + SMBNTencrypt(password, ninfo.challenge, ninfo.nt.data); + ninfo.lm.length = 24; + ninfo.lm.data = talloc(mem_ctx, 24); + SMBencrypt(password, ninfo.challenge, ninfo.lm.data); + + r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); + r.in.workstation = TEST_MACHINE_NAME; + r.in.credential = &auth; + r.in.return_authenticator = &auth2; + r.in.logon_level = 2; + r.in.logon.network = &ninfo; + + for (i=2;i<=3;i++) { + ZERO_STRUCT(auth2); + creds_client_authenticator(&creds, &auth); + + r.in.validation_level = i; + + printf("Testing SamLogon with validation level %d\n", i); + + status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r); + if (!NT_STATUS_IS_OK(status)) { + printf("LogonSamLogon - %s\n", nt_errstr(status)); + ret = False; + } + + if (!creds_client_check(&creds, &r.out.return_authenticator->cred)) { + printf("Credential chaining failed\n"); + } + } + + return ret; +} + + /* we remember the sequence numbers so we can easily do a DatabaseDelta */ static uint64_t sequence_nums[3]; @@ -328,7 +394,7 @@ static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) NTSTATUS status; struct netr_DatabaseSync r; struct creds_CredentialState creds; - const uint32_t database_ids[] = {0, 1, 2}; + const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; int i; BOOL ret = True; @@ -366,7 +432,7 @@ static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) if (r.out.delta_enum_array && r.out.delta_enum_array->num_deltas > 0 && - r.out.delta_enum_array->delta_enum[0].delta_type == 1 && + r.out.delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN && r.out.delta_enum_array->delta_enum[0].delta_union.domain) { sequence_nums[r.in.database_id] = r.out.delta_enum_array->delta_enum[0].delta_union.domain->sequence_num; @@ -969,7 +1035,7 @@ BOOL torture_rpc_netlogon(void) struct dcerpc_pipe *p; TALLOC_CTX *mem_ctx; BOOL ret = True; - void *join_ctx; + struct test_join *join_ctx; mem_ctx = talloc_init("torture_rpc_netlogon"); @@ -996,6 +1062,10 @@ BOOL torture_rpc_netlogon(void) ret = False; } + if (!test_SamLogon(p, mem_ctx)) { + ret = False; + } + if (!test_SetPassword(p, mem_ctx)) { ret = False; } diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c index 323adde534..7a9786fa2d 100644 --- a/source4/torture/rpc/schannel.c +++ b/source4/torture/rpc/schannel.c @@ -53,6 +53,63 @@ static BOOL test_samr_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) return True; } + +/* + try a netlogon SamLogon +*/ +static BOOL test_netlogon_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, + struct creds_CredentialState *creds) +{ + 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"); + + int i; + BOOL ret = True; + + ninfo.identity_info.domain_name.string = lp_workgroup(); + ninfo.identity_info.parameter_control = 0; + ninfo.identity_info.logon_id_low = 0; + ninfo.identity_info.logon_id_high = 0; + ninfo.identity_info.account_name.string = username; + ninfo.identity_info.workstation.string = TEST_MACHINE_NAME; + generate_random_buffer(ninfo.challenge, + sizeof(ninfo.challenge)); + ninfo.nt.length = 24; + ninfo.nt.data = talloc(mem_ctx, 24); + SMBNTencrypt(password, ninfo.challenge, ninfo.nt.data); + ninfo.lm.length = 24; + ninfo.lm.data = talloc(mem_ctx, 24); + SMBencrypt(password, ninfo.challenge, ninfo.lm.data); + + + r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); + r.in.workstation = TEST_MACHINE_NAME; + r.in.credential = &auth; + r.in.return_authenticator = &auth2; + r.in.logon_level = 2; + r.in.logon.network = &ninfo; + + for (i=2;i<3;i++) { + ZERO_STRUCT(auth2); + creds_client_authenticator(creds, &auth); + + r.in.validation_level = i; + + status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r); + + if (!creds_client_check(creds, &r.out.return_authenticator->cred)) { + printf("Credential chaining failed\n"); + ret = False; + } + + } + return ret; +} + /* test a schannel connection with the given flags */ @@ -66,6 +123,8 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx, const char *binding = lp_parm_string(-1, "torture", "binding"); struct dcerpc_binding b; struct dcerpc_pipe *p; + struct dcerpc_pipe *p_netlogon; + struct creds_CredentialState *creds; join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), acct_flags, &machine_password); @@ -99,12 +158,51 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx, goto failed; } + + status = dcerpc_parse_binding(mem_ctx, binding, &b); + if (!NT_STATUS_IS_OK(status)) { + printf("Bad binding string %s\n", binding); + goto failed; + } + + + /* Also test that when we connect to the netlogon pipe, that + * the credentials we setup on the first pipe are valid for + * the second */ + + b.flags &= ~DCERPC_AUTH_OPTIONS; + b.flags |= dcerpc_flags; + + status = dcerpc_pipe_connect_b(&p_netlogon, &b, + DCERPC_NETLOGON_UUID, + DCERPC_NETLOGON_VERSION, + lp_workgroup(), + TEST_MACHINE_NAME, + machine_password); + + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + + status = dcerpc_schannel_creds(p_netlogon->security_state.generic_state, mem_ctx, &creds); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + + /* do a couple of logins */ + if (!test_netlogon_ops(p_netlogon, mem_ctx, creds)) { + printf("Failed to process schannel secured ops\n"); + goto failed; + } + torture_leave_domain(join_ctx); + dcerpc_pipe_close(p_netlogon); dcerpc_pipe_close(p); return True; failed: torture_leave_domain(join_ctx); + dcerpc_pipe_close(p_netlogon); dcerpc_pipe_close(p); return False; } diff --git a/source4/torture/rpc/xplogin.c b/source4/torture/rpc/xplogin.c index a3cca7003c..e0bb706255 100644 --- a/source4/torture/rpc/xplogin.c +++ b/source4/torture/rpc/xplogin.c @@ -1021,7 +1021,7 @@ static BOOL xp_login(const char *dcname, const char *wksname, struct smbcli_transport *transport; struct dcerpc_pipe *netlogon_pipe; - struct creds_CredentialState netlogon_creds; + struct creds_CredentialState *netlogon_creds; struct dcerpc_pipe *netlogon_schannel_pipe; @@ -1032,13 +1032,18 @@ static BOOL xp_login(const char *dcname, const char *wksname, if (mem_ctx == NULL) return False; + netlogon_creds = talloc_p(mem_ctx, struct creds_CredentialState); + if (!netlogon_creds) { + return False; + } + if (!NT_STATUS_IS_OK(after_negprot(&transport, dcname, 139, wksname))) return False; if (!NT_STATUS_IS_OK(setup_netlogon_creds(transport, &netlogon_pipe, wksname, domain, wkspwd, - &netlogon_creds))) + netlogon_creds))) return False; if (!NT_STATUS_IS_OK(test_enumtrusts(transport))) @@ -1063,13 +1068,13 @@ static BOOL xp_login(const char *dcname, const char *wksname, DCERPC_NETLOGON_UUID, DCERPC_NETLOGON_VERSION, "", "", "", - netlogon_creds.session_key); + netlogon_creds); if (!NT_STATUS_IS_OK(status)) return False; status = torture_samlogon(netlogon_schannel_pipe, - &netlogon_creds, wksname, domain, + netlogon_creds, wksname, domain, user1name, user1pw); if (!NT_STATUS_IS_OK(status)) @@ -1078,7 +1083,7 @@ static BOOL xp_login(const char *dcname, const char *wksname, talloc_free(netlogon_pipe); status = torture_samlogon(netlogon_schannel_pipe, - &netlogon_creds, wksname, domain, + netlogon_creds, wksname, domain, user2name, user2pw); if (!NT_STATUS_IS_OK(status)) diff --git a/source4/torture/torture.c b/source4/torture/torture.c index 975b83e6ad..4db4662f6c 100644 --- a/source4/torture/torture.c +++ b/source4/torture/torture.c @@ -2439,6 +2439,7 @@ static struct { {"RPC-SAMR", torture_rpc_samr, 0}, {"RPC-NETLOGON", torture_rpc_netlogon, 0}, {"RPC-SAMLOGON", torture_rpc_samlogon, 0}, + {"RPC-SAMSYNC", torture_rpc_samsync, 0}, {"RPC-SCHANNEL", torture_rpc_schannel, 0}, {"RPC-WKSSVC", torture_rpc_wkssvc, 0}, {"RPC-SRVSVC", torture_rpc_srvsvc, 0}, |