sshlogin.c revision 76607
14Srgrimes/* 24Srgrimes * Author: Tatu Ylonen <ylo@cs.hut.fi> 34Srgrimes * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 44Srgrimes * All rights reserved 54Srgrimes * This file performs some of the things login(1) normally does. We cannot 64Srgrimes * easily use something like login -p -h host -f user, because there are 74Srgrimes * several different logins around, and it is hard to determined what kind of 84Srgrimes * login the current system has. Also, we want to be able to execute commands 94Srgrimes * on a tty. 104Srgrimes * 114Srgrimes * As far as I am concerned, the code I have written for this software 124Srgrimes * can be used freely for any purpose. Any derived versions of this 134Srgrimes * software must be clearly marked as such, and if the derived work is 144Srgrimes * incompatible with the protocol description in the RFC file, it must be 154Srgrimes * called by a name other than "ssh" or "Secure Shell". 164Srgrimes * 174Srgrimes * Copyright (c) 1999 Theo de Raadt. All rights reserved. 184Srgrimes * Copyright (c) 1999 Markus Friedl. All rights reserved. 194Srgrimes * 204Srgrimes * Redistribution and use in source and binary forms, with or without 214Srgrimes * modification, are permitted provided that the following conditions 224Srgrimes * are met: 234Srgrimes * 1. Redistributions of source code must retain the above copyright 244Srgrimes * notice, this list of conditions and the following disclaimer. 254Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 264Srgrimes * notice, this list of conditions and the following disclaimer in the 274Srgrimes * documentation and/or other materials provided with the distribution. 284Srgrimes * 294Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 304Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 314Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 324Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 33621Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 3450477Speter * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 354Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 364Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37719Swollman * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 385594Sbde * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39719Swollman */ 404Srgrimes 414Srgrimes#include "includes.h" 424SrgrimesRCSID("$OpenBSD: sshlogin.c,v 1.2 2001/03/24 16:43:27 stevesk Exp $"); 434SrgrimesRCSID("$FreeBSD: head/crypto/openssh/sshlogin.c 76607 2001-05-15 01:50:40Z green $"); 444Srgrimes 454Srgrimes#include <libutil.h> 464Srgrimes#include <utmp.h> 474Srgrimes#include "sshlogin.h" 484Srgrimes#include "log.h" 494Srgrimes 504Srgrimes/* 514Srgrimes * Returns the time when the user last logged in. Returns 0 if the 524Srgrimes * information is not available. This must be called before record_login. 534Srgrimes * The host the user logged in from will be returned in buf. 544Srgrimes */ 5524112Skato 5624112Skatou_long 5724112Skatoget_last_login_time(uid_t uid, const char *logname, 5824112Skato char *buf, u_int bufsize) 5924112Skato{ 6024112Skato struct lastlog ll; 612495Spst char *lastlog; 622495Spst int fd; 6319621Sdyson 6419621Sdyson lastlog = _PATH_LASTLOG; 6519621Sdyson buf[0] = '\0'; 6619621Sdyson 6719621Sdyson fd = open(lastlog, O_RDONLY); 6819621Sdyson if (fd < 0) 6919621Sdyson return 0; 7019621Sdyson lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); 7119621Sdyson if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) { 7219621Sdyson close(fd); 7319621Sdyson return 0; 7451127Speter } 7551127Speter close(fd); 7619621Sdyson if (bufsize > sizeof(ll.ll_host) + 1) 7719621Sdyson bufsize = sizeof(ll.ll_host) + 1; 7819621Sdyson strncpy(buf, ll.ll_host, bufsize - 1); 7919621Sdyson buf[bufsize - 1] = 0; 8098650Smp return ll.ll_time; 8198650Smp} 8298650Smp 8398650Smp/* 8498650Smp * Records that the user has logged in. I these parts of operating systems 8598650Smp * were more standardized. 8698650Smp */ 8798650Smp 8898650Smpvoid 8998650Smprecord_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, 9098650Smp const char *host, struct sockaddr * addr) 9198650Smp{ 9298650Smp int fd; 9398650Smp struct lastlog ll; 9498650Smp char *lastlog; 9598650Smp struct utmp u; 9698650Smp 9798650Smp /* Construct an utmp/wtmp entry. */ 9898650Smp memset(&u, 0, sizeof(u)); 9998650Smp strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line)); 10098650Smp u.ut_time = time(NULL); 10198650Smp strncpy(u.ut_name, user, sizeof(u.ut_name)); 10298650Smp realhostname_sa(u.ut_host, sizeof(u.ut_host), addr, addr->sa_len); 10398650Smp 10498650Smp login(&u); 10598650Smp lastlog = _PATH_LASTLOG; 10698650Smp 10798650Smp /* Update lastlog unless actually recording a logout. */ 10898650Smp if (strcmp(user, "") != 0) { 109108909Sjhb /* 11098650Smp * It is safer to bzero the lastlog structure first because 11198650Smp * some systems might have some extra fields in it (e.g. SGI) 11298650Smp */ 11319621Sdyson memset(&ll, 0, sizeof(ll)); 11419621Sdyson 115109691Sjhb /* Update lastlog. */ 116108909Sjhb ll.ll_time = time(NULL); 117108909Sjhb strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line)); 118108909Sjhb strncpy(ll.ll_host, host, sizeof(ll.ll_host)); 119108909Sjhb fd = open(lastlog, O_RDWR); 120108909Sjhb if (fd >= 0) { 121108909Sjhb lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); 122108909Sjhb if (write(fd, &ll, sizeof(ll)) != sizeof(ll)) 12345406Smsmith log("Could not write %.100s: %.100s", lastlog, strerror(errno)); 12445406Smsmith close(fd); 12545406Smsmith } 12645406Smsmith } 12745406Smsmith} 12845406Smsmith 12945406Smsmith/* Records that the user has logged out. */ 13045406Smsmith 13145406Smsmithvoid 13245406Smsmithrecord_logout(pid_t pid, const char *ttyname) 13345406Smsmith{ 13445406Smsmith const char *line = ttyname + 5; /* /dev/ttyq8 -> ttyq8 */ 13545406Smsmith if (logout(line)) 13645406Smsmith logwtmp(line, "", ""); 13745406Smsmith} 13845406Smsmith