diff options
author | Damien Miller <djm@mindrot.org> | 1999-12-30 15:08:44 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 1999-12-30 15:08:44 +1100 |
commit | e72b7af17e519eb1d433b5119ef551f2584f8be6 (patch) | |
tree | 7ebbc8fefdfcfd9669dbe05718b142996df69a85 /sshd.c | |
parent | ece22a8312357e1f34916659d77fa7dd8d15ae32 (diff) |
- Removed most of the pam code into its own file auth-pam.[ch]. This
cleaned up sshd.c up significantly.
- Several other cleanups
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 321 |
1 files changed, 59 insertions, 262 deletions
@@ -11,15 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "includes.h" | 13 | #include "includes.h" |
14 | RCSID("$Id: sshd.c,v 1.48 1999/12/28 23:25:41 damien Exp $"); | 14 | RCSID("$Id: sshd.c,v 1.49 1999/12/30 04:08:44 damien Exp $"); |
15 | |||
16 | #ifdef HAVE_POLL_H | ||
17 | # include <poll.h> | ||
18 | #else /* HAVE_POLL_H */ | ||
19 | # ifdef HAVE_SYS_POLL_H | ||
20 | # include <sys/poll.h> | ||
21 | # endif /* HAVE_SYS_POLL_H */ | ||
22 | #endif /* HAVE_POLL_H */ | ||
23 | 15 | ||
24 | #include "xmalloc.h" | 16 | #include "xmalloc.h" |
25 | #include "rsa.h" | 17 | #include "rsa.h" |
@@ -143,183 +135,6 @@ void do_child(const char *command, struct passwd * pw, const char *term, | |||
143 | const char *display, const char *auth_proto, | 135 | const char *display, const char *auth_proto, |
144 | const char *auth_data, const char *ttyname); | 136 | const char *auth_data, const char *ttyname); |
145 | 137 | ||
146 | #ifdef USE_PAM | ||
147 | static int pamconv(int num_msg, const struct pam_message **msg, | ||
148 | struct pam_response **resp, void *appdata_ptr); | ||
149 | int do_pam_auth(const char *user, const char *password); | ||
150 | void do_pam_account(char *username, char *remote_user); | ||
151 | void do_pam_session(char *username, char *ttyname); | ||
152 | void do_pam_setcred(); | ||
153 | void pam_cleanup_proc(void *context); | ||
154 | |||
155 | static struct pam_conv conv = { | ||
156 | pamconv, | ||
157 | NULL | ||
158 | }; | ||
159 | struct pam_handle_t *pamh = NULL; | ||
160 | const char *pampasswd = NULL; | ||
161 | char *pamconv_msg = NULL; | ||
162 | |||
163 | static int pamconv(int num_msg, const struct pam_message **msg, | ||
164 | struct pam_response **resp, void *appdata_ptr) | ||
165 | { | ||
166 | struct pam_response *reply; | ||
167 | int count; | ||
168 | size_t msg_len; | ||
169 | char *p; | ||
170 | |||
171 | /* PAM will free this later */ | ||
172 | reply = malloc(num_msg * sizeof(*reply)); | ||
173 | if (reply == NULL) | ||
174 | return PAM_CONV_ERR; | ||
175 | |||
176 | for(count = 0; count < num_msg; count++) { | ||
177 | switch (msg[count]->msg_style) { | ||
178 | case PAM_PROMPT_ECHO_OFF: | ||
179 | if (pampasswd == NULL) { | ||
180 | free(reply); | ||
181 | return PAM_CONV_ERR; | ||
182 | } | ||
183 | reply[count].resp_retcode = PAM_SUCCESS; | ||
184 | reply[count].resp = xstrdup(pampasswd); | ||
185 | break; | ||
186 | |||
187 | case PAM_TEXT_INFO: | ||
188 | reply[count].resp_retcode = PAM_SUCCESS; | ||
189 | reply[count].resp = xstrdup(""); | ||
190 | |||
191 | if (msg[count]->msg == NULL) | ||
192 | break; | ||
193 | |||
194 | debug("Adding PAM message: %s", msg[count]->msg); | ||
195 | |||
196 | msg_len = strlen(msg[count]->msg); | ||
197 | if (pamconv_msg) { | ||
198 | size_t n = strlen(pamconv_msg); | ||
199 | pamconv_msg = xrealloc(pamconv_msg, n + msg_len + 2); | ||
200 | p = pamconv_msg + n; | ||
201 | } else { | ||
202 | pamconv_msg = p = xmalloc(msg_len + 2); | ||
203 | } | ||
204 | memcpy(p, msg[count]->msg, msg_len); | ||
205 | p[msg_len] = '\n'; | ||
206 | p[msg_len + 1] = '\0'; | ||
207 | break; | ||
208 | |||
209 | case PAM_PROMPT_ECHO_ON: | ||
210 | case PAM_ERROR_MSG: | ||
211 | default: | ||
212 | free(reply); | ||
213 | return PAM_CONV_ERR; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | *resp = reply; | ||
218 | |||
219 | return PAM_SUCCESS; | ||
220 | } | ||
221 | |||
222 | void pam_cleanup_proc(void *context) | ||
223 | { | ||
224 | int pam_retval; | ||
225 | |||
226 | if (pamh != NULL) | ||
227 | { | ||
228 | pam_retval = pam_close_session((pam_handle_t *)pamh, 0); | ||
229 | if (pam_retval != PAM_SUCCESS) { | ||
230 | log("Cannot close PAM session: %.200s", | ||
231 | PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
232 | } | ||
233 | |||
234 | pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_DELETE_CRED); | ||
235 | if (pam_retval != PAM_SUCCESS) { | ||
236 | log("Cannot delete credentials: %.200s", | ||
237 | PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
238 | } | ||
239 | |||
240 | pam_retval = pam_end((pam_handle_t *)pamh, pam_retval); | ||
241 | if (pam_retval != PAM_SUCCESS) { | ||
242 | log("Cannot release PAM authentication: %.200s", | ||
243 | PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
244 | } | ||
245 | } | ||
246 | } | ||
247 | |||
248 | int do_pam_auth(const char *user, const char *password) | ||
249 | { | ||
250 | int pam_retval; | ||
251 | |||
252 | if ((options.permit_empty_passwd == 0) && (password[0] == '\0')) | ||
253 | return 0; | ||
254 | |||
255 | pampasswd = password; | ||
256 | |||
257 | pam_retval = pam_authenticate((pam_handle_t *)pamh, 0); | ||
258 | if (pam_retval == PAM_SUCCESS) { | ||
259 | debug("PAM Password authentication accepted for user \"%.100s\"", user); | ||
260 | return 1; | ||
261 | } else { | ||
262 | debug("PAM Password authentication for \"%.100s\" failed: %s", | ||
263 | user, PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
264 | return 0; | ||
265 | } | ||
266 | } | ||
267 | |||
268 | void do_pam_account(char *username, char *remote_user) | ||
269 | { | ||
270 | int pam_retval; | ||
271 | |||
272 | debug("PAM setting rhost to \"%.200s\"", get_canonical_hostname()); | ||
273 | pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RHOST, | ||
274 | get_canonical_hostname()); | ||
275 | if (pam_retval != PAM_SUCCESS) { | ||
276 | log("PAM set rhost failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
277 | do_fake_authloop(username); | ||
278 | } | ||
279 | |||
280 | if (remote_user != NULL) { | ||
281 | debug("PAM setting ruser to \"%.200s\"", remote_user); | ||
282 | pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user); | ||
283 | if (pam_retval != PAM_SUCCESS) { | ||
284 | log("PAM set ruser failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
285 | do_fake_authloop(username); | ||
286 | } | ||
287 | } | ||
288 | |||
289 | pam_retval = pam_acct_mgmt((pam_handle_t *)pamh, 0); | ||
290 | if (pam_retval != PAM_SUCCESS) { | ||
291 | log("PAM rejected by account configuration: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
292 | do_fake_authloop(username); | ||
293 | } | ||
294 | } | ||
295 | |||
296 | void do_pam_session(char *username, char *ttyname) | ||
297 | { | ||
298 | int pam_retval; | ||
299 | |||
300 | if (ttyname != NULL) { | ||
301 | debug("PAM setting tty to \"%.200s\"", ttyname); | ||
302 | pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_TTY, ttyname); | ||
303 | if (pam_retval != PAM_SUCCESS) | ||
304 | fatal("PAM set tty failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
305 | } | ||
306 | |||
307 | pam_retval = pam_open_session((pam_handle_t *)pamh, 0); | ||
308 | if (pam_retval != PAM_SUCCESS) | ||
309 | fatal("PAM session setup failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
310 | } | ||
311 | |||
312 | void do_pam_setcred() | ||
313 | { | ||
314 | int pam_retval; | ||
315 | |||
316 | debug("PAM establishing creds"); | ||
317 | pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_ESTABLISH_CRED); | ||
318 | if (pam_retval != PAM_SUCCESS) | ||
319 | fatal("PAM setcred failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
320 | } | ||
321 | #endif /* USE_PAM */ | ||
322 | |||
323 | /* | 138 | /* |
324 | * Signal handler for SIGHUP. Sshd execs itself when it receives SIGHUP; | 139 | * Signal handler for SIGHUP. Sshd execs itself when it receives SIGHUP; |
325 | * the effect is to reread the configuration file (and to regenerate | 140 | * the effect is to reread the configuration file (and to regenerate |
@@ -973,20 +788,7 @@ main(int ac, char **av) | |||
973 | verbose("Closing connection to %.100s", remote_ip); | 788 | verbose("Closing connection to %.100s", remote_ip); |
974 | 789 | ||
975 | #ifdef USE_PAM | 790 | #ifdef USE_PAM |
976 | { | 791 | finish_pam(); |
977 | int retval; | ||
978 | |||
979 | if (pamh != NULL) { | ||
980 | debug("Closing PAM session."); | ||
981 | retval = pam_close_session((pam_handle_t *)pamh, 0); | ||
982 | |||
983 | debug("Terminating PAM library."); | ||
984 | if (pam_end((pam_handle_t *)pamh, retval) != PAM_SUCCESS) | ||
985 | log("Cannot release PAM authentication."); | ||
986 | |||
987 | fatal_remove_cleanup(&pam_cleanup_proc, NULL); | ||
988 | } | ||
989 | } | ||
990 | #endif /* USE_PAM */ | 792 | #endif /* USE_PAM */ |
991 | 793 | ||
992 | packet_close(); | 794 | packet_close(); |
@@ -1306,17 +1108,7 @@ do_authentication(char *user) | |||
1306 | pw = &pwcopy; | 1108 | pw = &pwcopy; |
1307 | 1109 | ||
1308 | #ifdef USE_PAM | 1110 | #ifdef USE_PAM |
1309 | { | 1111 | start_pam(pw); |
1310 | int pam_retval; | ||
1311 | |||
1312 | debug("Starting up PAM with username \"%.200s\"", pw->pw_name); | ||
1313 | |||
1314 | pam_retval = pam_start("sshd", pw->pw_name, &conv, (pam_handle_t**)&pamh); | ||
1315 | if (pam_retval != PAM_SUCCESS) | ||
1316 | fatal("PAM initialisation failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
1317 | |||
1318 | fatal_add_cleanup(&pam_cleanup_proc, NULL); | ||
1319 | } | ||
1320 | #endif | 1112 | #endif |
1321 | 1113 | ||
1322 | /* | 1114 | /* |
@@ -1334,7 +1126,7 @@ do_authentication(char *user) | |||
1334 | (!options.kerberos_authentication || options.kerberos_or_local_passwd) && | 1126 | (!options.kerberos_authentication || options.kerberos_or_local_passwd) && |
1335 | #endif /* KRB4 */ | 1127 | #endif /* KRB4 */ |
1336 | #ifdef USE_PAM | 1128 | #ifdef USE_PAM |
1337 | do_pam_auth(pw->pw_name, "")) { | 1129 | auth_pam_password(pw, "")) { |
1338 | #else /* USE_PAM */ | 1130 | #else /* USE_PAM */ |
1339 | auth_password(pw, "")) { | 1131 | auth_password(pw, "")) { |
1340 | #endif /* USE_PAM */ | 1132 | #endif /* USE_PAM */ |
@@ -1477,9 +1269,6 @@ do_authloop(struct passwd * pw) | |||
1477 | authenticated = auth_rhosts(pw, client_user); | 1269 | authenticated = auth_rhosts(pw, client_user); |
1478 | 1270 | ||
1479 | snprintf(user, sizeof user, " ruser %s", client_user); | 1271 | snprintf(user, sizeof user, " ruser %s", client_user); |
1480 | #ifndef USE_PAM | ||
1481 | xfree(client_user); | ||
1482 | #endif /* USE_PAM */ | ||
1483 | break; | 1272 | break; |
1484 | 1273 | ||
1485 | case SSH_CMSG_AUTH_RHOSTS_RSA: | 1274 | case SSH_CMSG_AUTH_RHOSTS_RSA: |
@@ -1512,9 +1301,6 @@ do_authloop(struct passwd * pw) | |||
1512 | BN_clear_free(client_host_key_n); | 1301 | BN_clear_free(client_host_key_n); |
1513 | 1302 | ||
1514 | snprintf(user, sizeof user, " ruser %s", client_user); | 1303 | snprintf(user, sizeof user, " ruser %s", client_user); |
1515 | #ifndef USE_PAM | ||
1516 | xfree(client_user); | ||
1517 | #endif /* USE_PAM */ | ||
1518 | break; | 1304 | break; |
1519 | 1305 | ||
1520 | case SSH_CMSG_AUTH_RSA: | 1306 | case SSH_CMSG_AUTH_RSA: |
@@ -1545,7 +1331,7 @@ do_authloop(struct passwd * pw) | |||
1545 | 1331 | ||
1546 | #ifdef USE_PAM | 1332 | #ifdef USE_PAM |
1547 | /* Do PAM auth with password */ | 1333 | /* Do PAM auth with password */ |
1548 | authenticated = do_pam_auth(pw->pw_name, password); | 1334 | authenticated = auth_pam_password(pw, password); |
1549 | #else /* USE_PAM */ | 1335 | #else /* USE_PAM */ |
1550 | /* Try authentication with the password. */ | 1336 | /* Try authentication with the password. */ |
1551 | authenticated = auth_password(pw, password); | 1337 | authenticated = auth_password(pw, password); |
@@ -1615,29 +1401,24 @@ do_authloop(struct passwd * pw) | |||
1615 | get_remote_port(), | 1401 | get_remote_port(), |
1616 | user); | 1402 | user); |
1617 | 1403 | ||
1618 | #ifndef USE_PAM | ||
1619 | if (authenticated) | ||
1620 | return; | ||
1621 | |||
1622 | if (attempt > AUTH_FAIL_MAX) | ||
1623 | packet_disconnect(AUTH_FAIL_MSG, pw->pw_name); | ||
1624 | #else /* USE_PAM */ | ||
1625 | if (authenticated) { | 1404 | if (authenticated) { |
1626 | do_pam_account(pw->pw_name, client_user); | 1405 | #ifdef USE_PAM |
1627 | 1406 | if (!do_pam_account(pw->pw_name, client_user)) | |
1628 | if (client_user != NULL) | 1407 | { |
1629 | xfree(client_user); | 1408 | if (client_user != NULL) |
1409 | xfree(client_user); | ||
1630 | 1410 | ||
1411 | do_fake_authloop(pw->pw_name); | ||
1412 | } | ||
1413 | #endif /* USE_PAM */ | ||
1631 | return; | 1414 | return; |
1632 | } | 1415 | } |
1633 | 1416 | ||
1634 | if (attempt > AUTH_FAIL_MAX) { | 1417 | if (client_user != NULL) |
1635 | if (client_user != NULL) | 1418 | xfree(client_user); |
1636 | xfree(client_user); | ||
1637 | 1419 | ||
1420 | if (attempt > AUTH_FAIL_MAX) | ||
1638 | packet_disconnect(AUTH_FAIL_MSG, pw->pw_name); | 1421 | packet_disconnect(AUTH_FAIL_MSG, pw->pw_name); |
1639 | } | ||
1640 | #endif /* USE_PAM */ | ||
1641 | 1422 | ||
1642 | /* Send a message indicating that the authentication attempt failed. */ | 1423 | /* Send a message indicating that the authentication attempt failed. */ |
1643 | packet_start(SSH_SMSG_FAILURE); | 1424 | packet_start(SSH_SMSG_FAILURE); |
@@ -1672,8 +1453,10 @@ do_fake_authloop(char *user) | |||
1672 | for (attempt = 1;; attempt++) { | 1453 | for (attempt = 1;; attempt++) { |
1673 | /* Read a packet. This will not return if the client disconnects. */ | 1454 | /* Read a packet. This will not return if the client disconnects. */ |
1674 | int plen; | 1455 | int plen; |
1456 | #ifndef SKEY | ||
1457 | (void)packet_read(&plen); | ||
1458 | #else /* SKEY */ | ||
1675 | int type = packet_read(&plen); | 1459 | int type = packet_read(&plen); |
1676 | #ifdef SKEY | ||
1677 | int dlen; | 1460 | int dlen; |
1678 | char *password, *skeyinfo; | 1461 | char *password, *skeyinfo; |
1679 | /* Try to send a fake s/key challenge. */ | 1462 | /* Try to send a fake s/key challenge. */ |
@@ -1845,7 +1628,7 @@ do_authenticated(struct passwd * pw) | |||
1845 | 1628 | ||
1846 | #ifdef USE_PAM | 1629 | #ifdef USE_PAM |
1847 | /* do the pam_open_session since we have the pty */ | 1630 | /* do the pam_open_session since we have the pty */ |
1848 | do_pam_session(pw->pw_name,ttyname); | 1631 | do_pam_session(pw->pw_name, ttyname); |
1849 | #endif /* USE_PAM */ | 1632 | #endif /* USE_PAM */ |
1850 | 1633 | ||
1851 | break; | 1634 | break; |
@@ -1925,7 +1708,7 @@ do_authenticated(struct passwd * pw) | |||
1925 | 1708 | ||
1926 | #ifdef USE_PAM | 1709 | #ifdef USE_PAM |
1927 | do_pam_setcred(); | 1710 | do_pam_setcred(); |
1928 | #endif | 1711 | #endif /* USE_PAM */ |
1929 | if (forced_command != NULL) | 1712 | if (forced_command != NULL) |
1930 | goto do_forced_command; | 1713 | goto do_forced_command; |
1931 | debug("Forking shell."); | 1714 | debug("Forking shell."); |
@@ -1943,7 +1726,7 @@ do_authenticated(struct passwd * pw) | |||
1943 | 1726 | ||
1944 | #ifdef USE_PAM | 1727 | #ifdef USE_PAM |
1945 | do_pam_setcred(); | 1728 | do_pam_setcred(); |
1946 | #endif | 1729 | #endif /* USE_PAM */ |
1947 | if (forced_command != NULL) | 1730 | if (forced_command != NULL) |
1948 | goto do_forced_command; | 1731 | goto do_forced_command; |
1949 | /* Get command from the packet. */ | 1732 | /* Get command from the packet. */ |
@@ -2221,10 +2004,9 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, | |||
2221 | quiet_login = stat(line, &st) >= 0; | 2004 | quiet_login = stat(line, &st) >= 0; |
2222 | 2005 | ||
2223 | #ifdef USE_PAM | 2006 | #ifdef USE_PAM |
2224 | /* output the results of the pamconv() */ | 2007 | if (!quiet_login) |
2225 | if (!quiet_login && pamconv_msg != NULL) | 2008 | print_pam_messages(); |
2226 | fprintf(stderr, pamconv_msg); | 2009 | #endif /* USE_PAM */ |
2227 | #endif | ||
2228 | 2010 | ||
2229 | /* | 2011 | /* |
2230 | * If the user has logged in before, display the time of last | 2012 | * If the user has logged in before, display the time of last |
@@ -2389,6 +2171,39 @@ read_environment_file(char ***env, unsigned int *envsize, | |||
2389 | fclose(f); | 2171 | fclose(f); |
2390 | } | 2172 | } |
2391 | 2173 | ||
2174 | #ifdef USE_PAM | ||
2175 | /* | ||
2176 | * Sets any environment variables which have been specified by PAM | ||
2177 | */ | ||
2178 | void do_pam_environment(char ***env, int *envsize) | ||
2179 | { | ||
2180 | char *equals, var_name[512], var_val[512]; | ||
2181 | char **pam_env; | ||
2182 | int i; | ||
2183 | |||
2184 | if ((pam_env = fetch_pam_environment()) == NULL) | ||
2185 | return; | ||
2186 | |||
2187 | for(i = 0; pam_env[i] != NULL; i++) { | ||
2188 | if ((equals = strstr(pam_env[i], "=")) == NULL) | ||
2189 | continue; | ||
2190 | |||
2191 | if (strlen(pam_env[i]) < (sizeof(var_name) - 1)) | ||
2192 | { | ||
2193 | memset(var_name, '\0', sizeof(var_name)); | ||
2194 | memset(var_val, '\0', sizeof(var_val)); | ||
2195 | |||
2196 | strncpy(var_name, pam_env[i], equals - pam_env[i]); | ||
2197 | strcpy(var_val, equals + 1); | ||
2198 | |||
2199 | debug("PAM environment: %s=%s", var_name, var_val); | ||
2200 | |||
2201 | child_set_env(env, envsize, var_name, var_val); | ||
2202 | } | ||
2203 | } | ||
2204 | } | ||
2205 | #endif /* USE_PAM */ | ||
2206 | |||
2392 | /* | 2207 | /* |
2393 | * Performs common processing for the child, such as setting up the | 2208 | * Performs common processing for the child, such as setting up the |
2394 | * environment, closing extra file descriptors, setting the user and group | 2209 | * environment, closing extra file descriptors, setting the user and group |
@@ -2421,11 +2236,9 @@ do_child(const char *command, struct passwd * pw, const char *term, | |||
2421 | } | 2236 | } |
2422 | #endif /* USE_PAM */ | 2237 | #endif /* USE_PAM */ |
2423 | 2238 | ||
2424 | #ifdef HAVE_SETLOGIN | ||
2425 | /* Set login name in the kernel. */ | 2239 | /* Set login name in the kernel. */ |
2426 | if (setlogin(pw->pw_name) < 0) | 2240 | if (setlogin(pw->pw_name) < 0) |
2427 | error("setlogin failed: %s", strerror(errno)); | 2241 | error("setlogin failed: %s", strerror(errno)); |
2428 | #endif /* HAVE_SETLOGIN */ | ||
2429 | 2242 | ||
2430 | /* Set uid, gid, and groups. */ | 2243 | /* Set uid, gid, and groups. */ |
2431 | /* Login(1) does this as well, and it needs uid 0 for the "-h" | 2244 | /* Login(1) does this as well, and it needs uid 0 for the "-h" |
@@ -2526,23 +2339,7 @@ do_child(const char *command, struct passwd * pw, const char *term, | |||
2526 | 2339 | ||
2527 | #ifdef USE_PAM | 2340 | #ifdef USE_PAM |
2528 | /* Pull in any environment variables that may have been set by PAM. */ | 2341 | /* Pull in any environment variables that may have been set by PAM. */ |
2529 | { | 2342 | do_pam_environment(&env, &envsize); |
2530 | char *equals, var_name[512], var_val[512]; | ||
2531 | char **pam_env = pam_getenvlist((pam_handle_t *)pamh); | ||
2532 | int i; | ||
2533 | for(i = 0; pam_env && pam_env[i]; i++) { | ||
2534 | equals = strstr(pam_env[i], "="); | ||
2535 | if ((strlen(pam_env[i]) < (sizeof(var_name) - 1)) && (equals != NULL)) | ||
2536 | { | ||
2537 | debug("PAM environment: %s=%s", var_name, var_val); | ||
2538 | memset(var_name, '\0', sizeof(var_name)); | ||
2539 | memset(var_val, '\0', sizeof(var_val)); | ||
2540 | strncpy(var_name, pam_env[i], equals - pam_env[i]); | ||
2541 | strcpy(var_val, equals + 1); | ||
2542 | child_set_env(&env, &envsize, var_name, var_val); | ||
2543 | } | ||
2544 | } | ||
2545 | } | ||
2546 | #endif /* USE_PAM */ | 2343 | #endif /* USE_PAM */ |
2547 | 2344 | ||
2548 | if (xauthfile) | 2345 | if (xauthfile) |