1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

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 11f72a78e3)
This commit is contained in:
Tim Potter 2001-08-22 02:48:16 +00:00
parent 8d9cdf0d74
commit b0f167cdf2
6 changed files with 210 additions and 26 deletions

View File

@ -27,8 +27,9 @@
/* Prototypes from common.h */
int winbindd_request(int req_type, struct winbindd_request *request,
struct winbindd_response *response);
enum nss_status winbindd_request(int req_type,
struct winbindd_request *request,
struct winbindd_response *response);
/* List groups a user is a member of */
@ -260,6 +261,85 @@ static BOOL wbinfo_lookupname(char *name)
return True;
}
/* Authenticate a user with a plaintext password */
static BOOL wbinfo_auth(char *username)
{
struct winbindd_request request;
struct winbindd_response response;
enum winbindd_result result;
char *p;
/* Send off request */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
p = strchr(username, '%');
if (p) {
*p = 0;
fstrcpy(request.data.auth.user, username);
fstrcpy(request.data.auth.pass, p + 1);
*p = '%';
} else
fstrcpy(request.data.auth.user, username);
result = winbindd_request(WINBINDD_PAM_AUTH, &request, &response);
/* Display response */
printf("plaintext password authentication %s\n",
(result == WINBINDD_OK) ? "succeeded" : "failed");
return result == WINBINDD_OK;
}
/* Authenticate a user with a challenge/response */
static BOOL wbinfo_auth_crap(char *username)
{
struct winbindd_request request;
struct winbindd_response response;
enum winbindd_result result;
fstring pass;
char *p;
/* Send off request */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
p = strchr(username, '%');
if (p) {
*p = 0;
fstrcpy(request.data.auth_crap.user, username);
fstrcpy(pass, p + 1);
*p = '%';
} else
fstrcpy(request.data.auth_crap.user, username);
generate_random_buffer(request.data.auth_crap.chal, 8, False);
SMBencrypt(pass, request.data.auth_crap.chal,
request.data.auth_crap.lm_resp);
SMBNTencrypt(pass, request.data.auth_crap.chal,
request.data.auth_crap.nt_resp);
request.data.auth_crap.lm_resp_len = 24;
request.data.auth_crap.nt_resp_len = 24;
result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response);
/* Display response */
printf("challenge/response password authentication %s\n",
(result == WINBINDD_OK) ? "succeeded" : "failed");
return result == WINBINDD_OK;
}
/* Print domain users */
static BOOL print_domain_users(void)
@ -322,18 +402,20 @@ static BOOL print_domain_groups(void)
static void usage(void)
{
printf("Usage: wbinfo -ug | -n name | -sSY sid | -UG uid/gid | -tm\n");
printf("\t-u\tlists all domain users\n");
printf("\t-g\tlists all domain groups\n");
printf("\t-n name\tconverts name to sid\n");
printf("\t-s sid\tconverts sid to name\n");
printf("\t-U uid\tconverts uid to sid\n");
printf("\t-G gid\tconverts gid to sid\n");
printf("\t-S sid\tconverts sid to uid\n");
printf("\t-Y sid\tconverts sid to gid\n");
printf("\t-t\tcheck shared secret\n");
printf("\t-m\tlist trusted domains\n");
printf("\t-r user\tget user groups\n");
printf("Usage: wbinfo -ug | -n name | -sSY sid | -UG uid/gid | -tm "
"| -a user%%password\n");
printf("\t-u\t\t\tlists all domain users\n");
printf("\t-g\t\t\tlists all domain groups\n");
printf("\t-n name\t\t\tconverts name to sid\n");
printf("\t-s sid\t\t\tconverts sid to name\n");
printf("\t-U uid\t\t\tconverts uid to sid\n");
printf("\t-G gid\t\t\tconverts gid to sid\n");
printf("\t-S sid\t\t\tconverts sid to uid\n");
printf("\t-Y sid\t\t\tconverts sid to gid\n");
printf("\t-t\t\t\tcheck shared secret\n");
printf("\t-m\t\t\tlist trusted domains\n");
printf("\t-r user\t\t\tget user groups\n");
printf("\t-a user%%password\tauthenticate user\n");
}
/* Main program */
@ -371,7 +453,7 @@ int main(int argc, char **argv)
return 1;
}
while ((opt = getopt(argc, argv, "ugs:n:U:G:S:Y:tmr:")) != EOF) {
while ((opt = getopt(argc, argv, "ugs:n:U:G:S:Y:tmr:a:")) != EOF) {
switch (opt) {
case 'u':
if (!print_domain_users()) {
@ -444,7 +526,26 @@ int main(int argc, char **argv)
return 1;
}
break;
case 'a': {
BOOL got_error = False;
if (!wbinfo_auth(optarg)) {
printf("Could not authenticate user %s with "
"plaintext password\n", optarg);
got_error = True;
}
if (!wbinfo_auth_crap(optarg)) {
printf("Could not authenticate user %s with "
"challenge/response\n", optarg);
got_error = True;
}
if (got_error)
return 1;
break;
}
/* Invalid option */
default:

View File

@ -244,6 +244,7 @@ static struct dispatch_table dispatch_table[] = {
/* PAM auth functions */
{ WINBINDD_PAM_AUTH, winbindd_pam_auth },
{ WINBINDD_PAM_AUTH_CRAP, winbindd_pam_auth_crap },
{ WINBINDD_PAM_CHAUTHTOK, winbindd_pam_chauthtok },
/* Enumeration functions */

View File

@ -55,6 +55,7 @@ enum winbindd_cmd {
/* PAM authenticate and password change */
WINBINDD_PAM_AUTH,
WINBINDD_PAM_AUTH_CRAP,
WINBINDD_PAM_CHAUTHTOK,
/* List various things */
@ -99,6 +100,14 @@ struct winbindd_request {
fstring user;
fstring pass;
} auth; /* pam_winbind auth module */
struct {
char chal[8];
fstring user;
fstring lm_resp;
uint16 lm_resp_len;
fstring nt_resp;
uint16 nt_resp_len;
} auth_crap;
struct {
fstring user;
fstring oldpass;

View File

@ -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)

View File

@ -3,12 +3,12 @@
/* This file is automatically generated with "make proto". DO NOT EDIT */
/*The following definitions come from nsswitch/winbindd.c */
/* The following definitions come from nsswitch/winbindd.c */
void winbindd_dump_status(void);
int main(int argc, char **argv);
/*The following definitions come from nsswitch/winbindd_cache.c */
/* The following definitions come from nsswitch/winbindd_cache.c */
void winbindd_cache_init(void);
void winbindd_store_user_cache(char *domain,
@ -46,7 +46,7 @@ BOOL winbindd_fetch_gid_cache_entry(char *domain_name, gid_t gid,
void winbindd_flush_cache(void);
void winbindd_cache_dump_status(void);
/*The following definitions come from nsswitch/winbindd_group.c */
/* The following definitions come from nsswitch/winbindd_group.c */
enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
*state);
@ -58,7 +58,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state);
enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state);
enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state);
/*The following definitions come from nsswitch/winbindd_idmap.c */
/* The following definitions come from nsswitch/winbindd_idmap.c */
BOOL winbindd_idmap_get_uid_from_rid(char *domain_name, uint32 user_rid,
uid_t *uid);
@ -73,21 +73,22 @@ BOOL winbindd_idmap_get_rid_from_gid(gid_t gid, uint32 *group_rid,
BOOL winbindd_idmap_init(void);
void winbindd_idmap_dump_status(void);
/*The following definitions come from nsswitch/winbindd_misc.c */
/* The following definitions come from nsswitch/winbindd_misc.c */
BOOL _get_trust_account_password(char *domain, unsigned char *ret_pwd,
time_t *pass_last_set_time);
time_t *pass_last_set_time);
enum winbindd_result winbindd_check_machine_acct(
struct winbindd_cli_state *state);
enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state
*state);
/*The following definitions come from nsswitch/winbindd_pam.c */
/* The following definitions come from nsswitch/winbindd_pam.c */
enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) ;
enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) ;
enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state);
/*The following definitions come from nsswitch/winbindd_sid.c */
/* The following definitions come from nsswitch/winbindd_sid.c */
enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state);
enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state);
@ -96,7 +97,7 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state);
enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state);
enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state);
/*The following definitions come from nsswitch/winbindd_user.c */
/* The following definitions come from nsswitch/winbindd_user.c */
enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state
*state) ;
@ -107,7 +108,7 @@ enum winbindd_result winbindd_endpwent(struct winbindd_cli_state *state);
enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state);
enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state);
/*The following definitions come from nsswitch/winbindd_util.c */
/* The following definitions come from nsswitch/winbindd_util.c */
void debug_conn_state(void);
BOOL domain_handles_open(struct winbindd_domain *domain);

View File

@ -788,6 +788,7 @@ static struct cmdstr_table cmdstr_table[] = {
/* PAM auth functions */
{ WINBINDD_PAM_AUTH, "pam auth" },
{ WINBINDD_PAM_AUTH_CRAP, "pam auth crap" },
{ WINBINDD_PAM_CHAUTHTOK, "pam chauthtok" },
/* List things */