X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/92f90c575dc90af03902c853eb501d426ea453b1..48e671d5303c70deea9cde5c1a785882c0501f6e:/login.c diff --git a/login.c b/login.c index 335e9b30..633cc32b 100644 --- a/login.c +++ b/login.c @@ -53,17 +53,28 @@ unsigned long get_last_login_time(uid_t uid, const char *logname, char *buf, unsigned int bufsize) { +#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) struct lastlog ll; char *lastlog; int fd; +#ifdef LASTLOG_IS_DIR + char buf[1024]; +#endif /* LASTLOG_IS_DIR */ lastlog = _PATH_LASTLOG; buf[0] = '\0'; +#ifdef LASTLOG_IS_DIR fd = open(lastlog, O_RDONLY); if (fd < 0) return 0; lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); +#else /* LASTLOG_IS_DIR */ + snprintf(buf, sizeof(buf), "%s/%s", lastlog, logname); + fd = open(buf, O_RDONLY); + if (fd < 0) + return 0; +#endif /* LASTLOG_IS_DIR */ if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) { close(fd); return 0; @@ -74,6 +85,49 @@ get_last_login_time(uid_t uid, const char *logname, strncpy(buf, ll.ll_host, bufsize - 1); buf[bufsize - 1] = 0; return ll.ll_time; + +#else /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ + /* Look in wtmp for the last login */ + struct utmp wt; + char *wt_file = _PATH_WTMP; + int fd1; + unsigned long t = 0; + + if ( (fd1 = open(wt_file, O_RDONLY)) < 0 ) { + error("Couldn't open %.100s to find last login time.", wt_file); + return 0; + } + + /* seek to last record of file */ + lseek(fd1, (off_t)(0-sizeof(struct utmp)), SEEK_END); + + /* loop through wtmp for our last user login record */ + do { + if (read(fd1, &wt, sizeof(wt)) != sizeof(wt)) { + close(fd1); + return 0; + } + + if ( wt.ut_type == USER_PROCESS) { + if ( !strncmp(logname, wt.ut_user, 8) ) { + t = (unsigned long) wt.ut_time; +#ifdef HAVE_HOST_IN_UTMP + if (bufsize > sizeof(wt.ut_host) + 1) + bufsize = sizeof(wt.ut_host) + 1; + strncpy(buf, wt.ut_host, bufsize - 1); + buf[bufsize - 1] = 0; +#else /* HAVE_HOST_IN_UTMP */ + buf[0] = 0; +#endif /* HAVE_HOST_IN_UTMP */ + } + } + + if (lseek(fd1, (off_t)(0-2*sizeof(struct utmp)), SEEK_CUR) == -1) + break; + } while (t == 0); + + return t; +#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ } /* @@ -83,37 +137,109 @@ get_last_login_time(uid_t uid, const char *logname, void record_login(int pid, const char *ttyname, const char *user, uid_t uid, - const char *host, struct sockaddr_in * addr) + const char *host, struct sockaddr * addr) { - int fd; +#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) struct lastlog ll; char *lastlog; - struct UTMP_STR u; - const char *utmp, *wtmp; +#ifdef LASTLOG_IS_DIR + char buf[1024]; +#endif /* LASTLOG_IS_DIR */ +#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ + struct utmp u; +#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) + struct utmpx utx; +#endif /* Construct an utmp/wtmp entry. */ memset(&u, 0, sizeof(u)); strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line)); -#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) - u.ut_tv.tv_sec = time(NULL); - strncpy(u.ut_user, user, sizeof(u.ut_name)); -#else - u.ut_time = time(NULL); +#if defined(HAVE_ID_IN_UTMP) + strncpy(u.ut_id, ttyname + 8, sizeof(u.ut_id)); +#endif /* defined(HAVE_ID_IN_UTMP) */ strncpy(u.ut_name, user, sizeof(u.ut_name)); -#endif -#if defined(HAVE_HOST_IN_UTMP) || defined(HAVE_HOST_IN_UTMPX) +#if defined(HAVE_TV_IN_UTMP) + (void)gettimeofday(&u.ut_tv, NULL); +#else /* defined(HAVE_TV_IN_UTMP) */ + u.ut_time = time(NULL); +#endif /* defined(HAVE_TV_IN_UTMP) */ +#if defined(HAVE_PID_IN_UTMP) + u.ut_pid = (pid_t)pid; +#endif /* HAVE_PID_IN_UTMP */ +#if defined(HAVE_TYPE_IN_UTMP) + u.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS; +#endif /* HAVE_TYPE_IN_UTMP */ +#if defined(HAVE_HOST_IN_UTMP) strncpy(u.ut_host, host, sizeof(u.ut_host)); #endif +#if defined(HAVE_ADDR_IN_UTMP) + switch (addr->sa_family) { + case AF_INET: { + struct sockaddr_in *in = (struct sockaddr_in*)addr; + memcpy(&(u.ut_addr), &(in->sin_addr), sizeof(&(in->sin_addr))); + break; + } +#if defined(HAVE_ADDR_V6_IN_UTMP) + case AF_INET6: { + struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr; + memcpy(u.ut_addr_v6, &(in6->sin6_addr), sizeof(&(in6->sin6_addr))); + break; + } +#endif + default: + break; + } +#endif - /* Figure out the file names. */ - utmp = _PATH_UTMP; - wtmp = _PATH_WTMP; +#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) + memset(&utx, 0, sizeof(utx)); + strncpy(utx.ut_user, user, sizeof(utx.ut_name)); + strncpy(utx.ut_line, ttyname + 5, sizeof(utx.ut_line)); + strncpy(utx.ut_id, ttyname + 8, sizeof(utx.ut_id)); + utx.ut_pid = (pid_t)pid; + (void)gettimeofday(&utx.ut_tv, NULL); + utx.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS; +# ifdef HAVE_HOST_IN_UTMPX +# ifdef HAVE_SYSLEN_IN_UTMPX + utx.ut_syslen = strlen(host); + strncpy(utx.ut_host, host, utx.ut_syslen); +# else + strncpy(utx.ut_host, host, sizeof(utx.ut_host)); +# endif /* HAVE_SYSLEN_IN_UTMPX */ +# endif +#if defined(HAVE_ADDR_IN_UTMPX) + switch (addr->sa_family) { + case AF_INET: { + struct sockaddr_in *in = (struct sockaddr_in*)addr; + memcpy(&(utx.ut_addr), &(in->sin_addr), sizeof(&(in->sin_addr))); + break; + } +#if defined(HAVE_ADDR_V6_IN_UTMPX) + case AF_INET6: { + struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr; + memcpy(utx.ut_addr_v6, &(in6->sin6_addr), sizeof(&(in6->sin6_addr))); + break; + } +#endif + default: + break; + } +#endif +#endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */ +/*#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) && !defined(HAVE_LOGIN)*/ +#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) + login(&u, &utx); +#else /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */ login(&u); +#endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */ + +#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) lastlog = _PATH_LASTLOG; /* Update lastlog unless actually recording a logout. */ if (strcmp(user, "") != 0) { + int fd; /* * It is safer to bzero the lastlog structure first because * some systems might have some extra fields in it (e.g. SGI) @@ -124,14 +250,21 @@ record_login(int pid, const char *ttyname, const char *user, uid_t uid, ll.ll_time = time(NULL); strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line)); strncpy(ll.ll_host, host, sizeof(ll.ll_host)); +#ifdef LASTLOG_IS_DIR + snprintf(buf, sizeof(buf), "%s/%s", lastlog, logname); + fd = open(buf, O_RDWR); + if (fd >= 0) { +#else /* LASTLOG_IS_DIR */ fd = open(lastlog, O_RDWR); if (fd >= 0) { lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); +#endif /* LASTLOG_IS_DIR */ if (write(fd, &ll, sizeof(ll)) != sizeof(ll)) log("Could not write %.100s: %.100s", lastlog, strerror(errno)); close(fd); } } +#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ } /* Records that the user has logged out. */