winbind: Use domain name from lsa query for sid_to_name cache entry
[nivanova/samba-autobuild/.git] / source3 / winbindd / winbindd_cache.c
index e19ffbc24435fea75975667692bf0d296aef51c1..abdfd11dc531398e98b695cad0ebf22a17d1adb7 100644 (file)
@@ -35,6 +35,7 @@
 #include "passdb/machine_sid.h"
 #include "util_tdb.h"
 #include "libsmb/samlogon_cache.h"
+#include "lib/namemap_cache.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
@@ -118,15 +119,14 @@ static char *wcache_path(void)
         * Data needs to be kept persistent in state directory for
         * running with "winbindd offline logon".
         */
-       return state_path("winbindd_cache.tdb");
+       return state_path(talloc_tos(), "winbindd_cache.tdb");
 }
 
-/* get the winbind_cache structure */
-static struct winbind_cache *get_cache(struct winbindd_domain *domain)
+static void winbindd_domain_init_backend(struct winbindd_domain *domain)
 {
-       struct winbind_cache *ret = wcache;
-
-       /* We have to know what type of domain we are dealing with first. */
+       if (domain->backend != NULL) {
+               return;
+       }
 
        if (domain->internal) {
                domain->backend = &builtin_passdb_methods;
@@ -147,24 +147,6 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain)
                init_dc_connection(domain, false);
        }
 
-       /*
-          OK.  Listen up because I'm only going to say this once.
-          We have the following scenarios to consider
-          (a) trusted AD domains on a Samba DC,
-          (b) trusted AD domains and we are joined to a non-kerberos domain
-          (c) trusted AD domains and we are joined to a kerberos (AD) domain
-
-          For (a) we can always contact the trusted domain using krb5
-          since we have the domain trust account password
-
-          For (b) we can only use RPC since we have no way of
-          getting a krb5 ticket in our own domain
-
-          For (c) we can always use krb5 since we have a kerberos trust
-
-          --jerry
-        */
-
 #ifdef HAVE_ADS
        if (domain->backend == NULL) {
                struct winbindd_domain *our_domain = domain;
@@ -191,6 +173,14 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain)
                DBG_INFO("Setting MS-RPC methods for domain %s\n", domain->name);
                domain->backend = &reconnect_methods;
        }
+}
+
+/* get the winbind_cache structure */
+static struct winbind_cache *get_cache(struct winbindd_domain *domain)
+{
+       struct winbind_cache *ret = wcache;
+
+       winbindd_domain_init_backend(domain);
 
        if (ret != NULL) {
                return ret;
@@ -470,7 +460,7 @@ static NTSTATUS fetch_cache_seqnum( struct winbindd_domain *domain, time_t now )
        /* have we expired? */
 
        time_diff = now - domain->last_seq_check;
-       if ( time_diff > lp_winbind_cache_time() ) {
+       if ((int)time_diff > lp_winbind_cache_time()) {
                DEBUG(10,("fetch_cache_seqnum: timeout [%s][%u @ %u]\n",
                        domain->name, domain->sequence_number,
                        (uint32_t)domain->last_seq_check));
@@ -637,7 +627,7 @@ static bool centry_expired(struct winbindd_domain *domain, const char *keystr, s
           current sequence number or it did not timeout then it is OK */
        if (wcache_server_down(domain)
            || ((centry->sequence_number == domain->sequence_number)
-               && (centry->timeout > time(NULL)))) {
+               && ((time_t)centry->timeout > time(NULL)))) {
                DEBUG(10,("centry_expired: Key %s for domain %s is good.\n",
                        keystr, domain->name ));
                return false;
@@ -864,8 +854,8 @@ static void centry_put_hash16(struct cache_entry *centry, const uint8_t val[16])
 
 static void centry_put_sid(struct cache_entry *centry, const struct dom_sid *sid)
 {
-       fstring sid_string;
-       centry_put_string(centry, sid_to_fstring(sid_string, sid));
+       struct dom_sid_buf sid_string;
+       centry_put_string(centry, dom_sid_str_buf(sid, &sid_string));
 }
 
 
@@ -956,59 +946,40 @@ static void wcache_save_name_to_sid(struct winbindd_domain *domain,
                                    const char *name, const struct dom_sid *sid,
                                    enum lsa_SidType type)
 {
-       struct cache_entry *centry;
-       fstring uname;
-
-       centry = centry_start(domain, status);
-       if (!centry)
-               return;
+       bool ok;
 
-       if ((domain_name == NULL) || (domain_name[0] == '\0')) {
-               struct winbindd_domain *mydomain =
-                       find_domain_from_sid_noinit(sid);
-               if (mydomain != NULL) {
-                       domain_name = mydomain->name;
-               }
+       ok = namemap_cache_set_name2sid(domain_name, name, sid, type,
+                                       time(NULL) + lp_winbind_cache_time());
+       if (!ok) {
+               DBG_DEBUG("namemap_cache_set_name2sid failed\n");
        }
 
-       centry_put_uint32(centry, type);
-       centry_put_sid(centry, sid);
-       fstrcpy(uname, name);
-       (void)strupper_m(uname);
-       centry_end(centry, "NS/%s/%s", domain_name, uname);
-       DEBUG(10,("wcache_save_name_to_sid: %s\\%s -> %s (%s)\n", domain_name,
-                 uname, sid_string_dbg(sid), nt_errstr(status)));
-       centry_free(centry);
+       /*
+        * Don't store the reverse mapping. The name came from user
+        * input, and we might not have the correct capitalization,
+        * which is important for nsswitch.
+        */
 }
 
 static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS status, 
                                    const struct dom_sid *sid, const char *domain_name, const char *name, enum lsa_SidType type)
 {
-       struct cache_entry *centry;
-       fstring sid_string;
-
-       centry = centry_start(domain, status);
-       if (!centry)
-               return;
+       bool ok;
 
-       if ((domain_name == NULL) || (domain_name[0] == '\0')) {
-               struct winbindd_domain *mydomain =
-                       find_domain_from_sid_noinit(sid);
-               if (mydomain != NULL) {
-                       domain_name = mydomain->name;
-               }
+       ok = namemap_cache_set_sid2name(sid, domain_name, name, type,
+                                       time(NULL) + lp_winbind_cache_time());
+       if (!ok) {
+               DBG_DEBUG("namemap_cache_set_sid2name failed\n");
        }
 
-       if (NT_STATUS_IS_OK(status)) {
-               centry_put_uint32(centry, type);
-               centry_put_string(centry, domain_name);
-               centry_put_string(centry, name);
+       if (type != SID_NAME_UNKNOWN) {
+               ok = namemap_cache_set_name2sid(
+                       domain_name, name, sid, type,
+                       time(NULL) + lp_winbind_cache_time());
+               if (!ok) {
+                       DBG_DEBUG("namemap_cache_set_name2sid failed\n");
+               }
        }
-
-       centry_end(centry, "SN/%s", sid_to_fstring(sid_string, sid));
-       DEBUG(10,("wcache_save_sid_to_name: %s -> %s\\%s (%s)\n", sid_string,
-                 domain_name, name, nt_errstr(status)));
-       centry_free(centry);
 }
 
 static void wcache_save_lockout_policy(struct winbindd_domain *domain,
@@ -1152,7 +1123,7 @@ do_query:
 
        /* If its not in cache and we are offline, then fail */
 
-       if ( get_global_winbindd_state_offline() || !domain->online ) {
+       if (is_domain_offline(domain)) {
                DEBUG(8,("resolve_username_to_alias: rejecting query "
                         "in offline mode\n"));
                return NT_STATUS_NOT_FOUND;
@@ -1232,7 +1203,7 @@ do_query:
 
        /* If its not in cache and we are offline, then fail */
 
-       if ( get_global_winbindd_state_offline() || !domain->online ) {
+       if (is_domain_offline(domain)) {
                DEBUG(8,("resolve_alias_to_username: rejecting query "
                         "in offline mode\n"));
                return NT_STATUS_NOT_FOUND;
@@ -1269,8 +1240,9 @@ do_query:
 NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const struct dom_sid *sid)
 {
        struct winbind_cache *cache = get_cache(domain);
-       TDB_DATA data;
-       fstring key_str, tmp;
+       int ret;
+       struct dom_sid_buf tmp;
+       fstring key_str;
        uint32_t rid;
 
        if (!cache->tdb) {
@@ -1285,14 +1257,13 @@ NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const struct
                return NT_STATUS_INVALID_SID;
        }
 
-       fstr_sprintf(key_str, "CRED/%s", sid_to_fstring(tmp, sid));
+       fstr_sprintf(key_str, "CRED/%s", dom_sid_str_buf(sid, &tmp));
 
-       data = tdb_fetch(cache->tdb, string_tdb_data(key_str));
-       if (!data.dptr) {
+       ret = tdb_exists(cache->tdb, string_tdb_data(key_str));
+       if (ret != 1) {
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
-       SAFE_FREE(data.dptr);
        return NT_STATUS_OK;
 }
 
@@ -1309,7 +1280,7 @@ NTSTATUS wcache_get_creds(struct winbindd_domain *domain,
        struct cache_entry *centry = NULL;
        NTSTATUS status;
        uint32_t rid;
-       fstring tmp;
+       struct dom_sid_buf sidstr;
 
        if (!cache->tdb) {
                return NT_STATUS_INTERNAL_DB_ERROR;
@@ -1327,10 +1298,10 @@ NTSTATUS wcache_get_creds(struct winbindd_domain *domain,
           fall back to an unsalted cred. */
 
        centry = wcache_fetch(cache, domain, "CRED/%s",
-                             sid_to_fstring(tmp, sid));
+                             dom_sid_str_buf(sid, &sidstr));
        if (!centry) {
                DEBUG(10,("wcache_get_creds: entry for [CRED/%s] not found\n", 
-                         sid_string_dbg(sid)));
+                         dom_sid_str_buf(sid, &sidstr)));
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
@@ -1348,15 +1319,14 @@ NTSTATUS wcache_get_creds(struct winbindd_domain *domain,
 
        *cached_nt_pass = (const uint8_t *)centry_hash16(centry, mem_ctx);
        if (*cached_nt_pass == NULL) {
-               fstring sidstr;
 
-               sid_to_fstring(sidstr, sid);
+               dom_sid_str_buf(sid, &sidstr);
 
                /* Bad (old) cred cache. Delete and pretend we
                   don't have it. */
                DEBUG(0,("wcache_get_creds: bad entry for [CRED/%s] - deleting\n", 
-                               sidstr));
-               wcache_delete("CRED/%s", sidstr);
+                               sidstr.buf));
+               wcache_delete("CRED/%s", sidstr.buf);
                centry_free(centry);
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
@@ -1376,7 +1346,8 @@ NTSTATUS wcache_get_creds(struct winbindd_domain *domain,
        status = centry->status;
 
        DEBUG(10,("wcache_get_creds: [Cached] - cached creds for user %s status: %s\n",
-                 sid_string_dbg(sid), nt_errstr(status) ));
+                 dom_sid_str_buf(sid, &sidstr),
+                 nt_errstr(status) ));
 
        centry_free(centry);
        return status;
@@ -1389,7 +1360,7 @@ NTSTATUS wcache_save_creds(struct winbindd_domain *domain,
                           const uint8_t nt_pass[NT_HASH_LEN])
 {
        struct cache_entry *centry;
-       fstring sid_string;
+       struct dom_sid_buf sid_str;
        uint32_t rid;
        uint8_t cred_salt[NT_HASH_LEN];
        uint8_t salted_hash[NT_HASH_LEN];
@@ -1417,9 +1388,9 @@ NTSTATUS wcache_save_creds(struct winbindd_domain *domain,
 
        centry_put_hash16(centry, salted_hash);
        centry_put_hash16(centry, cred_salt);
-       centry_end(centry, "CRED/%s", sid_to_fstring(sid_string, sid));
+       centry_end(centry, "CRED/%s", dom_sid_str_buf(sid, &sid_str));
 
-       DEBUG(10,("wcache_save_creds: %s\n", sid_string));
+       DEBUG(10,("wcache_save_creds: %s\n", sid_str.buf));
 
        centry_free(centry);
 
@@ -1595,8 +1566,8 @@ do_fetch_cache:
                smb_panic_fn("enum_dom_groups out of memory");
        }
        for (i=0; i<(*num_entries); i++) {
-               fstrcpy((*info)[i].acct_name, centry_string(centry, mem_ctx));
-               fstrcpy((*info)[i].acct_desc, centry_string(centry, mem_ctx));
+               (*info)[i].acct_name = centry_string(centry, (*info));
+               (*info)[i].acct_desc = centry_string(centry, (*info));
                (*info)[i].rid = centry_uint32(centry);
        }
 
@@ -1690,8 +1661,8 @@ do_fetch_cache:
                smb_panic_fn("enum_dom_groups out of memory");
        }
        for (i=0; i<(*num_entries); i++) {
-               fstrcpy((*info)[i].acct_name, centry_string(centry, mem_ctx));
-               fstrcpy((*info)[i].acct_desc, centry_string(centry, mem_ctx));
+               (*info)[i].acct_name = centry_string(centry, (*info));
+               (*info)[i].acct_desc = centry_string(centry, (*info));
                (*info)[i].rid = centry_uint32(centry);
        }
 
@@ -1764,47 +1735,52 @@ skip_save:
        return status;
 }
 
+struct wcache_name_to_sid_state {
+       struct dom_sid *sid;
+       enum lsa_SidType *type;
+       bool offline;
+       bool found;
+};
+
+static void wcache_name_to_sid_fn(const struct dom_sid *sid,
+                                 enum lsa_SidType type,
+                                 bool expired,
+                                 void *private_data)
+{
+       struct wcache_name_to_sid_state *state = private_data;
+
+       *state->sid = *sid;
+       *state->type = type;
+       state->found = (!expired || state->offline);
+}
+
 static NTSTATUS wcache_name_to_sid(struct winbindd_domain *domain,
                                   const char *domain_name,
                                   const char *name,
                                   struct dom_sid *sid,
                                   enum lsa_SidType *type)
 {
-       struct winbind_cache *cache = get_cache(domain);
-       struct cache_entry *centry;
-       NTSTATUS status;
-       char *uname;
+       struct wcache_name_to_sid_state state = {
+               .sid = sid, .type = type, .found = false,
+               .offline = is_domain_offline(domain),
+       };
+       bool ok;
 
-       if (cache->tdb == NULL) {
+       ok = namemap_cache_find_name(domain_name, name, wcache_name_to_sid_fn,
+                                    &state);
+       if (!ok) {
+               DBG_DEBUG("namemap_cache_find_name failed\n");
                return NT_STATUS_NOT_FOUND;
        }
-
-       uname = talloc_strdup_upper(talloc_tos(), name);
-       if (uname == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if ((domain_name == NULL) || (domain_name[0] == '\0')) {
-               domain_name = domain->name;
-       }
-
-       centry = wcache_fetch(cache, domain, "NS/%s/%s", domain_name, uname);
-       TALLOC_FREE(uname);
-       if (centry == NULL) {
+       if (!state.found) {
+               DBG_DEBUG("cache entry not found\n");
                return NT_STATUS_NOT_FOUND;
        }
-
-       status = centry->status;
-       if (NT_STATUS_IS_OK(status)) {
-               *type = (enum lsa_SidType)centry_uint32(centry);
-               centry_sid(centry, sid);
+       if (*type == SID_NAME_UNKNOWN) {
+               return NT_STATUS_NONE_MAPPED;
        }
 
-       DEBUG(10,("name_to_sid: [Cached] - cached name for domain %s status: "
-                 "%s\n", domain->name, nt_errstr(status) ));
-
-       centry_free(centry);
-       return status;
+       return NT_STATUS_OK;
 }
 
 /* convert a single name to a sid in a domain */
@@ -1818,6 +1794,7 @@ NTSTATUS wb_cache_name_to_sid(struct winbindd_domain *domain,
 {
        NTSTATUS status;
        bool old_status;
+       const char *dom_name;
 
        old_status = domain->online;
 
@@ -1842,8 +1819,9 @@ NTSTATUS wb_cache_name_to_sid(struct winbindd_domain *domain,
        DEBUG(10,("name_to_sid: [Cached] - doing backend query for name for domain %s\n",
                domain->name ));
 
+       winbindd_domain_init_backend(domain);
        status = domain->backend->name_to_sid(domain, mem_ctx, domain_name,
-                                             name, flags, sid, type);
+                                             name, flags, &dom_name, sid, type);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
                NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
@@ -1859,11 +1837,17 @@ NTSTATUS wb_cache_name_to_sid(struct winbindd_domain *domain,
                }
        }
        /* and save it */
-       refresh_sequence_number(domain);
 
        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);
+               enum lsa_SidType save_type = *type;
+
+               if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
+                       save_type = SID_NAME_UNKNOWN;
+               }
+
+               wcache_save_name_to_sid(domain, status, domain_name, name, sid,
+                                       save_type);
 
                /* Only save the reverse mapping if this was not a UPN */
                if (!strchr(name, '@')) {
@@ -1871,13 +1855,43 @@ NTSTATUS wb_cache_name_to_sid(struct winbindd_domain *domain,
                                return NT_STATUS_INVALID_PARAMETER;
                        }
                        (void)strlower_m(discard_const_p(char, name));
-                       wcache_save_sid_to_name(domain, status, sid, domain_name, name, *type);
+                       wcache_save_sid_to_name(domain, status, sid,
+                                               dom_name, name, save_type);
                }
        }
 
        return status;
 }
 
+struct wcache_sid_to_name_state {
+       TALLOC_CTX *mem_ctx;
+       char **domain_name;
+       char **name;
+       enum lsa_SidType *type;
+       bool offline;
+       bool found;
+};
+
+static void wcache_sid_to_name_fn(const char *domain,
+                                 const char *name,
+                                 enum lsa_SidType type,
+                                 bool expired,
+                                 void *private_data)
+{
+       struct wcache_sid_to_name_state *state = private_data;
+
+       *state->domain_name = talloc_strdup(state->mem_ctx, domain);
+       if (*state->domain_name == NULL) {
+               return;
+       }
+       *state->name = talloc_strdup(state->mem_ctx, name);
+       if (*state->name == NULL) {
+               return;
+       }
+       *state->type = type;
+       state->found = (!expired || state->offline);
+}
+
 static NTSTATUS wcache_sid_to_name(struct winbindd_domain *domain,
                                   const struct dom_sid *sid,
                                   TALLOC_CTX *mem_ctx,
@@ -1885,39 +1899,27 @@ static NTSTATUS wcache_sid_to_name(struct winbindd_domain *domain,
                                   char **name,
                                   enum lsa_SidType *type)
 {
-       struct winbind_cache *cache = get_cache(domain);
-       struct cache_entry *centry;
-       char *sid_string;
-       NTSTATUS status;
+       struct wcache_sid_to_name_state state = {
+               .mem_ctx = mem_ctx, .found = false,
+               .domain_name = domain_name, .name = name, .type = type,
+               .offline = is_domain_offline(domain)
+       };
+       bool ok;
 
-       if (cache->tdb == NULL) {
+       ok = namemap_cache_find_sid(sid, wcache_sid_to_name_fn, &state);
+       if (!ok) {
+               DBG_DEBUG("namemap_cache_find_name failed\n");
                return NT_STATUS_NOT_FOUND;
        }
-
-       sid_string = sid_string_tos(sid);
-       if (sid_string == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       centry = wcache_fetch(cache, domain, "SN/%s", sid_string);
-       TALLOC_FREE(sid_string);
-       if (centry == NULL) {
+       if (!state.found) {
+               DBG_DEBUG("cache entry not found\n");
                return NT_STATUS_NOT_FOUND;
        }
-
-       if (NT_STATUS_IS_OK(centry->status)) {
-               *type = (enum lsa_SidType)centry_uint32(centry);
-               *domain_name = centry_string(centry, mem_ctx);
-               *name = centry_string(centry, mem_ctx);
+       if (*type == SID_NAME_UNKNOWN) {
+               return NT_STATUS_NONE_MAPPED;
        }
 
-       status = centry->status;
-       centry_free(centry);
-
-       DEBUG(10,("sid_to_name: [Cached] - cached name for domain %s status: "
-                 "%s\n", domain->name, nt_errstr(status) ));
-
-       return status;
+       return NT_STATUS_OK;
 }
 
 /* convert a sid to a user or group name. The sid is guaranteed to be in the domain
@@ -1956,6 +1958,8 @@ NTSTATUS wb_cache_sid_to_name(struct winbindd_domain *domain,
        DEBUG(10,("sid_to_name: [Cached] - doing backend query for name for domain %s\n",
                domain->name ));
 
+       winbindd_domain_init_backend(domain);
+
        status = domain->backend->sid_to_name(domain, mem_ctx, sid, domain_name, name, type);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
@@ -1973,7 +1977,6 @@ NTSTATUS wb_cache_sid_to_name(struct winbindd_domain *domain,
                }
        }
        /* and save it */
-       refresh_sequence_number(domain);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -2026,49 +2029,45 @@ NTSTATUS wb_cache_rids_to_names(struct winbindd_domain *domain,
 
        for (i=0; i<num_rids; i++) {
                struct dom_sid sid;
-               struct cache_entry *centry;
-               fstring tmp;
+               NTSTATUS status;
+               enum lsa_SidType type;
+               char *dom, *name;
 
                if (!sid_compose(&sid, domain_sid, rids[i])) {
                        result = NT_STATUS_INTERNAL_ERROR;
                        goto error;
                }
 
-               centry = wcache_fetch(cache, domain, "SN/%s",
-                                     sid_to_fstring(tmp, &sid));
-               if (!centry) {
-                       goto do_query;
-               }
+               status = wcache_sid_to_name(domain, &sid, *names, &dom,
+                                           &name, &type);
 
                (*types)[i] = SID_NAME_UNKNOWN;
                (*names)[i] = talloc_strdup(*names, "");
 
-               if (NT_STATUS_IS_OK(centry->status)) {
-                       char *dom;
+               if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+                       /* not cached */
+                       goto do_query;
+               }
+
+               if (NT_STATUS_IS_OK(status)) {
                        have_mapped = true;
-                       (*types)[i] = (enum lsa_SidType)centry_uint32(centry);
+                       (*types)[i] = type;
 
-                       dom = centry_string(centry, mem_ctx);
                        if (*domain_name == NULL) {
                                *domain_name = dom;
                        } else {
-                               talloc_free(dom);
+                               TALLOC_FREE(dom);
                        }
 
-                       (*names)[i] = centry_string(centry, *names);
+                       (*names)[i] = name;
 
-               } else if (NT_STATUS_EQUAL(centry->status, NT_STATUS_NONE_MAPPED)
-                          || NT_STATUS_EQUAL(centry->status, STATUS_SOME_UNMAPPED)) {
+               } else if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
                        have_unmapped = true;
-
                } else {
                        /* something's definitely wrong */
-                       result = centry->status;
-                       centry_free(centry);
+                       result = status;
                        goto error;
                }
-
-               centry_free(centry);
        }
 
        if (!have_mapped) {
@@ -2114,50 +2113,43 @@ NTSTATUS wb_cache_rids_to_names(struct winbindd_domain *domain,
 
                        for (i=0; i<num_rids; i++) {
                                struct dom_sid sid;
-                               struct cache_entry *centry;
-                               fstring tmp;
+                               NTSTATUS status;
+                               enum lsa_SidType type;
+                               char *dom, *name;
 
                                if (!sid_compose(&sid, domain_sid, rids[i])) {
                                        result = NT_STATUS_INTERNAL_ERROR;
                                        goto error;
                                }
 
-                               centry = wcache_fetch(cache, domain, "SN/%s",
-                                                     sid_to_fstring(tmp, &sid));
-                               if (!centry) {
-                                       (*types)[i] = SID_NAME_UNKNOWN;
-                                       (*names)[i] = talloc_strdup(*names, "");
-                                       continue;
-                               }
+                               status = wcache_sid_to_name(domain, &sid,
+                                                           *names, &dom,
+                                                           &name, &type);
 
                                (*types)[i] = SID_NAME_UNKNOWN;
                                (*names)[i] = talloc_strdup(*names, "");
 
-                               if (NT_STATUS_IS_OK(centry->status)) {
-                                       char *dom;
+                               if (NT_STATUS_IS_OK(status)) {
                                        have_mapped = true;
-                                       (*types)[i] = (enum lsa_SidType)centry_uint32(centry);
+                                       (*types)[i] = type;
 
-                                       dom = centry_string(centry, mem_ctx);
                                        if (*domain_name == NULL) {
                                                *domain_name = dom;
                                        } else {
-                                               talloc_free(dom);
+                                               TALLOC_FREE(dom);
                                        }
 
-                                       (*names)[i] = centry_string(centry, *names);
+                                       (*names)[i] = name;
 
-                               } else if (NT_STATUS_EQUAL(centry->status, NT_STATUS_NONE_MAPPED)) {
+                               } else if (NT_STATUS_EQUAL(
+                                                  status,
+                                                  NT_STATUS_NONE_MAPPED)) {
                                        have_unmapped = true;
-
                                } else {
                                        /* something's definitely wrong */
-                                       result = centry->status;
-                                       centry_free(centry);
+                                       result = status;
                                        goto error;
                                }
-
-                               centry_free(centry);
                        }
 
                        if (!have_mapped) {
@@ -2224,27 +2216,22 @@ NTSTATUS wb_cache_rids_to_names(struct winbindd_domain *domain,
        return result;
 }
 
-NTSTATUS wcache_query_user(struct winbindd_domain *domain,
-                          TALLOC_CTX *mem_ctx,
-                          const struct dom_sid *user_sid,
-                          struct wbint_userinfo *info)
+static NTSTATUS wcache_query_user(struct winbindd_domain *domain,
+                                 TALLOC_CTX *mem_ctx,
+                                 const struct dom_sid *user_sid,
+                                 struct wbint_userinfo *info)
 {
        struct winbind_cache *cache = get_cache(domain);
        struct cache_entry *centry = NULL;
        NTSTATUS status;
-       char *sid_string;
+       struct dom_sid_buf sid_string;
 
        if (cache->tdb == NULL) {
                return NT_STATUS_NOT_FOUND;
        }
 
-       sid_string = sid_string_tos(user_sid);
-       if (sid_string == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       centry = wcache_fetch(cache, domain, "U/%s", sid_string);
-       TALLOC_FREE(sid_string);
+       centry = wcache_fetch(
+               cache, domain, "U/%s", dom_sid_str_buf(user_sid, &sid_string));
        if (centry == NULL) {
                return NT_STATUS_NOT_FOUND;
        }
@@ -2321,25 +2308,28 @@ NTSTATUS wcache_query_user_fullname(struct winbindd_domain *domain,
        return NT_STATUS_OK;
 }
 
-NTSTATUS wcache_lookup_usergroups(struct winbindd_domain *domain,
-                                 TALLOC_CTX *mem_ctx,
-                                 const struct dom_sid *user_sid,
-                                 uint32_t *pnum_sids,
-                                 struct dom_sid **psids)
+static NTSTATUS wcache_lookup_usergroups(struct winbindd_domain *domain,
+                                        TALLOC_CTX *mem_ctx,
+                                        const struct dom_sid *user_sid,
+                                        uint32_t *pnum_sids,
+                                        struct dom_sid **psids)
 {
        struct winbind_cache *cache = get_cache(domain);
        struct cache_entry *centry = NULL;
        NTSTATUS status;
        uint32_t i, num_sids;
        struct dom_sid *sids;
-       fstring sid_string;
+       struct dom_sid_buf sid_string;
 
        if (cache->tdb == NULL) {
                return NT_STATUS_NOT_FOUND;
        }
 
-       centry = wcache_fetch(cache, domain, "UG/%s",
-                             sid_to_fstring(sid_string, user_sid));
+       centry = wcache_fetch(
+               cache,
+               domain,
+               "UG/%s",
+               dom_sid_str_buf(user_sid, &sid_string));
        if (centry == NULL) {
                return NT_STATUS_NOT_FOUND;
        }
@@ -2390,7 +2380,7 @@ NTSTATUS wb_cache_lookup_usergroups(struct winbindd_domain *domain,
        struct cache_entry *centry = NULL;
        NTSTATUS status;
        unsigned int i;
-       fstring sid_string;
+       struct dom_sid_buf sid_string;
        bool old_status;
 
        old_status = domain->online;
@@ -2444,7 +2434,7 @@ NTSTATUS wb_cache_lookup_usergroups(struct winbindd_domain *domain,
                centry_put_sid(centry, &(*user_gids)[i]);
        }       
 
-       centry_end(centry, "UG/%s", sid_to_fstring(sid_string, user_sid));
+       centry_end(centry, "UG/%s", dom_sid_str_buf(user_sid, &sid_string));
        centry_free(centry);
 
 skip_save:
@@ -2462,9 +2452,11 @@ static char *wcache_make_sidlist(TALLOC_CTX *mem_ctx, uint32_t num_sids,
                return NULL;
        }
        for (i=0; i<num_sids; i++) {
-               fstring tmp;
+               struct dom_sid_buf tmp;
                sidlist = talloc_asprintf_append_buffer(
-                       sidlist, "/%s", sid_to_fstring(tmp, &sids[i]));
+                       sidlist,
+                       "/%s",
+                       dom_sid_str_buf(&sids[i], &tmp));
                if (sidlist == NULL) {
                        return NULL;
                }
@@ -2615,19 +2607,17 @@ static NTSTATUS wcache_lookup_groupmem(struct winbindd_domain *domain,
        struct cache_entry *centry = NULL;
        NTSTATUS status;
        unsigned int i;
-       char *sid_string;
+       struct dom_sid_buf sid_string;
 
        if (cache->tdb == NULL) {
                return NT_STATUS_NOT_FOUND;
        }
 
-       sid_string = sid_string_tos(group_sid);
-       if (sid_string == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       centry = wcache_fetch(cache, domain, "GM/%s", sid_string);
-       TALLOC_FREE(sid_string);
+       centry = wcache_fetch(
+               cache,
+               domain,
+               "GM/%s",
+               dom_sid_str_buf(group_sid, &sid_string));
        if (centry == NULL) {
                return NT_STATUS_NOT_FOUND;
        }
@@ -2681,7 +2671,7 @@ NTSTATUS wb_cache_lookup_groupmem(struct winbindd_domain *domain,
        struct cache_entry *centry = NULL;
        NTSTATUS status;
        unsigned int i;
-       fstring sid_string;
+       struct dom_sid_buf sid_string;
        bool old_status;
 
        old_status = domain->online;
@@ -2737,7 +2727,9 @@ NTSTATUS wb_cache_lookup_groupmem(struct winbindd_domain *domain,
                centry_put_string(centry, (*names)[i]);
                centry_put_uint32(centry, (*name_types)[i]);
        }       
-       centry_end(centry, "GM/%s", sid_to_fstring(sid_string, group_sid));
+       centry_end(centry,
+                  "GM/%s",
+                  dom_sid_str_buf(group_sid, &sid_string));
        centry_free(centry);
 
 skip_save:
@@ -3025,7 +3017,8 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
 void wcache_invalidate_samlogon(struct winbindd_domain *domain, 
                                const struct dom_sid *sid)
 {
-        fstring key_str, sid_string;
+        fstring key_str;
+       struct dom_sid_buf sid_string;
        struct winbind_cache *cache;
 
        /* don't clear cached U/SID and UG/SID entries when we want to logon
@@ -3045,12 +3038,12 @@ void wcache_invalidate_samlogon(struct winbindd_domain *domain,
         }
 
        /* Clear U/SID cache entry */
-       fstr_sprintf(key_str, "U/%s", sid_to_fstring(sid_string, sid));
+       fstr_sprintf(key_str, "U/%s", dom_sid_str_buf(sid, &sid_string));
        DEBUG(10, ("wcache_invalidate_samlogon: clearing %s\n", key_str));
        tdb_delete(cache->tdb, string_tdb_data(key_str));
 
        /* Clear UG/SID cache entry */
-       fstr_sprintf(key_str, "UG/%s", sid_to_fstring(sid_string, sid));
+       fstr_sprintf(key_str, "UG/%s", dom_sid_str_buf(sid, &sid_string));
        DEBUG(10, ("wcache_invalidate_samlogon: clearing %s\n", key_str));
        tdb_delete(cache->tdb, string_tdb_data(key_str));
 
@@ -3111,7 +3104,7 @@ bool wcache_invalidate_cache_noinit(void)
        return true;
 }
 
-bool init_wcache(void)
+static bool init_wcache(void)
 {
        char *db_path;
 
@@ -3234,7 +3227,8 @@ bool lookup_cached_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
        return NT_STATUS_IS_OK(status);
 }
 
-bool lookup_cached_name(const char *domain_name,
+bool lookup_cached_name(const char *namespace,
+                       const char *domain_name,
                        const char *name,
                        struct dom_sid *sid,
                        enum lsa_SidType *type)
@@ -3243,7 +3237,7 @@ bool lookup_cached_name(const char *domain_name,
        NTSTATUS status;
        bool original_online_state;
 
-       domain = find_lookup_domain_from_name(domain_name);
+       domain = find_lookup_domain_from_name(namespace);
        if (domain == NULL) {
                return false;
        }
@@ -3433,11 +3427,12 @@ NTSTATUS wcache_remove_oldest_cached_creds(struct winbindd_domain *domain, const
        /* we possibly already have an entry */
        if (sid && NT_STATUS_IS_OK(wcache_cached_creds_exist(domain, sid))) {
 
-               fstring key_str, tmp;
+               fstring key_str;
+               struct dom_sid_buf tmp;
 
                DEBUG(11,("we already have an entry, deleting that\n"));
 
-               fstr_sprintf(key_str, "CRED/%s", sid_to_fstring(tmp, sid));
+               fstr_sprintf(key_str, "CRED/%s", dom_sid_str_buf(sid, &tmp));
 
                tdb_delete(cache->tdb, string_tdb_data(key_str));
 
@@ -3616,52 +3611,6 @@ static int validate_seqnum(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbu
        return 0;
 }
 
-static int validate_ns(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
-                      struct tdb_validation_status *state)
-{
-       struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
-       if (!centry) {
-               return 1;
-       }
-
-       (void)centry_uint32(centry);
-       if (NT_STATUS_IS_OK(centry->status)) {
-               struct dom_sid sid;
-               (void)centry_sid(centry, &sid);
-       }
-
-       centry_free(centry);
-
-       if (!(state->success)) {
-               return 1;
-       }
-       DEBUG(10,("validate_ns: %s ok\n", keystr));
-       return 0;
-}
-
-static int validate_sn(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
-                      struct tdb_validation_status *state)
-{
-       struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
-       if (!centry) {
-               return 1;
-       }
-
-       if (NT_STATUS_IS_OK(centry->status)) {
-               (void)centry_uint32(centry);
-               (void)centry_string(centry, mem_ctx);
-               (void)centry_string(centry, mem_ctx);
-       }
-
-       centry_free(centry);
-
-       if (!(state->success)) {
-               return 1;
-       }
-       DEBUG(10,("validate_sn: %s ok\n", keystr));
-       return 0;
-}
-
 static int validate_u(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
                      struct tdb_validation_status *state)
 {
@@ -4036,8 +3985,6 @@ struct key_val_struct {
        int (*validate_data_fn)(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf, struct tdb_validation_status* state);
 } key_val[] = {
        {"SEQNUM/", validate_seqnum},
-       {"NS/", validate_ns},
-       {"SN/", validate_sn},
        {"U/", validate_u},
        {"LOC_POL/", validate_loc_pol},
        {"PWD_POL/", validate_pwd_pol},
@@ -4442,7 +4389,7 @@ static int pack_tdc_domains( struct winbindd_tdc_domain *domains,
        /* now pack each domain trust record */
        for ( i=0; i<num_domains; i++ ) {
 
-               fstring tmp;
+               struct dom_sid_buf tmp;
 
                if ( buflen > 0 ) {
                        DEBUG(10,("pack_tdc_domains: Packing domain %s (%s)\n",
@@ -4453,7 +4400,7 @@ static int pack_tdc_domains( struct winbindd_tdc_domain *domains,
                len += tdb_pack( buffer+len, buflen-len, "fffddd",
                                 domains[i].domain_name,
                                 domains[i].dns_name ? domains[i].dns_name : "",
-                                sid_to_fstring(tmp, &domains[i].sid),
+                                dom_sid_str_buf(&domains[i].sid, &tmp),
                                 domains[i].trust_flags,
                                 domains[i].trust_attribs,
                                 domains[i].trust_type );
@@ -4618,11 +4565,12 @@ bool wcache_tdc_add_domain( struct winbindd_domain *domain )
        struct winbindd_tdc_domain *dom_list = NULL;
        size_t num_domains = 0;
        bool ret = false;
+       struct dom_sid_buf buf;
 
        DEBUG(10,("wcache_tdc_add_domain: Adding domain %s (%s), SID %s, "
                  "flags = 0x%x, attributes = 0x%x, type = 0x%x\n",
                  domain->name, domain->alt_name, 
-                 sid_string_dbg(&domain->sid),
+                 dom_sid_str_buf(&domain->sid, &buf),
                  domain->domain_flags,
                  domain->domain_trust_attribs,
                  domain->domain_type));        
@@ -4806,7 +4754,7 @@ bool wcache_fetch_ndr(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
                goto fail;
        }
 
-       if (!is_domain_offline(domain)) {
+       if (is_domain_online(domain)) {
                uint32_t entry_seqnum, dom_seqnum, last_check;
                uint64_t entry_timeout;
 
@@ -4821,7 +4769,7 @@ bool wcache_fetch_ndr(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
                        goto fail;
                }
                entry_timeout = BVAL(data.dptr, 4);
-               if (time(NULL) > entry_timeout) {
+               if (time(NULL) > (time_t)entry_timeout) {
                        DEBUG(10, ("Entry has timed out\n"));
                        goto fail;
                }