s3:winbindd:util: add a comment explaining the function parse_sidlist()
[samba.git] / source3 / winbindd / winbindd_util.c
index 14be0e26fa2ccec9e2e4e3fbada1d74029ad8c8a..6e13ca8ba7db19d9aafc03976e33350e3c4a6d39 100644 (file)
@@ -23,7 +23,9 @@
 #include "includes.h"
 #include "winbindd.h"
 #include "secrets.h"
-#include "../libcli/security/dom_sid.h"
+#include "../libcli/security/security.h"
+#include "../libcli/auth/pam_errors.h"
+#include "passdb/machine_sid.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
@@ -31,7 +33,7 @@
 extern struct winbindd_methods cache_methods;
 
 /**
- * @file winbindd_util.c
+ * @file winbindd_util.cq
  *
  * Winbind daemon for NT domain authentication nss module.
  **/
@@ -75,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)
@@ -83,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));
 }
 
 
@@ -106,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;
        }
 
@@ -162,6 +164,16 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
 
        ZERO_STRUCTP(domain);
 
+       domain->children = SMB_MALLOC_ARRAY(
+               struct winbindd_child, lp_winbind_max_domain_connections());
+       if (domain->children == NULL) {
+               SAFE_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);
@@ -249,7 +261,7 @@ static void add_trusted_domains( struct winbindd_domain *domain )
        struct trustdom_state *state;
        struct tevent_req *req;
 
-       state = TALLOC_ZERO_P(NULL, struct trustdom_state);
+       state = talloc_zero(NULL, struct trustdom_state);
        if (state == NULL) {
                DEBUG(0, ("talloc failed\n"));
                return;
@@ -643,49 +655,6 @@ bool init_domain_list(void)
        return True;
 }
 
-void check_domain_trusted( const char *name, const struct dom_sid *user_sid )
-{
-       struct winbindd_domain *domain;
-       struct dom_sid dom_sid;
-       uint32 rid;
-
-       /* Check if we even care */
-
-       if (!lp_allow_trusted_domains())
-               return;
-
-       domain = find_domain_from_name_noinit( name );
-       if ( domain )
-               return;
-
-       sid_copy( &dom_sid, user_sid );
-       if ( !sid_split_rid( &dom_sid, &rid ) )
-               return;
-
-       /* add the newly discovered trusted domain */
-
-       domain = add_trusted_domain( name, NULL, &cache_methods,
-                                    &dom_sid);
-
-       if ( !domain )
-               return;
-
-       /* assume this is a trust from a one-way transitive
-          forest trust */
-
-       domain->active_directory = True;
-       domain->domain_flags = NETR_TRUST_FLAG_OUTBOUND;
-       domain->domain_type  = NETR_TRUST_TYPE_UPLEVEL;
-       domain->internal = False;
-       domain->online = True;
-
-       setup_domain_child(domain);
-
-       wcache_tdc_add_domain( domain );
-
-       return;
-}
-
 /**
  * Given a domain name, return the struct winbindd domain info for it
  *
@@ -908,9 +877,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,
@@ -925,31 +892,6 @@ bool parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser,
        return ((*domain != NULL) && (*user != NULL));
 }
 
-/* add a domain user name to a buffer */
-void parse_add_domuser(void *buf, char *domuser, int *len)
-{
-       fstring domain;
-       char *p, *user;
-
-       user = domuser;
-       p = strchr(domuser, *lp_winbind_separator());
-
-       if (p) {
-
-               fstrcpy(domain, domuser);
-               domain[PTR_DIFF(p, domuser)] = 0;
-               p++;
-
-               if (assume_domain(domain)) {
-
-                       user = p;
-                       *len -= (PTR_DIFF(p, domuser));
-               }
-       }
-
-       safe_strcpy((char *)buf, user, *len);
-}
-
 /* Ensure an incoming username from NSS is fully qualified. Replace the
    incoming fstring with DOMAIN <separator> user. Returns the same
    values as parse_domain_user() but also replaces the incoming username.
@@ -989,7 +931,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));
@@ -1012,7 +954,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;
@@ -1089,12 +1034,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);
@@ -1229,7 +1180,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 */
@@ -1237,7 +1189,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 */
@@ -1401,3 +1354,48 @@ bool is_domain_offline(const struct winbindd_domain *domain)
        }
        return !domain->online;
 }
+
+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)
+{
+       const char *p;
+
+       p = sidstr;
+       if (p == NULL)
+               return False;
+
+       while (p[0] != '\0') {
+               struct dom_sid sid;
+               const char *q = NULL;
+
+               if (!dom_sid_parse_endp(p, &sid, &q)) {
+                       DEBUG(1, ("Could not parse sid %s\n", p));
+                       return false;
+               }
+               if ((q == NULL) || (q[0] != '\n')) {
+                       DEBUG(1, ("Got invalid sidstr: %s\n", p));
+                       return false;
+               }
+               if (!NT_STATUS_IS_OK(add_sid_to_array(mem_ctx, &sid, sids,
+                                                     num_sids)))
+               {
+                       return False;
+               }
+               p = q+1;
+       }
+       return True;
+}