summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/lib/util_sec.c36
-rw-r--r--source3/rpc_server/srv_pipe.c2
-rw-r--r--source3/smbd/password.c2
-rw-r--r--source3/smbd/sec_ctx.c39
4 files changed, 65 insertions, 14 deletions
diff --git a/source3/lib/util_sec.c b/source3/lib/util_sec.c
index d59b1b0471..132748ce13 100644
--- a/source3/lib/util_sec.c
+++ b/source3/lib/util_sec.c
@@ -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.
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 1d2c0c2713..b7be415abc 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -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);
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index f9bcad4154..82c0cef77d 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -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);
diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c
index 87bf8b1744..bdcdce6e14 100644
--- a/source3/smbd/sec_ctx.c
+++ b/source3/smbd/sec_ctx.c
@@ -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. */