sshlogin.c revision 264377
1100384Speter/* $OpenBSD: sshlogin.c,v 1.28 2014/01/31 16:39:19 tedu Exp $ */ 2100384Speter/* 3100384Speter * Author: Tatu Ylonen <ylo@cs.hut.fi> 4100384Speter * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 5100384Speter * All rights reserved 6100384Speter * This file performs some of the things login(1) normally does. We cannot 7100384Speter * easily use something like login -p -h host -f user, because there are 8100384Speter * several different logins around, and it is hard to determined what kind of 9100384Speter * login the current system has. Also, we want to be able to execute commands 10100384Speter * on a tty. 11100384Speter * 12100384Speter * As far as I am concerned, the code I have written for this software 13100384Speter * can be used freely for any purpose. Any derived versions of this 14100384Speter * software must be clearly marked as such, and if the derived work is 15100384Speter * incompatible with the protocol description in the RFC file, it must be 16100384Speter * called by a name other than "ssh" or "Secure Shell". 17100384Speter * 18100384Speter * Copyright (c) 1999 Theo de Raadt. All rights reserved. 19100384Speter * Copyright (c) 1999 Markus Friedl. All rights reserved. 20100384Speter * 21100384Speter * Redistribution and use in source and binary forms, with or without 22100384Speter * modification, are permitted provided that the following conditions 23100384Speter * are met: 24100384Speter * 1. Redistributions of source code must retain the above copyright 25100384Speter * notice, this list of conditions and the following disclaimer. 26100384Speter * 2. Redistributions in binary form must reproduce the above copyright 27118031Sobrien * notice, this list of conditions and the following disclaimer in the 28118031Sobrien * documentation and/or other materials provided with the distribution. 29118031Sobrien * 30104738Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 31104738Speter * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 32100384Speter * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 33100384Speter * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 34100384Speter * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 35100384Speter * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36100384Speter * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37100384Speter * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38123746Speter * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 39100384Speter * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40100384Speter */ 41100384Speter 42100384Speter#include "includes.h" 43100384Speter 44100384Speter#include <sys/types.h> 45100384Speter#include <sys/param.h> 46100384Speter#include <sys/socket.h> 47100384Speter 48100384Speter#include <netinet/in.h> 49100384Speter 50100384Speter#include <errno.h> 51100384Speter#include <fcntl.h> 52100384Speter#include <stdarg.h> 53100384Speter#include <stdio.h> 54100384Speter#include <string.h> 55146950Sps#include <time.h> 56100384Speter#include <unistd.h> 57100384Speter 58100384Speter#include "loginrec.h" 59100384Speter#include "log.h" 60100384Speter#include "buffer.h" 61100384Speter#include "servconf.h" 62150883Sjhb 63113859Sjhbextern Buffer loginmsg; 64100384Speterextern ServerOptions options; 65100384Speter 66100384Speter/* 67100384Speter * Returns the time when the user last logged in. Returns 0 if the 68100384Speter * information is not available. This must be called before record_login. 69100384Speter * The host the user logged in from will be returned in buf. 70127140Sjhb */ 71100384Spetertime_t 72100384Speterget_last_login_time(uid_t uid, const char *logname, 73100384Speter char *buf, size_t bufsize) 74100384Speter{ 75100384Speter struct logininfo li; 76100384Speter 77100384Speter login_get_lastlog(&li, uid); 78100384Speter strlcpy(buf, li.hostname, bufsize); 79100384Speter return (time_t)li.tv_sec; 80151582Sps} 81151582Sps 82119333Speter/* 83119333Speter * Generate and store last login message. This must be done before 84119333Speter * login_login() is called and lastlog is updated. 85100384Speter */ 86121719Speterstatic void 87121719Speterstore_lastlog_message(const char *user, uid_t uid) 88121719Speter{ 89121719Speter#ifndef NO_SSH_LASTLOG 90121719Speter char *time_string, hostname[MAXHOSTNAMELEN] = "", buf[512]; 91100384Speter time_t last_login_time; 92119333Speter 93100384Speter if (!options.print_lastlog) 94127140Sjhb return; 95127140Sjhb 96136152Sjhb# ifdef CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG 97100384Speter time_string = sys_auth_get_lastlogin_msg(user, uid); 98136152Sjhb if (time_string != NULL) { 99136152Sjhb buffer_append(&loginmsg, time_string, strlen(time_string)); 100136152Sjhb free(time_string); 101136152Sjhb } 102136152Sjhb# else 103100384Speter last_login_time = get_last_login_time(uid, user, hostname, 104100384Speter sizeof(hostname)); 105127140Sjhb 106127140Sjhb if (last_login_time != 0) { 107127140Sjhb time_string = ctime(&last_login_time); 108100384Speter time_string[strcspn(time_string, "\n")] = '\0'; 109100384Speter if (strcmp(hostname, "") == 0) 110100384Speter snprintf(buf, sizeof(buf), "Last login: %s\r\n", 111100384Speter time_string); 112100384Speter else 113100384Speter snprintf(buf, sizeof(buf), "Last login: %s from %s\r\n", 114100384Speter time_string, hostname); 115100384Speter buffer_append(&loginmsg, buf, strlen(buf)); 116100384Speter } 117100384Speter# endif /* CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG */ 118100384Speter#endif /* NO_SSH_LASTLOG */ 119100384Speter} 120100384Speter 121100384Speter/* 122100384Speter * Records that the user has logged in. I wish these parts of operating 123100384Speter * systems were more standardized. 124127140Sjhb */ 125100384Spetervoid 126100384Speterrecord_login(pid_t pid, const char *tty, const char *user, uid_t uid, 127100384Speter const char *host, struct sockaddr *addr, socklen_t addrlen) 128100384Speter{ 129128597Smarcel struct logininfo *li; 130100384Speter 131100384Speter /* save previous login details before writing new */ 132100384Speter store_lastlog_message(user, uid); 133100384Speter 134100384Speter li = login_alloc_entry(pid, user, host, tty); 135100384Speter login_set_addr(li, addr, addrlen); 136100384Speter login_login(li); 137100384Speter login_free_entry(li); 138100384Speter} 139100384Speter 140100384Speter#ifdef LOGIN_NEEDS_UTMPX 141100384Spetervoid 142100384Speterrecord_utmp_only(pid_t pid, const char *ttyname, const char *user, 143100384Speter const char *host, struct sockaddr *addr, socklen_t addrlen) 144100384Speter{ 145100384Speter struct logininfo *li; 146100384Speter 147100384Speter li = login_alloc_entry(pid, user, host, ttyname); 148100384Speter login_set_addr(li, addr, addrlen); 149100384Speter login_utmp_only(li); 150128260Speter login_free_entry(li); 151100384Speter} 152100384Speter#endif 153100384Speter 154128260Speter/* Records that the user has logged out. */ 155100384Spetervoid 156128597Smarcelrecord_logout(pid_t pid, const char *tty, const char *user) 157100384Speter{ 158128597Smarcel struct logininfo *li; 159100384Speter 160128260Speter li = login_alloc_entry(pid, user, NULL, tty); 161100384Speter login_logout(li); 162147178Spjd login_free_entry(li); 163147178Spjd} 164147178Spjd