summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auth.h1
-rw-r--r--auth2.c10
-rw-r--r--monitor.c37
-rw-r--r--monitor.h2
-rw-r--r--monitor_wrap.c27
-rw-r--r--monitor_wrap.h3
-rw-r--r--openbsd-compat/port-linux.c21
-rw-r--r--openbsd-compat/port-linux.h4
-rw-r--r--platform.c4
-rw-r--r--platform.h2
-rw-r--r--session.c10
-rw-r--r--session.h2
-rw-r--r--sshd.c2
-rw-r--r--sshpty.c4
-rw-r--r--sshpty.h2
15 files changed, 99 insertions, 32 deletions
diff --git a/auth.h b/auth.h
index becc672b5..5da9fe75f 100644
--- a/auth.h
+++ b/auth.h
@@ -63,6 +63,7 @@ struct Authctxt {
63 char *service; 63 char *service;
64 struct passwd *pw; /* set if 'valid' */ 64 struct passwd *pw; /* set if 'valid' */
65 char *style; 65 char *style;
66 char *role;
66 67
67 /* Method lists for multiple authentication */ 68 /* Method lists for multiple authentication */
68 char **auth_methods; /* modified from server config */ 69 char **auth_methods; /* modified from server config */
diff --git a/auth2.c b/auth2.c
index 1c217268c..92a6bcaf4 100644
--- a/auth2.c
+++ b/auth2.c
@@ -265,7 +265,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
265{ 265{
266 Authctxt *authctxt = ssh->authctxt; 266 Authctxt *authctxt = ssh->authctxt;
267 Authmethod *m = NULL; 267 Authmethod *m = NULL;
268 char *user = NULL, *service = NULL, *method = NULL, *style = NULL; 268 char *user = NULL, *service = NULL, *method = NULL, *style = NULL, *role = NULL;
269 int r, authenticated = 0; 269 int r, authenticated = 0;
270 double tstart = monotime_double(); 270 double tstart = monotime_double();
271 271
@@ -279,8 +279,13 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
279 debug("userauth-request for user %s service %s method %s", user, service, method); 279 debug("userauth-request for user %s service %s method %s", user, service, method);
280 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); 280 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
281 281
282 if ((role = strchr(user, '/')) != NULL)
283 *role++ = 0;
284
282 if ((style = strchr(user, ':')) != NULL) 285 if ((style = strchr(user, ':')) != NULL)
283 *style++ = 0; 286 *style++ = 0;
287 else if (role && (style = strchr(role, ':')) != NULL)
288 *style++ = '\0';
284 289
285 if (authctxt->attempt++ == 0) { 290 if (authctxt->attempt++ == 0) {
286 /* setup auth context */ 291 /* setup auth context */
@@ -307,8 +312,9 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
307 use_privsep ? " [net]" : ""); 312 use_privsep ? " [net]" : "");
308 authctxt->service = xstrdup(service); 313 authctxt->service = xstrdup(service);
309 authctxt->style = style ? xstrdup(style) : NULL; 314 authctxt->style = style ? xstrdup(style) : NULL;
315 authctxt->role = role ? xstrdup(role) : NULL;
310 if (use_privsep) 316 if (use_privsep)
311 mm_inform_authserv(service, style); 317 mm_inform_authserv(service, style, role);
312 userauth_banner(ssh); 318 userauth_banner(ssh);
313 if (auth2_setup_methods_lists(authctxt) != 0) 319 if (auth2_setup_methods_lists(authctxt) != 0)
314 ssh_packet_disconnect(ssh, 320 ssh_packet_disconnect(ssh,
diff --git a/monitor.c b/monitor.c
index ebf76c7f9..947fdfadc 100644
--- a/monitor.c
+++ b/monitor.c
@@ -118,6 +118,7 @@ int mm_answer_sign(struct ssh *, int, struct sshbuf *);
118int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *); 118int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *);
119int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *); 119int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *);
120int mm_answer_authserv(struct ssh *, int, struct sshbuf *); 120int mm_answer_authserv(struct ssh *, int, struct sshbuf *);
121int mm_answer_authrole(struct ssh *, int, struct sshbuf *);
121int mm_answer_authpassword(struct ssh *, int, struct sshbuf *); 122int mm_answer_authpassword(struct ssh *, int, struct sshbuf *);
122int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *); 123int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *);
123int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *); 124int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *);
@@ -198,6 +199,7 @@ struct mon_table mon_dispatch_proto20[] = {
198 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, 199 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
199 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, 200 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
200 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, 201 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
202 {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole},
201 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, 203 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
202 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, 204 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
203#ifdef USE_PAM 205#ifdef USE_PAM
@@ -820,6 +822,7 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m)
820 822
821 /* Allow service/style information on the auth context */ 823 /* Allow service/style information on the auth context */
822 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); 824 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
825 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1);
823 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); 826 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
824 827
825#ifdef USE_PAM 828#ifdef USE_PAM
@@ -853,16 +856,42 @@ mm_answer_authserv(struct ssh *ssh, int sock, struct sshbuf *m)
853 monitor_permit_authentications(1); 856 monitor_permit_authentications(1);
854 857
855 if ((r = sshbuf_get_cstring(m, &authctxt->service, NULL)) != 0 || 858 if ((r = sshbuf_get_cstring(m, &authctxt->service, NULL)) != 0 ||
856 (r = sshbuf_get_cstring(m, &authctxt->style, NULL)) != 0) 859 (r = sshbuf_get_cstring(m, &authctxt->style, NULL)) != 0 ||
860 (r = sshbuf_get_cstring(m, &authctxt->role, NULL)) != 0)
857 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 861 fatal("%s: buffer error: %s", __func__, ssh_err(r));
858 debug3("%s: service=%s, style=%s", 862 debug3("%s: service=%s, style=%s, role=%s",
859 __func__, authctxt->service, authctxt->style); 863 __func__, authctxt->service, authctxt->style, authctxt->role);
860 864
861 if (strlen(authctxt->style) == 0) { 865 if (strlen(authctxt->style) == 0) {
862 free(authctxt->style); 866 free(authctxt->style);
863 authctxt->style = NULL; 867 authctxt->style = NULL;
864 } 868 }
865 869
870 if (strlen(authctxt->role) == 0) {
871 free(authctxt->role);
872 authctxt->role = NULL;
873 }
874
875 return (0);
876}
877
878int
879mm_answer_authrole(struct ssh *ssh, int sock, struct sshbuf *m)
880{
881 int r;
882
883 monitor_permit_authentications(1);
884
885 if ((r = sshbuf_get_cstring(m, &authctxt->role, NULL)) != 0)
886 fatal("%s: buffer error: %s", __func__, ssh_err(r));
887 debug3("%s: role=%s",
888 __func__, authctxt->role);
889
890 if (strlen(authctxt->role) == 0) {
891 free(authctxt->role);
892 authctxt->role = NULL;
893 }
894
866 return (0); 895 return (0);
867} 896}
868 897
@@ -1554,7 +1583,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m)
1554 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); 1583 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
1555 if (res == 0) 1584 if (res == 0)
1556 goto error; 1585 goto error;
1557 pty_setowner(authctxt->pw, s->tty); 1586 pty_setowner(authctxt->pw, s->tty, authctxt->role);
1558 1587
1559 if ((r = sshbuf_put_u32(m, 1)) != 0 || 1588 if ((r = sshbuf_put_u32(m, 1)) != 0 ||
1560 (r = sshbuf_put_cstring(m, s->tty)) != 0) 1589 (r = sshbuf_put_cstring(m, s->tty)) != 0)
diff --git a/monitor.h b/monitor.h
index 2b1a2d590..4d87284aa 100644
--- a/monitor.h
+++ b/monitor.h
@@ -65,6 +65,8 @@ enum monitor_reqtype {
65 65
66 MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, 66 MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151,
67 MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, 67 MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153,
68
69 MONITOR_REQ_AUTHROLE = 154,
68}; 70};
69 71
70struct ssh; 72struct ssh;
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 6edb509a3..b49c268d3 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -364,10 +364,10 @@ mm_auth2_read_banner(void)
364 return (banner); 364 return (banner);
365} 365}
366 366
367/* Inform the privileged process about service and style */ 367/* Inform the privileged process about service, style, and role */
368 368
369void 369void
370mm_inform_authserv(char *service, char *style) 370mm_inform_authserv(char *service, char *style, char *role)
371{ 371{
372 struct sshbuf *m; 372 struct sshbuf *m;
373 int r; 373 int r;
@@ -377,7 +377,8 @@ mm_inform_authserv(char *service, char *style)
377 if ((m = sshbuf_new()) == NULL) 377 if ((m = sshbuf_new()) == NULL)
378 fatal("%s: sshbuf_new failed", __func__); 378 fatal("%s: sshbuf_new failed", __func__);
379 if ((r = sshbuf_put_cstring(m, service)) != 0 || 379 if ((r = sshbuf_put_cstring(m, service)) != 0 ||
380 (r = sshbuf_put_cstring(m, style ? style : "")) != 0) 380 (r = sshbuf_put_cstring(m, style ? style : "")) != 0 ||
381 (r = sshbuf_put_cstring(m, role ? role : "")) != 0)
381 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 382 fatal("%s: buffer error: %s", __func__, ssh_err(r));
382 383
383 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, m); 384 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, m);
@@ -385,6 +386,26 @@ mm_inform_authserv(char *service, char *style)
385 sshbuf_free(m); 386 sshbuf_free(m);
386} 387}
387 388
389/* Inform the privileged process about role */
390
391void
392mm_inform_authrole(char *role)
393{
394 struct sshbuf *m;
395 int r;
396
397 debug3("%s entering", __func__);
398
399 if ((m = sshbuf_new()) == NULL)
400 fatal("%s: sshbuf_new failed", __func__);
401 if ((r = sshbuf_put_cstring(m, role ? role : "")) != 0)
402 fatal("%s: buffer error: %s", __func__, ssh_err(r));
403
404 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, m);
405
406 sshbuf_free(m);
407}
408
388/* Do the password authentication */ 409/* Do the password authentication */
389int 410int
390mm_auth_password(struct ssh *ssh, char *password) 411mm_auth_password(struct ssh *ssh, char *password)
diff --git a/monitor_wrap.h b/monitor_wrap.h
index 485590c18..370b08e17 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -47,7 +47,8 @@ DH *mm_choose_dh(int, int, int);
47#endif 47#endif
48int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, 48int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *,
49 const u_char *, size_t, const char *, const char *, u_int compat); 49 const u_char *, size_t, const char *, const char *, u_int compat);
50void mm_inform_authserv(char *, char *); 50void mm_inform_authserv(char *, char *, char *);
51void mm_inform_authrole(char *);
51struct passwd *mm_getpwnamallow(struct ssh *, const char *); 52struct passwd *mm_getpwnamallow(struct ssh *, const char *);
52char *mm_auth2_read_banner(void); 53char *mm_auth2_read_banner(void);
53int mm_auth_password(struct ssh *, char *); 54int mm_auth_password(struct ssh *, char *);
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
index 622988822..3e6e07670 100644
--- a/openbsd-compat/port-linux.c
+++ b/openbsd-compat/port-linux.c
@@ -56,7 +56,7 @@ ssh_selinux_enabled(void)
56 56
57/* Return the default security context for the given username */ 57/* Return the default security context for the given username */
58static security_context_t 58static security_context_t
59ssh_selinux_getctxbyname(char *pwname) 59ssh_selinux_getctxbyname(char *pwname, const char *role)
60{ 60{
61 security_context_t sc = NULL; 61 security_context_t sc = NULL;
62 char *sename = NULL, *lvl = NULL; 62 char *sename = NULL, *lvl = NULL;
@@ -71,9 +71,16 @@ ssh_selinux_getctxbyname(char *pwname)
71#endif 71#endif
72 72
73#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL 73#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
74 r = get_default_context_with_level(sename, lvl, NULL, &sc); 74 if (role != NULL && role[0])
75 r = get_default_context_with_rolelevel(sename, role, lvl, NULL,
76 &sc);
77 else
78 r = get_default_context_with_level(sename, lvl, NULL, &sc);
75#else 79#else
76 r = get_default_context(sename, NULL, &sc); 80 if (role != NULL && role[0])
81 r = get_default_context_with_role(sename, role, NULL, &sc);
82 else
83 r = get_default_context(sename, NULL, &sc);
77#endif 84#endif
78 85
79 if (r != 0) { 86 if (r != 0) {
@@ -103,7 +110,7 @@ ssh_selinux_getctxbyname(char *pwname)
103 110
104/* Set the execution context to the default for the specified user */ 111/* Set the execution context to the default for the specified user */
105void 112void
106ssh_selinux_setup_exec_context(char *pwname) 113ssh_selinux_setup_exec_context(char *pwname, const char *role)
107{ 114{
108 security_context_t user_ctx = NULL; 115 security_context_t user_ctx = NULL;
109 116
@@ -112,7 +119,7 @@ ssh_selinux_setup_exec_context(char *pwname)
112 119
113 debug3("%s: setting execution context", __func__); 120 debug3("%s: setting execution context", __func__);
114 121
115 user_ctx = ssh_selinux_getctxbyname(pwname); 122 user_ctx = ssh_selinux_getctxbyname(pwname, role);
116 if (setexeccon(user_ctx) != 0) { 123 if (setexeccon(user_ctx) != 0) {
117 switch (security_getenforce()) { 124 switch (security_getenforce()) {
118 case -1: 125 case -1:
@@ -134,7 +141,7 @@ ssh_selinux_setup_exec_context(char *pwname)
134 141
135/* Set the TTY context for the specified user */ 142/* Set the TTY context for the specified user */
136void 143void
137ssh_selinux_setup_pty(char *pwname, const char *tty) 144ssh_selinux_setup_pty(char *pwname, const char *tty, const char *role)
138{ 145{
139 security_context_t new_tty_ctx = NULL; 146 security_context_t new_tty_ctx = NULL;
140 security_context_t user_ctx = NULL; 147 security_context_t user_ctx = NULL;
@@ -146,7 +153,7 @@ ssh_selinux_setup_pty(char *pwname, const char *tty)
146 153
147 debug3("%s: setting TTY context on %s", __func__, tty); 154 debug3("%s: setting TTY context on %s", __func__, tty);
148 155
149 user_ctx = ssh_selinux_getctxbyname(pwname); 156 user_ctx = ssh_selinux_getctxbyname(pwname, role);
150 157
151 /* XXX: should these calls fatal() upon failure in enforcing mode? */ 158 /* XXX: should these calls fatal() upon failure in enforcing mode? */
152 159
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
index 3c22a854d..c88129428 100644
--- a/openbsd-compat/port-linux.h
+++ b/openbsd-compat/port-linux.h
@@ -19,8 +19,8 @@
19 19
20#ifdef WITH_SELINUX 20#ifdef WITH_SELINUX
21int ssh_selinux_enabled(void); 21int ssh_selinux_enabled(void);
22void ssh_selinux_setup_pty(char *, const char *); 22void ssh_selinux_setup_pty(char *, const char *, const char *);
23void ssh_selinux_setup_exec_context(char *); 23void ssh_selinux_setup_exec_context(char *, const char *);
24void ssh_selinux_change_context(const char *); 24void ssh_selinux_change_context(const char *);
25void ssh_selinux_setfscreatecon(const char *); 25void ssh_selinux_setfscreatecon(const char *);
26#endif 26#endif
diff --git a/platform.c b/platform.c
index 44ba71dc5..2defe9425 100644
--- a/platform.c
+++ b/platform.c
@@ -143,7 +143,7 @@ platform_setusercontext(struct passwd *pw)
143 * called if sshd is running as root. 143 * called if sshd is running as root.
144 */ 144 */
145void 145void
146platform_setusercontext_post_groups(struct passwd *pw) 146platform_setusercontext_post_groups(struct passwd *pw, const char *role)
147{ 147{
148#if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM) 148#if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM)
149 /* 149 /*
@@ -184,7 +184,7 @@ platform_setusercontext_post_groups(struct passwd *pw)
184 } 184 }
185#endif /* HAVE_SETPCRED */ 185#endif /* HAVE_SETPCRED */
186#ifdef WITH_SELINUX 186#ifdef WITH_SELINUX
187 ssh_selinux_setup_exec_context(pw->pw_name); 187 ssh_selinux_setup_exec_context(pw->pw_name, role);
188#endif 188#endif
189} 189}
190 190
diff --git a/platform.h b/platform.h
index ea4f9c584..60d72ffe7 100644
--- a/platform.h
+++ b/platform.h
@@ -25,7 +25,7 @@ void platform_post_fork_parent(pid_t child_pid);
25void platform_post_fork_child(void); 25void platform_post_fork_child(void);
26int platform_privileged_uidswap(void); 26int platform_privileged_uidswap(void);
27void platform_setusercontext(struct passwd *); 27void platform_setusercontext(struct passwd *);
28void platform_setusercontext_post_groups(struct passwd *); 28void platform_setusercontext_post_groups(struct passwd *, const char *);
29char *platform_get_krb5_client(const char *); 29char *platform_get_krb5_client(const char *);
30char *platform_krb5_get_principal_name(const char *); 30char *platform_krb5_get_principal_name(const char *);
31int platform_sys_dir_uid(uid_t); 31int platform_sys_dir_uid(uid_t);
diff --git a/session.c b/session.c
index 06a33442a..871799590 100644
--- a/session.c
+++ b/session.c
@@ -1360,7 +1360,7 @@ safely_chroot(const char *path, uid_t uid)
1360 1360
1361/* Set login name, uid, gid, and groups. */ 1361/* Set login name, uid, gid, and groups. */
1362void 1362void
1363do_setusercontext(struct passwd *pw) 1363do_setusercontext(struct passwd *pw, const char *role)
1364{ 1364{
1365 char uidstr[32], *chroot_path, *tmp; 1365 char uidstr[32], *chroot_path, *tmp;
1366 1366
@@ -1388,7 +1388,7 @@ do_setusercontext(struct passwd *pw)
1388 endgrent(); 1388 endgrent();
1389#endif 1389#endif
1390 1390
1391 platform_setusercontext_post_groups(pw); 1391 platform_setusercontext_post_groups(pw, role);
1392 1392
1393 if (!in_chroot && options.chroot_directory != NULL && 1393 if (!in_chroot && options.chroot_directory != NULL &&
1394 strcasecmp(options.chroot_directory, "none") != 0) { 1394 strcasecmp(options.chroot_directory, "none") != 0) {
@@ -1529,7 +1529,7 @@ do_child(struct ssh *ssh, Session *s, const char *command)
1529 1529
1530 /* Force a password change */ 1530 /* Force a password change */
1531 if (s->authctxt->force_pwchange) { 1531 if (s->authctxt->force_pwchange) {
1532 do_setusercontext(pw); 1532 do_setusercontext(pw, s->authctxt->role);
1533 child_close_fds(ssh); 1533 child_close_fds(ssh);
1534 do_pwchange(s); 1534 do_pwchange(s);
1535 exit(1); 1535 exit(1);
@@ -1547,7 +1547,7 @@ do_child(struct ssh *ssh, Session *s, const char *command)
1547 /* When PAM is enabled we rely on it to do the nologin check */ 1547 /* When PAM is enabled we rely on it to do the nologin check */
1548 if (!options.use_pam) 1548 if (!options.use_pam)
1549 do_nologin(pw); 1549 do_nologin(pw);
1550 do_setusercontext(pw); 1550 do_setusercontext(pw, s->authctxt->role);
1551 /* 1551 /*
1552 * PAM session modules in do_setusercontext may have 1552 * PAM session modules in do_setusercontext may have
1553 * generated messages, so if this in an interactive 1553 * generated messages, so if this in an interactive
@@ -1946,7 +1946,7 @@ session_pty_req(struct ssh *ssh, Session *s)
1946 sshpkt_fatal(ssh, r, "%s: parse packet", __func__); 1946 sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
1947 1947
1948 if (!use_privsep) 1948 if (!use_privsep)
1949 pty_setowner(s->pw, s->tty); 1949 pty_setowner(s->pw, s->tty, s->authctxt->role);
1950 1950
1951 /* Set window size from the packet. */ 1951 /* Set window size from the packet. */
1952 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 1952 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
diff --git a/session.h b/session.h
index ce59dabd9..675c91146 100644
--- a/session.h
+++ b/session.h
@@ -77,7 +77,7 @@ void session_pty_cleanup2(Session *);
77Session *session_new(void); 77Session *session_new(void);
78Session *session_by_tty(char *); 78Session *session_by_tty(char *);
79void session_close(struct ssh *, Session *); 79void session_close(struct ssh *, Session *);
80void do_setusercontext(struct passwd *); 80void do_setusercontext(struct passwd *, const char *);
81 81
82const char *session_get_remote_name_or_ip(struct ssh *, u_int, int); 82const char *session_get_remote_name_or_ip(struct ssh *, u_int, int);
83 83
diff --git a/sshd.c b/sshd.c
index 62dc55cf2..65916fc6d 100644
--- a/sshd.c
+++ b/sshd.c
@@ -595,7 +595,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt)
595 reseed_prngs(); 595 reseed_prngs();
596 596
597 /* Drop privileges */ 597 /* Drop privileges */
598 do_setusercontext(authctxt->pw); 598 do_setusercontext(authctxt->pw, authctxt->role);
599 599
600 skip: 600 skip:
601 /* It is safe now to apply the key state */ 601 /* It is safe now to apply the key state */
diff --git a/sshpty.c b/sshpty.c
index bce09e255..308449b37 100644
--- a/sshpty.c
+++ b/sshpty.c
@@ -162,7 +162,7 @@ pty_change_window_size(int ptyfd, u_int row, u_int col,
162} 162}
163 163
164void 164void
165pty_setowner(struct passwd *pw, const char *tty) 165pty_setowner(struct passwd *pw, const char *tty, const char *role)
166{ 166{
167 struct group *grp; 167 struct group *grp;
168 gid_t gid; 168 gid_t gid;
@@ -186,7 +186,7 @@ pty_setowner(struct passwd *pw, const char *tty)
186 strerror(errno)); 186 strerror(errno));
187 187
188#ifdef WITH_SELINUX 188#ifdef WITH_SELINUX
189 ssh_selinux_setup_pty(pw->pw_name, tty); 189 ssh_selinux_setup_pty(pw->pw_name, tty, role);
190#endif 190#endif
191 191
192 if (st.st_uid != pw->pw_uid || st.st_gid != gid) { 192 if (st.st_uid != pw->pw_uid || st.st_gid != gid) {
diff --git a/sshpty.h b/sshpty.h
index 9ec7e9a15..de7e000ae 100644
--- a/sshpty.h
+++ b/sshpty.h
@@ -24,5 +24,5 @@ int pty_allocate(int *, int *, char *, size_t);
24void pty_release(const char *); 24void pty_release(const char *);
25void pty_make_controlling_tty(int *, const char *); 25void pty_make_controlling_tty(int *, const char *);
26void pty_change_window_size(int, u_int, u_int, u_int, u_int); 26void pty_change_window_size(int, u_int, u_int, u_int, u_int);
27void pty_setowner(struct passwd *, const char *); 27void pty_setowner(struct passwd *, const char *, const char *);
28void disconnect_controlling_tty(void); 28void disconnect_controlling_tty(void);