summaryrefslogtreecommitdiff
path: root/source3/auth/auth_domain.c
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-09-30 17:13:37 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:04:48 -0500
commit54abd2aa66069e6baf7769c496f46d9dba18db39 (patch)
tree9cf8e88168011797319ba9e9866749201b1eac1e /source3/auth/auth_domain.c
parent4a2cc231d22a82ed21771a72508f15d21ed63227 (diff)
downloadsamba-54abd2aa66069e6baf7769c496f46d9dba18db39.tar.gz
samba-54abd2aa66069e6baf7769c496f46d9dba18db39.tar.bz2
samba-54abd2aa66069e6baf7769c496f46d9dba18db39.zip
r10656: BIG merge from trunk. Features not copied over
* \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3)
Diffstat (limited to 'source3/auth/auth_domain.c')
-rw-r--r--source3/auth/auth_domain.c204
1 files changed, 108 insertions, 96 deletions
diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c
index cdf87adebb..4abc6c6656 100644
--- a/source3/auth/auth_domain.c
+++ b/source3/auth/auth_domain.c
@@ -40,15 +40,17 @@ extern BOOL global_machine_password_needs_changing;
*
**/
-static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
- const char *domain, const char *dc_name,
- struct in_addr dc_ip,
- const char *setup_creds_as,
- uint16 sec_chan,
- const unsigned char *trust_passwd,
- BOOL *retry)
+static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
+ const char *domain,
+ const char *dc_name,
+ struct in_addr dc_ip,
+ struct rpc_pipe_client **pipe_ret,
+ BOOL *retry)
{
NTSTATUS result;
+ struct rpc_pipe_client *netlogon_pipe = NULL;
+
+ *pipe_ret = NULL;
/* TODO: Send a SAMLOGON request to determine whether this is a valid
logonserver. We can avoid a 30-second timeout if the DC is down
@@ -64,8 +66,9 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
* ACCESS_DENIED errors if 2 auths are done from the same machine. JRA.
*/
- if (!grab_server_mutex(dc_name))
+ if (!grab_server_mutex(dc_name)) {
return NT_STATUS_NO_LOGON_SERVERS;
+ }
/* Attempt connection */
*retry = True;
@@ -95,36 +98,65 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
* into account also. This patch from "Bjart Kvarme" <bjart.kvarme@usit.uio.no>.
*/
- if(cli_nt_session_open(*cli, PI_NETLOGON) == False) {
+ /* open the netlogon pipe. */
+ if (lp_client_schannel()) {
+ /* We also setup the creds chain in the open_schannel call. */
+ netlogon_pipe = cli_rpc_pipe_open_schannel(*cli, PI_NETLOGON,
+ PIPE_AUTH_LEVEL_PRIVACY, domain, &result);
+ } else {
+ netlogon_pipe = cli_rpc_pipe_open_noauth(*cli, PI_NETLOGON, &result);
+ }
+
+ if(!netlogon_pipe) {
DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \
-machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli)));
- cli_nt_session_close(*cli);
- cli_ulogoff(*cli);
+machine %s. Error was : %s.\n", dc_name, nt_errstr(result)));
cli_shutdown(*cli);
release_server_mutex();
- return NT_STATUS_NO_LOGON_SERVERS;
+ return result;
}
- fstr_sprintf((*cli)->mach_acct, "%s$", setup_creds_as);
-
- /* This must be the remote domain (not ours) for schannel */
-
- fstrcpy( (*cli)->domain, domain );
+ if (!lp_client_schannel()) {
+ /* We need to set up a creds chain on an unauthenticated netlogon pipe. */
+ uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+ uint32 sec_chan_type = 0;
+ char machine_pwd[16];
+
+ if (!get_trust_pw(domain, machine_pwd, &sec_chan_type)) {
+ DEBUG(0, ("connect_to_domain_password_server: could not fetch "
+ "trust account password for domain '%s'\n",
+ domain));
+ cli_shutdown(*cli);
+ release_server_mutex();
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
- result = cli_nt_establish_netlogon(*cli, sec_chan, trust_passwd);
+ result = rpccli_netlogon_setup_creds(netlogon_pipe,
+ dc_name,
+ domain,
+ global_myname(),
+ machine_pwd,
+ sec_chan_type,
+ &neg_flags);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ cli_shutdown(*cli);
+ release_server_mutex();
+ return result;
+ }
+ }
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(0,("connect_to_domain_password_server: unable to setup the NETLOGON credentials to machine \
-%s. Error was : %s.\n", dc_name, nt_errstr(result)));
- cli_nt_session_close(*cli);
- cli_ulogoff(*cli);
+ if(!netlogon_pipe) {
+ DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \
+machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli)));
cli_shutdown(*cli);
release_server_mutex();
- return result;
+ return NT_STATUS_NO_LOGON_SERVERS;
}
/* We exit here with the mutex *locked*. JRA */
+ *pipe_ret = netlogon_pipe;
+
return NT_STATUS_OK;
}
@@ -135,18 +167,17 @@ machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli)));
************************************************************************/
static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- const char *domain,
- uchar chal[8],
- auth_serversupplied_info **server_info,
- const char *dc_name, struct in_addr dc_ip,
- const char *setup_creds_as,
- uint16 sec_chan,
- unsigned char trust_passwd[16],
- time_t last_change_time)
+ const auth_usersupplied_info *user_info,
+ const char *domain,
+ uchar chal[8],
+ auth_serversupplied_info **server_info,
+ const char *dc_name,
+ struct in_addr dc_ip)
+
{
NET_USER_INFO_3 info3;
struct cli_state *cli = NULL;
+ struct rpc_pipe_client *netlogon_pipe = NULL;
NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
int i;
BOOL retry = True;
@@ -162,8 +193,12 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
/* rety loop for robustness */
for (i = 0; !NT_STATUS_IS_OK(nt_status) && retry && (i < 3); i++) {
- nt_status = connect_to_domain_password_server(&cli, domain, dc_name,
- dc_ip, setup_creds_as, sec_chan, trust_passwd, &retry);
+ nt_status = connect_to_domain_password_server(&cli,
+ domain,
+ dc_name,
+ dc_ip,
+ &netlogon_pipe,
+ &retry);
}
if ( !NT_STATUS_IS_OK(nt_status) ) {
@@ -181,13 +216,19 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
* in the info3 structure.
*/
- nt_status = cli_netlogon_sam_network_logon(cli, mem_ctx,
- NULL, user_info->smb_name.str, user_info->domain.str,
- user_info->wksta_name.str, chal, user_info->lm_resp,
- user_info->nt_resp, &info3);
-
- /* let go as soon as possible so we avoid any potential deadlocks
- with winbind lookup up users or groups */
+ nt_status = rpccli_netlogon_sam_network_logon(netlogon_pipe,
+ mem_ctx,
+ dc_name, /* server name */
+ user_info->smb_name.str, /* user name logging on. */
+ user_info->domain.str, /* domain name */
+ user_info->wksta_name.str, /* workstation name */
+ chal, /* 8 byte challenge. */
+ user_info->lm_resp, /* lanman 24 byte response */
+ user_info->nt_resp, /* nt 24 byte response */
+ &info3); /* info3 out */
+
+ /* Let go as soon as possible so we avoid any potential deadlocks
+ with winbind lookup up users or groups. */
release_server_mutex();
@@ -195,7 +236,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
DEBUG(0,("domain_client_validate: unable to validate password "
"for user %s in domain %s to Domain controller %s. "
"Error was %s.\n", user_info->smb_name.str,
- user_info->domain.str, cli->srv_name_slash,
+ user_info->domain.str, dc_name,
nt_errstr(nt_status)));
/* map to something more useful */
@@ -203,32 +244,18 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
nt_status = NT_STATUS_NO_LOGON_SERVERS;
}
} else {
- nt_status = make_server_info_info3(mem_ctx, user_info->internal_username.str,
- user_info->smb_name.str, domain, server_info, &info3);
+ nt_status = make_server_info_info3(mem_ctx,
+ user_info->internal_username.str,
+ user_info->smb_name.str,
+ domain,
+ server_info,
+ &info3);
}
-#if 0
- /*
- * We don't actually need to do this - plus it fails currently with
- * NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to
- * send here. JRA.
- */
-
- if (NT_STATUS_IS_OK(status)) {
- if(cli_nt_logoff(&cli, &ctr) == False) {
- DEBUG(0,("domain_client_validate: unable to log off user %s in domain \
-%s to Domain controller %s. Error was %s.\n", user, domain, dc_name, cli_errstr(&cli)));
- nt_status = NT_STATUS_LOGON_FAILURE;
- }
- }
-#endif /* 0 */
-
/* Note - once the cli stream is shutdown the mem_ctx used
to allocate the other_sids and gids structures has been deleted - so
these pointers are no longer valid..... */
- cli_nt_session_close(cli);
- cli_ulogoff(cli);
cli_shutdown(cli);
return nt_status;
}
@@ -244,10 +271,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
auth_serversupplied_info **server_info)
{
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
- unsigned char trust_passwd[16];
- time_t last_change_time;
const char *domain = lp_workgroup();
- uint32 sec_channel_type = 0;
fstring dc_name;
struct in_addr dc_ip;
@@ -273,26 +297,6 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
return NT_STATUS_NOT_IMPLEMENTED;
}
- /*
- * Get the machine account password for our primary domain
- * No need to become_root() as secrets_init() is done at startup.
- */
-
- if (!secrets_fetch_trust_account_password(domain, trust_passwd, &last_change_time, &sec_channel_type))
- {
- DEBUG(0, ("check_ntdomain_security: could not fetch trust account password for domain '%s'\n", domain));
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- }
-
- /* Test if machine password has expired and needs to be changed */
- if (lp_machine_password_timeout()) {
- if (last_change_time > 0 &&
- time(NULL) > (last_change_time +
- lp_machine_password_timeout())) {
- global_machine_password_needs_changing = True;
- }
- }
-
/* we need our DC to send the net_sam_logon() request to */
if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
@@ -301,9 +305,13 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
return NT_STATUS_NO_LOGON_SERVERS;
}
- nt_status = domain_client_validate(mem_ctx, user_info, domain,
- (uchar *)auth_context->challenge.data, server_info, dc_name, dc_ip,
- global_myname(), sec_channel_type,trust_passwd, last_change_time);
+ nt_status = domain_client_validate(mem_ctx,
+ user_info,
+ domain,
+ (uchar *)auth_context->challenge.data,
+ server_info,
+ dc_name,
+ dc_ip);
return nt_status;
}
@@ -357,7 +365,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
/* No point is bothering if this is not a trusted domain.
This return makes "map to guest = bad user" work again.
The logic is that if we know nothing about the domain, that
- user is known to us and does not exist */
+ user is not known to us and does not exist */
if ( !is_trusted_domain( user_info->domain.str ) )
return NT_STATUS_NOT_IMPLEMENTED;
@@ -367,8 +375,8 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
* No need to become_root() as secrets_init() is done at startup.
*/
- if (!secrets_fetch_trusted_domain_password(user_info->domain.str, &trust_password, &sid, &last_change_time))
- {
+ if (!secrets_fetch_trusted_domain_password(user_info->domain.str, &trust_password,
+ &sid, &last_change_time)) {
DEBUG(0, ("check_trustdomain_security: could not fetch trust account password for domain %s\n", user_info->domain.str));
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
@@ -396,9 +404,13 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
return NT_STATUS_NO_LOGON_SERVERS;
}
- nt_status = domain_client_validate(mem_ctx, user_info, user_info->domain.str,
- (uchar *)auth_context->challenge.data, server_info, dc_name, dc_ip,
- lp_workgroup(), SEC_CHAN_DOMAIN, trust_md4_password, last_change_time);
+ nt_status = domain_client_validate(mem_ctx,
+ user_info,
+ user_info->domain.str,
+ (uchar *)auth_context->challenge.data,
+ server_info,
+ dc_name,
+ dc_ip);
return nt_status;
}