コード例 #1
0
ファイル: udev-acl.c プロジェクト: SaschaMester/devuan-udev
/* add or remove a ACL for a given uid from all matching devices */
static void apply_acl_to_devices(uid_t uid, int add)
{
	struct udev *udev;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *list_entry;

	/* iterate over all devices tagged with ACL_SET */
	udev = udev_new();
	enumerate = udev_enumerate_new(udev);
	udev_enumerate_add_match_tag(enumerate, "udev-acl");
	udev_enumerate_scan_devices(enumerate);
	udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
		struct udev_device *device;
		const char *node;

		device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
						      udev_list_entry_get_name(list_entry));
		if (device == NULL)
			continue;
		node = udev_device_get_devnode(device);
		if (node == NULL) {
			udev_device_unref(device);
			continue;
		}
		set_facl(node, uid, add);
		udev_device_unref(device);
	}
	udev_enumerate_unref(enumerate);
	udev_unref(udev);
}
コード例 #2
0
static void cleanup(void)
{
    g_cancellable_cancel(polkit_cancellable);

    if (state == STATE_WAITING_FOR_STDIN_EOF)
        set_facl(path, getuid(), 0);

    if (loop)
        g_main_loop_quit(loop);
}
コード例 #3
0
static void check_authorization_cb(PolkitAuthority *authority,
                                   GAsyncResult *res, gpointer data)
{
    PolkitAuthorizationResult *result;
    GError *err = NULL;
    struct stat stat_buf;

    g_clear_object(&polkit_cancellable);

    result = polkit_authority_check_authorization_finish(authority, res, &err);
    if (err) {
        FATAL_ERROR("PoliciKit error: %s\n", err->message);
        g_error_free(err);
        return;
    }

    if (polkit_authorization_result_get_dismissed(result)) {
        ERROR("CANCELED\n");
        return;
    }

    if (!polkit_authorization_result_get_is_authorized(result)) {
        ERROR("Not authorized\n");
        return;
    }

    snprintf(path, PATH_MAX, "/dev/bus/usb/%03d/%03d", busnum, devnum);

    if (stat(path, &stat_buf) != 0) {
        FATAL_ERROR("statting %s: %s\n", path, strerror(errno));
        return;
    }
    if (!S_ISCHR(stat_buf.st_mode)) {
        FATAL_ERROR("%s is not a character device\n", path);
        return;
    }

    if (set_facl(path, getuid(), 1)) {
        FATAL_ERROR("setting facl: %s\n", strerror(errno));
        return;
    }

    fprintf(stdout, "SUCCESS\n");
    fflush(stdout);
    state = STATE_WAITING_FOR_STDIN_EOF;
}
コード例 #4
0
ファイル: udev-acl.c プロジェクト: SaschaMester/devuan-udev
int main (int argc, char* argv[])
{
	static const struct option options[] = {
		{ "action", required_argument, NULL, 'a' },
		{ "device", required_argument, NULL, 'D' },
		{ "user", required_argument, NULL, 'u' },
		{ "debug", no_argument, NULL, 'd' },
		{ "help", no_argument, NULL, 'h' },
		{}
	};
	int action = -1;
	const char *device = NULL;
	bool uid_given = false;
	uid_t uid = 0;
	uid_t uid2 = 0;
	const char* remove_session_id = NULL;
	int rc = 0;

	/* valgrind is more important to us than a slice allocator */
	g_slice_set_config (G_SLICE_CONFIG_ALWAYS_MALLOC, 1);

	while (1) {
		int option;

		option = getopt_long(argc, argv, "+a:D:u:dh", options, NULL);
		if (option == -1)
			break;

		switch (option) {
		case 'a':
			if (strcmp(optarg, "remove") == 0)
				action = ACTION_REMOVE;
			else
				action = ACTION_ADD;
			break;
		case 'D':
			device = optarg;
			break;
		case 'u':
			uid_given = true;
			uid = strtoul(optarg, NULL, 10);
			break;
		case 'd':
			debug = 1;
			break;
		case 'h':
			printf("Usage: udev-acl --action=ACTION [--device=DEVICEFILE] [--user=UID]\n\n");
			goto out;
		}
	}

	if (action < 0 && device == NULL && !uid_given)
		if (!consolekit_called(argv[optind], &uid, &uid2, &remove_session_id, &action))
			uid_given = true;

	if (action < 0) {
		fprintf(stderr, "missing action\n\n");
		rc = 2;
		goto out;
	}

	if (device != NULL && uid_given) {
		fprintf(stderr, "only one option, --device=DEVICEFILE or --user=UID expected\n\n");
		rc = 3;
		goto out;
	}

	if (uid_given) {
		switch (action) {
		case ACTION_ADD:
			/* Add ACL for given uid to all matching devices. */
			apply_acl_to_devices(uid, 1);
			break;
		case ACTION_REMOVE:
			remove_uid(uid, remove_session_id);
			break;
		case ACTION_CHANGE:
			remove_uid(uid, remove_session_id);
			apply_acl_to_devices(uid2, 1);
			break;
		case ACTION_NONE:
			goto out;
			break;
		default:
			g_assert_not_reached();
			break;
		}
	} else if (device != NULL) {
		/*
		 * Add ACLs for all current session uids to a given device.
		 *
		 * Or remove ACLs for uids which do not have any current local
		 * active session. Remove is not really interesting, because in
		 * most cases the device node is removed anyway.
		 */
		GSList *list;
		GSList *l;

		list = uids_with_local_active_session(NULL);
		for (l = list; l != NULL; l = g_slist_next(l)) {
			uid_t u;

			u = GPOINTER_TO_UINT(l->data);
			if (action == ACTION_ADD || !uid_in_list(list, u))
				set_facl(device, u, action == ACTION_ADD);
		}
		g_slist_free(list);
	} else {
		fprintf(stderr, "--device=DEVICEFILE or --user=UID expected\n\n");
		rc = 3;
	}
out:
	return rc;
}