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; }
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; }