+2008-01-17 Samuel Thibault <samuel.thibault@ens-lyon.org>,
+ Guillem Jover <guillem@debian.org>
+
+ * utils/start-stop-daemon.c (gid_in_current_groups): New function.
+ (main): Call setuid only if requested to run as a different user
+ than the current one. Call setgid only if requested to run as a group
+ different than the current one, and initgroups only if the groups is
+ not part of the supplementary groups.
+
2008-01-16 Guillem Jover <guillem@debian.org>
* utils/start-stop-daemon.c (do_stop): Do not print messages when
--retry even if the daemon removed the pidfile. Closes: #460903
Thanks to Justin Pryzby for the analysis.
* Make --quiet silence --test in start-stop-daemon. Closes: #367998
+ * Check current uid and gid in start-stop-daemon before calling setuid,
+ setgid and initgroups. Closes: #222524
+ Based on a patch by Samuel Thibault.
[ Frank Lichtenheld ]
* Make the -L option of dpkg-parsechangelog actually work (it's
*list = NULL;
}
+static int
+gid_in_current_groups(gid_t gid)
+{
+ gid_t *gids;
+ int i, ngroups;
+
+ ngroups = getgroups(0, NULL);
+ gids = xmalloc(ngroups * sizeof(gid_t));
+ getgroups(ngroups, gids);
+
+ for (i = 0; i < ngroups; i++) {
+ if (gid == gids[i]) {
+ free(gids);
+ return 1;
+ }
+ }
+
+ free(gids);
+ return 0;
+}
+
static void
do_help(void)
{
}
if (chdir(changedir) < 0)
fatal("Unable to chdir() to %s", changedir);
- if (changeuser != NULL) {
- if (setgid(runas_gid))
- fatal("Unable to set gid to %d", runas_gid);
- if (initgroups(changeuser, runas_gid))
- fatal("Unable to set initgroups() with gid %d", runas_gid);
+
+ if (changeuser != NULL && getuid() != runas_uid) {
if (setuid(runas_uid))
fatal("Unable to set uid to %s", changeuser);
}
+ if (changegroup != NULL && *changegroup != '\0' && getgid() != runas_gid) {
+ if (!gid_in_current_groups(runas_gid))
+ if (initgroups(changeuser, runas_gid))
+ fatal("Unable to set initgroups() with gid %d",
+ runas_gid);
+ if (setgid(runas_gid))
+ fatal("Unable to set gid to %d", runas_gid);
+ }
+
if (background) {
/* Continue background setup */
int i;