Started to canonicalize our handling of uid -> sid code in order to
authorJeremy Allison <jra@samba.org>
Wed, 2 Aug 2000 02:11:55 +0000 (02:11 +0000)
committerJeremy Allison <jra@samba.org>
Wed, 2 Aug 2000 02:11:55 +0000 (02:11 +0000)
get ready and fix se_access_check().
Added cannonical lookup_name(), lookup_sid(), uid_to_sid(), gid_to_sid()
functions that look via winbind first the fall back on local lookup.

All Samba should use these rather than trying to call winbindd code
directly.

Added NT_USER_TOKEN struct in user_struct, contains list of NT sids
associated with this user.

se_access_check() should use this (cached) value rather than attempting
to do the same thing itself when given a uid/gid pair.

More work needs to be done to preserve these things accross security
context changes (especially with the tricky pipe problem) but I'm
beginning to see how this will be done..... probably by registering
a new vuid for an authenticated RPC pipe and not treating the
pipe calls specially.

More thoughts needed - but we're almost there...

Jeremy.
(This used to be commit 5e5cc6efe2e4687be59085f562caea1e2e05d0a8)

13 files changed:
source3/include/proto.h
source3/include/smb.h
source3/lib/util_seaccess.c
source3/nsswitch/wb_client.c
source3/passdb/passdb.c
source3/rpc_server/srv_lsa.c
source3/rpc_server/srv_samr.c
source3/smbd/password.c
source3/smbd/process.c
source3/smbd/sec_ctx.c
source3/smbd/service.c
source3/smbd/uid.c
source3/smbd/unix_acls.c

index 85ea676736809f7a985509a56f92aabb7d2b62ba..321f3098e90c50aad2f56e29f65cbf1b6c2a32d0 100644 (file)
@@ -1278,8 +1278,12 @@ void expire_workgroups_and_servers(time_t t);
 BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type);
 BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, 
                        uint8 *name_type);
-BOOL winbind_uid_to_sid(uid_t uid, DOM_SID *sid);
-BOOL winbind_gid_to_sid(gid_t gid, DOM_SID *sid);
+BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid);
+BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid);
+BOOL lookup_name(char *name, DOM_SID *psid, uint8 *name_type);
+BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, uint8 *name_type);
+DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid);
+DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid);
 
 /*The following definitions come from  nsswitch/wb_common.c  */
 
@@ -1622,9 +1626,10 @@ gid_t pdb_user_rid_to_gid(uint32 user_rid);
 uint32 pdb_uid_to_user_rid(uid_t uid);
 uint32 pdb_gid_to_group_rid(gid_t gid);
 BOOL pdb_rid_is_user(uint32 rid);
-BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use);
-BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use);
-BOOL setup_user_sids(user_struct *vuser);
+BOOL local_lookup_rid(uint32 rid, char *name, uint8 *psid_name_use);
+BOOL local_lookup_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use);
+DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid);
+DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid);
 
 /*The following definitions come from  passdb/secrets.c  */
 
@@ -3540,8 +3545,8 @@ user_struct *get_valid_user_struct(uint16 vuid);
 void invalidate_vuid(uint16 vuid);
 char *validated_username(uint16 vuid);
 char *validated_domain(uint16 vuid);
-int setup_groups(char *user, char *domain, 
-                uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups);
+int initialize_groups(char *user, uid_t uid, gid_t gid);
+void setup_nt_token(NT_USER_TOKEN *token, uid_t uid, gid_t gid, int ngroups, gid_t *groups);
 uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, 
                     char *domain,BOOL guest);
 void add_session_user(char *user);
@@ -3667,6 +3672,7 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
 
 /*The following definitions come from  smbd/sec_ctx.c  */
 
+int get_current_groups(int *p_ngroups, gid_t **p_groups);
 BOOL push_sec_ctx(void);
 void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups);
 void set_root_sec_ctx(void);
index bc9f17544c67b43e041a00139319e0b4b629ab8c..aaebe56f33dbfc240004441c727e8bcb403b3fd1 100644 (file)
@@ -399,6 +399,15 @@ typedef struct sid_info
 
 } DOM_SID;
 
+/*
+ * The complete list of SIDS belonging to this user.
+ * Created when a vuid is registered.
+ */
+
+typedef struct _nt_user_token {
+       size_t num_sids;
+       DOM_SID *user_sids;
+} NT_USER_TOKEN;
 
 /*** query a local group, get a list of these: shows who is in that group ***/
 
@@ -556,8 +565,8 @@ typedef struct connection_struct
        char *connectpath;
        char *origpath;
 
-        struct vfs_ops vfs_ops;                   /* Filesystem operations */
-        struct vfs_connection_struct *vfs_conn;   /* VFS specific connection stuff */
+       struct vfs_ops vfs_ops;                   /* Filesystem operations */
+       struct vfs_connection_struct *vfs_conn;   /* VFS specific connection stuff */
 
        char *user; /* name of user who *opened* this connection */
        uid_t uid; /* uid of user who *opened* this connection */
@@ -1663,12 +1672,7 @@ typedef struct
        int n_groups;
        gid_t *groups;
 
-#if 0
-       NET_USER_INFO_3 usr; /* This should not be here. */
-#else
-       DOM_SID user_sid;
-       DOM_SID *group_sids;
-#endif
+       NT_USER_TOKEN nt_user_token;
 
        /* per-user authentication information on NT RPCs */
        /* lkclXXXX - THIS SHOULD NOT BE HERE! */
index 05a7a306350432f09a7a851c38e22fc25bbfc3a5..52696d2d306eef8e7349b247f5d3b15b4d534538 100644 (file)
@@ -99,12 +99,12 @@ static BOOL check_ace(SEC_ACE *ace, BOOL is_owner, DOM_SID *sid,
                sid_to_string(sid_str, sid);
                sid_to_string(ace_sid_str, &ace->sid);
 
-               if (!winbind_lookup_sid(sid, name_dom, name, &name_type)) {
+               if (!lookup_sid(sid, name_dom, name, &name_type)) {
                        fstrcpy(name_dom, "UNKNOWN");
                        fstrcpy(name, "UNKNOWN");
                }
 
-               if (!winbind_lookup_sid(&ace->sid, ace_name_dom, ace_name, 
+               if (!lookup_sid(&ace->sid, ace_name_dom, ace_name, 
                                        &name_type)) {
                        fstrcpy(ace_name_dom, "UNKNOWN");
                        fstrcpy(ace_name, "UNKNOWN");
@@ -208,6 +208,7 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
                     uint32 acc_desired, uint32 *acc_granted, uint32 *status)
 {
        DOM_SID user_sid, group_sid;
+       DOM_SID owner_sid;
        DOM_SID **group_sids = NULL;
        int i, j;
        uint ngroup_sids = 0;
@@ -215,25 +216,30 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
        uint8 check_ace_type;
        fstring sid_str;
 
-       if (!status || !acc_granted) return False;
+       if (!status || !acc_granted)
+               return False;
 
        *status = NT_STATUS_ACCESS_DENIED;
        *acc_granted = 0;
 
-       /* No security descriptor allows all access */
+       /*
+        * No security descriptor or security descriptor with no DACL
+        * present allows all access.
+        */
 
-       if (!sd) {
+       if (!sd || (sd && (!(sd->type & SEC_DESC_DACL_PRESENT) || sd->dacl == NULL))) {
                *status = NT_STATUS_NOPROBLEMO;
                *acc_granted = acc_desired;
                acc_desired = 0;
-               DEBUG(3, ("no sd, access allowed\n"));
-
-                goto done;
+               DEBUG(3, ("se_access_check: no sd or blank DACL, access allowed\n"));
+               goto done;
        }
 
        /* If desired access mask is empty then no access is allowed */
 
        if (acc_desired == 0) {
+               *status = NT_STATUS_ACCESS_DENIED;
+               *acc_granted = 0;
                goto done;
        }
 
@@ -246,12 +252,12 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
 
        /* Create user sid */
 
-       if (!winbind_uid_to_sid(user->uid, &user_sid)) {
+       if (!uid_to_sid(&user_sid, user->uid)) {
                DEBUG(3, ("could not lookup sid for uid %d\n", user->uid));
+               goto done;
        }
 
-       sid_to_string(sid_str, &user_sid);
-       DEBUG(3, ("user sid is %s\n", sid_str));
+       DEBUG(3, ("se_access_check: user sid is %s\n", sid_to_string(sid_str, &user_sid) ));
 
        /* If we're the owner, then we can do anything */
 
@@ -266,8 +272,9 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
 
        /* Create group sid */
 
-       if (!winbind_gid_to_sid(user->gid, &group_sid)) {
+       if (!gid_to_sid(&group_sid, user->gid)) {
                DEBUG(3, ("could not lookup sid for gid %d\n", user->gid));
+               goto done;
        }
 
        sid_to_string(sid_str, &group_sid);
@@ -279,7 +286,7 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
 
        for (i = 0; i < user->ngroups; i++) {
                if (user->groups[i] != user->gid) {
-                       if (winbind_gid_to_sid(user->groups[i], &group_sid)) {
+                       if (gid_to_sid(&group_sid, user->groups[i])) {
 
                                /* If we're a group member then we can also
                                   do anything */
@@ -310,18 +317,18 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
 
        acl = sd->dacl;
 
-        if (acl == NULL || acl->ace == NULL || acl->num_aces == 0) {
+       if (acl == NULL || acl->ace == NULL || acl->num_aces == 0) {
 
                /* Checks against a NULL ACL succeed and return access
-                  granted = access requested. */
+                       granted = access requested. */
 
                *status = NT_STATUS_NOPROBLEMO;
                *acc_granted = acc_desired;
                acc_desired = 0;
                DEBUG(3, ("null ace, access allowed\n"));
 
-                goto done;
-        }
+               goto done;
+       }
 
        /* Check each ACE in ACL.  We break out of the loop if an ACE is
           either explicitly denied or explicitly allowed by the
@@ -370,7 +377,8 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
        }
 
  done:
-        free_sid_array(ngroup_sids, group_sids);
+
+       free_sid_array(ngroup_sids, group_sids);
        
        /* If any access desired bits are still on, return access denied
           and turn off any bits already granted. */
@@ -380,5 +388,5 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
                *status = NT_STATUS_ACCESS_DENIED;
        }
 
-        return *status == NT_STATUS_NOPROBLEMO;
+       return *status == NT_STATUS_NOPROBLEMO;
 }
index 78de466636d32dbf212bd7aac936695a4ac5dd14..47f1520efa667b4ced17acb0611e7b4bbf0b4d5c 100644 (file)
@@ -29,7 +29,6 @@
 
 BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type)
 {
-       extern pstring global_myname;
        struct winbindd_request request;
        struct winbindd_response response;
        enum nss_status result;
@@ -47,14 +46,6 @@ BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type)
                                       &response)) == NSS_STATUS_SUCCESS) {
                string_to_sid(sid, response.data.sid.sid);
                *name_type = response.data.sid.type;
-       } else {
-
-               /*
-                * Try a local lookup - winbindd may not
-                * be running.
-                */
-
-               return lookup_local_name(global_myname, name, sid, name_type);
        }
 
        return result == NSS_STATUS_SUCCESS;
@@ -85,7 +76,7 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name,
                if (sid_equal(&global_sam_sid, &tmp_sid)) {
 
                return map_domain_sid_to_name(&tmp_sid, dom_name) &&
-                       lookup_local_rid(rid, name, name_type);
+                       local_lookup_rid(rid, name, name_type);
                }
        }
 
@@ -106,15 +97,6 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name,
        if (result == NSS_STATUS_SUCCESS) {
                parse_domain_user(response.data.name.name, dom_name, name);
                *name_type = response.data.name.type;
-       } else {
-
-               DEBUG(10,("winbind_lookup_sid: winbind lookup for %s failed - trying builtin.\n",
-                               sid_str));
-
-               sid_copy(&tmp_sid, sid);
-               sid_split_rid(&tmp_sid, &rid);
-               return map_domain_sid_to_name(&tmp_sid, dom_name) &&
-                       lookup_known_rid(&tmp_sid, rid, name, name_type);
        }
 
        return (result == NSS_STATUS_SUCCESS);
@@ -122,13 +104,14 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name,
 
 /* Call winbindd to convert uid to sid */
 
-BOOL winbind_uid_to_sid(uid_t uid, DOM_SID *sid)
+BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
 {
        struct winbindd_request request;
        struct winbindd_response response;
        int result;
 
-       if (!sid) return False;
+       if (!sid)
+               return False;
 
        /* Initialise request */
 
@@ -154,13 +137,14 @@ BOOL winbind_uid_to_sid(uid_t uid, DOM_SID *sid)
 
 /* Call winbindd to convert uid to sid */
 
-BOOL winbind_gid_to_sid(gid_t gid, DOM_SID *sid)
+BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid)
 {
        struct winbindd_request request;
        struct winbindd_response response;
        int result;
 
-       if (!sid) return False;
+       if (!sid)
+               return False;
 
        /* Initialise request */
 
@@ -183,3 +167,79 @@ BOOL winbind_gid_to_sid(gid_t gid, DOM_SID *sid)
 
        return (result == NSS_STATUS_SUCCESS);
 }
+
+
+
+/*****************************************************************
+ *THE CANNONICAL* convert name to SID function.
+ Tries winbind first - then uses local lookup.
+*****************************************************************/  
+
+BOOL lookup_name(char *name, DOM_SID *psid, uint8 *name_type)
+{
+       extern pstring global_myname;
+
+       if (!winbind_lookup_name(name, psid, name_type)) {
+
+               DEBUG(10,("lookup_name: winbind lookup for %s failed - trying local\n", name ));
+
+               return local_lookup_name(global_myname, name, psid, name_type);
+       }
+       return True;
+}
+
+/*****************************************************************
+ *THE CANNONICAL* convert SID to name function.
+ Tries winbind first - then uses local lookup.
+*****************************************************************/  
+
+BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, uint8 *name_type)
+{
+       if (!winbind_lookup_sid(sid, dom_name, name, name_type)) {
+               fstring sid_str;
+               DOM_SID tmp_sid;
+               uint32 rid;
+
+               DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str, sid) ));
+
+               sid_copy(&tmp_sid, sid);
+               sid_split_rid(&tmp_sid, &rid);
+               return map_domain_sid_to_name(&tmp_sid, dom_name) &&
+                               lookup_known_rid(&tmp_sid, rid, name, name_type);
+       }
+       return True;
+}
+
+/*****************************************************************
+ *THE CANNONICAL* convert uid_t to SID function.
+ Tries winbind first - then uses local lookup.
+ Returns SID pointer.
+*****************************************************************/  
+
+DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid)
+{
+       if (!winbind_uid_to_sid(psid, uid)) {
+               DEBUG(10,("uid_to_sid: winbind lookup for uid %u failed - trying local.\n", (unsigned int)uid ));
+
+               return local_uid_to_sid(psid, uid);
+       }
+
+       return psid;
+}
+
+/*****************************************************************
+ *THE CANNONICAL* convert gid_t to SID function.
+ Tries winbind first - then uses local lookup.
+ Returns SID pointer.
+*****************************************************************/  
+
+DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid)
+{
+       if (!winbind_gid_to_sid(psid, gid)) {
+               DEBUG(10,("gid_to_sid: winbind lookup for gid %u failed - trying local.\n", (unsigned int)gid ));
+
+               return local_gid_to_sid(psid, gid);
+       }
+
+       return psid;
+}
index 04f02e3704145bc4c8cb5de90e8aa28acbfd7780..f0fe2499dfd237f8668555a85ac890ad57b8d10d 100644 (file)
@@ -1091,12 +1091,12 @@ BOOL pdb_rid_is_user(uint32 rid)
  Convert a rid into a name. Used in the lookup SID rpc.
  ********************************************************************/
 
-BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
+BOOL local_lookup_rid(uint32 rid, char *name, uint8 *psid_name_use)
 {
 
        BOOL is_user = pdb_rid_is_user(rid);
 
-       DEBUG(5,("lookup_local_rid: looking up %s RID %u.\n", is_user ? "user" :
+       DEBUG(5,("local_lookup_rid: looking up %s RID %u.\n", is_user ? "user" :
                        "group", (unsigned int)rid));
 
        if(is_user) {
@@ -1118,7 +1118,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
 
                        *psid_name_use = SID_NAME_USER;
 
-                       DEBUG(5,("lookup_local_rid: looking up uid %u %s\n", (unsigned int)uid,
+                       DEBUG(5,("local_lookup_rid: looking up uid %u %s\n", (unsigned int)uid,
                                pass ? "succeeded" : "failed" ));
 
                        if(!pass) {
@@ -1128,7 +1128,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
 
                        fstrcpy(name, pass->pw_name);
 
-                       DEBUG(5,("lookup_local_rid: found user %s for rid %u\n", name,
+                       DEBUG(5,("local_lookup_rid: found user %s for rid %u\n", name,
                                (unsigned int)rid ));
                }
 
@@ -1138,7 +1138,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
 
                *psid_name_use = SID_NAME_ALIAS;
 
-               DEBUG(5,("lookup_local_rid: looking up gid %u %s\n", (unsigned int)gid,
+               DEBUG(5,("local_local_rid: looking up gid %u %s\n", (unsigned int)gid,
                        gr ? "succeeded" : "failed" ));
 
                if(!gr) {
@@ -1148,7 +1148,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
 
                fstrcpy( name, gr->gr_name);
 
-               DEBUG(5,("lookup_local_rid: found group %s for rid %u\n", name,
+               DEBUG(5,("local_lookup_rid: found group %s for rid %u\n", name,
                        (unsigned int)rid ));
        }
 
@@ -1159,7 +1159,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
  Convert a name into a SID. Used in the lookup name rpc.
  ********************************************************************/
 
-BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use)
+BOOL local_lookup_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use)
 {
        extern DOM_SID global_sid_World_Domain;
        struct passwd *pass = NULL;
@@ -1206,71 +1206,29 @@ BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name
 }
 
 /****************************************************************************
- Create a list of SIDS for a user - primary and group.
- This is really the wrong way to do this and needs to go via winbind. JRA.
+ Convert a uid to SID - locally.
 ****************************************************************************/
 
-BOOL setup_user_sids(user_struct *vuser)
+DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
 {
     extern DOM_SID global_sam_sid;
 
-       sid_copy(&vuser->user_sid, &global_sam_sid);
-       sid_append_rid( &vuser->user_sid, pdb_uid_to_user_rid(vuser->uid));
+       sid_copy(psid, &global_sam_sid);
+       sid_append_rid(psid, pdb_uid_to_user_rid(uid));
 
-       if (vuser->n_groups != 0) {
-               int i;
+       return psid;
+}
 
-               vuser->group_sids = (DOM_SID *)malloc(sizeof(DOM_SID) * vuser->n_groups);
+/****************************************************************************
+ Convert a gid to SID - locally.
+****************************************************************************/
 
-               if (vuser->group_sids == NULL)
-                       return False;
+DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
+{
+    extern DOM_SID global_sam_sid;
 
-               for (i = 0; i < vuser->n_groups; i++) {
-                       sid_copy(&vuser->group_sids[i], &global_sam_sid);
-                       sid_append_rid( &vuser->group_sids[i], pdb_gid_to_group_rid(vuser->groups[i]));
-               }
-       }
+       sid_copy(psid, &global_sam_sid);
+       sid_append_rid(psid, pdb_gid_to_group_rid(gid));
 
-       return True;
-#if 0
-       /* Luke's code. */
-   if (usr == NULL)
-   {
-    int i;
-    extern DOM_SID global_sam_sid;
-    DEBUG(0,("vuser struct usr being filled in with trash, today\n"));
-    DEBUG(0,("this needs to be replaced with a proper surs impl.\n"));
-    DEBUG(0,("e.g. the one used in winbindd.  in fact, all\n"));
-    DEBUG(0,("occurrences of pdb_xxx_to_xxx should be replaced\n"));
-    DEBUG(0,("as soon as possible.\n"));
-    vuser->usr.user_id = pdb_uid_to_user_rid(uid);
-    vuser->usr.group_id = pdb_gid_to_group_rid(gid);
-    vuser->usr.num_groups = vuser->n_groups;
-    if (vuser->n_groups != 0)
-    {
-        vuser->usr.gids = g_new(DOM_GID, vuser->usr.num_groups);
-        if (vuser->usr.gids == NULL)
-            return UID_FIELD_INVALID;
-    }
-
-    for (i = 0; i < vuser->usr.num_groups; i++)
-    {
-        DOM_GID *ntgid = &vuser->usr.gids[i];
-        ntgid->attr = 0x7;
-        ntgid->g_rid = pdb_gid_to_group_rid(vuser->groups[i]);
-    }
-    /* this is possibly the worst thing to do, ever.  it assumes */
-    /* that all users of this system are in the local SAM database */
-    /* however, because there is no code to do anything otherwise, */
-    /* we have no choice */
-    init_dom_sid2(&vuser->usr.dom_sid, &global_sam_sid);
-   }
-   else
-   {
-      vuser->usr = *usr;
-   }                                           
-#endif
+       return psid;
 }
index bfb671d167d0b6f3b1ece166b8edad05833cc3cd..dc97d6db445095fb39679edc268331f9b3d83b7a 100644 (file)
@@ -238,7 +238,7 @@ static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
                if (map_domain_name_to_sid(&dom_sid, dom_name)) {
                        dom_idx = init_dom_ref(ref, dom_name, &dom_sid);
 
-                       if (lookup_local_name(dom_name, user, &sid, &sid_name_use) && sid_split_rid(&sid, &rid)) 
+                       if (local_lookup_name(dom_name, user, &sid, &sid_name_use) && sid_split_rid(&sid, &rid)) 
                                status = True;
                }
 
index 5a0f049ba75ff6ee16d16365e0bbaa51b3d8c1b5..e80175f71db8c7854a91ee665d20848ab958fa14 100644 (file)
@@ -978,7 +978,7 @@ static BOOL samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
   if(alias_rid == 0xffffffff)
       r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
 
-  if(!lookup_local_rid(alias_rid, alias, &type))
+  if(!local_lookup_rid(alias_rid, alias, &type))
     {
       r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
     }
@@ -1151,7 +1151,7 @@ static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
     if(sid_equal(&pol_sid, &global_sam_sid)) 
     {
       DOM_SID sid;
-      if(lookup_local_name(global_myname, name, 
+      if(local_lookup_name(global_myname, name, 
                           &sid, &type[i]))
        {
          sid_split_rid( &sid, &rid[i]);
index f9291b8705e49edfd15ac62588bbf191c8cfde80..0372e7a0f99901b8e9a858128de2187ffb4c4867 100644 (file)
@@ -112,6 +112,16 @@ user_struct *get_valid_user_struct(uint16 vuid)
   return &validated_users[vuid];
 }
 
+/****************************************************************************
+ Delete the SID list for this user.
+****************************************************************************/
+
+static void delete_nt_token(NT_USER_TOKEN *token)
+{
+       safe_free( token->user_sids );
+       ZERO_STRUCTP(token);
+}
+
 /****************************************************************************
 invalidate a uid
 ****************************************************************************/
@@ -133,8 +143,7 @@ void invalidate_vuid(uint16 vuid)
 
        vuser->groups  = NULL;
 
-       if (vuser->group_sids != NULL)
-               free (vuser->group_sids);
+       delete_nt_token(&vuser->nt_user_token);
 }
 
 
@@ -162,61 +171,54 @@ char *validated_domain(uint16 vuid)
 
 
 /****************************************************************************
-Setup the groups a user belongs to.
+ Initialize the groups a user belongs to.
 ****************************************************************************/
-int setup_groups(char *user, char *domain, 
-                uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups)
-{
-       int i,ngroups;
-       gid_t grp = 0;
-       gid_t *groups = NULL;
 
-       if (-1 == initgroups(user,gid))
-       {
+int initialize_groups(char *user, uid_t uid, gid_t gid)
+{
+       if (initgroups(user,gid) == -1) {
                DEBUG(0,("Unable to initgroups. Error was %s\n", strerror(errno) ));
-               if (getuid() == 0)
-               {
-                       if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767)
-                       {
+               if (getuid() == 0) {
+                       if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767) {
                                DEBUG(0,("This is probably a problem with the account %s\n", user));
                        }
                }
                return -1;
        }
+       return 0;
+}
 
-       ngroups = sys_getgroups(0,&grp);
-       if (ngroups <= 0)
-       {
-               ngroups = groups_max();
-       }
+/****************************************************************************
+ Create the SID list for this user.
+****************************************************************************/
 
-       if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL)
-       {
-               DEBUG(0,("setup_groups malloc fail !\n"));
-               return -1;
-       }
+void setup_nt_token(NT_USER_TOKEN *token, uid_t uid, gid_t gid, int ngroups, gid_t *groups)
+{
+       DOM_SID *psids;
+       int i;
 
-       ngroups = sys_getgroups(ngroups,groups);
+       ZERO_STRUCTP(token);
 
-       (*p_ngroups) = ngroups;
-       (*p_groups) = groups;
+       if ((token->user_sids = (DOM_SID *)malloc( (ngroups + 2)*sizeof(DOM_SID))) == NULL)
+               return;
 
-       DEBUG( 3, ( "%s is in %d groups: ", user, ngroups ) );
-       for (i = 0; i < ngroups; i++ )
-       {
-               DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) );
-       }
-       DEBUG( 3, ( "\n" ) );
+       psids = token->user_sids;
 
-       return 0;
-}
+       token->num_sids = ngroups + 2;
+
+       uid_to_sid( &psids[0], uid);
+       gid_to_sid( &psids[1], gid);
 
+       for (i = 0; i < ngroups; i++)
+               gid_to_sid( &psids[i+2], groups[i]);
+}
 
 /****************************************************************************
 register a uid/name pair as being valid and that a valid password
 has been given. vuid is biased by an offset. This allows us to
 tell random client vuid's (normally zero) from valid vuids.
 ****************************************************************************/
+
 uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, 
                     char *domain,BOOL guest)
 {
@@ -227,37 +229,15 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
   if(lp_security() == SEC_SHARE)
     return UID_FIELD_INVALID;
 
-#if 0
-  /*
-   * After observing MS-Exchange services writing to a Samba share
-   * I belive this code is incorrect. Each service does its own
-   * sessionsetup_and_X for the same user, and as each service shuts
-   * down, it does a user_logoff_and_X. As we are consolidating multiple
-   * sessionsetup_and_X's onto the same vuid here, when the first service
-   * shuts down, it invalidates all the open files for the other services.
-   * Hence I am removing this code and forcing each sessionsetup_and_X
-   * to get a new vuid.
-   * Jeremy Allison. (jallison@whistle.com).
-   */
-
-  int i;
-  for(i = 0; i < num_validated_users; i++) {
-    vuser = &validated_users[i];
-    if ( vuser->uid == uid )
-      return (uint16)(i + VUID_OFFSET); /* User already validated */
-  }
-#endif
-
   validated_users = (user_struct *)Realloc(validated_users,
                           sizeof(user_struct)*
                           (num_validated_users+1));
   
-  if (!validated_users)
-    {
+  if (!validated_users) {
       DEBUG(0,("Failed to realloc users struct!\n"));
       num_validated_users = 0;
       return UID_FIELD_INVALID;
-    }
+  }
 
   vuser = &validated_users[num_validated_users];
   num_validated_users++;
@@ -274,22 +254,21 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
 
   /* Find all the groups this uid is in and store them. 
      Used by become_user() */
-  setup_groups(unix_name,domain,uid,gid,
-              &vuser->n_groups,
-              &vuser->groups);
+  initialize_groups(unix_name, uid, gid);
+  get_current_groups( &vuser->n_groups, &vuser->groups);
 
-  setup_user_sids(vuser);
+  /* Create an NT_USER_TOKEN struct for this user. */
+  setup_nt_token(&vuser->nt_user_token, uid,gid, vuser->n_groups, vuser->groups);
 
   DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name));
 
   DEBUG(3, ("Clearing default real name\n"));
   fstrcpy(vuser->user.full_name, "<Full Name>");
   if (lp_unix_realname()) {
-    if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL)
-      {
+    if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) {
       DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos));
       fstrcpy(vuser->user.full_name, pwfile->pw_gecos);
-      }
+    }
   }
 
   memset(&vuser->dc, '\0', sizeof(vuser->dc));
index 2662db5896f89a5a06d511256bbf0b0d77588a39..37d8f8dd73a8fe60c4517584788a29ce763d9b24 100644 (file)
@@ -561,8 +561,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
       }
 
       /* load service specific parameters */
-      if (conn && 
-         !become_service(conn,(flags & AS_USER)?True:False)) {
+      if (conn && !become_service(conn,(flags & AS_USER)?True:False)) {
         return(ERROR(ERRSRV,ERRaccess));
       }
 
index f7ea1e2d868f000134c8aac1d404dbcf8c179604..432cb223e2f5e6d64a7a7317846341038550a782 100644 (file)
@@ -125,17 +125,37 @@ static void gain_root(void)
 
 /* Get the list of current groups */
 
-static void get_current_groups(int *ngroups, gid_t **groups)
+int get_current_groups(int *p_ngroups, gid_t **p_groups)
 {
-       *ngroups = getgroups(0, NULL);
-       *groups = (gid_t *)malloc(*ngroups * sizeof(gid_t));
+       int i;
+       gid_t grp;
+       int ngroups = sys_getgroups(0,&grp);
+       gid_t *groups;
+
+       (*p_ngroups) = 0;
+       (*p_groups) = NULL;
+
+       if (ngroups <= 0)
+               return -1;
+
+       if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL) {
+               DEBUG(0,("setup_groups malloc fail !\n"));
+               return -1;
+       }
+
+       if ((ngroups = sys_getgroups(ngroups,groups)) == -1)
+               return -1;
+
+       (*p_ngroups) = ngroups;
+       (*p_groups) = groups;
 
-       if (!groups) {
-               DEBUG(0, ("Out of memory in get_current_groups\n"));
-               return;
+       DEBUG( 3, ( "get_current_groups: uid %u is in %u groups: ", (unsigned int)getuid() , ngroups ) );
+       for (i = 0; i < ngroups; i++ ) {
+               DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) );
        }
+       DEBUG( 3, ( "\n" ) );
 
-       getgroups(*ngroups, *groups);
+    return ngroups;
 }
 
 /* Create a new security context on the stack.  It is the same as the old
index 2eab50c482df77b10852d22eba71ae8daa087756..d4760ca92da227a089c1f3969d436e8d812d0465 100644 (file)
@@ -511,8 +511,8 @@ connection_struct *make_connection(char *service,char *user,char *password, int
        if (!IS_IPC(conn)) {
                /* Find all the groups this uid is in and
                   store them. Used by become_user() */
-               setup_groups(conn->user,validated_domain(vuid),conn->uid,conn->gid,
-                            &conn->ngroups,&conn->groups);
+               initialize_groups(conn->user, conn->uid, conn->gid); 
+               get_current_groups(&conn->ngroups,&conn->groups);
                
                /* check number of connections */
                if (!claim_connection(conn,
index 172e872020347b1fb9232d79a2c51ff47bff12bc..4cb2c512b651303ff692ea938015caf1fcc90219 100644 (file)
@@ -38,7 +38,8 @@ BOOL become_guest(void)
        
        if (!pass)
                pass = Get_Pwnam(lp_guestaccount(-1),True);
-       if (!pass) return(False);
+       if (!pass)
+               return(False);
        
 #ifdef AIX
        /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before 
@@ -60,19 +61,21 @@ BOOL become_guest(void)
 
 static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
 {
-  int i;
-  for (i=0;i<conn->uid_cache.entries;i++)
-    if (conn->uid_cache.list[i] == vuser->uid) return(True);
+       int i;
+       for (i=0;i<conn->uid_cache.entries;i++)
+               if (conn->uid_cache.list[i] == vuser->uid)
+                       return(True);
 
-  if (!user_ok(vuser->user.unix_name,snum)) return(False);
+       if (!user_ok(vuser->user.unix_name,snum))
+               return(False);
 
-  i = conn->uid_cache.entries % UID_CACHE_SIZE;
-  conn->uid_cache.list[i] = vuser->uid;
+       i = conn->uid_cache.entries % UID_CACHE_SIZE;
+       conn->uid_cache.list[i] = vuser->uid;
 
-  if (conn->uid_cache.entries < UID_CACHE_SIZE)
-    conn->uid_cache.entries++;
+       if (conn->uid_cache.entries < UID_CACHE_SIZE)
+               conn->uid_cache.entries++;
 
-  return(True);
+       return(True);
 }
 
 /****************************************************************************
index 7a2dc6ab6ec9b068da157e250f03cc45a973a4ce..46c57af5de3c95f35955caeac4b4fdcae00032ad 100644 (file)
 
 static void create_file_sids(SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid)
 {
-  extern DOM_SID global_sam_sid;
-
-  sid_copy(powner_sid, &global_sam_sid);
-  sid_copy(pgroup_sid, &global_sam_sid);
-  sid_append_rid(powner_sid, pdb_uid_to_user_rid(psbuf->st_uid));
-  sid_append_rid(pgroup_sid, pdb_gid_to_group_rid(psbuf->st_gid));
+       uid_to_sid( powner_sid, psbuf->st_uid );
+       gid_to_sid( pgroup_sid, psbuf->st_gid );
 }
 
 /****************************************************************************