116e058b5SDag-Erling Smørgrav /*- 216e058b5SDag-Erling Smørgrav * Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994 316e058b5SDag-Erling Smørgrav * The Regents of the University of California. All rights reserved. 416e058b5SDag-Erling Smørgrav * Copyright (c) 2001 Mark R V Murray 516e058b5SDag-Erling Smørgrav * All rights reserved. 6f03a4b81SDag-Erling Smørgrav * Copyright (c) 2001 Networks Associates Technology, Inc. 716e058b5SDag-Erling Smørgrav * All rights reserved. 83a59e89eSDag-Erling Smørgrav * Copyright (c) 2004 Joe R. Doupnik 93a59e89eSDag-Erling Smørgrav * All rights reserved. 1016e058b5SDag-Erling Smørgrav * 1116e058b5SDag-Erling Smørgrav * Portions of this software were developed for the FreeBSD Project by 1216e058b5SDag-Erling Smørgrav * ThinkSec AS and NAI Labs, the Security Research Division of Network 1316e058b5SDag-Erling Smørgrav * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 1416e058b5SDag-Erling Smørgrav * ("CBOSS"), as part of the DARPA CHATS research program. 1516e058b5SDag-Erling Smørgrav * 1616e058b5SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 1716e058b5SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 1816e058b5SDag-Erling Smørgrav * are met: 1916e058b5SDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright 2016e058b5SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer. 2116e058b5SDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright 2216e058b5SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the 2316e058b5SDag-Erling Smørgrav * documentation and/or other materials provided with the distribution. 2416e058b5SDag-Erling Smørgrav * 3. The name of the author may not be used to endorse or promote 2516e058b5SDag-Erling Smørgrav * products derived from this software without specific prior written 2616e058b5SDag-Erling Smørgrav * permission. 2716e058b5SDag-Erling Smørgrav * 4. Neither the name of the University nor the names of its contributors 2816e058b5SDag-Erling Smørgrav * may be used to endorse or promote products derived from this software 2916e058b5SDag-Erling Smørgrav * without specific prior written permission. 3016e058b5SDag-Erling Smørgrav * 3116e058b5SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 3216e058b5SDag-Erling Smørgrav * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 3316e058b5SDag-Erling Smørgrav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3416e058b5SDag-Erling Smørgrav * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 3516e058b5SDag-Erling Smørgrav * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3616e058b5SDag-Erling Smørgrav * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3716e058b5SDag-Erling Smørgrav * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3816e058b5SDag-Erling Smørgrav * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3916e058b5SDag-Erling Smørgrav * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 4016e058b5SDag-Erling Smørgrav * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 4116e058b5SDag-Erling Smørgrav * SUCH DAMAGE. 4216e058b5SDag-Erling Smørgrav */ 4316e058b5SDag-Erling Smørgrav 4416e058b5SDag-Erling Smørgrav #include <sys/cdefs.h> 4516e058b5SDag-Erling Smørgrav __FBSDID("$FreeBSD$"); 4616e058b5SDag-Erling Smørgrav 4716e058b5SDag-Erling Smørgrav #define _BSD_SOURCE 4816e058b5SDag-Erling Smørgrav 49d1b8647fSEd Schouten #include <sys/time.h> 50f1b61fc8SEd Schouten 51f1b61fc8SEd Schouten #include <paths.h> 52d1b8647fSEd Schouten #include <stdlib.h> 53d1b8647fSEd Schouten #include <string.h> 5416e058b5SDag-Erling Smørgrav #include <time.h> 55d1b8647fSEd Schouten #include <unistd.h> 5629572408SEd Schouten #include <utmpx.h> 5716e058b5SDag-Erling Smørgrav 5816e058b5SDag-Erling Smørgrav #define PAM_SM_SESSION 5916e058b5SDag-Erling Smørgrav 608c66575dSDag-Erling Smørgrav #include <security/pam_appl.h> 6116e058b5SDag-Erling Smørgrav #include <security/pam_modules.h> 628c66575dSDag-Erling Smørgrav #include <security/pam_mod_misc.h> 6316e058b5SDag-Erling Smørgrav 64d1b8647fSEd Schouten #define PAM_UTMPX_ID "utmpx_id" 65d1b8647fSEd Schouten 6616e058b5SDag-Erling Smørgrav PAM_EXTERN int 6724fe7ba0SDag-Erling Smørgrav pam_sm_open_session(pam_handle_t *pamh, int flags, 6824fe7ba0SDag-Erling Smørgrav int argc __unused, const char *argv[] __unused) 6916e058b5SDag-Erling Smørgrav { 70d1b8647fSEd Schouten struct utmpx *utx, utl; 716ceeb690SPeter Wemm time_t t; 7291e93869SDag-Erling Smørgrav const char *user; 7391e93869SDag-Erling Smørgrav const void *rhost, *tty; 74d1b8647fSEd Schouten char *id; 7517c79ad0SEd Schouten int pam_err; 7616e058b5SDag-Erling Smørgrav 7724fe7ba0SDag-Erling Smørgrav pam_err = pam_get_user(pamh, &user, NULL); 7816e058b5SDag-Erling Smørgrav if (pam_err != PAM_SUCCESS) 7924fe7ba0SDag-Erling Smørgrav return (pam_err); 80*3cc381b0SDag-Erling Smørgrav if (user == NULL) 8124fe7ba0SDag-Erling Smørgrav return (PAM_SERVICE_ERR); 8216e058b5SDag-Erling Smørgrav PAM_LOG("Got user: %s", user); 8316e058b5SDag-Erling Smørgrav 8491e93869SDag-Erling Smørgrav pam_err = pam_get_item(pamh, PAM_RHOST, &rhost); 85f5e30bd1SDag-Erling Smørgrav if (pam_err != PAM_SUCCESS) { 86f5e30bd1SDag-Erling Smørgrav PAM_LOG("No PAM_RHOST"); 872569c273SDag-Erling Smørgrav goto err; 88f5e30bd1SDag-Erling Smørgrav } 8991e93869SDag-Erling Smørgrav pam_err = pam_get_item(pamh, PAM_TTY, &tty); 90f5e30bd1SDag-Erling Smørgrav if (pam_err != PAM_SUCCESS) { 91f5e30bd1SDag-Erling Smørgrav PAM_LOG("No PAM_TTY"); 922569c273SDag-Erling Smørgrav goto err; 93f5e30bd1SDag-Erling Smørgrav } 94eb6f605eSDag-Erling Smørgrav if (tty == NULL) { 95f5e30bd1SDag-Erling Smørgrav PAM_LOG("No PAM_TTY"); 96eb6f605eSDag-Erling Smørgrav pam_err = PAM_SERVICE_ERR; 97eb6f605eSDag-Erling Smørgrav goto err; 98eb6f605eSDag-Erling Smørgrav } 99f1b61fc8SEd Schouten /* Strip /dev/ component. */ 100f1b61fc8SEd Schouten if (strncmp(tty, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) 101f1b61fc8SEd Schouten tty = (const char *)tty + sizeof(_PATH_DEV) - 1; 10216e058b5SDag-Erling Smørgrav 10316e058b5SDag-Erling Smørgrav if ((flags & PAM_SILENT) == 0) { 10429572408SEd Schouten if (setutxdb(UTXDB_LASTLOGIN, NULL) != 0) { 10529572408SEd Schouten PAM_LOG("Failed to open lastlogin database"); 10617c79ad0SEd Schouten } else { 10729572408SEd Schouten utx = getutxuser(user); 10817c79ad0SEd Schouten if (utx != NULL && utx->ut_type == USER_PROCESS) { 10917c79ad0SEd Schouten t = utx->ut_tv.tv_sec; 11017c79ad0SEd Schouten if (*utx->ut_host != '\0') 11117c79ad0SEd Schouten pam_info(pamh, "Last login: %.*s from %s", 11217c79ad0SEd Schouten 24 - 5, ctime(&t), utx->ut_host); 11316e058b5SDag-Erling Smørgrav else 11417c79ad0SEd Schouten pam_info(pamh, "Last login: %.*s on %s", 11517c79ad0SEd Schouten 24 - 5, ctime(&t), utx->ut_line); 11616e058b5SDag-Erling Smørgrav } 11729572408SEd Schouten endutxent(); 11817c79ad0SEd Schouten } 11916e058b5SDag-Erling Smørgrav } 12016e058b5SDag-Erling Smørgrav 121d1b8647fSEd Schouten id = malloc(sizeof utl.ut_id); 122d1b8647fSEd Schouten if (id == NULL) { 123d1b8647fSEd Schouten pam_err = PAM_SERVICE_ERR; 124d1b8647fSEd Schouten goto err; 125d1b8647fSEd Schouten } 126d1b8647fSEd Schouten arc4random_buf(id, sizeof utl.ut_id); 127d1b8647fSEd Schouten 128d1b8647fSEd Schouten pam_err = pam_set_data(pamh, PAM_UTMPX_ID, id, openpam_free_data); 129d1b8647fSEd Schouten if (pam_err != PAM_SUCCESS) { 130d1b8647fSEd Schouten free(id); 131d1b8647fSEd Schouten goto err; 132d1b8647fSEd Schouten } 133d1b8647fSEd Schouten 134d1b8647fSEd Schouten memset(&utl, 0, sizeof utl); 135d1b8647fSEd Schouten utl.ut_type = USER_PROCESS; 136d1b8647fSEd Schouten memcpy(utl.ut_id, id, sizeof utl.ut_id); 137d1b8647fSEd Schouten strncpy(utl.ut_user, user, sizeof utl.ut_user); 138d1b8647fSEd Schouten strncpy(utl.ut_line, tty, sizeof utl.ut_line); 139d1b8647fSEd Schouten if (rhost != NULL) 140d1b8647fSEd Schouten strncpy(utl.ut_host, rhost, sizeof utl.ut_host); 141d1b8647fSEd Schouten utl.ut_pid = getpid(); 142d1b8647fSEd Schouten gettimeofday(&utl.ut_tv, NULL); 143d1b8647fSEd Schouten pututxline(&utl); 1449201dc40SDag-Erling Smørgrav 14589136eabSDag-Erling Smørgrav return (PAM_SUCCESS); 14616e058b5SDag-Erling Smørgrav 1472569c273SDag-Erling Smørgrav err: 14889136eabSDag-Erling Smørgrav if (openpam_get_option(pamh, "no_fail")) 14989136eabSDag-Erling Smørgrav return (PAM_SUCCESS); 1502569c273SDag-Erling Smørgrav return (pam_err); 15116e058b5SDag-Erling Smørgrav } 15216e058b5SDag-Erling Smørgrav 15316e058b5SDag-Erling Smørgrav PAM_EXTERN int 15417c79ad0SEd Schouten pam_sm_close_session(pam_handle_t *pamh, int flags __unused, 15524fe7ba0SDag-Erling Smørgrav int argc __unused, const char *argv[] __unused) 15616e058b5SDag-Erling Smørgrav { 157d1b8647fSEd Schouten struct utmpx utl; 158d1b8647fSEd Schouten const void *id; 159f0f1db2eSDag-Erling Smørgrav int pam_err; 16016e058b5SDag-Erling Smørgrav 161d1b8647fSEd Schouten pam_err = pam_get_data(pamh, PAM_UTMPX_ID, (const void **)&id); 162f0f1db2eSDag-Erling Smørgrav if (pam_err != PAM_SUCCESS) 163f0f1db2eSDag-Erling Smørgrav goto err; 164d1b8647fSEd Schouten 165d1b8647fSEd Schouten memset(&utl, 0, sizeof utl); 166d1b8647fSEd Schouten utl.ut_type = DEAD_PROCESS; 167d1b8647fSEd Schouten memcpy(utl.ut_id, id, sizeof utl.ut_id); 168d1b8647fSEd Schouten utl.ut_pid = getpid(); 169d1b8647fSEd Schouten gettimeofday(&utl.ut_tv, NULL); 170d1b8647fSEd Schouten pututxline(&utl); 171d1b8647fSEd Schouten 17224fe7ba0SDag-Erling Smørgrav return (PAM_SUCCESS); 173f0f1db2eSDag-Erling Smørgrav 174f0f1db2eSDag-Erling Smørgrav err: 175f0f1db2eSDag-Erling Smørgrav if (openpam_get_option(pamh, "no_fail")) 176f0f1db2eSDag-Erling Smørgrav return (PAM_SUCCESS); 177f0f1db2eSDag-Erling Smørgrav return (pam_err); 17816e058b5SDag-Erling Smørgrav } 17916e058b5SDag-Erling Smørgrav 18016e058b5SDag-Erling Smørgrav PAM_MODULE_ENTRY("pam_lastlog"); 181