/* * Copyright (C) 2011 Google Inc. * Copyright (C) 2012 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. * * Author: Nikki VonHollen * David Zeuthen */ #include "config.h" #include "glib.h" #include #include #include #include #include /* see test/data/etc/polkit-1/rules.d/10-testing.rules */ /* Test helper types */ static PolkitBackendJsAuthority *get_authority (void); static PolkitBackendJsAuthority * get_authority (void) { gchar *rules_dirs[4] = {0}; PolkitBackendJsAuthority *authority; rules_dirs[0] = polkit_test_get_data_path ("etc/polkit-1/rules.d"); rules_dirs[1] = polkit_test_get_data_path ("usr/local/share/polkit-1/rules.d"); rules_dirs[2] = polkit_test_get_data_path ("usr/share/polkit-1/rules.d"); rules_dirs[3] = NULL; g_assert (rules_dirs[0] != NULL); g_assert (rules_dirs[1] != NULL); authority = g_object_new (POLKIT_BACKEND_TYPE_JS_AUTHORITY, "rules-dirs", rules_dirs, NULL); g_free (rules_dirs[0]); g_free (rules_dirs[1]); return authority; } static void test_get_admin_identities_for_action_id (const gchar *action_id, const gchar *const *expected_admins) { PolkitBackendJsAuthority *authority = NULL; PolkitSubject *caller = NULL; PolkitSubject *subject = NULL; PolkitIdentity *user_for_subject = NULL; PolkitDetails *details = NULL; GError *error = NULL; GList *admin_identities = NULL; GList *l; guint n; authority = get_authority (); caller = polkit_unix_process_new_for_owner (getpid (), 0, getuid ()); subject = polkit_unix_process_new_for_owner (getpid (), 0, getuid ()); user_for_subject = polkit_identity_from_string ("unix-user:root", &error); g_assert_no_error (error); details = polkit_details_new (); /* Get the list of PolkitUnixUser objects who are admins */ admin_identities = polkit_backend_interactive_authority_get_admin_identities (POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority), caller, subject, user_for_subject, TRUE, /* is_local */ TRUE, /* is_active */ action_id, details); for (l = admin_identities, n = 0; l != NULL; l = l->next, n++) { PolkitIdentity *test_identity = POLKIT_IDENTITY (l->data); gchar *s; g_assert (expected_admins[n] != NULL); s = polkit_identity_to_string (test_identity); g_assert_cmpstr (expected_admins[n], ==, s); g_free (s); } g_assert_cmpstr (expected_admins[n], ==, NULL); g_list_free_full (admin_identities, g_object_unref); g_clear_object (&details); g_clear_object (&user_for_subject); g_clear_object (&subject); g_clear_object (&caller); g_clear_object (&authority); } static void test_get_admin_identities (void) { struct { const gchar *action_id; const gchar *expected_admins[5]; } test_cases[] = { { "com.example.doesntmatter", { "unix-group:admin", "unix-user:root" } }, { "net.company.action1", { "unix-group:admin" } }, { "net.company.action2", { "unix-group:users" } }, { "net.company.action3", { "unix-netgroup:foo" } }, }; guint n; for (n = 0; n < G_N_ELEMENTS (test_cases); n++) { test_get_admin_identities_for_action_id (test_cases[n].action_id, test_cases[n].expected_admins); } } /* ---------------------------------------------------------------------------------------------------- */ typedef struct RulesTestCase RulesTestCase; struct RulesTestCase { const gchar *test_name; const gchar *action_id; const gchar *identity; const gchar *vars; PolkitImplicitAuthorization expected_result; }; static const RulesTestCase rules_test_cases[] = { /* Check basics */ { "basic0", "net.company.productA.action0", "unix-user:root", NULL, POLKIT_IMPLICIT_AUTHORIZATION_ADMINISTRATOR_AUTHENTICATION_REQUIRED, }, { "basic1", "net.company.productA.action1", "unix-user:root", NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHENTICATION_REQUIRED, }, /* actions without explicit rules aren't automatically NOT_AUTHORIZED */ { "basic2", "net.company.productA.action2", "unix-user:john", NULL, POLKIT_IMPLICIT_AUTHORIZATION_UNKNOWN, }, /* Ordering tests ... we have six rules files, check they are * evaluated in order by checking the detail set by each rules * * - etc/polkit-1/rules.d/10-testing.rules (file a) * - usr/local/share/polkit-1/rules.d/10-testing.rules (file b) * - usr/share/polkit-1/rules.d/10-testing.rules (file c) * - etc/polkit-1/rules.d/15-testing.rules (file d) * - usr/share/polkit-1/rules.d/20-testing.rules (file e) * - usr/local/share/polkit-1/rules.d/25-testing.rules (file f) * * file. */ { /* defined in file a, b, c, d, e, f - should pick file a */ "order0", "net.company.order0", "unix-user:root", NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, }, { /* defined in file b, c, d, e, f - should pick file b */ "order1", "net.company.order1", "unix-user:root", NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, }, { /* defined in file c, d, e, f - should pick file c */ "order2", "net.company.order2", "unix-user:root", NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, }, { /* defined in file d, e, f - should pick file d */ "order3", "net.company.order3", "unix-user:root", NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, }, { /* defined in file e, f - should pick file e */ "order4", "net.company.order4", "unix-user:root", NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, }, /* variables */ { "variables1", "net.company.group.variables", "unix-user:root", "foo=1", POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, }, { "variables2", "net.company.group.variables", "unix-user:root", "foo=2", POLKIT_IMPLICIT_AUTHORIZATION_AUTHENTICATION_REQUIRED, }, { "variables3", "net.company.group.variables", "unix-user:root", NULL, POLKIT_IMPLICIT_AUTHORIZATION_ADMINISTRATOR_AUTHENTICATION_REQUIRED, }, /* check group membership */ { /* john is a member of group 'users', see test/etc/group */ "group_membership_with_member", "net.company.group.only_group_users", "unix-user:john", NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, }, { /* sally is not a member of group 'users', see test/etc/group */ "group_membership_with_non_member", "net.company.group.only_group_users", "unix-user:sally", NULL, POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED, }, /* check netgroup membership */ { /* john is a member of netgroup 'foo', see test/etc/netgroup */ "netgroup_membership_with_member", "net.company.group.only_netgroup_users", "unix-user:john", NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, }, { /* sally is not a member of netgroup 'foo', see test/etc/netgroup */ "netgroup_membership_with_non_member", "net.company.group.only_netgroup_users", "unix-user:sally", NULL, POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED, }, /* spawning */ { "spawning_non_existing_helper", "net.company.spawning.non_existing_helper", "unix-user:root", NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, }, { "spawning_successful_helper", "net.company.spawning.successful_helper", "unix-user:root", NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, }, { "spawning_failing_helper", "net.company.spawning.failing_helper", "unix-user:root", NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, }, { "spawning_helper_with_output", "net.company.spawning.helper_with_output", "unix-user:root", NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, }, { "spawning_helper_timeout", "net.company.spawning.helper_timeout", "unix-user:root", NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, }, /* runaway scripts */ { "runaway_script", "net.company.run_away_script", "unix-user:root", NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, }, { /* highuid1 is not a member of group 'users', see test/data/etc/group */ "group_membership_with_non_member(highuid22)", "net.company.group.only_group_users", "unix-user:highuid2", NULL, POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED, }, { /* highuid2 is not a member of group 'users', see test/data/etc/group */ "group_membership_with_non_member(highuid21)", "net.company.group.only_group_users", "unix-user:highuid2", NULL, POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED, }, { /* highuid1 is not a member of group 'users', see test/data/etc/group */ "group_membership_with_non_member(highuid24)", "net.company.group.only_group_users", "unix-user:2147483648", NULL, POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED, }, { /* highuid2 is not a member of group 'users', see test/data/etc/group */ "group_membership_with_non_member(highuid23)", "net.company.group.only_group_users", "unix-user:4000000000", NULL, POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED, }, { /* john is authorized to do this, see 10-testing.rules */ "john_action", "net.company.john_action", "unix-user:john", NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, }, { /* only john is authorized to do this, see 10-testing.rules */ "jane_action", "net.company.john_action", "unix-user:jane", NULL, POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED, }, { /* highuid2 is authorized to do this, see 10-testing.rules */ "highuid2_action", "net.company.highuid2_action", "unix-user:highuid2", NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, }, { /* only highuid2 is authorized to do this, see 10-testing.rules */ "highuid1_action", "net.company.highuid2_action", "unix-user:highuid1", NULL, POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED, }, }; /* ---------------------------------------------------------------------------------------------------- */ static void rules_test_func (gconstpointer user_data) { const RulesTestCase *tc = user_data; PolkitBackendJsAuthority *authority = NULL; PolkitSubject *caller = NULL; PolkitSubject *subject = NULL; PolkitIdentity *user_for_subject = NULL; PolkitDetails *details = NULL; GError *error = NULL; PolkitImplicitAuthorization result; authority = get_authority (); caller = polkit_unix_process_new_for_owner (getpid (), 0, getuid ()); subject = polkit_unix_process_new_for_owner (getpid (), 0, getuid ()); user_for_subject = polkit_identity_from_string (tc->identity, &error); g_assert_no_error (error); details = polkit_details_new (); if (tc->vars != NULL) { gchar *s; const gchar *key; const gchar *value; s = g_strdup (tc->vars); key = s; value = strchr (key, '='); g_assert (value != NULL); *((gchar *) value) = '\0'; value += 1; polkit_details_insert (details, key, value); g_free (s); } result = polkit_backend_interactive_authority_check_authorization_sync (POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority), caller, subject, user_for_subject, TRUE, TRUE, tc->action_id, details, POLKIT_IMPLICIT_AUTHORIZATION_UNKNOWN); g_assert_cmpint (result, ==, tc->expected_result); g_clear_object (&details); g_clear_object (&user_for_subject); g_clear_object (&subject); g_clear_object (&caller); g_clear_object (&authority); } static void add_rules_tests (void) { guint n; for (n = 0; n < G_N_ELEMENTS (rules_test_cases); n++) { const RulesTestCase *tc = &rules_test_cases[n]; gchar *s; s = g_strdup_printf ("/PolkitBackendJsAuthority/rules_%s", tc->test_name); g_test_add_data_func (s, &rules_test_cases[n], rules_test_func); g_free (s); } } /* ---------------------------------------------------------------------------------------------------- */ int main (int argc, char *argv[]) { setlocale (LC_ALL, ""); g_test_init (&argc, &argv, NULL); //polkit_test_redirect_logs (); g_test_add_func ("/PolkitBackendJsAuthority/get_admin_identities", test_get_admin_identities); add_rules_tests (); return g_test_run (); };