Branch data Line data Source code
1 : : /* $OpenBSD: sshlogin.c,v 1.28 2014/01/31 16:39:19 tedu Exp $ */
2 : : /*
3 : : * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 : : * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 : : * All rights reserved
6 : : * This file performs some of the things login(1) normally does. We cannot
7 : : * easily use something like login -p -h host -f user, because there are
8 : : * several different logins around, and it is hard to determined what kind of
9 : : * login the current system has. Also, we want to be able to execute commands
10 : : * on a tty.
11 : : *
12 : : * As far as I am concerned, the code I have written for this software
13 : : * can be used freely for any purpose. Any derived versions of this
14 : : * software must be clearly marked as such, and if the derived work is
15 : : * incompatible with the protocol description in the RFC file, it must be
16 : : * called by a name other than "ssh" or "Secure Shell".
17 : : *
18 : : * Copyright (c) 1999 Theo de Raadt. All rights reserved.
19 : : * Copyright (c) 1999 Markus Friedl. All rights reserved.
20 : : *
21 : : * Redistribution and use in source and binary forms, with or without
22 : : * modification, are permitted provided that the following conditions
23 : : * are met:
24 : : * 1. Redistributions of source code must retain the above copyright
25 : : * notice, this list of conditions and the following disclaimer.
26 : : * 2. Redistributions in binary form must reproduce the above copyright
27 : : * notice, this list of conditions and the following disclaimer in the
28 : : * documentation and/or other materials provided with the distribution.
29 : : *
30 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
31 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
33 : : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
34 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
35 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
39 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 : : */
41 : :
42 : : #include "includes.h"
43 : :
44 : : #include <sys/types.h>
45 : : #include <sys/param.h>
46 : : #include <sys/socket.h>
47 : :
48 : : #include <netinet/in.h>
49 : :
50 : : #include <errno.h>
51 : : #include <fcntl.h>
52 : : #include <stdarg.h>
53 : : #include <stdio.h>
54 : : #include <string.h>
55 : : #include <time.h>
56 : : #include <unistd.h>
57 : :
58 : : #include "loginrec.h"
59 : : #include "log.h"
60 : : #include "buffer.h"
61 : : #include "servconf.h"
62 : :
63 : : extern Buffer loginmsg;
64 : : extern ServerOptions options;
65 : :
66 : : /*
67 : : * Returns the time when the user last logged in. Returns 0 if the
68 : : * information is not available. This must be called before record_login.
69 : : * The host the user logged in from will be returned in buf.
70 : : */
71 : : time_t
72 : 0 : get_last_login_time(uid_t uid, const char *logname,
73 : : char *buf, size_t bufsize)
74 : : {
75 : : struct logininfo li;
76 : :
77 : 0 : login_get_lastlog(&li, uid);
78 : 0 : strlcpy(buf, li.hostname, bufsize);
79 : 0 : return (time_t)li.tv_sec;
80 : : }
81 : :
82 : : /*
83 : : * Generate and store last login message. This must be done before
84 : : * login_login() is called and lastlog is updated.
85 : : */
86 : : static void
87 : 0 : store_lastlog_message(const char *user, uid_t uid)
88 : : {
89 : : #ifndef NO_SSH_LASTLOG
90 : 0 : char *time_string, hostname[MAXHOSTNAMELEN] = "", buf[512];
91 : : time_t last_login_time;
92 : :
93 [ # # ]: 0 : if (!options.print_lastlog)
94 : 0 : return;
95 : :
96 : : # ifdef CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG
97 : : time_string = sys_auth_get_lastlogin_msg(user, uid);
98 : : if (time_string != NULL) {
99 : : buffer_append(&loginmsg, time_string, strlen(time_string));
100 : : free(time_string);
101 : : }
102 : : # else
103 : 0 : last_login_time = get_last_login_time(uid, user, hostname,
104 : : sizeof(hostname));
105 : :
106 [ # # ]: 0 : if (last_login_time != 0) {
107 : 0 : time_string = ctime(&last_login_time);
108 : 0 : time_string[strcspn(time_string, "\n")] = '\0';
109 [ # # ]: 0 : if (strcmp(hostname, "") == 0)
110 : : snprintf(buf, sizeof(buf), "Last login: %s\r\n",
111 : : time_string);
112 : : else
113 : : snprintf(buf, sizeof(buf), "Last login: %s from %s\r\n",
114 : : time_string, hostname);
115 : 0 : buffer_append(&loginmsg, buf, strlen(buf));
116 : : }
117 : : # endif /* CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG */
118 : : #endif /* NO_SSH_LASTLOG */
119 : : }
120 : :
121 : : /*
122 : : * Records that the user has logged in. I wish these parts of operating
123 : : * systems were more standardized.
124 : : */
125 : : void
126 : 0 : record_login(pid_t pid, const char *tty, const char *user, uid_t uid,
127 : : const char *host, struct sockaddr *addr, socklen_t addrlen)
128 : : {
129 : : struct logininfo *li;
130 : :
131 : : /* save previous login details before writing new */
132 : 0 : store_lastlog_message(user, uid);
133 : :
134 : 0 : li = login_alloc_entry(pid, user, host, tty);
135 : 0 : login_set_addr(li, addr, addrlen);
136 : 0 : login_login(li);
137 : 0 : login_free_entry(li);
138 : 0 : }
139 : :
140 : : #ifdef LOGIN_NEEDS_UTMPX
141 : : void
142 : : record_utmp_only(pid_t pid, const char *ttyname, const char *user,
143 : : const char *host, struct sockaddr *addr, socklen_t addrlen)
144 : : {
145 : : struct logininfo *li;
146 : :
147 : : li = login_alloc_entry(pid, user, host, ttyname);
148 : : login_set_addr(li, addr, addrlen);
149 : : login_utmp_only(li);
150 : : login_free_entry(li);
151 : : }
152 : : #endif
153 : :
154 : : /* Records that the user has logged out. */
155 : : void
156 : 0 : record_logout(pid_t pid, const char *tty, const char *user)
157 : : {
158 : : struct logininfo *li;
159 : :
160 : 0 : li = login_alloc_entry(pid, user, NULL, tty);
161 : 0 : login_logout(li);
162 : 0 : login_free_entry(li);
163 : 0 : }
|