dd090209cdc2a2c793e159fe0173562bd0ec15f3
[bbaumbach/samba-autobuild/.git] / third_party / pam_wrapper / modules / pam_set_items.c
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 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         unsigned int lvl = 0;
71         const char *prefix = "PWRAP";
72
73         d = getenv("PAM_WRAPPER_DEBUGLEVEL");
74         if (d != NULL) {
75                 lvl = atoi(d);
76         }
77
78         if (lvl < dbglvl) {
79                 return;
80         }
81
82         vsnprintf(buffer, sizeof(buffer), format, args);
83
84         switch (dbglvl) {
85         case PWRAP_LOG_ERROR:
86                 prefix = "PWRAP_ERROR";
87                 break;
88         case PWRAP_LOG_WARN:
89                 prefix = "PWRAP_WARN";
90                 break;
91         case PWRAP_LOG_DEBUG:
92                 prefix = "PWRAP_DEBUG";
93                 break;
94         case PWRAP_LOG_TRACE:
95                 prefix = "PWRAP_TRACE";
96                 break;
97         }
98
99         fprintf(stderr,
100                 "%s(%d) - PAM_SET_ITEM %s: %s\n",
101                 prefix,
102                 (int)getpid(),
103                 function,
104                 buffer);
105 }
106
107 static void pwrap_log(enum pwrap_dbglvl_e dbglvl,
108                       const char *function,
109                       const char *format, ...)
110 {
111         va_list va;
112
113         va_start(va, format);
114         pwrap_vlog(dbglvl, function, format, va);
115         va_end(va);
116 }
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 static void pam_setitem_env(pam_handle_t *pamh)
160 {
161         int i;
162         int rv;
163         const char *v;
164
165         for (i = 0; envs[i] != NULL; i++) {
166                 v = getenv(envs[i]);
167                 if (v == NULL) {
168                         continue;
169                 }
170
171                 PWRAP_LOG(PWRAP_LOG_TRACE, "%s=%s", envs[i], v);
172
173                 rv = pam_set_item(pamh, items[i], v);
174                 if (rv != PAM_SUCCESS) {
175                         continue;
176                 }
177         }
178 }
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         PWRAP_LOG(PWRAP_LOG_TRACE, "AUTHENTICATE");
189
190         pam_setitem_env(pamh);
191         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         PWRAP_LOG(PWRAP_LOG_TRACE, "SETCRED");
203
204         pam_setitem_env(pamh);
205         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         PWRAP_LOG(PWRAP_LOG_TRACE, "ACCT_MGMT");
217
218         pam_setitem_env(pamh);
219         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         PWRAP_LOG(PWRAP_LOG_TRACE, "OPEN_SESSION");
231
232         pam_setitem_env(pamh);
233         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         PWRAP_LOG(PWRAP_LOG_TRACE, "CLOSE_SESSION");
245
246         pam_setitem_env(pamh);
247         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         PWRAP_LOG(PWRAP_LOG_TRACE, "CHAUTHTOK");
259
260         pam_setitem_env(pamh);
261         return PAM_SUCCESS;
262 }