diff options
-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 @@ be our 'mysignal' by default. OK djm@ - (dtucker) [acconfig.h auth.c configure.ac sshd.8] Bug #422 again: deny any access to locked accounts. ok djm@ + - (djm) Bug #564: Perform PAM account checks for all authentications when + UsePAM=yes; ok dtucker 20030822 - (djm) s/get_progname/ssh_get_progname/g to avoid conflict with Heimdal @@ -862,4 +864,4 @@ - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. Report from murple@murple.net, diagnosis from dtucker@zip.com.au -$Id: ChangeLog,v 1.2902 2003/08/25 01:51:19 dtucker Exp $ +$Id: ChangeLog,v 1.2903 2003/08/25 03:08:49 djm Exp $ @@ -31,7 +31,7 @@ /* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ #include "includes.h" -RCSID("$Id: auth-pam.c,v 1.66 2003/08/08 03:43:37 dtucker Exp $"); +RCSID("$Id: auth-pam.c,v 1.67 2003/08/25 03:08:49 djm Exp $"); #ifdef USE_PAM #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 $"); #include "servconf.h" #include "ssh2.h" #include "xmalloc.h" +#include "auth-options.h" extern ServerOptions options; @@ -130,10 +131,8 @@ static void sshpam_free_ctx(void *); * Conversation function for authentication thread. */ static int -sshpam_thread_conv(int n, - const struct pam_message **msg, - struct pam_response **resp, - void *data) +sshpam_thread_conv(int n, const struct pam_message **msg, + struct pam_response **resp, void *data) { Buffer buffer; struct pam_ctxt *ctxt; @@ -216,9 +215,6 @@ sshpam_thread(void *ctxtp) sshpam_err = pam_authenticate(sshpam_handle, 0); if (sshpam_err != PAM_SUCCESS) goto auth_fail; - sshpam_err = pam_acct_mgmt(sshpam_handle, 0); - if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) - goto auth_fail; buffer_put_cstring(&buffer, "OK"); ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer); buffer_free(&buffer); @@ -246,12 +242,9 @@ sshpam_thread_cleanup(void *ctxtp) } static int -sshpam_null_conv(int n, - const struct pam_message **msg, - struct pam_response **resp, - void *data) +sshpam_null_conv(int n, const struct pam_message **msg, + struct pam_response **resp, void *data) { - return (PAM_CONV_ERR); } @@ -303,7 +296,7 @@ sshpam_init(const char *user) debug("PAM: setting PAM_RHOST to \"%s\"", pam_rhost); sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, pam_rhost); if (sshpam_err != PAM_SUCCESS) { - pam_end(sshpam_handle, sshpam_err); + pam_end(sshpam_handle, sshpam_err); sshpam_handle = NULL; return (-1); } @@ -403,9 +396,6 @@ sshpam_query(void *ctx, char **name, char **info, plen += snprintf(**prompts + plen, len, "%s", msg); xfree(msg); break; - case PAM_NEW_AUTHTOK_REQD: - sshpam_new_authtok_reqd = 1; - /* FALLTHROUGH */ case PAM_SUCCESS: case PAM_AUTH_ERR: if (**prompts != NULL) { @@ -519,10 +509,24 @@ finish_pam(void) sshpam_cleanup(NULL); } -int -do_pam_account(const char *user, const char *ruser) +u_int +do_pam_account(void) { - /* XXX */ + sshpam_err = pam_acct_mgmt(sshpam_handle, 0); + debug3("%s: pam_acct_mgmt = %d", __func__, sshpam_err); + + if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) + return (0); + + if (sshpam_err == PAM_NEW_AUTHTOK_REQD) { + sshpam_new_authtok_reqd = 1; + + /* Prevent forwardings until password changed */ + no_port_forwarding_flag |= 2; + no_agent_forwarding_flag |= 2; + no_x11_forwarding_flag |= 2; + } + return (1); } @@ -582,10 +586,8 @@ is_pam_password_change_required(void) } static int -pam_chauthtok_conv(int n, - const struct pam_message **msg, - struct pam_response **resp, - void *data) +pam_chauthtok_conv(int n, const struct pam_message **msg, + struct pam_response **resp, void *data) { char input[PAM_MAX_MSG_SIZE]; int i; @@ -635,7 +637,7 @@ do_pam_chauthtok(void) struct pam_conv pam_conv = { pam_chauthtok_conv, NULL }; if (use_privsep) - fatal("PAM: chauthtok not supprted with privsep"); + fatal("Password expired (unable to change with privsep)"); sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, (const void *)&pam_conv); if (sshpam_err != PAM_SUCCESS) @@ -1,4 +1,4 @@ -/* $Id: auth-pam.h,v 1.18 2003/05/19 01:28:44 djm Exp $ */ +/* $Id: auth-pam.h,v 1.19 2003/08/25 03:08:49 djm Exp $ */ /* * Copyright (c) 2000 Damien Miller. All rights reserved. @@ -33,7 +33,7 @@ void start_pam(const char *); void finish_pam(void); -int do_pam_account(const char *, const char *); +u_int do_pam_account(void); void do_pam_session(const char *, const char *); void do_pam_setcred(int ); int is_pam_password_change_required(void); @@ -290,6 +290,12 @@ do_authloop(Authctxt *authctxt) authenticated = 0; #endif +#ifdef USE_PAM + if (options.use_pam && authenticated && + !PRIVSEP(do_pam_account())) + authenticated = 0; +#endif + /* Log before sending the reply */ auth_log(authctxt, authenticated, get_authname(type), info); @@ -213,6 +213,11 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) !auth_root_allowed(method)) authenticated = 0; +#ifdef USE_PAM + if (options.use_pam && authenticated && !PRIVSEP(do_pam_account())) + authenticated = 0; +#endif + #ifdef _UNICOS if (authenticated && cray_access_denied(authctxt->user)) { authenticated = 0; @@ -118,6 +118,7 @@ int mm_answer_sessid(int, Buffer *); #ifdef USE_PAM int mm_answer_pam_start(int, Buffer *); +int mm_answer_pam_account(int, Buffer *); int mm_answer_pam_init_ctx(int, Buffer *); int mm_answer_pam_query(int, Buffer *); int mm_answer_pam_respond(int, Buffer *); @@ -165,6 +166,7 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, + {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, @@ -214,6 +216,7 @@ struct mon_table mon_dispatch_proto15[] = { #endif #ifdef USE_PAM {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, + {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, @@ -295,6 +298,18 @@ monitor_child_preauth(struct monitor *pmonitor) if (authctxt->pw->pw_uid == 0 && !auth_root_allowed(auth_method)) authenticated = 0; +#ifdef USE_PAM + /* PAM needs to perform account checks after auth */ + if (options.use_pam) { + Buffer m; + + buffer_init(&m); + mm_request_receive_expect(pmonitor->m_sendfd, + MONITOR_REQ_PAM_ACCOUNT, &m); + authenticated = mm_answer_pam_account(pmonitor->m_sendfd, &m); + buffer_free(&m); + } +#endif } if (ent->flags & MON_AUTHDECIDE) { @@ -771,9 +786,28 @@ mm_answer_pam_start(int socket, Buffer *m) xfree(user); + monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1); + return (0); } +int +mm_answer_pam_account(int socket, Buffer *m) +{ + u_int ret; + + if (!options.use_pam) + fatal("UsePAM not set, but ended up in %s anyway", __func__); + + ret = do_pam_account(); + + buffer_put_int(m, ret); + + mm_request_send(socket, MONITOR_ANS_PAM_ACCOUNT, m); + + return (ret); +} + static void *sshpam_ctxt, *sshpam_authok; extern KbdintDevice sshpam_device; @@ -51,6 +51,7 @@ enum monitor_reqtype { MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE, MONITOR_REQ_KRB5, MONITOR_ANS_KRB5, MONITOR_REQ_PAM_START, + MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT, MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX, MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY, MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND, diff --git a/monitor_wrap.c b/monitor_wrap.c index c7ba86ff..9e7e6b3c 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -682,6 +682,30 @@ mm_start_pam(char *user) buffer_free(&m); } +u_int +mm_do_pam_account(void) +{ + Buffer m; + u_int ret; + + debug3("%s entering", __func__); + if (!options.use_pam) + fatal("UsePAM=no, but ended up in %s anyway", __func__); + + buffer_init(&m); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m); + + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_PAM_ACCOUNT, &m); + ret = buffer_get_int(&m); + + buffer_free(&m); + + debug3("%s returning %d", __func__, ret); + + return (ret); +} + void * mm_sshpam_init_ctx(Authctxt *authctxt) { diff --git a/monitor_wrap.h b/monitor_wrap.h index e0dd73bd..ddd42ee2 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -57,6 +57,7 @@ BIGNUM *mm_auth_rsa_generate_challenge(Key *); #ifdef USE_PAM void mm_start_pam(char *); +u_int mm_do_pam_account(void); void *mm_sshpam_init_ctx(struct Authctxt *); int mm_sshpam_query(void *, char **, char **, u_int *, char ***, u_int **); int mm_sshpam_respond(void *, u_int, char **); @@ -719,6 +719,7 @@ do_login(Session *s, const char *command) if (options.use_pam && is_pam_password_change_required()) { print_pam_messages(); do_pam_chauthtok(); + /* XXX - signal [net] parent to enable forwardings */ } #endif |