static int show_policy(const char *fn) {
        Policy p = {};
        int r;

        r = policy_load(&p, STRV_MAKE(fn));
        if (r < 0) {
                log_error_errno(r, "Failed to load policy %s: %m", fn);
                return r;
        }

        policy_dump(&p);
        policy_free(&p);

        return 0;
}
int main(int argc, char *argv[]) {

        Policy p = {};

        printf("Showing session policy BEGIN\n");
        show_policy("/etc/dbus-1/session.conf");
        printf("Showing session policy END\n");

        printf("Showing system policy BEGIN\n");
        show_policy("/etc/dbus-1/system.conf");
        printf("Showing system policy END\n");

        /* Ownership tests */
        assert_se(test_policy_load(&p, "ownerships.conf") == 0);

        assert_se(policy_check_own(&p, 0, 0, "org.test.test1") == true);
        assert_se(policy_check_own(&p, 1, 0, "org.test.test1") == true);

        assert_se(policy_check_own(&p, 0, 0, "org.test.test2") == true);
        assert_se(policy_check_own(&p, 1, 0, "org.test.test2") == false);

        assert_se(policy_check_own(&p, 0, 0, "org.test.test3") == false);
        assert_se(policy_check_own(&p, 1, 0, "org.test.test3") == false);

        assert_se(policy_check_own(&p, 0, 0, "org.test.test4") == false);
        assert_se(policy_check_own(&p, 1, 0, "org.test.test4") == true);

        policy_free(&p);

        /* Signaltest */
        assert_se(test_policy_load(&p, "signals.conf") == 0);

        assert_se(policy_check_one_send(&p, 0, 0, SD_BUS_MESSAGE_SIGNAL, "bli.bla.blubb", NULL, "/an/object/path", NULL) == true);
        assert_se(policy_check_one_send(&p, 1, 0, SD_BUS_MESSAGE_SIGNAL, "bli.bla.blubb", NULL, "/an/object/path", NULL) == false);

        policy_free(&p);

        /* Method calls */
        assert_se(test_policy_load(&p, "methods.conf") == 0);
        policy_dump(&p);

        assert_se(policy_check_one_send(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test1", "/an/object/path", "bli.bla.blubb", "Member") == false);
        assert_se(policy_check_one_send(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test1", "/an/object/path", "bli.bla.blubb", "Member") == false);
        assert_se(policy_check_one_send(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test1", "/an/object/path", "org.test.int1", "Member") == true);
        assert_se(policy_check_one_send(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test1", "/an/object/path", "org.test.int2", "Member") == true);

        assert_se(policy_check_one_recv(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test3", "/an/object/path", "org.test.int3", "Member111") == true);

        policy_free(&p);

        /* User and groups */
        assert_se(test_policy_load(&p, "hello.conf") == 0);
        policy_dump(&p);

        assert_se(policy_check_hello(&p, 0, 0) == true);
        assert_se(policy_check_hello(&p, 1, 0) == false);
        assert_se(policy_check_hello(&p, 0, 1) == false);

        policy_free(&p);

        /* dbus1 test file: ownership */

        assert_se(test_policy_load(&p, "check-own-rules.conf") >= 0);
        policy_dump(&p);

        assert_se(policy_check_own(&p, 0, 0, "org.freedesktop") == false);
        assert_se(policy_check_own(&p, 0, 0, "org.freedesktop.ManySystem") == false);
        assert_se(policy_check_own(&p, 0, 0, "org.freedesktop.ManySystems") == true);
        assert_se(policy_check_own(&p, 0, 0, "org.freedesktop.ManySystems.foo") == true);
        assert_se(policy_check_own(&p, 0, 0, "org.freedesktop.ManySystems.foo.bar") == true);
        assert_se(policy_check_own(&p, 0, 0, "org.freedesktop.ManySystems2") == false);
        assert_se(policy_check_own(&p, 0, 0, "org.freedesktop.ManySystems2.foo") == false);
        assert_se(policy_check_own(&p, 0, 0, "org.freedesktop.ManySystems2.foo.bar") == false);

        policy_free(&p);

        /* dbus1 test file: many rules */

        assert_se(test_policy_load(&p, "many-rules.conf") >= 0);
        policy_dump(&p);
        policy_free(&p);

        /* dbus1 test file: generic test */

        assert_se(test_policy_load(&p, "test.conf") >= 0);
        policy_dump(&p);

        assert_se(policy_check_own(&p, 0, 0, "org.foo.FooService") == true);
        assert_se(policy_check_own(&p, 0, 0, "org.foo.FooService2") == false);
        assert_se(policy_check_one_send(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test1", "/an/object/path", "org.test.int2", "Member") == false);
        assert_se(policy_check_one_send(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test1", "/an/object/path", "org.foo.FooBroadcastInterface", "Member") == true);
        assert_se(policy_check_one_recv(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.foo.FooService", "/an/object/path", "org.foo.FooBroadcastInterface", "Member") == true);
        assert_se(policy_check_one_recv(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.foo.FooService", "/an/object/path", "org.foo.FooBroadcastInterface2", "Member") == false);
        assert_se(policy_check_one_recv(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.foo.FooService2", "/an/object/path", "org.foo.FooBroadcastInterface", "Member") == false);

        assert_se(policy_check_own(&p, 100, 0, "org.foo.FooService") == false);
        assert_se(policy_check_own(&p, 100, 0, "org.foo.FooService2") == false);
        assert_se(policy_check_one_send(&p, 100, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test1", "/an/object/path", "org.test.int2", "Member") == false);
        assert_se(policy_check_one_send(&p, 100, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test1", "/an/object/path", "org.foo.FooBroadcastInterface", "Member") == false);
        assert_se(policy_check_one_recv(&p, 100, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.foo.FooService", "/an/object/path", "org.foo.FooBroadcastInterface", "Member") == true);
        assert_se(policy_check_one_recv(&p, 100, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.foo.FooService", "/an/object/path", "org.foo.FooBroadcastInterface2", "Member") == false);
        assert_se(policy_check_one_recv(&p, 100, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.foo.FooService2", "/an/object/path", "org.foo.FooBroadcastInterface", "Member") == false);

        policy_free(&p);

        return EXIT_SUCCESS;
}
Example #3
0
static time_t
perform_enforce(int sockfd, engine_type *engine, int bForceUpdate,
	task_type* task, db_connection_t *dbconn)
{
	zone_list_t *zonelist = NULL;
	zone_t *zone, *firstzone = NULL;
	policy_t *policy;
	key_data_list_t *keylist;
	const key_data_t *key;
	time_t t_next, t_now = time_now(), t_reschedule = -1;
	/* Flags that indicate tasks to be scheduled after zones have been
	 * enforced. */
	int bSignerConfNeedsWriting = 0;
	int bSubmitToParent = 0;
	int bRetractFromParent = 0;
	int zone_updated;

	if (!(zonelist = zone_list_new(dbconn))
		/*|| zone_list_associated_fetch(zonelist)*/
		|| zone_list_get(zonelist))
	{
		zone_list_free(zonelist);
		zonelist = NULL;
	}
	if (!zonelist) {
		/* TODO: log error */
		ods_log_error("[%s] zonelist NULL", module_str);
		/* TODO: backoff? */
		return t_reschedule;
	}

	for (zone = zone_list_get_next(zonelist); zone;
		zone_free(zone), zone = zone_list_get_next(zonelist))
	{
		if (engine->need_to_reload || engine->need_to_exit) break;

		if (!bForceUpdate && (zone_next_change(zone) == -1)) {
			continue;
		} else if (zone_next_change(zone) > t_now && !bForceUpdate) {
			/* This zone needs no update, however it might be the first
			 * for future updates */
			if (zone_next_change(zone) < t_reschedule || !firstzone)
			{
				t_reschedule = zone_next_change(zone);
				if (firstzone) {
					zone_free(firstzone);
				}
				firstzone = zone;
				zone = NULL; /* keeps firstzone from being freed. */
			}
			continue;
		}
		if (!(policy = zone_get_policy(zone))) {
			client_printf(sockfd,
				"Next update for zone %s NOT scheduled "
				"because policy is missing !\n", zone_name(zone));
			if (zone_next_change(zone) != -1
				&& (zone_set_next_change(zone, -1)
					|| zone_update(zone)))
			{
				/* TODO: Log error */
			}
			continue;
		}

		if (policy_passthrough(policy)) {
			ods_log_info("Passing through zone %s.\n", zone_name(zone));
			zone_set_signconf_needs_writing(zone, 1);
			zone_update(zone);
			bSignerConfNeedsWriting = 1;
			policy_free(policy);
			continue;
		}

		zone_updated = 0;
		t_next = update(engine, dbconn, zone, policy, t_now, &zone_updated);
		policy_free(policy);
		bSignerConfNeedsWriting |= zone_signconf_needs_writing(zone);

		keylist = zone_get_keys(zone);
		while ((key = key_data_list_next(keylist))) {
			if (key_data_ds_at_parent(key) == KEY_DATA_DS_AT_PARENT_SUBMIT) {
				ods_log_warning("[%s] please submit DS "
					"with keytag %d for zone %s",
					module_str, key_data_keytag(key)&0xFFFF, zone_name(zone));
				bSubmitToParent = 1;
			} else if (key_data_ds_at_parent(key) == KEY_DATA_DS_AT_PARENT_RETRACT) {
				ods_log_warning("[%s] please retract DS "
					"with keytag %d for zone %s",
					module_str, key_data_keytag(key)&0xFFFF, zone_name(zone));
				bRetractFromParent = 1;
			}
		}
		key_data_list_free(keylist);

		if (t_next == -1) {
			client_printf(sockfd,
				"Next update for zone %s NOT scheduled "
				"by enforcer !\n", zone_name(zone));
			ods_log_debug("Next update for zone %s NOT scheduled "
				"by enforcer !\n", zone_name(zone));
		} else {
			/* Invalid schedule time then skip the zone.*/
			char tbuf[32] = "date/time invalid\n"; /* at least 26 bytes */
			ctime_r(&t_next, tbuf); /* note that ctime_r inserts \n */
			client_printf(sockfd,
				"Next update for zone %s scheduled at %s",
				zone_name(zone), tbuf);
			ods_log_debug("Next update for zone %s scheduled at %s",
				zone_name(zone), tbuf);
		}
		if (zone_next_change(zone) != t_next) {
			zone_set_next_change(zone, t_next);
			zone_updated = 1;
		}

		/*
		 * Commit the changes to the zone if there where any.
		 */
		if (zone_updated) {
			if (zone_update(zone)) {
				ods_log_debug("[%s] error zone_update(%s)", module_str, zone_name(zone));
			}
		}

		/*
		 * Find out when to schedule the next change.
		 */
		if (zone_next_change(zone) != -1
			&& (zone_next_change(zone) < t_reschedule
				|| !firstzone))
		{
			t_reschedule = zone_next_change(zone);
			if (firstzone) {
				zone_free(firstzone);
			}
			firstzone = zone;
			zone = NULL;
		}
	}
	zone_list_free(zonelist);

	/*
	 * Schedule the next change if needed.
	 */
	if (firstzone) {
		reschedule_enforce(task, t_reschedule, zone_name(firstzone));
		zone_free(firstzone);
	}

	/* Launch signer configuration writer task when one of the
	 * zones indicated that it needs to be written.
	 * TODO: unschedule it first!
	 */
	if (bSignerConfNeedsWriting) {
		task_type *signconf =
			signconf_task(dbconn, "signconf", "signer configurations");
		enf_schedule_task(sockfd,engine,signconf,"signconf");
	} else {
		ods_log_info("[%s] No changes to any signconf file required", module_str);
	}

	/* Launch ds-submit task when one of the updated key states has the
	 * DS_SUBMIT flag set. */
	if (bSubmitToParent) {
		task_type *submit =
			keystate_ds_submit_task(engine);
		enf_schedule_task(sockfd, engine, submit, "ds-submit");
	}


	/* Launch ds-retract task when one of the updated key states has the
	 * DS_RETRACT flag set. */
	if (bRetractFromParent) {
		task_type *retract =
			keystate_ds_retract_task(engine);
		enf_schedule_task(sockfd, engine, retract, "ds-retract");
	}


	return t_reschedule;
}