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