116e058b5SDag-Erling Smørgrav /*- 2*8a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 3*8a16b7a1SPedro F. Giffuni * 416e058b5SDag-Erling Smørgrav * Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994 516e058b5SDag-Erling Smørgrav * The Regents of the University of California. All rights reserved. 616e058b5SDag-Erling Smørgrav * Copyright (c) 2001 Mark R V Murray 716e058b5SDag-Erling Smørgrav * All rights reserved. 8f03a4b81SDag-Erling Smørgrav * Copyright (c) 2001 Networks Associates Technology, Inc. 916e058b5SDag-Erling Smørgrav * All rights reserved. 103a59e89eSDag-Erling Smørgrav * Copyright (c) 2004 Joe R. Doupnik 113a59e89eSDag-Erling Smørgrav * All rights reserved. 1216e058b5SDag-Erling Smørgrav * 1316e058b5SDag-Erling Smørgrav * Portions of this software were developed for the FreeBSD Project by 1416e058b5SDag-Erling Smørgrav * ThinkSec AS and NAI Labs, the Security Research Division of Network 1516e058b5SDag-Erling Smørgrav * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 1616e058b5SDag-Erling Smørgrav * ("CBOSS"), as part of the DARPA CHATS research program. 1716e058b5SDag-Erling Smørgrav * 1816e058b5SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 1916e058b5SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 2016e058b5SDag-Erling Smørgrav * are met: 2116e058b5SDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright 2216e058b5SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer. 2316e058b5SDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright 2416e058b5SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the 2516e058b5SDag-Erling Smørgrav * documentation and/or other materials provided with the distribution. 2616e058b5SDag-Erling Smørgrav * 3. The name of the author may not be used to endorse or promote 2716e058b5SDag-Erling Smørgrav * products derived from this software without specific prior written 2816e058b5SDag-Erling Smørgrav * permission. 2916e058b5SDag-Erling Smørgrav * 4. Neither the name of the University nor the names of its contributors 3016e058b5SDag-Erling Smørgrav * may be used to endorse or promote products derived from this software 3116e058b5SDag-Erling Smørgrav * without specific prior written permission. 3216e058b5SDag-Erling Smørgrav * 3316e058b5SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 3416e058b5SDag-Erling Smørgrav * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 3516e058b5SDag-Erling Smørgrav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3616e058b5SDag-Erling Smørgrav * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 3716e058b5SDag-Erling Smørgrav * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3816e058b5SDag-Erling Smørgrav * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3916e058b5SDag-Erling Smørgrav * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4016e058b5SDag-Erling Smørgrav * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4116e058b5SDag-Erling Smørgrav * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 4216e058b5SDag-Erling Smørgrav * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 4316e058b5SDag-Erling Smørgrav * SUCH DAMAGE. 4416e058b5SDag-Erling Smørgrav */ 4516e058b5SDag-Erling Smørgrav 4616e058b5SDag-Erling Smørgrav #include <sys/cdefs.h> 4716e058b5SDag-Erling Smørgrav __FBSDID("$FreeBSD$"); 4816e058b5SDag-Erling Smørgrav 4916e058b5SDag-Erling Smørgrav #define _BSD_SOURCE 5016e058b5SDag-Erling Smørgrav 51d1b8647fSEd Schouten #include <sys/time.h> 52f1b61fc8SEd Schouten 53f1b61fc8SEd Schouten #include <paths.h> 54d1b8647fSEd Schouten #include <stdlib.h> 55d1b8647fSEd Schouten #include <string.h> 5616e058b5SDag-Erling Smørgrav #include <time.h> 57d1b8647fSEd Schouten #include <unistd.h> 5829572408SEd Schouten #include <utmpx.h> 5916e058b5SDag-Erling Smørgrav 6016e058b5SDag-Erling Smørgrav #define PAM_SM_SESSION 6116e058b5SDag-Erling Smørgrav 628c66575dSDag-Erling Smørgrav #include <security/pam_appl.h> 6316e058b5SDag-Erling Smørgrav #include <security/pam_modules.h> 648c66575dSDag-Erling Smørgrav #include <security/pam_mod_misc.h> 6516e058b5SDag-Erling Smørgrav 66d1b8647fSEd Schouten #define PAM_UTMPX_ID "utmpx_id" 67d1b8647fSEd Schouten 6816e058b5SDag-Erling Smørgrav PAM_EXTERN int 6924fe7ba0SDag-Erling Smørgrav pam_sm_open_session(pam_handle_t *pamh, int flags, 7024fe7ba0SDag-Erling Smørgrav int argc __unused, const char *argv[] __unused) 7116e058b5SDag-Erling Smørgrav { 72d1b8647fSEd Schouten struct utmpx *utx, utl; 736ceeb690SPeter Wemm time_t t; 7491e93869SDag-Erling Smørgrav const char *user; 7591e93869SDag-Erling Smørgrav const void *rhost, *tty; 76d1b8647fSEd Schouten char *id; 7717c79ad0SEd Schouten int pam_err; 7816e058b5SDag-Erling Smørgrav 7924fe7ba0SDag-Erling Smørgrav pam_err = pam_get_user(pamh, &user, NULL); 8016e058b5SDag-Erling Smørgrav if (pam_err != PAM_SUCCESS) 8124fe7ba0SDag-Erling Smørgrav return (pam_err); 823cc381b0SDag-Erling Smørgrav if (user == NULL) 8324fe7ba0SDag-Erling Smørgrav return (PAM_SERVICE_ERR); 8416e058b5SDag-Erling Smørgrav PAM_LOG("Got user: %s", user); 8516e058b5SDag-Erling Smørgrav 8691e93869SDag-Erling Smørgrav pam_err = pam_get_item(pamh, PAM_RHOST, &rhost); 87f5e30bd1SDag-Erling Smørgrav if (pam_err != PAM_SUCCESS) { 88f5e30bd1SDag-Erling Smørgrav PAM_LOG("No PAM_RHOST"); 892569c273SDag-Erling Smørgrav goto err; 90f5e30bd1SDag-Erling Smørgrav } 9191e93869SDag-Erling Smørgrav pam_err = pam_get_item(pamh, PAM_TTY, &tty); 92f5e30bd1SDag-Erling Smørgrav if (pam_err != PAM_SUCCESS) { 93f5e30bd1SDag-Erling Smørgrav PAM_LOG("No PAM_TTY"); 942569c273SDag-Erling Smørgrav goto err; 95f5e30bd1SDag-Erling Smørgrav } 96eb6f605eSDag-Erling Smørgrav if (tty == NULL) { 97f5e30bd1SDag-Erling Smørgrav PAM_LOG("No PAM_TTY"); 98eb6f605eSDag-Erling Smørgrav pam_err = PAM_SERVICE_ERR; 99eb6f605eSDag-Erling Smørgrav goto err; 100eb6f605eSDag-Erling Smørgrav } 101f1b61fc8SEd Schouten /* Strip /dev/ component. */ 102f1b61fc8SEd Schouten if (strncmp(tty, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) 103f1b61fc8SEd Schouten tty = (const char *)tty + sizeof(_PATH_DEV) - 1; 10416e058b5SDag-Erling Smørgrav 10516e058b5SDag-Erling Smørgrav if ((flags & PAM_SILENT) == 0) { 10629572408SEd Schouten if (setutxdb(UTXDB_LASTLOGIN, NULL) != 0) { 10729572408SEd Schouten PAM_LOG("Failed to open lastlogin database"); 10817c79ad0SEd Schouten } else { 10929572408SEd Schouten utx = getutxuser(user); 11017c79ad0SEd Schouten if (utx != NULL && utx->ut_type == USER_PROCESS) { 11117c79ad0SEd Schouten t = utx->ut_tv.tv_sec; 11217c79ad0SEd Schouten if (*utx->ut_host != '\0') 11317c79ad0SEd Schouten pam_info(pamh, "Last login: %.*s from %s", 11417c79ad0SEd Schouten 24 - 5, ctime(&t), utx->ut_host); 11516e058b5SDag-Erling Smørgrav else 11617c79ad0SEd Schouten pam_info(pamh, "Last login: %.*s on %s", 11717c79ad0SEd Schouten 24 - 5, ctime(&t), utx->ut_line); 11816e058b5SDag-Erling Smørgrav } 11929572408SEd Schouten endutxent(); 12017c79ad0SEd Schouten } 12116e058b5SDag-Erling Smørgrav } 12216e058b5SDag-Erling Smørgrav 123d1b8647fSEd Schouten id = malloc(sizeof utl.ut_id); 124d1b8647fSEd Schouten if (id == NULL) { 125d1b8647fSEd Schouten pam_err = PAM_SERVICE_ERR; 126d1b8647fSEd Schouten goto err; 127d1b8647fSEd Schouten } 128d1b8647fSEd Schouten arc4random_buf(id, sizeof utl.ut_id); 129d1b8647fSEd Schouten 130d1b8647fSEd Schouten pam_err = pam_set_data(pamh, PAM_UTMPX_ID, id, openpam_free_data); 131d1b8647fSEd Schouten if (pam_err != PAM_SUCCESS) { 132d1b8647fSEd Schouten free(id); 133d1b8647fSEd Schouten goto err; 134d1b8647fSEd Schouten } 135d1b8647fSEd Schouten 136d1b8647fSEd Schouten memset(&utl, 0, sizeof utl); 137d1b8647fSEd Schouten utl.ut_type = USER_PROCESS; 138d1b8647fSEd Schouten memcpy(utl.ut_id, id, sizeof utl.ut_id); 139d1b8647fSEd Schouten strncpy(utl.ut_user, user, sizeof utl.ut_user); 140d1b8647fSEd Schouten strncpy(utl.ut_line, tty, sizeof utl.ut_line); 141d1b8647fSEd Schouten if (rhost != NULL) 142d1b8647fSEd Schouten strncpy(utl.ut_host, rhost, sizeof utl.ut_host); 143d1b8647fSEd Schouten utl.ut_pid = getpid(); 144d1b8647fSEd Schouten gettimeofday(&utl.ut_tv, NULL); 145d1b8647fSEd Schouten pututxline(&utl); 1469201dc40SDag-Erling Smørgrav 14789136eabSDag-Erling Smørgrav return (PAM_SUCCESS); 14816e058b5SDag-Erling Smørgrav 1492569c273SDag-Erling Smørgrav err: 15089136eabSDag-Erling Smørgrav if (openpam_get_option(pamh, "no_fail")) 15189136eabSDag-Erling Smørgrav return (PAM_SUCCESS); 1522569c273SDag-Erling Smørgrav return (pam_err); 15316e058b5SDag-Erling Smørgrav } 15416e058b5SDag-Erling Smørgrav 15516e058b5SDag-Erling Smørgrav PAM_EXTERN int 15617c79ad0SEd Schouten pam_sm_close_session(pam_handle_t *pamh, int flags __unused, 15724fe7ba0SDag-Erling Smørgrav int argc __unused, const char *argv[] __unused) 15816e058b5SDag-Erling Smørgrav { 159d1b8647fSEd Schouten struct utmpx utl; 160d1b8647fSEd Schouten const void *id; 161f0f1db2eSDag-Erling Smørgrav int pam_err; 16216e058b5SDag-Erling Smørgrav 163d1b8647fSEd Schouten pam_err = pam_get_data(pamh, PAM_UTMPX_ID, (const void **)&id); 164f0f1db2eSDag-Erling Smørgrav if (pam_err != PAM_SUCCESS) 165f0f1db2eSDag-Erling Smørgrav goto err; 166d1b8647fSEd Schouten 167d1b8647fSEd Schouten memset(&utl, 0, sizeof utl); 168d1b8647fSEd Schouten utl.ut_type = DEAD_PROCESS; 169d1b8647fSEd Schouten memcpy(utl.ut_id, id, sizeof utl.ut_id); 170d1b8647fSEd Schouten utl.ut_pid = getpid(); 171d1b8647fSEd Schouten gettimeofday(&utl.ut_tv, NULL); 172d1b8647fSEd Schouten pututxline(&utl); 173d1b8647fSEd Schouten 17424fe7ba0SDag-Erling Smørgrav return (PAM_SUCCESS); 175f0f1db2eSDag-Erling Smørgrav 176f0f1db2eSDag-Erling Smørgrav err: 177f0f1db2eSDag-Erling Smørgrav if (openpam_get_option(pamh, "no_fail")) 178f0f1db2eSDag-Erling Smørgrav return (PAM_SUCCESS); 179f0f1db2eSDag-Erling Smørgrav return (pam_err); 18016e058b5SDag-Erling Smørgrav } 18116e058b5SDag-Erling Smørgrav 18216e058b5SDag-Erling Smørgrav PAM_MODULE_ENTRY("pam_lastlog"); 183