From owner-freebsd-bugs@FreeBSD.ORG Tue Jun 5 10:10:15 2007 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 72A3116A46B for ; Tue, 5 Jun 2007 10:10:15 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.freebsd.org (Postfix) with ESMTP id 563A213C447 for ; Tue, 5 Jun 2007 10:10:15 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id l55AAEe2002410 for ; Tue, 5 Jun 2007 10:10:15 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id l55AAE76002409; Tue, 5 Jun 2007 10:10:14 GMT (envelope-from gnats) Date: Tue, 5 Jun 2007 10:10:14 GMT Message-Id: <200706051010.l55AAE76002409@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org From: Yar Tikhiy Cc: Subject: Re: bin/112574: sshd(8) ignores nologin(5) if using PAM and public key X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Yar Tikhiy List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Jun 2007 10:10:15 -0000 The following reply was made to PR bin/112574; it has been noted by GNATS. From: Yar Tikhiy To: des@freebsd.org Cc: bug-followup@freebsd.org Subject: Re: bin/112574: sshd(8) ignores nologin(5) if using PAM and public key Date: Tue, 5 Jun 2007 14:03:08 +0400 Hi Dag-Erling, What do you think about the following patch for pam_nologin? It addresses two problems described in PR bin/107612 and PR bin/112574. First, it adds full support for login.conf(5) so that "nologin" and "ignorenologin" capabilities are respected for the current user. Second, it adds an account management function identical to the authentication one so that pam_nologin can always work for sshd. Besides, it adds more error checking to pam_nologin. By adding account management function to pam_nologin, it also opens pam_nologin for use in services that do implicit authentication, such as cron and atrun. Thanks! -- Yar --- //depot/vendor/freebsd/src/lib/libpam/modules/pam_nologin/pam_nologin.8 2001/08/26 18:40:31 +++ //depot/user/yar/hack/lib/libpam/modules/pam_nologin/pam_nologin.8 2007/05/23 10:30:24 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD: src/lib/libpam/modules/pam_nologin/pam_nologin.8,v 1.5 2001/08/26 18:05:35 markm Exp $ .\" -.Dd July 8, 2001 +.Dd May 23, 2007 .Dt PAM_NOLOGIN 8 .Os .Sh NAME @@ -39,34 +39,37 @@ .Sh DESCRIPTION The NoLogin authentication service module for PAM, .Nm -provides functionality for only one PAM category: -authentication. +provides the same functionality for two PAM categories: +authentication and account management. In terms of the .Ar module-type -parameter, this is the +parameter, those are the .Dq Li auth -feature. +and +.Dq Li account +features. It also provides a null function for session management. .Ss NoLogin Authentication Module -The NoLogin authentication component -.Pq Fn pam_sm_authenticate , -always returns success for the superuser, -and returns success for all other users -if the file -.Pa /var/run/nologin -does not exist. -If -.Pa /var/run/nologin -does exist, -then its contents are echoed -to non-superusers +The NoLogin authentication component, +.Fn pam_sm_authenticate , +verifies whether logins are administratively disabled via +.Xr nologin 5 . +It returns success if the user's login class has an "ignorenologin" +capability specified in +.Xr login.conf 5 +or the +.Xr nologin 5 +file does not exist. +If neither condition is met, +then the contents of +.Xr nologin 5 +are echoed before failure is returned. -If a "nologin" capability -is specified in +The location of +.Xr nologin 5 +is specified by a "nologin" capability in .Xr login.conf 5 , -then the file thus specified -is used instead. -This usually defaults to +which defaults to .Pa /var/run/nologin . .Pp The following options may be passed to the authentication module: @@ -82,6 +85,13 @@ reasons why the user's authentication attempt was declined. .El +.Ss NoLogin Account Management Module +The NoLogin account management component, +.Fn pam_sm_acct_mgmt , +returns the same value as the NoLogin authentication component +would return. +This component can be used to provide the NoLogin functionality +to services that skip PAM authentication. .Sh SEE ALSO .Xr syslog 3 , .Xr login.conf 5 , --- //depot/vendor/freebsd/src/lib/libpam/modules/pam_nologin/pam_nologin.c 2006/03/20 17:37:22 +++ //depot/user/yar/hack/lib/libpam/modules/pam_nologin/pam_nologin.c 2007/05/23 10:28:55 @@ -47,23 +47,24 @@ #include #define PAM_SM_AUTH +#define PAM_SM_ACCOUNT #include #include #include -#define NOLOGIN "/var/run/nologin" +#define _PATH_NOLOGIN "/var/run/nologin" -static char nologin_def[] = NOLOGIN; +static char nologin_def[] = _PATH_NOLOGIN; -PAM_EXTERN int -pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, - int argc __unused, const char *argv[] __unused) +static int +pam_nologin_check(pam_handle_t *pamh, int flags) { login_cap_t *lc; struct passwd *pwd; struct stat st; int retval, fd; + ssize_t ss; const char *user, *nologin; char *mtmp; @@ -73,42 +74,70 @@ PAM_LOG("Got user: %s", user); - lc = login_getclass(NULL); + pwd = getpwnam(user); + if (pwd == NULL) + return (PAM_USER_UNKNOWN); + + /* + * login_getpwclass(3) will select the "root" class by default + * if pwd->pw_uid is 0. That class should have "ignorenologin" + * capability so that super-user can bypass nologin. + */ + lc = login_getpwclass(pwd); + if (lc == NULL) { + PAM_LOG("Unable to get login class for user %s", user); + return (PAM_SERVICE_ERR); + } + + if (login_getcapbool(lc, "ignorenologin", 0)) { + login_close(lc); + return (PAM_SUCCESS); + } + nologin = login_getcapstr(lc, "nologin", nologin_def, nologin_def); - login_close(lc); - lc = NULL; fd = open(nologin, O_RDONLY, 0); - if (fd < 0) + if (fd < 0) { + login_close(lc); return (PAM_SUCCESS); + } - PAM_LOG("Opened %s file", NOLOGIN); + PAM_LOG("Opened %s file", nologin); - pwd = getpwnam(user); - if (pwd && pwd->pw_uid == 0) - retval = PAM_SUCCESS; - else { - if (!pwd) - retval = PAM_USER_UNKNOWN; - else - retval = PAM_AUTH_ERR; + if (fstat(fd, &st) == 0) { + mtmp = malloc(st.st_size + 1); + if (mtmp != NULL) { + ss = read(fd, mtmp, st.st_size); + if (ss > 0) { + mtmp[ss] = '\0'; + pam_error(pamh, "%s", mtmp); + } + free(mtmp); + } } - if (fstat(fd, &st) < 0) - return (retval); + PAM_VERBOSE_ERROR("Administrator refusing you: %s", nologin); + + close(fd); + login_close(lc); + + return (PAM_AUTH_ERR); +} + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh, int flags, + int argc __unused, const char *argv[] __unused) +{ - mtmp = malloc(st.st_size + 1); - if (mtmp != NULL) { - read(fd, mtmp, st.st_size); - mtmp[st.st_size] = '\0'; - pam_error(pamh, "%s", mtmp); - free(mtmp); - } + return (pam_nologin_check(pamh, flags)); +} - if (retval != PAM_SUCCESS) - PAM_VERBOSE_ERROR("Administrator refusing you: %s", NOLOGIN); +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, + int argc __unused, const char *argv[] __unused) +{ - return (retval); + return (pam_nologin_check(pamh, flags)); } PAM_EXTERN int --- //depot/vendor/freebsd/src/etc/pam.d/sshd 2003/04/30 22:38:07 +++ //depot/user/yar/hack/etc/pam.d/sshd 2007/05/23 10:35:59 @@ -13,6 +13,7 @@ auth required pam_unix.so no_warn try_first_pass # account +account required pam_nologin.so #account required pam_krb5.so account required pam_login_access.so account required pam_unix.so