summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManoj Srivastava <srivasta@debian.org>2014-02-09 16:09:49 +0000
committerColin Watson <cjwatson@debian.org>2016-01-04 15:07:00 +0000
commit5f583693723b0f56608a9a91e58b248219a668c9 (patch)
tree6150b43049000afeb3ed01fa6d25e08d403c8f9c
parentc538473bc1958b99bb26283752f287df5934045a (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 8b27575b0..3c2222f79 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 2658aaa53..c063ad1a0 100644
--- a/monitor.c
+++ b/monitor.c
@@ -127,6 +127,7 @@ int mm_answer_sign(int, Buffer *);
127int mm_answer_pwnamallow(int, Buffer *); 127int mm_answer_pwnamallow(int, Buffer *);
128int mm_answer_auth2_read_banner(int, Buffer *); 128int mm_answer_auth2_read_banner(int, Buffer *);
129int mm_answer_authserv(int, Buffer *); 129int mm_answer_authserv(int, Buffer *);
130int mm_answer_authrole(int, Buffer *);
130int mm_answer_authpassword(int, Buffer *); 131int mm_answer_authpassword(int, Buffer *);
131int mm_answer_bsdauthquery(int, Buffer *); 132int mm_answer_bsdauthquery(int, Buffer *);
132int mm_answer_bsdauthrespond(int, Buffer *); 133int mm_answer_bsdauthrespond(int, Buffer *);
@@ -208,6 +209,7 @@ struct mon_table mon_dispatch_proto20[] = {
208 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, 209 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
209 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, 210 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
210 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, 211 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
212 {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole},
211 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, 213 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
212 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, 214 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
213#ifdef USE_PAM 215#ifdef USE_PAM
@@ -879,6 +881,7 @@ mm_answer_pwnamallow(int sock, Buffer *m)
879 else { 881 else {
880 /* Allow service/style information on the auth context */ 882 /* Allow service/style information on the auth context */
881 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); 883 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
884 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1);
882 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); 885 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
883 } 886 }
884#ifdef USE_PAM 887#ifdef USE_PAM
@@ -909,14 +912,37 @@ mm_answer_authserv(int sock, Buffer *m)
909 912
910 authctxt->service = buffer_get_string(m, NULL); 913 authctxt->service = buffer_get_string(m, NULL);
911 authctxt->style = buffer_get_string(m, NULL); 914 authctxt->style = buffer_get_string(m, NULL);
912 debug3("%s: service=%s, style=%s", 915 authctxt->role = buffer_get_string(m, NULL);
913 __func__, authctxt->service, authctxt->style); 916 debug3("%s: service=%s, style=%s, role=%s",
917 __func__, authctxt->service, authctxt->style, authctxt->role);
914 918
915 if (strlen(authctxt->style) == 0) { 919 if (strlen(authctxt->style) == 0) {
916 free(authctxt->style); 920 free(authctxt->style);
917 authctxt->style = NULL; 921 authctxt->style = NULL;
918 } 922 }
919 923
924 if (strlen(authctxt->role) == 0) {
925 free(authctxt->role);
926 authctxt->role = NULL;
927 }
928
929 return (0);
930}
931
932int
933mm_answer_authrole(int sock, Buffer *m)
934{
935 monitor_permit_authentications(1);
936
937 authctxt->role = buffer_get_string(m, NULL);
938 debug3("%s: role=%s",
939 __func__, authctxt->role);
940
941 if (strlen(authctxt->role) == 0) {
942 free(authctxt->role);
943 authctxt->role = NULL;
944 }
945
920 return (0); 946 return (0);
921} 947}
922 948
@@ -1544,7 +1570,7 @@ mm_answer_pty(int sock, Buffer *m)
1544 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); 1570 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
1545 if (res == 0) 1571 if (res == 0)
1546 goto error; 1572 goto error;
1547 pty_setowner(authctxt->pw, s->tty); 1573 pty_setowner(authctxt->pw, s->tty, authctxt->role);
1548 1574
1549 buffer_put_int(m, 1); 1575 buffer_put_int(m, 1);
1550 buffer_put_cstring(m, s->tty); 1576 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 81ceddb8f..679991178 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 975829027..57e740f89 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); 43int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int);
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 1c7a45d8f..436ae7c4f 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 5a64715e2..afac4a58f 100644
--- a/session.c
+++ b/session.c
@@ -1487,7 +1487,7 @@ safely_chroot(const char *path, uid_t uid)
1487 1487
1488/* Set login name, uid, gid, and groups. */ 1488/* Set login name, uid, gid, and groups. */
1489void 1489void
1490do_setusercontext(struct passwd *pw) 1490do_setusercontext(struct passwd *pw, const char *role)
1491{ 1491{
1492 char *chroot_path, *tmp; 1492 char *chroot_path, *tmp;
1493#ifdef USE_LIBIAF 1493#ifdef USE_LIBIAF
@@ -1518,7 +1518,7 @@ do_setusercontext(struct passwd *pw)
1518 endgrent(); 1518 endgrent();
1519#endif 1519#endif
1520 1520
1521 platform_setusercontext_post_groups(pw); 1521 platform_setusercontext_post_groups(pw, role);
1522 1522
1523 if (options.chroot_directory != NULL && 1523 if (options.chroot_directory != NULL &&
1524 strcasecmp(options.chroot_directory, "none") != 0) { 1524 strcasecmp(options.chroot_directory, "none") != 0) {
@@ -1677,7 +1677,7 @@ do_child(Session *s, const char *command)
1677 1677
1678 /* Force a password change */ 1678 /* Force a password change */
1679 if (s->authctxt->force_pwchange) { 1679 if (s->authctxt->force_pwchange) {
1680 do_setusercontext(pw); 1680 do_setusercontext(pw, s->authctxt->role);
1681 child_close_fds(); 1681 child_close_fds();
1682 do_pwchange(s); 1682 do_pwchange(s);
1683 exit(1); 1683 exit(1);
@@ -1704,7 +1704,7 @@ do_child(Session *s, const char *command)
1704 /* When PAM is enabled we rely on it to do the nologin check */ 1704 /* When PAM is enabled we rely on it to do the nologin check */
1705 if (!options.use_pam) 1705 if (!options.use_pam)
1706 do_nologin(pw); 1706 do_nologin(pw);
1707 do_setusercontext(pw); 1707 do_setusercontext(pw, s->authctxt->role);
1708 /* 1708 /*
1709 * PAM session modules in do_setusercontext may have 1709 * PAM session modules in do_setusercontext may have
1710 * generated messages, so if this in an interactive 1710 * generated messages, so if this in an interactive
@@ -2115,7 +2115,7 @@ session_pty_req(Session *s)
2115 tty_parse_modes(s->ttyfd, &n_bytes); 2115 tty_parse_modes(s->ttyfd, &n_bytes);
2116 2116
2117 if (!use_privsep) 2117 if (!use_privsep)
2118 pty_setowner(s->pw, s->tty); 2118 pty_setowner(s->pw, s->tty, s->authctxt->role);
2119 2119
2120 /* Set window size from the packet. */ 2120 /* Set window size from the packet. */
2121 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 2121 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 0e30e6e32..0537bc90d 100644
--- a/sshd.c
+++ b/sshd.c
@@ -782,7 +782,7 @@ privsep_postauth(Authctxt *authctxt)
782 explicit_bzero(rnd, sizeof(rnd)); 782 explicit_bzero(rnd, sizeof(rnd));
783 783
784 /* Drop privileges */ 784 /* Drop privileges */
785 do_setusercontext(authctxt->pw); 785 do_setusercontext(authctxt->pw, authctxt->role);
786 786
787 skip: 787 skip:
788 /* It is safe now to apply the key state */ 788 /* 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 *);