From 4bd633868e3284659668f14aa39ea84aaadc2dec Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 8 Sep 2014 01:30:24 +0200 Subject: instances can now start as a !root user Signed-off-by: John Crispin --- service/instance.c | 21 +++++++++++++++++++++ service/instance.h | 3 +++ 2 files changed, 24 insertions(+) diff --git a/service/instance.c b/service/instance.c index c22e546..6dfc61b 100644 --- a/service/instance.c +++ b/service/instance.c @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -40,6 +41,7 @@ enum { INSTANCE_ATTR_LIMITS, INSTANCE_ATTR_WATCH, INSTANCE_ATTR_ERROR, + INSTANCE_ATTR_USER, __INSTANCE_ATTR_MAX }; @@ -55,6 +57,7 @@ static const struct blobmsg_policy instance_attr[__INSTANCE_ATTR_MAX] = { [INSTANCE_ATTR_LIMITS] = { "limits", BLOBMSG_TYPE_TABLE }, [INSTANCE_ATTR_WATCH] = { "watch", BLOBMSG_TYPE_ARRAY }, [INSTANCE_ATTR_ERROR] = { "error", BLOBMSG_TYPE_ARRAY }, + [INSTANCE_ATTR_USER] = { "user", BLOBMSG_TYPE_STRING }, }; struct instance_netdev { @@ -158,6 +161,10 @@ instance_run(struct service_instance *in) if (fd > STDERR_FILENO) close(fd); } + if (in->uid || in->gid) { + setuid(in->uid); + setgid(in->gid); + } execvp(argv[0], argv); exit(127); } @@ -291,6 +298,12 @@ instance_config_changed(struct service_instance *in, struct service_instance *in if (in->nice != in_new->nice) return true; + if (in->uid != in_new->uid) + return true; + + if (in->gid != in_new->gid) + return true; + if (!blobmsg_list_equal(&in->limits, &in_new->limits)) return true; @@ -450,6 +463,14 @@ instance_config_parse(struct service_instance *in) return false; } + if (tb[INSTANCE_ATTR_USER]) { + struct passwd *p = getpwnam(blobmsg_get_string(tb[INSTANCE_ATTR_USER])); + if (p) { + in->uid = p->pw_uid; + in->gid = p->pw_gid; + } + } + instance_fill_any(&in->data, tb[INSTANCE_ATTR_DATA]); if (!instance_fill_array(&in->env, tb[INSTANCE_ATTR_ENV], NULL, false)) diff --git a/service/instance.h b/service/instance.h index a492f38..f76e795 100644 --- a/service/instance.h +++ b/service/instance.h @@ -29,6 +29,9 @@ struct service_instance { int8_t nice; bool valid; + uid_t uid; + gid_t gid; + bool halt; bool restart; bool respawn; -- cgit v1.2.3