summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2003-07-31 05:43:47 +0000
committerGerald Carter <jerry@samba.org>2003-07-31 05:43:47 +0000
commit0d087e3ba28a9061529c95799624ccc4686eb1e9 (patch)
tree6284d9b57fc77694b6967fc76ce90eadadb5a40b /source3/nsswitch
parent48c01deb300b51c97865ec0d738c64c7722da0d7 (diff)
downloadsamba-0d087e3ba28a9061529c95799624ccc4686eb1e9.tar.gz
samba-0d087e3ba28a9061529c95799624ccc4686eb1e9.tar.bz2
samba-0d087e3ba28a9061529c95799624ccc4686eb1e9.zip
working on transtive trusts issue:
* use DsEnumerateDomainTrusts() instead of LDAP search. wbinfo -m now lists all trusted downlevel domains and all domains in the forest. Thnigs to do: o Look at Krb5 connection trusted domains o make sure to initial the trusted domain cache as soon as possible (This used to be commit 0ab00ccaedf204b39c86a9e1c2fcac5f15d0e033)
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/winbindd_ads.c85
-rw-r--r--source3/nsswitch/winbindd_cache.c2
-rw-r--r--source3/nsswitch/winbindd_cm.c29
-rw-r--r--source3/nsswitch/winbindd_pam.c49
-rw-r--r--source3/nsswitch/winbindd_util.c58
5 files changed, 154 insertions, 69 deletions
diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c
index 462dd21531..7140dc35a0 100644
--- a/source3/nsswitch/winbindd_ads.c
+++ b/source3/nsswitch/winbindd_ads.c
@@ -801,24 +801,91 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
char ***alt_names,
DOM_SID **dom_sids)
{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DS_DOMAIN_TRUSTS *domains = NULL;
+ int count = 0;
+ int i;
+ 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;
DEBUG(3,("ads: trusted_domains\n"));
*num_domains = 0;
- *names = NULL;
+ *alt_names = NULL;
+ *names = NULL;
+ *dom_sids = NULL;
+
+ if ( !NT_STATUS_IS_OK(result = cm_fresh_connection(domain->name, 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;
+ }
+
+ if ( NT_STATUS_IS_OK(result) )
+ result = cli_ds_enum_domain_trusts( cli, mem_ctx, cli->desthost, flags, &domains, &count );
+
+ if ( NT_STATUS_IS_OK(result) && count) {
+
+ /* Allocate memory for trusted domain names and sids */
- ads = ads_cached_connection(domain);
+ if ( !(*names = (char **)talloc(mem_ctx, sizeof(char *) * count)) ) {
+ DEBUG(0, ("trusted_domains: out of memory\n"));
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
- if (!ads) {
- domain->last_status = NT_STATUS_SERVER_DISABLED;
- return NT_STATUS_UNSUCCESSFUL;
+ if ( !(*alt_names = (char **)talloc(mem_ctx, sizeof(char *) * count)) ) {
+ DEBUG(0, ("trusted_domains: out of memory\n"));
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ if ( !(*dom_sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * count)) ) {
+ DEBUG(0, ("trusted_domains: out of memory\n"));
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ /* Copy across names and sids */
+
+ for (i = 0; i < count; i++) {
+ fstring tmp;
+ fstring tmp2;
+
+ (*names)[i] = NULL;
+ (*alt_names)[i] = NULL;
+ ZERO_STRUCT( (*dom_sids)[i] );
+
+ if ( domains[i].netbios_ptr ) {
+ unistr2_to_ascii(tmp, &domains[i].netbios_domain, sizeof(tmp) - 1);
+ (*names)[i] = talloc_strdup(mem_ctx, tmp);
+ }
+
+ if ( domains[i].dns_ptr ) {
+ unistr2_to_ascii(tmp2, &domains[i].dns_domain, sizeof(tmp2) - 1);
+ (*alt_names)[i] = talloc_strdup(mem_ctx, tmp2);
+ }
+
+ /* sometimes we will get back a NULL SID from this call */
+
+ if ( domains[i].sid_ptr )
+ sid_copy(&(*dom_sids)[i], &domains[i].sid.sid);
+ }
+
+ *num_domains = count;
}
- rc = ads_trusted_domains(ads, mem_ctx, num_domains, names, alt_names, dom_sids);
+done:
+
+ SAFE_FREE( domains );
+
+ /* remove connection; This is a special case to the \NETLOGON pipe */
+
+ if ( cli )
+ cli_shutdown( cli );
- return ads_ntstatus(rc);
+ return result;
}
/* find the domain sid for a domain */
diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c
index f1c8542815..af4ccabade 100644
--- a/source3/nsswitch/winbindd_cache.c
+++ b/source3/nsswitch/winbindd_cache.c
@@ -106,7 +106,7 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain)
case SEC_ADS: {
extern struct winbindd_methods ads_methods;
/* always obey the lp_security parameter for our domain */
- if ( strequal(lp_realm(), domain->alt_name) ) {
+ if ( strequal(lp_realm(), domain->alt_name) || strequal(lp_workgroup(), domain->name) ) {
domain->backend = &ads_methods;
break;
}
diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c
index dbc3062edd..f07117b5ab 100644
--- a/source3/nsswitch/winbindd_cm.c
+++ b/source3/nsswitch/winbindd_cm.c
@@ -152,7 +152,7 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
result = cli_full_connection(&new_conn->cli, global_myname(), new_conn->controller,
&dc_ip, 0, "IPC$", "IPC", ipc_username, ipc_domain,
- ipc_password, CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK,
+ ipc_password, CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK,
Undefined, &retry);
secrets_named_mutex_release(new_conn->controller);
@@ -194,6 +194,25 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
return NT_STATUS_OK;
}
+/************************************************************************
+ Wrapper around statuc cm_open_connection to retreive a freshly
+ setup cli_state struct
+************************************************************************/
+
+NTSTATUS cm_fresh_connection(const char *domain, const int pipe_index,
+ struct cli_state **cli)
+{
+ NTSTATUS result;
+ struct winbindd_cm_conn conn;
+
+ result = cm_open_connection( domain, pipe_index, &conn );
+
+ if ( NT_STATUS_IS_OK(result) )
+ *cli = conn.cli;
+
+ return result;
+}
+
/* Return true if a connection is still alive */
static BOOL connection_ok(struct winbindd_cm_conn *conn)
@@ -326,13 +345,11 @@ BOOL cm_check_for_native_mode_win2k( const char *domain )
done:
-#if 0
- /*
- * I don't think we need to shutdown here ? JRA.
- */
+ /* close the connection; no other cals use this pipe and it is called only
+ on reestablishing the domain list --jerry */
+
if ( conn.cli )
cli_shutdown( conn.cli );
-#endif
return ret;
}
diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c
index 8edd00f806..a8908487c1 100644
--- a/source3/nsswitch/winbindd_pam.c
+++ b/source3/nsswitch/winbindd_pam.c
@@ -53,55 +53,6 @@ static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
-/*******************************************************************
- wrapper around retrieving the trust account password
-*******************************************************************/
-
-static BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16],
- time_t *pass_last_set_time, uint32 *channel)
-{
- DOM_SID sid;
- char *pwd;
-
- /* if we are a DC and this is not our domain, then lookup an account
- for the domain trust */
-
- if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains() )
- {
- if ( !secrets_fetch_trusted_domain_password(domain, &pwd, &sid,
- pass_last_set_time) )
- {
- DEBUG(0, ("get_trust_pw: could not fetch trust account "
- "password for trusted domain %s\n", domain));
- return False;
- }
-
- *channel = SEC_CHAN_DOMAIN;
- E_md4hash(pwd, ret_pwd);
- SAFE_FREE(pwd);
-
- return True;
- }
- else /* just get the account for our domain (covers
- ROLE_DOMAIN_MEMBER as well */
- {
- /* get the machine trust account for our domain */
-
- if ( !secrets_fetch_trust_account_password (lp_workgroup(), ret_pwd,
- pass_last_set_time, channel) )
- {
- DEBUG(0, ("get_trust_pw: could not fetch trust account "
- "password for my domain %s\n", domain));
- return False;
- }
-
- return True;
- }
-
- /* Failure */
- return False;
-}
-
/**********************************************************************
Authenticate a user with a clear test password
**********************************************************************/
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c
index 6177c46aef..ca5146fc56 100644
--- a/source3/nsswitch/winbindd_util.c
+++ b/source3/nsswitch/winbindd_util.c
@@ -111,7 +111,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
fstrcpy(domain->name, alt_name);
fstrcpy(domain->alt_name, domain_name);
} else {
- fstrcpy(domain->name, domain_name);
+ fstrcpy(domain->name, domain_name);
if (alt_name) {
fstrcpy(domain->alt_name, alt_name);
}
@@ -183,8 +183,8 @@ void rescan_trusted_domains(BOOL force)
continue;
}
- /* Add each domain to the trusted domain list. Each domain inherits
- the access methods of its parent */
+ /* Add each domain to the trusted domain list */
+
for(i = 0; i < num_domains; i++) {
DEBUG(10,("Found domain %s\n", names[i]));
add_trusted_domain(names[i], alt_names?alt_names[i]:NULL,
@@ -209,7 +209,7 @@ BOOL init_domain_list(void)
free_domain_list();
/* Add ourselves as the first entry */
- domain = add_trusted_domain(lp_workgroup(), NULL, &cache_methods, NULL);
+ domain = add_trusted_domain( lp_workgroup(), NULL, &cache_methods, NULL);
if (!secrets_fetch_domain_sid(domain->name, &domain->sid)) {
DEBUG(1, ("Could not fetch sid for our domain %s\n",
domain->name));
@@ -782,3 +782,53 @@ BOOL winbindd_upgrade_idmap(void)
return idmap_convert(idmap_name);
}
+
+/*******************************************************************
+ wrapper around retrieving the trust account password
+*******************************************************************/
+
+BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16],
+ time_t *pass_last_set_time, uint32 *channel)
+{
+ DOM_SID sid;
+ char *pwd;
+
+ /* if we are a DC and this is not our domain, then lookup an account
+ for the domain trust */
+
+ if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains() )
+ {
+ if ( !secrets_fetch_trusted_domain_password(domain, &pwd, &sid,
+ pass_last_set_time) )
+ {
+ DEBUG(0, ("get_trust_pw: could not fetch trust account "
+ "password for trusted domain %s\n", domain));
+ return False;
+ }
+
+ *channel = SEC_CHAN_DOMAIN;
+ E_md4hash(pwd, ret_pwd);
+ SAFE_FREE(pwd);
+
+ return True;
+ }
+ else /* just get the account for our domain (covers
+ ROLE_DOMAIN_MEMBER as well */
+ {
+ /* get the machine trust account for our domain */
+
+ if ( !secrets_fetch_trust_account_password (lp_workgroup(), ret_pwd,
+ pass_last_set_time, channel) )
+ {
+ DEBUG(0, ("get_trust_pw: could not fetch trust account "
+ "password for my domain %s\n", domain));
+ return False;
+ }
+
+ return True;
+ }
+
+ /* Failure */
+ return False;
+}
+