10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * Author: Tatu Ylonen <ylo@cs.hut.fi>
30Sstevel@tonic-gate * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
40Sstevel@tonic-gate * All rights reserved
50Sstevel@tonic-gate * This file performs some of the things login(1) normally does. We cannot
60Sstevel@tonic-gate * easily use something like login -p -h host -f user, because there are
70Sstevel@tonic-gate * several different logins around, and it is hard to determined what kind of
80Sstevel@tonic-gate * login the current system has. Also, we want to be able to execute commands
90Sstevel@tonic-gate * on a tty.
100Sstevel@tonic-gate *
110Sstevel@tonic-gate * As far as I am concerned, the code I have written for this software
120Sstevel@tonic-gate * can be used freely for any purpose. Any derived versions of this
130Sstevel@tonic-gate * software must be clearly marked as such, and if the derived work is
140Sstevel@tonic-gate * incompatible with the protocol description in the RFC file, it must be
150Sstevel@tonic-gate * called by a name other than "ssh" or "Secure Shell".
160Sstevel@tonic-gate *
170Sstevel@tonic-gate * Copyright (c) 1999 Theo de Raadt. All rights reserved.
180Sstevel@tonic-gate * Copyright (c) 1999 Markus Friedl. All rights reserved.
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
210Sstevel@tonic-gate * modification, are permitted provided that the following conditions
220Sstevel@tonic-gate * are met:
230Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
240Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
250Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
260Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the
270Sstevel@tonic-gate * documentation and/or other materials provided with the distribution.
280Sstevel@tonic-gate *
290Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
300Sstevel@tonic-gate * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
310Sstevel@tonic-gate * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
320Sstevel@tonic-gate * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
330Sstevel@tonic-gate * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
340Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
350Sstevel@tonic-gate * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
360Sstevel@tonic-gate * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
370Sstevel@tonic-gate * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
380Sstevel@tonic-gate * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
390Sstevel@tonic-gate */
400Sstevel@tonic-gate /*
419845SJan.Pechanec@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
420Sstevel@tonic-gate * Use is subject to license terms.
430Sstevel@tonic-gate */
440Sstevel@tonic-gate
450Sstevel@tonic-gate #include "includes.h"
460Sstevel@tonic-gate RCSID("$OpenBSD: sshlogin.c,v 1.5 2002/08/29 15:57:25 stevesk Exp $");
470Sstevel@tonic-gate
480Sstevel@tonic-gate #include "loginrec.h"
490Sstevel@tonic-gate #include "log.h"
50*11044SHuie-Ying.Lee@Sun.COM #include "buffer.h"
510Sstevel@tonic-gate #include "servconf.h"
520Sstevel@tonic-gate #include "canohost.h"
530Sstevel@tonic-gate #include "packet.h"
540Sstevel@tonic-gate
550Sstevel@tonic-gate extern u_int utmp_len;
560Sstevel@tonic-gate extern ServerOptions options;
570Sstevel@tonic-gate
580Sstevel@tonic-gate /*
590Sstevel@tonic-gate * Returns the time when the user last logged in. Returns 0 if the
600Sstevel@tonic-gate * information is not available. This must be called before record_login.
610Sstevel@tonic-gate * The host the user logged in from will be returned in buf.
620Sstevel@tonic-gate */
630Sstevel@tonic-gate u_long
get_last_login_time(uid_t uid,const char * logname,char * buf,u_int bufsize)640Sstevel@tonic-gate get_last_login_time(uid_t uid, const char *logname,
650Sstevel@tonic-gate char *buf, u_int bufsize)
660Sstevel@tonic-gate {
670Sstevel@tonic-gate struct logininfo li;
680Sstevel@tonic-gate
690Sstevel@tonic-gate (void) login_get_lastlog(&li, uid);
700Sstevel@tonic-gate (void) strlcpy(buf, li.hostname, bufsize);
710Sstevel@tonic-gate return li.tv_sec;
720Sstevel@tonic-gate }
730Sstevel@tonic-gate
740Sstevel@tonic-gate /*
759845SJan.Pechanec@Sun.COM * Records that the user has logged in. If only these parts of operating
769845SJan.Pechanec@Sun.COM * systems were more standardized.
770Sstevel@tonic-gate */
780Sstevel@tonic-gate void
record_login(pid_t pid,const char * ttyname,const char * progname,const char * user)790Sstevel@tonic-gate record_login(pid_t pid, const char *ttyname, const char *progname,
800Sstevel@tonic-gate const char *user)
810Sstevel@tonic-gate {
820Sstevel@tonic-gate struct logininfo *li;
830Sstevel@tonic-gate static int initialized = 0;
840Sstevel@tonic-gate static socklen_t fromlen;
850Sstevel@tonic-gate static struct sockaddr_storage from;
860Sstevel@tonic-gate static const char *remote_name_or_ip;
870Sstevel@tonic-gate
880Sstevel@tonic-gate if (pid == 0)
890Sstevel@tonic-gate pid = getpid();
900Sstevel@tonic-gate /*
910Sstevel@tonic-gate * Get IP address of client. If the connection is not a socket, let
920Sstevel@tonic-gate * the address be 0.0.0.0.
930Sstevel@tonic-gate */
940Sstevel@tonic-gate if (!initialized) {
950Sstevel@tonic-gate (void) memset(&from, 0, sizeof(from));
960Sstevel@tonic-gate if (packet_connection_is_on_socket()) {
970Sstevel@tonic-gate fromlen = sizeof(from);
980Sstevel@tonic-gate if (getpeername(packet_get_connection_in(),
990Sstevel@tonic-gate (struct sockaddr *) &from, &fromlen) < 0) {
1000Sstevel@tonic-gate debug("getpeername: %.100s", strerror(errno));
1010Sstevel@tonic-gate fatal_cleanup();
1020Sstevel@tonic-gate }
1030Sstevel@tonic-gate }
1040Sstevel@tonic-gate remote_name_or_ip = get_remote_name_or_ip(utmp_len,
1050Sstevel@tonic-gate options.verify_reverse_mapping);
1060Sstevel@tonic-gate
1070Sstevel@tonic-gate initialized = 1;
1080Sstevel@tonic-gate }
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate li = login_alloc_entry(pid, user, remote_name_or_ip, ttyname, progname);
1110Sstevel@tonic-gate login_set_addr(li, (struct sockaddr*) &from, sizeof(struct sockaddr));
1120Sstevel@tonic-gate (void) login_login(li);
1130Sstevel@tonic-gate login_free_entry(li);
1140Sstevel@tonic-gate }
1150Sstevel@tonic-gate
1160Sstevel@tonic-gate /* Records that the user has logged out. */
1170Sstevel@tonic-gate void
record_logout(pid_t pid,const char * ttyname,const char * progname,const char * user)1180Sstevel@tonic-gate record_logout(pid_t pid, const char *ttyname, const char *progname,
1190Sstevel@tonic-gate const char *user)
1200Sstevel@tonic-gate {
1210Sstevel@tonic-gate struct logininfo *li;
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate li = login_alloc_entry(pid, user, NULL, ttyname, progname);
1240Sstevel@tonic-gate (void) login_logout(li);
1250Sstevel@tonic-gate login_free_entry(li);
1260Sstevel@tonic-gate }
127