Esempio n. 1
0
static int chown_cgroup_wrapper(void *data)
{
	struct chown_data *arg = data;
	char **slist = subsystems;
	int i, ret = -1;
	uid_t destuid;

	if (setresgid(0,0,0) < 0)
		SYSERROR("Failed to setgid to 0");
	if (setresuid(0,0,0) < 0)
		SYSERROR("Failed to setuid to 0");
	if (setgroups(0, NULL) < 0)
		SYSERROR("Failed to clear groups");
	cgm_dbus_disconnect();
	if (!cgm_dbus_connect()) {
		ERROR("Error connecting to cgroup manager");
		return -1;
	}
	destuid = get_ns_uid(arg->origuid);

	if (cgm_supports_multiple_controllers)
		slist = subsystems_inone;

	for (i = 0; slist[i]; i++) {
		if (do_chown_cgroup(slist[i], arg->cgroup_path, destuid) < 0) {
			ERROR("Failed to chown %s:%s to container root",
				slist[i], arg->cgroup_path);
			goto fail;
		}
	}
	ret = 0;
fail:
	cgm_dbus_disconnect();
	return ret;
}
Esempio n. 2
0
static int do_chown_cgroup(const char *controller, const char *cgroup_path,
		uid_t origuid)
{
	int sv[2] = {-1, -1}, optval = 1, ret = -1;
	char buf[1];

	uid_t caller_nsuid = get_ns_uid(origuid);

	if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sv) < 0) {
		SYSERROR("Error creating socketpair");
		goto out;
	}
	if (setsockopt(sv[1], SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) == -1) {
		SYSERROR("setsockopt failed");
		goto out;
	}
	if (setsockopt(sv[0], SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) == -1) {
		SYSERROR("setsockopt failed");
		goto out;
	}
	if ( cgmanager_chown_scm_sync(NULL, cgroup_manager, controller,
				       cgroup_path, sv[1]) != 0) {
		NihError *nerr;
		nerr = nih_error_get();
		ERROR("call to cgmanager_chown_scm_sync failed: %s", nerr->message);
		nih_free(nerr);
		goto out;
	}
	/* now send credentials */

	fd_set rfds;
	FD_ZERO(&rfds);
	FD_SET(sv[0], &rfds);
	if (select(sv[0]+1, &rfds, NULL, NULL, NULL) < 0) {
		ERROR("Error getting go-ahead from server: %s", strerror(errno));
		goto out;
	}
	if (read(sv[0], &buf, 1) != 1) {
		ERROR("Error getting reply from server over socketpair");
		goto out;
	}
	if (send_creds(sv[0], getpid(), getuid(), getgid())) {
		SYSERROR("%s: Error sending pid over SCM_CREDENTIAL", __func__);
		goto out;
	}
	FD_ZERO(&rfds);
	FD_SET(sv[0], &rfds);
	if (select(sv[0]+1, &rfds, NULL, NULL, NULL) < 0) {
		ERROR("Error getting go-ahead from server: %s", strerror(errno));
		goto out;
	}
	if (read(sv[0], &buf, 1) != 1) {
		ERROR("Error getting reply from server over socketpair");
		goto out;
	}
	if (send_creds(sv[0], getpid(), caller_nsuid, 0)) {
		SYSERROR("%s: Error sending pid over SCM_CREDENTIAL", __func__);
		goto out;
	}
	FD_ZERO(&rfds);
	FD_SET(sv[0], &rfds);
	if (select(sv[0]+1, &rfds, NULL, NULL, NULL) < 0) {
		ERROR("Error getting go-ahead from server: %s", strerror(errno));
		goto out;
	}
	ret = read(sv[0], buf, 1);
out:
	close(sv[0]);
	close(sv[1]);
	if (ret == 1 && *buf == '1')
		return 0;
	return -1;
}