11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: sshlogin.c,v 1.27 2011/01/11 06:06:09 djm Exp $ */
21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Author: Tatu Ylonen <ylo@cs.hut.fi>
41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *                    All rights reserved
61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * This file performs some of the things login(1) normally does.  We cannot
71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * easily use something like login -p -h host -f user, because there are
81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * several different logins around, and it is hard to determined what kind of
91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * login the current system has.  Also, we want to be able to execute commands
101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * on a tty.
111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * As far as I am concerned, the code I have written for this software
131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * can be used freely for any purpose.  Any derived versions of this
141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * software must be clearly marked as such, and if the derived work is
151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * incompatible with the protocol description in the RFC file, it must be
161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * called by a name other than "ssh" or "Secure Shell".
171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1999 Theo de Raadt.  All rights reserved.
191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1999 Markus Friedl.  All rights reserved.
201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without
221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions
231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met:
241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright
251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    notice, this list of conditions and the following disclaimer.
261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright
271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    notice, this list of conditions and the following disclaimer in the
281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    documentation and/or other materials provided with the distribution.
291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h"
431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h>
451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/param.h>
461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/socket.h>
471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <netinet/in.h>
491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h>
511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <fcntl.h>
521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h>
531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdio.h>
541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h>
551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <time.h>
561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <unistd.h>
571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "loginrec.h"
591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h"
601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "buffer.h"
611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "servconf.h"
621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern Buffer loginmsg;
641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern ServerOptions options;
651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Returns the time when the user last logged in.  Returns 0 if the
681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * information is not available.  This must be called before record_login.
691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * The host the user logged in from will be returned in buf.
701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtime_t
721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodget_last_login_time(uid_t uid, const char *logname,
731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    char *buf, size_t bufsize)
741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct logininfo li;
761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	login_get_lastlog(&li, uid);
781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	strlcpy(buf, li.hostname, bufsize);
791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return (time_t)li.tv_sec;
801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Generate and store last login message.  This must be done before
841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * login_login() is called and lastlog is updated.
851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstore_lastlog_message(const char *user, uid_t uid)
881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifndef NO_SSH_LASTLOG
901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char *time_string, hostname[MAXHOSTNAMELEN] = "", buf[512];
911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	time_t last_login_time;
921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!options.print_lastlog)
941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return;
951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# ifdef CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG
971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	time_string = sys_auth_get_lastlogin_msg(user, uid);
981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (time_string != NULL) {
991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_append(&loginmsg, time_string, strlen(time_string));
1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(time_string);
1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# else
1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	last_login_time = get_last_login_time(uid, user, hostname,
1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    sizeof(hostname));
1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (last_login_time != 0) {
1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		time_string = ctime(&last_login_time);
1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		time_string[strcspn(time_string, "\n")] = '\0';
1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (strcmp(hostname, "") == 0)
1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			snprintf(buf, sizeof(buf), "Last login: %s\r\n",
1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    time_string);
1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		else
1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			snprintf(buf, sizeof(buf), "Last login: %s from %s\r\n",
1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    time_string, hostname);
1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_append(&loginmsg, buf, strlen(buf));
1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# endif /* CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG */
1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* NO_SSH_LASTLOG */
1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Records that the user has logged in.  I wish these parts of operating
1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * systems were more standardized.
1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodrecord_login(pid_t pid, const char *tty, const char *user, uid_t uid,
1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    const char *host, struct sockaddr *addr, socklen_t addrlen)
1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct logininfo *li;
1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* save previous login details before writing new */
1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	store_lastlog_message(user, uid);
1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	li = login_alloc_entry(pid, user, host, tty);
1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	login_set_addr(li, addr, addrlen);
1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	login_login(li);
1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	login_free_entry(li);
1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef LOGIN_NEEDS_UTMPX
1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodrecord_utmp_only(pid_t pid, const char *ttyname, const char *user,
1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 const char *host, struct sockaddr *addr, socklen_t addrlen)
1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct logininfo *li;
1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	li = login_alloc_entry(pid, user, host, ttyname);
1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	login_set_addr(li, addr, addrlen);
1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	login_utmp_only(li);
1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	login_free_entry(li);
1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Records that the user has logged out. */
1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodrecord_logout(pid_t pid, const char *tty, const char *user)
1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct logininfo *li;
1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	li = login_alloc_entry(pid, user, NULL, tty);
1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	login_logout(li);
1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	login_free_entry(li);
1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
164