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