summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManoj Srivastava <srivasta@debian.org>2014-02-09 16:09:49 +0000
committerColin Watson <cjwatson@debian.org>2018-04-03 08:20:56 +0100
commit7da968d97beba5fb80a5488516563ea1376db907 (patch)
tree0e9107c92138281814181acbdd1428a6862ef63b
parent398af3d66bfe8dc7d436570026571e522a0a13a0 (diff)
Handle SELinux authorisation roles
Rejected upstream due to discomfort with magic usernames; a better approach will need an SSH protocol change. In the meantime, this came from Debian's SELinux maintainer, so we'll keep it until we have something better. Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1641 Bug-Debian: http://bugs.debian.org/394795 Last-Update: 2017-10-04 Patch-Name: selinux-role.patch
-rw-r--r--auth.h1
-rw-r--r--auth2.c10
-rw-r--r--monitor.c32
-rw-r--r--monitor.h2
-rw-r--r--monitor_wrap.c22
-rw-r--r--monitor_wrap.h3
-rw-r--r--openbsd-compat/port-linux.c27
-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, 97 insertions, 30 deletions
diff --git a/auth.h b/auth.h
index 23ce67caf..15ba7073e 100644
--- a/auth.h
+++ b/auth.h
@@ -65,6 +65,7 @@ struct Authctxt {
65 char *service; 65 char *service;
66 struct passwd *pw; /* set if 'valid' */ 66 struct passwd *pw; /* set if 'valid' */
67 char *style; 67 char *style;
68 char *role;
68 69
69 /* Method lists for multiple authentication */ 70 /* Method lists for multiple authentication */
70 char **auth_methods; /* modified from server config */ 71 char **auth_methods; /* modified from server config */
diff --git a/auth2.c b/auth2.c
index c34f58c45..be5e9f15f 100644
--- a/auth2.c
+++ b/auth2.c
@@ -218,7 +218,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
218{ 218{
219 Authctxt *authctxt = ssh->authctxt; 219 Authctxt *authctxt = ssh->authctxt;
220 Authmethod *m = NULL; 220 Authmethod *m = NULL;
221 char *user, *service, *method, *style = NULL; 221 char *user, *service, *method, *style = NULL, *role = NULL;
222 int authenticated = 0; 222 int authenticated = 0;
223 223
224 if (authctxt == NULL) 224 if (authctxt == NULL)
@@ -230,8 +230,13 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
230 debug("userauth-request for user %s service %s method %s", user, service, method); 230 debug("userauth-request for user %s service %s method %s", user, service, method);
231 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); 231 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
232 232
233 if ((role = strchr(user, '/')) != NULL)
234 *role++ = 0;
235
233 if ((style = strchr(user, ':')) != NULL) 236 if ((style = strchr(user, ':')) != NULL)
234 *style++ = 0; 237 *style++ = 0;
238 else if (role && (style = strchr(role, ':')) != NULL)
239 *style++ = '\0';
235 240
236 if (authctxt->attempt++ == 0) { 241 if (authctxt->attempt++ == 0) {
237 /* setup auth context */ 242 /* setup auth context */
@@ -258,8 +263,9 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
258 use_privsep ? " [net]" : ""); 263 use_privsep ? " [net]" : "");
259 authctxt->service = xstrdup(service); 264 authctxt->service = xstrdup(service);
260 authctxt->style = style ? xstrdup(style) : NULL; 265 authctxt->style = style ? xstrdup(style) : NULL;
266 authctxt->role = role ? xstrdup(role) : NULL;
261 if (use_privsep) 267 if (use_privsep)
262 mm_inform_authserv(service, style); 268 mm_inform_authserv(service, style, role);
263 userauth_banner(); 269 userauth_banner();
264 if (auth2_setup_methods_lists(authctxt) != 0) 270 if (auth2_setup_methods_lists(authctxt) != 0)
265 packet_disconnect("no authentication methods enabled"); 271 packet_disconnect("no authentication methods enabled");
diff --git a/monitor.c b/monitor.c
index 868fb0d2d..ed37458fb 100644
--- a/monitor.c
+++ b/monitor.c
@@ -128,6 +128,7 @@ int mm_answer_sign(int, Buffer *);
128int mm_answer_pwnamallow(int, Buffer *); 128int mm_answer_pwnamallow(int, Buffer *);
129int mm_answer_auth2_read_banner(int, Buffer *); 129int mm_answer_auth2_read_banner(int, Buffer *);
130int mm_answer_authserv(int, Buffer *); 130int mm_answer_authserv(int, Buffer *);
131int mm_answer_authrole(int, Buffer *);
131int mm_answer_authpassword(int, Buffer *); 132int mm_answer_authpassword(int, Buffer *);
132int mm_answer_bsdauthquery(int, Buffer *); 133int mm_answer_bsdauthquery(int, Buffer *);
133int mm_answer_bsdauthrespond(int, Buffer *); 134int mm_answer_bsdauthrespond(int, Buffer *);
@@ -206,6 +207,7 @@ struct mon_table mon_dispatch_proto20[] = {
206 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, 207 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
207 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, 208 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
208 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, 209 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
210 {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole},
209 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, 211 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
210 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, 212 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
211#ifdef USE_PAM 213#ifdef USE_PAM
@@ -806,6 +808,7 @@ mm_answer_pwnamallow(int sock, Buffer *m)
806 808
807 /* Allow service/style information on the auth context */ 809 /* Allow service/style information on the auth context */
808 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); 810 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
811 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1);
809 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); 812 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
810 813
811#ifdef USE_PAM 814#ifdef USE_PAM
@@ -836,14 +839,37 @@ mm_answer_authserv(int sock, Buffer *m)
836 839
837 authctxt->service = buffer_get_string(m, NULL); 840 authctxt->service = buffer_get_string(m, NULL);
838 authctxt->style = buffer_get_string(m, NULL); 841 authctxt->style = buffer_get_string(m, NULL);
839 debug3("%s: service=%s, style=%s", 842 authctxt->role = buffer_get_string(m, NULL);
840 __func__, authctxt->service, authctxt->style); 843 debug3("%s: service=%s, style=%s, role=%s",
844 __func__, authctxt->service, authctxt->style, authctxt->role);
841 845
842 if (strlen(authctxt->style) == 0) { 846 if (strlen(authctxt->style) == 0) {
843 free(authctxt->style); 847 free(authctxt->style);
844 authctxt->style = NULL; 848 authctxt->style = NULL;
845 } 849 }
846 850
851 if (strlen(authctxt->role) == 0) {
852 free(authctxt->role);
853 authctxt->role = NULL;
854 }
855
856 return (0);
857}
858
859int
860mm_answer_authrole(int sock, Buffer *m)
861{
862 monitor_permit_authentications(1);
863
864 authctxt->role = buffer_get_string(m, NULL);
865 debug3("%s: role=%s",
866 __func__, authctxt->role);
867
868 if (strlen(authctxt->role) == 0) {
869 free(authctxt->role);
870 authctxt->role = NULL;
871 }
872
847 return (0); 873 return (0);
848} 874}
849 875
@@ -1497,7 +1523,7 @@ mm_answer_pty(int sock, Buffer *m)
1497 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); 1523 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
1498 if (res == 0) 1524 if (res == 0)
1499 goto error; 1525 goto error;
1500 pty_setowner(authctxt->pw, s->tty); 1526 pty_setowner(authctxt->pw, s->tty, authctxt->role);
1501 1527
1502 buffer_put_int(m, 1); 1528 buffer_put_int(m, 1);
1503 buffer_put_cstring(m, s->tty); 1529 buffer_put_cstring(m, s->tty);
diff --git a/monitor.h b/monitor.h
index ec41404c7..4c7955d7a 100644
--- a/monitor.h
+++ b/monitor.h
@@ -68,6 +68,8 @@ enum monitor_reqtype {
68 MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, 68 MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151,
69 MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, 69 MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153,
70 70
71 MONITOR_REQ_AUTHROLE = 154,
72
71}; 73};
72 74
73struct monitor { 75struct monitor {
diff --git a/monitor_wrap.c b/monitor_wrap.c
index e749efc18..7b2d06c65 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -331,10 +331,10 @@ mm_auth2_read_banner(void)
331 return (banner); 331 return (banner);
332} 332}
333 333
334/* Inform the privileged process about service and style */ 334/* Inform the privileged process about service, style, and role */
335 335
336void 336void
337mm_inform_authserv(char *service, char *style) 337mm_inform_authserv(char *service, char *style, char *role)
338{ 338{
339 Buffer m; 339 Buffer m;
340 340
@@ -343,12 +343,30 @@ mm_inform_authserv(char *service, char *style)
343 buffer_init(&m); 343 buffer_init(&m);
344 buffer_put_cstring(&m, service); 344 buffer_put_cstring(&m, service);
345 buffer_put_cstring(&m, style ? style : ""); 345 buffer_put_cstring(&m, style ? style : "");
346 buffer_put_cstring(&m, role ? role : "");
346 347
347 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m); 348 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
348 349
349 buffer_free(&m); 350 buffer_free(&m);
350} 351}
351 352
353/* Inform the privileged process about role */
354
355void
356mm_inform_authrole(char *role)
357{
358 Buffer m;
359
360 debug3("%s entering", __func__);
361
362 buffer_init(&m);
363 buffer_put_cstring(&m, role ? role : "");
364
365 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m);
366
367 buffer_free(&m);
368}
369
352/* Do the password authentication */ 370/* Do the password authentication */
353int 371int
354mm_auth_password(struct ssh *ssh, char *password) 372mm_auth_password(struct ssh *ssh, char *password)
diff --git a/monitor_wrap.h b/monitor_wrap.h
index 0970d1f87..492de5c85 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -43,7 +43,8 @@ int mm_is_monitor(void);
43DH *mm_choose_dh(int, int, int); 43DH *mm_choose_dh(int, int, int);
44int mm_key_sign(struct sshkey *, u_char **, u_int *, const u_char *, u_int, 44int mm_key_sign(struct sshkey *, u_char **, u_int *, const u_char *, u_int,
45 const char *); 45 const char *);
46void mm_inform_authserv(char *, char *); 46void mm_inform_authserv(char *, char *, char *);
47void mm_inform_authrole(char *);
47struct passwd *mm_getpwnamallow(const char *); 48struct passwd *mm_getpwnamallow(const char *);
48char *mm_auth2_read_banner(void); 49char *mm_auth2_read_banner(void);
49int mm_auth_password(struct ssh *, char *); 50int mm_auth_password(struct ssh *, char *);
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
index 8c5325cc3..8a3e5c68d 100644
--- a/openbsd-compat/port-linux.c
+++ b/openbsd-compat/port-linux.c
@@ -27,6 +27,12 @@
27#include <string.h> 27#include <string.h>
28#include <stdio.h> 28#include <stdio.h>
29 29
30#ifdef WITH_SELINUX
31#include "key.h"
32#include "hostfile.h"
33#include "auth.h"
34#endif
35
30#include "log.h" 36#include "log.h"
31#include "xmalloc.h" 37#include "xmalloc.h"
32#include "port-linux.h" 38#include "port-linux.h"
@@ -55,7 +61,7 @@ ssh_selinux_enabled(void)
55 61
56/* Return the default security context for the given username */ 62/* Return the default security context for the given username */
57static security_context_t 63static security_context_t
58ssh_selinux_getctxbyname(char *pwname) 64ssh_selinux_getctxbyname(char *pwname, const char *role)
59{ 65{
60 security_context_t sc = NULL; 66 security_context_t sc = NULL;
61 char *sename = NULL, *lvl = NULL; 67 char *sename = NULL, *lvl = NULL;
@@ -70,9 +76,16 @@ ssh_selinux_getctxbyname(char *pwname)
70#endif 76#endif
71 77
72#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL 78#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
73 r = get_default_context_with_level(sename, lvl, NULL, &sc); 79 if (role != NULL && role[0])
80 r = get_default_context_with_rolelevel(sename, role, lvl, NULL,
81 &sc);
82 else
83 r = get_default_context_with_level(sename, lvl, NULL, &sc);
74#else 84#else
75 r = get_default_context(sename, NULL, &sc); 85 if (role != NULL && role[0])
86 r = get_default_context_with_role(sename, role, NULL, &sc);
87 else
88 r = get_default_context(sename, NULL, &sc);
76#endif 89#endif
77 90
78 if (r != 0) { 91 if (r != 0) {
@@ -102,7 +115,7 @@ ssh_selinux_getctxbyname(char *pwname)
102 115
103/* Set the execution context to the default for the specified user */ 116/* Set the execution context to the default for the specified user */
104void 117void
105ssh_selinux_setup_exec_context(char *pwname) 118ssh_selinux_setup_exec_context(char *pwname, const char *role)
106{ 119{
107 security_context_t user_ctx = NULL; 120 security_context_t user_ctx = NULL;
108 121
@@ -111,7 +124,7 @@ ssh_selinux_setup_exec_context(char *pwname)
111 124
112 debug3("%s: setting execution context", __func__); 125 debug3("%s: setting execution context", __func__);
113 126
114 user_ctx = ssh_selinux_getctxbyname(pwname); 127 user_ctx = ssh_selinux_getctxbyname(pwname, role);
115 if (setexeccon(user_ctx) != 0) { 128 if (setexeccon(user_ctx) != 0) {
116 switch (security_getenforce()) { 129 switch (security_getenforce()) {
117 case -1: 130 case -1:
@@ -133,7 +146,7 @@ ssh_selinux_setup_exec_context(char *pwname)
133 146
134/* Set the TTY context for the specified user */ 147/* Set the TTY context for the specified user */
135void 148void
136ssh_selinux_setup_pty(char *pwname, const char *tty) 149ssh_selinux_setup_pty(char *pwname, const char *tty, const char *role)
137{ 150{
138 security_context_t new_tty_ctx = NULL; 151 security_context_t new_tty_ctx = NULL;
139 security_context_t user_ctx = NULL; 152 security_context_t user_ctx = NULL;
@@ -145,7 +158,7 @@ ssh_selinux_setup_pty(char *pwname, const char *tty)
145 158
146 debug3("%s: setting TTY context on %s", __func__, tty); 159 debug3("%s: setting TTY context on %s", __func__, tty);
147 160
148 user_ctx = ssh_selinux_getctxbyname(pwname); 161 user_ctx = ssh_selinux_getctxbyname(pwname, role);
149 162
150 /* XXX: should these calls fatal() upon failure in enforcing mode? */ 163 /* XXX: should these calls fatal() upon failure in enforcing mode? */
151 164
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 18c7751de..380ee3a41 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 58826db16..ff301c983 100644
--- a/session.c
+++ b/session.c
@@ -1322,7 +1322,7 @@ safely_chroot(const char *path, uid_t uid)
1322 1322
1323/* Set login name, uid, gid, and groups. */ 1323/* Set login name, uid, gid, and groups. */
1324void 1324void
1325do_setusercontext(struct passwd *pw) 1325do_setusercontext(struct passwd *pw, const char *role)
1326{ 1326{
1327 char *chroot_path, *tmp; 1327 char *chroot_path, *tmp;
1328 1328
@@ -1350,7 +1350,7 @@ do_setusercontext(struct passwd *pw)
1350 endgrent(); 1350 endgrent();
1351#endif 1351#endif
1352 1352
1353 platform_setusercontext_post_groups(pw); 1353 platform_setusercontext_post_groups(pw, role);
1354 1354
1355 if (!in_chroot && options.chroot_directory != NULL && 1355 if (!in_chroot && options.chroot_directory != NULL &&
1356 strcasecmp(options.chroot_directory, "none") != 0) { 1356 strcasecmp(options.chroot_directory, "none") != 0) {
@@ -1487,7 +1487,7 @@ do_child(struct ssh *ssh, Session *s, const char *command)
1487 1487
1488 /* Force a password change */ 1488 /* Force a password change */
1489 if (s->authctxt->force_pwchange) { 1489 if (s->authctxt->force_pwchange) {
1490 do_setusercontext(pw); 1490 do_setusercontext(pw, s->authctxt->role);
1491 child_close_fds(ssh); 1491 child_close_fds(ssh);
1492 do_pwchange(s); 1492 do_pwchange(s);
1493 exit(1); 1493 exit(1);
@@ -1505,7 +1505,7 @@ do_child(struct ssh *ssh, Session *s, const char *command)
1505 /* When PAM is enabled we rely on it to do the nologin check */ 1505 /* When PAM is enabled we rely on it to do the nologin check */
1506 if (!options.use_pam) 1506 if (!options.use_pam)
1507 do_nologin(pw); 1507 do_nologin(pw);
1508 do_setusercontext(pw); 1508 do_setusercontext(pw, s->authctxt->role);
1509 /* 1509 /*
1510 * PAM session modules in do_setusercontext may have 1510 * PAM session modules in do_setusercontext may have
1511 * generated messages, so if this in an interactive 1511 * generated messages, so if this in an interactive
@@ -1897,7 +1897,7 @@ session_pty_req(struct ssh *ssh, Session *s)
1897 tty_parse_modes(s->ttyfd, &n_bytes); 1897 tty_parse_modes(s->ttyfd, &n_bytes);
1898 1898
1899 if (!use_privsep) 1899 if (!use_privsep)
1900 pty_setowner(s->pw, s->tty); 1900 pty_setowner(s->pw, s->tty, s->authctxt->role);
1901 1901
1902 /* Set window size from the packet. */ 1902 /* Set window size from the packet. */
1903 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 1903 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
diff --git a/session.h b/session.h
index 54dd1f0ca..8535ebcef 100644
--- a/session.h
+++ b/session.h
@@ -76,7 +76,7 @@ void session_pty_cleanup2(Session *);
76Session *session_new(void); 76Session *session_new(void);
77Session *session_by_tty(char *); 77Session *session_by_tty(char *);
78void session_close(struct ssh *, Session *); 78void session_close(struct ssh *, Session *);
79void do_setusercontext(struct passwd *); 79void do_setusercontext(struct passwd *, const char *);
80 80
81const char *session_get_remote_name_or_ip(struct ssh *, u_int, int); 81const char *session_get_remote_name_or_ip(struct ssh *, u_int, int);
82 82
diff --git a/sshd.c b/sshd.c
index 4ed0364f2..6d911c19a 100644
--- a/sshd.c
+++ b/sshd.c
@@ -679,7 +679,7 @@ privsep_postauth(Authctxt *authctxt)
679 reseed_prngs(); 679 reseed_prngs();
680 680
681 /* Drop privileges */ 681 /* Drop privileges */
682 do_setusercontext(authctxt->pw); 682 do_setusercontext(authctxt->pw, authctxt->role);
683 683
684 skip: 684 skip:
685 /* It is safe now to apply the key state */ 685 /* It is safe now to apply the key state */
diff --git a/sshpty.c b/sshpty.c
index 4da84d05f..676ade50e 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;
@@ -184,7 +184,7 @@ pty_setowner(struct passwd *pw, const char *tty)
184 strerror(errno)); 184 strerror(errno));
185 185
186#ifdef WITH_SELINUX 186#ifdef WITH_SELINUX
187 ssh_selinux_setup_pty(pw->pw_name, tty); 187 ssh_selinux_setup_pty(pw->pw_name, tty, role);
188#endif 188#endif
189 189
190 if (st.st_uid != pw->pw_uid || st.st_gid != gid) { 190 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);