Merge branch 'v3-2-test' of ssh://git.samba.org/data/git/samba into v3-2-test
[ira/wip.git] / source3 / winbindd / winbindd_util.c
index 795209619ced8ffcb121ecec4e1dd65e9e2b3054..7933ecf63e42391729e6c7176cd5a3b72bc8001f 100644 (file)
@@ -41,7 +41,7 @@ extern struct winbindd_methods passdb_methods;
    individual winbindd_domain structures cannot be made.  Keep a copy of
    the domain name instead. */
 
    individual winbindd_domain structures cannot be made.  Keep a copy of
    the domain name instead. */
 
-static struct winbindd_domain *_domain_list;
+static struct winbindd_domain *_domain_list = NULL;
 
 /**
    When was the last scan of trusted domains done?
 
 /**
    When was the last scan of trusted domains done?
@@ -212,7 +212,7 @@ static void add_trusted_domains( struct winbindd_domain *domain )
        TALLOC_CTX *mem_ctx;
        struct winbindd_request *request;
        struct winbindd_response *response;
        TALLOC_CTX *mem_ctx;
        struct winbindd_request *request;
        struct winbindd_response *response;
-       uint32 fr_flags = (DS_DOMAIN_TREE_ROOT|DS_DOMAIN_IN_FOREST);    
+       uint32 fr_flags = (NETR_TRUST_FLAG_TREEROOT|NETR_TRUST_FLAG_IN_FOREST);
 
        struct trustdom_state *state;
 
 
        struct trustdom_state *state;
 
@@ -385,8 +385,8 @@ static void rescan_forest_root_trusts( void )
                   the domain_list() as our primary domain may not 
                   have been initialized. */
 
                   the domain_list() as our primary domain may not 
                   have been initialized. */
 
-               if ( !(dom_list[i].trust_flags & DS_DOMAIN_TREE_ROOT) ) {
-                       continue;                       
+               if ( !(dom_list[i].trust_flags & NETR_TRUST_FLAG_TREEROOT) ) {
+                       continue;
                }
        
                /* Here's the forest root */
                }
        
                /* Here's the forest root */
@@ -450,10 +450,10 @@ static void rescan_forest_trusts( void )
 
                if ( d && (d->internal || d->primary ) )
                        continue;               
 
                if ( d && (d->internal || d->primary ) )
                        continue;               
-               
-               if ( (flags & DS_DOMAIN_DIRECT_INBOUND) &&
-                    (type == DS_DOMAIN_TRUST_TYPE_UPLEVEL) &&
-                    (attribs == DS_DOMAIN_TRUST_ATTRIB_FOREST_TRANSITIVE) )
+
+               if ( (flags & NETR_TRUST_FLAG_INBOUND) &&
+                    (type == NETR_TRUST_TYPE_UPLEVEL) &&
+                    (attribs == NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) )
                {
                        /* add the trusted domain if we don't know
                           about it */
                {
                        /* add the trusted domain if we don't know
                           about it */
@@ -494,9 +494,13 @@ void rescan_trusted_domains( void )
            ((now-last_trustdom_scan) < WINBINDD_RESCAN_FREQ) )
                return;
                
            ((now-last_trustdom_scan) < WINBINDD_RESCAN_FREQ) )
                return;
                
-       /* clear the TRUSTDOM cache first */
-
-       wcache_tdc_clear();
+       /* I use to clear the cache here and start over but that
+          caused problems in child processes that needed the
+          trust dom list early on.  Removing it means we
+          could have some trusted domains listed that have been
+          removed from our primary domain's DC until a full
+          restart.  This should be ok since I think this is what
+          Windows does as well. */
 
        /* this will only add new domains we didn't already know about
           in the domain_list()*/
 
        /* this will only add new domains we didn't already know about
           in the domain_list()*/
@@ -561,7 +565,7 @@ enum winbindd_result init_child_connection(struct winbindd_domain *domain,
                /* The primary domain has to find the DC name itself */
                request->cmd = WINBINDD_INIT_CONNECTION;
                fstrcpy(request->domain_name, domain->name);
                /* The primary domain has to find the DC name itself */
                request->cmd = WINBINDD_INIT_CONNECTION;
                fstrcpy(request->domain_name, domain->name);
-               request->data.init_conn.is_primary = domain->internal ? False : True;
+               request->data.init_conn.is_primary = domain->primary ? true : false;
                fstrcpy(request->data.init_conn.dcname, "");
                async_request(mem_ctx, &domain->child, request, response,
                              init_child_recv, state);
                fstrcpy(request->data.init_conn.dcname, "");
                async_request(mem_ctx, &domain->child, request, response,
                              init_child_recv, state);
@@ -760,8 +764,8 @@ void check_domain_trusted( const char *name, const DOM_SID *user_sid )
           forest trust */
 
        domain->active_directory = True;
           forest trust */
 
        domain->active_directory = True;
-       domain->domain_flags = DS_DOMAIN_DIRECT_OUTBOUND;
-       domain->domain_type  = DS_DOMAIN_TRUST_TYPE_UPLEVEL;
+       domain->domain_flags = NETR_TRUST_FLAG_OUTBOUND;
+       domain->domain_type  = NETR_TRUST_TYPE_UPLEVEL;
        domain->internal = False;
        domain->online = True;  
 
        domain->internal = False;
        domain->online = True;  
 
@@ -1294,19 +1298,22 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
        /* always add the primary group to the sid array */
        sid_compose(&primary_group, &info3->dom_sid.sid, info3->user_rid);
        
        /* always add the primary group to the sid array */
        sid_compose(&primary_group, &info3->dom_sid.sid, info3->user_rid);
        
-       if (!add_sid_to_array(mem_ctx, &primary_group, user_sids, &num_groups)) {
+       status = add_sid_to_array(mem_ctx, &primary_group, user_sids,
+                                 &num_groups);
+       if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(info3);
                TALLOC_FREE(info3);
-               return NT_STATUS_NO_MEMORY;
+               return status;
        }
 
        for (i=0; i<info3->num_groups; i++) {
                sid_copy(&group_sid, &info3->dom_sid.sid);
                sid_append_rid(&group_sid, info3->gids[i].g_rid);
 
        }
 
        for (i=0; i<info3->num_groups; i++) {
                sid_copy(&group_sid, &info3->dom_sid.sid);
                sid_append_rid(&group_sid, info3->gids[i].g_rid);
 
-               if (!add_sid_to_array(mem_ctx, &group_sid, user_sids,
-                                &num_groups)) {
+               status = add_sid_to_array(mem_ctx, &group_sid, user_sids,
+                                         &num_groups);
+               if (!NT_STATUS_IS_OK(status)) {
                        TALLOC_FREE(info3);
                        TALLOC_FREE(info3);
-                       return NT_STATUS_NO_MEMORY;
+                       return status;
                }
        }
 
                }
        }
 
@@ -1318,11 +1325,11 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
                if (info3->other_sids_attrib[i] & SE_GROUP_RESOURCE)
                        continue;
 
                if (info3->other_sids_attrib[i] & SE_GROUP_RESOURCE)
                        continue;
 
-               if (!add_sid_to_array(mem_ctx, &info3->other_sids[i].sid,
-                                     user_sids, &num_groups))
-               {
+               status = add_sid_to_array(mem_ctx, &info3->other_sids[i].sid,
+                                         user_sids, &num_groups);
+               if (!NT_STATUS_IS_OK(status)) {
                        TALLOC_FREE(info3);
                        TALLOC_FREE(info3);
-                       return NT_STATUS_NO_MEMORY;                     
+                       return status;
                }
        }
        
                }
        }
        
@@ -1373,31 +1380,56 @@ void ws_name_return( char *name, char replace )
 /*********************************************************************
  ********************************************************************/
 
 /*********************************************************************
  ********************************************************************/
 
-bool winbindd_can_contact_domain( struct winbindd_domain *domain )
+bool winbindd_can_contact_domain(struct winbindd_domain *domain)
 {
 {
+       struct winbindd_tdc_domain *tdc = NULL;
+       TALLOC_CTX *frame = talloc_stackframe();
+       bool ret = false;
+
        /* We can contact the domain if it is our primary domain */
 
        /* We can contact the domain if it is our primary domain */
 
-       if ( domain->primary )
-               return True;
+       if (domain->primary) {
+               return true;
+       }
 
 
-       /* Can always contact a domain that is in out forest */
+       /* Trust the TDC cache and not the winbindd_domain flags */
 
 
-       if ( domain->domain_flags & DS_DOMAIN_IN_FOREST )
-               return True;    
+       if ((tdc = wcache_tdc_fetch_domain(frame, domain->name)) == NULL) {
+               DEBUG(10,("winbindd_can_contact_domain: %s not found in cache\n",
+                         domain->name));
+               return false;
+       }
 
 
-       /* We cannot contact the domain if it is running AD and
-          we have no inbound trust */
+       /* Can always contact a domain that is in out forest */
 
 
-       if ( domain->active_directory && 
-            ((domain->domain_flags&DS_DOMAIN_DIRECT_INBOUND) != DS_DOMAIN_DIRECT_INBOUND) ) 
-       {
-               return False;
+       if (tdc->trust_flags & NETR_TRUST_FLAG_IN_FOREST) {
+               ret = true;
+               goto done;
        }
        
        }
        
+       /*
+        * On a _member_ server, we cannot contact the domain if it
+        * is running AD and we have no inbound trust.
+        */
+
+       if (!IS_DC && 
+            domain->active_directory &&
+           ((tdc->trust_flags & NETR_TRUST_FLAG_INBOUND) != NETR_TRUST_FLAG_INBOUND))
+       {
+               DEBUG(10, ("winbindd_can_contact_domain: %s is an AD domain "
+                          "and we have no inbound trust.\n", domain->name));
+               goto done;
+       }
+
        /* Assume everything else is ok (probably not true but what
           can you do?) */
        /* Assume everything else is ok (probably not true but what
           can you do?) */
+
+       ret = true;     
+
+done:  
+       talloc_destroy(frame);
        
        
-       return True;    
+       return ret;     
 }
 
 /*********************************************************************
 }
 
 /*********************************************************************