Page MenuHomeFreeBSD

D17056.id.diff
No OneTemporary

D17056.id.diff

Index: auth2.c
===================================================================
--- auth2.c
+++ 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);
@@ -291,7 +291,7 @@
authctxt->pw->pw_name, from_host);
packet_disconnect("Logins not available right now.");
}
- login_close(lc);
+ PRIVSEP(login_close(lc));
}
#endif /* HAVE_LOGIN_CAP */
Index: buffer.h
===================================================================
--- buffer.h
+++ buffer.h
@@ -21,6 +21,7 @@
#ifndef BUFFER_H
#define BUFFER_H
+#include <pwd.h>
#include "sshbuf.h"
typedef struct sshbuf Buffer;
@@ -91,5 +92,9 @@
void buffer_get_ecpoint(Buffer *, const EC_GROUP *, EC_POINT *);
#endif
+void buffer_put_passwd(Buffer *, const struct passwd *);
+struct passwd *buffer_get_passwd(Buffer *);
+void buffer_free_passwd(struct passwd *);
+
#endif /* BUFFER_H */
Index: buffer.c
===================================================================
--- buffer.c
+++ buffer.c
@@ -115,4 +115,75 @@
fatal("%s: buffer error", __func__);
}
+void
+buffer_put_passwd(Buffer *buffer, const struct passwd *pwent)
+{
+ /* We never send pointer values of struct passwd.
+ It is safe from wild pointer even if a new pointer member is added. */
+ buffer_put_int64(buffer, sizeof(*pwent));
+ buffer_put_cstring(buffer, pwent->pw_name);
+ buffer_put_cstring(buffer, "*");
+ buffer_put_int(buffer, pwent->pw_uid);
+ buffer_put_int(buffer, pwent->pw_gid);
+ buffer_put_int64(buffer, pwent->pw_change);
+#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
+ buffer_put_cstring(buffer, pwent->pw_gecos);
+#endif
+#ifdef HAVE_STRUCT_PASSWD_PW_CLASS
+ buffer_put_cstring(buffer, pwent->pw_class);
+#endif
+ buffer_put_cstring(buffer, pwent->pw_dir);
+ buffer_put_cstring(buffer, pwent->pw_shell);
+ buffer_put_int64(buffer, pwent->pw_expire);
+ buffer_put_int(buffer, pwent->pw_fields);
+}
+
+struct passwd *
+buffer_get_passwd(Buffer *buffer)
+{
+ struct passwd *pw;
+ size_t len;
+
+ /* check if size of struct passwd is as same as sender's size */
+ len = buffer_get_int64(buffer);
+ if (len != sizeof(*pw))
+ return NULL;
+
+ pw = calloc(1, sizeof(*pw));
+ if (pw == NULL)
+ return NULL;
+
+ pw->pw_name = buffer_get_string(buffer, NULL);
+ pw->pw_passwd = buffer_get_string(buffer, NULL);
+ pw->pw_uid = buffer_get_int(buffer);
+ pw->pw_gid = buffer_get_int(buffer);
+ pw->pw_change = buffer_get_int64(buffer);
+#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
+ pw->pw_gecos = buffer_get_string(buffer, NULL);
+#endif
+#ifdef HAVE_STRUCT_PASSWD_PW_CLASS
+ pw->pw_class = buffer_get_string(buffer, NULL);
+#endif
+ pw->pw_dir = buffer_get_string(buffer, NULL);
+ pw->pw_shell = buffer_get_string(buffer, NULL);
+ pw->pw_expire = buffer_get_int64(buffer);
+ pw->pw_fields = buffer_get_int(buffer);
+ return pw;
+}
+
+void
+buffer_free_passwd(struct passwd *pwent)
+{
+ free(pwent->pw_shell);
+ free(pwent->pw_dir);
+#ifdef HAVE_STRUCT_PASSWD_PW_CLASS
+ free(pwent->pw_class);
+#endif
+#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
+ free(pwent->pw_gecos);
+#endif
+ free(pwent->pw_passwd);
+ free(pwent->pw_name);
+ free(pwent);
+}
Index: monitor.h
===================================================================
--- monitor.h
+++ 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: monitor.c
===================================================================
--- monitor.c
+++ 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,40 @@
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_passwd(m);
+ if (pw == NULL)
+ fatal("%s: receive get struct passwd failed", __func__);
+
+ lc = login_getpwclass(pw);
+ if (lc == NULL) {
+ buffer_put_char(m, 0);
+ goto out;
+ }
+
+ buffer_put_char(m, 1);
+ buffer_put_cstring(m, lc->lc_class);
+ buffer_put_cstring(m, lc->lc_cap);
+ buffer_put_cstring(m, lc->lc_style);
+
+ login_close(lc);
+ out:
+ debug3("%s: sending MONITOR_ANS_GETPWCLASS", __func__);
+ mm_request_send(sock, MONITOR_ANS_GETPWCLASS, m);
+
+ buffer_free_passwd(pw);
+
+ return (0);
+}
+
/* Retrieves the password entry and also checks if the user is permitted */
int
@@ -744,17 +780,7 @@
authctxt->valid = 1;
buffer_put_char(m, 1);
- 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);
+ buffer_put_passwd(m, pwent);
out:
ssh_packet_set_log_preamble(ssh, "%suser %s",
Index: monitor_wrap.h
===================================================================
--- monitor_wrap.h
+++ monitor_wrap.h
@@ -28,6 +28,8 @@
#ifndef _MM_WRAP_H_
#define _MM_WRAP_H_
+#include <login_cap.h>
+
extern int use_privsep;
#define PRIVSEP(x) (use_privsep ? mm_##x : x)
@@ -45,6 +47,8 @@
const char *);
void mm_inform_authserv(char *, char *);
struct passwd *mm_getpwnamallow(const char *);
+login_cap_t *mm_login_getpwclass(const struct passwd *pwd);
+void mm_login_close(login_cap_t *lc);
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: monitor_wrap.c
===================================================================
--- monitor_wrap.c
+++ 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;
+
+ debug3("%s entering", __func__);
+
+ buffer_init(&m);
+ buffer_put_passwd(&m, pwent);
+
+ 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 = malloc(sizeof(*lc));
+ if (lc == NULL)
+ fatal("%s: fail to allocate memory", __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);
+}
+
+void
+mm_login_close(login_cap_t *lc)
+{
+ if (lc != NULL) {
+ free(lc->lc_style);
+ free(lc->lc_class);
+ free(lc->lc_cap);
+ free(lc);
+ }
+}
+
struct passwd *
mm_getpwnamallow(const char *username)
{
@@ -261,19 +306,9 @@
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);
+ pw = buffer_get_passwd(&m);
+ if (pw == NULL)
+ fatal("%s: receive struct passwd failed", __func__);
out:
/* copy options block as a Match directive may have changed some */
Index: sandbox-capsicum.c
===================================================================
--- sandbox-capsicum.c
+++ sandbox-capsicum.c
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <capsicum_helpers.h>
#include "log.h"
#include "monitor.h"
@@ -71,6 +72,8 @@
struct rlimit rl_zero;
cap_rights_t rights;
+ caph_cache_tzdata();
+
rl_zero.rlim_cur = rl_zero.rlim_max = 0;
if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1)
Index: sshd.c
===================================================================
--- sshd.c
+++ sshd.c
@@ -2084,6 +2084,10 @@
* the socket goes away.
*/
remote_ip = ssh_remote_ipaddr(ssh);
+#ifdef HAVE_LOGIN_CAP
+ /* Also caches remote hostname for sandboxed child*/
+ auth_get_canonical_hostname(ssh, options.use_dns);
+#endif
#ifdef SSH_AUDIT_EVENTS
audit_connection_from(remote_ip, remote_port);

File Metadata

Mime Type
text/plain
Expires
Fri, Jan 30, 10:37 PM (13 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28104956
Default Alt Text
D17056.id.diff (9 KB)

Event Timeline