From 2d257ccf620ce1b611f89cec8f0a94c88c2f2881 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Thu, 5 Jul 2012 10:50:08 +0200 Subject: pac responder: limit access by checking UIDs A check for allowed UIDs is added in the common responder code directly after accept(). If the platform does not support reading the UID of the peer but allowed UIDs are configured, access is denied. Currently only the PAC responder sets the allowed UIDs for a socket. The default is that only root is allowed to access the socket of the PAC responder. Fixes: https://fedorahosted.org/sssd/ticket/1382 --- src/tests/responder_socket_access-tests.c | 178 ++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 src/tests/responder_socket_access-tests.c (limited to 'src/tests/responder_socket_access-tests.c') diff --git a/src/tests/responder_socket_access-tests.c b/src/tests/responder_socket_access-tests.c new file mode 100644 index 00000000..734bf1cb --- /dev/null +++ b/src/tests/responder_socket_access-tests.c @@ -0,0 +1,178 @@ +/* + SSSD - Test for routine to check to access to responder sockets + + Authors: + Sumit Bose + + Copyright (C) 2012 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include + +#include "tests/common.h" +#include "responder/common/responder.h" + +struct cli_protocol_version *register_cli_protocol_version(void) +{ + static struct cli_protocol_version responder_test_cli_protocol_version[] = { + {0, NULL, NULL} + }; + + return responder_test_cli_protocol_version; +} + +struct s2a_data { + const char *inp; + int exp_ret; + size_t exp_count; + uid_t *exp_uids; +}; + +struct s2a_data s2a_data[] = { + {"1,2,3", 0, 3, (uid_t []){1, 2, 3}}, + {"1,2,3, 4,5 , 6 , 7 ", 0, 7, (uid_t []){1, 2, 3, 4, 5, 6, 7}}, + {"1", 0, 1, (uid_t []){1}}, + {"1, +2,3", 0, 3, (uid_t []){1, 2, 3}}, + {"1, -2,3", ERANGE, 0, NULL}, + {"1, 2ab, 3, 4", EINVAL, 0, NULL}, + {"1,", EINVAL, 0, NULL}, + {"", EINVAL, 0, NULL}, + {"1, 2, 4294967295", 0, 3, (uid_t []){1, 2, 4294967295U}}, + {"1, 2, 4294967296", ERANGE, 0, NULL}, + {"1, 2, root, 4, 5", 0, 5, (uid_t []){1, 2, 0, 4, 5}}, + {NULL, EINVAL, 0, NULL}, + {NULL, -1, 0, NULL} +}; + +START_TEST(resp_str_to_array_test) +{ + int ret; + size_t uid_count; + uid_t *uids = NULL; + size_t c; + size_t d; + + for (c = 0; s2a_data[c].exp_ret != -1; c++) { + ret = csv_string_to_uid_array(global_talloc_context, s2a_data[c].inp, + true, &uid_count, &uids); + fail_unless(ret == s2a_data[c].exp_ret, + "csv_string_to_uid_array failed [%d][%s].", ret, + strerror(ret)); + if (ret == 0) { + fail_unless(uid_count == s2a_data[c].exp_count, + "Wrong number of values, expected [%d], got [%d].", + s2a_data[c].exp_count, uid_count); + for (d = 0; d < s2a_data[c].exp_count; d++) { + fail_unless(uids[d] == s2a_data[c].exp_uids[d], + "Wrong value, expected [%d], got [%d].\n", + s2a_data[c].exp_uids[d], uids[d]); + } + } + + talloc_free(uids); + uids = NULL; + } + +} +END_TEST + +struct uid_check_data { + uid_t uid; + size_t allowed_uids_count; + uid_t *allowed_uids; + int exp_ret; +}; + +struct uid_check_data uid_check_data[] = { + {1, 3, (uid_t []){1, 2, 3}, 0}, + {2, 3, (uid_t []){1, 2, 3}, 0}, + {3, 3, (uid_t []){1, 2, 3}, 0}, + {4, 3, (uid_t []){1, 2, 3}, EACCES}, + {4, 0, NULL, EINVAL}, + {0, 0, NULL, -1} +}; + +START_TEST(check_allowed_uids_test) +{ + int ret; + size_t c; + + for (c = 0; uid_check_data[c].exp_ret == -1; c++) { + ret = check_allowed_uids(uid_check_data[c].uid, + uid_check_data[c].allowed_uids_count, + uid_check_data[c].allowed_uids); + fail_unless(ret == uid_check_data[c].exp_ret, + "check_allowed_uids failed [%d][%s].", ret, strerror(ret)); + } +} +END_TEST + +Suite *responder_test_suite(void) +{ + Suite *s = suite_create ("Responder socket access"); + + TCase *tc_utils = tcase_create("Utility test"); + + tcase_add_test(tc_utils, resp_str_to_array_test); + tcase_add_test(tc_utils, check_allowed_uids_test); + + suite_add_tcase(s, tc_utils); + + return s; +} + +int main(int argc, const char *argv[]) +{ + int opt; + int number_failed; + poptContext pc; + + struct poptOption long_options[] = { + POPT_AUTOHELP + SSSD_MAIN_OPTS + POPT_TABLEEND + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ + debug_level = SSSDBG_INVALID; + + pc = poptGetContext(argv[0], argc, argv, long_options, 0); + while((opt = poptGetNextOpt(pc)) != -1) { + switch(opt) { + default: + fprintf(stderr, "\nInvalid option %s: %s\n\n", + poptBadOption(pc, 0), poptStrerror(opt)); + poptPrintUsage(pc, stderr, 0); + return 1; + } + } + poptFreeContext(pc); + + CONVERT_AND_SET_DEBUG_LEVEL(debug_level); + tests_set_cwd(); + + Suite *s = responder_test_suite(); + SRunner *sr = srunner_create(s); + + /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ + srunner_run_all(sr, CK_ENV); + number_failed = srunner_ntests_failed (sr); + srunner_free (sr); + + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} -- cgit