1 /* 2 * Fake PAM library test suite. 3 * 4 * This is not actually a test for the pam-util layer, but rather is a test 5 * for the trickier components of the fake PAM library that in turn is used to 6 * test the pam-util layer and PAM modules. 7 * 8 * The canonical version of this file is maintained in the rra-c-util package, 9 * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>. 10 * 11 * Written by Russ Allbery <eagle@eyrie.org> 12 * Copyright 2010, 2013 13 * The Board of Trustees of the Leland Stanford Junior University 14 * 15 * Permission is hereby granted, free of charge, to any person obtaining a 16 * copy of this software and associated documentation files (the "Software"), 17 * to deal in the Software without restriction, including without limitation 18 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 19 * and/or sell copies of the Software, and to permit persons to whom the 20 * Software is furnished to do so, subject to the following conditions: 21 * 22 * The above copyright notice and this permission notice shall be included in 23 * all copies or substantial portions of the Software. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 28 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 30 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 31 * DEALINGS IN THE SOFTWARE. 32 * 33 * SPDX-License-Identifier: MIT 34 */ 35 36 #include <config.h> 37 #include <portable/pam.h> 38 #include <portable/system.h> 39 40 #include <tests/fakepam/pam.h> 41 #include <tests/tap/basic.h> 42 43 44 int 45 main(void) 46 { 47 pam_handle_t *pamh; 48 struct pam_conv conv = {NULL, NULL}; 49 char **env; 50 size_t i; 51 52 /* 53 * Skip this test if the native PAM library doesn't support a PAM 54 * environment, since we "break" pam_putenv to mirror the native behavior 55 * in that case. 56 */ 57 #ifndef HAVE_PAM_GETENV 58 skip_all("system doesn't support PAM environment"); 59 #endif 60 61 plan(33); 62 63 /* Basic environment manipulation. */ 64 if (pam_start("test", NULL, &conv, &pamh) != PAM_SUCCESS) 65 sysbail("Fake PAM initialization failed"); 66 is_int(PAM_BAD_ITEM, pam_putenv(pamh, "TEST"), "delete when NULL"); 67 ok(pam_getenv(pamh, "TEST") == NULL, "getenv when NULL"); 68 env = pam_getenvlist(pamh); 69 ok(env != NULL, "getenvlist when NULL returns non-NULL"); 70 if (env == NULL) 71 bail("pam_getenvlist returned NULL"); 72 is_string(NULL, env[0], "...but first element is NULL"); 73 for (i = 0; env[i] != NULL; i++) 74 free(env[i]); 75 free(env); 76 77 /* putenv and getenv. */ 78 is_int(PAM_SUCCESS, pam_putenv(pamh, "TEST=foo"), "putenv TEST"); 79 is_string("foo", pam_getenv(pamh, "TEST"), "getenv TEST"); 80 is_int(PAM_SUCCESS, pam_putenv(pamh, "FOO=bar"), "putenv FOO"); 81 is_int(PAM_SUCCESS, pam_putenv(pamh, "BAR=baz"), "putenv BAR"); 82 is_string("foo", pam_getenv(pamh, "TEST"), "getenv TEST"); 83 is_string("bar", pam_getenv(pamh, "FOO"), "getenv FOO"); 84 is_string("baz", pam_getenv(pamh, "BAR"), "getenv BAR"); 85 ok(pam_getenv(pamh, "BAZ") == NULL, "getenv BAZ is NULL"); 86 87 /* Replacing and deleting environment variables. */ 88 is_int(PAM_BAD_ITEM, pam_putenv(pamh, "BAZ"), "putenv nonexistent delete"); 89 is_int(PAM_SUCCESS, pam_putenv(pamh, "FOO=foo"), "putenv replace"); 90 is_int(PAM_SUCCESS, pam_putenv(pamh, "FOON=bar=n"), "putenv prefix"); 91 is_string("foo", pam_getenv(pamh, "FOO"), "getenv FOO"); 92 is_string("bar=n", pam_getenv(pamh, "FOON"), "getenv FOON"); 93 is_int(PAM_BAD_ITEM, pam_putenv(pamh, "FO"), "putenv delete FO"); 94 is_int(PAM_SUCCESS, pam_putenv(pamh, "FOO"), "putenv delete FOO"); 95 ok(pam_getenv(pamh, "FOO") == NULL, "getenv FOO is NULL"); 96 is_string("bar=n", pam_getenv(pamh, "FOON"), "getenv FOON"); 97 is_string("baz", pam_getenv(pamh, "BAR"), "getenv BAR"); 98 99 /* pam_getenvlist. */ 100 env = pam_getenvlist(pamh); 101 ok(env != NULL, "getenvlist not NULL"); 102 if (env == NULL) 103 bail("pam_getenvlist returned NULL"); 104 is_string("TEST=foo", env[0], "getenvlist TEST"); 105 is_string("BAR=baz", env[1], "getenvlist BAR"); 106 is_string("FOON=bar=n", env[2], "getenvlist FOON"); 107 ok(env[3] == NULL, "getenvlist length"); 108 for (i = 0; env[i] != NULL; i++) 109 free(env[i]); 110 free(env); 111 is_int(PAM_SUCCESS, pam_putenv(pamh, "FOO=foo"), "putenv FOO"); 112 is_string("TEST=foo", pamh->environ[0], "pamh environ TEST"); 113 is_string("BAR=baz", pamh->environ[1], "pamh environ BAR"); 114 is_string("FOON=bar=n", pamh->environ[2], "pamh environ FOON"); 115 is_string("FOO=foo", pamh->environ[3], "pamh environ FOO"); 116 ok(pamh->environ[4] == NULL, "pamh environ length"); 117 118 pam_end(pamh, 0); 119 120 return 0; 121 } 122