fixed a problem with getgroups() where it could include our current
authorAndrew Tridgell <tridge@samba.org>
Mon, 15 Jul 2002 03:59:14 +0000 (03:59 +0000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 15 Jul 2002 03:59:14 +0000 (03:59 +0000)
effective gid which could mean that the user gets group 0 in their
group list for acl interpretation

this is a replacement fix for the one richard did in 2.2 (which didn't
cope wiith variable behaviour depending on which nss module was in
use)

source/lib/util_sec.c
source/rpc_server/srv_pipe.c
source/smbd/password.c
source/smbd/sec_ctx.c

index d59b1b0471664a7b9a0f67cd4337a1418b67f89f..132748ce138e147b2ae019e78bb970ed7ca9e408 100644 (file)
@@ -227,6 +227,7 @@ void set_effective_gid(gid_t gid)
 }
 
 static uid_t saved_euid, saved_ruid;
+static gid_t saved_egid, saved_rgid;
 
 /****************************************************************************
  save the real and effective uid for later restoration. Used by the quotas
@@ -264,6 +265,41 @@ void restore_re_uid(void)
        assert_uid(saved_ruid, saved_euid);
 }
 
+
+/****************************************************************************
+ save the real and effective gid for later restoration. Used by the 
+ getgroups code
+****************************************************************************/
+void save_re_gid(void)
+{
+       saved_rgid = getgid();
+       saved_egid = getegid();
+}
+
+/****************************************************************************
+ and restore them!
+****************************************************************************/
+void restore_re_gid(void)
+{
+#if USE_SETRESUID
+       setresgid(saved_rgid, saved_egid, -1);
+#elif USE_SETREUID
+       setregid(saved_rgid, -1);
+       setregid(-1,saved_egid);
+#elif USE_SETUIDX
+       setgidx(ID_REAL, saved_rgid);
+       setgidx(ID_EFFECTIVE, saved_egid);
+#else
+       set_effective_gid(saved_egid);
+       if (getgid() != saved_rgid)
+               setgid(saved_rgid);
+       set_effective_gid(saved_egid);
+#endif
+
+       assert_gid(saved_rgid, saved_egid);
+}
+
+
 /****************************************************************************
  set the real AND effective uid to the current effective uid in a way that
  allows root to be regained.
index 1d2c0c271363d577e8ee9bd8c6f3912cddb4d1af..b7be415abcd01cfd676858c27d8535b2ade75a5a 100644 (file)
@@ -435,7 +435,7 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name ));
 
        /* Set up pipe user group membership. */
        initialise_groups(p->pipe_user_name, p->pipe_user.uid, p->pipe_user.gid);
-       get_current_groups( &p->pipe_user.ngroups, &p->pipe_user.groups);
+       get_current_groups(p->pipe_user.gid, &p->pipe_user.ngroups, &p->pipe_user.groups);
 
        if (server_info->ptok)
                add_supplementary_nt_login_groups(&p->pipe_user.ngroups, &p->pipe_user.groups, &server_info->ptok);
index f9bcad4154c5c521c047c378756f37c03d7ebe63..82c0cef77d7a93b1d03115f5fd221d31ef455c8d 100644 (file)
@@ -289,7 +289,7 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name)
        /* Find all the groups this uid is in and store them. 
                Used by change_to_user() */
        initialise_groups(vuser->user.unix_name, vuser->uid, vuser->gid);
-       get_current_groups( &vuser->n_groups, &vuser->groups);
+       get_current_groups(vuser->gid, &vuser->n_groups, &vuser->groups);
 
        if (server_info->ptok)
                add_supplementary_nt_login_groups(&vuser->n_groups, &vuser->groups, &server_info->ptok);
index 87bf8b174437dbb438e4fd72ed744ec63b90c8f8..bdcdce6e14509225d4625774d1c46a83d053b18c 100644 (file)
@@ -132,29 +132,39 @@ static void gain_root(void)
  Get the list of current groups.
 ****************************************************************************/
 
-int get_current_groups(int *p_ngroups, gid_t **p_groups)
+int get_current_groups(gid_t gid, int *p_ngroups, gid_t **p_groups)
 {
        int i;
        gid_t grp;
-       int ngroups = sys_getgroups(0,&grp);
-       gid_t *groups;
+       int ngroups;
+       gid_t *groups = NULL;
 
        (*p_ngroups) = 0;
        (*p_groups) = NULL;
 
-       if (ngroups <= 0)
-               return -1;
+       /* this looks a little strange, but is needed to cope with
+          systems that put the current egid in the group list
+          returned from getgroups() (tridge) */
+       save_re_gid();
+       set_effective_gid(gid);
+       setgid(gid);
 
-       if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL) {
+       ngroups = sys_getgroups(0,&grp);
+       if (ngroups <= 0) {
+               goto fail;
+       }
+
+       if((groups = (gid_t *)malloc(sizeof(gid_t)*(ngroups+1))) == NULL) {
                DEBUG(0,("setup_groups malloc fail !\n"));
-               return -1;
+               goto fail;
        }
 
        if ((ngroups = sys_getgroups(ngroups,groups)) == -1) {
-               SAFE_FREE(groups);
-               return -1;
+               goto fail;
        }
 
+       restore_re_gid();
+
        (*p_ngroups) = ngroups;
        (*p_groups) = groups;
 
@@ -164,7 +174,12 @@ int get_current_groups(int *p_ngroups, gid_t **p_groups)
        }
        DEBUG( 3, ( "\n" ) );
 
-    return ngroups;
+       return ngroups;
+
+fail:
+       SAFE_FREE(groups);
+       restore_re_gid();
+       return -1;
 }
 
 /****************************************************************************
@@ -204,7 +219,7 @@ BOOL initialise_groups(char *user, uid_t uid, gid_t gid)
        SAFE_FREE(prev_ctx_p->groups);
        prev_ctx_p->ngroups = 0;
 
-       get_current_groups(&prev_ctx_p->ngroups, &prev_ctx_p->groups);
+       get_current_groups(gid, &prev_ctx_p->ngroups, &prev_ctx_p->groups);
 
  done:
        unbecome_root();
@@ -404,7 +419,7 @@ void init_sec_ctx(void)
        ctx_p->uid = geteuid();
        ctx_p->gid = getegid();
 
-       get_current_groups(&ctx_p->ngroups, &ctx_p->groups);
+       get_current_groups(ctx_p->gid, &ctx_p->ngroups, &ctx_p->groups);
 
        ctx_p->token = NULL; /* Maps to guest user. */