- (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@
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
@ -1455,4 +1458,4 @@
save auth method before monitor_reset_key_state(); bugzilla bug #284;
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 "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");

10
auth.c
View File

@ -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,

View File

@ -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
/*

16
auth2.c
View File

@ -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;

View File

@ -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);

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 "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);

View File

@ -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 */

View File

@ -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 *);

View File

@ -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);

3
sshd.c
View File

@ -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();

View File

@ -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