Fix for bug #4801: Correctly implement lsa lookup levels for lookupnames.
authorMichael Adam <obnox@samba.org>
Wed, 12 Dec 2007 17:03:20 +0000 (18:03 +0100)
committerMichael Adam <obnox@samba.org>
Thu, 13 Dec 2007 09:15:13 +0000 (10:15 +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
(This used to be commit dd320c0924ce393a89b1cab020fd5cffc5b80380)

source3/passdb/lookup_sid.c
source3/rpc_server/srv_lsa_nt.c

index bb54959e96b14856d478d9b1c4fedc3e263bd456..54db14fbfe803ca6ce3fdac7deee07d88160b5f8 100644 (file)
@@ -59,16 +59,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)) {
@@ -80,8 +83,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);
@@ -97,6 +101,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;
        }
@@ -131,14 +136,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);
@@ -148,7 +157,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);
@@ -162,7 +173,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);
@@ -177,7 +190,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 && (pdb_get_trusteddom_pw(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;
@@ -186,7 +201,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);
@@ -199,7 +216,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 20655082a519745388a5e3ee7f6254a81b41c289..c5f0c7b6ab1698e53e2bc6640ad865c27168cb50 100644 (file)
@@ -1035,6 +1035,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
  ***************************************************************************/
@@ -1054,10 +1079,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) {
@@ -1123,11 +1145,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) {