summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManoj Srivastava <srivasta@debian.org>2014-02-09 16:09:49 +0000
committerColin Watson <cjwatson@debian.org>2016-02-29 12:32:23 +0000
commita00cba810338ce920de432e7797a45794bf280ba (patch)
tree2e9b6cc4f62364ecfdd99aa8b409e84ad6637a8c
parent9496f70a8203592158275489519996476b2356af (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: 2015-08-19 Patch-Name: selinux-role.patch
-rw-r--r--auth.h1
-rw-r--r--auth1.c8
-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
16 files changed, 104 insertions, 31 deletions
diff --git a/auth.h b/auth.h
index 2160154f4..3b3a0853e 100644
--- a/auth.h
+++ b/auth.h
@@ -62,6 +62,7 @@ struct Authctxt {
62 char *service; 62 char *service;
63 struct passwd *pw; /* set if 'valid' */ 63 struct passwd *pw; /* set if 'valid' */
64 char *style; 64 char *style;
65 char *role;
65 void *kbdintctxt; 66 void *kbdintctxt;
66 char *info; /* Extra info for next auth_log */ 67 char *info; /* Extra info for next auth_log */
67#ifdef BSD_AUTH 68#ifdef BSD_AUTH
diff --git a/auth1.c b/auth1.c
index 5073c49bb..dd0064832 100644
--- a/auth1.c
+++ b/auth1.c
@@ -383,7 +383,7 @@ void
383do_authentication(Authctxt *authctxt) 383do_authentication(Authctxt *authctxt)
384{ 384{
385 u_int ulen; 385 u_int ulen;
386 char *user, *style = NULL; 386 char *user, *style = NULL, *role = NULL;
387 387
388 /* Get the name of the user that we wish to log in as. */ 388 /* Get the name of the user that we wish to log in as. */
389 packet_read_expect(SSH_CMSG_USER); 389 packet_read_expect(SSH_CMSG_USER);
@@ -392,11 +392,17 @@ do_authentication(Authctxt *authctxt)
392 user = packet_get_cstring(&ulen); 392 user = packet_get_cstring(&ulen);
393 packet_check_eom(); 393 packet_check_eom();
394 394
395 if ((role = strchr(user, '/')) != NULL)
396 *role++ = '\0';
397
395 if ((style = strchr(user, ':')) != NULL) 398 if ((style = strchr(user, ':')) != NULL)
396 *style++ = '\0'; 399 *style++ = '\0';
400 else if (role && (style = strchr(role, ':')) != NULL)
401 *style++ = '\0';
397 402
398 authctxt->user = user; 403 authctxt->user = user;
399 authctxt->style = style; 404 authctxt->style = style;
405 authctxt->role = role;
400 406
401 /* Verify that the user is a valid user. */ 407 /* Verify that the user is a valid user. */
402 if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) 408 if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
diff --git a/auth2.c b/auth2.c
index 3f49bdca0..6eb3cc7b9 100644
--- a/auth2.c
+++ b/auth2.c
@@ -216,7 +216,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
216{ 216{
217 Authctxt *authctxt = ctxt; 217 Authctxt *authctxt = ctxt;
218 Authmethod *m = NULL; 218 Authmethod *m = NULL;
219 char *user, *service, *method, *style = NULL; 219 char *user, *service, *method, *style = NULL, *role = NULL;
220 int authenticated = 0; 220 int authenticated = 0;
221 221
222 if (authctxt == NULL) 222 if (authctxt == NULL)
@@ -228,8 +228,13 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
228 debug("userauth-request for user %s service %s method %s", user, service, method); 228 debug("userauth-request for user %s service %s method %s", user, service, method);
229 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); 229 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
230 230
231 if ((role = strchr(user, '/')) != NULL)
232 *role++ = 0;
233
231 if ((style = strchr(user, ':')) != NULL) 234 if ((style = strchr(user, ':')) != NULL)
232 *style++ = 0; 235 *style++ = 0;
236 else if (role && (style = strchr(role, ':')) != NULL)
237 *style++ = '\0';
233 238
234 if (authctxt->attempt++ == 0) { 239 if (authctxt->attempt++ == 0) {
235 /* setup auth context */ 240 /* setup auth context */
@@ -253,8 +258,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
253 use_privsep ? " [net]" : ""); 258 use_privsep ? " [net]" : "");
254 authctxt->service = xstrdup(service); 259 authctxt->service = xstrdup(service);
255 authctxt->style = style ? xstrdup(style) : NULL; 260 authctxt->style = style ? xstrdup(style) : NULL;
261 authctxt->role = role ? xstrdup(role) : NULL;
256 if (use_privsep) 262 if (use_privsep)
257 mm_inform_authserv(service, style); 263 mm_inform_authserv(service, style, role);
258 userauth_banner(); 264 userauth_banner();
259 if (auth2_setup_methods_lists(authctxt) != 0) 265 if (auth2_setup_methods_lists(authctxt) != 0)
260 packet_disconnect("no authentication methods enabled"); 266 packet_disconnect("no authentication methods enabled");
diff --git a/monitor.c b/monitor.c
index 6c8202325..5be3fbfdb 100644
--- a/monitor.c
+++ b/monitor.c
@@ -126,6 +126,7 @@ int mm_answer_sign(int, Buffer *);
126int mm_answer_pwnamallow(int, Buffer *); 126int mm_answer_pwnamallow(int, Buffer *);
127int mm_answer_auth2_read_banner(int, Buffer *); 127int mm_answer_auth2_read_banner(int, Buffer *);
128int mm_answer_authserv(int, Buffer *); 128int mm_answer_authserv(int, Buffer *);
129int mm_answer_authrole(int, Buffer *);
129int mm_answer_authpassword(int, Buffer *); 130int mm_answer_authpassword(int, Buffer *);
130int mm_answer_bsdauthquery(int, Buffer *); 131int mm_answer_bsdauthquery(int, Buffer *);
131int mm_answer_bsdauthrespond(int, Buffer *); 132int mm_answer_bsdauthrespond(int, Buffer *);
@@ -207,6 +208,7 @@ struct mon_table mon_dispatch_proto20[] = {
207 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, 208 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
208 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, 209 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
209 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, 210 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
211 {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole},
210 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, 212 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
211 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, 213 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
212#ifdef USE_PAM 214#ifdef USE_PAM
@@ -875,6 +877,7 @@ mm_answer_pwnamallow(int sock, Buffer *m)
875 else { 877 else {
876 /* Allow service/style information on the auth context */ 878 /* Allow service/style information on the auth context */
877 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); 879 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
880 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1);
878 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); 881 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
879 } 882 }
880#ifdef USE_PAM 883#ifdef USE_PAM
@@ -905,14 +908,37 @@ mm_answer_authserv(int sock, Buffer *m)
905 908
906 authctxt->service = buffer_get_string(m, NULL); 909 authctxt->service = buffer_get_string(m, NULL);
907 authctxt->style = buffer_get_string(m, NULL); 910 authctxt->style = buffer_get_string(m, NULL);
908 debug3("%s: service=%s, style=%s", 911 authctxt->role = buffer_get_string(m, NULL);
909 __func__, authctxt->service, authctxt->style); 912 debug3("%s: service=%s, style=%s, role=%s",
913 __func__, authctxt->service, authctxt->style, authctxt->role);
910 914
911 if (strlen(authctxt->style) == 0) { 915 if (strlen(authctxt->style) == 0) {
912 free(authctxt->style); 916 free(authctxt->style);
913 authctxt->style = NULL; 917 authctxt->style = NULL;
914 } 918 }
915 919
920 if (strlen(authctxt->role) == 0) {
921 free(authctxt->role);
922 authctxt->role = NULL;
923 }
924
925 return (0);
926}
927
928int
929mm_answer_authrole(int sock, Buffer *m)
930{
931 monitor_permit_authentications(1);
932
933 authctxt->role = buffer_get_string(m, NULL);
934 debug3("%s: role=%s",
935 __func__, authctxt->role);
936
937 if (strlen(authctxt->role) == 0) {
938 free(authctxt->role);
939 authctxt->role = NULL;
940 }
941
916 return (0); 942 return (0);
917} 943}
918 944
@@ -1541,7 +1567,7 @@ mm_answer_pty(int sock, Buffer *m)
1541 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); 1567 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
1542 if (res == 0) 1568 if (res == 0)
1543 goto error; 1569 goto error;
1544 pty_setowner(authctxt->pw, s->tty); 1570 pty_setowner(authctxt->pw, s->tty, authctxt->role);
1545 1571
1546 buffer_put_int(m, 1); 1572 buffer_put_int(m, 1);
1547 buffer_put_cstring(m, s->tty); 1573 buffer_put_cstring(m, s->tty);
diff --git a/monitor.h b/monitor.h
index bc50ade1f..2d82b8b84 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 mm_master; 75struct mm_master;
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 74fbd2ef3..eaf0a1294 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -327,10 +327,10 @@ mm_auth2_read_banner(void)
327 return (banner); 327 return (banner);
328} 328}
329 329
330/* Inform the privileged process about service and style */ 330/* Inform the privileged process about service, style, and role */
331 331
332void 332void
333mm_inform_authserv(char *service, char *style) 333mm_inform_authserv(char *service, char *style, char *role)
334{ 334{
335 Buffer m; 335 Buffer m;
336 336
@@ -339,12 +339,30 @@ mm_inform_authserv(char *service, char *style)
339 buffer_init(&m); 339 buffer_init(&m);
340 buffer_put_cstring(&m, service); 340 buffer_put_cstring(&m, service);
341 buffer_put_cstring(&m, style ? style : ""); 341 buffer_put_cstring(&m, style ? style : "");
342 buffer_put_cstring(&m, role ? role : "");
342 343
343 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m); 344 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
344 345
345 buffer_free(&m); 346 buffer_free(&m);
346} 347}
347 348
349/* Inform the privileged process about role */
350
351void
352mm_inform_authrole(char *role)
353{
354 Buffer m;
355
356 debug3("%s entering", __func__);
357
358 buffer_init(&m);
359 buffer_put_cstring(&m, role ? role : "");
360
361 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m);
362
363 buffer_free(&m);
364}
365
348/* Do the password authentication */ 366/* Do the password authentication */
349int 367int
350mm_auth_password(Authctxt *authctxt, char *password) 368mm_auth_password(Authctxt *authctxt, char *password)
diff --git a/monitor_wrap.h b/monitor_wrap.h
index 403f8d00c..d9de551c2 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -41,7 +41,8 @@ void mm_log_handler(LogLevel, const char *, void *);
41int mm_is_monitor(void); 41int mm_is_monitor(void);
42DH *mm_choose_dh(int, int, int); 42DH *mm_choose_dh(int, int, int);
43int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int, const char *); 43int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int, const char *);
44void mm_inform_authserv(char *, char *); 44void mm_inform_authserv(char *, char *, char *);
45void mm_inform_authrole(char *);
45struct passwd *mm_getpwnamallow(const char *); 46struct passwd *mm_getpwnamallow(const char *);
46char *mm_auth2_read_banner(void); 47char *mm_auth2_read_banner(void);
47int mm_auth_password(struct Authctxt *, char *); 48int mm_auth_password(struct Authctxt *, char *);
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
index f36999d7a..f9cdc15c3 100644
--- a/openbsd-compat/port-linux.c
+++ b/openbsd-compat/port-linux.c
@@ -29,6 +29,12 @@
29#include <string.h> 29#include <string.h>
30#include <stdio.h> 30#include <stdio.h>
31 31
32#ifdef WITH_SELINUX
33#include "key.h"
34#include "hostfile.h"
35#include "auth.h"
36#endif
37
32#include "log.h" 38#include "log.h"
33#include "xmalloc.h" 39#include "xmalloc.h"
34#include "port-linux.h" 40#include "port-linux.h"
@@ -58,7 +64,7 @@ ssh_selinux_enabled(void)
58 64
59/* Return the default security context for the given username */ 65/* Return the default security context for the given username */
60static security_context_t 66static security_context_t
61ssh_selinux_getctxbyname(char *pwname) 67ssh_selinux_getctxbyname(char *pwname, const char *role)
62{ 68{
63 security_context_t sc = NULL; 69 security_context_t sc = NULL;
64 char *sename = NULL, *lvl = NULL; 70 char *sename = NULL, *lvl = NULL;
@@ -73,9 +79,16 @@ ssh_selinux_getctxbyname(char *pwname)
73#endif 79#endif
74 80
75#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL 81#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
76 r = get_default_context_with_level(sename, lvl, NULL, &sc); 82 if (role != NULL && role[0])
83 r = get_default_context_with_rolelevel(sename, role, lvl, NULL,
84 &sc);
85 else
86 r = get_default_context_with_level(sename, lvl, NULL, &sc);
77#else 87#else
78 r = get_default_context(sename, NULL, &sc); 88 if (role != NULL && role[0])
89 r = get_default_context_with_role(sename, role, NULL, &sc);
90 else
91 r = get_default_context(sename, NULL, &sc);
79#endif 92#endif
80 93
81 if (r != 0) { 94 if (r != 0) {
@@ -105,7 +118,7 @@ ssh_selinux_getctxbyname(char *pwname)
105 118
106/* Set the execution context to the default for the specified user */ 119/* Set the execution context to the default for the specified user */
107void 120void
108ssh_selinux_setup_exec_context(char *pwname) 121ssh_selinux_setup_exec_context(char *pwname, const char *role)
109{ 122{
110 security_context_t user_ctx = NULL; 123 security_context_t user_ctx = NULL;
111 124
@@ -114,7 +127,7 @@ ssh_selinux_setup_exec_context(char *pwname)
114 127
115 debug3("%s: setting execution context", __func__); 128 debug3("%s: setting execution context", __func__);
116 129
117 user_ctx = ssh_selinux_getctxbyname(pwname); 130 user_ctx = ssh_selinux_getctxbyname(pwname, role);
118 if (setexeccon(user_ctx) != 0) { 131 if (setexeccon(user_ctx) != 0) {
119 switch (security_getenforce()) { 132 switch (security_getenforce()) {
120 case -1: 133 case -1:
@@ -136,7 +149,7 @@ ssh_selinux_setup_exec_context(char *pwname)
136 149
137/* Set the TTY context for the specified user */ 150/* Set the TTY context for the specified user */
138void 151void
139ssh_selinux_setup_pty(char *pwname, const char *tty) 152ssh_selinux_setup_pty(char *pwname, const char *tty, const char *role)
140{ 153{
141 security_context_t new_tty_ctx = NULL; 154 security_context_t new_tty_ctx = NULL;
142 security_context_t user_ctx = NULL; 155 security_context_t user_ctx = NULL;
@@ -147,7 +160,7 @@ ssh_selinux_setup_pty(char *pwname, const char *tty)
147 160
148 debug3("%s: setting TTY context on %s", __func__, tty); 161 debug3("%s: setting TTY context on %s", __func__, tty);
149 162
150 user_ctx = ssh_selinux_getctxbyname(pwname); 163 user_ctx = ssh_selinux_getctxbyname(pwname, role);
151 164
152 /* XXX: should these calls fatal() upon failure in enforcing mode? */ 165 /* XXX: should these calls fatal() upon failure in enforcing mode? */
153 166
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
index e3d1004aa..80ce13ad9 100644
--- a/openbsd-compat/port-linux.h
+++ b/openbsd-compat/port-linux.h
@@ -21,8 +21,8 @@
21 21
22#ifdef WITH_SELINUX 22#ifdef WITH_SELINUX
23int ssh_selinux_enabled(void); 23int ssh_selinux_enabled(void);
24void ssh_selinux_setup_pty(char *, const char *); 24void ssh_selinux_setup_pty(char *, const char *, const char *);
25void ssh_selinux_setup_exec_context(char *); 25void ssh_selinux_setup_exec_context(char *, const char *);
26void ssh_selinux_change_context(const char *); 26void ssh_selinux_change_context(const char *);
27void ssh_selinux_setfscreatecon(const char *); 27void ssh_selinux_setfscreatecon(const char *);
28#endif 28#endif
diff --git a/platform.c b/platform.c
index ee313da55..f35ec39a8 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 e687c99b6..823901b65 100644
--- a/platform.h
+++ b/platform.h
@@ -27,7 +27,7 @@ void platform_post_fork_parent(pid_t child_pid);
27void platform_post_fork_child(void); 27void platform_post_fork_child(void);
28int platform_privileged_uidswap(void); 28int platform_privileged_uidswap(void);
29void platform_setusercontext(struct passwd *); 29void platform_setusercontext(struct passwd *);
30void platform_setusercontext_post_groups(struct passwd *); 30void platform_setusercontext_post_groups(struct passwd *, const char *);
31char *platform_get_krb5_client(const char *); 31char *platform_get_krb5_client(const char *);
32char *platform_krb5_get_principal_name(const char *); 32char *platform_krb5_get_principal_name(const char *);
33int platform_sys_dir_uid(uid_t); 33int platform_sys_dir_uid(uid_t);
diff --git a/session.c b/session.c
index 7a02500ab..99ec6f363 100644
--- a/session.c
+++ b/session.c
@@ -1489,7 +1489,7 @@ safely_chroot(const char *path, uid_t uid)
1489 1489
1490/* Set login name, uid, gid, and groups. */ 1490/* Set login name, uid, gid, and groups. */
1491void 1491void
1492do_setusercontext(struct passwd *pw) 1492do_setusercontext(struct passwd *pw, const char *role)
1493{ 1493{
1494 char *chroot_path, *tmp; 1494 char *chroot_path, *tmp;
1495 1495
@@ -1517,7 +1517,7 @@ do_setusercontext(struct passwd *pw)
1517 endgrent(); 1517 endgrent();
1518#endif 1518#endif
1519 1519
1520 platform_setusercontext_post_groups(pw); 1520 platform_setusercontext_post_groups(pw, role);
1521 1521
1522 if (!in_chroot && options.chroot_directory != NULL && 1522 if (!in_chroot && options.chroot_directory != NULL &&
1523 strcasecmp(options.chroot_directory, "none") != 0) { 1523 strcasecmp(options.chroot_directory, "none") != 0) {
@@ -1674,7 +1674,7 @@ do_child(Session *s, const char *command)
1674 1674
1675 /* Force a password change */ 1675 /* Force a password change */
1676 if (s->authctxt->force_pwchange) { 1676 if (s->authctxt->force_pwchange) {
1677 do_setusercontext(pw); 1677 do_setusercontext(pw, s->authctxt->role);
1678 child_close_fds(); 1678 child_close_fds();
1679 do_pwchange(s); 1679 do_pwchange(s);
1680 exit(1); 1680 exit(1);
@@ -1701,7 +1701,7 @@ do_child(Session *s, const char *command)
1701 /* When PAM is enabled we rely on it to do the nologin check */ 1701 /* When PAM is enabled we rely on it to do the nologin check */
1702 if (!options.use_pam) 1702 if (!options.use_pam)
1703 do_nologin(pw); 1703 do_nologin(pw);
1704 do_setusercontext(pw); 1704 do_setusercontext(pw, s->authctxt->role);
1705 /* 1705 /*
1706 * PAM session modules in do_setusercontext may have 1706 * PAM session modules in do_setusercontext may have
1707 * generated messages, so if this in an interactive 1707 * generated messages, so if this in an interactive
@@ -2112,7 +2112,7 @@ session_pty_req(Session *s)
2112 tty_parse_modes(s->ttyfd, &n_bytes); 2112 tty_parse_modes(s->ttyfd, &n_bytes);
2113 2113
2114 if (!use_privsep) 2114 if (!use_privsep)
2115 pty_setowner(s->pw, s->tty); 2115 pty_setowner(s->pw, s->tty, s->authctxt->role);
2116 2116
2117 /* Set window size from the packet. */ 2117 /* Set window size from the packet. */
2118 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 2118 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
diff --git a/session.h b/session.h
index 6a2f35e41..ef6593c34 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(Session *); 79void session_close(Session *);
80void do_setusercontext(struct passwd *); 80void do_setusercontext(struct passwd *, const char *);
81void child_set_env(char ***envp, u_int *envsizep, const char *name, 81void child_set_env(char ***envp, u_int *envsizep, const char *name,
82 const char *value); 82 const char *value);
83 83
diff --git a/sshd.c b/sshd.c
index d1dd711fc..bb093ccc0 100644
--- a/sshd.c
+++ b/sshd.c
@@ -781,7 +781,7 @@ privsep_postauth(Authctxt *authctxt)
781 explicit_bzero(rnd, sizeof(rnd)); 781 explicit_bzero(rnd, sizeof(rnd));
782 782
783 /* Drop privileges */ 783 /* Drop privileges */
784 do_setusercontext(authctxt->pw); 784 do_setusercontext(authctxt->pw, authctxt->role);
785 785
786 skip: 786 skip:
787 /* It is safe now to apply the key state */ 787 /* It is safe now to apply the key state */
diff --git a/sshpty.c b/sshpty.c
index 15da8c649..e89efb74a 100644
--- a/sshpty.c
+++ b/sshpty.c
@@ -187,7 +187,7 @@ pty_change_window_size(int ptyfd, u_int row, u_int col,
187} 187}
188 188
189void 189void
190pty_setowner(struct passwd *pw, const char *tty) 190pty_setowner(struct passwd *pw, const char *tty, const char *role)
191{ 191{
192 struct group *grp; 192 struct group *grp;
193 gid_t gid; 193 gid_t gid;
@@ -209,7 +209,7 @@ pty_setowner(struct passwd *pw, const char *tty)
209 strerror(errno)); 209 strerror(errno));
210 210
211#ifdef WITH_SELINUX 211#ifdef WITH_SELINUX
212 ssh_selinux_setup_pty(pw->pw_name, tty); 212 ssh_selinux_setup_pty(pw->pw_name, tty, role);
213#endif 213#endif
214 214
215 if (st.st_uid != pw->pw_uid || st.st_gid != gid) { 215 if (st.st_uid != pw->pw_uid || st.st_gid != gid) {
diff --git a/sshpty.h b/sshpty.h
index cfa322480..edf24365f 100644
--- a/sshpty.h
+++ b/sshpty.h
@@ -24,4 +24,4 @@ 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 *);