/* * Generate and store last login message. This must be done before * login_login() is called and lastlog is updated. */ static void store_lastlog_message(const char *user, uid_t uid) { char *time_string, hostname[HOST_NAME_MAX+1] = ""; time_t last_login_time; int r; if (!options.print_lastlog) return; last_login_time = get_last_login_time(uid, user, hostname, sizeof(hostname)); if (last_login_time != 0) { if ((time_string = ctime(&last_login_time)) != NULL) time_string[strcspn(time_string, "\n")] = '\0'; if (strcmp(hostname, "") == 0) r = sshbuf_putf(loginmsg, "Last login: %s\r\n", time_string); else r = sshbuf_putf(loginmsg, "Last login: %s from %s\r\n", time_string, hostname); if (r != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); } }
/* * Generate and store last login message. This must be done before * login_login() is called and lastlog is updated. */ static void store_lastlog_message(const char *user, uid_t uid) { char *time_string, hostname[MAXHOSTNAMELEN] = "", buf[512]; time_t last_login_time; #ifndef NO_SSH_LASTLOG if (!options.print_lastlog) return; last_login_time = get_last_login_time(uid, user, hostname, sizeof(hostname)); if (last_login_time != 0) { time_string = ctime(&last_login_time); time_string[strcspn(time_string, "\n")] = '\0'; if (strcmp(hostname, "") == 0) snprintf(buf, sizeof(buf), "Last login: %s\r\n", time_string); else snprintf(buf, sizeof(buf), "Last login: %s from %s\r\n", time_string, hostname); buffer_append(&loginmsg, buf, strlen(buf)); } #endif /* NO_SSH_LASTLOG */ }
/* * Generate and store last login message. This must be done before * login_login() is called and lastlog is updated. */ static void store_lastlog_message(const char *user, uid_t uid) { #ifndef NO_SSH_LASTLOG char *time_string, hostname[MAXHOSTNAMELEN] = "", buf[512]; time_t last_login_time; if (!options.print_lastlog) return; # ifdef CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG time_string = sys_auth_get_lastlogin_msg(user, uid); if (time_string != NULL) { buffer_append(&loginmsg, time_string, strlen(time_string)); free(time_string); } # else last_login_time = get_last_login_time(uid, user, hostname, sizeof(hostname)); if (last_login_time != 0) { time_string = ctime(&last_login_time); time_string[strcspn(time_string, "\n")] = '\0'; if (strcmp(hostname, "") == 0) snprintf(buf, sizeof(buf), "Last login: %s\r\n", time_string); else snprintf(buf, sizeof(buf), "Last login: %s from %s\r\n", time_string, hostname); buffer_append(&loginmsg, buf, strlen(buf)); } # endif /* CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG */ #endif /* NO_SSH_LASTLOG */ }
/* * Generate and store last login message. This must be done before * login_login() is called and lastlog is updated. */ static void store_lastlog_message(const char *user, uid_t uid) { char *time_string, hostname[HOST_NAME_MAX+1] = "", buf[512]; time_t last_login_time; if (!options.print_lastlog) return; last_login_time = get_last_login_time(uid, user, hostname, sizeof(hostname)); if (last_login_time != 0) { if ((time_string = ctime(&last_login_time)) != NULL) time_string[strcspn(time_string, "\n")] = '\0'; if (strcmp(hostname, "") == 0) snprintf(buf, sizeof(buf), "Last login: %s\r\n", time_string); else snprintf(buf, sizeof(buf), "Last login: %s from %s\r\n", time_string, hostname); buffer_append(&loginmsg, buf, strlen(buf)); } }
/* * To be called from userauth methods, directly (as in keyboard-interactive) or * indirectly (from auth_pam_password() or from do_pam_non_initial_userauth(). * * The caller is responsible for calling new_start_pam() first. * * PAM state is not cleaned up here on error. This is left to subsequent calls * to new_start_pam() or to the cleanup function upon authentication error. */ int finish_userauth_do_pam(Authctxt *authctxt) { int retval; char *user, *method; /* Various checks; fail gracefully */ if (authctxt == NULL || authctxt->pam == NULL) return PAM_SYSTEM_ERR; /* shouldn't happen */ if (compat20) { if (authctxt->method == NULL || authctxt->method->name == NULL) return PAM_SYSTEM_ERR; /* shouldn't happen */ method = authctxt->method->name; } else if ((method = authctxt->v1_auth_name) == NULL) return PAM_SYSTEM_ERR; /* shouldn't happen */ if (AUTHPAM_DONE(authctxt)) return PAM_SYSTEM_ERR; /* shouldn't happen */ if (!(authctxt->pam->state & PAM_S_DONE_ACCT_MGMT)) { retval = pam_acct_mgmt(authctxt->pam->h, 0); authctxt->pam->last_pam_retval = retval; if (retval == PAM_NEW_AUTHTOK_REQD) { userauth_force_kbdint(); return retval; } if (retval != PAM_SUCCESS) return retval; authctxt->pam->state |= PAM_S_DONE_ACCT_MGMT; } /* * Handle PAM_USER change, if any. * * We do this before pam_open_session() because we need the PAM_USER's * UID for: * * a) PermitRootLogin checking * b) to get at the lastlog entry before pam_open_session() updates it. */ retval = pam_get_item(authctxt->pam->h, PAM_USER, (void **) &user); if (retval != PAM_SUCCESS) { fatal("PAM failure: pam_get_item(PAM_USER) " "returned %d: %.200s", retval, PAM_STRERROR(authctxt->pam->h, retval)); } if (user == NULL || *user == '\0') { debug("PAM set NULL PAM_USER"); return PAM_PERM_DENIED; } if (strcmp(user, authctxt->user) != 0) { log("PAM changed the SSH username"); pwfree(&authctxt->pw); authctxt->pw = PRIVSEP(getpwnamallow(user)); authctxt->valid = (authctxt->pw != NULL); xfree(authctxt->user); authctxt->user = xstrdup(user); } if (!authctxt->valid) { debug2("PAM set PAM_USER to unknown user"); /* * Return success, userauth_finish() will catch * this and send back a failure message. */ return PAM_SUCCESS; } /* Check PermitRootLogin semantics */ if (authctxt->pw->pw_uid == 0 && !auth_root_allowed(method)) return PAM_PERM_DENIED; if (!(authctxt->pam->state & PAM_S_DONE_SETCRED)) { retval = pam_setcred(authctxt->pam->h, PAM_ESTABLISH_CRED); authctxt->pam->last_pam_retval = retval; if (retval != PAM_SUCCESS) return retval; authctxt->pam->state |= PAM_S_DONE_SETCRED; #ifdef GSSAPI /* * Store GSS-API delegated creds after pam_setcred(), which may * have set the current credential store. */ ssh_gssapi_storecreds(NULL, authctxt); #endif /* GSSAPI */ } /* * On Solaris pam_unix_session.so updates the lastlog, but does * not converse a PAM_TEXT_INFO message about it. So we need to * fetch the lastlog entry here and save it for use later. */ authctxt->last_login_time = get_last_login_time(authctxt->pw->pw_uid, authctxt->pw->pw_name, authctxt->last_login_host, sizeof(authctxt->last_login_host)); if (!(authctxt->pam->state & PAM_S_DONE_OPEN_SESSION)) { retval = pam_open_session(authctxt->pam->h, 0); authctxt->pam->last_pam_retval = retval; if (retval != PAM_SUCCESS) return retval; authctxt->pam->state |= PAM_S_DONE_OPEN_SESSION; } /* * All PAM work done successfully. * * PAM handle stays around so we can call pam_close_session() on * it later. */ return PAM_SUCCESS; }