1200062Sed/*- 2200062Sed * Copyright (c) 2009 Ed Schouten <ed@FreeBSD.org> 3200062Sed * All rights reserved. 4200062Sed * 5200062Sed * Redistribution and use in source and binary forms, with or without 6200062Sed * modification, are permitted provided that the following conditions 7200062Sed * are met: 8200062Sed * 1. Redistributions of source code must retain the above copyright 9200062Sed * notice, this list of conditions and the following disclaimer. 10200062Sed * 2. Redistributions in binary form must reproduce the above copyright 11200062Sed * notice, this list of conditions and the following disclaimer in the 12200062Sed * documentation and/or other materials provided with the distribution. 13200062Sed * 14200062Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15200062Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16200062Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17200062Sed * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18200062Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19200062Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20200062Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21200062Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22200062Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23200062Sed * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24200062Sed * SUCH DAMAGE. 25200062Sed */ 26200062Sed 27200062Sed#include <sys/cdefs.h> 28200062Sed__FBSDID("$FreeBSD$"); 29200062Sed 30200062Sed#include <pwd.h> 31200062Sed#include <unistd.h> 32200062Sed#include <stdlib.h> 33200062Sed#include <string.h> 34200062Sed#include <sysexits.h> 35200062Sed#include <ulog.h> 36200062Sed 37200062Sed/* 38200062Sed * This setuid helper utility writes user login records to disk. 39223367Sed * Unprivileged processes are not capable of writing records to utmpx, 40223367Sed * but we do want to allow this for pseudo-terminals. Because a file 41223367Sed * descriptor to a pseudo-terminal master device can only be obtained by 42223367Sed * processes using the pseudo-terminal, we expect such a descriptor on 43223367Sed * stdin. 44200062Sed * 45200062Sed * It uses the real user ID of the calling process to determine the 46200062Sed * username. It does allow users to log arbitrary hostnames. 47200062Sed */ 48200062Sed 49234469Sedstatic const char * 50234469Sedget_username(void) 51234469Sed{ 52234469Sed const struct passwd *pw; 53234469Sed const char *login; 54234469Sed uid_t uid; 55234469Sed 56234469Sed /* 57234469Sed * Attempt to determine the username corresponding to this login 58234469Sed * session. First, validate the results of getlogin() against 59234469Sed * the password database. If getlogin() returns invalid data, 60234469Sed * return an arbitrary username corresponding to this uid. 61234469Sed */ 62234469Sed uid = getuid(); 63234469Sed if ((login = getlogin()) != NULL && (pw = getpwnam(login)) != NULL && 64234469Sed pw->pw_uid == uid) 65234469Sed return (login); 66234469Sed if ((pw = getpwuid(uid)) != NULL) 67234469Sed return (pw->pw_name); 68234469Sed return (NULL); 69234469Sed} 70234469Sed 71200062Sedint 72200062Sedmain(int argc, char *argv[]) 73200062Sed{ 74223367Sed const char *line, *user, *host; 75200062Sed 76200062Sed /* Device line name. */ 77200062Sed if ((line = ptsname(STDIN_FILENO)) == NULL) 78200062Sed return (EX_USAGE); 79200062Sed 80200062Sed if ((argc == 2 || argc == 3) && strcmp(argv[1], "login") == 0) { 81200062Sed /* Username. */ 82234469Sed user = get_username(); 83223367Sed if (user == NULL) 84200062Sed return (EX_OSERR); 85200062Sed 86200062Sed /* Hostname. */ 87223367Sed host = argc == 3 ? argv[2] : NULL; 88200062Sed 89223367Sed ulog_login(line, user, host); 90200062Sed return (EX_OK); 91200062Sed } else if (argc == 2 && strcmp(argv[1], "logout") == 0) { 92200085Sed ulog_logout(line); 93200062Sed return (EX_OK); 94200062Sed } 95200062Sed 96200062Sed return (EX_USAGE); 97200062Sed} 98