diff options
author | Damien Miller <djm@mindrot.org> | 2003-08-25 13:08:49 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2003-08-25 13:08:49 +1000 |
commit | 1f499fd3688d034daf787859044ede73767b6141 (patch) | |
tree | 0fec594fff3ac5fb6cc4faab19924e047db10207 | |
parent | e41bba584737f028579961ddf6669b6a768e47e7 (diff) |
- (djm) Bug #564: Perform PAM account checks for all authentications when
UsePAM=yes; ok dtucker
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | auth-pam.c | 52 | ||||
-rw-r--r-- | auth-pam.h | 4 | ||||
-rw-r--r-- | auth1.c | 6 | ||||
-rw-r--r-- | auth2.c | 5 | ||||
-rw-r--r-- | monitor.c | 34 | ||||
-rw-r--r-- | monitor.h | 1 | ||||
-rw-r--r-- | monitor_wrap.c | 24 | ||||
-rw-r--r-- | monitor_wrap.h | 1 | ||||
-rw-r--r-- | session.c | 1 |
10 files changed, 104 insertions, 28 deletions
@@ -8,6 +8,8 @@ | |||
8 | be our 'mysignal' by default. OK djm@ | 8 | be our 'mysignal' by default. OK djm@ |
9 | - (dtucker) [acconfig.h auth.c configure.ac sshd.8] Bug #422 again: deny | 9 | - (dtucker) [acconfig.h auth.c configure.ac sshd.8] Bug #422 again: deny |
10 | any access to locked accounts. ok djm@ | 10 | any access to locked accounts. ok djm@ |
11 | - (djm) Bug #564: Perform PAM account checks for all authentications when | ||
12 | UsePAM=yes; ok dtucker | ||
11 | 13 | ||
12 | 20030822 | 14 | 20030822 |
13 | - (djm) s/get_progname/ssh_get_progname/g to avoid conflict with Heimdal | 15 | - (djm) s/get_progname/ssh_get_progname/g to avoid conflict with Heimdal |
@@ -862,4 +864,4 @@ | |||
862 | - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. | 864 | - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. |
863 | Report from murple@murple.net, diagnosis from dtucker@zip.com.au | 865 | Report from murple@murple.net, diagnosis from dtucker@zip.com.au |
864 | 866 | ||
865 | $Id: ChangeLog,v 1.2902 2003/08/25 01:51:19 dtucker Exp $ | 867 | $Id: ChangeLog,v 1.2903 2003/08/25 03:08:49 djm Exp $ |
diff --git a/auth-pam.c b/auth-pam.c index 970ff61cb..c0b6ded12 100644 --- a/auth-pam.c +++ b/auth-pam.c | |||
@@ -31,7 +31,7 @@ | |||
31 | 31 | ||
32 | /* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ | 32 | /* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ |
33 | #include "includes.h" | 33 | #include "includes.h" |
34 | RCSID("$Id: auth-pam.c,v 1.66 2003/08/08 03:43:37 dtucker Exp $"); | 34 | RCSID("$Id: auth-pam.c,v 1.67 2003/08/25 03:08:49 djm Exp $"); |
35 | 35 | ||
36 | #ifdef USE_PAM | 36 | #ifdef USE_PAM |
37 | #include <security/pam_appl.h> | 37 | #include <security/pam_appl.h> |
@@ -49,6 +49,7 @@ RCSID("$Id: auth-pam.c,v 1.66 2003/08/08 03:43:37 dtucker Exp $"); | |||
49 | #include "servconf.h" | 49 | #include "servconf.h" |
50 | #include "ssh2.h" | 50 | #include "ssh2.h" |
51 | #include "xmalloc.h" | 51 | #include "xmalloc.h" |
52 | #include "auth-options.h" | ||
52 | 53 | ||
53 | extern ServerOptions options; | 54 | extern ServerOptions options; |
54 | 55 | ||
@@ -130,10 +131,8 @@ static void sshpam_free_ctx(void *); | |||
130 | * Conversation function for authentication thread. | 131 | * Conversation function for authentication thread. |
131 | */ | 132 | */ |
132 | static int | 133 | static int |
133 | sshpam_thread_conv(int n, | 134 | sshpam_thread_conv(int n, const struct pam_message **msg, |
134 | const struct pam_message **msg, | 135 | struct pam_response **resp, void *data) |
135 | struct pam_response **resp, | ||
136 | void *data) | ||
137 | { | 136 | { |
138 | Buffer buffer; | 137 | Buffer buffer; |
139 | struct pam_ctxt *ctxt; | 138 | struct pam_ctxt *ctxt; |
@@ -216,9 +215,6 @@ sshpam_thread(void *ctxtp) | |||
216 | sshpam_err = pam_authenticate(sshpam_handle, 0); | 215 | sshpam_err = pam_authenticate(sshpam_handle, 0); |
217 | if (sshpam_err != PAM_SUCCESS) | 216 | if (sshpam_err != PAM_SUCCESS) |
218 | goto auth_fail; | 217 | goto auth_fail; |
219 | sshpam_err = pam_acct_mgmt(sshpam_handle, 0); | ||
220 | if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) | ||
221 | goto auth_fail; | ||
222 | buffer_put_cstring(&buffer, "OK"); | 218 | buffer_put_cstring(&buffer, "OK"); |
223 | ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer); | 219 | ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer); |
224 | buffer_free(&buffer); | 220 | buffer_free(&buffer); |
@@ -246,12 +242,9 @@ sshpam_thread_cleanup(void *ctxtp) | |||
246 | } | 242 | } |
247 | 243 | ||
248 | static int | 244 | static int |
249 | sshpam_null_conv(int n, | 245 | sshpam_null_conv(int n, const struct pam_message **msg, |
250 | const struct pam_message **msg, | 246 | struct pam_response **resp, void *data) |
251 | struct pam_response **resp, | ||
252 | void *data) | ||
253 | { | 247 | { |
254 | |||
255 | return (PAM_CONV_ERR); | 248 | return (PAM_CONV_ERR); |
256 | } | 249 | } |
257 | 250 | ||
@@ -303,7 +296,7 @@ sshpam_init(const char *user) | |||
303 | debug("PAM: setting PAM_RHOST to \"%s\"", pam_rhost); | 296 | debug("PAM: setting PAM_RHOST to \"%s\"", pam_rhost); |
304 | sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, pam_rhost); | 297 | sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, pam_rhost); |
305 | if (sshpam_err != PAM_SUCCESS) { | 298 | if (sshpam_err != PAM_SUCCESS) { |
306 | pam_end(sshpam_handle, sshpam_err); | 299 | pam_end(sshpam_handle, sshpam_err); |
307 | sshpam_handle = NULL; | 300 | sshpam_handle = NULL; |
308 | return (-1); | 301 | return (-1); |
309 | } | 302 | } |
@@ -403,9 +396,6 @@ sshpam_query(void *ctx, char **name, char **info, | |||
403 | plen += snprintf(**prompts + plen, len, "%s", msg); | 396 | plen += snprintf(**prompts + plen, len, "%s", msg); |
404 | xfree(msg); | 397 | xfree(msg); |
405 | break; | 398 | break; |
406 | case PAM_NEW_AUTHTOK_REQD: | ||
407 | sshpam_new_authtok_reqd = 1; | ||
408 | /* FALLTHROUGH */ | ||
409 | case PAM_SUCCESS: | 399 | case PAM_SUCCESS: |
410 | case PAM_AUTH_ERR: | 400 | case PAM_AUTH_ERR: |
411 | if (**prompts != NULL) { | 401 | if (**prompts != NULL) { |
@@ -519,10 +509,24 @@ finish_pam(void) | |||
519 | sshpam_cleanup(NULL); | 509 | sshpam_cleanup(NULL); |
520 | } | 510 | } |
521 | 511 | ||
522 | int | 512 | u_int |
523 | do_pam_account(const char *user, const char *ruser) | 513 | do_pam_account(void) |
524 | { | 514 | { |
525 | /* XXX */ | 515 | sshpam_err = pam_acct_mgmt(sshpam_handle, 0); |
516 | debug3("%s: pam_acct_mgmt = %d", __func__, sshpam_err); | ||
517 | |||
518 | if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) | ||
519 | return (0); | ||
520 | |||
521 | if (sshpam_err == PAM_NEW_AUTHTOK_REQD) { | ||
522 | sshpam_new_authtok_reqd = 1; | ||
523 | |||
524 | /* Prevent forwardings until password changed */ | ||
525 | no_port_forwarding_flag |= 2; | ||
526 | no_agent_forwarding_flag |= 2; | ||
527 | no_x11_forwarding_flag |= 2; | ||
528 | } | ||
529 | |||
526 | return (1); | 530 | return (1); |
527 | } | 531 | } |
528 | 532 | ||
@@ -582,10 +586,8 @@ is_pam_password_change_required(void) | |||
582 | } | 586 | } |
583 | 587 | ||
584 | static int | 588 | static int |
585 | pam_chauthtok_conv(int n, | 589 | pam_chauthtok_conv(int n, const struct pam_message **msg, |
586 | const struct pam_message **msg, | 590 | struct pam_response **resp, void *data) |
587 | struct pam_response **resp, | ||
588 | void *data) | ||
589 | { | 591 | { |
590 | char input[PAM_MAX_MSG_SIZE]; | 592 | char input[PAM_MAX_MSG_SIZE]; |
591 | int i; | 593 | int i; |
@@ -635,7 +637,7 @@ do_pam_chauthtok(void) | |||
635 | struct pam_conv pam_conv = { pam_chauthtok_conv, NULL }; | 637 | struct pam_conv pam_conv = { pam_chauthtok_conv, NULL }; |
636 | 638 | ||
637 | if (use_privsep) | 639 | if (use_privsep) |
638 | fatal("PAM: chauthtok not supprted with privsep"); | 640 | fatal("Password expired (unable to change with privsep)"); |
639 | sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, | 641 | sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, |
640 | (const void *)&pam_conv); | 642 | (const void *)&pam_conv); |
641 | if (sshpam_err != PAM_SUCCESS) | 643 | if (sshpam_err != PAM_SUCCESS) |
diff --git a/auth-pam.h b/auth-pam.h index fdbd0febd..7f7c16d2e 100644 --- a/auth-pam.h +++ b/auth-pam.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: auth-pam.h,v 1.18 2003/05/19 01:28:44 djm Exp $ */ | 1 | /* $Id: auth-pam.h,v 1.19 2003/08/25 03:08:49 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2000 Damien Miller. All rights reserved. |
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | void start_pam(const char *); | 34 | void start_pam(const char *); |
35 | void finish_pam(void); | 35 | void finish_pam(void); |
36 | int do_pam_account(const char *, const char *); | 36 | u_int do_pam_account(void); |
37 | void do_pam_session(const char *, const char *); | 37 | void do_pam_session(const char *, const char *); |
38 | void do_pam_setcred(int ); | 38 | void do_pam_setcred(int ); |
39 | int is_pam_password_change_required(void); | 39 | int is_pam_password_change_required(void); |
@@ -290,6 +290,12 @@ do_authloop(Authctxt *authctxt) | |||
290 | authenticated = 0; | 290 | authenticated = 0; |
291 | #endif | 291 | #endif |
292 | 292 | ||
293 | #ifdef USE_PAM | ||
294 | if (options.use_pam && authenticated && | ||
295 | !PRIVSEP(do_pam_account())) | ||
296 | authenticated = 0; | ||
297 | #endif | ||
298 | |||
293 | /* Log before sending the reply */ | 299 | /* Log before sending the reply */ |
294 | auth_log(authctxt, authenticated, get_authname(type), info); | 300 | auth_log(authctxt, authenticated, get_authname(type), info); |
295 | 301 | ||
@@ -213,6 +213,11 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) | |||
213 | !auth_root_allowed(method)) | 213 | !auth_root_allowed(method)) |
214 | authenticated = 0; | 214 | authenticated = 0; |
215 | 215 | ||
216 | #ifdef USE_PAM | ||
217 | if (options.use_pam && authenticated && !PRIVSEP(do_pam_account())) | ||
218 | authenticated = 0; | ||
219 | #endif | ||
220 | |||
216 | #ifdef _UNICOS | 221 | #ifdef _UNICOS |
217 | if (authenticated && cray_access_denied(authctxt->user)) { | 222 | if (authenticated && cray_access_denied(authctxt->user)) { |
218 | authenticated = 0; | 223 | authenticated = 0; |
@@ -118,6 +118,7 @@ int mm_answer_sessid(int, Buffer *); | |||
118 | 118 | ||
119 | #ifdef USE_PAM | 119 | #ifdef USE_PAM |
120 | int mm_answer_pam_start(int, Buffer *); | 120 | int mm_answer_pam_start(int, Buffer *); |
121 | int mm_answer_pam_account(int, Buffer *); | ||
121 | int mm_answer_pam_init_ctx(int, Buffer *); | 122 | int mm_answer_pam_init_ctx(int, Buffer *); |
122 | int mm_answer_pam_query(int, Buffer *); | 123 | int mm_answer_pam_query(int, Buffer *); |
123 | int mm_answer_pam_respond(int, Buffer *); | 124 | int mm_answer_pam_respond(int, Buffer *); |
@@ -165,6 +166,7 @@ struct mon_table mon_dispatch_proto20[] = { | |||
165 | {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, | 166 | {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, |
166 | #ifdef USE_PAM | 167 | #ifdef USE_PAM |
167 | {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, | 168 | {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, |
169 | {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, | ||
168 | {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, | 170 | {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, |
169 | {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, | 171 | {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, |
170 | {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, | 172 | {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, |
@@ -214,6 +216,7 @@ struct mon_table mon_dispatch_proto15[] = { | |||
214 | #endif | 216 | #endif |
215 | #ifdef USE_PAM | 217 | #ifdef USE_PAM |
216 | {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, | 218 | {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, |
219 | {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, | ||
217 | {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, | 220 | {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, |
218 | {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, | 221 | {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, |
219 | {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, | 222 | {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, |
@@ -295,6 +298,18 @@ monitor_child_preauth(struct monitor *pmonitor) | |||
295 | if (authctxt->pw->pw_uid == 0 && | 298 | if (authctxt->pw->pw_uid == 0 && |
296 | !auth_root_allowed(auth_method)) | 299 | !auth_root_allowed(auth_method)) |
297 | authenticated = 0; | 300 | authenticated = 0; |
301 | #ifdef USE_PAM | ||
302 | /* PAM needs to perform account checks after auth */ | ||
303 | if (options.use_pam) { | ||
304 | Buffer m; | ||
305 | |||
306 | buffer_init(&m); | ||
307 | mm_request_receive_expect(pmonitor->m_sendfd, | ||
308 | MONITOR_REQ_PAM_ACCOUNT, &m); | ||
309 | authenticated = mm_answer_pam_account(pmonitor->m_sendfd, &m); | ||
310 | buffer_free(&m); | ||
311 | } | ||
312 | #endif | ||
298 | } | 313 | } |
299 | 314 | ||
300 | if (ent->flags & MON_AUTHDECIDE) { | 315 | if (ent->flags & MON_AUTHDECIDE) { |
@@ -771,9 +786,28 @@ mm_answer_pam_start(int socket, Buffer *m) | |||
771 | 786 | ||
772 | xfree(user); | 787 | xfree(user); |
773 | 788 | ||
789 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1); | ||
790 | |||
774 | return (0); | 791 | return (0); |
775 | } | 792 | } |
776 | 793 | ||
794 | int | ||
795 | mm_answer_pam_account(int socket, Buffer *m) | ||
796 | { | ||
797 | u_int ret; | ||
798 | |||
799 | if (!options.use_pam) | ||
800 | fatal("UsePAM not set, but ended up in %s anyway", __func__); | ||
801 | |||
802 | ret = do_pam_account(); | ||
803 | |||
804 | buffer_put_int(m, ret); | ||
805 | |||
806 | mm_request_send(socket, MONITOR_ANS_PAM_ACCOUNT, m); | ||
807 | |||
808 | return (ret); | ||
809 | } | ||
810 | |||
777 | static void *sshpam_ctxt, *sshpam_authok; | 811 | static void *sshpam_ctxt, *sshpam_authok; |
778 | extern KbdintDevice sshpam_device; | 812 | extern KbdintDevice sshpam_device; |
779 | 813 | ||
@@ -51,6 +51,7 @@ enum monitor_reqtype { | |||
51 | MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE, | 51 | MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE, |
52 | MONITOR_REQ_KRB5, MONITOR_ANS_KRB5, | 52 | MONITOR_REQ_KRB5, MONITOR_ANS_KRB5, |
53 | MONITOR_REQ_PAM_START, | 53 | MONITOR_REQ_PAM_START, |
54 | MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT, | ||
54 | MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX, | 55 | MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX, |
55 | MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY, | 56 | MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY, |
56 | MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND, | 57 | MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND, |
diff --git a/monitor_wrap.c b/monitor_wrap.c index c7ba86ffc..9e7e6b3c3 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c | |||
@@ -682,6 +682,30 @@ mm_start_pam(char *user) | |||
682 | buffer_free(&m); | 682 | buffer_free(&m); |
683 | } | 683 | } |
684 | 684 | ||
685 | u_int | ||
686 | mm_do_pam_account(void) | ||
687 | { | ||
688 | Buffer m; | ||
689 | u_int ret; | ||
690 | |||
691 | debug3("%s entering", __func__); | ||
692 | if (!options.use_pam) | ||
693 | fatal("UsePAM=no, but ended up in %s anyway", __func__); | ||
694 | |||
695 | buffer_init(&m); | ||
696 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m); | ||
697 | |||
698 | mm_request_receive_expect(pmonitor->m_recvfd, | ||
699 | MONITOR_ANS_PAM_ACCOUNT, &m); | ||
700 | ret = buffer_get_int(&m); | ||
701 | |||
702 | buffer_free(&m); | ||
703 | |||
704 | debug3("%s returning %d", __func__, ret); | ||
705 | |||
706 | return (ret); | ||
707 | } | ||
708 | |||
685 | void * | 709 | void * |
686 | mm_sshpam_init_ctx(Authctxt *authctxt) | 710 | mm_sshpam_init_ctx(Authctxt *authctxt) |
687 | { | 711 | { |
diff --git a/monitor_wrap.h b/monitor_wrap.h index e0dd73bd0..ddd42ee28 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h | |||
@@ -57,6 +57,7 @@ BIGNUM *mm_auth_rsa_generate_challenge(Key *); | |||
57 | 57 | ||
58 | #ifdef USE_PAM | 58 | #ifdef USE_PAM |
59 | void mm_start_pam(char *); | 59 | void mm_start_pam(char *); |
60 | u_int mm_do_pam_account(void); | ||
60 | void *mm_sshpam_init_ctx(struct Authctxt *); | 61 | void *mm_sshpam_init_ctx(struct Authctxt *); |
61 | int mm_sshpam_query(void *, char **, char **, u_int *, char ***, u_int **); | 62 | int mm_sshpam_query(void *, char **, char **, u_int *, char ***, u_int **); |
62 | int mm_sshpam_respond(void *, u_int, char **); | 63 | int mm_sshpam_respond(void *, u_int, char **); |
@@ -719,6 +719,7 @@ do_login(Session *s, const char *command) | |||
719 | if (options.use_pam && is_pam_password_change_required()) { | 719 | if (options.use_pam && is_pam_password_change_required()) { |
720 | print_pam_messages(); | 720 | print_pam_messages(); |
721 | do_pam_chauthtok(); | 721 | do_pam_chauthtok(); |
722 | /* XXX - signal [net] parent to enable forwardings */ | ||
722 | } | 723 | } |
723 | #endif | 724 | #endif |
724 | 725 | ||