struct passwd * getpwnamallow(const char *user) { #ifdef HAVE_LOGIN_CAP extern login_cap_t *lc; #ifdef BSD_AUTH auth_session_t *as; #endif #endif struct ssh *ssh = active_state; /* XXX */ struct passwd *pw; struct connection_info *ci = get_connection_info(1, options.use_dns); ci->user = user; parse_server_match_config(&options, ci); log_change_level(options.log_level); process_permitopen(ssh, &options); pw = getpwnam(user); if (pw == NULL) { pfilter_notify(1); logit("Invalid user %.100s from %.100s port %d", user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); return (NULL); } if (!allowed_user(pw)) return (NULL); #ifdef HAVE_LOGIN_CAP if ((lc = login_getclass(pw->pw_class)) == NULL) { debug("unable to get login class: %s", user); return (NULL); } #ifdef BSD_AUTH if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 || auth_approval(as, lc, pw->pw_name, "ssh") <= 0) { debug("Approval failure for %s", user); pw = NULL; } if (as != NULL) auth_close(as); #endif #endif if (pw != NULL) return (pwcopy(pw)); return (NULL); }
struct passwd * mm_getpwnamallow(const char *username) { struct ssh *ssh = active_state; /* XXX */ Buffer m; struct passwd *pw; u_int len, i; ServerOptions *newopts; debug3("%s entering", __func__); buffer_init(&m); buffer_put_cstring(&m, username); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m); debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m); if (buffer_get_char(&m) == 0) { pw = NULL; goto out; } pw = buffer_get_string(&m, &len); if (len != sizeof(struct passwd)) fatal("%s: struct passwd size mismatch", __func__); pw->pw_name = buffer_get_string(&m, NULL); pw->pw_passwd = buffer_get_string(&m, NULL); #ifdef HAVE_STRUCT_PASSWD_PW_GECOS pw->pw_gecos = buffer_get_string(&m, NULL); #endif #ifdef HAVE_STRUCT_PASSWD_PW_CLASS pw->pw_class = buffer_get_string(&m, NULL); #endif pw->pw_dir = buffer_get_string(&m, NULL); pw->pw_shell = buffer_get_string(&m, NULL); out: /* copy options block as a Match directive may have changed some */ newopts = buffer_get_string(&m, &len); if (len != sizeof(*newopts)) fatal("%s: option block size mismatch", __func__); #define M_CP_STROPT(x) do { \ if (newopts->x != NULL) \ newopts->x = buffer_get_string(&m, NULL); \ } while (0) #define M_CP_STRARRAYOPT(x, nx) do { \ for (i = 0; i < newopts->nx; i++) \ newopts->x[i] = buffer_get_string(&m, NULL); \ } while (0) #define M_CP_STRARRAYOPT_ALLOC(x, nx) do { \ newopts->x = newopts->nx == 0 ? \ NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \ M_CP_STRARRAYOPT(x, nx); \ } while (0) /* See comment in servconf.h */ COPY_MATCH_STRING_OPTS(); #undef M_CP_STROPT #undef M_CP_STRARRAYOPT #undef M_CP_STRARRAYOPT_ALLOC copy_set_server_options(&options, newopts, 1); log_change_level(options.log_level); process_permitopen(ssh, &options); free(newopts); buffer_free(&m); return (pw); }
struct passwd * getpwnamallow(const char *user) { struct ssh *ssh = active_state; /* XXX */ #ifdef HAVE_LOGIN_CAP extern login_cap_t *lc; #ifdef BSD_AUTH auth_session_t *as; #endif #endif struct passwd *pw; struct connection_info *ci = get_connection_info(1, options.use_dns); ci->user = user; parse_server_match_config(&options, ci); log_change_level(options.log_level); process_permitopen(ssh, &options); #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_setauthdb(user); #endif pw = getpwnam(user); #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_restoreauthdb(); #endif #ifdef HAVE_CYGWIN /* * Windows usernames are case-insensitive. To avoid later problems * when trying to match the username, the user is only allowed to * login if the username is given in the same case as stored in the * user database. */ if (pw != NULL && strcmp(user, pw->pw_name) != 0) { logit("Login name %.100s does not match stored username %.100s", user, pw->pw_name); pw = NULL; } #endif if (pw == NULL) { logit("Invalid user %.100s from %.100s port %d", user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); #ifdef CUSTOM_FAILED_LOGIN record_failed_login(user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); #endif #ifdef SSH_AUDIT_EVENTS audit_event(SSH_INVALID_USER); #endif /* SSH_AUDIT_EVENTS */ return (NULL); } if (!allowed_user(pw)) return (NULL); #ifdef HAVE_LOGIN_CAP if ((lc = login_getclass(pw->pw_class)) == NULL) { debug("unable to get login class: %s", user); return (NULL); } #ifdef BSD_AUTH if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 || auth_approval(as, lc, pw->pw_name, "ssh") <= 0) { debug("Approval failure for %s", user); pw = NULL; } if (as != NULL) auth_close(as); #endif #endif if (pw != NULL) return (pwcopy(pw)); return (NULL); }