diff options
author | Andrew Bartlett <abartlet@samba.org> | 2004-06-07 08:54:49 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:56:35 -0500 |
commit | 46c88d561f9a5cbaf2b70e937fbc20dff6d31703 (patch) | |
tree | ca3a6cd0b0a18052d56f48c87cb6ed9cf7965973 /source4 | |
parent | bd40d94a05e5f3353b54b2cc94d76c58be7e3766 (diff) | |
download | samba-46c88d561f9a5cbaf2b70e937fbc20dff6d31703.tar.gz samba-46c88d561f9a5cbaf2b70e937fbc20dff6d31703.tar.bz2 samba-46c88d561f9a5cbaf2b70e937fbc20dff6d31703.zip |
r1061: The start of the SamLogon call for the NETLOGON pipe.
Changes:
- Check for a valid 'pipe_state' in netr_ServerAuthenticate3 before
we dereference it
- removes the expansionroom[7] in the netr_SamInfo* structs to 7
individual elements.
- renames netr_SamInfo -> netr_SamInfo2
netr_SamInfo2 -> netr_SamInfo3
- Having the thing we always called an 'info3' being 'netr_SamInfo2'
was just too confusing.
- Expand and fill in extra details about users from the SAM, into
the server_info, for processing into the SamLogon reply.
- Add a dum_sid_dup() function to duplicate a struct dom_sid
The SamLogon code currently does not return supplementary groups, and is
only tested with Samba4 smbtorture.
Andrew Bartlett
(This used to be commit 6c92563b7961f15fc74b02601e105d5e1d04f04d)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/libcli/util/dom_sid.c | 33 | ||||
-rw-r--r-- | source4/librpc/idl/netlogon.idl | 26 | ||||
-rw-r--r-- | source4/rpc_server/netlogon/dcerpc_netlogon.c | 185 | ||||
-rw-r--r-- | source4/torture/rpc/netlogon.c | 56 |
4 files changed, 217 insertions, 83 deletions
diff --git a/source4/libcli/util/dom_sid.c b/source4/libcli/util/dom_sid.c index cdf89ccf96..9b8b45e302 100644 --- a/source4/libcli/util/dom_sid.c +++ b/source4/libcli/util/dom_sid.c @@ -89,3 +89,36 @@ struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr) return ret; } +/* + convert a string to a dom_sid, returning a talloc'd dom_sid +*/ +struct dom_sid *dom_sid_dup(TALLOC_CTX *mem_ctx, struct dom_sid *dom_sid) +{ + struct dom_sid *ret; + int i; + ret = talloc_p(mem_ctx, struct dom_sid); + if (!ret) { + return NULL; + } + + ret->sub_auths = talloc_array_p(mem_ctx, uint32_t, dom_sid->num_auths); + if (!ret->sub_auths) { + return NULL; + } + + ret->sid_rev_num = dom_sid->sid_rev_num; + ret->id_auth[0] = dom_sid->id_auth[0]; + ret->id_auth[1] = dom_sid->id_auth[1]; + ret->id_auth[2] = dom_sid->id_auth[2]; + ret->id_auth[3] = dom_sid->id_auth[3]; + ret->id_auth[4] = dom_sid->id_auth[4]; + ret->id_auth[5] = dom_sid->id_auth[5]; + ret->num_auths = dom_sid->num_auths; + + for (i=0;i<dom_sid->num_auths;i++) { + ret->sub_auths[i] = dom_sid->sub_auths[i]; + } + + return ret; +} + diff --git a/source4/librpc/idl/netlogon.idl b/source4/librpc/idl/netlogon.idl index a3e1e804dc..48154dc001 100644 --- a/source4/librpc/idl/netlogon.idl +++ b/source4/librpc/idl/netlogon.idl @@ -171,8 +171,14 @@ interface netlogon dom_sid2 *domain_sid; netr_LMSessionKey LMSessKey; uint32 AccountControl; - uint32 expansionroom[7]; - } netr_SamInfo; + uint32 unknown1; + uint32 unknown2; + uint32 unknown3; + uint32 unknown4; + uint32 unknown5; + uint32 unknown6; + uint32 unknown7; + } netr_SamInfo2; typedef struct { dom_sid2 *sid; @@ -205,10 +211,16 @@ interface netlogon dom_sid2 *domain_sid; netr_LMSessionKey LMSessKey; uint32 AccountControl; - uint32 expansionroom[7]; + uint32 unknown1; + uint32 unknown2; + uint32 unknown3; + uint32 unknown4; + uint32 unknown5; + uint32 unknown6; + uint32 unknown7; uint32 sidcount; [size_is(sidcount)] netr_SidAttr *sids; - } netr_SamInfo2; + } netr_SamInfo3; typedef struct { uint32 pac_size; @@ -227,8 +239,8 @@ interface netlogon } netr_PacInfo; typedef union { - [case(2)] netr_SamInfo *sam; - [case(3)] netr_SamInfo2 *sam2; + [case(2)] netr_SamInfo2 *sam2; + [case(3)] netr_SamInfo3 *sam3; [case(4)] netr_PacInfo *pac; [case(5)] netr_PacInfo *pac2; } netr_Validation; @@ -237,7 +249,7 @@ interface netlogon [in] unistr *server_name, [in] unistr *workstation, [in] netr_Authenticator *credential, - [in][out] netr_Authenticator *authenticator, + [in][out] netr_Authenticator *return_authenticator, [in] uint16 logon_level, [in] [switch_is(logon_level)] netr_LogonLevel logon, [in] uint16 validation_level, diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index bfc5e3b759..933f28d84a 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -228,7 +228,6 @@ static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TAL return nt_status; } - static NTSTATUS netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_ServerAuthenticate *r) { @@ -302,12 +301,12 @@ static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLO const char **domain_attrs = attrs; ZERO_STRUCT(mod); - if (!netr_creds_server_step_check(pipe_state, &r->in.credential, &r->out.return_authenticator)) { + if (!pipe_state) { + DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); return NT_STATUS_ACCESS_DENIED; } - if (!pipe_state) { - DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); + if (!netr_creds_server_step_check(pipe_state, &r->in.credential, &r->out.return_authenticator)) { return NT_STATUS_ACCESS_DENIED; } @@ -426,8 +425,6 @@ static WERROR netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX */ -#if 0 - static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_LogonSamLogon *r) { @@ -438,8 +435,24 @@ static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CT struct auth_serversupplied_info *server_info; NTSTATUS nt_status; const uint8_t *chal; + static const char zeros[16]; + struct netr_SamInfo2 *sam2; + struct netr_SamInfo3 *sam; - + if (!pipe_state) { + DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); + return NT_STATUS_ACCESS_DENIED; + } + + r->out.return_authenticator = talloc_p(mem_ctx, struct netr_Authenticator); + if (!r->out.return_authenticator) { + return NT_STATUS_NO_MEMORY; + } + + if (!netr_creds_server_step_check(pipe_state, r->in.credential, r->out.return_authenticator)) { + return NT_STATUS_ACCESS_DENIED; + } + switch (r->in.logon_level) { case 1: case 3: @@ -476,8 +489,8 @@ static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CT r->in.logon.network->identity_info.account_name.string, r->in.logon.network->identity_info.domain_name.string, r->in.logon.network->identity_info.workstation.string, - r->in.logon.network->nt.data, r->in.logon.network->nt.length, - r->in.logon.network->lm.data, r->in.logon.network->lm.length); + r->in.logon.network->lm.data, r->in.logon.network->lm.length, + r->in.logon.network->nt.data, r->in.logon.network->nt.length); break; default: free_auth_context(&auth_context); @@ -498,48 +511,127 @@ static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CT } free_auth_context(&auth_context); + sam = talloc_p(mem_ctx, struct netr_SamInfo3); + + sam->last_logon = server_info->last_logon; + sam->last_logoff = server_info->last_logoff; + sam->acct_expiry = server_info->acct_expiry; + sam->last_password_change = server_info->last_password_change; + sam->allow_password_change = server_info->allow_password_change; + sam->force_password_change = server_info->force_password_change; + + sam->account_name.string = talloc_strdup(mem_ctx, server_info->account_name); + sam->full_name.string = talloc_strdup(mem_ctx, server_info->full_name); + sam->logon_script.string = talloc_strdup(mem_ctx, server_info->account_name); + sam->profile_path.string = talloc_strdup(mem_ctx, server_info->profile_path); + sam->home_directory.string = talloc_strdup(mem_ctx, server_info->home_directory); + sam->home_drive.string = talloc_strdup(mem_ctx, server_info->home_drive); + + sam->logon_count = server_info->logon_count; + sam->bad_password_count = sam->bad_password_count; + sam->rid = server_info->user_sid->sub_auths[server_info->user_sid->num_auths-1]; + sam->primary_gid = server_info->primary_group_sid->sub_auths[server_info->primary_group_sid->num_auths-1]; + sam->group_count = 0; + sam->groupids = NULL; + + sam->acct_flags = server_info->acct_flags; + + sam->logon_server.string = lp_netbios_name(); + + sam->domain.string = talloc_strdup(mem_ctx, server_info->domain); + + sam->domain_sid = dom_sid_dup(mem_ctx, server_info->user_sid); + sam->domain_sid->num_auths--; + + sam->sidcount = 0; + sam->sids = NULL; + + if (server_info->user_session_key.length == sizeof(sam->key.key)) { + memcpy(sam->key.key, server_info->user_session_key.data, sizeof(sam->key.key)); + } else { + ZERO_STRUCT(sam->key.key); + } + + if (memcmp(sam->key.key, zeros, + sizeof(sam->key.key)) != 0) { + /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */ + creds_arcfour_crypt(pipe_state->creds, + sam->key.key, + sizeof(sam->key.key)); + } + + if (server_info->lm_session_key.length == sizeof(sam->LMSessKey.key)) { + memcpy(sam->LMSessKey.key, server_info->lm_session_key.data, + sizeof(sam->LMSessKey.key)); + } else { + ZERO_STRUCT(sam->LMSessKey.key); + } + + if (memcmp(sam->LMSessKey.key, zeros, + sizeof(sam->LMSessKey.key)) != 0) { + creds_arcfour_crypt(pipe_state->creds, + sam->LMSessKey.key, + sizeof(sam->LMSessKey.key)); + } + switch (r->in.validation_level) { case 2: { - struct netr_SamInfo *sam; - sam = talloc_p(mem_ctx, struct netr_SamInfo); - r->out.validation.sam = sam; - - sam->last_logon = server_info->last_logon; - sam->last_logoff = server_info->last_logoff; - sam->acct_expiry = server_info->acct_expiry; - sam->last_password_change = server_info->last_password_change; - sam->allow_password_change = server_info->allow_password_change; - sam->force_password_change = server_info->force_password_change; - - sam->account_name.string = talloc_strdup(mem_ctx, server_info->account_name); - sam->full_name.string = talloc_strdup(mem_ctx, server_info->full_name); - sam->logon_script.string = talloc_strdup(mem_ctx, server_info->account_name); - sam->profile_path.string = talloc_strdup(mem_ctx, server_info->profile_path); - sam->home_directory.string = talloc_strdup(mem_ctx, server_info->home_directory); - sam->home_drive.string = talloc_strdup(mem_ctx, server_info->home_drive); - - sam->logon_count = server_info->logon_count; - sam->bad_password_count = sam->bad_password_count; - sam->rid = server_info->user_sid->sub_auths[server_info->user_sid->num_auths-1]; - sam->primary_gid = server_info->primary_group_sid->sub_auths[server_info->primary_group_sid->num_auths-1]; - sam->group_count = 0; - sam->groupids = NULL; - - sam->acct_flags = server_info->acct_flags; - - sam->domain.string = talloc_strdup(mem_ctx, server_info->domain); - - /* need to finish */ + sam2 = talloc_p(mem_ctx, struct netr_SamInfo2); + r->out.validation.sam2 = sam2; + sam2->last_logon = sam->last_logon; + sam2->last_logoff = sam->last_logoff; + sam2->acct_expiry = sam->acct_expiry; + + sam2->last_password_change = sam->last_password_change; + sam2->allow_password_change = sam->allow_password_change; + + sam2->force_password_change = sam->force_password_change; + + + sam2->account_name = sam->account_name; + sam2->full_name = sam->full_name; + sam2->logon_script = sam->logon_script; + sam2->profile_path = sam->profile_path; + sam2->home_directory = sam->home_directory; + sam2->home_drive = sam->home_drive; + + sam2->logon_count = sam->logon_count; + sam2->bad_password_count = sam->bad_password_count; + sam2->rid = sam->rid; + sam2->primary_gid = sam->primary_gid; + sam2->group_count = sam->group_count; + sam2->groupids = sam->groupids; + + sam2->acct_flags = sam->acct_flags; + + sam2->key = sam->key; + + sam2->logon_server = sam->logon_server; + + sam2->domain = sam->domain; + + sam2->domain_sid = sam->domain_sid; + + sam2->LMSessKey = sam->LMSessKey; + + sam2->AccountControl = sam->AccountControl; + + /* can we implicit memcpy an array? */ + + sam2->unknown1 = sam->unknown1; + sam2->unknown2 = sam->unknown2; + sam2->unknown3 = sam->unknown3; + sam2->unknown4 = sam->unknown4; + sam2->unknown5 = sam->unknown5; + sam2->unknown6 = sam->unknown6; + sam2->unknown7 = sam->unknown7; break; } case 3: { - struct netr_SamInfo2 *sam; - sam = talloc_p(mem_ctx, struct netr_SamInfo2); - r->out.validation.sam2 = sam; - + r->out.validation.sam3 = sam; break; } default: @@ -550,13 +642,6 @@ static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CT return NT_STATUS_OK; } -#else -static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct netr_LogonSamLogon *r) -{ - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); -} -#endif /* netr_LogonSamLogoff diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index a0b49d91eb..a336ef7acb 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -355,7 +355,7 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state, ZERO_STRUCT(samlogon_state->auth2); creds_client_authenticator(&samlogon_state->creds, &samlogon_state->auth); - r->out.authenticator = NULL; + r->out.return_authenticator = NULL; status = dcerpc_netr_LogonSamLogon(samlogon_state->p, samlogon_state->mem_ctx, r); if (!NT_STATUS_IS_OK(status)) { if (error_string) { @@ -363,8 +363,8 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state, } } - if (!r->out.authenticator || - !creds_client_check(&samlogon_state->creds, &r->out.authenticator->cred)) { + if (!r->out.return_authenticator || + !creds_client_check(&samlogon_state->creds, &r->out.return_authenticator->cred)) { printf("Credential chaining failed\n"); } @@ -377,30 +377,19 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state, if (r->in.validation_level == 2) { static const char zeros[16]; - if (memcmp(r->out.validation.sam->LMSessKey.key, zeros, - sizeof(r->out.validation.sam->LMSessKey.key)) != 0) { + if (memcmp(r->out.validation.sam2->key.key, zeros, + sizeof(r->out.validation.sam2->key.key)) != 0) { creds_arcfour_crypt(&samlogon_state->creds, - r->out.validation.sam->LMSessKey.key, - sizeof(r->out.validation.sam->LMSessKey.key)); - } - - if (lm_key) { - memcpy(lm_key, r->out.validation.sam->LMSessKey.key, 8); - } - - if (memcmp(r->out.validation.sam->key.key, zeros, sizeof(r->out.validation.sam->key.key)) != 0) { - creds_arcfour_crypt(&samlogon_state->creds, - r->out.validation.sam->key.key, - sizeof(r->out.validation.sam->key.key)); + r->out.validation.sam2->key.key, + sizeof(r->out.validation.sam2->key.key)); } if (user_session_key) { - memcpy(user_session_key, r->out.validation.sam->key.key, 16); + memcpy(user_session_key, r->out.validation.sam2->key.key, 16); } - } else if (r->in.validation_level == 3) { - static const char zeros[16]; - if (memcmp(r->out.validation.sam2->LMSessKey.key, zeros, sizeof(r->out.validation.sam2->LMSessKey.key)) != 0) { + if (memcmp(r->out.validation.sam2->LMSessKey.key, zeros, + sizeof(r->out.validation.sam2->LMSessKey.key)) != 0) { creds_arcfour_crypt(&samlogon_state->creds, r->out.validation.sam2->LMSessKey.key, sizeof(r->out.validation.sam2->LMSessKey.key)); @@ -410,15 +399,30 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state, memcpy(lm_key, r->out.validation.sam2->LMSessKey.key, 8); } - if (memcmp(r->out.validation.sam2->key.key, zeros, sizeof(r->out.validation.sam2->key.key)) != 0) { + } else if (r->in.validation_level == 3) { + static const char zeros[16]; + if (memcmp(r->out.validation.sam3->key.key, zeros, + sizeof(r->out.validation.sam3->key.key)) != 0) { creds_arcfour_crypt(&samlogon_state->creds, - r->out.validation.sam2->key.key, - sizeof(r->out.validation.sam2->key.key)); + r->out.validation.sam3->key.key, + sizeof(r->out.validation.sam3->key.key)); } if (user_session_key) { - memcpy(user_session_key, r->out.validation.sam2->key.key, 16); + memcpy(user_session_key, r->out.validation.sam3->key.key, 16); } + + if (memcmp(r->out.validation.sam3->LMSessKey.key, zeros, + sizeof(r->out.validation.sam3->LMSessKey.key)) != 0) { + creds_arcfour_crypt(&samlogon_state->creds, + r->out.validation.sam3->LMSessKey.key, + sizeof(r->out.validation.sam3->LMSessKey.key)); + } + + if (lm_key) { + memcpy(lm_key, r->out.validation.sam3->LMSessKey.key, 8); + } + } } @@ -912,7 +916,7 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) samlogon_state.r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); samlogon_state.r.in.workstation = TEST_MACHINE_NAME; samlogon_state.r.in.credential = &samlogon_state.auth; - samlogon_state.r.in.authenticator = &samlogon_state.auth2; + samlogon_state.r.in.return_authenticator = &samlogon_state.auth2; for (i=2;i<=3;i++) { samlogon_state.r.in.validation_level = i; |