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
main(void)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