Fix for bug #4801: Correctly implement lsa lookup levels for lookupnames.
authorMichael Adam <obnox@samba.org>
Fri, 30 Nov 2007 15:11:43 +0000 (16:11 +0100)
committerMichael Adam <obnox@samba.org>
Wed, 12 Dec 2007 17:01:06 +0000 (18:01 +0100)
This is a first patch aimed at fixing bug #4801.
It is still incomplete in that winbindd does not walk
the the trusted domains to lookup unqualified names here.
Apart from that this fix should be pretty much complete.

Michael

source/passdb/lookup_sid.c
source/rpc_server/srv_lsa_nt.c

index 37285f01d2364694ea58d21a677eba67dd433da7..d1390fdadbbfc24d310dea1cec518733cfce87c9 100644 (file)
@@ -60,16 +60,19 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
                name = talloc_strdup(tmp_ctx, full_name);
        }
 
-       DEBUG(10,("lookup_name: %s => %s (domain), %s (name)\n", 
-               full_name, domain, name));
-
        if ((domain == NULL) || (name == NULL)) {
                DEBUG(0, ("talloc failed\n"));
                TALLOC_FREE(tmp_ctx);
                return False;
        }
 
-       if (strequal(domain, get_global_sam_name())) {
+       DEBUG(10,("lookup_name: %s => %s (domain), %s (name)\n",
+               full_name, domain, name));
+       DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));
+
+       if ((flags & LOOKUP_NAME_DOMAIN) &&
+           strequal(domain, get_global_sam_name()))
+       {
 
                /* It's our own domain, lookup the name in passdb */
                if (lookup_global_sam_name(name, flags, &rid, &type)) {
@@ -81,8 +84,9 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
                return False;
        }
 
-       if (strequal(domain, builtin_domain_name())) {
-
+       if ((flags & LOOKUP_NAME_BUILTIN) &&
+           strequal(domain, builtin_domain_name()))
+       {
                /* Explicit request for a name in BUILTIN */
                if (lookup_builtin_name(name, &rid)) {
                        sid_copy(&sid, &global_sid_Builtin);
@@ -98,6 +102,7 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
         * domain yet at this point yet. This comes later. */
 
        if ((domain[0] != '\0') &&
+           (flags & ~(LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED)) &&
            (winbind_lookup_name(domain, name, &sid, &type))) {
                        goto ok;
        }
@@ -132,14 +137,18 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
 
        /* 1. well-known names */
 
-       if (lookup_wellknown_name(tmp_ctx, name, &sid, &domain)) {
+       if ((flags & LOOKUP_NAME_WKN) &&
+           lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
+       {
                type = SID_NAME_WKN_GRP;
                goto ok;
        }
 
        /* 2. Builtin domain as such */
 
-       if (strequal(name, builtin_domain_name())) {
+       if ((flags & (LOOKUP_NAME_BUILTIN|LOOKUP_NAME_REMOTE)) &&
+           strequal(name, builtin_domain_name()))
+       {
                /* Swap domain and name */
                tmp = name; name = domain; domain = tmp;
                sid_copy(&sid, &global_sid_Builtin);
@@ -149,7 +158,9 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
 
        /* 3. Account domain */
 
-       if (strequal(name, get_global_sam_name())) {
+       if ((flags & LOOKUP_NAME_DOMAIN) &&
+           strequal(name, get_global_sam_name()))
+       {
                if (!secrets_fetch_domain_sid(name, &sid)) {
                        DEBUG(3, ("Could not fetch my SID\n"));
                        TALLOC_FREE(tmp_ctx);
@@ -163,7 +174,9 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
 
        /* 4. Primary domain */
 
-       if (!IS_DC && strequal(name, lp_workgroup())) {
+       if ((flags & LOOKUP_NAME_DOMAIN) && !IS_DC &&
+           strequal(name, lp_workgroup()))
+       {
                if (!secrets_fetch_domain_sid(name, &sid)) {
                        DEBUG(3, ("Could not fetch the domain SID\n"));
                        TALLOC_FREE(tmp_ctx);
@@ -178,8 +191,9 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
        /* 5. Trusted domains as such, to me it looks as if members don't do
               this, tested an XP workstation in a NT domain -- vl */
 
-       if (IS_DC && (secrets_fetch_trusted_domain_password(name, NULL,
-                                                           &sid, NULL))) {
+       if ((flags & LOOKUP_NAME_REMOTE) && IS_DC &&
+           (secrets_fetch_trusted_domain_password(name, NULL, &sid, NULL)))
+       {
                /* Swap domain and name */
                tmp = name; name = domain; domain = tmp;
                type = SID_NAME_DOMAIN;
@@ -188,7 +202,9 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
 
        /* 6. Builtin aliases */        
 
-       if (lookup_builtin_name(name, &rid)) {
+       if ((flags & LOOKUP_NAME_BUILTIN) &&
+           lookup_builtin_name(name, &rid))
+       {
                domain = talloc_strdup(tmp_ctx, builtin_domain_name());
                sid_copy(&sid, &global_sid_Builtin);
                sid_append_rid(&sid, rid);
@@ -201,7 +217,9 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
 
        /* Both cases are done by looking at our passdb */
 
-       if (lookup_global_sam_name(name, flags, &rid, &type)) {
+       if ((flags & LOOKUP_NAME_DOMAIN) &&
+           lookup_global_sam_name(name, flags, &rid, &type))
+       {
                domain = talloc_strdup(tmp_ctx, get_global_sam_name());
                sid_copy(&sid, get_global_sam_sid());
                sid_append_rid(&sid, rid);
index 7a47cedf4a5b8d6d1ce269ae2ad21ace5b5bc500..c105edf19d8ee45f428a25f7eb7f118264c34ec0 100644 (file)
@@ -1032,6 +1032,31 @@ NTSTATUS _lsa_lookup_sids3(pipes_struct *p,
        return r_u->status;
 }
 
+static int lsa_lookup_level_to_flags(uint16 level)
+{
+       int flags;
+
+       switch (level) {
+               case 1:
+                       flags = LOOKUP_NAME_ALL;
+                       break;
+               case 2:
+                       flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
+                       break;
+               case 3:
+                       flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
+                       break;
+               case 4:
+               case 5:
+               case 6:
+               default:
+                       flags = LOOKUP_NAME_NONE;
+                       break;
+       }
+
+       return flags;
+}
+
 /***************************************************************************
 lsa_reply_lookup_names
  ***************************************************************************/
@@ -1051,10 +1076,7 @@ NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP
                DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries));
        }
                
-       /* Probably the lookup_level is some sort of bitmask. */
-       if (q_u->lookup_level == 1) {
-               flags = LOOKUP_NAME_ALL;
-       }
+       flags = lsa_lookup_level_to_flags(q_u->lookup_level);
 
        ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
        if (!ref) {
@@ -1120,11 +1142,8 @@ NTSTATUS _lsa_lookup_names2(pipes_struct *p, LSA_Q_LOOKUP_NAMES2 *q_u, LSA_R_LOO
                num_entries = MAX_LOOKUP_SIDS;
                DEBUG(5,("_lsa_lookup_names2: truncating name lookup list to %d\n", num_entries));
        }
-               
-       /* Probably the lookup_level is some sort of bitmask. */
-       if (q_u->lookup_level == 1) {
-               flags = LOOKUP_NAME_ALL;
-       }
+
+       flags = lsa_lookup_level_to_flags(q_u->lookup_level);
 
        ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
        if (ref == NULL) {