Line data Source code
1 : /*
2 : * Copyright (c) 2015 Andreas Schneider <asn@samba.org>
3 : * Copyright (c) 2015 Jakub Hrozek <jakub.hrozek@posteo.se>
4 : *
5 : * This program is free software: you can redistribute it and/or modify
6 : * it under the terms of the GNU General Public License as published by
7 : * the Free Software Foundation, either version 3 of the License, or
8 : * (at your option) any later version.
9 : *
10 : * This program is distributed in the hope that it will be useful,
11 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : * GNU General Public License for more details.
14 : *
15 : * You should have received a copy of the GNU General Public License
16 : * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 : */
18 : #include "config.h"
19 :
20 : #include <stdlib.h>
21 : #include <stdio.h>
22 : #include <stdarg.h>
23 : #include <string.h>
24 : #include <unistd.h>
25 :
26 : #ifdef HAVE_SECURITY_PAM_APPL_H
27 : #include <security/pam_appl.h>
28 : #endif
29 : #ifdef HAVE_SECURITY_PAM_MODULES_H
30 : #include <security/pam_modules.h>
31 : #endif
32 :
33 : #include "config.h"
34 :
35 : /* GCC have printf type attribute check. */
36 : #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT
37 : #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
38 : #else
39 : #define PRINTF_ATTRIBUTE(a,b)
40 : #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
41 :
42 : /*****************
43 : * LOGGING
44 : *****************/
45 :
46 : enum pwrap_dbglvl_e {
47 : PWRAP_LOG_ERROR = 0,
48 : PWRAP_LOG_WARN,
49 : PWRAP_LOG_DEBUG,
50 : PWRAP_LOG_TRACE
51 : };
52 :
53 : static void pwrap_log(enum pwrap_dbglvl_e dbglvl,
54 : const char *function,
55 : const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
56 : # define PWRAP_LOG(dbglvl, ...) pwrap_log((dbglvl), __func__, __VA_ARGS__)
57 :
58 : static void pwrap_vlog(enum pwrap_dbglvl_e dbglvl,
59 : const char *function,
60 : const char *format,
61 : va_list args) PRINTF_ATTRIBUTE(3, 0);
62 :
63 40 : static void pwrap_vlog(enum pwrap_dbglvl_e dbglvl,
64 : const char *function,
65 : const char *format,
66 : va_list args)
67 : {
68 : char buffer[1024];
69 : const char *d;
70 40 : unsigned int lvl = 0;
71 40 : const char *prefix = "PWRAP";
72 :
73 40 : d = getenv("PAM_WRAPPER_DEBUGLEVEL");
74 40 : if (d != NULL) {
75 40 : lvl = atoi(d);
76 : }
77 :
78 40 : if (lvl < dbglvl) {
79 40 : return;
80 : }
81 :
82 0 : vsnprintf(buffer, sizeof(buffer), format, args);
83 :
84 0 : switch (dbglvl) {
85 0 : case PWRAP_LOG_ERROR:
86 0 : prefix = "PWRAP_ERROR";
87 0 : break;
88 0 : case PWRAP_LOG_WARN:
89 0 : prefix = "PWRAP_WARN";
90 0 : break;
91 0 : case PWRAP_LOG_DEBUG:
92 0 : prefix = "PWRAP_DEBUG";
93 0 : break;
94 0 : case PWRAP_LOG_TRACE:
95 0 : prefix = "PWRAP_TRACE";
96 0 : break;
97 : }
98 :
99 0 : fprintf(stderr,
100 : "%s(%d) - PAM_SET_ITEM %s: %s\n",
101 : prefix,
102 0 : (int)getpid(),
103 : function,
104 : buffer);
105 : }
106 :
107 40 : static void pwrap_log(enum pwrap_dbglvl_e dbglvl,
108 : const char *function,
109 : const char *format, ...)
110 : {
111 : va_list va;
112 :
113 40 : va_start(va, format);
114 40 : pwrap_vlog(dbglvl, function, format, va);
115 40 : va_end(va);
116 40 : }
117 :
118 : #define ITEM_FILE_KEY "item_file="
119 :
120 : static const char *envs[] = {
121 : #ifndef HAVE_OPENPAM
122 : "PAM_SERVICE",
123 : #endif
124 : "PAM_USER",
125 : "PAM_USER_PROMPT",
126 : "PAM_TTY",
127 : "PAM_RUSER",
128 : "PAM_RHOST",
129 : "PAM_AUTHTOK",
130 : "PAM_OLDAUTHTOK",
131 : #ifdef PAM_XDISPLAY
132 : "PAM_XDISPLAY",
133 : #endif
134 : #ifdef PAM_AUTHTOK_TYPE
135 : "PAM_AUTHTOK_TYPE",
136 : #endif
137 : NULL
138 : };
139 :
140 : static const int items[] = {
141 : #ifndef HAVE_OPENPAM
142 : PAM_SERVICE,
143 : #endif
144 : PAM_USER,
145 : PAM_USER_PROMPT,
146 : PAM_TTY,
147 : PAM_RUSER,
148 : PAM_RHOST,
149 : PAM_AUTHTOK,
150 : PAM_OLDAUTHTOK,
151 : #ifdef PAM_XDISPLAY
152 : PAM_XDISPLAY,
153 : #endif
154 : #ifdef PAM_AUTHTOK_TYPE
155 : PAM_AUTHTOK_TYPE,
156 : #endif
157 : };
158 :
159 24 : static void pam_setitem_env(pam_handle_t *pamh)
160 : {
161 : int i;
162 : int rv;
163 : const char *v;
164 :
165 264 : for (i = 0; envs[i] != NULL; i++) {
166 240 : v = getenv(envs[i]);
167 240 : if (v == NULL) {
168 224 : continue;
169 : }
170 :
171 16 : PWRAP_LOG(PWRAP_LOG_TRACE, "%s=%s", envs[i], v);
172 :
173 16 : rv = pam_set_item(pamh, items[i], v);
174 16 : if (rv != PAM_SUCCESS) {
175 0 : continue;
176 : }
177 : }
178 24 : }
179 :
180 : PAM_EXTERN int
181 : pam_sm_authenticate(pam_handle_t *pamh, int flags,
182 : int argc, const char *argv[])
183 : {
184 : (void) flags; /* unused */
185 : (void) argc; /* unused */
186 : (void) argv; /* unused */
187 :
188 0 : PWRAP_LOG(PWRAP_LOG_TRACE, "AUTHENTICATE");
189 :
190 0 : pam_setitem_env(pamh);
191 0 : return PAM_SUCCESS;
192 : }
193 :
194 : PAM_EXTERN int
195 : pam_sm_setcred(pam_handle_t *pamh, int flags,
196 : int argc, const char *argv[])
197 : {
198 : (void) flags; /* unused */
199 : (void) argc; /* unused */
200 : (void) argv; /* unused */
201 :
202 0 : PWRAP_LOG(PWRAP_LOG_TRACE, "SETCRED");
203 :
204 0 : pam_setitem_env(pamh);
205 0 : return PAM_SUCCESS;
206 : }
207 :
208 : PAM_EXTERN int
209 : pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
210 : int argc, const char *argv[])
211 : {
212 : (void) flags; /* unused */
213 : (void) argc; /* unused */
214 : (void) argv; /* unused */
215 :
216 0 : PWRAP_LOG(PWRAP_LOG_TRACE, "ACCT_MGMT");
217 :
218 0 : pam_setitem_env(pamh);
219 0 : return PAM_SUCCESS;
220 : }
221 :
222 : PAM_EXTERN int
223 : pam_sm_open_session(pam_handle_t *pamh, int flags,
224 : int argc, const char *argv[])
225 : {
226 : (void) flags; /* unused */
227 : (void) argc; /* unused */
228 : (void) argv; /* unused */
229 :
230 0 : PWRAP_LOG(PWRAP_LOG_TRACE, "OPEN_SESSION");
231 :
232 0 : pam_setitem_env(pamh);
233 0 : return PAM_SUCCESS;
234 : }
235 :
236 : PAM_EXTERN int
237 : pam_sm_close_session(pam_handle_t *pamh, int flags,
238 : int argc, const char *argv[])
239 : {
240 : (void) flags; /* unused */
241 : (void) argc; /* unused */
242 : (void) argv; /* unused */
243 :
244 0 : PWRAP_LOG(PWRAP_LOG_TRACE, "CLOSE_SESSION");
245 :
246 0 : pam_setitem_env(pamh);
247 0 : return PAM_SUCCESS;
248 : }
249 :
250 : PAM_EXTERN int
251 : pam_sm_chauthtok(pam_handle_t *pamh, int flags,
252 : int argc, const char *argv[])
253 : {
254 : (void) flags; /* unused */
255 : (void) argc; /* unused */
256 : (void) argv; /* unused */
257 :
258 24 : PWRAP_LOG(PWRAP_LOG_TRACE, "CHAUTHTOK");
259 :
260 24 : pam_setitem_env(pamh);
261 24 : return PAM_SUCCESS;
262 : }
|