+const char *
+get_remote_name_or_ip(void)
+{
+ static const char *remote = "";
+ if (utmp_len > 0)
+ remote = get_canonical_hostname(options.reverse_mapping_check);
+ if (utmp_len == 0 || strlen(remote) > utmp_len)
+ remote = get_remote_ipaddr();
+ return remote;
+}
+
+/* administrative, login(1)-like work */
+void
+do_login(Session *s, const char *command)
+{
+ FILE *f;
+ char *time_string;
+ char buf[256];
+ char hostname[MAXHOSTNAMELEN];
+ socklen_t fromlen;
+ struct sockaddr_storage from;
+ struct stat st;
+ time_t last_login_time;
+ struct passwd * pw = s->pw;
+ pid_t pid = getpid();
+
+ /*
+ * Get IP address of client. If the connection is not a socket, let
+ * the address be 0.0.0.0.
+ */
+ memset(&from, 0, sizeof(from));
+ if (packet_connection_is_on_socket()) {
+ fromlen = sizeof(from);
+ if (getpeername(packet_get_connection_in(),
+ (struct sockaddr *) & from, &fromlen) < 0) {
+ debug("getpeername: %.100s", strerror(errno));
+ fatal_cleanup();
+ }
+ }
+
+ /* Get the time and hostname when the user last logged in. */
+ hostname[0] = '\0';
+ last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name,
+ hostname, sizeof(hostname));
+
+ /* Record that there was a login on that tty from the remote host. */
+ record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
+ get_remote_name_or_ip(), (struct sockaddr *)&from);
+
+#ifdef USE_PAM
+ /*
+ * If password change is needed, do it now.
+ * This needs to occur before the ~/.hushlogin check.
+ */
+ if (is_pam_password_change_required()) {
+ print_pam_messages();
+ do_pam_chauthtok();
+ }
+#endif
+
+ /* Done if .hushlogin exists or a command given. */
+ if (command != NULL)
+ return;
+ snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
+#ifdef HAVE_LOGIN_CAP
+ if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
+#else
+ if (stat(buf, &st) >= 0)
+#endif
+ return;
+
+#ifdef USE_PAM
+ if (!is_pam_password_change_required())
+ print_pam_messages();
+#endif /* USE_PAM */
+#ifdef WITH_AIXAUTHENTICATE
+ if (aixloginmsg && *aixloginmsg)
+ printf("%s\n", aixloginmsg);
+#endif /* WITH_AIXAUTHENTICATE */
+
+ if (last_login_time != 0) {
+ time_string = ctime(&last_login_time);
+ if (strchr(time_string, '\n'))
+ *strchr(time_string, '\n') = 0;
+ if (strcmp(hostname, "") == 0)
+ printf("Last login: %s\r\n", time_string);
+ else
+ printf("Last login: %s from %s\r\n", time_string, hostname);
+ }
+ if (options.print_motd) {
+#ifdef HAVE_LOGIN_CAP
+ f = fopen(login_getcapstr(lc, "welcome", "/etc/motd",
+ "/etc/motd"), "r");
+#else
+ f = fopen("/etc/motd", "r");
+#endif
+ if (f) {
+ while (fgets(buf, sizeof(buf), f))
+ fputs(buf, stdout);
+ fclose(f);
+ }
+ }
+}
+