1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-10 12:58:35 +03:00

Use cli_nt_login_network() instead of domain_client_validate() to perform

pam authentication.  This allows us to link in less other crap.

Authenticating with a challenge/response doesn't seem to work though - we
always get back NT_STATUS_WRONG_PASSWORD.
This commit is contained in:
Tim Potter -
parent 5c3521c937
commit d85aa1ce83
4 changed files with 88 additions and 43 deletions

View File

@ -398,8 +398,8 @@ WINBINDD_OBJ1 = \
nsswitch/winbindd_cm.o
NECESSARY_BECAUSE_SAMBA_DEPENDENCIES_ARE_SO_BROKEN_OBJ = \
libsmb/domain_client_validate.o smbd/auth_util.o \
rpc_client/cli_netlogon.o rpc_client/cli_login.o
rpc_client/cli_netlogon.o rpc_client/cli_login.o \
smbd/auth_util.o
WINBINDD_OBJ = \
$(WINBINDD_OBJ1) $(NOPROTO_OBJ) $(PASSDB_OBJ) \

View File

@ -513,3 +513,33 @@ CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, DOM_SID *domain_sid,
return &hnd;
}
/* Get a handle on a netlogon pipe */
struct cli_state *cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd)
{
struct winbindd_cm_conn conn;
NTSTATUS result;
/* Open an initial conection */
ZERO_STRUCT(conn);
if (!cm_open_connection(domain, PIPE_NETLOGON, &conn)) {
DEBUG(3, ("Could not open a connection to %s\n", domain));
return NULL;
}
result = cli_nt_setup_creds(conn.cli, trust_passwd);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(0, ("error connecting to domain password server: %s\n",
get_nt_error_msg(result)));
cli_shutdown(conn.cli);
return NULL;
}
/* We only want the client handle from this structure */
return conn.cli;
}

View File

@ -53,13 +53,15 @@ static void parse_domain_user(char *domuser, fstring domain, fstring user)
enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
{
NTSTATUS result;
fstring name_domain, name_user, auth_dc;
fstring name_domain, name_user;
int passlen;
unsigned char trust_passwd[16];
time_t last_change_time;
auth_usersupplied_info *user_info;
auth_serversupplied_info *server_info;
uint32 smb_uid_low;
NET_USER_INFO_3 info3;
NET_ID_INFO_CTR ctr;
struct cli_state *cli;
DEBUG(3, ("[%5d]: pam auth %s\n", state->pid,
state->request.data.auth.user));
@ -76,39 +78,41 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
passlen = strlen(state->request.data.auth.pass);
if (state->request.data.auth.pass[0]) {
make_user_info_for_winbind(&user_info,
name_user, name_domain,
state->request.data.auth.pass);
} else {
if (state->request.data.auth.pass[0])
make_user_info_winbind(&user_info,
name_user, name_domain,
state->request.data.auth.pass);
else
return WINBINDD_ERROR;
}
/*
* 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()));
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;
}
if (!cm_get_dc_name(lp_workgroup(), auth_dc)) {
DEBUG(3, ("Could not find dc for workgroup %s\n",
lp_workgroup()));
/* We really don't care what LUID we give the user. */
generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False);
ZERO_STRUCT(info3);
if (!(cli = cm_get_netlogon_cli(lp_workgroup(), trust_passwd))) {
DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
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 = cli_nt_login_network(cli, user_info, smb_uid_low,
&ctr, &info3);
result = domain_client_validate(user_info, &server_info,
auth_dc, trust_passwd,
last_change_time);
free_user_info(&user_info);
free_server_info(&server_info); /* No info needed */
cli_shutdown(cli);
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
@ -118,11 +122,15 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
{
NTSTATUS result;
fstring name_domain, name_user, auth_dc;
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;
uint32 smb_uid_low;
NET_USER_INFO_3 info3;
NET_ID_INFO_CTR ctr;
struct cli_state *cli;
DEBUG(3, ("[%5d]: pam auth crap %s\n", state->pid,
state->request.data.auth_crap.user));
@ -132,36 +140,42 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
parse_domain_user(state->request.data.auth_crap.user, name_domain,
name_user);
make_user_info_winbind_crap(&user_info, name_user,
name_domain, state->request.data.auth_crap.chal,
(uchar *)state->request.data.auth_crap.lm_resp, 24,
(uchar *)state->request.data.auth_crap.nt_resp, 24);
make_user_info_winbind_crap(
&user_info, name_user,
name_domain, state->request.data.auth_crap.chal,
(uchar *)state->request.data.auth_crap.lm_resp,
state->request.data.auth_crap.lm_resp_len,
(uchar *)state->request.data.auth_crap.nt_resp,
state->request.data.auth_crap.nt_resp_len);
/*
* 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()));
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;
}
if (!cm_get_dc_name(lp_workgroup(), auth_dc)) {
DEBUG(3, ("Could not find dc for workgroup %s\n",
lp_workgroup()));
/* We really don't care what LUID we give the user. */
generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False);
ZERO_STRUCT(info3);
if (!(cli = cm_get_netlogon_cli(lp_workgroup(), trust_passwd))) {
DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
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 = cli_nt_login_network(cli, user_info, smb_uid_low,
&ctr, &info3);
result = domain_client_validate(user_info, &server_info,
auth_dc, trust_passwd,
last_change_time);
free_user_info(&user_info);
free_server_info(&server_info); /* No info needed */
cli_shutdown(cli);
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}

View File

@ -55,6 +55,7 @@ CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, DOM_SID *domain_sid,
uint32 user_rid);
CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, DOM_SID *domain_sid,
uint32 group_rid);
struct cli_state *cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd);
/* The following definitions come from nsswitch/winbindd_group.c */