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.c56
1 files changed, 48 insertions, 8 deletions
diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c
index 0cbc3166c8..558f418d94 100644
--- a/source3/nsswitch/winbindd_pam.c
+++ b/source3/nsswitch/winbindd_pam.c
@@ -23,6 +23,8 @@
#include "winbindd.h"
+extern pstring global_myname;
+
/* Copy of parse_domain_user from winbindd_util.c. Parse a string of the
form DOMAIN/user into a domain and a user */
@@ -50,10 +52,17 @@ static void parse_domain_user(char *domuser, fstring domain, fstring user)
enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
{
- BOOL result, user_exists;
+ BOOL result;
fstring name_domain, name_user;
int passlen;
+ unsigned char local_lm_response[24];
+ unsigned char local_nt_response[24];
+
+ auth_usersupplied_info user_info;
+ auth_serversupplied_info server_info;
+ AUTH_STR theirdomain, smb_username, wksta_name;
+
DEBUG(3, ("[%5d]: pam auth %s\n", state->pid,
state->request.data.auth.user));
@@ -68,17 +77,48 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
passlen = strlen(state->request.data.auth.pass);
-
+
+ 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;
+
+ generate_random_buffer( user_info.chal, 8, False);
+
+ if (state->request.data.auth.pass) {
+ 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;
+ SMBNTencrypt((uchar *)state->request.data.auth.pass, user_info.chal, local_nt_response);
+ user_info.nt_resp.buffer = (uint8 *)local_nt_response;
+ user_info.nt_resp.len = 24;
+ } else {
+ 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(name_user, name_domain,
- state->request.data.auth.pass,
- passlen,
- state->request.data.auth.pass,
- passlen, &user_exists,
- server_state.controller);
+ result = (domain_client_validate(&user_info, &server_info,
+ server_state.controller) == NT_STATUS_NOPROBLEMO);
return result ? WINBINDD_OK : WINBINDD_ERROR;
}