summaryrefslogtreecommitdiff
path: root/source3/nsswitch/winbindd_pam.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch/winbindd_pam.c')
-rw-r--r--source3/nsswitch/winbindd_pam.c73
1 files changed, 72 insertions, 1 deletions
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)