summaryrefslogtreecommitdiff
path: root/source3/nsswitch/winbindd_ads.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch/winbindd_ads.c')
-rw-r--r--source3/nsswitch/winbindd_ads.c57
1 files changed, 47 insertions, 10 deletions
diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c
index e52f448a63..4ce0894ab3 100644
--- a/source3/nsswitch/winbindd_ads.c
+++ b/source3/nsswitch/winbindd_ads.c
@@ -24,6 +24,9 @@
#ifdef HAVE_ADS
+/* the realm of our primary LDAP server */
+static char *primary_realm;
+
/*
a wrapper around ldap_search_s that retries depending on the error code
@@ -33,7 +36,8 @@ int ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope,
const char *exp,
const char **attrs, void **res)
{
- int rc = -1, rc2;
+ int rc = -1;
+ ADS_RETURN_CODE rc2;
int count = 3;
if (!ads->ld &&
@@ -59,9 +63,15 @@ int ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope,
}
ads->ld = NULL;
rc2 = ads_connect(ads);
- if (rc2) {
- DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n", ads_errstr(rc)));
- return rc2;
+ if (rc2.rc) {
+ DEBUG(1,("ads_search_retry: failed to reconnect:\n"));
+ if(rc2.error_type)
+ ads_display_status("", rc2.rc, rc2.minor_status);
+ else
+ DEBUG(1,("LDAP error: %s\n", ads_errstr(rc2.rc)));
+
+ ads_destroy(&ads);
+ return rc2.rc;
}
}
DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(rc)));
@@ -92,8 +102,9 @@ int ads_search_retry_dn(ADS_STRUCT *ads, void **res,
static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
{
ADS_STRUCT *ads;
- int rc;
+ ADS_RETURN_CODE rc;
char *ccache;
+ struct in_addr server_ip;
if (domain->private) {
return (ADS_STRUCT *)domain->private;
@@ -104,7 +115,12 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
SETENV("KRB5CCNAME", ccache, 1);
unlink(ccache);
- ads = ads_init(NULL, NULL, NULL, NULL);
+ if (!resolve_name(domain->name, &server_ip, 0x1b)) {
+ DEBUG(1,("Can't find PDC for domain %s\n", domain->name));
+ return NULL;
+ }
+
+ ads = ads_init(primary_realm, inet_ntoa(server_ip), NULL, NULL);
if (!ads) {
DEBUG(1,("ads_init for domain %s failed\n", domain->name));
return NULL;
@@ -115,12 +131,22 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
ads->password = secrets_fetch_machine_password();
rc = ads_connect(ads);
- if (rc) {
- DEBUG(1,("ads_connect for domain %s failed: %s\n", domain->name, ads_errstr(rc)));
+ if (rc.rc) {
+ DEBUG(1,("ads_connect for domain %s failed:\n", domain->name));
+ if(rc.error_type)
+ ads_display_status("", rc.rc, rc.minor_status);
+ else
+ DEBUG(1,("LDAP error: %s\n", ads_errstr(rc.rc)));
+
ads_destroy(&ads);
return NULL;
}
+ /* remember our primary realm for trusted domain support */
+ if (!primary_realm) {
+ primary_realm = strdup(ads->realm);
+ }
+
domain->private = (void *)ads;
return ads;
}
@@ -546,7 +572,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
}
if (!ads_pull_uint32(ads, msg, "primaryGroupID", &primary_group)) {
- DEBUG(1,("No primary group for rid=%d !?\n", user_rid));
+ DEBUG(1,("%s: No primary group for rid=%d !?\n", domain->name, user_rid));
goto done;
}
@@ -666,8 +692,19 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
char ***names,
DOM_SID **dom_sids)
{
+ ADS_STRUCT *ads = NULL;
+
*num_domains = 0;
- return NT_STATUS_NOT_IMPLEMENTED;
+ *names = NULL;
+
+ ads = ads_cached_connection(domain);
+ if (!ads) return NT_STATUS_UNSUCCESSFUL;
+
+ if (!ads_trusted_domains(ads, mem_ctx, num_domains, names, dom_sids)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ return NT_STATUS_OK;
}
/* find the domain sid for a domain */