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 <string.h>
23
24 #ifdef HAVE_SECURITY_PAM_APPL_H
25 #include <security/pam_appl.h>
26 #endif
27 #ifdef HAVE_SECURITY_PAM_MODULES_H
28 #include <security/pam_modules.h>
29 #endif
30
31 #include "pwrap_compat.h"
32
str_opt(const int opt)33 static const char *str_opt(const int opt)
34 {
35 switch (opt) {
36 case PAM_SERVICE:
37 return "PAM_SERVICE";
38 case PAM_USER:
39 return "PAM_USER";
40 case PAM_USER_PROMPT:
41 return "PAM_USER_PROMPT";
42 case PAM_TTY:
43 return "PAM_TTY";
44 case PAM_RUSER:
45 return "PAM_RUSER";
46 case PAM_RHOST:
47 return "PAM_RHOST";
48 case PAM_AUTHTOK:
49 return "PAM_AUTHTOK";
50 case PAM_OLDAUTHTOK:
51 return "PAM_OLDAUTHTOK";
52 #ifdef PAM_XDISPLAY
53 case PAM_XDISPLAY:
54 return "PAM_XDISPLAY";
55 #endif
56 #ifdef PAM_AUTHTOK_TYPE
57 case PAM_AUTHTOK_TYPE:
58 return "PAM_AUTHTOK_TYPE";
59 #endif
60 }
61
62 return NULL; /* Unsupported */
63 }
64
putenv_item(pam_handle_t * pamh,int item_type)65 static int putenv_item(pam_handle_t *pamh,
66 int item_type)
67 {
68 const char *opt_name;
69 const char *value = NULL;
70 char *env_name;
71 size_t env_len;
72 int rv;
73
74 rv = pam_get_item(pamh, item_type, (const void **) &value);
75 if (rv != PAM_SUCCESS) {
76 return rv;
77 }
78
79 if (value == NULL) {
80 return PAM_SUCCESS;
81 }
82
83 opt_name = str_opt(item_type);
84 if (opt_name == NULL) {
85 /* Probably some non-printable value */
86 return PAM_BAD_ITEM;
87 }
88
89 env_len = strlen(value) + strlen(opt_name) + 2;
90 env_name = malloc(env_len);
91 if (env_name == NULL) {
92 return PAM_BUF_ERR;
93 }
94
95 rv = snprintf(env_name, env_len, "%s=%s", opt_name, value);
96 if (rv < 0) {
97 free(env_name);
98 return PAM_BUF_ERR;
99 }
100
101 rv = pam_putenv(pamh, env_name);
102 free(env_name);
103
104 return rv;
105 }
106
107 /* Get all pam_items and put them into environment */
pam_putitem(pam_handle_t * pamh)108 static int pam_putitem(pam_handle_t *pamh)
109 {
110
111 putenv_item(pamh, PAM_SERVICE);
112 putenv_item(pamh, PAM_USER);
113 putenv_item(pamh, PAM_USER_PROMPT);
114 putenv_item(pamh, PAM_TTY);
115 putenv_item(pamh, PAM_RUSER);
116 putenv_item(pamh, PAM_RHOST);
117 putenv_item(pamh, PAM_AUTHTOK);
118 putenv_item(pamh, PAM_OLDAUTHTOK);
119 #ifdef PAM_XDISPLAY
120 putenv_item(pamh, PAM_XDISPLAY);
121 #endif
122 #ifdef PAM_AUTHTOK_TYPE
123 putenv_item(pamh, PAM_AUTHTOK_TYPE);
124 #endif
125
126 return PAM_SUCCESS;
127 }
128
129 PAM_EXTERN int
pam_sm_authenticate(pam_handle_t * pamh,int flags,int argc,const char * argv[])130 pam_sm_authenticate(pam_handle_t *pamh, int flags,
131 int argc, const char *argv[])
132 {
133 (void) flags; /* unused */
134 (void) argc; /* unused */
135 (void) argv; /* unused */
136
137 return pam_putitem(pamh);
138 }
139
140 PAM_EXTERN int
pam_sm_setcred(pam_handle_t * pamh,int flags,int argc,const char * argv[])141 pam_sm_setcred(pam_handle_t *pamh, int flags,
142 int argc, const char *argv[])
143 {
144 (void) flags; /* unused */
145 (void) argc; /* unused */
146 (void) argv; /* unused */
147
148 return pam_putitem(pamh);
149 }
150
151 PAM_EXTERN int
pam_sm_acct_mgmt(pam_handle_t * pamh,int flags,int argc,const char * argv[])152 pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
153 int argc, const char *argv[])
154 {
155 (void) flags; /* unused */
156 (void) argc; /* unused */
157 (void) argv; /* unused */
158
159 return pam_putitem(pamh);
160 }
161
162 PAM_EXTERN int
pam_sm_open_session(pam_handle_t * pamh,int flags,int argc,const char * argv[])163 pam_sm_open_session(pam_handle_t *pamh, int flags,
164 int argc, const char *argv[])
165 {
166 (void) flags; /* unused */
167 (void) argc; /* unused */
168 (void) argv; /* unused */
169
170 return pam_putitem(pamh);
171 }
172
173 PAM_EXTERN int
pam_sm_close_session(pam_handle_t * pamh,int flags,int argc,const char * argv[])174 pam_sm_close_session(pam_handle_t *pamh, int flags,
175 int argc, const char *argv[])
176 {
177 (void) flags; /* unused */
178 (void) argc; /* unused */
179 (void) argv; /* unused */
180
181 return pam_putitem(pamh);
182 }
183
184 PAM_EXTERN int
pam_sm_chauthtok(pam_handle_t * pamh,int flags,int argc,const char * argv[])185 pam_sm_chauthtok(pam_handle_t *pamh, int flags,
186 int argc, const char *argv[])
187 {
188 (void) flags; /* unused */
189 (void) argc; /* unused */
190 (void) argv; /* unused */
191
192 return pam_putitem(pamh);
193 }
194