MFC:
Use the current user's login class for the decisions about where the nologin(5) file is located and whether the user may bypass its restriction. Add some error checks. Revision Changes Path 1.7 +16 -15 src/lib/libpam/modules/pam_nologin/pam_nologin.8 1.13 +42 -29 src/lib/libpam/modules/pam_nologin/pam_nologin.c Note: To avoid POLA violation, the merged module still lets root in irrespective of login.conf settings. In HEAD, root has to have an explicit "ignorenologin" capability to bypass nologin(5). PR: bin/107612
This commit is contained in:
parent
f510b9f527
commit
fa260264c0
@ -50,23 +50,24 @@ 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
|
||||
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:
|
||||
|
@ -52,9 +52,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <security/pam_modules.h>
|
||||
#include <security/pam_mod_misc.h>
|
||||
|
||||
#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,
|
||||
@ -64,6 +64,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags __unused,
|
||||
struct passwd *pwd;
|
||||
struct stat st;
|
||||
int retval, fd;
|
||||
ssize_t ss;
|
||||
const char *user, *nologin;
|
||||
char *mtmp;
|
||||
|
||||
@ -73,42 +74,60 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags __unused,
|
||||
|
||||
PAM_LOG("Got user: %s", user);
|
||||
|
||||
lc = login_getclass(NULL);
|
||||
nologin = login_getcapstr(lc, "nologin", nologin_def, nologin_def);
|
||||
login_close(lc);
|
||||
lc = NULL;
|
||||
pwd = getpwnam(user);
|
||||
if (pwd == NULL)
|
||||
return (PAM_USER_UNKNOWN);
|
||||
|
||||
fd = open(nologin, O_RDONLY, 0);
|
||||
if (fd < 0)
|
||||
/*
|
||||
* Old bug compatibility in RELENG_6: always let root in.
|
||||
*/
|
||||
if (pwd->pw_uid == 0)
|
||||
return (PAM_SUCCESS);
|
||||
|
||||
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;
|
||||
/*
|
||||
* 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 (fstat(fd, &st) < 0)
|
||||
return (retval);
|
||||
|
||||
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, NULL);
|
||||
free(mtmp);
|
||||
if (login_getcapbool(lc, "ignorenologin", 0)) {
|
||||
login_close(lc);
|
||||
return (PAM_SUCCESS);
|
||||
}
|
||||
|
||||
if (retval != PAM_SUCCESS)
|
||||
PAM_VERBOSE_ERROR("Administrator refusing you: %s", NOLOGIN);
|
||||
nologin = login_getcapstr(lc, "nologin", nologin_def, nologin_def);
|
||||
|
||||
return (retval);
|
||||
fd = open(nologin, O_RDONLY, 0);
|
||||
if (fd < 0) {
|
||||
login_close(lc);
|
||||
return (PAM_SUCCESS);
|
||||
}
|
||||
|
||||
PAM_LOG("Opened %s file", nologin);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
PAM_VERBOSE_ERROR("Administrator refusing you: %s", nologin);
|
||||
|
||||
close(fd);
|
||||
login_close(lc);
|
||||
|
||||
return (PAM_AUTH_ERR);
|
||||
}
|
||||
|
||||
PAM_EXTERN int
|
||||
|
Loading…
x
Reference in New Issue
Block a user