summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManoj Srivastava <srivasta@debian.org>2014-02-09 16:09:49 +0000
committerColin Watson <cjwatson@debian.org>2016-08-07 12:18:42 +0100
commit7a7851c903e5dbb58a85014deb2c88cb718068c9 (patch)
tree3c558bbeaf0e964e6b9c55128f0f8007113c47ef
parentc027de5eb3e6cb1718990841c2a9cbc89fd53151 (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 55170af50..50baeaadb 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 ce0d37601..461311bda 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 05bb48a8e..e91054e5f 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 *);
@@ -209,6 +210,7 @@ struct mon_table mon_dispatch_proto20[] = {
209 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, 210 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
210 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, 211 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
211 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, 212 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
213 {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole},
212 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, 214 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
213 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, 215 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
214#ifdef USE_PAM 216#ifdef USE_PAM
@@ -880,6 +882,7 @@ mm_answer_pwnamallow(int sock, Buffer *m)
880 else { 882 else {
881 /* Allow service/style information on the auth context */ 883 /* Allow service/style information on the auth context */
882 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); 884 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
885 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1);
883 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); 886 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
884 } 887 }
885#ifdef USE_PAM 888#ifdef USE_PAM
@@ -910,14 +913,37 @@ mm_answer_authserv(int sock, Buffer *m)
910 913
911 authctxt->service = buffer_get_string(m, NULL); 914 authctxt->service = buffer_get_string(m, NULL);
912 authctxt->style = buffer_get_string(m, NULL); 915 authctxt->style = buffer_get_string(m, NULL);
913 debug3("%s: service=%s, style=%s", 916 authctxt->role = buffer_get_string(m, NULL);
914 __func__, authctxt->service, authctxt->style); 917 debug3("%s: service=%s, style=%s, role=%s",
918 __func__, authctxt->service, authctxt->style, authctxt->role);
915 919
916 if (strlen(authctxt->style) == 0) { 920 if (strlen(authctxt->style) == 0) {
917 free(authctxt->style); 921 free(authctxt->style);
918 authctxt->style = NULL; 922 authctxt->style = NULL;
919 } 923 }
920 924
925 if (strlen(authctxt->role) == 0) {
926 free(authctxt->role);
927 authctxt->role = NULL;
928 }
929
930 return (0);
931}
932
933int
934mm_answer_authrole(int sock, Buffer *m)
935{
936 monitor_permit_authentications(1);
937
938 authctxt->role = buffer_get_string(m, NULL);
939 debug3("%s: role=%s",
940 __func__, authctxt->role);
941
942 if (strlen(authctxt->role) == 0) {
943 free(authctxt->role);
944 authctxt->role = NULL;
945 }
946
921 return (0); 947 return (0);
922} 948}
923 949
@@ -1553,7 +1579,7 @@ mm_answer_pty(int sock, Buffer *m)
1553 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); 1579 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
1554 if (res == 0) 1580 if (res == 0)
1555 goto error; 1581 goto error;
1556 pty_setowner(authctxt->pw, s->tty); 1582 pty_setowner(authctxt->pw, s->tty, authctxt->role);
1557 1583
1558 buffer_put_int(m, 1); 1584 buffer_put_int(m, 1);
1559 buffer_put_cstring(m, s->tty); 1585 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 5a9f1b52d..11e3a6956 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -328,10 +328,10 @@ mm_auth2_read_banner(void)
328 return (banner); 328 return (banner);
329} 329}
330 330
331/* Inform the privileged process about service and style */ 331/* Inform the privileged process about service, style, and role */
332 332
333void 333void
334mm_inform_authserv(char *service, char *style) 334mm_inform_authserv(char *service, char *style, char *role)
335{ 335{
336 Buffer m; 336 Buffer m;
337 337
@@ -340,12 +340,30 @@ mm_inform_authserv(char *service, char *style)
340 buffer_init(&m); 340 buffer_init(&m);
341 buffer_put_cstring(&m, service); 341 buffer_put_cstring(&m, service);
342 buffer_put_cstring(&m, style ? style : ""); 342 buffer_put_cstring(&m, style ? style : "");
343 buffer_put_cstring(&m, role ? role : "");
343 344
344 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m); 345 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
345 346
346 buffer_free(&m); 347 buffer_free(&m);
347} 348}
348 349
350/* Inform the privileged process about role */
351
352void
353mm_inform_authrole(char *role)
354{
355 Buffer m;
356
357 debug3("%s entering", __func__);
358
359 buffer_init(&m);
360 buffer_put_cstring(&m, role ? role : "");
361
362 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m);
363
364 buffer_free(&m);
365}
366
349/* Do the password authentication */ 367/* Do the password authentication */
350int 368int
351mm_auth_password(Authctxt *authctxt, char *password) 369mm_auth_password(Authctxt *authctxt, char *password)
diff --git a/monitor_wrap.h b/monitor_wrap.h
index b5414c298..d5b3334dc 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 acf8554cd..483170680 100644
--- a/platform.c
+++ b/platform.c
@@ -145,7 +145,7 @@ platform_setusercontext(struct passwd *pw)
145 * called if sshd is running as root. 145 * called if sshd is running as root.
146 */ 146 */
147void 147void
148platform_setusercontext_post_groups(struct passwd *pw) 148platform_setusercontext_post_groups(struct passwd *pw, const char *role)
149{ 149{
150#if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM) 150#if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM)
151 /* 151 /*
@@ -186,7 +186,7 @@ platform_setusercontext_post_groups(struct passwd *pw)
186 } 186 }
187#endif /* HAVE_SETPCRED */ 187#endif /* HAVE_SETPCRED */
188#ifdef WITH_SELINUX 188#ifdef WITH_SELINUX
189 ssh_selinux_setup_exec_context(pw->pw_name); 189 ssh_selinux_setup_exec_context(pw->pw_name, role);
190#endif 190#endif
191} 191}
192 192
diff --git a/platform.h b/platform.h
index e97ecd909..5b7230428 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 2235f26ac..6dfcf842f 100644
--- a/session.c
+++ b/session.c
@@ -1517,7 +1517,7 @@ safely_chroot(const char *path, uid_t uid)
1517 1517
1518/* Set login name, uid, gid, and groups. */ 1518/* Set login name, uid, gid, and groups. */
1519void 1519void
1520do_setusercontext(struct passwd *pw) 1520do_setusercontext(struct passwd *pw, const char *role)
1521{ 1521{
1522 char *chroot_path, *tmp; 1522 char *chroot_path, *tmp;
1523 1523
@@ -1545,7 +1545,7 @@ do_setusercontext(struct passwd *pw)
1545 endgrent(); 1545 endgrent();
1546#endif 1546#endif
1547 1547
1548 platform_setusercontext_post_groups(pw); 1548 platform_setusercontext_post_groups(pw, role);
1549 1549
1550 if (!in_chroot && options.chroot_directory != NULL && 1550 if (!in_chroot && options.chroot_directory != NULL &&
1551 strcasecmp(options.chroot_directory, "none") != 0) { 1551 strcasecmp(options.chroot_directory, "none") != 0) {
@@ -1703,7 +1703,7 @@ do_child(Session *s, const char *command)
1703 1703
1704 /* Force a password change */ 1704 /* Force a password change */
1705 if (s->authctxt->force_pwchange) { 1705 if (s->authctxt->force_pwchange) {
1706 do_setusercontext(pw); 1706 do_setusercontext(pw, s->authctxt->role);
1707 child_close_fds(); 1707 child_close_fds();
1708 do_pwchange(s); 1708 do_pwchange(s);
1709 exit(1); 1709 exit(1);
@@ -1730,7 +1730,7 @@ do_child(Session *s, const char *command)
1730 /* When PAM is enabled we rely on it to do the nologin check */ 1730 /* When PAM is enabled we rely on it to do the nologin check */
1731 if (!options.use_pam) 1731 if (!options.use_pam)
1732 do_nologin(pw); 1732 do_nologin(pw);
1733 do_setusercontext(pw); 1733 do_setusercontext(pw, s->authctxt->role);
1734 /* 1734 /*
1735 * PAM session modules in do_setusercontext may have 1735 * PAM session modules in do_setusercontext may have
1736 * generated messages, so if this in an interactive 1736 * generated messages, so if this in an interactive
@@ -2141,7 +2141,7 @@ session_pty_req(Session *s)
2141 tty_parse_modes(s->ttyfd, &n_bytes); 2141 tty_parse_modes(s->ttyfd, &n_bytes);
2142 2142
2143 if (!use_privsep) 2143 if (!use_privsep)
2144 pty_setowner(s->pw, s->tty); 2144 pty_setowner(s->pw, s->tty, s->authctxt->role);
2145 2145
2146 /* Set window size from the packet. */ 2146 /* Set window size from the packet. */
2147 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 2147 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
diff --git a/session.h b/session.h
index f18eaf329..2b7d939c8 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 982e5455e..76306da24 100644
--- a/sshd.c
+++ b/sshd.c
@@ -787,7 +787,7 @@ privsep_postauth(Authctxt *authctxt)
787 explicit_bzero(rnd, sizeof(rnd)); 787 explicit_bzero(rnd, sizeof(rnd));
788 788
789 /* Drop privileges */ 789 /* Drop privileges */
790 do_setusercontext(authctxt->pw); 790 do_setusercontext(authctxt->pw, authctxt->role);
791 791
792 skip: 792 skip:
793 /* It is safe now to apply the key state */ 793 /* 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 *);