1/* pam_nologin module */ 2 3/* 4 * $Id: pam_nologin.c,v 1.5 2002/03/27 19:20:24 bbraun Exp $ 5 * 6 * Written by Michael K. Johnson <johnsonm@redhat.com> 1996/10/24 7 * 8 * Portions Copyright (C) 2002-2009 Apple Inc. All rights reserved. 9 * 10 * Redistribution and use in source and binary forms of Linux-PAM, with 11 * or without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * 1. Redistributions of source code must retain any existing copyright 15 * notice, and this entire permission notice in its entirety, 16 * including the disclaimer of warranties. 17 * 18 * 2. Redistributions in binary form must reproduce all prior and current 19 * copyright notices, this list of conditions, and the following 20 * disclaimer in the documentation and/or other materials provided 21 * with the distribution. 22 * 23 * 3. The name of any author may not be used to endorse or promote 24 * products derived from this software without their specific prior 25 * written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 28 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 29 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 30 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 31 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 32 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 33 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 34 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 35 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 36 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 37 * DAMAGE. 38 */ 39 40#include <stdio.h> 41#include <stdlib.h> 42#include <unistd.h> 43#include <fcntl.h> 44#include <sys/types.h> 45#include <sys/stat.h> 46#include <sys/syslimits.h> 47#include <pwd.h> 48#include <string.h> 49 50/* 51 * here, we make a definition for the externally accessible function 52 * in this file (this definition is required for static a module 53 * but strongly encouraged generally) it is used to instruct the 54 * modules include file to define the function prototypes. 55 */ 56 57#define PAM_SM_ACCOUNT 58 59#include <security/pam_modules.h> 60#include <security/pam_appl.h> 61 62 63/* --- account management function (only) --- */ 64 65PAM_EXTERN 66int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, 67 const char **argv) 68{ 69 int retval = PAM_SUCCESS; 70 int fd; 71 const char *username; 72 char *mtmp=NULL; 73 struct passwd *user_pwd; 74 struct passwd pwdbuf; 75 char pwbuffer[2 * PATH_MAX]; 76 struct pam_conv *conversation; 77 struct pam_message message; 78 struct pam_message *pmessage = &message; 79 struct pam_response *resp = NULL; 80 struct stat st; 81 82 if ((fd = open("/etc/nologin", O_RDONLY, 0)) >= 0) { 83 /* root can still log in; lusers cannot */ 84 if ((pam_get_user(pamh, &username, NULL) != PAM_SUCCESS) 85 || !username) { 86 openpam_log(PAM_LOG_ERROR, "Failed to obtain the username."); 87 return PAM_SERVICE_ERR; 88 } 89 if (getpwnam_r(username, &pwdbuf, pwbuffer, sizeof(pwbuffer), &user_pwd) != 0) { 90 openpam_log(PAM_LOG_ERROR, "The getpwnam_r call failed."); 91 user_pwd = NULL; 92 } 93 if (user_pwd && user_pwd->pw_uid == 0) { 94 message.msg_style = PAM_TEXT_INFO; 95 } else { 96 if (!user_pwd) { 97 openpam_log(PAM_LOG_ERROR, "The user is invalid."); 98 retval = PAM_USER_UNKNOWN; 99 } else { 100 openpam_log(PAM_LOG_ERROR, "Denying non-root login."); 101 retval = PAM_AUTH_ERR; 102 } 103 message.msg_style = PAM_ERROR_MSG; 104 } 105 106 /* fill in message buffer with contents of /etc/nologin */ 107 if (fstat(fd, &st) < 0) {/* give up trying to display message */ 108 openpam_log(PAM_LOG_DEBUG, "Failure displaying the message."); 109 return retval; 110 } 111 message.msg = mtmp = malloc(st.st_size+1); 112 /* if malloc failed... */ 113 if (!message.msg){ 114 openpam_log(PAM_LOG_DEBUG, "The message is empty."); 115 return retval; 116 } 117 read(fd, mtmp, st.st_size); 118 mtmp[st.st_size] = '\000'; 119 120 /* Use conversation function to give user contents of /etc/nologin */ 121 pam_get_item(pamh, PAM_CONV, (const void **)&conversation); 122 conversation->conv(1, (const struct pam_message **)&pmessage, 123 &resp, conversation->appdata_ptr); 124 free(mtmp); 125 if (NULL != resp && NULL != resp->resp) { 126 memset(resp->resp, 0, strlen(resp->resp)); 127 } 128 } 129 130 return retval; 131} 132 133 134#ifdef PAM_STATIC 135 136/* static module data */ 137 138struct pam_module _pam_nologin_modstruct = { 139 "pam_nologin", 140 pam_sm_authenticate, 141 pam_sm_setcred, 142 NULL, 143 NULL, 144 NULL, 145 NULL, 146}; 147 148#endif 149 150/* end of module definition */ 151