1 /*
2 * Check pam_sepermit return values and conf= option.
3 *
4 * Copyright (c) 2020-2022 Dmitry V. Levin <ldv@altlinux.org>
5 */
6
7 #include "test_assert.h"
8
9 #include <limits.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <security/pam_appl.h>
14
15 #define MODULE_NAME "pam_sepermit"
16 #define TEST_NAME "tst-" MODULE_NAME "-retval"
17
18 static const char service_file[] = TEST_NAME ".service";
19 static const char missing_file[] = TEST_NAME ".missing";
20 static const char config_file[] = TEST_NAME ".conf";
21 static struct pam_conv conv;
22
23 int
24 main(void)
25 {
26 pam_handle_t *pamh = NULL;
27 FILE *fp;
28 char cwd[PATH_MAX];
29
30 ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
31
32 /* PAM_USER_UNKNOWN */
33 ASSERT_NE(NULL, fp = fopen(service_file, "w"));
34 ASSERT_LT(0,
35 fprintf(fp, "#%%PAM-1.0\n"
36 "auth required %s/.libs/%s.so\n"
37 "account required %s/.libs/%s.so\n"
38 "password required %s/.libs/%s.so\n"
39 "session required %s/.libs/%s.so\n",
40 cwd, MODULE_NAME,
41 cwd, MODULE_NAME,
42 cwd, MODULE_NAME,
43 cwd, MODULE_NAME));
44 ASSERT_EQ(0, fclose(fp));
45
46 ASSERT_EQ(PAM_SUCCESS,
47 pam_start_confdir(service_file, "", &conv, ".", &pamh));
48 ASSERT_NE(NULL, pamh);
49 ASSERT_EQ(PAM_USER_UNKNOWN, pam_authenticate(pamh, 0));
50 ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0));
51 ASSERT_EQ(PAM_USER_UNKNOWN, pam_acct_mgmt(pamh, 0));
52 ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
53 ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
54 ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
55 ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
56 pamh = NULL;
57
58 ASSERT_NE(NULL, fp = fopen(config_file, "w"));
59 ASSERT_LT(0, fprintf(fp, "nosuchuser:ignore\n"));
60 ASSERT_EQ(0, fclose(fp));
61
62 /*
63 * conf= specifies an existing file,
64 * PAM_IGNORE -> PAM_PERM_DENIED
65 */
66 ASSERT_NE(NULL, fp = fopen(service_file, "w"));
67 ASSERT_LT(0,
68 fprintf(fp, "#%%PAM-1.0\n"
69 "auth required %s/.libs/%s.so conf=%s\n"
70 "account required %s/.libs/%s.so conf=%s\n"
71 "password required %s/.libs/%s.so conf=%s\n"
72 "session required %s/.libs/%s.so conf=%s\n",
73 cwd, MODULE_NAME, config_file,
74 cwd, MODULE_NAME, config_file,
75 cwd, MODULE_NAME, config_file,
76 cwd, MODULE_NAME, config_file));
77 ASSERT_EQ(0, fclose(fp));
78
79 ASSERT_EQ(PAM_SUCCESS,
80 pam_start_confdir(service_file, "root", &conv, ".", &pamh));
81 ASSERT_NE(NULL, pamh);
82 ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0));
83 ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0));
84 ASSERT_EQ(PAM_PERM_DENIED, pam_acct_mgmt(pamh, 0));
85 ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
86 ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
87 ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
88 ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
89 pamh = NULL;
90
91 /*
92 * conf= specifies an existing file,
93 * PAM_IGNORE -> PAM_SUCCESS
94 */
95 ASSERT_NE(NULL, fp = fopen(service_file, "w"));
96 ASSERT_LT(0,
97 fprintf(fp, "#%%PAM-1.0\n"
98 "auth required %s/.libs/%s.so conf=%s\n"
99 "auth required %s/../pam_permit/.libs/pam_permit.so\n"
100 "account required %s/.libs/%s.so conf=%s\n"
101 "account required %s/../pam_permit/.libs/pam_permit.so\n"
102 "password required %s/.libs/%s.so conf=%s\n"
103 "password required %s/../pam_permit/.libs/pam_permit.so\n"
104 "session required %s/.libs/%s.so conf=%s\n"
105 "session required %s/../pam_permit/.libs/pam_permit.so\n",
106 cwd, MODULE_NAME, config_file, cwd,
107 cwd, MODULE_NAME, config_file, cwd,
108 cwd, MODULE_NAME, config_file, cwd,
109 cwd, MODULE_NAME, config_file, cwd));
110 ASSERT_EQ(0, fclose(fp));
111
112 ASSERT_EQ(PAM_SUCCESS,
113 pam_start_confdir(service_file, "root", &conv, ".", &pamh));
114 ASSERT_NE(NULL, pamh);
115 ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
116 ASSERT_EQ(PAM_SUCCESS, pam_setcred(pamh, 0));
117 ASSERT_EQ(PAM_SUCCESS, pam_acct_mgmt(pamh, 0));
118 ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
119 ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
120 ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
121 ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
122 pamh = NULL;
123
124 /*
125 * conf= specifies a missing file,
126 * PAM_IGNORE -> PAM_PERM_DENIED
127 */
128 ASSERT_NE(NULL, fp = fopen(service_file, "w"));
129 ASSERT_LT(0,
130 fprintf(fp, "#%%PAM-1.0\n"
131 "auth required %s/.libs/%s.so conf=%s\n"
132 "account required %s/.libs/%s.so conf=%s\n"
133 "password required %s/.libs/%s.so conf=%s\n"
134 "session required %s/.libs/%s.so conf=%s\n",
135 cwd, MODULE_NAME, missing_file,
136 cwd, MODULE_NAME, missing_file,
137 cwd, MODULE_NAME, missing_file,
138 cwd, MODULE_NAME, missing_file));
139 ASSERT_EQ(0, fclose(fp));
140
141 ASSERT_EQ(PAM_SUCCESS,
142 pam_start_confdir(service_file, "root", &conv, ".", &pamh));
143 ASSERT_NE(NULL, pamh);
144 ASSERT_EQ(PAM_SERVICE_ERR, pam_authenticate(pamh, 0));
145 ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0));
146 ASSERT_EQ(PAM_SERVICE_ERR, pam_acct_mgmt(pamh, 0));
147 ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
148 ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
149 ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
150 ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
151 pamh = NULL;
152
153 /* cleanup */
154 ASSERT_EQ(0, unlink(config_file));
155 ASSERT_EQ(0, unlink(service_file));
156
157 return 0;
158 }