|
|
|
From b2a41801904c4b281a717dde7f5e146cbd4500b3 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Karel Zak <kzak@redhat.com>
|
|
|
|
Date: Mon, 15 Feb 2016 13:55:37 +0100
|
|
|
|
Subject: [PATCH 66/84] su: clean up groups initialization
|
|
|
|
|
|
|
|
This patch does not change any su/runuser behaviour, code changes:
|
|
|
|
|
|
|
|
* don't use huge groups[NGROUPS_MAX]; the array has 256k, but we need
|
|
|
|
it only occasionally when -G/-g specified.
|
|
|
|
|
|
|
|
* the current code uses groups[0] for -g and the rest for -G, this patch adds
|
|
|
|
'gid' to remember -g argument to avoid memmove()
|
|
|
|
|
|
|
|
* add function add_supp_group() to simplify su_main()
|
|
|
|
|
|
|
|
* add note about -G and -g relation to the man pages (undocumented now)
|
|
|
|
|
|
|
|
Upstream: http://github.com/karelzak/util-linux/commit/c619d3d167115990e9228b27851e0cc2faa8f936
|
|
|
|
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1304426
|
|
|
|
Signed-off-by: Karel Zak <kzak@redhat.com>
|
|
|
|
---
|
|
|
|
login-utils/runuser.1 | 5 ++--
|
|
|
|
login-utils/su-common.c | 68 +++++++++++++++++++++++++++----------------------
|
|
|
|
login-utils/su.1 | 5 ++--
|
|
|
|
3 files changed, 44 insertions(+), 34 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/login-utils/runuser.1 b/login-utils/runuser.1
|
|
|
|
index 7201ff0..d82dbb0 100644
|
|
|
|
--- a/login-utils/runuser.1
|
|
|
|
+++ b/login-utils/runuser.1
|
|
|
|
@@ -75,8 +75,9 @@ shell.
|
|
|
|
\fB\-g\fR, \fB\-\-group\fR=\fIgroup\fR\fR
|
|
|
|
specify the primary group, this option is allowed for root user only
|
|
|
|
.TP
|
|
|
|
-\fB\-G\fR, \fB\-\-supp-group\fR=\fIgroup\fR\fR
|
|
|
|
-specify a supplemental group, this option is allowed for root user only
|
|
|
|
+.BR \-G , " \-\-supp\-group" = \fIgroup
|
|
|
|
+Specify a supplemental group. This option is available to the root user only. The first specified
|
|
|
|
+supplementary group is also used as a primary group if the option \fB\-\-group\fR is unspecified.
|
|
|
|
.TP
|
|
|
|
\fB\-\fR, \fB\-l\fR, \fB\-\-login\fR
|
|
|
|
Starts the shell as login shell with an environment similar to a real
|
|
|
|
diff --git a/login-utils/su-common.c b/login-utils/su-common.c
|
|
|
|
index dd87804..d53d690 100644
|
|
|
|
--- a/login-utils/su-common.c
|
|
|
|
+++ b/login-utils/su-common.c
|
|
|
|
@@ -535,7 +535,7 @@ modify_environment (const struct passwd *pw, const char *shell)
|
|
|
|
/* Become the user and group(s) specified by PW. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
-init_groups (const struct passwd *pw, gid_t *groups, int num_groups)
|
|
|
|
+init_groups (const struct passwd *pw, gid_t *groups, size_t num_groups)
|
|
|
|
{
|
|
|
|
int retval;
|
|
|
|
|
|
|
|
@@ -707,6 +707,28 @@ evaluate_uid(void)
|
|
|
|
return (uid_t) 0 == ruid && ruid == euid ? 0 : 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static gid_t
|
|
|
|
+add_supp_group(const char *name, gid_t **groups, size_t *ngroups)
|
|
|
|
+{
|
|
|
|
+ struct group *gr;
|
|
|
|
+
|
|
|
|
+ if (*ngroups >= NGROUPS_MAX)
|
|
|
|
+ errx(EXIT_FAILURE,
|
|
|
|
+ P_("specifying more than %d supplemental group is not possible",
|
|
|
|
+ "specifying more than %d supplemental groups is not possible",
|
|
|
|
+ NGROUPS_MAX - 1), NGROUPS_MAX - 1);
|
|
|
|
+
|
|
|
|
+ gr = getgrnam(name);
|
|
|
|
+ if (!gr)
|
|
|
|
+ errx(EXIT_FAILURE, _("group %s does not exist"), name);
|
|
|
|
+
|
|
|
|
+ *groups = xrealloc(*groups, sizeof(gid_t) * (*ngroups + 1));
|
|
|
|
+ (*groups)[*ngroups] = gr->gr_gid;
|
|
|
|
+ (*ngroups)++;
|
|
|
|
+
|
|
|
|
+ return gr->gr_gid;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
int
|
|
|
|
su_main (int argc, char **argv, int mode)
|
|
|
|
{
|
|
|
|
@@ -717,10 +739,12 @@ su_main (int argc, char **argv, int mode)
|
|
|
|
char *shell = NULL;
|
|
|
|
struct passwd *pw;
|
|
|
|
struct passwd pw_copy;
|
|
|
|
- struct group *gr;
|
|
|
|
- gid_t groups[NGROUPS_MAX];
|
|
|
|
- int num_supp_groups = 0;
|
|
|
|
- int use_gid = 0;
|
|
|
|
+
|
|
|
|
+ gid_t *groups = NULL;
|
|
|
|
+ size_t ngroups = 0;
|
|
|
|
+ bool use_supp = false;
|
|
|
|
+ bool use_gid = false;
|
|
|
|
+ gid_t gid = 0;
|
|
|
|
|
|
|
|
static const struct option longopts[] = {
|
|
|
|
{"command", required_argument, NULL, 'c'},
|
|
|
|
@@ -765,23 +789,13 @@ su_main (int argc, char **argv, int mode)
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'g':
|
|
|
|
- gr = getgrnam(optarg);
|
|
|
|
- if (!gr)
|
|
|
|
- errx(EXIT_FAILURE, _("group %s does not exist"), optarg);
|
|
|
|
- use_gid = 1;
|
|
|
|
- groups[0] = gr->gr_gid;
|
|
|
|
+ use_gid = true;
|
|
|
|
+ gid = add_supp_group(optarg, &groups, &ngroups);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'G':
|
|
|
|
- num_supp_groups++;
|
|
|
|
- if (num_supp_groups >= NGROUPS_MAX)
|
|
|
|
- errx(EXIT_FAILURE,
|
|
|
|
- _("can't specify more than %d supplemental groups"),
|
|
|
|
- NGROUPS_MAX - 1);
|
|
|
|
- gr = getgrnam(optarg);
|
|
|
|
- if (!gr)
|
|
|
|
- errx(EXIT_FAILURE, _("group %s does not exist"), optarg);
|
|
|
|
- groups[num_supp_groups] = gr->gr_gid;
|
|
|
|
+ use_supp = true;
|
|
|
|
+ add_supp_group(optarg, &groups, &ngroups);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'l':
|
|
|
|
@@ -852,7 +866,7 @@ su_main (int argc, char **argv, int mode)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
- if ((num_supp_groups || use_gid) && restricted)
|
|
|
|
+ if ((use_supp || use_gid) && restricted)
|
|
|
|
errx(EXIT_FAILURE, _("only root can specify alternative groups"));
|
|
|
|
|
|
|
|
logindefs_load_defaults = load_config;
|
|
|
|
@@ -878,16 +892,10 @@ su_main (int argc, char **argv, int mode)
|
|
|
|
: DEFAULT_SHELL);
|
|
|
|
endpwent ();
|
|
|
|
|
|
|
|
- if (num_supp_groups && !use_gid)
|
|
|
|
- {
|
|
|
|
- pw->pw_gid = groups[1];
|
|
|
|
- memmove (groups, groups + 1, sizeof(gid_t) * num_supp_groups);
|
|
|
|
- }
|
|
|
|
- else if (use_gid)
|
|
|
|
- {
|
|
|
|
+ if (use_supp && !use_gid)
|
|
|
|
pw->pw_gid = groups[0];
|
|
|
|
- num_supp_groups++;
|
|
|
|
- }
|
|
|
|
+ else if (use_gid)
|
|
|
|
+ pw->pw_gid = gid;
|
|
|
|
|
|
|
|
authenticate (pw);
|
|
|
|
|
|
|
|
@@ -912,7 +920,7 @@ su_main (int argc, char **argv, int mode)
|
|
|
|
shell = xstrdup (shell ? shell : pw->pw_shell);
|
|
|
|
}
|
|
|
|
|
|
|
|
- init_groups (pw, groups, num_supp_groups);
|
|
|
|
+ init_groups (pw, groups, ngroups);
|
|
|
|
|
|
|
|
if (!simulate_login || command)
|
|
|
|
suppress_pam_info = 1; /* don't print PAM info messages */
|
|
|
|
diff --git a/login-utils/su.1 b/login-utils/su.1
|
|
|
|
index eab1a6f..1f69868 100644
|
|
|
|
--- a/login-utils/su.1
|
|
|
|
+++ b/login-utils/su.1
|
|
|
|
@@ -62,8 +62,9 @@ shell.
|
|
|
|
\fB\-g\fR, \fB\-\-group\fR=\fIgroup\fR\fR
|
|
|
|
specify the primary group, this option is allowed for root user only
|
|
|
|
.TP
|
|
|
|
-\fB\-G\fR, \fB\-\-supp-group\fR=\fIgroup\fR\fR
|
|
|
|
-specify a supplemental group, this option is allowed for root user only
|
|
|
|
+.BR \-G , " \-\-supp\-group" = \fIgroup
|
|
|
|
+Specify a supplemental group. This option is available to the root user only. The first specified
|
|
|
|
+supplementary group is also used as a primary group if the option \fB\-\-group\fR is unspecified.
|
|
|
|
.TP
|
|
|
|
\fB\-\fR, \fB\-l\fR, \fB\-\-login\fR
|
|
|
|
Starts the shell as login shell with an environment similar to a real
|
|
|
|
--
|
|
|
|
2.7.4
|
|
|
|
|