r12051: Merge across the lookup_name and lookup_sid work. Lets see how the build...
authorVolker Lendecke <vlendec@samba.org>
Sat, 3 Dec 2005 18:34:13 +0000 (18:34 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:05:43 +0000 (11:05 -0500)
reacts :-)

Volker

19 files changed:
source/Makefile.in
source/auth/auth_util.c
source/groupdb/mapping.c
source/include/passdb.h
source/include/smb.h
source/lib/util_sid.c
source/modules/vfs_afsacl.c
source/nsswitch/wb_client.c
source/passdb/lookup_sid.c
source/passdb/machine_sid.c
source/passdb/passdb.c
source/passdb/pdb_interface.c
source/passdb/secrets.c
source/passdb/util_builtin.c [new file with mode: 0644]
source/passdb/util_sam_sid.c [deleted file]
source/passdb/util_wellknown.c [new file with mode: 0644]
source/rpc_server/srv_lsa_nt.c
source/rpc_server/srv_samr_nt.c
source/smbd/lanman.c

index 888a0ebe344bcd91c736d32d5d850330d11088ee..c0753a76c004ba35c7f1f2abfc0a7275560990df 100644 (file)
@@ -326,7 +326,7 @@ LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o
 PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o
 
 PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
-               passdb/util_sam_sid.o passdb/pdb_compat.o \
+               passdb/util_wellknown.o passdb/util_builtin.o passdb/pdb_compat.o \
                passdb/lookup_sid.o \
                passdb/login_cache.o @PDB_STATIC@ passdb/pdb_sql.o \
                lib/system_smbd.o lib/account_pol.o lib/privileges.o
index 61cb7f31cc759e934a86fc52ed2db92f5937fe4d..ce1ce31d08a2209a9b97a7eb9e4ea5dc66b94160 100644 (file)
@@ -1550,7 +1550,7 @@ NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
  Check for a SID in an NT_USER_TOKEN
 ****************************************************************************/
 
-BOOL nt_token_check_sid ( DOM_SID *sid, NT_USER_TOKEN *token )
+static BOOL nt_token_check_sid ( DOM_SID *sid, NT_USER_TOKEN *token )
 {
        int i;
        
@@ -1598,8 +1598,6 @@ BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
 BOOL is_trusted_domain(const char* dom_name)
 {
        DOM_SID trustdom_sid;
-       char *pass = NULL;
-       time_t lct;
        BOOL ret;
 
        /* no trusted domains for a standalone server */
@@ -1613,9 +1611,8 @@ BOOL is_trusted_domain(const char* dom_name)
                become_root();
                DEBUG (5,("is_trusted_domain: Checking for domain trust with [%s]\n",
                        dom_name ));
-               ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct);
+               ret = secrets_fetch_trusted_domain_password(dom_name, NULL, NULL, NULL);
                unbecome_root();
-               SAFE_FREE(pass);
                if (ret)
                        return True;
        }
index 1e8586786cdb40fafe36ea948854ac7295f524c0..14040e4f52ba6e53df1dac1eca5a0468911d26b0 100644 (file)
@@ -1166,11 +1166,22 @@ NTSTATUS pdb_default_create_alias(struct pdb_methods *methods,
        enum SID_NAME_USE type;
        uint32 new_rid;
        gid_t gid;
-
+       BOOL exists;
        GROUP_MAP map;
 
-       if (lookup_name(get_global_sam_name(), name, &sid, &type))
+       TALLOC_CTX *mem_ctx = talloc_new(NULL);
+
+       if (mem_ctx == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       exists = lookup_name(mem_ctx, name, LOOKUP_NAME_ISOLATED,
+                            NULL, NULL, &sid, &type);
+       talloc_free(mem_ctx);
+
+       if (exists) {
                return NT_STATUS_ALIAS_EXISTS;
+       }
 
        if (!winbind_allocate_rid_and_gid(&new_rid, &gid))
                return NT_STATUS_ACCESS_DENIED;
index 0589b9a7cd46b10a92cc7c1fea9cbd73a4d85e17..20ea7021d070b9f7d6647af696c1f9373c50b0a0 100644 (file)
@@ -376,6 +376,13 @@ typedef struct pdb_context
                                    const char **pp_names,
                                    uint32 *attrs);
 
+       NTSTATUS (*pdb_lookup_names)(struct pdb_context *context,
+                                    const DOM_SID *domain_sid,
+                                    size_t num_names,
+                                    const char **names,
+                                    uint32 *rids,
+                                    uint32 *attrs);
+
        NTSTATUS (*pdb_get_account_policy)(struct pdb_context *context,
                                           int policy_index, uint32 *value);
 
@@ -499,6 +506,13 @@ typedef struct pdb_methods
                                const char **pp_names,
                                uint32 *attrs);
 
+       NTSTATUS (*lookup_names)(struct pdb_methods *methods,
+                                const DOM_SID *domain_sid,
+                                int num_names,
+                                const char **pp_names,
+                                uint32 *rids,
+                                uint32 *attrs);
+
        NTSTATUS (*get_account_policy)(struct pdb_methods *methods,
                                       int policy_index, uint32 *value);
 
index 6511f10365f326ecc46a32e5ccc020cac40a14d2..50b8c0369f4fe18a1dccc0a777178156669de0cf 100644 (file)
@@ -264,6 +264,10 @@ enum SID_NAME_USE
        SID_NAME_COMPUTER     /* sid for a computer */
 };
 
+#define LOOKUP_NAME_ISOLATED 1 /* Look up unqualified names */
+#define LOOKUP_NAME_REMOTE   2  /* Ask others */
+#define LOOKUP_NAME_ALL (LOOKUP_NAME_ISOLATED|LOOKUP_NAME_REMOTE)
+
 /**
  * @brief Security Identifier
  *
index 4c274b5e01d2abe6e457a4d306d19f8d641a19bb..92bc2fb89311b84c0ed8cd80f823c11a39c95b8a 100644 (file)
@@ -75,11 +75,14 @@ const DOM_SID global_sid_Builtin_Backup_Operators = /* Builtin backup operators
 const DOM_SID global_sid_Builtin_Replicator =          /* Builtin replicator */
 { 1, 2, {0,0,0,0,0,5}, {32,552,0,0,0,0,0,0,0,0,0,0,0,0,0}};
 
+/* Unused, left here for documentary purposes */
+#if 0
 #define SECURITY_NULL_SID_AUTHORITY    0
 #define SECURITY_WORLD_SID_AUTHORITY   1
 #define SECURITY_LOCAL_SID_AUTHORITY   2
 #define SECURITY_CREATOR_SID_AUTHORITY 3
 #define SECURITY_NT_AUTHORITY          5
+#endif
 
 /*
  * An NT compatible anonymous token.
@@ -188,24 +191,6 @@ void split_domain_name(const char *fullname, char *domain, char *name)
                        fullname, domain, name));
 }
 
-/****************************************************************************
- Test if a SID is wellknown and resolvable.
-****************************************************************************/
-
-BOOL resolvable_wellknown_sid(DOM_SID *sid)
-{
-       uint32 ia = (sid->id_auth[5]) +
-                       (sid->id_auth[4] << 8 ) +
-                       (sid->id_auth[3] << 16) +
-                       (sid->id_auth[2] << 24);
-
-       if (sid->sid_rev_num != SEC_DESC_REVISION || sid->num_auths < 1)
-               return False;
-
-       return (ia == SECURITY_WORLD_SID_AUTHORITY ||
-               ia == SECURITY_CREATOR_SID_AUTHORITY);
-}
-
 /*****************************************************************
  Convert a SID to an ascii string.
 *****************************************************************/
@@ -532,30 +517,6 @@ BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
        return sid_compare(sid1, sid2) == 0;
 }
 
-/*****************************************************************
- Check if the SID is the builtin SID (S-1-5-32).
-*****************************************************************/  
-
-BOOL sid_check_is_builtin(const DOM_SID *sid)
-{
-       return sid_equal(sid, &global_sid_Builtin);
-}
-
-/*****************************************************************
- Check if the SID is one of the builtin SIDs (S-1-5-32-a).
-*****************************************************************/  
-
-BOOL sid_check_is_in_builtin(const DOM_SID *sid)
-{
-       DOM_SID dom_sid;
-       uint32 rid;
-
-       sid_copy(&dom_sid, sid);
-       sid_split_rid(&dom_sid, &rid);
-       
-       return sid_equal(&dom_sid, &global_sid_Builtin);
-}
-
 /*****************************************************************
  Calculates size of a sid.
 *****************************************************************/  
index 41f40d1e3c4f15ec6c0a5ebb5bbae097a5e70830..3794299b9a02ba50931bfb93c85d350102924c36 100644 (file)
@@ -105,27 +105,6 @@ static struct afs_ace *clone_afs_ace(TALLOC_CTX *mem_ctx, struct afs_ace *ace)
        return result;
 }
        
-
-/* Ok, this is sort-of a hack. We assume here that we have winbind users in
- * AFS. And yet another copy of parse_domain_user.... */
-
-static BOOL parse_domain_user(const char *domuser, fstring domain,
-                             fstring user)
-{
-       char *p = strchr(domuser,*lp_winbind_separator());
-
-       if (p==NULL) {
-               return False;
-       }
-
-       fstrcpy(user, p+1);
-       fstrcpy(domain, domuser);
-       domain[PTR_DIFF(p, domuser)] = 0;
-       strupper_m(domain);
-       
-       return True;
-}
-
 static struct afs_ace *new_afs_ace(TALLOC_CTX *mem_ctx,
                                   BOOL positive,
                                   const char *name, uint32 rights)
@@ -168,14 +147,16 @@ static struct afs_ace *new_afs_ace(TALLOC_CTX *mem_ctx,
 
        } else {
 
-               fstring user, domain;
+               fstring domain, uname;
+               char *p;
 
-               if (!parse_domain_user(name, domain, user)) {
-                       fstrcpy(user, name);
-                       fstrcpy(domain, lp_workgroup());
+               p = strchr_m(name, lp_winbind_separator());
+               if (p != NULL) {
+                       *p = '\\';
                }
-                   
-               if (!lookup_name(domain, user, &sid, &type)) {
+
+               if (!lookup_name(name, LOOKUP_NAME_FULL,
+                                domain, uname, &sid, &type)) {
                        DEBUG(10, ("Could not find AFS user %s\n", name));
 
                        sid_copy(&sid, &global_sid_NULL);
index db56cf04441e4f3f335db1238510fe0b23701425..6fe55e1209815bf7e37a56b0d677ed513cfe7327 100644 (file)
@@ -64,39 +64,52 @@ BOOL winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
 
 /* Call winbindd to convert sid to name */
 
-BOOL winbind_lookup_sid(const DOM_SID *sid, 
-                       fstring dom_name, fstring name, 
+BOOL winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid, 
+                       char **domain, char **name,
                         enum SID_NAME_USE *name_type)
 {
        struct winbindd_request request;
        struct winbindd_response response;
        NSS_STATUS result;
-       fstring sid_str;
        
        /* Initialise request */
 
        ZERO_STRUCT(request);
        ZERO_STRUCT(response);
 
-       sid_to_string(sid_str, sid);
-       fstrcpy(request.data.sid, sid_str);
+       fstrcpy(request.data.sid, sid_string_static(sid));
        
        /* Make request */
 
-       result = winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response);
+       result = winbindd_request_response(WINBINDD_LOOKUPSID, &request,
+                                          &response);
 
-       /* Copy out result */
+       if (result != NSS_STATUS_SUCCESS) {
+               return False;
+       }
 
-       if (result == NSS_STATUS_SUCCESS) {
-               fstrcpy(dom_name, response.data.name.dom_name);
-               fstrcpy(name, response.data.name.name);
-               *name_type = (enum SID_NAME_USE)response.data.name.type;
+       /* Copy out result */
 
-               DEBUG(10, ("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n", 
-                           sid_str, dom_name, name));
+       if (domain != NULL) {
+               *domain = talloc_strdup(mem_ctx, response.data.name.dom_name);
+               if (*domain == NULL) {
+                       DEBUG(0, ("talloc failed\n"));
+                       return False;
+               }
+       }
+       if (name != NULL) {
+               *name = talloc_strdup(mem_ctx, response.data.name.name);
+               if (*name == NULL) {
+                       DEBUG(0, ("talloc failed\n"));
+                       return False;
+               }
        }
 
-       return (result == NSS_STATUS_SUCCESS);
+       *name_type = (enum SID_NAME_USE)response.data.name.type;
+
+       DEBUG(10, ("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n", 
+                  sid_string_static(sid), *domain, *name));
+       return True;
 }
 
 /* Call winbindd to convert SID to uid */
index b397e084c3382174cb92b27d1fbe2109d8763382..bad5d278aedfc60fd3701317d3283f229cad7d3d 100644 (file)
 #include "includes.h"
 
 /*****************************************************************
- *THE CANONICAL* convert name to SID function.
- Tries local lookup first - for local domains - then uses winbind.
+ Dissect a user-provided name into domain, name, sid and type.
+
+ If an explicit domain name was given in the form domain\user, it
+ has to try that. If no explicit domain name was given, we have
+ to do guesswork.
 *****************************************************************/  
 
-BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type)
+BOOL lookup_name(TALLOC_CTX *mem_ctx,
+                const char *full_name, int flags,
+                char **ret_domain, char **ret_name,
+                DOM_SID *ret_sid, enum SID_NAME_USE *ret_type)
 {
-       fstring sid;
-       BOOL local_lookup = False;
-       
-       *name_type = SID_NAME_UNKNOWN;
+       char *p, *tmp;
+       char *domain = NULL;
+       char *name = NULL;
+       uint32 rid;
+       DOM_SID sid;
+       enum SID_NAME_USE type;
+
+       p = strchr_m(full_name, '\\');
+
+       if (p != NULL) {
+               domain = talloc_strndup(mem_ctx, full_name,
+                                       PTR_DIFF(p, full_name));
+               name = talloc_strdup(mem_ctx, p+1);
+       } else {
+               domain = talloc_strdup(mem_ctx, "");
+               name = talloc_strdup(mem_ctx, full_name);
+       }
+
+       if ((domain == NULL) || (name == NULL)) {
+               DEBUG(0, ("talloc failed\n"));
+               return False;
+       }
 
-       /* If we are looking up a domain user, make sure it is
-          for the local machine only */
-       
        if (strequal(domain, get_global_sam_name())) {
-               if (local_lookup_name(name, psid, name_type)) {
-                       DEBUG(10,
-                             ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n",
-                              domain, name, sid_to_string(sid,psid),
-                              sid_type_lookup(*name_type), (unsigned int)*name_type));
-                       return True;
+
+               /* It's our own domain, lookup the name in passdb */
+               if (lookup_global_sam_name(name, &rid, &type)) {
+                       sid_copy(&sid, get_global_sam_sid());
+                       sid_append_rid(&sid, rid);
+                       goto ok;
                }
-       } else {
-               /* Remote */
-               if (winbind_lookup_name(domain, name, psid, name_type)) {
-                       
-                       DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n",
-                                 domain, name, sid_to_string(sid, psid), 
-                                 (unsigned int)*name_type));
-                       return True;
+               return False;
+       }
+
+       if (strequal(domain, builtin_domain_name())) {
+
+               /* Explicit request for a name in BUILTIN */
+               if (lookup_builtin_name(name, &rid)) {
+                       sid_copy(&sid, &global_sid_Builtin);
+                       sid_append_rid(&sid, rid);
+                       type = SID_NAME_ALIAS;
+                       goto ok;
                }
+               return False;
        }
-       
-       DEBUG(10, ("lookup_name: %s lookup for [%s]\\[%s] failed\n", 
-                  local_lookup ? "local" : "winbind", domain, name));
+
+       if (domain[0] != '\0') {
+               /* An explicit domain name was given, here our last resort is
+                * winbind. */
+               if (winbind_lookup_name(domain, name, &sid, &type)) {
+                       goto ok;
+               }
+               return False;
+       }
+
+       if (!(flags & LOOKUP_NAME_ISOLATED)) {
+               return False;
+       }
+
+       /* Now the guesswork begins, we haven't been given an explicit
+        * domain. Try the sequence as documented on
+        * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
+        * November 27, 2005 */
+
+       /* 1. well-known names */
+
+       {
+               tmp = domain;
+               if (lookup_wellknown_name(mem_ctx, name, &sid, &domain)) {
+                       talloc_free(tmp);
+                       type = SID_NAME_WKN_GRP;
+                       goto ok;
+               }
+       }
+
+       /* 2. Builtin domain as such */
+
+       if (strequal(name, builtin_domain_name())) {
+               /* Swap domain and name */
+               tmp = name; name = domain; domain = tmp;
+               sid_copy(&sid, &global_sid_Builtin);
+               type = SID_NAME_DOMAIN;
+               goto ok;
+       }
+
+       /* 3. Account domain */
+
+       if (strequal(name, get_global_sam_name())) {
+               if (!secrets_fetch_domain_sid(name, &sid)) {
+                       DEBUG(3, ("Could not fetch my SID\n"));
+                       return False;
+               }
+               /* Swap domain and name */
+               tmp = name; name = domain; domain = tmp;
+               type = SID_NAME_DOMAIN;
+               goto ok;
+       }
+
+       /* 4. Primary domain */
+
+       if (!IS_DC && strequal(name, lp_workgroup())) {
+               if (!secrets_fetch_domain_sid(name, &sid)) {
+                       DEBUG(3, ("Could not fetch the domain SID\n"));
+                       return False;
+               }
+               /* Swap domain and name */
+               tmp = name; name = domain; domain = tmp;
+               type = SID_NAME_DOMAIN;
+               goto ok;
+       }
+
+       /* 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))) {
+               /* Swap domain and name */
+               tmp = name; name = domain; domain = tmp;
+               type = SID_NAME_DOMAIN;
+               goto ok;
+       }
+
+       /* 6. Builtin aliases */        
+
+       if (lookup_builtin_name(name, &rid)) {
+               domain = talloc_strdup(mem_ctx, builtin_domain_name());
+               sid_copy(&sid, &global_sid_Builtin);
+               sid_append_rid(&sid, rid);
+               type = SID_NAME_ALIAS;
+               goto ok;
+       }
+
+       /* 7. Local systems' SAM (DCs don't have a local SAM) */
+       /* 8. Primary SAM (On members, this is the domain) */
+
+       /* Both cases are done by looking at our passdb */
+
+       if (lookup_global_sam_name(name, &rid, &type)) {
+               domain = talloc_strdup(mem_ctx, get_global_sam_name());
+               sid_copy(&sid, get_global_sam_sid());
+               sid_append_rid(&sid, rid);
+               goto ok;
+       }
+
+       /* Now our local possibilities are exhausted. */
+
+       if (!(flags & LOOKUP_NAME_REMOTE)) {
+               return False;
+       }
+
+       /* If we are not a DC, we have to ask in our primary domain. Let
+        * winbind do that. */
+
+       if (!IS_DC &&
+           (winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
+               domain = talloc_strdup(mem_ctx, lp_workgroup());
+               goto ok;
+       }
+
+       /* 9. Trusted domains */
+
+       /* If we're a DC we have to ask all trusted DC's. Winbind does not do
+        * that (yet), but give it a chance. */
+
+       if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
+               DOM_SID dom_sid;
+               uint32 tmp_rid;
+               enum SID_NAME_USE domain_type;
+               
+               if (type == SID_NAME_DOMAIN) {
+                       /* Swap name and type */
+                       tmp = name; name = domain; domain = tmp;
+                       goto ok;
+               }
+
+               talloc_free(domain);
+
+               /* Here we have to cope with a little deficiency in the
+                * winbind API: We have to ask it again for the name of the
+                * domain it figured out itself. Maybe fix that later... */
+
+               sid_copy(&dom_sid, &sid);
+               sid_split_rid(&dom_sid, &tmp_rid);
+
+               if (!winbind_lookup_sid(mem_ctx, &dom_sid, &domain, NULL,
+                                       &domain_type) ||
+                   (domain_type != SID_NAME_DOMAIN)) {
+                       DEBUG(2, ("winbind could not find the domain's name it "
+                                 "just looked up for us\n"));
+                       return False;
+               }
+
+               talloc_free(domain);
+               goto ok;
+       }
+
+       /* 10. Don't translate */
 
        return False;
+
+ ok:
+       if ((domain == NULL) || (name == NULL)) {
+               DEBUG(0, ("talloc failed\n"));
+               return False;
+       }
+
+       strupper_m(domain);
+
+       if (ret_name != NULL) {
+               *ret_name = name;
+       } else {
+               talloc_free(name);
+       }
+
+       if (ret_domain != NULL) {
+               *ret_domain = domain;
+       } else {
+               talloc_free(domain);
+       }
+
+       if (ret_sid != NULL) {
+               sid_copy(ret_sid, &sid);
+       }
+
+       if (ret_type != NULL) {
+               *ret_type = type;
+       }
+
+       return True;
 }
 
 /*****************************************************************
@@ -66,22 +270,21 @@ BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_N
  Tries local lookup first - for local sids, then tries winbind.
 *****************************************************************/  
 
-BOOL lookup_sid(const DOM_SID *sid, fstring dom_name, fstring name,
-               enum SID_NAME_USE *name_type)
+BOOL lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
+               char **ret_domain, char **ret_name,
+               enum SID_NAME_USE *ret_type)
 {
-       if (!name_type)
-               return False;
-
-       *name_type = SID_NAME_UNKNOWN;
-
+       char *domain = NULL;
+       char *name = NULL;
+       enum SID_NAME_USE type;
        /* Check if this is our own sid.  This should perhaps be done by
           winbind?  For the moment handle it here. */
 
        if (sid_check_is_domain(sid)) {
-               fstrcpy(dom_name, get_global_sam_name());
-               fstrcpy(name, "");
-               *name_type = SID_NAME_DOMAIN;
-               return True;
+               domain = talloc_strdup(mem_ctx, get_global_sam_name());
+               name = talloc_strdup(mem_ctx, "");
+               type = SID_NAME_DOMAIN;
+               goto ok;
        }
 
        if (sid_check_is_in_our_domain(sid)) {
@@ -89,22 +292,22 @@ BOOL lookup_sid(const DOM_SID *sid, fstring dom_name, fstring name,
                SMB_ASSERT(sid_peek_rid(sid, &rid));
 
                /* For our own domain passdb is responsible */
-               fstrcpy(dom_name, get_global_sam_name());
-               return lookup_global_sam_rid(rid, name, name_type);
+               if (!lookup_global_sam_rid(mem_ctx, rid, &name, &type)) {
+                       return False;
+               }
+
+               domain = talloc_strdup(mem_ctx, get_global_sam_name());
+               goto ok;
        }
 
        if (sid_check_is_builtin(sid)) {
 
-               /* Got through map_domain_sid_to_name here so that the mapping
-                * of S-1-5-32 to the name "BUILTIN" in as few places as
-                * possible. We might add i18n... */
-               SMB_ASSERT(map_domain_sid_to_name(sid, dom_name));
+               domain = talloc_strdup(mem_ctx, builtin_domain_name());
 
                /* Yes, W2k3 returns "BUILTIN" both as domain and name here */
-               fstrcpy(name, dom_name); 
-
-               *name_type = SID_NAME_DOMAIN;
-               return True;
+               name = talloc_strdup(mem_ctx, builtin_domain_name());
+               type = SID_NAME_DOMAIN;
+               goto ok;
        }
 
        if (sid_check_is_in_builtin(sid)) {
@@ -112,39 +315,56 @@ BOOL lookup_sid(const DOM_SID *sid, fstring dom_name, fstring name,
 
                SMB_ASSERT(sid_peek_rid(sid, &rid));
 
-               /* Got through map_domain_sid_to_name here so that the mapping
-                * of S-1-5-32 to the name "BUILTIN" in as few places as
-                * possible. We might add i18n... */
-               SMB_ASSERT(map_domain_sid_to_name(&global_sid_Builtin,
-                                                 dom_name));
+               if (!lookup_builtin_rid(mem_ctx, rid, &name)) {
+                       return False;
+               }
 
                /* There's only aliases in S-1-5-32 */
-               *name_type = SID_NAME_ALIAS;
+               type = SID_NAME_ALIAS;
+               domain = talloc_strdup(mem_ctx, builtin_domain_name());
 
-               return lookup_builtin_rid(rid, name);
+               goto ok;
        }
 
-       if (winbind_lookup_sid(sid, dom_name, name, name_type)) {
-               return True;
+       if (winbind_lookup_sid(mem_ctx, sid, &domain, &name, &type)) {
+               goto ok;
        }
 
        DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying "
                  "special SIDs.\n", sid_string_static(sid)));
 
-       {
-               const char *dom, *obj_name;
-               
-               if (lookup_special_sid(sid, &dom, &obj_name, name_type)) {
-                       DEBUG(10, ("found %s\\%s\n", dom, obj_name));
-                       fstrcpy(dom_name, dom);
-                       fstrcpy(name, obj_name);
-                       return True;
-               }
+       if (lookup_wellknown_sid(mem_ctx, sid, &domain, &name)) {
+               type = SID_NAME_WKN_GRP;
+               goto ok;
        }
 
-       DEBUG(10, ("lookup_sid failed\n"));
-
+       DEBUG(10, ("Failed to lookup sid %s\n", sid_string_static(sid)));
        return False;
+
+ ok:
+
+       if ((domain == NULL) || (name == NULL)) {
+               DEBUG(0, ("talloc failed\n"));
+               return False;
+       }
+
+       if (ret_domain != NULL) {
+               *ret_domain = domain;
+       } else {
+               talloc_free(domain);
+       }
+
+       if (ret_name != NULL) {
+               *ret_name = name;
+       } else {
+               talloc_free(name);
+       }
+
+       if (ret_type != NULL) {
+               *ret_type = type;
+       }
+
+       return True;
 }
 
 /*****************************************************************
@@ -187,10 +407,9 @@ static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid)
 
        for (pc = uid_sid_cache_head; pc; pc = pc->next) {
                if (pc->uid == uid) {
-                       fstring sid;
                        *psid = pc->sid;
                        DEBUG(3,("fetch sid from uid cache %u -> %s\n",
-                               (unsigned int)uid, sid_to_string(sid, psid)));
+                                (unsigned int)uid, sid_string_static(psid)));
                        DLIST_PROMOTE(uid_sid_cache_head, pc);
                        return True;
                }
@@ -208,10 +427,9 @@ static BOOL fetch_uid_from_cache( uid_t *puid, const DOM_SID *psid )
 
        for (pc = uid_sid_cache_head; pc; pc = pc->next) {
                if (sid_compare(&pc->sid, psid) == 0) {
-                       fstring sid;
                        *puid = pc->uid;
                        DEBUG(3,("fetch uid from cache %u -> %s\n",
-                               (unsigned int)*puid, sid_to_string(sid, psid)));
+                                (unsigned int)*puid, sid_string_static(psid)));
                        DLIST_PROMOTE(uid_sid_cache_head, pc);
                        return True;
                }
@@ -261,10 +479,9 @@ static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid)
 
        for (pc = gid_sid_cache_head; pc; pc = pc->next) {
                if (pc->gid == gid) {
-                       fstring sid;
                        *psid = pc->sid;
                        DEBUG(3,("fetch sid from gid cache %u -> %s\n",
-                               (unsigned int)gid, sid_to_string(sid, psid)));
+                                (unsigned int)gid, sid_string_static(psid)));
                        DLIST_PROMOTE(gid_sid_cache_head, pc);
                        return True;
                }
@@ -282,10 +499,9 @@ static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid)
 
        for (pc = gid_sid_cache_head; pc; pc = pc->next) {
                if (sid_compare(&pc->sid, psid) == 0) {
-                       fstring sid;
                        *pgid = pc->gid;
                        DEBUG(3,("fetch gid from cache %u -> %s\n",
-                                (unsigned int)*pgid, sid_to_string(sid, psid)));
+                                (unsigned int)*pgid, sid_string_static(psid)));
                        DLIST_PROMOTE(gid_sid_cache_head, pc);
                        return True;
                }
@@ -331,7 +547,6 @@ static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
 
 NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
 {
-       fstring sid;
        uid_t low, high;
 
        ZERO_STRUCTP(psid);
@@ -348,7 +563,7 @@ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
                if (winbind_uid_to_sid(psid, uid)) {
 
                        DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
-                               (unsigned int)uid, sid_to_string(sid, psid)));
+                                 (unsigned int)uid, sid_string_static(psid)));
 
                        if (psid)
                                store_uid_sid_cache(psid, uid);
@@ -361,7 +576,8 @@ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
                return NT_STATUS_UNSUCCESSFUL;
        }
         
-       DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid)));
+       DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid,
+                 sid_string_static(psid)));
 
        store_uid_sid_cache(psid, uid);
        return NT_STATUS_OK;
@@ -373,7 +589,6 @@ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
 
 NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
 {
-       fstring sid;
        gid_t low, high;
 
        ZERO_STRUCTP(psid);
@@ -390,7 +605,7 @@ NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
                if (winbind_gid_to_sid(psid, gid)) {
 
                        DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
-                               (unsigned int)gid, sid_to_string(sid, psid)));
+                                 (unsigned int)gid, sid_string_static(psid)));
                         
                        if (psid)
                                store_gid_sid_cache(psid, gid);
@@ -403,7 +618,8 @@ NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
                return NT_STATUS_UNSUCCESSFUL;
        }
         
-       DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid)));
+       DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid,
+                 sid_string_static(psid)));
 
        store_gid_sid_cache(psid, gid);
        return NT_STATUS_OK;
@@ -415,7 +631,6 @@ NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
 
 NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid)
 {
-       fstring dom_name, name, sid_str;
        enum SID_NAME_USE name_type;
 
        if (fetch_uid_from_cache(puid, psid))
@@ -437,7 +652,7 @@ NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid)
        
        /* If it is not our local domain, only hope is winbindd */
 
-       if ( !winbind_lookup_sid(psid, dom_name, name, &name_type) ) {
+       if ( !winbind_lookup_sid(NULL, psid, NULL, NULL, &name_type) ) {
                DEBUG(10,("sid_to_uid: winbind lookup for non-local sid %s failed\n",
                        sid_string_static(psid) ));
                        
@@ -456,12 +671,12 @@ NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid)
 
        if ( !winbind_sid_to_uid(puid, psid) ) {
                DEBUG(10,("sid_to_uid: winbind failed to allocate a new uid for sid %s\n",
-                       sid_to_string(sid_str, psid) ));
+                         sid_string_static(psid)));
                return NT_STATUS_UNSUCCESSFUL;
        }
 
 success:
-       DEBUG(10,("sid_to_uid: %s -> %u\n", sid_to_string(sid_str, psid),
+       DEBUG(10,("sid_to_uid: %s -> %u\n", sid_string_static(psid),
                (unsigned int)*puid ));
 
        store_uid_sid_cache(psid, *puid);
@@ -475,7 +690,6 @@ success:
 
 NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid)
 {
-       fstring dom_name, name, sid_str;
        enum SID_NAME_USE name_type;
 
        if (fetch_gid_from_cache(pgid, psid))
@@ -489,8 +703,9 @@ NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid)
        if ( local_sid_to_gid(pgid, psid, &name_type) )
                goto success;
        
-       if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
-               DEBUG(10,("sid_to_gid: no one knows the SID %s (tried local, then winbind)\n", sid_to_string(sid_str, psid)));
+       if (!winbind_lookup_sid(NULL, psid, NULL, NULL, &name_type)) {
+               DEBUG(10,("sid_to_gid: no one knows the SID %s (tried local, then "
+                         "winbind)\n", sid_string_static(psid)));
                
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -514,13 +729,13 @@ NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid)
 
        if ( !winbind_sid_to_gid(pgid, psid) ) {
                DEBUG(10,("sid_to_gid: winbind failed to allocate a new gid for sid %s\n",
-                       sid_to_string(sid_str, psid) ));
+                         sid_string_static(psid)));
                return NT_STATUS_UNSUCCESSFUL;
        }
 
 success:
-       DEBUG(10,("sid_to_gid: %s -> %u\n", sid_to_string(sid_str, psid),
-               (unsigned int)*pgid ));
+       DEBUG(10,("sid_to_gid: %s -> %u\n", sid_string_static(psid),
+                 (unsigned int)*pgid ));
 
        store_gid_sid_cache(psid, *pgid);
        
index 87ec27d34eacb91d16a3506e2d2403d433365854..074a516bcb6713e81e40323056b9512d5c671201 100644 (file)
@@ -198,3 +198,27 @@ void reset_global_sam_sid(void)
 {
        SAFE_FREE(global_sam_sid);
 }
+
+/*****************************************************************
+ Check if the SID is our domain SID (S-1-5-21-x-y-z).
+*****************************************************************/  
+
+BOOL sid_check_is_domain(const DOM_SID *sid)
+{
+       return sid_equal(sid, get_global_sam_sid());
+}
+
+/*****************************************************************
+ Check if the SID is our domain SID (S-1-5-21-x-y-z).
+*****************************************************************/  
+
+BOOL sid_check_is_in_our_domain(const DOM_SID *sid)
+{
+       DOM_SID dom_sid;
+       uint32 rid;
+
+       sid_copy(&dom_sid, sid);
+       sid_split_rid(&dom_sid, &rid);
+       
+       return sid_equal(&dom_sid, get_global_sam_sid());
+}
index e073db3499c572ed450fc961918545fde24abc92..3ca26a57c744fe10f20a4745a8cb9c83d73f8356 100644 (file)
@@ -735,7 +735,7 @@ BOOL algorithmic_pdb_rid_is_user(uint32 rid)
  Look up a rid in the SAM we're responsible for (i.e. passdb)
  ********************************************************************/
 
-BOOL lookup_global_sam_rid(uint32 rid, fstring name,
+BOOL lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid, char **name,
                           enum SID_NAME_USE *psid_name_use)
 {
        SAM_ACCOUNT *sam_account = NULL;
@@ -760,7 +760,7 @@ BOOL lookup_global_sam_rid(uint32 rid, fstring name,
        become_root();
        if (pdb_getsampwsid(sam_account, &sid)) {
                unbecome_root();                /* -----> EXIT BECOME_ROOT() */
-               fstrcpy(name, pdb_get_username(sam_account));
+               *name = talloc_strdup(mem_ctx, pdb_get_username(sam_account));
                *psid_name_use = SID_NAME_USER;
 
                pdb_free_sam(&sam_account);
@@ -784,14 +784,14 @@ BOOL lookup_global_sam_rid(uint32 rid, fstring name,
                                 map.nt_name));
                }
 
-               fstrcpy(name, map.nt_name);
+               *name = talloc_strdup(mem_ctx, map.nt_name);
                *psid_name_use = map.sid_name_use;
                return True;
        }
 
        if (rid == DOMAIN_USER_RID_ADMIN) {
                *psid_name_use = SID_NAME_USER;
-               fstrcpy(name, "Administrator");
+               *name = talloc_strdup(mem_ctx, "Administrator");
                return True;
        }
 
@@ -807,13 +807,15 @@ BOOL lookup_global_sam_rid(uint32 rid, fstring name,
                DEBUG(5,("lookup_global_sam_rid: looking up uid %u %s\n",
                         (unsigned int)uid, pw ? "succeeded" : "failed" ));
                         
-               if ( !pw )
-                       fstr_sprintf(name, "unix_user.%u", (unsigned int)uid);
-               else 
-                       fstrcpy( name, pw->pw_name );
+               if ( !pw ) {
+                       *name  = talloc_asprintf(mem_ctx, "unix_user.%u",
+                                                (unsigned int)uid);
+               } else {
+                       *name = talloc_strdup(mem_ctx, pw->pw_name );
+               }
                        
                DEBUG(5,("lookup_global_sam_rid: found user %s for rid %u\n",
-                        name, (unsigned int)rid ));
+                        *name, (unsigned int)rid ));
                         
                *psid_name_use = SID_NAME_USER;
                
@@ -830,13 +832,15 @@ BOOL lookup_global_sam_rid(uint32 rid, fstring name,
                DEBUG(5,("lookup_global_sam_rid: looking up gid %u %s\n",
                         (unsigned int)gid, gr ? "succeeded" : "failed" ));
                        
-               if( !gr )
-                       fstr_sprintf(name, "unix_group.%u", (unsigned int)gid);
-               else
-                       fstrcpy( name, gr->gr_name);
+               if( !gr ) {
+                       *name = talloc_asprintf(mem_ctx, "unix_group.%u",
+                                              (unsigned int)gid);
+               } else {
+                       *name = talloc_strdup(mem_ctx, gr->gr_name);
+               }
                        
                DEBUG(5,("lookup_global_sam_rid: found group %s for rid %u\n",
-                        name, (unsigned int)rid ));
+                        *name, (unsigned int)rid ));
                
                /* assume algorithmic groups are domain global groups */
                
@@ -850,17 +854,13 @@ BOOL lookup_global_sam_rid(uint32 rid, fstring name,
  Convert a name into a SID. Used in the lookup name rpc.
  ********************************************************************/
 
-BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
+BOOL lookup_global_sam_name(const char *c_user, uint32_t *rid, enum SID_NAME_USE *type)
 {
-       DOM_SID local_sid;
-       DOM_SID sid;
        fstring user;
        SAM_ACCOUNT *sam_account = NULL;
        struct group *grp;
        GROUP_MAP map;
 
-       *psid_name_use = SID_NAME_UNKNOWN;
-
        /*
         * user may be quoted a const string, and map_username and
         * friends can modify it. Make a modifiable copy. JRA.
@@ -868,17 +868,6 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
 
        fstrcpy(user, c_user);
 
-       sid_copy(&local_sid, get_global_sam_sid());
-
-       if (map_name_to_wellknown_sid(&sid, psid_name_use, user)){
-               fstring sid_str;
-               sid_copy( psid, &sid);
-               sid_to_string(sid_str, &sid);
-               DEBUG(10,("lookup_name: name %s = SID %s, type = %u\n", user, sid_str,
-                       (unsigned int)*psid_name_use ));
-               return True;
-       }
-
        (void)map_username(user);
 
        if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
@@ -889,10 +878,28 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
        
        become_root();
        if (pdb_getsampwnam(sam_account, user)) {
+               const DOM_SID *user_sid;
+
                unbecome_root();
-               sid_copy(psid, pdb_get_user_sid(sam_account));
-               *psid_name_use = SID_NAME_USER;
-               
+
+               user_sid = pdb_get_user_sid(sam_account);
+
+               if (!sid_check_is_in_our_domain(user_sid)) {
+                       DEBUG(0, ("User %s with invalid SID %s in passdb\n",
+                                 user, sid_string_static(user_sid)));
+                       return False;
+               }
+
+               sid_peek_rid(user_sid, rid);
+
+               if (pdb_get_acct_ctrl(sam_account) &
+                   (ACB_DOMTRUST|ACB_WSTRUST|ACB_SVRTRUST)) {
+                       /* We have to filter them out in lsa_lookupnames,
+                        * indicate that this is not a real user.  */
+                       *type = SID_NAME_COMPUTER;
+               } else {
+                       *type = SID_NAME_USER;
+               }
                pdb_free_sam(&sam_account);
                return True;
        }
@@ -905,41 +912,51 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
 
        /* check if it's a mapped group */
        if (pdb_getgrnam(&map, user)) {
-               /* yes it's a mapped group */
-               sid_copy(&local_sid, &map.sid);
-               *psid_name_use = map.sid_name_use;
-       } else {
-               /* it's not a mapped group */
-               grp = getgrnam(user);
-               if(!grp) {
-                       unbecome_root();                /* ---> exit form block */      
+
+               unbecome_root();
+
+               /* BUILTIN groups are looked up elsewhere */
+               if (!sid_check_is_in_our_domain(&map.sid)) {
+                       DEBUG(10, ("Found group %s (%s) not in our domain -- "
+                                  "ignoring.", user,
+                                  sid_string_static(&map.sid)));
                        return False;
                }
                
-               /* 
-                *check if it's mapped, if it is reply it doesn't exist
-                *
-                * that's to prevent this case:
-                *
-                * unix group ug is mapped to nt group ng
-                * someone does a lookup on ug
-                * we must not reply as it doesn't "exist" anymore
-                * for NT. For NT only ng exists.
-                * JFM, 30/11/2001
-                */
+               /* yes it's a mapped group */
+               sid_peek_rid(&map.sid, rid);
+               *type = map.sid_name_use;
+               return True;
+       }
+
+       /* it's not a mapped group */
+       grp = getgrnam(user);
+       if(!grp) {
+               unbecome_root();                /* ---> exit form block */      
+               return False;
+       }
                
-               if (pdb_getgrgid(&map, grp->gr_gid)){
-                       unbecome_root();                /* ---> exit form block */
-                       return False;
-               }
+       /* 
+        *check if it's mapped, if it is reply it doesn't exist
+        *
+        * that's to prevent this case:
+        *
+        * unix group ug is mapped to nt group ng
+        * someone does a lookup on ug
+        * we must not reply as it doesn't "exist" anymore
+        * for NT. For NT only ng exists.
+        * JFM, 30/11/2001
+        */
                
-               sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
-               *psid_name_use = SID_NAME_ALIAS;
+       if (pdb_getgrgid(&map, grp->gr_gid)) {
+               unbecome_root();                /* ---> exit form block */
+               return False;
        }
        unbecome_root();
        /* END ROOT BLOCK */
 
-       sid_copy( psid, &local_sid);
+       *rid = pdb_gid_to_group_rid(grp->gr_gid);
+       *type = SID_NAME_ALIAS;
 
        return True;
 }
index 875e264bf01ff09ab043a5fa972f77d6db149f46..6ac5a3e965417b7c0d078c9b2f43859f6b8459cc 100644 (file)
@@ -699,6 +699,25 @@ static NTSTATUS context_lookup_rids(struct pdb_context *context,
                                                 rids, pp_names, pp_attrs);
 }
 
+static NTSTATUS context_lookup_names(struct pdb_context *context,
+                                    const DOM_SID *domain_sid,
+                                    size_t num_names,
+                                    const char **pp_names,
+                                    uint32 *rids,
+                                    uint32 *pp_attrs)
+{
+       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
+       if ((!context) || (!context->pdb_methods)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return ret;
+       }
+
+       return context->pdb_methods->lookup_names(context->pdb_methods,
+                                                 domain_sid, num_names,
+                                                 pp_names, rids, pp_attrs);
+}
+
 static NTSTATUS context_get_account_policy(struct pdb_context *context,
                                           int policy_index, uint32 *value)
 {
@@ -906,6 +925,7 @@ static NTSTATUS make_pdb_context(struct pdb_context **context)
        (*context)->pdb_enum_aliasmem = context_enum_aliasmem;
        (*context)->pdb_enum_alias_memberships = context_enum_alias_memberships;
        (*context)->pdb_lookup_rids = context_lookup_rids;
+       (*context)->pdb_lookup_names = context_lookup_names;
 
        (*context)->pdb_get_account_policy = context_get_account_policy;
        (*context)->pdb_set_account_policy = context_set_account_policy;
@@ -1413,6 +1433,22 @@ NTSTATUS pdb_lookup_rids(const DOM_SID *domain_sid,
                                            num_rids, rids, names, attrs);
 }
 
+NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid,
+                         int num_names,
+                         const char **names,
+                         uint32 *rids,
+                         uint32 *attrs)
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+       if (!pdb_context) {
+               return NT_STATUS_NOT_IMPLEMENTED;
+       }
+
+       return pdb_context->pdb_lookup_names(pdb_context, domain_sid,
+                                            num_names, names, rids, attrs);
+}
+
 BOOL pdb_get_account_policy(int policy_index, uint32 *value)
 {
        struct pdb_context *pdb_context = pdb_get_static_context(False);
@@ -1655,14 +1691,11 @@ NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
        if (sid_check_is_builtin(domain_sid)) {
 
                for (i=0; i<num_rids; i++) {
-                       fstring name;
+                       char *name;
 
-                       if (lookup_builtin_rid(rids[i], name)) {
+                       if (lookup_builtin_rid(names, rids[i], &name)) {
                                attrs[i] = SID_NAME_ALIAS;
-                               names[i] = talloc_strdup(names, name);
-                               if (names[i] == NULL) {
-                                       return NT_STATUS_NO_MEMORY;
-                               }
+                               names[i] = name;
                                DEBUG(5,("lookup_rids: %s:%d\n",
                                         names[i], attrs[i]));
                                have_mapped = True;
@@ -1680,14 +1713,69 @@ NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
        }
 
        for (i = 0; i < num_rids; i++) {
-               fstring tmpname;
-               enum SID_NAME_USE type;
-
-               if (lookup_global_sam_rid(rids[i], tmpname, &type)) {
-                       attrs[i] = (uint32)type;
-                       names[i] = talloc_strdup(names, tmpname);
-                       if (names[i] == NULL)
-                               return NT_STATUS_NO_MEMORY;
+               char *name;
+
+               if (lookup_global_sam_rid(names, rids[i], &name, &attrs[i])) {
+                       names[i] = name;
+                       DEBUG(5,("lookup_rids: %s:%d\n", names[i], attrs[i]));
+                       have_mapped = True;
+               } else {
+                       have_unmapped = True;
+                       attrs[i] = SID_NAME_UNKNOWN;
+               }
+       }
+
+ done:
+
+       result = NT_STATUS_NONE_MAPPED;
+
+       if (have_mapped)
+               result = have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
+
+       return result;
+}
+
+NTSTATUS pdb_default_lookup_names(struct pdb_methods *methods,
+                                 const DOM_SID *domain_sid,
+                                 int num_names,
+                                 const char **names,
+                                 uint32 *rids,
+                                 uint32 *attrs)
+{
+       int i;
+       NTSTATUS result;
+       BOOL have_mapped = False;
+       BOOL have_unmapped = False;
+
+       if (sid_check_is_builtin(domain_sid)) {
+
+               for (i=0; i<num_names; i++) {
+                       uint32 rid;
+
+                       if (lookup_builtin_name(names[i], &rid)) {
+                               attrs[i] = SID_NAME_ALIAS;
+                               rids[i] = rid;
+                               DEBUG(5,("lookup_rids: %s:%d\n",
+                                        names[i], attrs[i]));
+                               have_mapped = True;
+                       } else {
+                               have_unmapped = True;
+                               attrs[i] = SID_NAME_UNKNOWN;
+                       }
+               }
+               goto done;
+       }
+
+       /* Should not happen, but better check once too many */
+       if (!sid_check_is_domain(domain_sid)) {
+               return NT_STATUS_INVALID_HANDLE;
+       }
+
+       for (i = 0; i < num_names; i++) {
+               char *name;
+
+               if (lookup_global_sam_rid(names, rids[i], &name, &attrs[i])) {
+                       names[i] = name;
                        DEBUG(5,("lookup_rids: %s:%d\n", names[i], attrs[i]));
                        have_mapped = True;
                } else {
index bf57e013fc5ad79a9997c791521b5102449ac7bc..c173a5ea868e8c6d183e5518f7c2233f27f05f18 100644 (file)
@@ -359,7 +359,7 @@ BOOL secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
        if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
 
        /* domain sid */
-       sid_copy(sid, &pass.domain_sid);
+       if (sid != NULL) sid_copy(sid, &pass.domain_sid);
                
        return True;
 }
diff --git a/source/passdb/util_builtin.c b/source/passdb/util_builtin.c
new file mode 100644 (file)
index 0000000..e22f5f3
--- /dev/null
@@ -0,0 +1,110 @@
+/* 
+   Unix SMB/CIFS implementation.
+   Translate BUILTIN names to SIDs and vice versa
+   Copyright (C) Volker Lendecke 2005
+      
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+struct rid_name_map {
+       uint32 rid;
+       const char *name;
+};
+
+static const struct rid_name_map builtin_aliases[] = {
+       { BUILTIN_ALIAS_RID_ADMINS,             "Administrators" },
+       { BUILTIN_ALIAS_RID_USERS,              "Users" },
+       { BUILTIN_ALIAS_RID_GUESTS,             "Guests" },
+       { BUILTIN_ALIAS_RID_POWER_USERS,        "Power Users" },
+       { BUILTIN_ALIAS_RID_ACCOUNT_OPS,        "Account Operators" },
+       { BUILTIN_ALIAS_RID_SYSTEM_OPS,         "Server Operators" },
+       { BUILTIN_ALIAS_RID_PRINT_OPS,          "Print Operators" },
+       { BUILTIN_ALIAS_RID_BACKUP_OPS,         "Backup Operators" },
+       { BUILTIN_ALIAS_RID_REPLICATOR,         "Replicator" },
+       { BUILTIN_ALIAS_RID_RAS_SERVERS,        "RAS Servers" },
+       { BUILTIN_ALIAS_RID_PRE_2K_ACCESS,      "Pre-Windows 2000 Compatible Access" },
+       {  0, NULL}};
+
+/*******************************************************************
+ Look up a rid in the BUILTIN domain
+ ********************************************************************/
+BOOL lookup_builtin_rid(TALLOC_CTX *mem_ctx, uint32 rid, char **name)
+{
+       const struct rid_name_map *aliases = builtin_aliases;
+
+       while (aliases->name != NULL) {
+               if (rid == aliases->rid) {
+                       *name = talloc_strdup(mem_ctx, aliases->name);
+                       return True;
+               }
+               aliases++;
+       }
+
+       return False;
+}
+
+/*******************************************************************
+ Look up a name in the BUILTIN domain
+ ********************************************************************/
+BOOL lookup_builtin_name(const char *name, uint32 *rid)
+{
+       const struct rid_name_map *aliases = builtin_aliases;
+
+       while (aliases->name != NULL) {
+               if (strequal(name, aliases->name)) {
+                       *rid = aliases->rid;
+                       return True;
+               }
+               aliases++;
+       }
+
+       return False;
+}
+
+/*****************************************************************
+ Return the name of the BUILTIN domain
+*****************************************************************/  
+
+const char *builtin_domain_name(void)
+{
+       return "BUILTIN";
+}
+
+/*****************************************************************
+ Check if the SID is the builtin SID (S-1-5-32).
+*****************************************************************/  
+
+BOOL sid_check_is_builtin(const DOM_SID *sid)
+{
+       return sid_equal(sid, &global_sid_Builtin);
+}
+
+/*****************************************************************
+ Check if the SID is one of the builtin SIDs (S-1-5-32-a).
+*****************************************************************/  
+
+BOOL sid_check_is_in_builtin(const DOM_SID *sid)
+{
+       DOM_SID dom_sid;
+       uint32 rid;
+
+       sid_copy(&dom_sid, sid);
+       sid_split_rid(&dom_sid, &rid);
+       
+       return sid_equal(&dom_sid, &global_sid_Builtin);
+}
+
diff --git a/source/passdb/util_sam_sid.c b/source/passdb/util_sam_sid.c
deleted file mode 100644 (file)
index 822b7f6..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-/* 
-   Unix SMB/CIFS implementation.
-   Samba utility functions
-   Copyright (C) Andrew Tridgell 1992-1998
-   Copyright (C) Luke Kenneth Caseson Leighton 1998-1999
-   Copyright (C) Jeremy Allison  1999
-   
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#define MAX_SID_NAMES  7
-
-typedef struct _known_sid_users {
-       uint32 rid;
-       enum SID_NAME_USE sid_name_use;
-       const char *known_user_name;
-} known_sid_users;
-
-struct sid_name_map_info
-{
-       const DOM_SID *sid;
-       const char *name;
-       const known_sid_users *known_users;
-};
-
-static const known_sid_users everyone_users[] = {
-       { 0, SID_NAME_WKN_GRP, "Everyone" },
-       {0, (enum SID_NAME_USE)0, NULL}};
-
-static const known_sid_users creator_owner_users[] = {
-       { 0, SID_NAME_WKN_GRP, "Creator Owner" },
-       { 1, SID_NAME_WKN_GRP, "Creator Group" },
-       {0, (enum SID_NAME_USE)0, NULL}};
-
-static const known_sid_users nt_authority_users[] = {
-       {  1, SID_NAME_WKN_GRP, "Dialup" },
-       {  2, SID_NAME_WKN_GRP, "Network"},
-       {  3, SID_NAME_WKN_GRP, "Batch"},
-       {  4, SID_NAME_WKN_GRP, "Interactive"},
-       {  6, SID_NAME_WKN_GRP, "Service"},
-       {  7, SID_NAME_WKN_GRP, "AnonymousLogon"},
-       {  8, SID_NAME_WKN_GRP, "Proxy"},
-       {  9, SID_NAME_WKN_GRP, "ServerLogon"},
-       { 10, SID_NAME_WKN_GRP, "Self"},
-       { 11, SID_NAME_WKN_GRP, "Authenticated Users"},
-       { 12, SID_NAME_WKN_GRP, "Restricted"},
-       { 13, SID_NAME_WKN_GRP, "Terminal Server User"},
-       { 14, SID_NAME_WKN_GRP, "Remote Interactive Logon"},
-       { 15, SID_NAME_WKN_GRP, "This Organization"},
-       { 18, SID_NAME_WKN_GRP, "SYSTEM"},
-       { 19, SID_NAME_WKN_GRP, "Local Service"},
-       { 20, SID_NAME_WKN_GRP, "Network Service"},
-       {  0, (enum SID_NAME_USE)0, NULL}};
-
-static const known_sid_users builtin_groups[] = {
-       { BUILTIN_ALIAS_RID_ADMINS, SID_NAME_ALIAS, "Administrators" },
-       { BUILTIN_ALIAS_RID_USERS, SID_NAME_ALIAS, "Users" },
-       { BUILTIN_ALIAS_RID_GUESTS, SID_NAME_ALIAS, "Guests" },
-       { BUILTIN_ALIAS_RID_POWER_USERS, SID_NAME_ALIAS, "Power Users" },
-       { BUILTIN_ALIAS_RID_ACCOUNT_OPS, SID_NAME_ALIAS, "Account Operators" },
-       { BUILTIN_ALIAS_RID_SYSTEM_OPS, SID_NAME_ALIAS, "Server Operators" },
-       { BUILTIN_ALIAS_RID_PRINT_OPS, SID_NAME_ALIAS, "Print Operators" },
-       { BUILTIN_ALIAS_RID_BACKUP_OPS, SID_NAME_ALIAS, "Backup Operators" },
-       { BUILTIN_ALIAS_RID_REPLICATOR, SID_NAME_ALIAS, "Replicator" },
-       { BUILTIN_ALIAS_RID_RAS_SERVERS, SID_NAME_ALIAS, "RAS Servers" },
-       { BUILTIN_ALIAS_RID_PRE_2K_ACCESS, SID_NAME_ALIAS, "Pre-Windows 2000 Compatible Access" },
-       {  0, (enum SID_NAME_USE)0, NULL}};
-
-static struct sid_name_map_info special_domains[] = {
-       { &global_sid_Builtin, "BUILTIN", builtin_groups },
-       { &global_sid_World_Domain, "", everyone_users },
-       { &global_sid_Creator_Owner_Domain, "", creator_owner_users },
-       { &global_sid_NT_Authority, "NT Authority", nt_authority_users },
-       { NULL, NULL, NULL }};
-
-/**************************************************************************
- Turns a domain SID into a name, returned in the nt_domain argument.
-***************************************************************************/
-
-BOOL map_domain_sid_to_name(const DOM_SID *sid, fstring nt_domain)
-{
-       fstring sid_str;
-       int i = 0;
-       
-       sid_to_string(sid_str, sid);
-
-       DEBUG(5,("map_domain_sid_to_name: %s\n", sid_str));
-
-       while (special_domains[i].sid != NULL) {
-               DEBUG(5,("map_domain_sid_to_name: compare: %s\n",
-                        sid_string_static(special_domains[i].sid)));
-               if (sid_equal(special_domains[i].sid, sid)) {           
-                       fstrcpy(nt_domain, special_domains[i].name);
-                       DEBUG(5,("map_domain_sid_to_name: found '%s'\n",
-                                nt_domain));
-                       return True;
-               }
-               i++;
-       }
-
-       DEBUG(5,("map_domain_sid_to_name: mapping for %s not found\n",
-                sid_string_static(sid)));
-
-       return False;
-}
-
-/**************************************************************************
- Looks up a known username from one of the known domains.
-***************************************************************************/
-
-BOOL lookup_special_sid(const DOM_SID *sid, const char **domain,
-                       const char **name, enum SID_NAME_USE *type)
-{
-       int i;
-       DOM_SID dom_sid;
-       uint32 rid;
-       const known_sid_users *users = NULL;
-
-       sid_copy(&dom_sid, sid);
-       if (!sid_split_rid(&dom_sid, &rid)) {
-               DEBUG(2, ("Could not split rid from SID\n"));
-               return False;
-       }
-
-       for (i=0; special_domains[i].sid != NULL; i++) {
-               if (sid_equal(&dom_sid, special_domains[i].sid)) {
-                       *domain = special_domains[i].name;
-                       users = special_domains[i].known_users;
-                       break;
-               }
-       }
-
-       if (users == NULL) {
-               DEBUG(10, ("SID %s is no special sid\n",
-                          sid_string_static(sid)));
-               return False;
-       }
-
-       for (i=0; users[i].known_user_name != NULL; i++) {
-               if (rid == users[i].rid) {
-                       *name = users[i].known_user_name;
-                       *type = users[i].sid_name_use;
-                       return True;
-               }
-       }
-
-       DEBUG(10, ("RID of special SID %s not found\n",
-                  sid_string_static(sid)));
-
-       return False;
-}
-
-/*******************************************************************
- Look up a rid in the BUILTIN domain
- ********************************************************************/
-BOOL lookup_builtin_rid(uint32 rid, fstring name)
-{
-       const known_sid_users *aliases = builtin_groups;
-       int i;
-
-       for (i=0; aliases[i].known_user_name != NULL; i++) {
-               if (rid == aliases[i].rid) {
-                       fstrcpy(name, aliases[i].known_user_name);
-                       return True;
-               }
-       }
-
-       return False;
-}
-
-/*****************************************************************
- Check if the SID is our domain SID (S-1-5-21-x-y-z).
-*****************************************************************/  
-
-BOOL sid_check_is_domain(const DOM_SID *sid)
-{
-       return sid_equal(sid, get_global_sam_sid());
-}
-
-/*****************************************************************
- Check if the SID is our domain SID (S-1-5-21-x-y-z).
-*****************************************************************/  
-
-BOOL sid_check_is_in_our_domain(const DOM_SID *sid)
-{
-       DOM_SID dom_sid;
-       uint32 rid;
-
-       sid_copy(&dom_sid, sid);
-       sid_split_rid(&dom_sid, &rid);
-       
-       return sid_equal(&dom_sid, get_global_sam_sid());
-}
-
-/**************************************************************************
- Try and map a name to one of the well known SIDs.
-***************************************************************************/
-
-BOOL map_name_to_wellknown_sid(DOM_SID *sid, enum SID_NAME_USE *use, const char *name)
-{
-       int i, j;
-
-       DEBUG(10,("map_name_to_wellknown_sid: looking up %s\n", name));
-
-       for (i=0; special_domains[i].sid != NULL; i++) {
-               const known_sid_users *users = special_domains[i].known_users;
-
-               if (users == NULL)
-                       continue;
-
-               for (j=0; users[j].known_user_name != NULL; j++) {
-                       if ( strequal(users[j].known_user_name, name) ) {
-                               sid_copy(sid, special_domains[i].sid);
-                               sid_append_rid(sid, users[j].rid);
-                               *use = users[j].sid_name_use;
-                               return True;
-                       }
-               }
-       }
-
-       return False;
-}
-
-
diff --git a/source/passdb/util_wellknown.c b/source/passdb/util_wellknown.c
new file mode 100644 (file)
index 0000000..b1eb8b4
--- /dev/null
@@ -0,0 +1,149 @@
+/* 
+   Unix SMB/CIFS implementation.
+   Lookup routines for well-known SIDs
+   Copyright (C) Andrew Tridgell 1992-1998
+   Copyright (C) Luke Kenneth Caseson Leighton 1998-1999
+   Copyright (C) Jeremy Allison  1999
+   Copyright (C) Volker Lendecke 2005
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+struct rid_name_map {
+       uint32 rid;
+       const char *name;
+};
+
+struct sid_name_map_info
+{
+       const DOM_SID *sid;
+       const char *name;
+       const struct rid_name_map *known_users;
+};
+
+static const struct rid_name_map everyone_users[] = {
+       { 0, "Everyone" },
+       { 0, NULL}};
+
+static const struct rid_name_map creator_owner_users[] = {
+       { 0, "Creator Owner" },
+       { 1, "Creator Group" },
+       { 0, NULL}};
+
+static const struct rid_name_map nt_authority_users[] = {
+       {  1, "Dialup" },
+       {  2, "Network"},
+       {  3, "Batch"},
+       {  4, "Interactive"},
+       {  6, "Service"},
+       {  7, "AnonymousLogon"},
+       {  8, "Proxy"},
+       {  9, "ServerLogon"},
+       { 10, "Self"},
+       { 11, "Authenticated Users"},
+       { 12, "Restricted"},
+       { 13, "Terminal Server User"},
+       { 14, "Remote Interactive Logon"},
+       { 15, "This Organization"},
+       { 18, "SYSTEM"},
+       { 19, "Local Service"},
+       { 20, "Network Service"},
+       {  0,  NULL}};
+
+static struct sid_name_map_info special_domains[] = {
+       { &global_sid_World_Domain, "", everyone_users },
+       { &global_sid_Creator_Owner_Domain, "", creator_owner_users },
+       { &global_sid_NT_Authority, "NT Authority", nt_authority_users },
+       { NULL, NULL, NULL }};
+
+/**************************************************************************
+ Looks up a known username from one of the known domains.
+***************************************************************************/
+
+BOOL lookup_wellknown_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
+                         char **domain, char **name)
+{
+       int i;
+       DOM_SID dom_sid;
+       uint32 rid;
+       const struct rid_name_map *users = NULL;
+
+       sid_copy(&dom_sid, sid);
+       if (!sid_split_rid(&dom_sid, &rid)) {
+               DEBUG(2, ("Could not split rid from SID\n"));
+               return False;
+       }
+
+       for (i=0; special_domains[i].sid != NULL; i++) {
+               if (sid_equal(&dom_sid, special_domains[i].sid)) {
+                       *domain = talloc_strdup(mem_ctx,
+                                               special_domains[i].name);
+                       users = special_domains[i].known_users;
+                       break;
+               }
+       }
+
+       if (users == NULL) {
+               DEBUG(10, ("SID %s is no special sid\n",
+                          sid_string_static(sid)));
+               return False;
+       }
+
+       for (i=0; users[i].name != NULL; i++) {
+               if (rid == users[i].rid) {
+                       *name = talloc_strdup(mem_ctx, users[i].name);
+                       return True;
+               }
+       }
+
+       DEBUG(10, ("RID of special SID %s not found\n",
+                  sid_string_static(sid)));
+
+       return False;
+}
+
+/**************************************************************************
+ Try and map a name to one of the well known SIDs.
+***************************************************************************/
+
+BOOL lookup_wellknown_name(TALLOC_CTX *mem_ctx, const char *name,
+                          DOM_SID *sid, char **domain)
+{
+       int i, j;
+
+       DEBUG(10,("map_name_to_wellknown_sid: looking up %s\n", name));
+
+       for (i=0; special_domains[i].sid != NULL; i++) {
+               const struct rid_name_map *users =
+                       special_domains[i].known_users;
+
+               if (users == NULL)
+                       continue;
+
+               for (j=0; users[j].name != NULL; j++) {
+                       if ( strequal(users[j].name, name) ) {
+                               sid_copy(sid, special_domains[i].sid);
+                               sid_append_rid(sid, users[j].rid);
+                               *domain = talloc_strdup(
+                                       mem_ctx, special_domains[i].name);
+                               return True;
+                       }
+               }
+       }
+
+       return False;
+}
index b56ae1091412b2554c2acbf007aeb983a4574424..78e9cd6211252f0b39815ea86a9c7987203da918 100644 (file)
@@ -135,67 +135,75 @@ static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
  init_lsa_rid2s
  ***************************************************************************/
 
-static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
-                               int num_entries, UNISTR2 *name,
-                               uint32 *mapped_count, BOOL endian)
+static int init_lsa_rid2s(TALLOC_CTX *mem_ctx,
+                         DOM_R_REF *ref, DOM_RID2 *rid2,
+                         int num_entries, UNISTR2 *name,
+                         int flags)
 {
-       int i;
-       int total = 0;
-       *mapped_count = 0;
+       int mapped_count, i;
 
        SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
 
+       mapped_count = 0;
+
        become_root(); /* lookup_name can require root privs */
 
        for (i = 0; i < num_entries; i++) {
                BOOL status = False;
                DOM_SID sid;
-               uint32 rid = 0xffffffff;
-               int dom_idx = -1;
-               pstring full_name;
-               fstring dom_name, user;
-               enum SID_NAME_USE name_type = SID_NAME_UNKNOWN;
+               uint32 rid;
+               int dom_idx;
+               char *full_name, *domain;
+               enum SID_NAME_USE type = SID_NAME_UNKNOWN;
 
                /* Split name into domain and user component */
 
-               unistr2_to_ascii(full_name, &name[i], sizeof(full_name));
-               split_domain_name(full_name, dom_name, user);
-
-               /* Lookup name */
+               if (rpcstr_pull_unistr2_talloc(mem_ctx, &full_name,
+                                              &name[i]) < 0) {
+                       DEBUG(0, ("pull_ucs2_talloc failed\n"));
+                       return 0;
+               }
 
                DEBUG(5, ("init_lsa_rid2s: looking up name %s\n", full_name));
 
-               status = lookup_name(dom_name, user, &sid, &name_type);
-
-               if((name_type == SID_NAME_UNKNOWN) && (lp_server_role() == ROLE_DOMAIN_MEMBER)  && (strncmp(dom_name, full_name, strlen(dom_name)) != 0)) {
-                       DEBUG(5, ("init_lsa_rid2s: domain name not provided and local account not found, using member domain\n"));
-                       fstrcpy(dom_name, lp_workgroup());
-                       status = lookup_name(dom_name, user, &sid, &name_type);
-               }
+               /* We can ignore the result of lookup_name, it will not touch
+                  "type" if it's not successful */
 
-               if (name_type == SID_NAME_WKN_GRP) {
-                       /* BUILTIN aliases are still aliases :-) */
-                       name_type = SID_NAME_ALIAS;
-               }
+               lookup_name(mem_ctx, full_name, flags, &domain, NULL,
+                           &sid, &type);
 
                DEBUG(5, ("init_lsa_rid2s: %s\n", status ? "found" : 
                          "not found"));
 
-               if (status && name_type != SID_NAME_UNKNOWN) {
+               switch (type) {
+               case SID_NAME_USER:
+               case SID_NAME_DOM_GRP:
+               case SID_NAME_DOMAIN:
+               case SID_NAME_ALIAS:
+               case SID_NAME_WKN_GRP:
+                       /* Leave these unchanged */
+                       break;
+               default:
+                       /* Don't hand out anything but the list above */
+                       type = SID_NAME_UNKNOWN;
+                       break;
+               }
+
+               rid = 0;
+               dom_idx = -1;
+
+               if (type != SID_NAME_UNKNOWN) {
                        sid_split_rid(&sid, &rid);
-                       dom_idx = init_dom_ref(ref, dom_name, &sid);
-                       (*mapped_count)++;
-               } else {
-                       dom_idx = -1;
-                       rid = 0;
-                       name_type = SID_NAME_UNKNOWN;
+                       dom_idx = init_dom_ref(ref, domain, &sid);
+                       mapped_count++;
                }
 
-               init_dom_rid2(&rid2[total], rid, name_type, dom_idx);
-               total++;
+               init_dom_rid2(&rid2[i], rid, type, dom_idx);
        }
 
        unbecome_root();
+
+       return mapped_count;
 }
 
 /***************************************************************************
@@ -250,42 +258,44 @@ static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME
                DOM_SID find_sid = sid[i].sid;
                uint32 rid = 0xffffffff;
                int dom_idx = -1;
-               fstring name, dom_name;
-               enum SID_NAME_USE sid_name_use = (enum SID_NAME_USE)0;
+               char *name, *domain;
+               enum SID_NAME_USE type = SID_NAME_UNKNOWN;
 
-               sid_to_string(name, &find_sid);
-               DEBUG(5, ("init_lsa_trans_names: looking up sid %s\n", name));
+               DEBUG(5, ("init_lsa_trans_names: looking up sid %s\n",
+                         sid_string_static(&find_sid)));
 
                /* Lookup sid from winbindd */
 
-               status = lookup_sid(&find_sid, dom_name, name, &sid_name_use);
+               status = lookup_sid(ctx, &find_sid, &domain, &name, &type);
 
                DEBUG(5, ("init_lsa_trans_names: %s\n", status ? "found" : 
                          "not found"));
 
                if (!status) {
-                       sid_name_use = SID_NAME_UNKNOWN;
-                       memset(dom_name, '\0', sizeof(dom_name));
-                       sid_to_string(name, &find_sid);
+                       type = SID_NAME_UNKNOWN;
+                       domain = talloc_strdup(ctx, "");
+                       name = talloc_strdup(ctx,
+                                            sid_string_static(&find_sid));
                        dom_idx = -1;
 
-                       DEBUG(10,("init_lsa_trans_names: added unknown user '%s' to "
-                                 "referenced list.\n", name ));
+                       DEBUG(10,("init_lsa_trans_names: added unknown user "
+                                 "'%s' to referenced list.\n", name ));
                } else {
                        (*mapped_count)++;
                        /* Store domain sid in ref array */
                        if (find_sid.num_auths == 5) {
                                sid_split_rid(&find_sid, &rid);
                        }
-                       dom_idx = init_dom_ref(ref, dom_name, &find_sid);
+                       dom_idx = init_dom_ref(ref, domain, &find_sid);
 
-                       DEBUG(10,("init_lsa_trans_names: added %s '%s\\%s' (%d) to referenced list.\n", 
-                               sid_type_lookup(sid_name_use), dom_name, name, sid_name_use ));
+                       DEBUG(10,("init_lsa_trans_names: added %s '%s\\%s' "
+                                 "(%d) to referenced list.\n", 
+                                 sid_type_lookup(type), domain, name, type));
 
                }
 
                init_lsa_trans_name(&trn->name[total], &trn->uni_name[total],
-                                       sid_name_use, name, dom_idx);
+                                   type, name, dom_idx);
                total++;
        }
 
@@ -697,12 +707,18 @@ NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP
        DOM_R_REF *ref;
        DOM_RID2 *rids;
        uint32 mapped_count = 0;
+       int flags = 0;
 
        if (num_entries >  MAX_LOOKUP_SIDS) {
                num_entries = MAX_LOOKUP_SIDS;
                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;
+       }
+
        ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
        rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID2, num_entries);
 
@@ -720,10 +736,11 @@ NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP
        if (!ref || !rids)
                return NT_STATUS_NO_MEMORY;
 
+       /* set up the LSA Lookup RIDs response */
+       mapped_count = init_lsa_rid2s(p->mem_ctx, ref, rids, num_entries,
+                                     names, flags);
 done:
 
-       /* set up the LSA Lookup RIDs response */
-       init_lsa_rid2s(ref, rids, num_entries, names, &mapped_count, p->endian);
        if (NT_STATUS_IS_OK(r_u->status)) {
                if (mapped_count == 0)
                        r_u->status = NT_STATUS_NONE_MAPPED;
@@ -1109,15 +1126,13 @@ NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVS
 NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u)
 {
        struct lsa_info *info=NULL;
-       fstring name, dom_name;
-       enum SID_NAME_USE type;
 
        /* find the connection policy handle. */
 
        if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
                return NT_STATUS_INVALID_HANDLE;
 
-       if (!lookup_sid(&info->sid, dom_name, name, &type))
+       if (!lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, NULL))
                return NT_STATUS_ACCESS_DENIED;
 
        /*
index 635d87076231817d9a38d155e0664081562b032f..13f3a3284b99614a458703e8403634ce8ce89b24 100644 (file)
@@ -1366,9 +1366,7 @@ NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAM
 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
 {
        uint32 rid[MAX_SAM_ENTRIES];
-       uint32 local_rid;
        enum SID_NAME_USE type[MAX_SAM_ENTRIES];
-       enum SID_NAME_USE local_type;
        int i;
        int num_rids = q_u->num_names2;
        DOM_SID pol_sid;
@@ -1400,42 +1398,30 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO
        
        for (i = 0; i < num_rids; i++) {
                fstring name;
-               DOM_SID sid;
                int ret;
 
                r_u->status = NT_STATUS_NONE_MAPPED;
+               type[i] = SID_NAME_UNKNOWN;
 
                rid [i] = 0xffffffff;
-               type[i] = SID_NAME_UNKNOWN;
 
                ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
 
-               /*
-                * we are only looking for a name
-                * the SID we get back can be outside
-                * the scope of the pol_sid
-                * 
-                * in clear: it prevents to reply to domain\group: yes
-                * when only builtin\group exists.
-                *
-                * a cleaner code is to add the sid of the domain we're looking in
-                * to the local_lookup_name function.
-                */
-                
-               if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
-                       sid_split_rid(&sid, &local_rid);
-                               
-                       if (sid_equal(&sid, &pol_sid)) {
-                               rid[i]=local_rid;
-
-                               /* Windows does not return WKN_GRP here, even
-                                * on lookups in builtin */
-                               type[i] = (local_type == SID_NAME_WKN_GRP) ?
-                                       SID_NAME_ALIAS : local_type;
-
-                               r_u->status = NT_STATUS_OK;
+               if (ret <= 0) {
+                       continue;
+               }
+
+               if (sid_check_is_builtin(&pol_sid)) {
+                       if (lookup_builtin_name(name, &rid[i])) {
+                               type[i] = SID_NAME_ALIAS;
                        }
-               }
+               } else {
+                       lookup_global_sam_name(name, &rid[i], &type[i]);
+               }
+
+               if (type[i] != SID_NAME_UNKNOWN) {
+                       r_u->status = NT_STATUS_OK;
+               }
        }
 
        init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
@@ -2247,6 +2233,41 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
        return r_u->status;
 }
 
+/* W2k3 seems to use the same check for all 3 objects that can be created via
+ * SAMR, if you try to create for example "Dialup" as an alias it says
+ * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
+ * database. */
+
+static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
+{
+       enum SID_NAME_USE type;
+       BOOL result;
+
+       become_root();
+       /* Lookup in our local databases (only LOOKUP_NAME_ISOLATED set)
+        * whether the name already exists */
+       result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_ISOLATED,
+                            NULL, NULL, NULL, &type);
+       unbecome_root();
+
+       if (!result) {
+               return NT_STATUS_OK;
+       }
+
+       DEBUG(5, ("trying to create %s, exists as %s\n",
+                 new_name, sid_type_lookup(type)));
+
+       if (type == SID_NAME_DOM_GRP) {
+               return NT_STATUS_GROUP_EXISTS;
+       }
+       if (type == SID_NAME_ALIAS) {
+               return NT_STATUS_ALIAS_EXISTS;
+       }
+
+       /* Yes, the default is NT_STATUS_USER_EXISTS */
+       return NT_STATUS_USER_EXISTS;
+}
+
 /*******************************************************************
  _samr_create_user
  Create an account, can be either a normal user or a machine.
@@ -2294,19 +2315,11 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
        rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
        strlower_m(account);
 
-       pdb_init_sam(&sam_pass);
-
-       become_root();
-       ret = pdb_getsampwnam(sam_pass, account);
-       unbecome_root();
-       if (ret == True) {
-               /* this account exists: say so */
-               pdb_free_sam(&sam_pass);
-               return NT_STATUS_USER_EXISTS;
+       nt_status = can_create(p->mem_ctx, account);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               return nt_status;
        }
 
-       pdb_free_sam(&sam_pass);
-
        /*********************************************************************
         * HEADS UP!  If we have to create a new user account, we have to get 
         * a new RID from somewhere.  This used to be done by the passdb 
@@ -2776,7 +2789,7 @@ NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_A
        /* append the alias' RID to it */
        
        if (!sid_append_rid(&sid, alias_rid))
-               return NT_STATUS_NO_SUCH_USER;
+               return NT_STATUS_NO_SUCH_ALIAS;
                
        /*check if access can be granted as requested by client. */
        
@@ -2793,12 +2806,21 @@ NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_A
        if ( !NT_STATUS_IS_OK(status) )
                return status;
 
-       /*
-        * we should check if the rid really exist !!!
-        * JFM.
-        */
+       {
+               /* Check we actually have the requested alias */
+               enum SID_NAME_USE type;
+               BOOL result;
 
-       /* associate the user's SID with the new handle. */
+               become_root();
+               result = lookup_sid(NULL, &sid, NULL, NULL, &type);
+               unbecome_root();
+
+               if (!result || (type != SID_NAME_ALIAS)) {
+                       return NT_STATUS_NO_SUCH_ALIAS;
+               }
+       }
+
+       /* associate the alias SID with the new handle. */
        if ((info = get_samr_info_by_sid(&sid)) == NULL)
                return NT_STATUS_NO_MEMORY;
                
@@ -2814,12 +2836,11 @@ NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_A
 /*******************************************************************
  set_user_info_7
  ********************************************************************/
-static NTSTATUS set_user_info_7(const SAM_USER_INFO_7 *id7, SAM_ACCOUNT *pwd)
+static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
+                               const SAM_USER_INFO_7 *id7, SAM_ACCOUNT *pwd)
 {
        fstring new_name;
-       SAM_ACCOUNT *check_acct = NULL;
        NTSTATUS rc;
-       BOOL check_rc;
 
        if (id7 == NULL) {
                DEBUG(5, ("set_user_info_7: NULL id7\n"));
@@ -2842,13 +2863,9 @@ static NTSTATUS set_user_info_7(const SAM_USER_INFO_7 *id7, SAM_ACCOUNT *pwd)
           simply that the rename fails with a slightly different status
           code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
 
-       pdb_init_sam(&check_acct);
-       check_rc = pdb_getsampwnam(check_acct, new_name);
-       pdb_free_sam(&check_acct);
-
-       if (check_rc == True) {
-               /* this account exists: say so */
-               return NT_STATUS_USER_EXISTS;
+       rc = can_create(mem_ctx, new_name);
+       if (!NT_STATUS_IS_OK(rc)) {
+               return rc;
        }
 
        rc = pdb_rename_sam_account(pwd, new_name);
@@ -3365,7 +3382,8 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
        
        switch (switch_value) {
                case 7:
-                       r_u->status = set_user_info_7(ctr->info.id7, pwd);
+                       r_u->status = set_user_info_7(p->mem_ctx,
+                                                     ctr->info.id7, pwd);
                        break;
                case 16:
                        if (!set_user_info_16(ctr->info.id16, pwd))
@@ -4199,9 +4217,10 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S
 
        unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
 
-       /* check if group already exist */
-       if ((grp=getgrnam(name)) != NULL)
-               return NT_STATUS_GROUP_EXISTS;
+       r_u->status = can_create(p->mem_ctx, name);
+       if (!NT_STATUS_IS_OK(r_u->status)) {
+               return r_u->status;
+       }
 
        se_priv_copy( &se_rights, &se_add_users );
        can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
@@ -4289,6 +4308,11 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S
        if (!sid_equal(&dom_sid, get_global_sam_sid()))
                return NT_STATUS_ACCESS_DENIED;
 
+       r_u->status = can_create(p->mem_ctx, name);
+       if (!NT_STATUS_IS_OK(r_u->status)) {
+               return r_u->status;
+       }
+
        unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
 
        se_priv_copy( &se_rights, &se_add_users );
index 1e2a2488515f72f45f163a522a6d24bab8035788..90e36e2a83941ecde0e30eeb3074cc96ae24a352 100644 (file)
@@ -1837,9 +1837,6 @@ static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *para
        gid_t *gids;
        size_t num_groups;
        size_t i;
-       fstring grp_domain;
-       fstring grp_name;
-       enum SID_NAME_USE grp_type;
        struct passwd *passwd;
        NTSTATUS result;
 
@@ -1896,9 +1893,12 @@ static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *para
                goto out;
 
        for (i=0; i<num_groups; i++) {
+
+               char *grp_name;
        
-               if ( lookup_sid(&sids[i], grp_domain, grp_name, &grp_type) ) {
-                       pstrcpy(p, grp_name); 
+               if ( lookup_sid(sampw->mem_ctx, &sids[i], NULL, &grp_name,
+                               NULL) ) {
+                       pstrcpy(p, grp_name);
                        p += 21; 
                        count++;
                }