summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/auth/auth_domain.c7
-rw-r--r--source3/libsmb/namequery_dc.c27
-rw-r--r--source3/libsmb/trusts_util.c2
-rw-r--r--source3/nsswitch/winbindd_ads.c4
-rw-r--r--source3/nsswitch/winbindd_cm.c61
-rw-r--r--source3/nsswitch/winbindd_misc.c14
-rw-r--r--source3/nsswitch/winbindd_pam.c118
-rw-r--r--source3/nsswitch/winbindd_rpc.c22
-rw-r--r--source3/nsswitch/winbindd_util.c10
9 files changed, 144 insertions, 121 deletions
diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c
index 43e7597cd9..0f34bcc0e2 100644
--- a/source3/auth/auth_domain.c
+++ b/source3/auth/auth_domain.c
@@ -165,6 +165,9 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
if ( !NT_STATUS_IS_OK(nt_status) ) {
DEBUG(0,("domain_client_validate: Domain password server not available.\n"));
+ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) {
+ return NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE;
+ }
return nt_status;
}
@@ -290,7 +293,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
/* we need our DC to send the net_sam_logon() request to */
- if ( !get_dc_name(domain, dc_name, &dc_ip) ) {
+ if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n",
user_info->domain.str));
return NT_STATUS_NO_LOGON_SERVERS;
@@ -385,7 +388,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
/* use get_dc_name() for consistency even through we know that it will be
a netbios name */
- if ( !get_dc_name(user_info->domain.str, dc_name, &dc_ip) ) {
+ if ( !get_dc_name(user_info->domain.str, NULL, dc_name, &dc_ip) ) {
DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n",
user_info->domain.str));
return NT_STATUS_NO_LOGON_SERVERS;
diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c
index df7f856cd7..31d759e0d2 100644
--- a/source3/libsmb/namequery_dc.c
+++ b/source3/libsmb/namequery_dc.c
@@ -29,27 +29,23 @@
Find the name and IP address for a server in he realm/domain
*************************************************************************/
-static BOOL ads_dc_name(const char *domain, struct in_addr *dc_ip, fstring srv_name)
+static BOOL ads_dc_name(const char *domain, const char *realm, struct in_addr *dc_ip, fstring srv_name)
{
ADS_STRUCT *ads;
- const char *realm = domain;
- if (strequal(realm, lp_workgroup()))
+ if (!realm && strequal(domain, lp_workgroup()))
realm = lp_realm();
ads = ads_init(realm, domain, NULL);
if (!ads)
return False;
- /* we don't need to bind, just connect */
- ads->auth.flags |= ADS_AUTH_NO_BIND;
-
DEBUG(4,("ads_dc_name: domain=%s\n", domain));
#ifdef HAVE_ADS
- /* a full ads_connect() is actually overkill, as we don't srictly need
- to do the SASL auth in order to get the info we need, but libads
- doesn't offer a better way right now */
+ /* we don't need to bind, just connect */
+ ads->auth.flags |= ADS_AUTH_NO_BIND;
+
ads_connect(ads);
#endif
@@ -157,7 +153,7 @@ static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip
wrapper around ads and rpc methods of finds DC's
**********************************************************************/
-BOOL get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
+BOOL get_dc_name(const char *domain, const char *realm, fstring srv_name, struct in_addr *ip_out)
{
struct in_addr dc_ip;
BOOL ret;
@@ -167,15 +163,14 @@ BOOL get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
ret = False;
- if ( strequal(lp_workgroup(), domain) || strequal(lp_realm(), domain) )
+ if ( strequal(lp_workgroup(), domain) || strequal(lp_realm(), realm) )
our_domain = True;
- /* always try to obey what the admin specified in smb.conf.
- If it is not our domain, assume that domain names with periods
- in them are realm names */
+ /* always try to obey what the admin specified in smb.conf
+ (for the local domain) */
- if ( (our_domain && lp_security()==SEC_ADS) || strchr_m(domain, '.') ) {
- ret = ads_dc_name(domain, &dc_ip, srv_name);
+ if ( (our_domain && lp_security()==SEC_ADS) || realm ) {
+ ret = ads_dc_name(domain, realm, &dc_ip, srv_name);
}
if (!ret) {
diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c
index 7c1000b9a5..b420e4fa08 100644
--- a/source3/libsmb/trusts_util.c
+++ b/source3/libsmb/trusts_util.c
@@ -144,7 +144,7 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
/* lookup a DC first */
- if ( !get_dc_name(domain, dc_name, &dc_ip) ) {
+ if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n",
domain));
return False;
diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c
index 3a70c1a01e..5e12b0fbb5 100644
--- a/source3/nsswitch/winbindd_ads.c
+++ b/source3/nsswitch/winbindd_ads.c
@@ -842,7 +842,6 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
struct cli_state *cli = NULL;
/* i think we only need our forest and downlevel trusted domains */
uint32 flags = DS_DOMAIN_IN_FOREST | DS_DOMAIN_DIRECT_OUTBOUND;
- char *contact_domain_name;
DEBUG(3,("ads: trusted_domains\n"));
@@ -851,8 +850,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
*names = NULL;
*dom_sids = NULL;
- contact_domain_name = *domain->alt_name ? domain->alt_name : domain->name;
- if ( !NT_STATUS_IS_OK(result = cm_fresh_connection(contact_domain_name, PI_NETLOGON, &cli)) ) {
+ if ( !NT_STATUS_IS_OK(result = cm_fresh_connection(domain, PI_NETLOGON, &cli)) ) {
DEBUG(5, ("trusted_domains: Could not open a connection to %s for PIPE_NETLOGON (%s)\n",
domain->name, nt_errstr(result)));
return NT_STATUS_UNSUCCESSFUL;
diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c
index 73c8a6b783..bdbf80eb2f 100644
--- a/source3/nsswitch/winbindd_cm.c
+++ b/source3/nsswitch/winbindd_cm.c
@@ -113,8 +113,8 @@ static void cm_get_ipc_userpass(char **username, char **domain, char **password)
/* Open a connction to the remote server, cache failures for 30 seconds */
-static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
- struct winbindd_cm_conn *new_conn)
+static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const int pipe_index,
+ struct winbindd_cm_conn *new_conn)
{
NTSTATUS result;
char *machine_password;
@@ -125,21 +125,22 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
ZERO_STRUCT(dc_ip);
- fstrcpy(new_conn->domain, domain);
- fstrcpy(new_conn->pipe_name, get_pipe_name_from_index(pipe_index));
+ fstrcpy(new_conn->domain, domain->name);
/* connection failure cache has been moved inside of get_dc_name
so we can deal with half dead DC's --jerry */
- if (!get_dc_name(domain, new_conn->controller, &dc_ip)) {
+ if (!get_dc_name(domain->name, domain->alt_name[0] ? domain->alt_name : NULL,
+ new_conn->controller, &dc_ip)) {
result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
- add_failed_connection_entry(domain, "", result);
+ add_failed_connection_entry(domain->name, "", result);
return result;
}
/* Initialise SMB connection */
+ fstrcpy(new_conn->pipe_name, get_pipe_name_from_index(pipe_index));
- /* grab stored passwords */
+/* grab stored passwords */
machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(), lp_realm()) == -1) {
@@ -181,7 +182,7 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
if (!NT_STATUS_IS_OK(result = cli_session_setup_spnego(new_conn->cli, machine_krb5_principal,
machine_password,
- domain))) {
+ domain->name))) {
DEBUG(4,("failed kerberos session setup with %s\n", nt_errstr(result)));
}
}
@@ -201,7 +202,7 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
if (!cli_session_setup(new_conn->cli, ipc_username,
ipc_password, strlen(ipc_password)+1,
ipc_password, strlen(ipc_password)+1,
- domain)) {
+ domain->name)) {
result = cli_nt_error(new_conn->cli);
DEBUG(4,("failed authenticated session setup with %s\n", nt_errstr(result)));
if (NT_STATUS_IS_OK(result))
@@ -258,13 +259,13 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
SAFE_FREE(machine_password);
if (!NT_STATUS_IS_OK(result)) {
- add_failed_connection_entry(domain, new_conn->controller, result);
+ add_failed_connection_entry(domain->name, new_conn->controller, result);
return result;
}
/* set the domain if empty; needed for schannel connections */
if ( !*new_conn->cli->domain )
- fstrcpy( new_conn->cli->domain, domain );
+ fstrcpy( new_conn->cli->domain, domain->name );
if ( !cli_nt_session_open (new_conn->cli, pipe_index) ) {
@@ -278,7 +279,7 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
* specific UUID right now, i'm not going to bother. --jerry
*/
if ( !is_win2k_pipe(pipe_index) )
- add_failed_connection_entry(domain, new_conn->controller, result);
+ add_failed_connection_entry(domain->name, new_conn->controller, result);
cli_shutdown(new_conn->cli);
return result;
}
@@ -291,7 +292,7 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
setup cli_state struct
************************************************************************/
-NTSTATUS cm_fresh_connection(const char *domain, const int pipe_index,
+NTSTATUS cm_fresh_connection(struct winbindd_domain *domain, const int pipe_index,
struct cli_state **cli)
{
NTSTATUS result;
@@ -338,13 +339,13 @@ static BOOL connection_ok(struct winbindd_cm_conn *conn)
/* Search the cache for a connection. If there is a broken one,
shut it down properly and return NULL. */
-static void find_cm_connection(const char *domain, const char *pipe_name,
+static void find_cm_connection(struct winbindd_domain *domain, const char *pipe_name,
struct winbindd_cm_conn **conn_out)
{
struct winbindd_cm_conn *conn;
for (conn = cm_conns; conn; ) {
- if (strequal(conn->domain, domain) &&
+ if (strequal(conn->domain, domain->name) &&
strequal(conn->pipe_name, pipe_name)) {
if (!connection_ok(conn)) {
/* Dead connection - remove it. */
@@ -367,7 +368,7 @@ static void find_cm_connection(const char *domain, const char *pipe_name,
/* Initialize a new connection up to the RPC BIND. */
-static NTSTATUS new_cm_connection(const char *domain, const char *pipe_name,
+static NTSTATUS new_cm_connection(struct winbindd_domain *domain, const char *pipe_name,
struct winbindd_cm_conn **conn_out)
{
struct winbindd_cm_conn *conn;
@@ -380,7 +381,7 @@ static NTSTATUS new_cm_connection(const char *domain, const char *pipe_name,
if (!NT_STATUS_IS_OK(result = cm_open_connection(domain, get_pipe_index(pipe_name), conn))) {
DEBUG(3, ("Could not open a connection to %s for %s (%s)\n",
- domain, pipe_name, nt_errstr(result)));
+ domain->name, pipe_name, nt_errstr(result)));
SAFE_FREE(conn);
return result;
}
@@ -392,7 +393,7 @@ static NTSTATUS new_cm_connection(const char *domain, const char *pipe_name,
/* Get a connection to the remote DC and open the pipe. If there is already a connection, use that */
-static NTSTATUS get_connection_from_cache(const char *domain, const char *pipe_name,
+static NTSTATUS get_connection_from_cache(struct winbindd_domain *domain, const char *pipe_name,
struct winbindd_cm_conn **conn_out)
{
find_cm_connection(domain, pipe_name, conn_out);
@@ -406,7 +407,7 @@ static NTSTATUS get_connection_from_cache(const char *domain, const char *pipe_n
/**********************************************************************************
**********************************************************************************/
-BOOL cm_check_for_native_mode_win2k( const char *domain )
+BOOL cm_check_for_native_mode_win2k( struct winbindd_domain *domain )
{
NTSTATUS result;
struct winbindd_cm_conn conn;
@@ -419,7 +420,7 @@ BOOL cm_check_for_native_mode_win2k( const char *domain )
if ( !NT_STATUS_IS_OK(result = cm_open_connection(domain, PI_LSARPC_DS, &conn)) ) {
DEBUG(5, ("cm_check_for_native_mode_win2k: Could not open a connection to %s for PIPE_LSARPC (%s)\n",
- domain, nt_errstr(result)));
+ domain->name, nt_errstr(result)));
return False;
}
@@ -450,7 +451,7 @@ done:
/* Return a LSA policy handle on a domain */
-NTSTATUS cm_get_lsa_handle(const char *domain, CLI_POLICY_HND **return_hnd)
+NTSTATUS cm_get_lsa_handle(struct winbindd_domain *domain, CLI_POLICY_HND **return_hnd)
{
struct winbindd_cm_conn *conn;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
@@ -503,7 +504,7 @@ NTSTATUS cm_get_lsa_handle(const char *domain, CLI_POLICY_HND **return_hnd)
/* Return a SAM policy handle on a domain */
-NTSTATUS cm_get_sam_handle(char *domain, CLI_POLICY_HND **return_hnd)
+NTSTATUS cm_get_sam_handle(struct winbindd_domain *domain, CLI_POLICY_HND **return_hnd)
{
struct winbindd_cm_conn *conn;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
@@ -561,7 +562,7 @@ NTSTATUS cm_get_sam_handle(char *domain, CLI_POLICY_HND **return_hnd)
/* Get a handle on a netlogon pipe. This is a bit of a hack to re-use the
netlogon pipe as no handle is returned. */
-NTSTATUS cm_get_netlogon_cli(const char *domain,
+NTSTATUS cm_get_netlogon_cli(struct winbindd_domain *domain,
const unsigned char *trust_passwd,
uint32 sec_channel_type,
BOOL fresh,
@@ -571,7 +572,6 @@ NTSTATUS cm_get_netlogon_cli(const char *domain,
struct winbindd_cm_conn *conn;
fstring lock_name;
BOOL got_mutex;
- struct winbindd_domain *wb_domain = NULL;
if (!cli)
return NT_STATUS_INVALID_PARAMETER;
@@ -613,16 +613,9 @@ NTSTATUS cm_get_netlogon_cli(const char *domain,
if ( sec_channel_type == SEC_CHAN_DOMAIN )
fstr_sprintf(conn->cli->mach_acct, "%s$", lp_workgroup());
- /* we need the short form of the domain name for the schanel
- rpc bind. What if we fail? I don't think we should ever get
- a request for a domain name not in our list but I'm not bailing
- out if we do since I'm not 10% certain about this --jerry */
-
- if ( (wb_domain = find_domain_from_name( domain )) != NULL ) {
- DEBUG(5,("cm_get_netlogon_cli: Using short for of domain name [%s] for netlogon rpc bind\n",
- wb_domain->name));
- fstrcpy( conn->cli->domain, wb_domain->name);
- }
+
+ fstrcpy( conn->cli->domain, domain->name);
+
result = cli_nt_establish_netlogon(conn->cli, sec_channel_type, trust_passwd);
diff --git a/source3/nsswitch/winbindd_misc.c b/source3/nsswitch/winbindd_misc.c
index 63bda0d1df..08b5be827d 100644
--- a/source3/nsswitch/winbindd_misc.c
+++ b/source3/nsswitch/winbindd_misc.c
@@ -37,7 +37,8 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat
struct cli_state *cli;
uint32 sec_channel_type;
const char *contact_domain_name = NULL;
-
+ struct winbindd_domain *contact_domain;
+
DEBUG(3, ("[%5lu]: check machine account\n", (unsigned long)state->pid));
/* Get trust account password */
@@ -57,12 +58,19 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat
if ( !contact_domain_name || !*contact_domain_name )
contact_domain_name = lp_workgroup();
-
+
+ contact_domain = find_domain_from_name(contact_domain_name);
+ if (!contact_domain) {
+ result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ DEBUG(1, ("%s is not a trusted domain\n", contact_domain_name));
+ goto done;
+ }
+
/* This call does a cli_nt_setup_creds() which implicitly checks
the trust account password. */
/* Don't shut this down - it belongs to the connection cache code */
- result = cm_get_netlogon_cli(contact_domain_name,
+ result = cm_get_netlogon_cli(contact_domain,
trust_passwd, sec_channel_type, True, &cli);
if (!NT_STATUS_IS_OK(result)) {
diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c
index 54513b1bc1..196ceea9a0 100644
--- a/source3/nsswitch/winbindd_pam.c
+++ b/source3/nsswitch/winbindd_pam.c
@@ -75,7 +75,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
int attempts = 0;
unsigned char local_lm_response[24];
unsigned char local_nt_response[24];
- const char *contact_domain;
+ struct winbindd_domain *contact_domain;
BOOL retry;
/* Ensure null termination */
@@ -107,21 +107,15 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
lm_resp = data_blob_talloc(mem_ctx, local_lm_response, sizeof(local_lm_response));
nt_resp = data_blob_talloc(mem_ctx, local_nt_response, sizeof(local_nt_response));
- if ( !get_trust_pw(name_domain, trust_passwd, &last_change_time, &sec_channel_type) ) {
- result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- goto done;
- }
-
/* what domain should we contact? */
if ( IS_DC ) {
- if (!find_domain_from_name(name_domain)) {
- DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n",
+ if (!(contact_domain = find_domain_from_name(name_domain))) {
+ DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
state->request.data.auth.user, name_domain, name_user, name_domain));
result = NT_STATUS_NO_SUCH_USER;
goto done;
}
- contact_domain = name_domain;
} else {
if (is_myname(name_domain)) {
@@ -129,8 +123,20 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
result = NT_STATUS_NO_SUCH_USER;
goto done;
}
- contact_domain = lp_workgroup();
+
+ if (!(contact_domain = find_our_domain())) {
+ DEBUG(1, ("Authenticatoin for [%s] -> [%s]\\[%s] in our domain failed - we can't find our domain!\n",
+ state->request.data.auth.user, name_domain, name_user));
+ result = NT_STATUS_NO_SUCH_USER;
+ goto done;
+ }
+ }
+
+ if ( !get_trust_pw(contact_domain->name, trust_passwd, &last_change_time, &sec_channel_type) ) {
+ result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ goto done;
}
+
/* check authentication loop */
do {
@@ -194,7 +200,10 @@ done:
state->response.data.auth.nt_status = NT_STATUS_V(result);
fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
- fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result));
+
+ /* we might have given a more useful error above */
+ if (!*state->response.data.auth.error_string)
+ fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result));
state->response.data.auth.pam_error = nt_status_to_pam(result);
DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n",
@@ -221,10 +230,10 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
NET_USER_INFO_3 info3;
struct cli_state *cli = NULL;
TALLOC_CTX *mem_ctx = NULL;
- char *user = NULL;
- const char *domain = NULL;
+ char *name_user = NULL;
+ const char *name_domain = NULL;
const char *workstation;
- const char *contact_domain;
+ struct winbindd_domain *contact_domain;
DOM_CRED ret_creds;
int attempts = 0;
BOOL retry;
@@ -255,7 +264,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
goto done;
}
- if (pull_utf8_talloc(mem_ctx, &user, state->request.data.auth_crap.user) == (size_t)-1) {
+ if (pull_utf8_talloc(mem_ctx, &name_user, state->request.data.auth_crap.user) == (size_t)-1) {
DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
result = NT_STATUS_UNSUCCESSFUL;
goto done;
@@ -268,24 +277,19 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
- domain = dom;
+ name_domain = dom;
} else if (lp_winbind_use_default_domain()) {
- domain = lp_workgroup();
+ name_domain = lp_workgroup();
} else {
DEBUG(5,("no domain specified with username (%s) - failing auth\n",
- user));
- result = NT_STATUS_INVALID_PARAMETER;
+ name_user));
+ result = NT_STATUS_NO_SUCH_USER;
goto done;
}
DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n", (unsigned long)state->pid,
- domain, user));
+ name_domain, name_user));
- if ( !get_trust_pw(domain, trust_passwd, &last_change_time, &sec_channel_type) ) {
- result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- goto done;
- }
-
if (*state->request.data.auth_crap.workstation) {
char *wrk = NULL;
if (pull_utf8_talloc(mem_ctx, &wrk, state->request.data.auth_crap.workstation) == (size_t)-1) {
@@ -312,23 +316,37 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
/* what domain should we contact? */
+
+ /* what domain should we contact? */
+
if ( IS_DC ) {
- if (!find_domain_from_name(domain)) {
- DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n",
- state->request.data.auth.user, domain, user, domain));
+ if (!(contact_domain = find_domain_from_name(name_domain))) {
+ DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
+ state->request.data.auth.user, name_domain, name_user, name_domain));
result = NT_STATUS_NO_SUCH_USER;
goto done;
}
- contact_domain = domain;
+
} else {
- if (is_myname(domain)) {
- DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", domain));
+ if (is_myname(name_domain)) {
+ DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain));
result = NT_STATUS_NO_SUCH_USER;
goto done;
}
- contact_domain = lp_workgroup();
+
+ if (!(contact_domain = find_our_domain())) {
+ DEBUG(1, ("Authenticatoin for [%s] -> [%s]\\[%s] in our domain failed - we can't find our domain!\n",
+ state->request.data.auth.user, name_domain, name_user));
+ result = NT_STATUS_NO_SUCH_USER;
+ goto done;
+ }
}
+ if ( !get_trust_pw(contact_domain->name, trust_passwd, &last_change_time, &sec_channel_type) ) {
+ result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ goto done;
+ }
+
do {
ZERO_STRUCT(info3);
ZERO_STRUCT(ret_creds);
@@ -345,7 +363,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
result = cli_netlogon_sam_network_logon(cli, mem_ctx,
&ret_creds,
- user, domain,
+ name_user, name_domain,
workstation,
state->request.data.auth_crap.chal,
lm_resp, nt_resp,
@@ -369,7 +387,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
if ( NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED) ) {
DEBUG(3,("winbindd_pam_auth_crap: sam_logon returned ACCESS_DENIED. Maybe the trust account "
"password was changed and we didn't know it. Killing connections to domain %s\n",
- domain));
+ contact_domain->name));
winbindd_cm_flush();
retry = True;
cli = NULL;
@@ -381,7 +399,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
if (NT_STATUS_IS_OK(result)) {
netsamlogon_cache_store( cli->mem_ctx, &info3 );
- wcache_invalidate_samlogon(find_domain_from_name(domain), &info3);
+ wcache_invalidate_samlogon(find_domain_from_name(name_domain), &info3);
if (state->request.flags & WBFLAG_PAM_INFO3_NDR) {
result = append_info3_as_ndr(mem_ctx, state, &info3);
@@ -393,12 +411,12 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
const char *nt_username, *nt_domain;
if (!(nt_username = unistr2_tdup(mem_ctx, &(info3.uni_user_name)))) {
/* If the server didn't give us one, just use the one we sent them */
- nt_username = user;
+ nt_username = name_user;
}
if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3.uni_logon_dom)))) {
/* If the server didn't give us one, just use the one we sent them */
- nt_domain = domain;
+ nt_domain = name_domain;
}
fill_domain_username(username_out, nt_domain, nt_username);
@@ -437,8 +455,8 @@ done:
DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
("NTLM CRAP authentication for user [%s]\\[%s] returned %s (PAM: %d)\n",
- domain,
- user,
+ name_domain,
+ name_user,
state->response.data.auth.nt_status_string,
state->response.data.auth.pam_error));
@@ -456,10 +474,19 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state)
char *oldpass, *newpass;
fstring domain, user;
CLI_POLICY_HND *hnd;
+ TALLOC_CTX *mem_ctx;
+ struct winbindd_domain *contact_domain;
DEBUG(3, ("[%5lu]: pam chauthtok %s\n", (unsigned long)state->pid,
state->request.data.chauthtok.user));
+ if (!(mem_ctx = talloc_init("winbind password change for (utf8) %s",
+ state->request.data.chauthtok.user))) {
+ DEBUG(0, ("winbindd_pam_auth_crap: could not talloc_init()!\n"));
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
/* Setup crap */
if (state == NULL)
@@ -467,7 +494,7 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state)
parse_domain_user(state->request.data.chauthtok.user, domain, user);
- if (!find_domain_from_name(domain)) {
+ if (!(contact_domain = find_domain_from_name(domain))) {
DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n",
state->request.data.chauthtok.user, domain, user, domain));
result = NT_STATUS_NO_SUCH_USER;
@@ -481,17 +508,15 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state)
/* Get sam handle */
- if ( NT_STATUS_IS_ERR(result = cm_get_sam_handle(domain, &hnd)) ) {
+ if ( NT_STATUS_IS_ERR(result = cm_get_sam_handle(contact_domain, &hnd)) ) {
DEBUG(1, ("could not get SAM handle on DC for %s\n", domain));
goto done;
}
- if (!cli_oem_change_password(hnd->cli, user, newpass, oldpass)) {
+ if (!NT_STATUS_IS_OK(result = cli_samr_chgpasswd_user(hnd->cli, mem_ctx,
+ user, newpass, oldpass))) {
DEBUG(1, ("password change failed for user %s/%s\n", domain,
user));
- result = NT_STATUS_WRONG_PASSWORD;
- } else {
- result = NT_STATUS_OK;
}
done:
@@ -507,5 +532,8 @@ done:
state->response.data.auth.nt_status_string,
state->response.data.auth.pam_error));
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c
index 813621f3f7..f619aa3564 100644
--- a/source3/nsswitch/winbindd_rpc.c
+++ b/source3/nsswitch/winbindd_rpc.c
@@ -53,7 +53,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
do {
/* Get sam handle */
- if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)) )
+ if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)) )
return result;
/* Get domain handle */
@@ -163,7 +163,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
retry = 0;
do {
- if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)))
return result;
status = cli_samr_open_domain(hnd->cli, mem_ctx,
@@ -228,7 +228,7 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
retry = 0;
do {
- if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)) )
+ if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)) )
return result;
result = cli_samr_open_domain( hnd->cli, mem_ctx, &hnd->pol,
@@ -300,7 +300,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
retry = 0;
do {
- if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd))) {
+ if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain, &hnd))) {
return result;
}
@@ -340,7 +340,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
retry = 0;
do {
- if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd)))
+ if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain, &hnd)))
return result;
result = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol,
@@ -409,7 +409,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
do {
/* Get sam handle; if we fail here there is no hope */
- if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)))
goto done;
/* Get domain handle */
@@ -510,7 +510,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
do {
/* Get sam handle; if we fail here there is no hope */
- if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)))
goto done;
/* Get domain handle */
@@ -598,7 +598,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
retry = 0;
do {
/* Get sam handle */
- if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)))
goto done;
/* Get domain handle */
@@ -876,7 +876,7 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
}
#endif /* HAVE_LDAP */
/* Get sam handle */
- if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)))
goto done;
/* Get domain handle */
@@ -932,7 +932,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
retry = 0;
do {
- if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(lp_workgroup(), &hnd)))
+ if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(find_our_domain(), &hnd)))
goto done;
result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
@@ -961,7 +961,7 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
retry = 0;
do {
/* Get lsa handle */
- if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd)))
+ if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain, &hnd)))
goto done;
result = cli_lsa_query_info_policy(hnd->cli, mem_ctx,
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c
index 1f9537ac25..22192e4582 100644
--- a/source3/nsswitch/winbindd_util.c
+++ b/source3/nsswitch/winbindd_util.c
@@ -82,7 +82,6 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
DOM_SID *sid)
{
struct winbindd_domain *domain;
- char *contact_name;
const char *alternative_name = NULL;
/* ignore alt_name if we are not in an AD domain */
@@ -135,12 +134,11 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
sid_copy(&domain->sid, sid);
}
- /* see if this is a native mode win2k domain (use realm name if possible) */
+ /* see if this is a native mode win2k domain */
- contact_name = *domain->alt_name ? domain->alt_name : domain->name;
- domain->native_mode = cm_check_for_native_mode_win2k( contact_name );
+ domain->native_mode = cm_check_for_native_mode_win2k( domain );
- DEBUG(3,("add_trusted_domain: %s is a %s mode domain\n", contact_name,
+ DEBUG(3,("add_trusted_domain: %s is a %s mode domain\n", domain->name,
domain->native_mode ? "native" : "mixed (or NT4)" ));
/* Link to domain list */
@@ -298,7 +296,7 @@ BOOL init_domain_list(void)
*
* @note Do *not* pass lp_workgroup() to this function. domain_list
* may modify it's value, and free that pointer. Instead, our local
- * domain may be found by looking at the first entry in domain_list()
+ * domain may be found by calling find_our_domain().
* directly.
*
*