summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichal Nazarewicz <mina86@mina86.com>2009-07-19 08:17:55 +0200
committerMax Kellermann <max@duempel.org>2009-07-19 08:17:55 +0200
commitd718a8b59d1f48abcff7f5626a237c1998fc83d5 (patch)
tree746fd0eb526ece35f71d8c5ca0f480ba107ec11d /src
parent4100035b19a5d0dedcf8f71a272fa67f6a24361a (diff)
daemon: added "group" configuration option
The "group" configuration option is similar to "user" as it sets user set what group MPD shall run as. With "user" option, MPD changed GID to the GID of the user, however, more control could be desired. Moreover, the patch changes the way of checking whether no setuid(2)/setgid(2) is required -- previously user names were compered, now UID and GIDs are compered (ie. the one we already have (getuid(2)/getgid(2)) with the one we want to change to).
Diffstat (limited to 'src')
-rw-r--r--src/conf.c1
-rw-r--r--src/conf.h1
-rw-r--r--src/daemon.c48
-rw-r--r--src/daemon.h2
-rw-r--r--src/main.c1
5 files changed, 35 insertions, 18 deletions
diff --git a/src/conf.c b/src/conf.c
index 777cbe6ed..a423b5d2d 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -61,6 +61,7 @@ static struct config_entry config_entries[] = {
{ .name = CONF_PID_FILE, false, false },
{ .name = CONF_STATE_FILE, false, false },
{ .name = CONF_USER, false, false },
+ { .name = CONF_GROUP, false, false },
{ .name = CONF_BIND_TO_ADDRESS, true, false },
{ .name = CONF_PORT, false, false },
{ .name = CONF_LOG_LEVEL, false, false },
diff --git a/src/conf.h b/src/conf.h
index 669542167..fda3a12b9 100644
--- a/src/conf.h
+++ b/src/conf.h
@@ -34,6 +34,7 @@
#define CONF_PID_FILE "pid_file"
#define CONF_STATE_FILE "state_file"
#define CONF_USER "user"
+#define CONF_GROUP "group"
#define CONF_BIND_TO_ADDRESS "bind_to_address"
#define CONF_PORT "port"
#define CONF_LOG_LEVEL "log_level"
diff --git a/src/daemon.c b/src/daemon.c
index 33b2953a9..e7fcd0986 100644
--- a/src/daemon.c
+++ b/src/daemon.c
@@ -45,14 +45,17 @@
static char *user_name;
/** the Unix user id which MPD runs as */
-static uid_t user_uid;
+static uid_t user_uid = (uid_t)-1;
/** the Unix group id which MPD runs as */
-static gid_t user_gid;
+static gid_t user_gid = (pid_t)-1;
/** the absolute path of the pidfile */
static char *pidfile;
+/* whether "group" conf. option was given */
+static bool had_group = false;
+
#endif
void
@@ -107,16 +110,19 @@ daemonize_set_user(void)
if (user_name == NULL)
return;
- /* get uid */
- if (setgid(user_gid) == -1) {
- g_error("cannot setgid for user \"%s\": %s",
- user_name, g_strerror(errno));
+ /* set gid */
+ if (user_gid != (gid_t)-1 && user_gid != getgid()) {
+ if (setgid(user_gid) == -1) {
+ g_error("cannot setgid to %d: %s",
+ (int)user_gid, g_strerror(errno));
+ }
}
+
#ifdef _BSD_SOURCE
/* init suplementary groups
* (must be done before we change our uid)
*/
- if (initgroups(user_name, user_gid) == -1) {
+ if (!had_group && initgroups(user_name, user_gid) == -1) {
g_warning("cannot init supplementary groups "
"of user \"%s\": %s",
user_name, g_strerror(errno));
@@ -124,7 +130,8 @@ daemonize_set_user(void)
#endif
/* set uid */
- if (setuid(user_uid) == -1) {
+ if (user_uid != (uid_t)-1 && user_uid != getuid() &&
+ setuid(user_uid) == -1) {
g_error("cannot change to uid of user \"%s\": %s",
user_name, g_strerror(errno));
}
@@ -196,25 +203,32 @@ daemonize(bool detach)
}
void
-daemonize_init(const char *user, const char *_pidfile)
+daemonize_init(const char *user, const char *group, const char *_pidfile)
{
#ifndef WIN32
- if (user != NULL && strcmp(user, g_get_user_name()) != 0) {
- struct passwd *pwd;
-
- user_name = g_strdup(user);
-
- pwd = getpwnam(user_name);
- if (pwd == NULL)
- g_error("no such user \"%s\"", user_name);
+ if (user) {
+ struct passwd *pwd = getpwnam(user);
+ if (!pwd)
+ g_error("no such user \"%s\"", user);
user_uid = pwd->pw_uid;
user_gid = pwd->pw_gid;
+ user_name = g_strdup(user);
+
/* this is needed by libs such as arts */
g_setenv("HOME", pwd->pw_dir, true);
}
+ if (group) {
+ struct group *grp = grp = getgrnam(group);
+ if (!grp)
+ g_error("no such group \"%s\"", group);
+ user_gid = grp->gr_gid;
+ had_group = true;
+ }
+
+
pidfile = g_strdup(_pidfile);
#else
(void)user;
diff --git a/src/daemon.h b/src/daemon.h
index 5b3f9a7dc..46a4c4f71 100644
--- a/src/daemon.h
+++ b/src/daemon.h
@@ -23,7 +23,7 @@
#include <stdbool.h>
void
-daemonize_init(const char *user, const char *pidfile);
+daemonize_init(const char *user, const char *group, const char *pidfile);
void
daemonize_finish(void);
diff --git a/src/main.c b/src/main.c
index 3d0aaabc9..54b31c1f8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -94,6 +94,7 @@ static void
glue_daemonize_init(const struct options *options)
{
daemonize_init(config_get_string(CONF_USER, NULL),
+ config_get_string(CONF_GROUP, NULL),
config_get_path(CONF_PID_FILE));
if (options->kill)