示例#1
0
int chmod_main(const char *controller, const char *cgroup, const char *file,
		struct ucred p, struct ucred r, int mode)
{
	char rcgpath[MAXPATHLEN];
	nih_local char *path = NULL;

	if (!sane_cgroup(cgroup)) {
		nih_error("%s: unsafe cgroup", __func__);
		return -1;
	}

	if (file && ( strchr(file, '/') || strchr(file, '\\')) ) {
		nih_dbus_error_raise_printf (DBUS_ERROR_INVALID_ARGS,
				"invalid file");
		return -1;
	}

	// Get r's current cgroup in rcgpath
	if (!compute_pid_cgroup(r.pid, controller, "", rcgpath, NULL)) {
		nih_error("%s: Could not determine the requested cgroup", __func__);
		return -1;
	}

	path = NIH_MUST( nih_sprintf(NULL, "%s/%s", rcgpath, cgroup) );
	if (file && strlen(file))
		NIH_MUST( nih_strcat_sprintf(&path, NULL, "/%s", file) );
	if (realpath_escapes(path, rcgpath)) {
		nih_error("%s: Invalid path %s", __func__, path);
		return -1;
	}
	// is r allowed to descend under the parent dir?
	if (!may_access(r.pid, r.uid, r.gid, path, O_RDONLY)) {
		nih_error("%s: pid %d (uid %u gid %u) may not read under %s", __func__,
			r.pid, r.uid, r.gid, path);
		return -1;
	}

	// does r have privilege over the cgroup dir?
	if (!may_access(r.pid, r.uid, r.gid, path, O_RDWR)) {
		nih_error("%s: Pid %d may not chmod %s\n", __func__, r.pid, path);
		return -1;
	}

	// go ahead and chmod it.
	if (!chmod_cgroup_path(path, mode)) {
		nih_error("%s: Failed to change mode on %s to %d", __func__,
			path, mode);
		return -1;
	}

	return 0;
}
示例#2
0
文件: pam_cgm.c 项目: hallyn/pam-cgm
static void get_active_controllers(void)
{
	int i;
	nih_local char **list = cgm_list_controllers();

	if (!list) {
		mysyslog(LOG_NOTICE, "unable to detect controllers");
		ctrl_list = NIH_MUST( nih_strdup(NULL, "all") );
		return;
	}
	for (i = 0; list[i]; i++) {
		if (strcmp(list[i], "name=systemd") == 0)
			continue;
		NIH_MUST( nih_strcat_sprintf(&ctrl_list, NULL, "%s%s",
			ctrl_list ? "," : "", list[i]) );
	}
}
示例#3
0
/**
 * session_from_dbus:
 * @parent: parent,
 * @message: D-Bus message.
 *
 * Create a new session, based on the specified D-Bus message.
 *
 * Return new Session, or NULL on error.
 **/
Session *
session_from_dbus (const void     *parent,
		   NihDBusMessage *message)
{
	const char     *sender;
	DBusError       dbus_error;
	unsigned long   unix_user;
	unsigned long   unix_process_id;
	char            root[PATH_MAX];
	Session        *session;
	struct passwd  *pwd;
	nih_local char *conf_path = NULL;

	nih_assert (message != NULL);

	/* Handle explicit command-line request and alternative request
	 * method (primarily for test framework) to disable session support.
	 */
	if (disable_sessions || getenv ("UPSTART_NO_SESSIONS"))
		return NULL;

	session_init ();

	/* Ask D-Bus nicely for the origin uid and/or pid of the caller;
	 * sadly we can't ask the bus daemon for the origin pid, so that
	 * one will just have to stay user-session only.
	 */
	dbus_error_init (&dbus_error);

	sender = dbus_message_get_sender (message->message);
	if (sender) {
		unix_user = dbus_bus_get_unix_user (message->connection, sender,
						    &dbus_error);
		if (unix_user == (unsigned long)-1) {
			dbus_error_free (&dbus_error);
			unix_user = 0;
		}

		unix_process_id = 0;

	} else {
		if (! dbus_connection_get_unix_user (message->connection,
						     &unix_user))
			unix_process_id = 0;

		if (! dbus_connection_get_unix_process_id (message->connection,
							   &unix_process_id))
			unix_process_id = 0;
	}

	/* If we retrieved a process id, look up the root path for it;
	 * if it's just '/' don't worry so much about it.
	 */
	if (unix_process_id) {
		nih_local char *symlink = NULL;
		ssize_t len;

		symlink = NIH_MUST (nih_sprintf (NULL, "/proc/%lu/root",
						 unix_process_id));
		len = readlink (symlink, root, sizeof root);
		if (len < 0)
			return NULL;

		root[len] = '\0';

		if (! strcmp (root, "/")) {
			unix_process_id = 0;
			if (! unix_user)
				return NULL;
		}

	} else if (! unix_user) {
		/* No process id or user id found, return the NULL session */
		return NULL;
	}

	if (unix_user) {
		pwd = getpwuid (unix_user);

		if (! pwd || ! pwd->pw_dir) {
			nih_error ("%lu: %s: %s", unix_user,
				   _("Unable to lookup home directory"),
				   strerror (errno));
			return NULL;
		}

		NIH_MUST (nih_strcat_sprintf (&conf_path, NULL, "%s/%s",
					pwd->pw_dir, USERCONFDIR));
	}


	/* Now find in the existing Sessions list */
	NIH_LIST_FOREACH_SAFE (sessions, iter) {
		Session *session = (Session *)iter;

		if (unix_process_id) {
			if (! session->chroot)
				continue;

			/* ignore sessions relating to other chroots */
			if (strcmp (session->chroot, root))
				continue;
		}

		/* ignore sessions relating to other users */
		if (unix_user != session->user)
			continue;

		/* Found a user with the same uid but different
		 * conf_dir to the existing session user. Either the
		 * original user has been deleted and a new user created
		 * with the same uid, or the original users home
		 * directory has changed since they first started
		 * running jobs. Whatever the reason, we (can only) honour
		 * the new value.
		 *
		 * Since multiple users with the same uid are considered
		 * to be "the same user", invalidate the old path,
		 * allowing the correct new path to be set below.
		 *
		 * Note that there may be a possibility of trouble if
		 * the scenario relates to a deleted user and that original
		 * user still has jobs running. However, if that were the
		 * case, those jobs would likely fail anyway since they
		 * would have no working directory due to the original
		 * users home directory being deleted/changed/made inaccessible.
		 */
		if (unix_user && conf_path && session->conf_path &&
				strcmp (conf_path, session->conf_path)) {
			nih_free (session->conf_path);
			session->conf_path = NULL;
		}

		if (! session->conf_path)
			session_create_conf_source (session);

		return session;
	}
示例#4
0
void
test_strcat_sprintf (void)
{
    char *str, *ret;

    TEST_FUNCTION ("test_strcat_sprintf");

    /* Check that we can extend a string with a formatted string,
     * resulting in the original string being modified and the new
     * pointer stored in the argument and returned.
     */
    TEST_FEATURE ("with original string");
    TEST_ALLOC_FAIL {
        char *tmp;

        TEST_ALLOC_SAFE {
            str = nih_strdup (NULL, "this");
        }

        tmp = str;
        ret = nih_strcat_sprintf (&str, NULL,
        " %s a test %d", "is", 54321);

        if (test_alloc_failed) {
            TEST_EQ_P (ret, NULL);
            TEST_EQ_P (str, tmp);
            TEST_EQ_STR (str, "this");

            nih_free (str);
            continue;
        }

        TEST_NE (ret, NULL);
        TEST_EQ_P (ret, str);

        TEST_ALLOC_SIZE (str, 21);
        TEST_EQ_STR (str, "this is a test 54321");

        nih_free (str);
    }


    /* Check that when no string is passed, this behaves as sprintf.
     */
    TEST_FEATURE ("with NULL");
    TEST_ALLOC_FAIL {
        str = NULL;
        ret = nih_strcat_sprintf (&str, NULL,
        "%s a test %d", "is", 54321);

        if (test_alloc_failed) {
            TEST_EQ_P (ret, NULL);
            TEST_EQ_P (str, NULL);
            continue;
        }

        TEST_NE (ret, NULL);
        TEST_EQ_P (ret, str);

        TEST_ALLOC_SIZE (str, 15);
        TEST_EQ_STR (str, "is a test 54321");

        nih_free (str);
    }
}