]> andersk Git - openssh.git/commitdiff
- (djm) Bug #564: Perform PAM account checks for all authentications when
authordjm <djm>
Mon, 25 Aug 2003 03:08:49 +0000 (03:08 +0000)
committerdjm <djm>
Mon, 25 Aug 2003 03:08:49 +0000 (03:08 +0000)
   UsePAM=yes; ok dtucker

ChangeLog
auth-pam.c
auth-pam.h
auth1.c
auth2.c
monitor.c
monitor.h
monitor_wrap.c
monitor_wrap.h
session.c

index 39398fc4a11e43abeba29d43595c0613e3fa369e..81ba9cc471e5ee359de8978d17b8dc85d2235b1a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 
index 30f0004851ff1d063f1c7c2a5a164b5099b6db7a..b9c1898c1d5a212d31bcda8d10d71846cfd58ea3 100644 (file)
@@ -49,6 +49,7 @@ RCSID("$Id$");
 #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)
index 3342feed36190f7efc3637d50b58896542ad1267..622342d3ea04825c04c751e2ddad9c556baf2f5a 100644 (file)
@@ -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);
diff --git a/auth1.c b/auth1.c
index 7c0100103b842e4196bb1a69dbcabbb86dee7d4c..d8b5836bafc9bc282417de599de00f3b8bf8766e 100644 (file)
--- a/auth1.c
+++ b/auth1.c
@@ -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);
 
diff --git a/auth2.c b/auth2.c
index 639bf91170db412d8e5a60362cd6243e77ebd7d9..e6ec8ddcd315138b88c26566b61c94b4b8e212a6 100644 (file)
--- a/auth2.c
+++ b/auth2.c
@@ -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;
index 95fd0cf64caf0a55ef4ade5c83c1f17367dbd467..80b1a8fba291ca86b3a590b776792dc48748c246 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -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;
 
index 13b21aa429f76a6fc344fedbfc58d0990135182c..eeac78e037b1664fa4db91136b20e12528df9827 100644 (file)
--- a/monitor.h
+++ b/monitor.h
@@ -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,
index c7ba86ffcf2b4ab9ddd2b39b643fd43a5e727777..9e7e6b3c3e1a1ad783de4c51a267a97b5e576d8d 100644 (file)
@@ -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)
 {
index e0dd73bd0366b6f79d131d17cb2bda3be3e7548d..ddd42ee28ce7ab2dd10111977655346045fee367 100644 (file)
@@ -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 **);
index d3ef89a0c95d9da64146fdfed07d12cab4b31a6b..20c4b8a97346f008b20c920dfe27f757c628670f 100644 (file)
--- a/session.c
+++ b/session.c
@@ -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
 
This page took 0.070285 seconds and 5 git commands to generate.