pam_nologin.c revision 1.9
11.9Schristos/* $NetBSD: pam_nologin.c,v 1.9 2013/06/20 20:54:52 christos Exp $ */ 21.2Schristos 31.1Schristos/*- 41.1Schristos * Copyright 2001 Mark R V Murray 51.1Schristos * All rights reserved. 61.1Schristos * Copyright (c) 2001 Networks Associates Technology, Inc. 71.1Schristos * All rights reserved. 81.1Schristos * 91.1Schristos * Portions of this software were developed for the FreeBSD Project by 101.1Schristos * ThinkSec AS and NAI Labs, the Security Research Division of Network 111.1Schristos * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 121.1Schristos * ("CBOSS"), as part of the DARPA CHATS research program. 131.1Schristos * 141.1Schristos * Redistribution and use in source and binary forms, with or without 151.1Schristos * modification, are permitted provided that the following conditions 161.1Schristos * are met: 171.1Schristos * 1. Redistributions of source code must retain the above copyright 181.1Schristos * notice, this list of conditions and the following disclaimer. 191.1Schristos * 2. Redistributions in binary form must reproduce the above copyright 201.1Schristos * notice, this list of conditions and the following disclaimer in the 211.1Schristos * documentation and/or other materials provided with the distribution. 221.1Schristos * 3. The name of the author may not be used to endorse or promote 231.1Schristos * products derived from this software without specific prior written 241.1Schristos * permission. 251.1Schristos * 261.1Schristos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 271.1Schristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 281.1Schristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 291.1Schristos * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 301.1Schristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 311.1Schristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 321.1Schristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 331.1Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 341.1Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 351.1Schristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 361.1Schristos * SUCH DAMAGE. 371.1Schristos */ 381.1Schristos 391.1Schristos#include <sys/cdefs.h> 401.2Schristos#ifdef __FreeBSD__ 411.1Schristos__FBSDID("$FreeBSD: src/lib/libpam/modules/pam_nologin/pam_nologin.c,v 1.10 2002/04/12 22:27:21 des Exp $"); 421.2Schristos#else 431.9Schristos__RCSID("$NetBSD: pam_nologin.c,v 1.9 2013/06/20 20:54:52 christos Exp $"); 441.2Schristos#endif 451.2Schristos 461.1Schristos 471.1Schristos#include <sys/types.h> 481.1Schristos#include <sys/stat.h> 491.1Schristos#include <fcntl.h> 501.1Schristos#include <login_cap.h> 511.1Schristos#include <pwd.h> 521.3Smanu#include <errno.h> 531.3Smanu#include <string.h> 541.1Schristos#include <stdio.h> 551.1Schristos#include <stdlib.h> 561.1Schristos#include <unistd.h> 571.1Schristos 581.1Schristos#define PAM_SM_AUTH 591.1Schristos 601.1Schristos#include <security/pam_appl.h> 611.1Schristos#include <security/pam_modules.h> 621.1Schristos#include <security/pam_mod_misc.h> 631.1Schristos 641.3Smanu#define NOLOGIN "/etc/nologin" 651.1Schristos 661.1Schristosstatic char nologin_def[] = NOLOGIN; 671.1Schristos 681.1SchristosPAM_EXTERN int 691.1Schristospam_sm_authenticate(pam_handle_t *pamh, int flags __unused, 701.1Schristos int argc __unused, const char *argv[] __unused) 711.1Schristos{ 721.1Schristos login_cap_t *lc; 731.4Sthorpej struct passwd *pwd, pwres; 741.1Schristos struct stat st; 751.1Schristos int retval, fd; 761.3Smanu int ignorenologin = 0; 771.3Smanu int rootlogin = 0; 781.1Schristos const char *user, *nologin; 791.1Schristos char *mtmp; 801.4Sthorpej char pwbuf[1024]; 811.1Schristos 821.3Smanu if ((retval = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) 831.3Smanu return retval; 841.1Schristos 851.1Schristos PAM_LOG("Got user: %s", user); 861.1Schristos 871.3Smanu /* 881.3Smanu * For root, the default is to ignore nologin, but the 891.3Smanu * ignorenologin capability can override this, so we 901.3Smanu * set the default appropriately. 911.3Smanu * 921.3Smanu * Do not allow login of unexisting users, so that a directory 931.3Smanu * failure will not cause the nologin capability to be ignored. 941.3Smanu */ 951.5Schristos if (getpwnam_r(user, &pwres, pwbuf, sizeof(pwbuf), &pwd) != 0 || 961.5Schristos pwd == NULL) { 971.3Smanu return PAM_USER_UNKNOWN; 981.3Smanu } else { 991.3Smanu if (pwd->pw_uid == 0) 1001.3Smanu rootlogin = 1; 1011.3Smanu } 1021.3Smanu 1031.9Schristos lc = login_getpwclass(pwd); 1041.3Smanu ignorenologin = login_getcapbool(lc, "ignorenologin", rootlogin); 1051.1Schristos nologin = login_getcapstr(lc, "nologin", nologin_def, nologin_def); 1061.1Schristos login_close(lc); 1071.1Schristos lc = NULL; 1081.1Schristos 1091.3Smanu if (ignorenologin) 1101.3Smanu return PAM_SUCCESS; 1111.3Smanu 1121.3Smanu if ((fd = open(nologin, O_RDONLY, 0)) == -1) { 1131.3Smanu /* 1141.3Smanu * The file does not exist, login is granted 1151.3Smanu */ 1161.3Smanu if (errno == ENOENT) 1171.3Smanu return PAM_SUCCESS; 1181.3Smanu 1191.3Smanu /* 1201.3Smanu * open failed, but the file exists. This could be 1211.3Smanu * a temporary problem (system resources exausted): 1221.3Smanu * Refuse the login. 1231.3Smanu */ 1241.3Smanu PAM_LOG("Cannot open %s file: %s", nologin, strerror(errno)); 1251.3Smanu return PAM_AUTH_ERR; 1261.1Schristos } 1271.1Schristos 1281.3Smanu PAM_LOG("Opened %s file", nologin); 1291.3Smanu 1301.8Swiz if (fstat(fd, &st) < 0) { 1311.8Swiz close(fd); 1321.3Smanu return PAM_AUTH_ERR; 1331.8Swiz } 1341.1Schristos 1351.1Schristos mtmp = malloc(st.st_size + 1); 1361.1Schristos if (mtmp != NULL) { 1371.1Schristos read(fd, mtmp, st.st_size); 1381.1Schristos mtmp[st.st_size] = '\0'; 1391.7Schristos pam_error(pamh, "%s", mtmp); 1401.1Schristos free(mtmp); 1411.1Schristos } 1421.8Swiz close(fd); 1431.1Schristos 1441.3Smanu PAM_VERBOSE_ERROR("Administrator refusing you: %s", nologin); 1451.1Schristos 1461.3Smanu return PAM_AUTH_ERR; 1471.1Schristos} 1481.1Schristos 1491.1SchristosPAM_EXTERN int 1501.1Schristospam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, 1511.1Schristos int argc __unused, const char *argv[] __unused) 1521.1Schristos{ 1531.1Schristos 1541.1Schristos return (PAM_SUCCESS); 1551.1Schristos} 1561.1Schristos 1571.1SchristosPAM_MODULE_ENTRY("pam_nologin"); 158