added name_to_sid to the backend
authorAndrew Tridgell <tridge@samba.org>
Mon, 3 Dec 2001 08:17:46 +0000 (08:17 +0000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 3 Dec 2001 08:17:46 +0000 (08:17 +0000)
(This used to be commit 816e40a51af80a7f703c0451304de406deab3dd8)

source3/nsswitch/wb_client.c
source3/nsswitch/winbindd.h
source3/nsswitch/winbindd_ads.c
source3/nsswitch/winbindd_cache.c
source3/nsswitch/winbindd_group.c
source3/nsswitch/winbindd_proto.h
source3/nsswitch/winbindd_rpc.c
source3/nsswitch/winbindd_sid.c
source3/nsswitch/winbindd_user.c
source3/nsswitch/winbindd_util.c

index 92fdd62b15aef221df3b72592f61a0e67ddd0f3c..cfb90e24979b24b115a8b50a561e2f347ad8b978 100644 (file)
@@ -32,7 +32,7 @@ NSS_STATUS winbindd_request(int req_type,
 /* Copy of parse_domain_user from winbindd_util.c.  Parse a string of the
    form DOMAIN/user into a domain and a user */
 
-static void parse_domain_user(char *domuser, fstring domain, fstring user)
+static void parse_domain_user(const char *domuser, fstring domain, fstring user)
 {
         char *p = strchr(domuser,*lp_winbind_separator());
 
index 9de23b986d044b1c0545e91b227b282e55d1b33a..12567367634747de5be1d59dc05f6f64cafe99f8 100644 (file)
@@ -98,6 +98,11 @@ struct winbindd_methods {
                                    TALLOC_CTX *mem_ctx,
                                    uint32 *start_ndx, uint32 *num_entries, 
                                    struct acct_info **info);
+
+       NTSTATUS (*name_to_sid)(struct winbindd_domain *domain,
+                               const char *name,
+                               DOM_SID *sid,
+                               enum SID_NAME_USE *type);
 };
 
 /* Structures to hold per domain information */
index c728f9659c504c183f87c2fa07b512456d57fb88..d54f1d939109471f018f1f0b2f0f25048d137daf 100644 (file)
@@ -170,7 +170,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
 
                if (!ads_pull_uint32(ads, msg, "sAMAccountType", 
                                     &account_type) ||
-                   !(account_type & ATYPE_NORMAL_GROUP)) continue;
+                   !(account_type & ATYPE_GROUP)) continue;
 
                name = ads_pull_string(ads, mem_ctx, msg, "sAMAccountName");
                gecos = ads_pull_string(ads, mem_ctx, msg, "name");
@@ -198,10 +198,84 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
 }
 
 
+/* convert a single name to a sid in a domain */
+static NTSTATUS name_to_sid(struct winbindd_domain *domain,
+                           const char *name,
+                           DOM_SID *sid,
+                           enum SID_NAME_USE *type)
+{
+       ADS_STRUCT *ads;
+       const char *attrs[] = {"objectSid", "sAMAccountType", NULL};
+       int rc, count;
+       void *res;
+       char *exp;
+       uint32 t;
+       fstring name2, dom2;
+       
+       /* sigh. Need to fix interface to give us a raw name */
+       parse_domain_user(name, dom2, name2);
+
+       DEBUG(3,("ads: name_to_sid\n"));
+
+       ads = ads_init(NULL, NULL, NULL);
+       if (!ads) {
+               DEBUG(1,("ads_init failed\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       rc = ads_connect(ads);
+       if (rc) {
+               DEBUG(1,("name_to_sid ads_connect: %s\n", ads_errstr(rc)));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       asprintf(&exp, "(sAMAccountName=%s)", name2);
+       rc = ads_search(ads, &res, exp, attrs);
+       free(exp);
+       if (rc) {
+               DEBUG(1,("name_to_sid ads_search: %s\n", ads_errstr(rc)));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       count = ads_count_replies(ads, res);
+       if (count != 1) {
+               DEBUG(1,("name_to_sid: %s not found\n", name));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       if (!ads_pull_sid(ads, res, "objectSid", sid)) {
+               DEBUG(1,("No sid for %s !?\n", name));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       if (!ads_pull_uint32(ads, res, "sAMAccountType", &t)) {
+               DEBUG(1,("No sAMAccountType for %s !?\n", name));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       switch (t & 0xF0000000) {
+       case ATYPE_GROUP:
+               *type = SID_NAME_DOM_GRP;
+               break;
+       case ATYPE_USER:
+               *type = SID_NAME_USER;
+               break;
+       default:
+               DEBUG(1,("hmm, need to map account type 0x%x\n", t));
+               *type = SID_NAME_UNKNOWN;
+               break;
+       }
+
+       ads_destroy(&ads);
+
+       return NT_STATUS_OK;
+}
+
 /* the rpc backend methods are exposed via this structure */
 struct winbindd_methods ads_methods = {
        query_dispinfo,
-       enum_dom_groups
+       enum_dom_groups,
+       name_to_sid
 };
 
 #endif
index 8ad5bc2e7d8237fda6d784f553677811bc4c16fa..24a2118fb1f0bcd1c58a0d66d6dc1af8bf344411 100644 (file)
@@ -150,7 +150,7 @@ static BOOL cache_domain_expired(struct winbindd_domain *domain,
 }
 
 static void set_cache_sequence_number(struct winbindd_domain *domain, 
-                                      char *cache_type, char *subkey)
+                                      const char *cache_type, const char *subkey)
 {
        fstring keystr;
 
@@ -161,7 +161,7 @@ static void set_cache_sequence_number(struct winbindd_domain *domain,
 }
 
 static uint32 get_cache_sequence_number(struct winbindd_domain *domain, 
-                                        char *cache_type, char *subkey)
+                                        const char *cache_type, const char *subkey)
 {
        fstring keystr;
        uint32 seq_num;
@@ -178,7 +178,7 @@ static uint32 get_cache_sequence_number(struct winbindd_domain *domain,
 
 /* Fill the user or group cache with supplied data */
 
-static void store_cache(struct winbindd_domain *domain, char *cache_type,
+static void store_cache(struct winbindd_domain *domain, const char *cache_type,
                        void *sam_entries, int buflen)
 {
        fstring keystr;
@@ -229,8 +229,8 @@ void winbindd_store_group_cache(struct winbindd_domain *domain,
                    num_sam_entries * sizeof(struct acct_info));
 }
 
-static void store_cache_entry(struct winbindd_domain *domain, char *cache_type,
-                              char *name, void *buf, int len)
+static void store_cache_entry(struct winbindd_domain *domain, const char *cache_type,
+                              const char *name, void *buf, int len)
 {
        fstring keystr;
 
@@ -261,13 +261,13 @@ void winbindd_store_name_cache_entry(struct winbindd_domain *domain,
 /* Fill a SID cache entry */
 
 void winbindd_store_sid_cache_entry(struct winbindd_domain *domain, 
-                                     char *name, struct winbindd_sid *sid)
+                                   const char *name, struct winbindd_sid *sid)
 {
        if (lp_winbind_cache_time() == 0) 
                return;
 
        store_cache_entry(domain, CACHE_TYPE_SID, name, sid, 
-               sizeof(struct winbindd_sid));
+                         sizeof(struct winbindd_sid));
 
        set_cache_sequence_number(domain, CACHE_TYPE_SID, name);
 }
@@ -451,7 +451,8 @@ BOOL winbindd_fetch_group_cache(struct winbindd_domain *domain,
 }
 
 static BOOL fetch_cache_entry(struct winbindd_domain *domain, 
-                              char *cache_type, char *name, void *buf, int len)
+                              const char *cache_type, 
+                             const char *name, void *buf, int len)
 {
        TDB_DATA data;
        fstring keystr;
@@ -476,9 +477,8 @@ static BOOL fetch_cache_entry(struct winbindd_domain *domain,
 }
 
 /* Fetch an individual SID cache entry */
-
 BOOL winbindd_fetch_sid_cache_entry(struct winbindd_domain *domain, 
-                                     char *name, struct winbindd_sid *sid)
+                                   const char *name, struct winbindd_sid *sid)
 {
        uint32 seq_num;
 
index a183f2592679daa7baeda448fa2d1f596d8cdbd8..f71cdb7ece72f34bc21ea7d9bcf842fe71ea2055 100644 (file)
@@ -247,7 +247,7 @@ enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state *sta
 
        /* Get rid and name type from name */
         
-       if (!winbindd_lookup_sid_by_name(name, &group_sid, &name_type)) {
+       if (!winbindd_lookup_sid_by_name(domain, name, &group_sid, &name_type)) {
                DEBUG(1, ("group %s in domain %s does not exist\n", 
                          name_group, name_domain));
 
@@ -955,7 +955,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
        
        /* Get rid and name type from name.  The following costs 1 packet */
 
-       if (!winbindd_lookup_sid_by_name(name, &user_sid, &name_type)) {
+       if (!winbindd_lookup_sid_by_name(domain, name, &user_sid, &name_type)) {
                DEBUG(1, ("user '%s' does not exist\n", name_user));
                goto done;
        }
index 8c71e70dc2b7344d1561a74267e889a10670616a..923ee2450e8ac5db84b15619baddf7c95896740f 100644 (file)
@@ -7,6 +7,9 @@
 
 int main(int argc, char **argv);
 
+/* The following definitions come from nsswitch/winbindd_ads.c  */
+
+
 /* The following definitions come from nsswitch/winbindd_cache.c  */
 
 void winbindd_cache_init(void);
@@ -19,7 +22,7 @@ void winbindd_store_group_cache(struct winbindd_domain *domain,
 void winbindd_store_name_cache_entry(struct winbindd_domain *domain, 
                                      char *sid, struct winbindd_name *name);
 void winbindd_store_sid_cache_entry(struct winbindd_domain *domain, 
-                                     char *name, struct winbindd_sid *sid);
+                                   const char *name, struct winbindd_sid *sid);
 void winbindd_store_user_cache_entry(struct winbindd_domain *domain, 
                                      char *user_name, struct winbindd_pw *pw);
 void winbindd_store_uid_cache_entry(struct winbindd_domain *domain, uid_t uid, 
@@ -37,7 +40,7 @@ BOOL winbindd_fetch_group_cache(struct winbindd_domain *domain,
                                struct acct_info **sam_entries,
                                 int *num_entries);
 BOOL winbindd_fetch_sid_cache_entry(struct winbindd_domain *domain, 
-                                     char *name, struct winbindd_sid *sid);
+                                   const char *name, struct winbindd_sid *sid);
 BOOL winbindd_fetch_name_cache_entry(struct winbindd_domain *domain, 
                                      char *sid, struct winbindd_name *name);
 BOOL winbindd_fetch_user_cache_entry(struct winbindd_domain *domain, 
@@ -59,17 +62,16 @@ CLI_POLICY_HND *cm_get_lsa_handle(char *domain);
 CLI_POLICY_HND *cm_get_sam_handle(char *domain);
 CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain, DOM_SID *domain_sid);
 CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, DOM_SID *domain_sid,
-                                       uint32 user_rid);
+                                      uint32 user_rid);
 CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, DOM_SID *domain_sid,
-                                        uint32 group_rid);
+                                       uint32 group_rid);
 NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd,
-                             struct cli_state **cli);
+                            struct cli_state **cli);
 void winbindd_cm_status(void);
 
 /* The following definitions come from nsswitch/winbindd_group.c  */
 
-enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state 
-                                                 *state);
+enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state *state);
 enum winbindd_result winbindd_getgrnam_from_gid(struct winbindd_cli_state 
                                                 *state);
 enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state);
@@ -105,6 +107,9 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) ;
 enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) ;
 enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state);
 
+/* The following definitions come from nsswitch/winbindd_rpc.c  */
+
+
 /* The following definitions come from nsswitch/winbindd_sid.c  */
 
 enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state);
@@ -116,10 +121,8 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state);
 
 /* The following definitions come from nsswitch/winbindd_user.c  */
 
-enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state 
-                                                *state) ;
-enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state 
-                                                *state);
+enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state *state) ;
+enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state *state);
 enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state);
 enum winbindd_result winbindd_endpwent(struct winbindd_cli_state *state);
 enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state);
@@ -132,7 +135,8 @@ struct winbindd_domain *find_domain_from_sid(DOM_SID *sid);
 BOOL get_domain_info(void);
 void free_domain_info(void);
 BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain);
-BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid, enum SID_NAME_USE *type);
+BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain, 
+                                const char *name, DOM_SID *sid, enum SID_NAME_USE *type);
 BOOL winbindd_lookup_name_by_sid(DOM_SID *sid,
                                 fstring name,
                                 enum SID_NAME_USE *type);
@@ -151,5 +155,5 @@ BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain,
 void free_getent_state(struct getent_state *state);
 BOOL winbindd_param_init(void);
 BOOL check_domain_env(char *domain_env, char *domain);
-void parse_domain_user(char *domuser, fstring domain, fstring user);
+void parse_domain_user(const char *domuser, fstring domain, fstring user);
 #endif /* _PROTO_H_ */
index ba428c5aedfd2366b202c0698ab48f8ca124904b..fe2540f33d4c58e016de7a13e6bb6104e0b8df78 100644 (file)
@@ -121,10 +121,43 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
        return status;
 }
 
+/* convert a single name to a sid in a domain */
+static NTSTATUS name_to_sid(struct winbindd_domain *domain,
+                           const char *name,
+                           DOM_SID *sid,
+                           enum SID_NAME_USE *type)
+{
+       TALLOC_CTX *mem_ctx;
+       CLI_POLICY_HND *hnd;
+       NTSTATUS status;
+       DOM_SID *sids = NULL;
+       uint32 *types = NULL;
+       int num_sids;
+
+       if (!(mem_ctx = talloc_init()))
+               return NT_STATUS_NO_MEMORY;
+        
+       if (!(hnd = cm_get_lsa_handle(domain->name)))
+               return NT_STATUS_UNSUCCESSFUL;
+        
+       status = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol, 1, &name, 
+                                     &sids, &types, &num_sids);
+        
+       /* Return rid and type if lookup successful */        
+       if (NT_STATUS_IS_OK(status)) {
+               sid_copy(sid, &sids[0]);
+               *type = types[0];
+       }
+
+       talloc_destroy(mem_ctx);
+       return status;
+}
+
 
 /* the rpc backend methods are exposed via this structure */
 struct winbindd_methods msrpc_methods = {
        query_dispinfo,
-       enum_dom_groups
+       enum_dom_groups,
+       name_to_sid
 };
 
index bc014f26918d39a97694978c093cef51e32cf22d..07537b82fa8509a9476efdc9d3bf57183ef4172d 100644 (file)
@@ -70,7 +70,7 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state)
        enum SID_NAME_USE type;
        fstring sid_str, name_domain, name_user, name;
        DOM_SID sid;
-       
+       struct winbindd_domain *domain;
        DEBUG(3, ("[%5d]: lookupname %s\n", state->pid,
                  state->request.data.name));
 
@@ -78,9 +78,14 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state)
 
        snprintf(name, sizeof(name), "%s\\%s", name_domain, name_user);
 
-       /* Lookup name from PDC using lsa_lookup_names() */
+       if ((domain = find_domain_from_name(name_domain)) == NULL) {
+               DEBUG(0, ("could not find domain entry for domain %s\n", 
+                         name_domain));
+               return WINBINDD_ERROR;
+       }
 
-       if (!winbindd_lookup_sid_by_name(name, &sid, &type)) {
+       /* Lookup name from PDC using lsa_lookup_names() */
+       if (!winbindd_lookup_sid_by_name(domain, name, &sid, &type)) {
                return WINBINDD_ERROR;
        }
 
index 2cc64cb56504970567e84703194123c2bf2db9db..5a4dd82d78e7d3a1272a1ef7837ef88f73ec5102 100644 (file)
@@ -140,7 +140,7 @@ enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state *stat
        
        /* Get rid and name type from name */
 
-       if (!winbindd_lookup_sid_by_name(name, &user_sid, &name_type)) {
+       if (!winbindd_lookup_sid_by_name(domain, name, &user_sid, &name_type)) {
                DEBUG(1, ("user '%s' does not exist\n", name_user));
                winbindd_store_user_cache_entry(domain, name_user, &negative_pw_cache_entry);
                return WINBINDD_ERROR;
index 50cc76f1e9052fe377bfdd9c4511e3ed5119bec5..c18e0deda3e8f37842343ab03ecc15c67a39decd 100644 (file)
@@ -283,22 +283,12 @@ BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain)
 
 /* Store a SID in a domain indexed by name in the cache. */
 
-static void store_sid_by_name_in_cache(fstring name, DOM_SID *sid, enum SID_NAME_USE type)
+static void store_sid_by_name_in_cache(struct winbindd_domain *domain,
+                                      const char *name, 
+                                      DOM_SID *sid, enum SID_NAME_USE type)
 {
-       fstring domain_str;
-       char *p;
        struct winbindd_sid sid_val;
-       struct winbindd_domain *domain;
-
-       /* Get name from domain. */
-       fstrcpy( domain_str, name);
-       p = strchr(domain_str, '\\');
-       if (p)
-               *p = '\0';
-
-       if ((domain = find_domain_from_name(domain_str)) == NULL)
-        return;
-
+       
        sid_to_string(sid_val.sid, sid);
        sid_val.type = (int)type;
 
@@ -310,21 +300,11 @@ static void store_sid_by_name_in_cache(fstring name, DOM_SID *sid, enum SID_NAME
 
 /* Lookup a SID in a domain indexed by name in the cache. */
 
-static BOOL winbindd_lookup_sid_by_name_in_cache(fstring name, DOM_SID *sid, enum SID_NAME_USE *type)
+static BOOL winbindd_lookup_sid_by_name_in_cache(struct winbindd_domain *domain,
+                                                const char *name, 
+                                                DOM_SID *sid, enum SID_NAME_USE *type)
 {
-       fstring domain_str;
-       char *p;
        struct winbindd_sid sid_ret;
-       struct winbindd_domain *domain;
-
-       /* Get name from domain. */
-       fstrcpy( domain_str, name);
-       p = strchr(domain_str, '\\');
-       if (p)
-               *p = '\0';
-
-       if ((domain = find_domain_from_name(domain_str)) == NULL)
-                return False;
 
        if (!winbindd_fetch_sid_cache_entry(domain, name, &sid_ret))
                return False;
@@ -340,23 +320,21 @@ static BOOL winbindd_lookup_sid_by_name_in_cache(fstring name, DOM_SID *sid, enu
 
 /* Store a name in a domain indexed by SID in the cache. */
 
-static void store_name_by_sid_in_cache(DOM_SID *sid, fstring name, enum SID_NAME_USE type)
+static void store_name_by_sid_in_cache(struct winbindd_domain *domain,
+                                      DOM_SID *sid, 
+                                      const char *name, enum SID_NAME_USE type)
 {
        fstring sid_str;
        uint32 rid;
        DOM_SID domain_sid;
        struct winbindd_name name_val;
-       struct winbindd_domain *domain;
 
        /* Split sid into domain sid and user rid */
        sid_copy(&domain_sid, sid);
        sid_split_rid(&domain_sid, &rid);
 
-       if ((domain = find_domain_from_sid(&domain_sid)) == NULL)
-        return;
-
        sid_to_string(sid_str, sid);
-       fstrcpy( name_val.name, name );
+       fstrcpy(name_val.name, name );
        name_val.type = (int)type;
 
        DEBUG(10,("store_name_by_sid_in_cache: storing cache entry SID %s -> %s\n",
@@ -398,15 +376,10 @@ static BOOL winbindd_lookup_name_by_sid_in_cache(DOM_SID *sid, fstring name, enu
 
 /* Lookup a sid in a domain from a name */
 
-BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid, enum SID_NAME_USE *type)
+BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain, 
+                                const char *name, DOM_SID *sid, enum SID_NAME_USE *type)
 {
-       int num_sids = 0, num_names = 1;
-       DOM_SID *sids = NULL;
-       uint32 *types = NULL;
-       CLI_POLICY_HND *hnd;
        NTSTATUS result;
-       TALLOC_CTX *mem_ctx;
-       BOOL rv = False;
         
        /* Don't bother with machine accounts */
         
@@ -414,55 +387,29 @@ BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid, enum SID_NAME_USE *ty
                return False;
 
        /* First check cache. */
-       if (winbindd_lookup_sid_by_name_in_cache(name, sid, type)) {
+       if (winbindd_lookup_sid_by_name_in_cache(domain, name, sid, type)) {
                if (*type == SID_NAME_USE_NONE)
                        return False; /* Negative cache hit. */
                return True;
        }
        /* Lookup name */
-        
-       if (!(mem_ctx = talloc_init()))
-               return False;
-        
-       if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
-               goto done;
-        
-       result = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol, 
-                               num_names, (char **)&name, &sids, 
-                               &types, &num_sids);
+       result = domain->methods->name_to_sid(domain, name, sid, type);
         
        /* Return rid and type if lookup successful */
-        
        if (NT_STATUS_IS_OK(result)) {
-                
-               /* Return sid */
-                
-               if ((sid != NULL) && (sids != NULL))
-                       sid_copy(sid, &sids[0]);
-                
-               /* Return name type */
-                
-               if ((type != NULL) && (types != NULL))
-                       *type = types[0];
-
-               /* Store the forward and reverse map of this lookup in the cache. */
-                store_sid_by_name_in_cache(name, &sids[0], types[0]);
-               store_name_by_sid_in_cache(&sids[0], name, types[0]);
+                store_sid_by_name_in_cache(domain, name, sid, *type);
+               store_name_by_sid_in_cache(domain, sid, name, *type);
        } else {
-               /* JRA. Here's where we add the -ve cache store with a name type of SID_NAME_USE_NONE. */
+               /* JRA. Here's where we add the -ve cache store with a
+                   name type of SID_NAME_USE_NONE. */
                DOM_SID nullsid;
 
                ZERO_STRUCT(nullsid);
-               store_sid_by_name_in_cache(name, &nullsid, SID_NAME_USE_NONE);
+               store_sid_by_name_in_cache(domain, name, &nullsid, SID_NAME_USE_NONE);
                *type = SID_NAME_UNKNOWN;
        }
 
-       rv = NT_STATUS_IS_OK(result);
-
- done:
-       talloc_destroy(mem_ctx);
-        
-       return rv;
+       return NT_STATUS_IS_OK(result);
 }
 
 /**
@@ -489,6 +436,7 @@ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid,
        NTSTATUS result;
        TALLOC_CTX *mem_ctx;
        BOOL rv = False;
+       struct winbindd_domain *domain;
 
        /* First check cache. */
        if (winbindd_lookup_name_by_sid_in_cache(sid, name, type)) {
@@ -500,6 +448,12 @@ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid,
                        return True;
        }
 
+       domain = find_domain_from_sid(sid);
+       if (!domain) {
+               DEBUG(1,("Can't find domain from sid\n"));
+               return False;
+       }
+
        /* Lookup name */
 
        if (!(mem_ctx = talloc_init()))
@@ -526,13 +480,13 @@ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid,
                if ((type != NULL) && (types != NULL))
                        *type = types[0];
 
-               store_sid_by_name_in_cache(names[0], sid, types[0]);
-               store_name_by_sid_in_cache(sid, names[0], types[0]);
+               store_sid_by_name_in_cache(domain, names[0], sid, types[0]);
+               store_name_by_sid_in_cache(domain, sid, names[0], types[0]);
        } else {
                /* OK, so we tried to look up a name in this sid, and
                 * didn't find it.  Therefore add a negative cache
                 * entry.  */
-               store_name_by_sid_in_cache(sid, "", SID_NAME_USE_NONE);
+               store_name_by_sid_in_cache(domain, sid, "", SID_NAME_USE_NONE);
                *type = SID_NAME_UNKNOWN;
                fstrcpy(name, name_deadbeef);
        }
@@ -817,7 +771,7 @@ BOOL check_domain_env(char *domain_env, char *domain)
 
 /* Parse a string of the form DOMAIN/user into a domain and a user */
 
-void parse_domain_user(char *domuser, fstring domain, fstring user)
+void parse_domain_user(const char *domuser, fstring domain, fstring user)
 {
        char *p;
        char *sep = lp_winbind_separator();