- (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
This commit is contained in:
Damien Miller 2003-05-14 15:11:48 +10:00
parent 9c617693c2
commit 4e448a31ae
12 changed files with 70 additions and 54 deletions

View File

@ -68,6 +68,9 @@
implement kerberos over ssh2 ("kerberos-2@ssh.com"); tested with jakob@ implement kerberos over ssh2 ("kerberos-2@ssh.com"); tested with jakob@
server interops with commercial client; ok jakob@ djm@ server interops with commercial client; ok jakob@ djm@
- (djm) Make portable build with MIT krb5 (some issues remain) - (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 20030512
- (djm) Redhat spec: Don't install profile.d scripts when not - (djm) Redhat spec: Don't install profile.d scripts when not
@ -1455,4 +1458,4 @@
save auth method before monitor_reset_key_state(); bugzilla bug #284; save auth method before monitor_reset_key_state(); bugzilla bug #284;
ok provos@ ok provos@
$Id: ChangeLog,v 1.2693 2003/05/14 04:31:11 djm Exp $ $Id: ChangeLog,v 1.2694 2003/05/14 05:11:48 djm Exp $

View File

@ -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 "ssh2.h"
#include "xmalloc.h" #include "xmalloc.h"
extern ServerOptions options;
#define __unused #define __unused
#ifdef USE_POSIX_THREADS #ifdef USE_POSIX_THREADS
@ -276,7 +278,6 @@ sshpam_cleanup(void *arg)
static int static int
sshpam_init(const char *user) sshpam_init(const char *user)
{ {
extern ServerOptions options;
extern u_int utmp_len; extern u_int utmp_len;
const char *pam_rhost, *pam_user; const char *pam_rhost, *pam_user;
@ -313,6 +314,10 @@ sshpam_init_ctx(Authctxt *authctxt)
struct pam_ctxt *ctxt; struct pam_ctxt *ctxt;
int socks[2]; int socks[2];
/* Refuse to start if we don't have PAM enabled */
if (!options.use_pam)
return NULL;
/* Initialize PAM */ /* Initialize PAM */
if (sshpam_init(authctxt->user) == -1) { if (sshpam_init(authctxt->user) == -1) {
error("PAM: initialization failed"); error("PAM: initialization failed");

10
auth.c
View File

@ -78,8 +78,8 @@ allowed_user(struct passwd * pw)
#ifdef WITH_AIXAUTHENTICATE #ifdef WITH_AIXAUTHENTICATE
char *loginmsg; char *loginmsg;
#endif /* WITH_AIXAUTHENTICATE */ #endif /* WITH_AIXAUTHENTICATE */
#if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \ #if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) && \
!defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE) defined(HAS_SHADOW_EXPIRE)
struct spwd *spw; struct spwd *spw;
time_t today; time_t today;
#endif #endif
@ -88,10 +88,10 @@ allowed_user(struct passwd * pw)
if (!pw || !pw->pw_name) if (!pw || !pw->pw_name)
return 0; return 0;
#if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \ #if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) && \
!defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE) defined(HAS_SHADOW_EXPIRE)
#define DAY (24L * 60 * 60) /* 1 day in seconds */ #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; today = time(NULL) / DAY;
debug3("allowed_user: today %d sp_expire %d sp_lstchg %d" debug3("allowed_user: today %d sp_expire %d sp_lstchg %d"
" sp_max %d", (int)today, (int)spw->sp_expire, " sp_max %d", (int)today, (int)spw->sp_expire,

View File

@ -342,11 +342,6 @@ do_authloop(Authctxt *authctxt)
!auth_root_allowed(get_authname(type))) !auth_root_allowed(get_authname(type)))
authenticated = 0; authenticated = 0;
#endif #endif
#ifdef USE_PAM
if (!use_privsep && authenticated &&
!do_pam_account(pw->pw_name, client_user))
authenticated = 0;
#endif
/* Log before sending the reply */ /* Log before sending the reply */
auth_log(authctxt, authenticated, get_authname(type), info); auth_log(authctxt, authenticated, get_authname(type), info);
@ -413,7 +408,8 @@ do_authentication(void)
use_privsep ? " [net]" : ""); use_privsep ? " [net]" : "");
#ifdef USE_PAM #ifdef USE_PAM
PRIVSEP(start_pam(user)); if (options.use_pam)
PRIVSEP(start_pam(user));
#endif #endif
/* /*

16
auth2.c
View File

@ -91,10 +91,6 @@ do_authentication2(void)
/* challenge-response is implemented via keyboard interactive */ /* challenge-response is implemented via keyboard interactive */
if (options.challenge_response_authentication) if (options.challenge_response_authentication)
options.kbd_interactive_authentication = 1; 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_init(&dispatch_protocol_error);
dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); 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; authctxt->valid = 1;
debug2("input_userauth_request: setting up authctxt for %s", user); debug2("input_userauth_request: setting up authctxt for %s", user);
#ifdef USE_PAM #ifdef USE_PAM
PRIVSEP(start_pam(authctxt->pw->pw_name)); if (options.use_pam)
PRIVSEP(start_pam(authctxt->pw->pw_name));
#endif #endif
} else { } else {
logit("input_userauth_request: illegal user %s", user); logit("input_userauth_request: illegal user %s", user);
#ifdef USE_PAM #ifdef USE_PAM
PRIVSEP(start_pam(user)); if (options.use_pam)
PRIVSEP(start_pam(user));
#endif #endif
} }
setproctitle("%s%s", authctxt->pw ? user : "unknown", setproctitle("%s%s", authctxt->pw ? user : "unknown",
@ -215,12 +213,6 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
!auth_root_allowed(method)) !auth_root_allowed(method))
authenticated = 0; authenticated = 0;
#ifdef USE_PAM
if (!use_privsep && authenticated && authctxt->user &&
!do_pam_account(authctxt->user, NULL))
authenticated = 0;
#endif /* USE_PAM */
#ifdef _UNICOS #ifdef _UNICOS
if (authenticated && cray_access_denied(authctxt->user)) { if (authenticated && cray_access_denied(authctxt->user)) {
authenticated = 0; authenticated = 0;

View File

@ -567,7 +567,8 @@ mm_answer_pwnamallow(int socket, Buffer *m)
} }
#ifdef USE_PAM #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 #endif
return (0); return (0);
@ -750,6 +751,9 @@ mm_answer_pam_start(int socket, Buffer *m)
{ {
char *user; char *user;
if (!options.use_pam)
fatal("UsePAM not set, but ended up in %s anyway", __func__);
user = buffer_get_string(m, NULL); user = buffer_get_string(m, NULL);
start_pam(user); start_pam(user);

View File

@ -47,6 +47,7 @@ RCSID("$OpenBSD: monitor_wrap.c,v 1.26 2003/04/07 08:29:57 markus Exp $");
#include "atomicio.h" #include "atomicio.h"
#include "monitor_fdpass.h" #include "monitor_fdpass.h"
#include "getput.h" #include "getput.h"
#include "servconf.h"
#include "auth.h" #include "auth.h"
#include "channels.h" #include "channels.h"
@ -59,6 +60,7 @@ extern z_stream incoming_stream;
extern z_stream outgoing_stream; extern z_stream outgoing_stream;
extern struct monitor *pmonitor; extern struct monitor *pmonitor;
extern Buffer input, output; extern Buffer input, output;
extern ServerOptions options;
void void
mm_request_send(int socket, enum monitor_reqtype type, Buffer *m) mm_request_send(int socket, enum monitor_reqtype type, Buffer *m)
@ -669,6 +671,8 @@ mm_start_pam(char *user)
Buffer m; Buffer m;
debug3("%s entering", __func__); debug3("%s entering", __func__);
if (!options.use_pam)
fatal("UsePAM=no, but ended up in %s anyway", __func__);
buffer_init(&m); buffer_init(&m);
buffer_put_cstring(&m, user); buffer_put_cstring(&m, user);

View File

@ -59,8 +59,10 @@ initialize_server_options(ServerOptions *options)
{ {
memset(options, 0, sizeof(*options)); memset(options, 0, sizeof(*options));
#ifdef USE_PAM
/* Portable-specific options */ /* Portable-specific options */
options->pam_authentication_via_kbd_int = -1; options->use_pam = -1;
#endif
/* Standard Options */ /* Standard Options */
options->num_ports = 0; options->num_ports = 0;
@ -136,8 +138,10 @@ void
fill_default_server_options(ServerOptions *options) fill_default_server_options(ServerOptions *options)
{ {
/* Portable-specific options */ /* Portable-specific options */
if (options->pam_authentication_via_kbd_int == -1) #ifdef USE_PAM
options->pam_authentication_via_kbd_int = 0; if (options->use_pam == -1)
options->use_pam = 1;
#endif
/* Standard Options */ /* Standard Options */
if (options->protocol == SSH_PROTO_UNKNOWN) if (options->protocol == SSH_PROTO_UNKNOWN)
@ -279,7 +283,7 @@ fill_default_server_options(ServerOptions *options)
typedef enum { typedef enum {
sBadOption, /* == unknown option */ sBadOption, /* == unknown option */
/* Portable-specific options */ /* Portable-specific options */
sPAMAuthenticationViaKbdInt, sUsePAM,
/* Standard Options */ /* Standard Options */
sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
sPermitRootLogin, sLogFacility, sLogLevel, sPermitRootLogin, sLogFacility, sLogLevel,
@ -315,7 +319,7 @@ static struct {
ServerOpCodes opcode; ServerOpCodes opcode;
} keywords[] = { } keywords[] = {
/* Portable-specific options */ /* Portable-specific options */
{ "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt }, { "UsePAM", sUsePAM },
/* Standard Options */ /* Standard Options */
{ "port", sPort }, { "port", sPort },
{ "hostkey", sHostKeyFile }, { "hostkey", sHostKeyFile },
@ -462,8 +466,8 @@ process_server_config_line(ServerOptions *options, char *line,
opcode = parse_token(arg, filename, linenum); opcode = parse_token(arg, filename, linenum);
switch (opcode) { switch (opcode) {
/* Portable-specific options */ /* Portable-specific options */
case sPAMAuthenticationViaKbdInt: case sUsePAM:
intptr = &options->pam_authentication_via_kbd_int; intptr = &options->use_pam;
goto parse_flag; goto parse_flag;
/* Standard Options */ /* Standard Options */

View File

@ -131,7 +131,7 @@ typedef struct {
char *authorized_keys_file; /* File containing public keys */ char *authorized_keys_file; /* File containing public keys */
char *authorized_keys_file2; char *authorized_keys_file2;
int pam_authentication_via_kbd_int; int use_pam; /* Enable auth via PAM */
} ServerOptions; } ServerOptions;
void initialize_server_options(ServerOptions *); void initialize_server_options(ServerOptions *);

View File

@ -456,11 +456,13 @@ do_exec_no_pty(Session *s, const char *command)
session_proctitle(s); session_proctitle(s);
#if defined(USE_PAM) #if defined(USE_PAM)
do_pam_session(s->pw->pw_name, NULL); if (options.use_pam) {
do_pam_setcred(1); do_pam_session(s->pw->pw_name, NULL);
if (is_pam_password_change_required()) do_pam_setcred(1);
packet_disconnect("Password change required but no " if (is_pam_password_change_required())
"TTY available"); packet_disconnect("Password change required but no "
"TTY available");
}
#endif /* USE_PAM */ #endif /* USE_PAM */
/* Fork the child. */ /* Fork the child. */
@ -583,8 +585,10 @@ do_exec_pty(Session *s, const char *command)
ttyfd = s->ttyfd; ttyfd = s->ttyfd;
#if defined(USE_PAM) #if defined(USE_PAM)
do_pam_session(s->pw->pw_name, s->tty); if (options.use_pam) {
do_pam_setcred(1); do_pam_session(s->pw->pw_name, s->tty);
do_pam_setcred(1);
}
#endif #endif
/* Fork the child. */ /* Fork the child. */
@ -753,7 +757,7 @@ do_login(Session *s, const char *command)
* If password change is needed, do it now. * If password change is needed, do it now.
* This needs to occur before the ~/.hushlogin check. * 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(); print_pam_messages();
do_pam_chauthtok(); do_pam_chauthtok();
} }
@ -763,7 +767,7 @@ do_login(Session *s, const char *command)
return; return;
#ifdef USE_PAM #ifdef USE_PAM
if (!is_pam_password_change_required()) if (options.use_pam && !is_pam_password_change_required())
print_pam_messages(); print_pam_messages();
#endif /* USE_PAM */ #endif /* USE_PAM */
#ifdef WITH_AIXAUTHENTICATE #ifdef WITH_AIXAUTHENTICATE
@ -1077,10 +1081,9 @@ do_setup_env(Session *s, const char *shell)
* Pull in any environment variables that may have * Pull in any environment variables that may have
* been set by PAM. * been set by PAM.
*/ */
{ if (options.use_pam) {
char **p; char **p = fetch_pam_environment();
p = fetch_pam_environment();
copy_environment(p, &env, &envsize); copy_environment(p, &env, &envsize);
free_pam_environment(p); free_pam_environment(p);
} }
@ -1248,7 +1251,8 @@ do_setusercontext(struct passwd *pw)
* These will have been wiped by the above initgroups() call. * These will have been wiped by the above initgroups() call.
* Reestablish them here. * Reestablish them here.
*/ */
do_pam_setcred(0); if (options.use_pam)
do_pam_setcred(0);
# endif /* USE_PAM */ # endif /* USE_PAM */
# if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) # if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
irix_setusercontext(pw); irix_setusercontext(pw);

3
sshd.c
View File

@ -1544,7 +1544,8 @@ main(int ac, char **av)
verbose("Closing connection to %.100s", remote_ip); verbose("Closing connection to %.100s", remote_ip);
#ifdef USE_PAM #ifdef USE_PAM
finish_pam(); if (options.use_pam)
finish_pam();
#endif /* USE_PAM */ #endif /* USE_PAM */
packet_close(); packet_close();

View File

@ -422,12 +422,15 @@ The probability increases linearly and all connection attempts
are refused if the number of unauthenticated connections reaches are refused if the number of unauthenticated connections reaches
.Dq full .Dq full
(60). (60).
.It Cm PAMAuthenticationViaKbdInt
Specifies whether PAM challenge response authentication is allowed. This .It Cm UsePAM
allows the use of most PAM challenge response authentication modules, but Enables PAM authentication (via challenge-response) and session set up.
it will allow password authentication regardless of whether If you enable this, you should probably disable
.Cm PasswordAuthentication .Cm PasswordAuthentication .
is enabled. If you enable
.CM UsePAM
then you will not be able to run sshd as a non-root user.
.It Cm PasswordAuthentication .It Cm PasswordAuthentication
Specifies whether password authentication is allowed. Specifies whether password authentication is allowed.
The default is The default is