winbind: Make centry_start static
[samba.git] / source3 / winbindd / winbindd_util.c
index 7dff138fc137b0a1381da743e024d8ebc5e0dad1..85b014d97ccc5965ca423b66a948205ce50f259e 100644 (file)
@@ -67,7 +67,7 @@ static void free_domain_list(void)
                struct winbindd_domain *next = domain->next;
 
                DLIST_REMOVE(_domain_list, domain);
-               SAFE_FREE(domain);
+               TALLOC_FREE(domain);
                domain = next;
        }
 }
@@ -77,7 +77,7 @@ static bool is_internal_domain(const struct dom_sid *sid)
        if (sid == NULL)
                return False;
 
-       return (sid_check_is_domain(sid) || sid_check_is_builtin(sid));
+       return (sid_check_is_our_sam(sid) || sid_check_is_builtin(sid));
 }
 
 static bool is_in_internal_domain(const struct dom_sid *sid)
@@ -85,7 +85,7 @@ static bool is_in_internal_domain(const struct dom_sid *sid)
        if (sid == NULL)
                return False;
 
-       return (sid_check_is_in_our_domain(sid) || sid_check_is_in_builtin(sid));
+       return (sid_check_is_in_our_sam(sid) || sid_check_is_in_builtin(sid));
 }
 
 
@@ -108,9 +108,9 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
                }
        }
 
-       /* ignore alt_name if we are not in an AD domain */
+       /* use alt_name if available to allow DNS lookups */
 
-       if ( (lp_security() == SEC_ADS) && alt_name && *alt_name) {
+       if (alt_name && *alt_name) {
                alternative_name = alt_name;
        }
 
@@ -156,27 +156,31 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
        }
 
        /* Create new domain entry */
-
-       if ((domain = SMB_MALLOC_P(struct winbindd_domain)) == NULL)
+       domain = talloc_zero(NULL, struct winbindd_domain);
+       if (domain == NULL) {
                return NULL;
+       }
 
-       /* Fill in fields */
-
-       ZERO_STRUCTP(domain);
-
-       domain->children = SMB_MALLOC_ARRAY(
-               struct winbindd_child, lp_winbind_max_domain_connections());
+       domain->children = talloc_zero_array(domain,
+                                            struct winbindd_child,
+                                            lp_winbind_max_domain_connections());
        if (domain->children == NULL) {
-               SAFE_FREE(domain);
+               TALLOC_FREE(domain);
+               return NULL;
+       }
+
+       domain->name = talloc_strdup(domain, domain_name);
+       if (domain->name == NULL) {
+               TALLOC_FREE(domain);
                return NULL;
        }
-       memset(domain->children, 0,
-              sizeof(struct winbindd_child)
-              * lp_winbind_max_domain_connections());
 
-       fstrcpy(domain->name, domain_name);
        if (alternative_name) {
-               fstrcpy(domain->alt_name, alternative_name);
+               domain->alt_name = talloc_strdup(domain, alternative_name);
+               if (domain->alt_name == NULL) {
+                       TALLOC_FREE(domain);
+                       return NULL;
+               }
        }
 
        domain->methods = methods;
@@ -303,6 +307,7 @@ static void trustdom_list_done(struct tevent_req *req)
                struct dom_sid sid;
                struct winbindd_domain *domain;
                char *alternate_name = NULL;
+               bool domain_exists;
 
                alt_name = strchr(p, '\\');
                if (alt_name == NULL) {
@@ -336,22 +341,25 @@ static void trustdom_list_done(struct tevent_req *req)
                if ( !strequal( alt_name, "(null)" ) )
                        alternate_name = alt_name;
 
-               /* If we have an existing domain structure, calling
-                  add_trusted_domain() will update the SID if
-                  necessary.  This is important because we need the
-                  SID for sibling domains */
+               /* Check if we already have a child for the domain */
+               domain_exists = (find_domain_from_name_noinit(p) != NULL);
 
-               if ( find_domain_from_name_noinit(p) != NULL ) {
-                       domain = add_trusted_domain(p, alternate_name,
-                                                   &cache_methods,
-                                                   &sid);
-               } else {
-                       domain = add_trusted_domain(p, alternate_name,
-                                                   &cache_methods,
-                                                   &sid);
-                       if (domain) {
-                               setup_domain_child(domain);
-                       }
+               /*
+                * We always call add_trusted_domain() cause on an existing
+                * domain structure, it will update the SID if necessary.
+                * This is important because we need the SID for sibling
+                * domains.
+                */
+               domain = add_trusted_domain(p, alternate_name,
+                                           &cache_methods,
+                                           &sid);
+
+               /*
+                * If the domain doesn't exist yet and got correctly added,
+                * setup a new domain child.
+                */
+               if (!domain_exists && domain != NULL) {
+                       setup_domain_child(domain);
                }
                p=q;
                if (p != NULL)
@@ -675,7 +683,7 @@ struct winbindd_domain *find_domain_from_name_noinit(const char *domain_name)
 
        for (domain = domain_list(); domain != NULL; domain = domain->next) {
                if (strequal(domain_name, domain->name) ||
-                   (domain->alt_name[0] &&
+                   (domain->alt_name != NULL &&
                     strequal(domain_name, domain->alt_name))) {
                        return domain;
                }
@@ -755,7 +763,7 @@ struct winbindd_domain *find_root_domain(void)
 {
        struct winbindd_domain *ours = find_our_domain();
 
-       if (ours->forest_name[0] == '\0') {
+       if (ours->forest_name == NULL) {
                return NULL;
        }
 
@@ -877,9 +885,7 @@ bool parse_domain_user(const char *domuser, fstring domain, fstring user)
                domain[PTR_DIFF(p, domuser)] = 0;
        }
 
-       strupper_m(domain);
-
-       return True;
+       return strupper_m(domain);
 }
 
 bool parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser,
@@ -933,7 +939,7 @@ void fill_domain_username(fstring name, const char *domain, const char *user, bo
        fstring tmp_user;
 
        fstrcpy(tmp_user, user);
-       strlower_m(tmp_user);
+       (void)strlower_m(tmp_user);
 
        if (can_assume && assume_domain(domain)) {
                strlcpy(name, tmp_user, sizeof(fstring));
@@ -956,7 +962,10 @@ char *fill_domain_username_talloc(TALLOC_CTX *mem_ctx,
        char *tmp_user, *name;
 
        tmp_user = talloc_strdup(mem_ctx, user);
-       strlower_m(tmp_user);
+       if (!strlower_m(tmp_user)) {
+               TALLOC_FREE(tmp_user);
+               return NULL;
+       }
 
        if (can_assume && assume_domain(domain)) {
                name = tmp_user;
@@ -1033,12 +1042,18 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
                return NT_STATUS_UNSUCCESSFUL;
        }
 
-       /* Skip Domain local groups outside our domain.
-          We'll get these from the getsidaliases() RPC call. */
+       /*
+        * Before bug #7843 the "Domain Local" groups were added with a
+        * lookupuseraliases call, but this isn't done anymore for our domain
+        * so we need to resolve resource groups here.
+        *
+        * When to use Resource Groups:
+        * http://technet.microsoft.com/en-us/library/cc753670%28v=WS.10%29.aspx
+        */
        status = sid_array_from_info3(mem_ctx, info3,
                                      user_sids,
                                      &num_groups,
-                                     false, true);
+                                     false);
 
        if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(info3);
@@ -1173,7 +1188,8 @@ bool winbindd_can_contact_domain(struct winbindd_domain *domain)
        /* We can contact the domain if it is our primary domain */
 
        if (domain->primary) {
-               return true;
+               ret = true;
+               goto done;
        }
 
        /* Trust the TDC cache and not the winbindd_domain flags */
@@ -1181,7 +1197,8 @@ bool winbindd_can_contact_domain(struct winbindd_domain *domain)
        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;
+               ret = false;
+               goto done;
        }
 
        /* Can always contact a domain that is in out forest */
@@ -1351,6 +1368,15 @@ bool is_domain_online(const struct winbindd_domain *domain)
        return !is_domain_offline(domain);
 }
 
+/**
+ * Parse an char array into a list of sids.
+ *
+ * The input sidstr should consist of 0-terminated strings
+ * representing sids, separated by newline characters '\n'.
+ * The list is terminated by an empty string, i.e.
+ * character '\0' directly following a character '\n'
+ * (or '\0' right at the start of sidstr).
+ */
 bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
                   struct dom_sid **sids, uint32_t *num_sids)
 {