1 /*
2 * Check pam_localuser return values.
3 *
4 * Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
5 */
6
7 #include "test_assert.h"
8
9 #include <limits.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
14 #include <security/pam_appl.h>
15
16 #define MODULE_NAME "pam_localuser"
17 #define TEST_NAME "tst-" MODULE_NAME "-retval"
18
19 static const char service_file[] = TEST_NAME ".service";
20 static const char passwd_file[] = TEST_NAME ".passwd";
21 static const char missing_file[] = TEST_NAME ".missing";
22
23 static const char alice_line[] = "alice:x:1001:1001:Alice:/home/alice:";
24 static const char bob_line[] = "bob:x:1002:1002:Bob:/home/bob:";
25 static const char craig_prefix[] = ":x:1003:1003:";
26 static const char craig_suffix[] = "craig:/home/craig:";
27
28 int
29 main(void)
30 {
31 static struct pam_conv conv;
32 pam_handle_t *pamh = NULL;
33 FILE *fp;
34 char cwd[PATH_MAX];
35 char name[BUFSIZ];
36
37 ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
38
39 /* default passwd */
40 ASSERT_NE(NULL, fp = fopen(service_file, "w"));
41 ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
42 "auth required %s/.libs/%s.so\n",
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_SERVICE_ERR, pam_authenticate(pamh, 0));
50 ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
51 pamh = NULL;
52
53 memset(name, 'x', sizeof(name) - 1);
54 name[sizeof(name) - 1] = '\0';
55 ASSERT_EQ(PAM_SUCCESS,
56 pam_start_confdir(service_file, name, &conv, ".", &pamh));
57 ASSERT_NE(NULL, pamh);
58 ASSERT_EQ(PAM_SERVICE_ERR, pam_authenticate(pamh, 0));
59 ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
60 pamh = NULL;
61
62 ASSERT_EQ(PAM_SUCCESS,
63 pam_start_confdir(service_file, "root:x", &conv, ".", &pamh));
64 ASSERT_NE(NULL, pamh);
65 ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0));
66 ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
67 pamh = NULL;
68
69 /* missing passwd file */
70 ASSERT_NE(NULL, fp = fopen(service_file, "w"));
71 ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
72 "auth required %s/.libs/%s.so file=%s\n",
73 cwd, MODULE_NAME, missing_file));
74 ASSERT_EQ(0, fclose(fp));
75
76 ASSERT_EQ(PAM_SUCCESS,
77 pam_start_confdir(service_file, "root", &conv, ".", &pamh));
78 ASSERT_NE(NULL, pamh);
79 ASSERT_EQ(PAM_SERVICE_ERR, pam_authenticate(pamh, 0));
80 ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
81 pamh = NULL;
82
83 /* custom passwd file */
84 ASSERT_NE(NULL, fp = fopen(service_file, "w"));
85 ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
86 "auth required %s/.libs/%s.so file=%s\n",
87 cwd, MODULE_NAME, passwd_file));
88 ASSERT_EQ(0, fclose(fp));
89
90 memcpy(name + (sizeof(name) - sizeof(craig_prefix)),
91 craig_prefix, sizeof(craig_prefix));
92 ASSERT_NE(NULL, fp = fopen(passwd_file, "w"));
93 ASSERT_LT(0, fprintf(fp, "%s\n%s\n%s%s\n",
94 alice_line, bob_line, name, craig_suffix));
95 ASSERT_EQ(0, fclose(fp));
96
97 ASSERT_EQ(PAM_SUCCESS,
98 pam_start_confdir(service_file, "", &conv, ".", &pamh));
99 ASSERT_NE(NULL, pamh);
100 ASSERT_EQ(PAM_SERVICE_ERR, pam_authenticate(pamh, 0));
101 ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
102 pamh = NULL;
103
104 memset(name, 'x', sizeof(name) - 1);
105 ASSERT_EQ(PAM_SUCCESS,
106 pam_start_confdir(service_file, name, &conv, ".", &pamh));
107 ASSERT_NE(NULL, pamh);
108 ASSERT_EQ(PAM_SERVICE_ERR, pam_authenticate(pamh, 0));
109 ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
110 pamh = NULL;
111
112 ASSERT_EQ(PAM_SUCCESS,
113 pam_start_confdir(service_file, "alice", &conv, ".", &pamh));
114 ASSERT_NE(NULL, pamh);
115 ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
116 ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
117 pamh = NULL;
118
119 ASSERT_EQ(PAM_SUCCESS,
120 pam_start_confdir(service_file, "bob", &conv, ".", &pamh));
121 ASSERT_NE(NULL, pamh);
122 ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
123 ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
124 pamh = NULL;
125
126 ASSERT_EQ(PAM_SUCCESS,
127 pam_start_confdir(service_file, "alice:x", &conv, ".", &pamh));
128 ASSERT_NE(NULL, pamh);
129 ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0));
130 ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
131 pamh = NULL;
132
133 ASSERT_EQ(PAM_SUCCESS,
134 pam_start_confdir(service_file, "craig", &conv, ".", &pamh));
135 ASSERT_NE(NULL, pamh);
136 ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0));
137 ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
138 pamh = NULL;
139
140 ASSERT_EQ(0, unlink(service_file));
141 ASSERT_EQ(0, unlink(passwd_file));
142
143 return 0;
144 }