Author: mimir
Date: 2007-09-06 11:07:58 +0000 (Thu, 06 Sep 2007)
New Revision: 24977

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=24977

Log:
Ensure negative caching for name2sid, sid2name and rids2names
mappings.


rafal


Modified:
   branches/SAMBA_3_2/source/nsswitch/winbindd_cache.c


Changeset:
Modified: branches/SAMBA_3_2/source/nsswitch/winbindd_cache.c
===================================================================
--- branches/SAMBA_3_2/source/nsswitch/winbindd_cache.c 2007-09-06 11:07:13 UTC 
(rev 24976)
+++ branches/SAMBA_3_2/source/nsswitch/winbindd_cache.c 2007-09-06 11:07:58 UTC 
(rev 24977)
@@ -353,6 +353,19 @@
        return True;
 }
 
+
+/*
+  pull a NTSTATUS from a cache entry
+*/
+static NTSTATUS centry_ntstatus(struct cache_entry *centry)
+{
+       NTSTATUS status;
+
+       status = NT_STATUS(centry_uint32(centry));
+       return status;
+}
+
+
 /* the server is considered down if it can't give us a sequence number */
 static BOOL wcache_server_down(struct winbindd_domain *domain)
 {
@@ -587,7 +600,7 @@
                return NULL;
        }
        
-       centry->status = NT_STATUS(centry_uint32(centry));
+       centry->status = centry_ntstatus(centry);
        centry->sequence_number = centry_uint32(centry);
 
        return centry;
@@ -746,7 +759,18 @@
        centry_put_string(centry, sid_to_string(sid_string, sid));
 }
 
+
 /*
+  put NTSTATUS into a centry
+*/
+static void centry_put_ntstatus(struct cache_entry *centry, NTSTATUS status)
+{
+       uint32 status_value = NT_STATUS_V(status);
+       centry_put_uint32(centry, status_value);
+}
+
+
+/*
   push a NTTIME into a centry 
 */
 static void centry_put_nttime(struct cache_entry *centry, NTTIME nt)
@@ -784,7 +808,7 @@
        centry->data = SMB_XMALLOC_ARRAY(uint8, centry->len);
        centry->ofs = 0;
        centry->sequence_number = domain->sequence_number;
-       centry_put_uint32(centry, NT_STATUS_V(status));
+       centry_put_ntstatus(centry, status);
        centry_put_uint32(centry, centry->sequence_number);
        return centry;
 }
@@ -842,18 +866,16 @@
        struct cache_entry *centry;
        fstring sid_string;
 
-       if (is_null_sid(sid)) {
-               return;
-       }
-
        centry = centry_start(domain, status);
        if (!centry)
                return;
+
        if (NT_STATUS_IS_OK(status)) {
                centry_put_uint32(centry, type);
                centry_put_string(centry, domain_name);
                centry_put_string(centry, name);
        }
+
        centry_end(centry, "SN/%s", sid_to_string(sid_string, sid));
        DEBUG(10,("wcache_save_sid_to_name: %s -> %s (%s)\n", sid_string, 
                  name, nt_errstr(status)));
@@ -1376,9 +1398,10 @@
        centry = wcache_fetch(cache, domain, "NS/%s/%s", domain_name, uname);
        if (!centry)
                goto do_query;
-       *type = (enum lsa_SidType)centry_uint32(centry);
+
        status = centry->status;
        if (NT_STATUS_IS_OK(status)) {
+               *type = (enum lsa_SidType)centry_uint32(centry);
                centry_sid(centry, mem_ctx, sid);
        }
 
@@ -1411,17 +1434,18 @@
        /* and save it */
        refresh_sequence_number(domain, False);
 
-       if (domain->online && !is_null_sid(sid)) {
+       if (domain->online &&
+           (NT_STATUS_IS_OK(status) || NT_STATUS_EQUAL(status, 
NT_STATUS_NONE_MAPPED))) {
                wcache_save_name_to_sid(domain, status, domain_name, name, sid, 
*type);
-       }
 
-       /* Only save the reverse mapping if this was not a UPN */
-       if (NT_STATUS_IS_OK(status) && !strchr(name, '@')) {
-               strupper_m(CONST_DISCARD(char *,domain_name));
-               strlower_m(CONST_DISCARD(char *,name));
-               wcache_save_sid_to_name(domain, status, sid, domain_name, name, 
*type);
+               /* Only save the reverse mapping if this was not a UPN */
+               if (!strchr(name, '@')) {
+                       strupper_m(CONST_DISCARD(char *,domain_name));
+                       strlower_m(CONST_DISCARD(char *,name));
+                       wcache_save_sid_to_name(domain, status, sid, 
domain_name, name, *type);
+               }
        }
-
+       
        return status;
 }
 
@@ -1445,12 +1469,13 @@
        centry = wcache_fetch(cache, domain, "SN/%s", sid_to_string(sid_string, 
sid));
        if (!centry)
                goto do_query;
-       if (NT_STATUS_IS_OK(centry->status)) {
+
+       status = centry->status;
+       if (NT_STATUS_IS_OK(status)) {
                *type = (enum lsa_SidType)centry_uint32(centry);
                *domain_name = centry_string(centry, mem_ctx);
                *name = centry_string(centry, mem_ctx);
        }
-       status = centry->status;
 
        DEBUG(10,("sid_to_name: [Cached] - cached name for domain %s status: 
%s\n",
                domain->name, nt_errstr(status) ));
@@ -1547,15 +1572,23 @@
                        char *dom;
                        have_mapped = True;
                        (*types)[i] = (enum lsa_SidType)centry_uint32(centry);
+
                        dom = centry_string(centry, mem_ctx);
                        if (*domain_name == NULL) {
                                *domain_name = dom;
                        } else {
                                talloc_free(dom);
                        }
+
                        (*names)[i] = centry_string(centry, *names);
+
+               } else if (NT_STATUS_EQUAL(centry->status, 
NT_STATUS_NONE_MAPPED)) {
+                       have_unmapped = True;
+
                } else {
-                       have_unmapped = True;
+                       /* something's definitely wrong */
+                       result = centry->status;
+                       goto error;
                }
 
                centry_free(centry);
@@ -1578,6 +1611,30 @@
                                                rids, num_rids, domain_name,
                                                names, types);
 
+       /*
+         None of the queried rids has been found so save all negative entries
+       */
+       if (NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED)) {
+               for (i = 0; i < num_rids; i++) {
+                       DOM_SID sid;
+                       const char *name = "";
+                       const enum lsa_SidType type = SID_NAME_UNKNOWN;
+                       NTSTATUS status = NT_STATUS_NONE_MAPPED;
+                       
+                       if (!sid_compose(&sid, domain_sid, rids[i])) {
+                               return NT_STATUS_INTERNAL_ERROR;
+                       }
+
+                       wcache_save_sid_to_name(domain, status, &sid, 
*domain_name,
+                                               name, type);
+               }
+
+               return result;
+       }
+
+       /*
+         Some or all of the queried rids have been found.
+       */
        if (!NT_STATUS_IS_OK(result) &&
            !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
                return result;
@@ -1639,15 +1696,19 @@
        
        if (!centry)
                goto do_query;
-
-       info->acct_name = centry_string(centry, mem_ctx);
-       info->full_name = centry_string(centry, mem_ctx);
-       info->homedir = centry_string(centry, mem_ctx);
-       info->shell = centry_string(centry, mem_ctx);
-       info->primary_gid = centry_uint32(centry);
-       centry_sid(centry, mem_ctx, &info->user_sid);
-       centry_sid(centry, mem_ctx, &info->group_sid);
+       
+       /* if status is not ok then this is a negative hit
+          and the rest of the data doesn't matter */
        status = centry->status;
+       if (NT_STATUS_IS_OK(status)) {
+               info->acct_name = centry_string(centry, mem_ctx);
+               info->full_name = centry_string(centry, mem_ctx);
+               info->homedir = centry_string(centry, mem_ctx);
+               info->shell = centry_string(centry, mem_ctx);
+               info->primary_gid = centry_uint32(centry);
+               centry_sid(centry, mem_ctx, &info->user_sid);
+               centry_sid(centry, mem_ctx, &info->group_sid);
+       }
 
        DEBUG(10,("query_user: [Cached] - cached info for domain %s status: 
%s\n",
                domain->name, nt_errstr(status) ));
@@ -1752,10 +1813,12 @@
        centry = centry_start(domain, status);
        if (!centry)
                goto skip_save;
+
        centry_put_uint32(centry, *num_groups);
        for (i=0; i<(*num_groups); i++) {
                centry_put_sid(centry, &(*user_gids)[i]);
        }       
+
        centry_end(centry, "UG/%s", sid_to_string(sid_string, user_sid));
        centry_free(centry);
 

Reply via email to