pam_nologin.c revision 1.4
11.4Sthorpej/* $NetBSD: pam_nologin.c,v 1.4 2005/03/31 15:11:54 thorpej 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.4Sthorpej__RCSID("$NetBSD: pam_nologin.c,v 1.4 2005/03/31 15:11:54 thorpej 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.4Sthorpej if (getpwnam_r(user, &pwres, pwbuf, sizeof(pwbuf), &pwd) != 0) { 961.3Smanu return PAM_USER_UNKNOWN; 971.3Smanu } else { 981.3Smanu if (pwd->pw_uid == 0) 991.3Smanu rootlogin = 1; 1001.3Smanu } 1011.3Smanu 1021.1Schristos lc = login_getclass(NULL); 1031.3Smanu ignorenologin = login_getcapbool(lc, "ignorenologin", rootlogin); 1041.1Schristos nologin = login_getcapstr(lc, "nologin", nologin_def, nologin_def); 1051.1Schristos login_close(lc); 1061.1Schristos lc = NULL; 1071.1Schristos 1081.3Smanu if (ignorenologin) 1091.3Smanu return PAM_SUCCESS; 1101.3Smanu 1111.3Smanu if ((fd = open(nologin, O_RDONLY, 0)) == -1) { 1121.3Smanu /* 1131.3Smanu * The file does not exist, login is granted 1141.3Smanu */ 1151.3Smanu if (errno == ENOENT) 1161.3Smanu return PAM_SUCCESS; 1171.3Smanu 1181.3Smanu /* 1191.3Smanu * open failed, but the file exists. This could be 1201.3Smanu * a temporary problem (system resources exausted): 1211.3Smanu * Refuse the login. 1221.3Smanu */ 1231.3Smanu PAM_LOG("Cannot open %s file: %s", nologin, strerror(errno)); 1241.3Smanu return PAM_AUTH_ERR; 1251.1Schristos } 1261.1Schristos 1271.3Smanu PAM_LOG("Opened %s file", nologin); 1281.3Smanu 1291.1Schristos if (fstat(fd, &st) < 0) 1301.3Smanu return PAM_AUTH_ERR; 1311.1Schristos 1321.1Schristos mtmp = malloc(st.st_size + 1); 1331.1Schristos if (mtmp != NULL) { 1341.1Schristos read(fd, mtmp, st.st_size); 1351.1Schristos mtmp[st.st_size] = '\0'; 1361.1Schristos pam_error(pamh, "%s", mtmp, NULL); 1371.1Schristos free(mtmp); 1381.1Schristos } 1391.1Schristos 1401.3Smanu PAM_VERBOSE_ERROR("Administrator refusing you: %s", nologin); 1411.1Schristos 1421.3Smanu return PAM_AUTH_ERR; 1431.1Schristos} 1441.1Schristos 1451.1SchristosPAM_EXTERN int 1461.1Schristospam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, 1471.1Schristos int argc __unused, const char *argv[] __unused) 1481.1Schristos{ 1491.1Schristos 1501.1Schristos return (PAM_SUCCESS); 1511.1Schristos} 1521.1Schristos 1531.1SchristosPAM_MODULE_ENTRY("pam_nologin"); 154