Avoid overriding default ccache for ads operations.
[kai/samba.git] / source3 / winbindd / winbindd_ads.c
index a392305b5512423da0470c7060c6127bff485d4c..628fd1c3f2790c7902b0e8651240c6779a1ce921 100644 (file)
 
 #include "includes.h"
 #include "winbindd.h"
+#include "rpc_client/rpc_client.h"
 #include "../librpc/gen_ndr/ndr_netlogon_c.h"
 #include "../libds/common/flags.h"
 #include "ads.h"
 #include "secrets.h"
 #include "../libcli/ldap/ldap_ndr.h"
 #include "../libcli/security/security.h"
+#include "../libds/common/flag_mapping.h"
+#include "passdb.h"
 
 #ifdef HAVE_ADS
 
@@ -75,15 +78,15 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
                }
        }
 
-       /* we don't want this to affect the users ccache */
-       setenv("KRB5CCNAME", "MEMORY:winbind_ccache", 1);
-
        ads = ads_init(domain->alt_name, domain->name, NULL);
        if (!ads) {
                DEBUG(1,("ads_init for domain %s failed\n", domain->name));
                return NULL;
        }
 
+       /* we don't want ads operations to affect the default ccache */
+       ads->auth.ccache_name = SMB_STRDUP("MEMORY:winbind_ccache");
+
        /* the machine acct password might have change - fetch it every time */
 
        SAFE_FREE(ads->auth.password);
@@ -96,7 +99,10 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
                        return NULL;
                }
                ads->auth.realm = SMB_STRDUP( ads->server.realm );
-               strupper_m( ads->auth.realm );
+               if (!strupper_m( ads->auth.realm )) {
+                       ads_destroy( &ads );
+                       return NULL;
+               }
        }
        else {
                struct winbindd_domain *our_domain = domain;
@@ -111,7 +117,10 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
 
                if ( our_domain->alt_name[0] != '\0' ) {
                        ads->auth.realm = SMB_STRDUP( our_domain->alt_name );
-                       strupper_m( ads->auth.realm );
+                       if (!strupper_m( ads->auth.realm )) {
+                               ads_destroy( &ads );
+                               return NULL;
+                       }
                }
                else
                        ads->auth.realm = SMB_STRDUP( lp_realm() );
@@ -185,8 +194,12 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
        }
 
        rc = ads_search_retry(ads, &res, "(objectCategory=user)", attrs);
-       if (!ADS_ERR_OK(rc) || !res) {
+       if (!ADS_ERR_OK(rc)) {
                DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc)));
+               status = ads_ntstatus(rc);
+       } else if (!res) {
+               DEBUG(1,("query_user_list ads_search returned NULL res\n"));
+
                goto done;
        }
 
@@ -196,7 +209,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
                goto done;
        }
 
-       (*pinfo) = TALLOC_ZERO_ARRAY(mem_ctx, struct wbint_userinfo, count);
+       (*pinfo) = talloc_zero_array(mem_ctx, struct wbint_userinfo, count);
        if (!*pinfo) {
                status = NT_STATUS_NO_MEMORY;
                goto done;
@@ -245,14 +258,8 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
                const char *gecos = NULL;
                gid_t primary_gid = (gid_t)-1;
 
-               /*
-                * Don't use our variable "ads" in this call here, every call
-                * to nss_get_info_cached can destroy the connection inside
-                * the domain.
-                */
                status = nss_get_info_cached(domain, &info->user_sid, mem_ctx,
-                                            ads_cached_connection(domain),
-                                            msg, &info->homedir, &info->shell,
+                                            &info->homedir, &info->shell,
                                             &gecos, &primary_gid);
                if (!NT_STATUS_IS_OK(status)) {
                        /*
@@ -280,7 +287,7 @@ done:
 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
                                TALLOC_CTX *mem_ctx,
                                uint32 *num_entries, 
-                               struct acct_info **info)
+                               struct wb_acct_info **info)
 {
        ADS_STRUCT *ads = NULL;
        const char *attrs[] = {"userPrincipalName", "sAMAccountName",
@@ -343,9 +350,13 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
        }
 
        rc = ads_search_retry(ads, &res, filter, attrs);
-       if (!ADS_ERR_OK(rc) || !res) {
+       if (!ADS_ERR_OK(rc)) {
+               status = ads_ntstatus(rc);
                DEBUG(1,("enum_dom_groups ads_search: %s\n", ads_errstr(rc)));
                goto done;
+       } else if (!res) {
+               DEBUG(1,("enum_dom_groups ads_search returned NULL res\n"));
+               goto done;
        }
 
        count = ads_count_replies(ads, res);
@@ -354,7 +365,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
                goto done;
        }
 
-       (*info) = TALLOC_ZERO_ARRAY(mem_ctx, struct acct_info, count);
+       (*info) = talloc_zero_array(mem_ctx, struct wb_acct_info, count);
        if (!*info) {
                status = NT_STATUS_NO_MEMORY;
                goto done;
@@ -402,7 +413,7 @@ done:
 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
                                TALLOC_CTX *mem_ctx,
                                uint32 *num_entries, 
-                               struct acct_info **info)
+                               struct wb_acct_info **info)
 {
        /*
         * This is a stub function only as we returned the domain 
@@ -492,7 +503,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
 
        /* try netsamlogon cache first */
 
-       if ( (user = netsamlogon_cache_get( mem_ctx, sid )) != NULL ) 
+       if (winbindd_use_cache() && (user = netsamlogon_cache_get( mem_ctx, sid )) != NULL )
        {
                DEBUG(5,("query_user: Cache lookup succeeded for %s\n", 
                         sid_string_dbg(sid)));
@@ -503,7 +514,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
                info->acct_name = talloc_strdup(mem_ctx, user->base.account_name.string);
                info->full_name = talloc_strdup(mem_ctx, user->base.full_name.string);
 
-               nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL, 
+               nss_get_info_cached( domain, sid, mem_ctx,
                              &info->homedir, &info->shell, &info->full_name, 
                              &gid );
                info->primary_gid = gid;
@@ -529,7 +540,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
 
                /* Try to fill in what the nss_info backend can do */
 
-               nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL, 
+               nss_get_info_cached( domain, sid, mem_ctx,
                              &info->homedir, &info->shell, &info->full_name, 
                              &gid);
                info->primary_gid = gid;
@@ -553,10 +564,14 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
        }
        rc = ads_search_retry(ads, &msg, ldap_exp, attrs);
        SAFE_FREE(ldap_exp);
-       if (!ADS_ERR_OK(rc) || !msg) {
+       if (!ADS_ERR_OK(rc)) {
                DEBUG(1,("query_user(sid=%s) ads_search: %s\n",
                         sid_string_dbg(sid), ads_errstr(rc)));
                return ads_ntstatus(rc);
+       } else if (!msg) {
+               DEBUG(1,("query_user(sid=%s) ads_search returned NULL res\n",
+                        sid_string_dbg(sid)));
+               return NT_STATUS_INTERNAL_ERROR;
        }
 
        count = ads_count_replies(ads, msg);
@@ -588,7 +603,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
        ads_msgfree(ads, msg);
        msg = NULL;
 
-       status = nss_get_info_cached( domain, sid, mem_ctx, ads, msg,
+       status = nss_get_info_cached( domain, sid, mem_ctx,
                      &info->homedir, &info->shell, &info->full_name, 
                      &gid);
        info->primary_gid = gid;
@@ -665,11 +680,15 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain,
 
        rc = ads_search_retry(ads, &res, ldap_exp, group_attrs);
 
-       if (!ADS_ERR_OK(rc) || !res) {
+       if (!ADS_ERR_OK(rc)) {
                DEBUG(1,("lookup_usergroups ads_search member=%s: %s\n", user_dn, ads_errstr(rc)));
                return ads_ntstatus(rc);
+       } else if (!res) {
+               DEBUG(1,("lookup_usergroups ads_search returned NULL res\n"));
+               return NT_STATUS_INTERNAL_ERROR;
        }
 
+
        count = ads_count_replies(ads, res);
 
        *user_sids = NULL;
@@ -772,7 +791,7 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
                goto done;
        }
 
-       group_sids = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_strings + 1);
+       group_sids = talloc_zero_array(mem_ctx, struct dom_sid, num_strings + 1);
        if (!group_sids) {
                status = NT_STATUS_NO_MEMORY;
                goto done;
@@ -1088,10 +1107,10 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
         * cache. Only the rest is passed to the lsa_lookup_sids call. */
 
        if (num_members) {
-               (*sid_mem) = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_members);
-               (*names) = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_members);
-               (*name_types) = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_members);
-               (sid_mem_nocache) = TALLOC_ZERO_ARRAY(tmp_ctx, struct dom_sid, num_members);
+               (*sid_mem) = talloc_zero_array(mem_ctx, struct dom_sid, num_members);
+               (*names) = talloc_zero_array(mem_ctx, char *, num_members);
+               (*name_types) = talloc_zero_array(mem_ctx, uint32, num_members);
+               (sid_mem_nocache) = talloc_zero_array(tmp_ctx, struct dom_sid, num_members);
 
                if ((members == NULL) || (*sid_mem == NULL) ||
                    (*names == NULL) || (*name_types == NULL) ||