From: djm Date: Wed, 14 May 2003 05:11:48 +0000 (+0000) Subject: - (djm) Add new UsePAM configuration directive to allow runtime control X-Git-Tag: PRE_KRB4_REMOVAL~194 X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/commitdiff_plain/7fceb20db1ed429d32f787bf1d04fe9b367b7d01 - (djm) Add new UsePAM configuration directive to allow runtime control over usage of PAM. This allows non-root use of sshd when built with --with-pam --- diff --git a/ChangeLog b/ChangeLog index 34d6b517..f08f8b4b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -68,6 +68,9 @@ implement kerberos over ssh2 ("kerberos-2@ssh.com"); tested with jakob@ server interops with commercial client; ok jakob@ djm@ - (djm) Make portable build with MIT krb5 (some issues remain) + - (djm) Add new UsePAM configuration directive to allow runtime control + over usage of PAM. This allows non-root use of sshd when built with + --with-pam 20030512 - (djm) Redhat spec: Don't install profile.d scripts when not diff --git a/auth-pam.c b/auth-pam.c index f4718035..234e8f43 100644 --- a/auth-pam.c +++ b/auth-pam.c @@ -49,6 +49,8 @@ RCSID("$FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48: #include "ssh2.h" #include "xmalloc.h" +extern ServerOptions options; + #define __unused #ifdef USE_POSIX_THREADS @@ -276,7 +278,6 @@ sshpam_cleanup(void *arg) static int sshpam_init(const char *user) { - extern ServerOptions options; extern u_int utmp_len; const char *pam_rhost, *pam_user; @@ -313,6 +314,10 @@ sshpam_init_ctx(Authctxt *authctxt) struct pam_ctxt *ctxt; int socks[2]; + /* Refuse to start if we don't have PAM enabled */ + if (!options.use_pam) + return NULL; + /* Initialize PAM */ if (sshpam_init(authctxt->user) == -1) { error("PAM: initialization failed"); diff --git a/auth.c b/auth.c index a17cc557..8b58cc67 100644 --- a/auth.c +++ b/auth.c @@ -78,8 +78,8 @@ allowed_user(struct passwd * pw) #ifdef WITH_AIXAUTHENTICATE char *loginmsg; #endif /* WITH_AIXAUTHENTICATE */ -#if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \ - !defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE) +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) && \ + defined(HAS_SHADOW_EXPIRE) struct spwd *spw; time_t today; #endif @@ -88,10 +88,10 @@ allowed_user(struct passwd * pw) if (!pw || !pw->pw_name) return 0; -#if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \ - !defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE) +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) && \ + defined(HAS_SHADOW_EXPIRE) #define DAY (24L * 60 * 60) /* 1 day in seconds */ - if ((spw = getspnam(pw->pw_name)) != NULL) { + if (!options.use_pam && (spw = getspnam(pw->pw_name)) != NULL) { today = time(NULL) / DAY; debug3("allowed_user: today %d sp_expire %d sp_lstchg %d" " sp_max %d", (int)today, (int)spw->sp_expire, diff --git a/auth1.c b/auth1.c index 7fe36315..6cb0b04b 100644 --- a/auth1.c +++ b/auth1.c @@ -342,11 +342,6 @@ do_authloop(Authctxt *authctxt) !auth_root_allowed(get_authname(type))) authenticated = 0; #endif -#ifdef USE_PAM - if (!use_privsep && authenticated && - !do_pam_account(pw->pw_name, client_user)) - authenticated = 0; -#endif /* Log before sending the reply */ auth_log(authctxt, authenticated, get_authname(type), info); @@ -413,7 +408,8 @@ do_authentication(void) use_privsep ? " [net]" : ""); #ifdef USE_PAM - PRIVSEP(start_pam(user)); + if (options.use_pam) + PRIVSEP(start_pam(user)); #endif /* diff --git a/auth2.c b/auth2.c index 03d170e2..5ca02000 100644 --- a/auth2.c +++ b/auth2.c @@ -91,10 +91,6 @@ do_authentication2(void) /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; - if (options.pam_authentication_via_kbd_int) - options.kbd_interactive_authentication = 1; - if (use_privsep) - options.pam_authentication_via_kbd_int = 0; dispatch_init(&dispatch_protocol_error); dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); @@ -163,12 +159,14 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) authctxt->valid = 1; debug2("input_userauth_request: setting up authctxt for %s", user); #ifdef USE_PAM - PRIVSEP(start_pam(authctxt->pw->pw_name)); + if (options.use_pam) + PRIVSEP(start_pam(authctxt->pw->pw_name)); #endif } else { logit("input_userauth_request: illegal user %s", user); #ifdef USE_PAM - PRIVSEP(start_pam(user)); + if (options.use_pam) + PRIVSEP(start_pam(user)); #endif } setproctitle("%s%s", authctxt->pw ? user : "unknown", @@ -215,12 +213,6 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) !auth_root_allowed(method)) authenticated = 0; -#ifdef USE_PAM - if (!use_privsep && authenticated && authctxt->user && - !do_pam_account(authctxt->user, NULL)) - authenticated = 0; -#endif /* USE_PAM */ - #ifdef _UNICOS if (authenticated && cray_access_denied(authctxt->user)) { authenticated = 0; diff --git a/monitor.c b/monitor.c index 78d1e2e0..36f9a6c2 100644 --- a/monitor.c +++ b/monitor.c @@ -567,7 +567,8 @@ mm_answer_pwnamallow(int socket, Buffer *m) } #ifdef USE_PAM - monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); + if (options.use_pam) + monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); #endif return (0); @@ -750,6 +751,9 @@ mm_answer_pam_start(int socket, Buffer *m) { char *user; + if (!options.use_pam) + fatal("UsePAM not set, but ended up in %s anyway", __func__); + user = buffer_get_string(m, NULL); start_pam(user); diff --git a/monitor_wrap.c b/monitor_wrap.c index a83413a5..bd3a01a2 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -47,6 +47,7 @@ RCSID("$OpenBSD: monitor_wrap.c,v 1.26 2003/04/07 08:29:57 markus Exp $"); #include "atomicio.h" #include "monitor_fdpass.h" #include "getput.h" +#include "servconf.h" #include "auth.h" #include "channels.h" @@ -59,6 +60,7 @@ extern z_stream incoming_stream; extern z_stream outgoing_stream; extern struct monitor *pmonitor; extern Buffer input, output; +extern ServerOptions options; void mm_request_send(int socket, enum monitor_reqtype type, Buffer *m) @@ -669,6 +671,8 @@ mm_start_pam(char *user) Buffer m; debug3("%s entering", __func__); + if (!options.use_pam) + fatal("UsePAM=no, but ended up in %s anyway", __func__); buffer_init(&m); buffer_put_cstring(&m, user); diff --git a/servconf.c b/servconf.c index 8e283908..fbdc4d8f 100644 --- a/servconf.c +++ b/servconf.c @@ -59,8 +59,10 @@ initialize_server_options(ServerOptions *options) { memset(options, 0, sizeof(*options)); +#ifdef USE_PAM /* Portable-specific options */ - options->pam_authentication_via_kbd_int = -1; + options->use_pam = -1; +#endif /* Standard Options */ options->num_ports = 0; @@ -136,8 +138,10 @@ void fill_default_server_options(ServerOptions *options) { /* Portable-specific options */ - if (options->pam_authentication_via_kbd_int == -1) - options->pam_authentication_via_kbd_int = 0; +#ifdef USE_PAM + if (options->use_pam == -1) + options->use_pam = 1; +#endif /* Standard Options */ if (options->protocol == SSH_PROTO_UNKNOWN) @@ -279,7 +283,7 @@ fill_default_server_options(ServerOptions *options) typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ - sPAMAuthenticationViaKbdInt, + sUsePAM, /* Standard Options */ sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, @@ -315,7 +319,7 @@ static struct { ServerOpCodes opcode; } keywords[] = { /* Portable-specific options */ - { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt }, + { "UsePAM", sUsePAM }, /* Standard Options */ { "port", sPort }, { "hostkey", sHostKeyFile }, @@ -462,8 +466,8 @@ process_server_config_line(ServerOptions *options, char *line, opcode = parse_token(arg, filename, linenum); switch (opcode) { /* Portable-specific options */ - case sPAMAuthenticationViaKbdInt: - intptr = &options->pam_authentication_via_kbd_int; + case sUsePAM: + intptr = &options->use_pam; goto parse_flag; /* Standard Options */ diff --git a/servconf.h b/servconf.h index 024987dd..afa80675 100644 --- a/servconf.h +++ b/servconf.h @@ -131,7 +131,7 @@ typedef struct { char *authorized_keys_file; /* File containing public keys */ char *authorized_keys_file2; - int pam_authentication_via_kbd_int; + int use_pam; /* Enable auth via PAM */ } ServerOptions; void initialize_server_options(ServerOptions *); diff --git a/session.c b/session.c index 1a86f5f8..5b445f93 100644 --- a/session.c +++ b/session.c @@ -456,11 +456,13 @@ do_exec_no_pty(Session *s, const char *command) session_proctitle(s); #if defined(USE_PAM) - do_pam_session(s->pw->pw_name, NULL); - do_pam_setcred(1); - if (is_pam_password_change_required()) - packet_disconnect("Password change required but no " - "TTY available"); + if (options.use_pam) { + do_pam_session(s->pw->pw_name, NULL); + do_pam_setcred(1); + if (is_pam_password_change_required()) + packet_disconnect("Password change required but no " + "TTY available"); + } #endif /* USE_PAM */ /* Fork the child. */ @@ -583,8 +585,10 @@ do_exec_pty(Session *s, const char *command) ttyfd = s->ttyfd; #if defined(USE_PAM) - do_pam_session(s->pw->pw_name, s->tty); - do_pam_setcred(1); + if (options.use_pam) { + do_pam_session(s->pw->pw_name, s->tty); + do_pam_setcred(1); + } #endif /* Fork the child. */ @@ -753,7 +757,7 @@ do_login(Session *s, const char *command) * If password change is needed, do it now. * This needs to occur before the ~/.hushlogin check. */ - if (is_pam_password_change_required()) { + if (options.use_pam && is_pam_password_change_required()) { print_pam_messages(); do_pam_chauthtok(); } @@ -763,7 +767,7 @@ do_login(Session *s, const char *command) return; #ifdef USE_PAM - if (!is_pam_password_change_required()) + if (options.use_pam && !is_pam_password_change_required()) print_pam_messages(); #endif /* USE_PAM */ #ifdef WITH_AIXAUTHENTICATE @@ -1077,10 +1081,9 @@ do_setup_env(Session *s, const char *shell) * Pull in any environment variables that may have * been set by PAM. */ - { - char **p; + if (options.use_pam) { + char **p = fetch_pam_environment(); - p = fetch_pam_environment(); copy_environment(p, &env, &envsize); free_pam_environment(p); } @@ -1248,7 +1251,8 @@ do_setusercontext(struct passwd *pw) * These will have been wiped by the above initgroups() call. * Reestablish them here. */ - do_pam_setcred(0); + if (options.use_pam) + do_pam_setcred(0); # endif /* USE_PAM */ # if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) irix_setusercontext(pw); diff --git a/sshd.c b/sshd.c index 9e2e218c..cb70fa0c 100644 --- a/sshd.c +++ b/sshd.c @@ -1544,7 +1544,8 @@ main(int ac, char **av) verbose("Closing connection to %.100s", remote_ip); #ifdef USE_PAM - finish_pam(); + if (options.use_pam) + finish_pam(); #endif /* USE_PAM */ packet_close(); diff --git a/sshd_config.5 b/sshd_config.5 index 31ef3996..1278cb61 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -422,12 +422,15 @@ The probability increases linearly and all connection attempts are refused if the number of unauthenticated connections reaches .Dq full (60). -.It Cm PAMAuthenticationViaKbdInt -Specifies whether PAM challenge response authentication is allowed. This -allows the use of most PAM challenge response authentication modules, but -it will allow password authentication regardless of whether -.Cm PasswordAuthentication -is enabled. + +.It Cm UsePAM +Enables PAM authentication (via challenge-response) and session set up. +If you enable this, you should probably disable +.Cm PasswordAuthentication . +If you enable +.CM UsePAM +then you will not be able to run sshd as a non-root user. + .It Cm PasswordAuthentication Specifies whether password authentication is allowed. The default is