Index: crypto/openssh/auth2.c =================================================================== --- crypto/openssh/auth2.c +++ crypto/openssh/auth2.c @@ -276,7 +276,7 @@ #ifdef HAVE_LOGIN_CAP if (authctxt->pw != NULL && - (lc = login_getpwclass(authctxt->pw)) != NULL) { + (lc = PRIVSEP(login_getpwclass(authctxt->pw))) != NULL) { logit("user %s login class %s", authctxt->pw->pw_name, authctxt->pw->pw_class); from_host = auth_get_canonical_hostname(ssh, options.use_dns); Index: crypto/openssh/monitor.h =================================================================== --- crypto/openssh/monitor.h +++ crypto/openssh/monitor.h @@ -55,7 +55,8 @@ MONITOR_REQ_GSSSTEP = 44, MONITOR_ANS_GSSSTEP = 45, MONITOR_REQ_GSSUSEROK = 46, MONITOR_ANS_GSSUSEROK = 47, MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, - MONITOR_REQ_TERM = 50, + MONITOR_REQ_GETPWCLASS = 50, MONITOR_ANS_GETPWCLASS = 51, + MONITOR_REQ_TERM = 52, MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, Index: crypto/openssh/monitor.c =================================================================== --- crypto/openssh/monitor.c +++ crypto/openssh/monitor.c @@ -125,6 +125,7 @@ int mm_answer_moduli(int, Buffer *); int mm_answer_sign(int, Buffer *); +int mm_answer_login_getpwclass(int, Buffer *); int mm_answer_pwnamallow(int, Buffer *); int mm_answer_auth2_read_banner(int, Buffer *); int mm_answer_authserv(int, Buffer *); @@ -203,6 +204,7 @@ #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, + {MONITOR_REQ_GETPWCLASS, MON_AUTH, mm_answer_login_getpwclass}, {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, @@ -707,6 +709,61 @@ return (0); } +int +mm_answer_login_getpwclass(int sock, Buffer *m) +{ + login_cap_t *lc; + struct passwd *pw; + u_int len; + + debug3("%s", __func__); + + 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); + + lc = login_getpwclass(pw); + if (lc == NULL) { + buffer_put_char(m, 0); + goto out; + } + + buffer_put_char(m, 1); + buffer_put_string(m, lc, sizeof(login_cap_t)); + buffer_put_cstring(m, lc->lc_class); + buffer_put_cstring(m, lc->lc_cap); + buffer_put_cstring(m, lc->lc_style); + + debug3("%s: sending MONITOR_ANS_GETPWCLASS: %s", __func__, lc->lc_class); + login_close(lc); + out: + mm_request_send(sock, MONITOR_ANS_GETPWCLASS, m); + + free(pw->pw_shell); + free(pw->pw_dir); +#ifdef HAVE_STRUCT_PASSWD_PW_CLASS + free(pw->pw_class); +#endif +#ifdef HAVE_STRUCT_PASSWD_PW_GECOS + free(pw->pw_gecos); +#endif + free(pw->pw_passwd); + free(pw->pw_name); + free(pw); + + return (0); +} + /* Retrieves the password entry and also checks if the user is permitted */ int Index: crypto/openssh/monitor_wrap.h =================================================================== --- crypto/openssh/monitor_wrap.h +++ crypto/openssh/monitor_wrap.h @@ -45,6 +45,7 @@ const char *); void mm_inform_authserv(char *, char *); struct passwd *mm_getpwnamallow(const char *); +login_cap_t *mm_login_getpwclass(const struct passwd *pwd); char *mm_auth2_read_banner(void); int mm_auth_password(struct ssh *, char *); int mm_key_allowed(enum mm_keytype, const char *, const char *, struct sshkey *, Index: crypto/openssh/monitor_wrap.c =================================================================== --- crypto/openssh/monitor_wrap.c +++ crypto/openssh/monitor_wrap.c @@ -238,6 +238,51 @@ return (0); } +login_cap_t * +mm_login_getpwclass(const struct passwd *pwent) +{ + Buffer m; + login_cap_t *lc; + u_int len; + + debug3("%s entering", __func__); + + buffer_init(&m); + buffer_put_string(&m, pwent, sizeof(struct passwd)); + buffer_put_cstring(&m, pwent->pw_name); + buffer_put_cstring(&m, "*"); +#ifdef HAVE_STRUCT_PASSWD_PW_GECOS + buffer_put_cstring(&m, pwent->pw_gecos); +#endif +#ifdef HAVE_STRUCT_PASSWD_PW_CLASS + buffer_put_cstring(&m, pwent->pw_class); +#endif + buffer_put_cstring(&m, pwent->pw_dir); + buffer_put_cstring(&m, pwent->pw_shell); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GETPWCLASS, &m); + + debug3("%s: waiting for MONITOR_ANS_GETPWCLASS", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GETPWCLASS, &m); + + if (buffer_get_char(&m) == 0) { + lc = NULL; + goto out; + } + + lc = buffer_get_string(&m, &len); + if (len != sizeof(login_cap_t)) + fatal("%s: login_cap_t size mismatch", __func__); + lc->lc_class = buffer_get_string(&m, NULL); + lc->lc_cap = buffer_get_string(&m, NULL); + lc->lc_style = buffer_get_string(&m, NULL); + + out: + buffer_free(&m); + + return (lc); +} + struct passwd * mm_getpwnamallow(const char *username) { Index: crypto/openssh/sandbox-capsicum.c =================================================================== --- crypto/openssh/sandbox-capsicum.c +++ crypto/openssh/sandbox-capsicum.c @@ -71,6 +71,9 @@ struct rlimit rl_zero; cap_rights_t rights; + /* cache timezone data */ + tzset(); + rl_zero.rlim_cur = rl_zero.rlim_max = 0; if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1)