1 /* 2 * QEMU PAM authorization object tests 3 * 4 * Copyright (c) 2018 Red Hat, Inc. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 * 19 */ 20 21 #include "qemu/osdep.h" 22 #include "qapi/error.h" 23 #include "qemu/module.h" 24 #include "authz/pamacct.h" 25 26 #include <security/pam_appl.h> 27 28 static bool failauth; 29 30 /* 31 * These three functions are exported by libpam.so. 32 * 33 * By defining them again here, our impls are resolved 34 * by the linker instead of those in libpam.so 35 * 36 * The test suite is thus isolated from the host system 37 * PAM setup, so we can do predictable test scenarios 38 */ 39 int 40 pam_start(const char *service_name, const char *user, 41 const struct pam_conv *pam_conversation, 42 pam_handle_t **pamh) 43 { 44 failauth = true; 45 if (!g_str_equal(service_name, "qemu-vnc")) { 46 return PAM_AUTH_ERR; 47 } 48 49 if (g_str_equal(user, "fred")) { 50 failauth = false; 51 } 52 53 *pamh = (pam_handle_t *)0xbadeaffe; 54 return PAM_SUCCESS; 55 } 56 57 58 int 59 pam_acct_mgmt(pam_handle_t *pamh, int flags) 60 { 61 if (failauth) { 62 return PAM_AUTH_ERR; 63 } 64 65 return PAM_SUCCESS; 66 } 67 68 69 int 70 pam_end(pam_handle_t *pamh, int status) 71 { 72 return PAM_SUCCESS; 73 } 74 75 76 static void test_authz_unknown_service(void) 77 { 78 Error *local_err = NULL; 79 QAuthZPAM *auth = qauthz_pam_new("auth0", 80 "qemu-does-not-exist", 81 &error_abort); 82 83 g_assert_nonnull(auth); 84 85 g_assert_false(qauthz_is_allowed(QAUTHZ(auth), "fred", &local_err)); 86 87 error_free_or_abort(&local_err); 88 object_unparent(OBJECT(auth)); 89 } 90 91 92 static void test_authz_good_user(void) 93 { 94 QAuthZPAM *auth = qauthz_pam_new("auth0", 95 "qemu-vnc", 96 &error_abort); 97 98 g_assert_nonnull(auth); 99 100 g_assert_true(qauthz_is_allowed(QAUTHZ(auth), "fred", &error_abort)); 101 102 object_unparent(OBJECT(auth)); 103 } 104 105 106 static void test_authz_bad_user(void) 107 { 108 Error *local_err = NULL; 109 QAuthZPAM *auth = qauthz_pam_new("auth0", 110 "qemu-vnc", 111 &error_abort); 112 113 g_assert_nonnull(auth); 114 115 g_assert_false(qauthz_is_allowed(QAUTHZ(auth), "bob", &local_err)); 116 117 error_free_or_abort(&local_err); 118 object_unparent(OBJECT(auth)); 119 } 120 121 122 int main(int argc, char **argv) 123 { 124 g_test_init(&argc, &argv, NULL); 125 126 module_call_init(MODULE_INIT_QOM); 127 128 g_test_add_func("/auth/pam/unknown-service", test_authz_unknown_service); 129 g_test_add_func("/auth/pam/good-user", test_authz_good_user); 130 g_test_add_func("/auth/pam/bad-user", test_authz_bad_user); 131 132 return g_test_run(); 133 } 134