From b0f167cdf2942ddaeaa03032542e74345ce81308 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 22 Aug 2001 02:48:16 +0000 Subject: Added another authentication interface to winbindd. The Challenge Response Authentication Protocol (CRAP) takes a tuple of (username, random challenge, encrypted lm password, encrypted nt password) where the passwords are encrypted with the random challenge ala ntlmssp. (This used to be commit 11f72a78e3a16bbb17b576d80b47a9eb818ee428) --- source3/nsswitch/winbindd_pam.c | 73 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) (limited to 'source3/nsswitch/winbindd_pam.c') diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 4dc08c6086..e595bb0796 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -104,7 +104,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) generate_random_buffer( user_info.chal, 8, False); - if (state->request.data.auth.pass) { + if (state->request.data.auth.pass[0]) { SMBencrypt((uchar *)state->request.data.auth.pass, user_info.chal, local_lm_response); user_info.lm_resp.buffer = (uint8 *)local_lm_response; user_info.lm_resp.len = 24; @@ -136,6 +136,77 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) return result ? WINBINDD_OK : WINBINDD_ERROR; } +/* Challenge Response Authentication Protocol */ + +enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) +{ + BOOL result; + fstring name_domain, name_user; + unsigned char trust_passwd[16]; + time_t last_change_time; + auth_usersupplied_info user_info; + auth_serversupplied_info server_info; + AUTH_STR theirdomain, smb_username, wksta_name; + + DEBUG(3, ("[%5d]: pam auth crap %s\n", state->pid, + state->request.data.auth_crap.user)); + + /* Parse domain and username */ + + parse_domain_user(state->request.data.auth_crap.user, name_domain, + name_user); + + ZERO_STRUCT(user_info); + ZERO_STRUCT(theirdomain); + ZERO_STRUCT(smb_username); + ZERO_STRUCT(wksta_name); + + theirdomain.str = name_domain; + theirdomain.len = strlen(theirdomain.str); + + user_info.requested_domain = theirdomain; + user_info.domain = theirdomain; + + user_info.smb_username.str = name_user; + user_info.smb_username.len = strlen(name_user); + + user_info.requested_username.str = name_user; + user_info.requested_username.len = strlen(name_user); + + user_info.wksta_name.str = global_myname; + user_info.wksta_name.len = strlen(user_info.wksta_name.str); + + user_info.wksta_name = wksta_name; + + memcpy(user_info.chal, state->request.data.auth_crap.chal, 8); + + user_info.lm_resp.buffer = state->request.data.auth_crap.lm_resp; + user_info.nt_resp.buffer = state->request.data.auth_crap.nt_resp; + + user_info.lm_resp.len = 24; + user_info.nt_resp.len = 24; + + /* + * Get the machine account password for our primary domain + */ + + if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, &last_change_time)) + { + DEBUG(0, ("winbindd_pam_auth: could not fetch trust account password for domain %s\n", lp_workgroup())); + return WINBINDD_ERROR; + } + + /* So domain_client_validate() actually opens a new connection + for each authentication performed. This can theoretically + be optimised to use an already open IPC$ connection. */ + + result = (domain_client_validate(&user_info, &server_info, + server_state.controller, trust_passwd, + last_change_time) == NT_STATUS_NOPROBLEMO); + + return result ? WINBINDD_OK : WINBINDD_ERROR; +} + /* Change a user password */ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state) -- cgit