Bugzilla – Attachment 198 Details for
Bug 423
Workaround for pw change in privsep mode (3.5.p1)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Add privsep'ed do_pam_chauthtok()
openssh-pamexpire_privsep2.patch (text/plain), 9.35 KB, created by
Darren Tucker
on 2003-01-08 22:17:59 AEDT
(
hide
)
Description:
Add privsep'ed do_pam_chauthtok()
Filename:
MIME Type:
Creator:
Darren Tucker
Created:
2003-01-08 22:17:59 AEDT
Size:
9.35 KB
patch
obsolete
>Index: auth-pam.c >=================================================================== >RCS file: /cvs/openssh/auth-pam.c,v >retrieving revision 1.54 >diff -u -r1.54 auth-pam.c >--- auth-pam.c 28 Jul 2002 20:24:08 -0000 1.54 >+++ auth-pam.c 4 Jan 2003 12:11:31 -0000 >@@ -33,17 +33,18 @@ > #include "servconf.h" > #include "canohost.h" > #include "readpass.h" >+#include "channels.h" >+#include "misc.h" > > extern char *__progname; > > extern int use_privsep; >+extern ServerOptions options; > > RCSID("$Id: auth-pam.c,v 1.54 2002/07/28 20:24:08 stevesk Exp $"); > > #define NEW_AUTHTOK_MSG \ > "Warning: Your password has expired, please change it now." >-#define NEW_AUTHTOK_MSG_PRIVSEP \ >- "Your password has expired, the session cannot proceed." > > static int do_pam_conversation(int num_msg, const struct pam_message **msg, > struct pam_response **resp, void *appdata_ptr); >@@ -204,7 +205,6 @@ > /* Attempt password authentation using PAM */ > int auth_pam_password(Authctxt *authctxt, const char *password) > { >- extern ServerOptions options; > int pam_retval; > struct passwd *pw = authctxt->pw; > >@@ -256,18 +256,17 @@ > case PAM_SUCCESS: > /* This is what we want */ > break; >-#if 0 > case PAM_NEW_AUTHTOK_REQD: >- message_cat(&__pam_msg, use_privsep ? >- NEW_AUTHTOK_MSG_PRIVSEP : NEW_AUTHTOK_MSG); >+ message_cat(&__pam_msg, NEW_AUTHTOK_MSG); > /* flag that password change is necessary */ > password_change_required = 1; > /* disallow other functionality for now */ > no_port_forwarding_flag |= 2; > no_agent_forwarding_flag |= 2; > no_x11_forwarding_flag |= 2; >+ /* set signal handler to restore flags */ >+ mysignal(SIGUSR1, password_change_successful_handler); > break; >-#endif > default: > log("PAM rejected by account configuration[%d]: " > "%.200s", pam_retval, PAM_STRERROR(__pamh, >@@ -344,26 +343,32 @@ > do_pam_set_conv(&conv); > > if (password_change_required) { >- if (use_privsep) >- fatal("Password changing is currently unsupported" >- " with privilege separation"); > pamstate = OTHER; > pam_retval = pam_chauthtok(__pamh, PAM_CHANGE_EXPIRED_AUTHTOK); > if (pam_retval != PAM_SUCCESS) > fatal("PAM pam_chauthtok failed[%d]: %.200s", > pam_retval, PAM_STRERROR(__pamh, pam_retval)); >-#if 0 >- /* XXX: This would need to be done in the parent process, >- * but there's currently no way to pass such request. */ >- no_port_forwarding_flag &= ~2; >- no_agent_forwarding_flag &= ~2; >- no_x11_forwarding_flag &= ~2; >- if (!no_port_forwarding_flag && options.allow_tcp_forwarding) >- channel_permit_all_opens(); >-#endif >+ password_change_required = 0; > } > } > >+/* >+ * Because do_pam_chauthtok is called after forking to exec the user's >+ * shell, restoring the port forwarding flags is done by sending a >+ * USR1 signal after the password is changed successfully. >+ */ >+void password_change_successful_handler(int sig) >+{ >+ debug("%s: restoring port forwarding flags", __func__); >+ mysignal(SIGUSR1, SIG_DFL); /* unset handler */ >+ password_change_required = 0; >+ no_port_forwarding_flag &= ~2; >+ no_agent_forwarding_flag &= ~2; >+ no_x11_forwarding_flag &= ~2; >+ if (!no_port_forwarding_flag && options.allow_tcp_forwarding) >+ channel_permit_all_opens(); >+} >+ > /* Cleanly shutdown PAM */ > void finish_pam(void) > { >@@ -375,7 +380,6 @@ > void start_pam(const char *user) > { > int pam_retval; >- extern ServerOptions options; > extern u_int utmp_len; > const char *rhost; > >Index: auth-pam.h >=================================================================== >RCS file: /cvs/openssh/auth-pam.h,v >retrieving revision 1.16 >diff -u -r1.16 auth-pam.h >--- auth-pam.h 23 Jul 2002 00:44:07 -0000 1.16 >+++ auth-pam.h 4 Jan 2003 12:11:31 -0000 >@@ -43,6 +43,7 @@ > void print_pam_messages(void); > int is_pam_password_change_required(void); > void do_pam_chauthtok(void); >+void password_change_successful_handler(int); > void do_pam_set_conv(struct pam_conv *); > void message_cat(char **p, const char *a); > >Index: monitor.c >=================================================================== >RCS file: /cvs/openssh/monitor.c,v >retrieving revision 1.33 >diff -u -r1.33 monitor.c >--- monitor.c 9 Nov 2002 15:47:49 -0000 1.33 >+++ monitor.c 4 Jan 2003 12:11:32 -0000 >@@ -118,6 +118,7 @@ > > #ifdef USE_PAM > int mm_answer_pam_start(int, Buffer *); >+int mm_answer_pam_chauthtok(int, Buffer *); > #endif > > #ifdef KRB4 >@@ -183,6 +184,9 @@ > {MONITOR_REQ_PTY, 0, mm_answer_pty}, > {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup}, > {MONITOR_REQ_TERM, 0, mm_answer_term}, >+#ifdef USE_PAM >+ {MONITOR_REQ_PAM_CHAUTHTOK, 0, mm_answer_pam_chauthtok}, >+#endif > {0, 0, NULL} > }; > >@@ -219,6 +223,9 @@ > {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty}, > {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup}, > {MONITOR_REQ_TERM, 0, mm_answer_term}, >+#ifdef USE_PAM >+ {MONITOR_REQ_PAM_CHAUTHTOK, 0, mm_answer_pam_chauthtok}, >+#endif > {0, 0, NULL} > }; > >@@ -328,6 +335,7 @@ > if (!no_pty_flag) { > monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); > monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); >+ monitor_permit(mon_dispatch, MONITOR_REQ_PAM_CHAUTHTOK, 1); > } > > for (;;) >@@ -746,6 +754,56 @@ > xfree(user); > > return (0); >+} >+ >+int >+mm_answer_pam_chauthtok(int socket, Buffer *m) >+{ >+ pid_t pid; >+ int ttyfd, status; >+ mysig_t old_signal; >+ >+ old_signal = mysignal(SIGCHLD, SIG_DFL); >+ >+ ttyfd = mm_receive_fd(socket); >+ debug3("%s: ttyfd %d, ttyname %s", __func__, ttyfd, ttyname(ttyfd)); >+ >+ if ((pid = fork()) == 0) { >+ fatal_remove_all_cleanups(); >+ >+ /* set up stdin, stdout and stderr */ >+ if (dup2(ttyfd, 0) < 0) >+ error("dup2 stdin: %s", strerror(errno)); >+ if (dup2(ttyfd, 1) < 0) >+ error("dup2 stdout: %s", strerror(errno)); >+ if (dup2(ttyfd, 2) < 0) >+ error("dup2 stderr: %s", strerror(errno)); >+ >+ /* call PAM chauthtok and return status to parent */ >+ do_pam_chauthtok(); >+ >+ if(is_pam_password_change_required()) >+ exit(1); /* failed */ >+ else >+ exit(0); /* success */ >+ } >+ >+ close(ttyfd); >+ >+ if (waitpid(pid, &status, 0) == -1) >+ fatal("Couldn't wait for child: %s", strerror(errno)); >+ debug("chauthtok child returned %d", status); >+ >+ if (WIFEXITED(status) && (WEXITSTATUS(status) == 0)) >+ debug("password changed sucessfully"); >+ else >+ fatal("do_pam_chauthtok() failed, child returned %d", status); >+ >+ mysignal(SIGCHLD, old_signal); >+ >+ mm_request_send(socket, MONITOR_ANS_PAM_CHAUTHTOK, m); >+ >+ return 1; > } > #endif > >Index: monitor.h >=================================================================== >RCS file: /cvs/openssh/monitor.h,v >retrieving revision 1.10 >diff -u -r1.10 monitor.h >--- monitor.h 27 Sep 2002 03:26:02 -0000 1.10 >+++ monitor.h 4 Jan 2003 12:11:32 -0000 >@@ -52,6 +52,7 @@ > MONITOR_REQ_KRB4, MONITOR_ANS_KRB4, > MONITOR_REQ_KRB5, MONITOR_ANS_KRB5, > MONITOR_REQ_PAM_START, >+ MONITOR_REQ_PAM_CHAUTHTOK, MONITOR_ANS_PAM_CHAUTHTOK, > MONITOR_REQ_TERM > }; > >Index: monitor_wrap.c >=================================================================== >RCS file: /cvs/openssh/monitor_wrap.c,v >retrieving revision 1.21 >diff -u -r1.21 monitor_wrap.c >--- monitor_wrap.c 23 Dec 2002 02:06:20 -0000 1.21 >+++ monitor_wrap.c 4 Jan 2003 12:11:33 -0000 >@@ -663,6 +663,27 @@ > > buffer_free(&m); > } >+ >+/* >+ * Privsep chauthtok works by passing a descriptor to the session's >+ * stdin/stdout to the monitor, which then sets up a child with this >+ * descriptor as stdin, stdout then calls do_pam_chauthtok >+ */ >+ >+void >+mm_do_pam_chauthtok(void) >+{ >+ Buffer m; >+ >+ debug3("%s entering", __func__); >+ >+ buffer_init(&m); >+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_CHAUTHTOK, &m); >+ mm_send_fd(pmonitor->m_recvfd, STDIN_FILENO); >+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_CHAUTHTOK, &m); >+ >+ buffer_free(&m); >+} > #endif /* USE_PAM */ > > /* Request process termination */ >Index: monitor_wrap.h >=================================================================== >RCS file: /cvs/openssh/monitor_wrap.h,v >retrieving revision 1.9 >diff -u -r1.9 monitor_wrap.h >--- monitor_wrap.h 27 Sep 2002 03:26:04 -0000 1.9 >+++ monitor_wrap.h 4 Jan 2003 12:11:33 -0000 >@@ -57,6 +57,7 @@ > > #ifdef USE_PAM > void mm_start_pam(char *); >+void mm_do_pam_chauthtok(void); > #endif > > void mm_terminate(void); >Index: session.c >=================================================================== >RCS file: /cvs/openssh/session.c,v >retrieving revision 1.226 >diff -u -r1.226 session.c >--- session.c 3 Jan 2003 03:52:54 -0000 1.226 >+++ session.c 4 Jan 2003 12:11:34 -0000 >@@ -753,7 +753,10 @@ > */ > if (is_pam_password_change_required()) { > print_pam_messages(); >- do_pam_chauthtok(); >+ PRIVSEP(do_pam_chauthtok()); >+ /* change successful, tell parent to restore port >+ * forwarding flags */ >+ kill(getppid(), SIGUSR1); > } > #endif > >Index: openbsd-compat/readpassphrase.c >=================================================================== >RCS file: /cvs/openssh/openbsd-compat/readpassphrase.c,v >retrieving revision 1.9 >diff -u -r1.9 readpassphrase.c >--- openbsd-compat/readpassphrase.c 11 Sep 2002 00:29:13 -0000 1.9 >+++ openbsd-compat/readpassphrase.c 4 Jan 2003 12:11:36 -0000 >@@ -85,6 +85,15 @@ > output = STDERR_FILENO; > } > >+ /* >+ * Odd case where stdin is a tty but /dev/tty is not >+ * available. Used for passed file descriptor during privsep. >+ */ >+ if (isatty(STDIN_FILENO)) { >+ input = dup(STDIN_FILENO); >+ output = dup(STDERR_FILENO); >+ } >+ > /* > * Catch signals that would otherwise cause the user to end > * up with echo turned off in the shell. Don't worry about
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 423
:
162
|
163
| 198 |
246
|
375
|
376
|
377