]> andersk Git - openssh.git/blobdiff - auth-pam.c
- jmc@cvs.openbsd.org 2005/05/20 11:23:32
[openssh.git] / auth-pam.c
index 3e489c06733a08304429da658fb48fb2d8bcaad0..e1b8e783a0a336bd660d2aa1eed85f74ed1644a8 100644 (file)
@@ -76,7 +76,17 @@ extern Buffer loginmsg;
 extern int compat20;
 extern u_int utmp_len;
 
+/* so we don't silently change behaviour */
 #ifdef USE_POSIX_THREADS
+# error "USE_POSIX_THREADS replaced by UNSUPPORTED_POSIX_THREADS_HACK"
+#endif
+
+/*
+ * Formerly known as USE_POSIX_THREADS, using this is completely unsupported
+ * and generally a bad idea.  Use at own risk and do not expect support if
+ * this breaks.
+ */
+#ifdef UNSUPPORTED_POSIX_THREADS_HACK
 #include <pthread.h>
 /*
  * Avoid namespace clash when *not* using pthreads for systems *with*
@@ -98,7 +108,7 @@ struct pam_ctxt {
 static void sshpam_free_ctx(void *);
 static struct pam_ctxt *cleanup_ctxt;
 
-#ifndef USE_POSIX_THREADS
+#ifndef UNSUPPORTED_POSIX_THREADS_HACK
 /*
  * Simulate threads with processes.
  */
@@ -186,6 +196,7 @@ static int sshpam_account_status = -1;
 static char **sshpam_env = NULL;
 static Authctxt *sshpam_authctxt = NULL;
 static const char *sshpam_password = NULL;
+static char badpw[] = "\b\n\r\177INCORRECT";
 
 /* Some PAM implementations don't implement this */
 #ifndef HAVE_PAM_GETENVLIST
@@ -254,7 +265,7 @@ import_environments(Buffer *b)
 
        debug3("PAM: %s entering", __func__);
 
-#ifndef USE_POSIX_THREADS
+#ifndef UNSUPPORTED_POSIX_THREADS_HACK
        /* Import variables set by do_pam_account */
        sshpam_account_status = buffer_get_int(b);
        sshpam_password_change_required(buffer_get_int(b));
@@ -383,7 +394,7 @@ sshpam_thread(void *ctxtp)
        struct pam_conv sshpam_conv;
        int flags = (options.permit_empty_passwd == 0 ?
            PAM_DISALLOW_NULL_AUTHTOK : 0);
-#ifndef USE_POSIX_THREADS
+#ifndef UNSUPPORTED_POSIX_THREADS_HACK
        extern char **environ;
        char **env_from_pam;
        u_int i;
@@ -427,7 +438,7 @@ sshpam_thread(void *ctxtp)
 
        buffer_put_cstring(&buffer, "OK");
 
-#ifndef USE_POSIX_THREADS
+#ifndef UNSUPPORTED_POSIX_THREADS_HACK
        /* Export variables set by do_pam_account */
        buffer_put_int(&buffer, sshpam_account_status);
        buffer_put_int(&buffer, sshpam_authctxt->force_pwchange);
@@ -446,7 +457,7 @@ sshpam_thread(void *ctxtp)
        buffer_put_int(&buffer, i);
        for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++)
                buffer_put_cstring(&buffer, env_from_pam[i]);
-#endif /* USE_POSIX_THREADS */
+#endif /* UNSUPPORTED_POSIX_THREADS_HACK */
 
        /* XXX - can't do much about an error here */
        ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer);
@@ -654,7 +665,7 @@ sshpam_query(void *ctx, char **name, char **info,
        size_t plen;
        u_char type;
        char *msg;
-       size_t len;
+       size_t len, mlen;
 
        debug3("PAM: %s entering", __func__);
        buffer_init(&buffer);
@@ -667,22 +678,27 @@ sshpam_query(void *ctx, char **name, char **info,
        while (ssh_msg_recv(ctxt->pam_psock, &buffer) == 0) {
                type = buffer_get_char(&buffer);
                msg = buffer_get_string(&buffer, NULL);
+               mlen = strlen(msg);
                switch (type) {
                case PAM_PROMPT_ECHO_ON:
                case PAM_PROMPT_ECHO_OFF:
                        *num = 1;
-                       len = plen + strlen(msg) + 1;
+                       len = plen + mlen + 1;
                        **prompts = xrealloc(**prompts, len);
-                       plen += snprintf(**prompts + plen, len, "%s", msg);
+                       strlcpy(**prompts + plen, msg, len - plen);
+                       plen += mlen;
                        **echo_on = (type == PAM_PROMPT_ECHO_ON);
                        xfree(msg);
                        return (0);
                case PAM_ERROR_MSG:
                case PAM_TEXT_INFO:
                        /* accumulate messages */
-                       len = plen + strlen(msg) + 2;
+                       len = plen + mlen + 2;
                        **prompts = xrealloc(**prompts, len);
-                       plen += snprintf(**prompts + plen, len, "%s\n", msg);
+                       strlcpy(**prompts + plen, msg, len - plen);
+                       plen += mlen;
+                       strlcat(**prompts + plen, "\n", len - plen);
+                       plen++;
                        xfree(msg);
                        break;
                case PAM_SUCCESS:
@@ -696,6 +712,12 @@ sshpam_query(void *ctx, char **name, char **info,
                                **prompts = NULL;
                        }
                        if (type == PAM_SUCCESS) {
+                               if (!sshpam_authctxt->valid ||
+                                   (sshpam_authctxt->pw->pw_uid == 0 &&
+                                   options.permit_root_login != PERMIT_YES))
+                                       fatal("Internal error: PAM auth "
+                                           "succeeded when it should have "
+                                           "failed");
                                import_environments(&buffer);
                                *num = 0;
                                **echo_on = 0;
@@ -741,7 +763,12 @@ sshpam_respond(void *ctx, u_int num, char **resp)
                return (-1);
        }
        buffer_init(&buffer);
-       buffer_put_cstring(&buffer, *resp);
+       if (sshpam_authctxt->valid &&
+           (sshpam_authctxt->pw->pw_uid != 0 ||
+            options.permit_root_login == PERMIT_YES))
+               buffer_put_cstring(&buffer, *resp);
+       else
+               buffer_put_cstring(&buffer, badpw);
        if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) {
                buffer_free(&buffer);
                return (-1);
@@ -1088,7 +1115,6 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password)
 {
        int flags = (options.permit_empty_passwd == 0 ?
            PAM_DISALLOW_NULL_AUTHTOK : 0);
-       static char badpw[] = "\b\n\r\177INCORRECT";
 
        if (!options.use_pam || sshpam_handle == NULL)
                fatal("PAM: %s called when PAM disabled or failed to "
This page took 0.14142 seconds and 4 git commands to generate.