X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/5d33c697df2ab1a61c34bd4fcf3d011860d88f9b..822015dda8008714e520ca557865c28023adbc83:/auth-pam.c diff --git a/auth-pam.c b/auth-pam.c index c9c33295..d25cff37 100644 --- a/auth-pam.c +++ b/auth-pam.c @@ -56,6 +56,13 @@ RCSID("$Id$"); #include #endif +/* OpenGroup RFC86.0 and XSSO specify no "const" on arguments */ +#ifdef PAM_SUN_CODEBASE +# define sshpam_const /* Solaris, HP-UX, AIX */ +#else +# define sshpam_const const /* LinuxPAM, OpenPAM */ +#endif + #include "auth.h" #include "auth-pam.h" #include "buffer.h" @@ -76,7 +83,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 /* * Avoid namespace clash when *not* using pthreads for systems *with* @@ -98,7 +115,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. */ @@ -245,17 +262,6 @@ sshpam_password_change_required(int reqd) } } -/* Check ssh internal flags in addition to PAM */ - -static int -sshpam_login_allowed(Authctxt *ctxt) -{ - if (ctxt->valid && (ctxt->pw->pw_uid != 0 || - options.permit_root_login == PERMIT_YES)) - return 1; - return 0; -} - /* Import regular and PAM environment from subprocess */ static void import_environments(Buffer *b) @@ -266,7 +272,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)); @@ -301,7 +307,7 @@ import_environments(Buffer *b) * Conversation function for authentication thread. */ static int -sshpam_thread_conv(int n, struct pam_message **msg, +sshpam_thread_conv(int n, sshpam_const struct pam_message **msg, struct pam_response **resp, void *data) { Buffer buffer; @@ -395,13 +401,15 @@ 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; const char *pam_user; + const char **ptr_pam_user = &pam_user; - pam_get_item(sshpam_handle, PAM_USER, (void **)&pam_user); + pam_get_item(sshpam_handle, PAM_USER, + (sshpam_const void **)ptr_pam_user); environ[0] = NULL; if (sshpam_authctxt != NULL) { @@ -439,7 +447,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); @@ -458,7 +466,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); @@ -493,7 +501,7 @@ sshpam_thread_cleanup(void) } static int -sshpam_null_conv(int n, struct pam_message **msg, +sshpam_null_conv(int n, sshpam_const struct pam_message **msg, struct pam_response **resp, void *data) { debug3("PAM: %s entering, %d messages", __func__, n); @@ -503,7 +511,7 @@ sshpam_null_conv(int n, struct pam_message **msg, static struct pam_conv null_conv = { sshpam_null_conv, NULL }; static int -sshpam_store_conv(int n, struct pam_message **msg, +sshpam_store_conv(int n, sshpam_const struct pam_message **msg, struct pam_response **resp, void *data) { struct pam_response *reply; @@ -572,11 +580,12 @@ sshpam_init(Authctxt *authctxt) { extern char *__progname; const char *pam_rhost, *pam_user, *user = authctxt->user; + const char **ptr_pam_user = &pam_user; if (sshpam_handle != NULL) { /* We already have a PAM context; check if the user matches */ sshpam_err = pam_get_item(sshpam_handle, - PAM_USER, (void **)&pam_user); + PAM_USER, (sshpam_const void **)ptr_pam_user); if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0) return (0); pam_end(sshpam_handle, sshpam_err); @@ -713,7 +722,9 @@ sshpam_query(void *ctx, char **name, char **info, **prompts = NULL; } if (type == PAM_SUCCESS) { - if (!sshpam_login_allowed(sshpam_authctxt)) + 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"); @@ -762,7 +773,9 @@ sshpam_respond(void *ctx, u_int num, char **resp) return (-1); } buffer_init(&buffer); - if (sshpam_login_allowed(sshpam_authctxt)) + 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); @@ -888,7 +901,7 @@ do_pam_setcred(int init) } static int -sshpam_tty_conv(int n, struct pam_message **msg, +sshpam_tty_conv(int n, sshpam_const struct pam_message **msg, struct pam_response **resp, void *data) { char input[PAM_MAX_MSG_SIZE]; @@ -1047,7 +1060,7 @@ free_pam_environment(char **env) * display. */ static int -sshpam_passwd_conv(int n, struct pam_message **msg, +sshpam_passwd_conv(int n, sshpam_const struct pam_message **msg, struct pam_response **resp, void *data) { struct pam_response *reply; @@ -1125,7 +1138,8 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) * by PermitRootLogin, use an invalid password to prevent leaking * information via timing (eg if the PAM config has a delay on fail). */ - if (!sshpam_login_allowed(authctxt)) + if (!authctxt->valid || (authctxt->pw->pw_uid == 0 && + options.permit_root_login != PERMIT_YES)) sshpam_password = badpw; sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, @@ -1136,7 +1150,7 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) sshpam_err = pam_authenticate(sshpam_handle, flags); sshpam_password = NULL; - if (sshpam_err == PAM_SUCCESS && sshpam_login_allowed(authctxt)) { + if (sshpam_err == PAM_SUCCESS && authctxt->valid) { debug("PAM: password authentication accepted for %.100s", authctxt->user); return 1;