#include "service.h"
#include "instance.h"
+#define UJAIL_BIN_PATH "/sbin/ujail"
enum {
INSTANCE_ATTR_COMMAND,
struct jail *jail = &in->jail;
int argc = 0;
- argv[argc++] = "/sbin/ujail";
+ argv[argc++] = UJAIL_BIN_PATH;
if (jail->name) {
argv[argc++] = "-n";
argv[argc++] = in->seccomp;
}
+ if (in->user) {
+ argv[argc++] = "-U";
+ argv[argc++] = in->user;
+ }
+
+ if (in->group) {
+ argv[argc++] = "-G";
+ argv[argc++] = in->group;
+ }
+
if (in->no_new_privs)
argv[argc++] = "-c";
if (!in->pidfile)
return 0;
if (unlink(in->pidfile)) {
- ERROR("Failed to removed pidfile: %s: %m\n", in->pidfile);
+ ERROR("Failed to remove pidfile: %s: %m\n", in->pidfile);
return 1;
}
return 0;
ULOG_WARN("Seccomp support for %s::%s not available\n", in->srv->name, in->name);
#endif
- if (in->has_jail)
+ if (in->has_jail) {
argc = jail_run(in, argv);
+ if (argc != in->jail.argc)
+ ULOG_WARN("expected %i jail params, used %i for %s::%s\n",
+ in->jail.argc, argc, in->srv->name, in->name);
+ }
blobmsg_for_each_attr(cur, in->command, rem)
argv[argc++] = blobmsg_data(cur);
closefd(_stderr);
}
- if (in->user && in->pw_gid && initgroups(in->user, in->pw_gid)) {
+ if (!in->has_jail && in->user && in->pw_gid && initgroups(in->user, in->pw_gid)) {
ERROR("failed to initgroups() for user %s: %m\n", in->user);
exit(127);
}
- if (in->gr_gid && setgid(in->gr_gid)) {
+ if (!in->has_jail && in->gr_gid && setgid(in->gr_gid)) {
ERROR("failed to set group id %d: %m\n", in->gr_gid);
exit(127);
}
- if (in->uid && setuid(in->uid)) {
+ if (!in->has_jail && in->uid && setuid(in->uid)) {
ERROR("failed to set user id %d: %m\n", in->uid);
exit(127);
}
struct blob_attr *tb[__JAIL_ATTR_MAX];
struct jail *jail = &in->jail;
struct stat s;
+ int r;
- if (stat("/sbin/ujail", &s))
+ r = stat(UJAIL_BIN_PATH, &s);
+ if (r < 0) {
+ DEBUG(2, "unable to find %s: %m (%d)\n", UJAIL_BIN_PATH, r);
return 0;
+ }
blobmsg_parse(jail_attr, __JAIL_ATTR_MAX, tb,
blobmsg_data(attr), blobmsg_data_len(attr));
jail->argc = 2;
if (tb[JAIL_ATTR_NAME]) {
- jail->name = blobmsg_get_string(tb[JAIL_ATTR_NAME]);
+ jail->name = strdup(blobmsg_get_string(tb[JAIL_ATTR_NAME]));
jail->argc += 2;
}
if (tb[JAIL_ATTR_HOSTNAME]) {
- jail->hostname = blobmsg_get_string(tb[JAIL_ATTR_HOSTNAME]);
+ jail->hostname = strdup(blobmsg_get_string(tb[JAIL_ATTR_HOSTNAME]));
jail->argc += 2;
}
if (tb[JAIL_ATTR_PROCFS]) {
if (in->seccomp)
jail->argc += 2;
+ if (in->user)
+ jail->argc += 2;
+
+ if (in->group)
+ jail->argc += 2;
+
+ if (in->no_new_privs)
+ jail->argc++;
+
return 1;
}
in->no_new_privs = blobmsg_get_bool(tb[INSTANCE_ATTR_NO_NEW_PRIVS]);
if (!in->trace && tb[INSTANCE_ATTR_SECCOMP])
- in->seccomp = blobmsg_get_string(tb[INSTANCE_ATTR_SECCOMP]);
+ in->seccomp = strdup(blobmsg_get_string(tb[INSTANCE_ATTR_SECCOMP]));
if (tb[INSTANCE_ATTR_PIDFILE]) {
char *pidfile = blobmsg_get_string(tb[INSTANCE_ATTR_PIDFILE]);
if (pidfile)
- in->pidfile = pidfile;
+ in->pidfile = strdup(pidfile);
}
if (tb[INSTANCE_ATTR_RELOADSIG])
blobmsg_list_free(&in->jail.mount);
}
+static void
+instance_config_move_strdup(char **dst, char *src)
+{
+ if (*dst) {
+ free(*dst);
+ *dst = NULL;
+ }
+
+ if (!src)
+ return;
+
+ *dst = strdup(src);
+}
+
static void
instance_config_move(struct service_instance *in, struct service_instance *in_src)
{
blobmsg_list_move(&in->jail.mount, &in_src->jail.mount);
in->trigger = in_src->trigger;
in->command = in_src->command;
- in->pidfile = in_src->pidfile;
in->respawn = in_src->respawn;
in->respawn_retry = in_src->respawn_retry;
in->respawn_threshold = in_src->respawn_threshold;
in->respawn_timeout = in_src->respawn_timeout;
in->name = in_src->name;
in->trace = in_src->trace;
- in->seccomp = in_src->seccomp;
in->node.avl.key = in_src->node.avl.key;
in->syslog_facility = in_src->syslog_facility;
+ instance_config_move_strdup(&in->pidfile, in_src->pidfile);
+ instance_config_move_strdup(&in->seccomp, in_src->seccomp);
+ instance_config_move_strdup(&in->jail.name, in_src->jail.name);
+ instance_config_move_strdup(&in->jail.hostname, in_src->jail.hostname);
+
free(in->config);
in->config = in_src->config;
in_src->config = NULL;
free(in->config);
free(in->user);
free(in->group);
+ free(in->jail.name);
+ free(in->jail.hostname);
+ free(in->seccomp);
+ free(in->pidfile);
free(in);
}