sshlogin.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /* $OpenBSD: sshlogin.c,v 1.34 2019/06/28 13:35:04 deraadt 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. #include "includes.h"
  42. #include <sys/types.h>
  43. #include <sys/socket.h>
  44. #include <netinet/in.h>
  45. #include <errno.h>
  46. #include <fcntl.h>
  47. #include <stdarg.h>
  48. #include <stdio.h>
  49. #include <string.h>
  50. #include <time.h>
  51. #include <unistd.h>
  52. #include <limits.h>
  53. #include "sshlogin.h"
  54. #include "ssherr.h"
  55. #include "loginrec.h"
  56. #include "log.h"
  57. #include "sshbuf.h"
  58. #include "misc.h"
  59. #include "servconf.h"
  60. extern struct sshbuf *loginmsg;
  61. extern ServerOptions options;
  62. /*
  63. * Returns the time when the user last logged in. Returns 0 if the
  64. * information is not available. This must be called before record_login.
  65. * The host the user logged in from will be returned in buf.
  66. */
  67. time_t
  68. get_last_login_time(uid_t uid, const char *logname,
  69. char *buf, size_t bufsize)
  70. {
  71. struct logininfo li;
  72. login_get_lastlog(&li, uid);
  73. strlcpy(buf, li.hostname, bufsize);
  74. return (time_t)li.tv_sec;
  75. }
  76. /*
  77. * Generate and store last login message. This must be done before
  78. * login_login() is called and lastlog is updated.
  79. */
  80. static void
  81. store_lastlog_message(const char *user, uid_t uid)
  82. {
  83. #ifndef NO_SSH_LASTLOG
  84. # ifndef CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG
  85. char hostname[HOST_NAME_MAX+1] = "";
  86. time_t last_login_time;
  87. # endif
  88. char *time_string;
  89. int r;
  90. if (!options.print_lastlog)
  91. return;
  92. # ifdef CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG
  93. time_string = sys_auth_get_lastlogin_msg(user, uid);
  94. if (time_string != NULL) {
  95. if ((r = sshbuf_put(loginmsg,
  96. time_string, strlen(time_string))) != 0)
  97. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  98. free(time_string);
  99. }
  100. # else
  101. last_login_time = get_last_login_time(uid, user, hostname,
  102. sizeof(hostname));
  103. if (last_login_time != 0) {
  104. time_string = ctime(&last_login_time);
  105. time_string[strcspn(time_string, "\n")] = '\0';
  106. if (strcmp(hostname, "") == 0)
  107. r = sshbuf_putf(loginmsg, "Last login: %s\r\n",
  108. time_string);
  109. else
  110. r = sshbuf_putf(loginmsg, "Last login: %s from %s\r\n",
  111. time_string, hostname);
  112. if (r != 0)
  113. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  114. }
  115. # endif /* CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG */
  116. #endif /* NO_SSH_LASTLOG */
  117. }
  118. /*
  119. * Records that the user has logged in. I wish these parts of operating
  120. * systems were more standardized.
  121. */
  122. void
  123. record_login(pid_t pid, const char *tty, const char *user, uid_t uid,
  124. const char *host, struct sockaddr *addr, socklen_t addrlen)
  125. {
  126. struct logininfo *li;
  127. /* save previous login details before writing new */
  128. store_lastlog_message(user, uid);
  129. li = login_alloc_entry(pid, user, host, tty);
  130. login_set_addr(li, addr, addrlen);
  131. login_login(li);
  132. login_free_entry(li);
  133. }
  134. #ifdef LOGIN_NEEDS_UTMPX
  135. void
  136. record_utmp_only(pid_t pid, const char *ttyname, const char *user,
  137. const char *host, struct sockaddr *addr, socklen_t addrlen)
  138. {
  139. struct logininfo *li;
  140. li = login_alloc_entry(pid, user, host, ttyname);
  141. login_set_addr(li, addr, addrlen);
  142. login_utmp_only(li);
  143. login_free_entry(li);
  144. }
  145. #endif
  146. /* Records that the user has logged out. */
  147. void
  148. record_logout(pid_t pid, const char *tty, const char *user)
  149. {
  150. struct logininfo *li;
  151. li = login_alloc_entry(pid, user, NULL, tty);
  152. login_logout(li);
  153. login_free_entry(li);
  154. }