summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManoj Srivastava <srivasta@debian.org>2014-02-09 16:09:49 +0000
committerColin Watson <cjwatson@debian.org>2014-02-09 16:17:20 +0000
commit07f2a771c490bd68cd5c5ea9c535705e93bd94f3 (patch)
tree3e2ead17b4c91699c13b0417d46bfd750a04e0b8
parent950be7e1b1a01ee9b25e2a72726a6370b8acacb6 (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: 2013-09-14 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 80f089869..5b6824f71 100644
--- a/auth.h
+++ b/auth.h
@@ -59,6 +59,7 @@ struct Authctxt {
59 char *service; 59 char *service;
60 struct passwd *pw; /* set if 'valid' */ 60 struct passwd *pw; /* set if 'valid' */
61 char *style; 61 char *style;
62 char *role;
62 void *kbdintctxt; 63 void *kbdintctxt;
63 char *info; /* Extra info for next auth_log */ 64 char *info; /* Extra info for next auth_log */
64 void *jpake_ctx; 65 void *jpake_ctx;
diff --git a/auth1.c b/auth1.c
index f1ac59814..2803a3c97 100644
--- a/auth1.c
+++ b/auth1.c
@@ -380,7 +380,7 @@ void
380do_authentication(Authctxt *authctxt) 380do_authentication(Authctxt *authctxt)
381{ 381{
382 u_int ulen; 382 u_int ulen;
383 char *user, *style = NULL; 383 char *user, *style = NULL, *role = NULL;
384 384
385 /* Get the name of the user that we wish to log in as. */ 385 /* Get the name of the user that we wish to log in as. */
386 packet_read_expect(SSH_CMSG_USER); 386 packet_read_expect(SSH_CMSG_USER);
@@ -389,11 +389,17 @@ do_authentication(Authctxt *authctxt)
389 user = packet_get_cstring(&ulen); 389 user = packet_get_cstring(&ulen);
390 packet_check_eom(); 390 packet_check_eom();
391 391
392 if ((role = strchr(user, '/')) != NULL)
393 *role++ = '\0';
394
392 if ((style = strchr(user, ':')) != NULL) 395 if ((style = strchr(user, ':')) != NULL)
393 *style++ = '\0'; 396 *style++ = '\0';
397 else if (role && (style = strchr(role, ':')) != NULL)
398 *style++ = '\0';
394 399
395 authctxt->user = user; 400 authctxt->user = user;
396 authctxt->style = style; 401 authctxt->style = style;
402 authctxt->role = role;
397 403
398 /* Verify that the user is a valid user. */ 404 /* Verify that the user is a valid user. */
399 if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) 405 if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
diff --git a/auth2.c b/auth2.c
index 6ed8f042b..b55bbcd95 100644
--- a/auth2.c
+++ b/auth2.c
@@ -222,7 +222,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
222{ 222{
223 Authctxt *authctxt = ctxt; 223 Authctxt *authctxt = ctxt;
224 Authmethod *m = NULL; 224 Authmethod *m = NULL;
225 char *user, *service, *method, *style = NULL; 225 char *user, *service, *method, *style = NULL, *role = NULL;
226 int authenticated = 0; 226 int authenticated = 0;
227 227
228 if (authctxt == NULL) 228 if (authctxt == NULL)
@@ -234,8 +234,13 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
234 debug("userauth-request for user %s service %s method %s", user, service, method); 234 debug("userauth-request for user %s service %s method %s", user, service, method);
235 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); 235 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
236 236
237 if ((role = strchr(user, '/')) != NULL)
238 *role++ = 0;
239
237 if ((style = strchr(user, ':')) != NULL) 240 if ((style = strchr(user, ':')) != NULL)
238 *style++ = 0; 241 *style++ = 0;
242 else if (role && (style = strchr(role, ':')) != NULL)
243 *style++ = '\0';
239 244
240 if (authctxt->attempt++ == 0) { 245 if (authctxt->attempt++ == 0) {
241 /* setup auth context */ 246 /* setup auth context */
@@ -259,8 +264,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
259 use_privsep ? " [net]" : ""); 264 use_privsep ? " [net]" : "");
260 authctxt->service = xstrdup(service); 265 authctxt->service = xstrdup(service);
261 authctxt->style = style ? xstrdup(style) : NULL; 266 authctxt->style = style ? xstrdup(style) : NULL;
267 authctxt->role = role ? xstrdup(role) : NULL;
262 if (use_privsep) 268 if (use_privsep)
263 mm_inform_authserv(service, style); 269 mm_inform_authserv(service, style, role);
264 userauth_banner(); 270 userauth_banner();
265 if (auth2_setup_methods_lists(authctxt) != 0) 271 if (auth2_setup_methods_lists(authctxt) != 0)
266 packet_disconnect("no authentication methods enabled"); 272 packet_disconnect("no authentication methods enabled");
diff --git a/monitor.c b/monitor.c
index 9079c9762..e8d63eb22 100644
--- a/monitor.c
+++ b/monitor.c
@@ -146,6 +146,7 @@ int mm_answer_sign(int, Buffer *);
146int mm_answer_pwnamallow(int, Buffer *); 146int mm_answer_pwnamallow(int, Buffer *);
147int mm_answer_auth2_read_banner(int, Buffer *); 147int mm_answer_auth2_read_banner(int, Buffer *);
148int mm_answer_authserv(int, Buffer *); 148int mm_answer_authserv(int, Buffer *);
149int mm_answer_authrole(int, Buffer *);
149int mm_answer_authpassword(int, Buffer *); 150int mm_answer_authpassword(int, Buffer *);
150int mm_answer_bsdauthquery(int, Buffer *); 151int mm_answer_bsdauthquery(int, Buffer *);
151int mm_answer_bsdauthrespond(int, Buffer *); 152int mm_answer_bsdauthrespond(int, Buffer *);
@@ -227,6 +228,7 @@ struct mon_table mon_dispatch_proto20[] = {
227 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, 228 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
228 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, 229 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
229 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, 230 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
231 {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole},
230 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, 232 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
231 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, 233 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
232#ifdef USE_PAM 234#ifdef USE_PAM
@@ -844,6 +846,7 @@ mm_answer_pwnamallow(int sock, Buffer *m)
844 else { 846 else {
845 /* Allow service/style information on the auth context */ 847 /* Allow service/style information on the auth context */
846 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); 848 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
849 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1);
847 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); 850 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
848 } 851 }
849#ifdef USE_PAM 852#ifdef USE_PAM
@@ -874,14 +877,37 @@ mm_answer_authserv(int sock, Buffer *m)
874 877
875 authctxt->service = buffer_get_string(m, NULL); 878 authctxt->service = buffer_get_string(m, NULL);
876 authctxt->style = buffer_get_string(m, NULL); 879 authctxt->style = buffer_get_string(m, NULL);
877 debug3("%s: service=%s, style=%s", 880 authctxt->role = buffer_get_string(m, NULL);
878 __func__, authctxt->service, authctxt->style); 881 debug3("%s: service=%s, style=%s, role=%s",
882 __func__, authctxt->service, authctxt->style, authctxt->role);
879 883
880 if (strlen(authctxt->style) == 0) { 884 if (strlen(authctxt->style) == 0) {
881 free(authctxt->style); 885 free(authctxt->style);
882 authctxt->style = NULL; 886 authctxt->style = NULL;
883 } 887 }
884 888
889 if (strlen(authctxt->role) == 0) {
890 free(authctxt->role);
891 authctxt->role = NULL;
892 }
893
894 return (0);
895}
896
897int
898mm_answer_authrole(int sock, Buffer *m)
899{
900 monitor_permit_authentications(1);
901
902 authctxt->role = buffer_get_string(m, NULL);
903 debug3("%s: role=%s",
904 __func__, authctxt->role);
905
906 if (strlen(authctxt->role) == 0) {
907 free(authctxt->role);
908 authctxt->role = NULL;
909 }
910
885 return (0); 911 return (0);
886} 912}
887 913
@@ -1486,7 +1512,7 @@ mm_answer_pty(int sock, Buffer *m)
1486 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); 1512 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
1487 if (res == 0) 1513 if (res == 0)
1488 goto error; 1514 goto error;
1489 pty_setowner(authctxt->pw, s->tty); 1515 pty_setowner(authctxt->pw, s->tty, authctxt->role);
1490 1516
1491 buffer_put_int(m, 1); 1517 buffer_put_int(m, 1);
1492 buffer_put_cstring(m, s->tty); 1518 buffer_put_cstring(m, s->tty);
diff --git a/monitor.h b/monitor.h
index 315ef996d..3c13706a8 100644
--- a/monitor.h
+++ b/monitor.h
@@ -73,6 +73,8 @@ enum monitor_reqtype {
73 MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, 73 MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151,
74 MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, 74 MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153,
75 75
76 MONITOR_REQ_AUTHROLE = 154,
77
76}; 78};
77 79
78struct mm_master; 80struct mm_master;
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 44019f32a..69bc324b5 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -320,10 +320,10 @@ mm_auth2_read_banner(void)
320 return (banner); 320 return (banner);
321} 321}
322 322
323/* Inform the privileged process about service and style */ 323/* Inform the privileged process about service, style, and role */
324 324
325void 325void
326mm_inform_authserv(char *service, char *style) 326mm_inform_authserv(char *service, char *style, char *role)
327{ 327{
328 Buffer m; 328 Buffer m;
329 329
@@ -332,12 +332,30 @@ mm_inform_authserv(char *service, char *style)
332 buffer_init(&m); 332 buffer_init(&m);
333 buffer_put_cstring(&m, service); 333 buffer_put_cstring(&m, service);
334 buffer_put_cstring(&m, style ? style : ""); 334 buffer_put_cstring(&m, style ? style : "");
335 buffer_put_cstring(&m, role ? role : "");
335 336
336 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m); 337 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
337 338
338 buffer_free(&m); 339 buffer_free(&m);
339} 340}
340 341
342/* Inform the privileged process about role */
343
344void
345mm_inform_authrole(char *role)
346{
347 Buffer m;
348
349 debug3("%s entering", __func__);
350
351 buffer_init(&m);
352 buffer_put_cstring(&m, role ? role : "");
353
354 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m);
355
356 buffer_free(&m);
357}
358
341/* Do the password authentication */ 359/* Do the password authentication */
342int 360int
343mm_auth_password(Authctxt *authctxt, char *password) 361mm_auth_password(Authctxt *authctxt, char *password)
diff --git a/monitor_wrap.h b/monitor_wrap.h
index ec9b9b1c3..4d12e2956 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 *, u_char *, u_int); 43int mm_key_sign(Key *, u_char **, u_int *, 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 4637a7a3e..de6ad3fd7 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 3262b2478..a962f15b5 100644
--- a/platform.c
+++ b/platform.c
@@ -134,7 +134,7 @@ platform_setusercontext(struct passwd *pw)
134 * called if sshd is running as root. 134 * called if sshd is running as root.
135 */ 135 */
136void 136void
137platform_setusercontext_post_groups(struct passwd *pw) 137platform_setusercontext_post_groups(struct passwd *pw, const char *role)
138{ 138{
139#if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM) 139#if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM)
140 /* 140 /*
@@ -181,7 +181,7 @@ platform_setusercontext_post_groups(struct passwd *pw)
181 } 181 }
182#endif /* HAVE_SETPCRED */ 182#endif /* HAVE_SETPCRED */
183#ifdef WITH_SELINUX 183#ifdef WITH_SELINUX
184 ssh_selinux_setup_exec_context(pw->pw_name); 184 ssh_selinux_setup_exec_context(pw->pw_name, role);
185#endif 185#endif
186} 186}
187 187
diff --git a/platform.h b/platform.h
index 19f6bfdd3..3188a3d7c 100644
--- a/platform.h
+++ b/platform.h
@@ -26,7 +26,7 @@ void platform_post_fork_parent(pid_t child_pid);
26void platform_post_fork_child(void); 26void platform_post_fork_child(void);
27int platform_privileged_uidswap(void); 27int platform_privileged_uidswap(void);
28void platform_setusercontext(struct passwd *); 28void platform_setusercontext(struct passwd *);
29void platform_setusercontext_post_groups(struct passwd *); 29void platform_setusercontext_post_groups(struct passwd *, const char *);
30char *platform_get_krb5_client(const char *); 30char *platform_get_krb5_client(const char *);
31char *platform_krb5_get_principal_name(const char *); 31char *platform_krb5_get_principal_name(const char *);
32int platform_sys_dir_uid(uid_t); 32int platform_sys_dir_uid(uid_t);
diff --git a/session.c b/session.c
index d4b57bdfb..b4d74d984 100644
--- a/session.c
+++ b/session.c
@@ -1474,7 +1474,7 @@ safely_chroot(const char *path, uid_t uid)
1474 1474
1475/* Set login name, uid, gid, and groups. */ 1475/* Set login name, uid, gid, and groups. */
1476void 1476void
1477do_setusercontext(struct passwd *pw) 1477do_setusercontext(struct passwd *pw, const char *role)
1478{ 1478{
1479 char *chroot_path, *tmp; 1479 char *chroot_path, *tmp;
1480 1480
@@ -1502,7 +1502,7 @@ do_setusercontext(struct passwd *pw)
1502 endgrent(); 1502 endgrent();
1503#endif 1503#endif
1504 1504
1505 platform_setusercontext_post_groups(pw); 1505 platform_setusercontext_post_groups(pw, role);
1506 1506
1507 if (options.chroot_directory != NULL && 1507 if (options.chroot_directory != NULL &&
1508 strcasecmp(options.chroot_directory, "none") != 0) { 1508 strcasecmp(options.chroot_directory, "none") != 0) {
@@ -1646,7 +1646,7 @@ do_child(Session *s, const char *command)
1646 1646
1647 /* Force a password change */ 1647 /* Force a password change */
1648 if (s->authctxt->force_pwchange) { 1648 if (s->authctxt->force_pwchange) {
1649 do_setusercontext(pw); 1649 do_setusercontext(pw, s->authctxt->role);
1650 child_close_fds(); 1650 child_close_fds();
1651 do_pwchange(s); 1651 do_pwchange(s);
1652 exit(1); 1652 exit(1);
@@ -1673,7 +1673,7 @@ do_child(Session *s, const char *command)
1673 /* When PAM is enabled we rely on it to do the nologin check */ 1673 /* When PAM is enabled we rely on it to do the nologin check */
1674 if (!options.use_pam) 1674 if (!options.use_pam)
1675 do_nologin(pw); 1675 do_nologin(pw);
1676 do_setusercontext(pw); 1676 do_setusercontext(pw, s->authctxt->role);
1677 /* 1677 /*
1678 * PAM session modules in do_setusercontext may have 1678 * PAM session modules in do_setusercontext may have
1679 * generated messages, so if this in an interactive 1679 * generated messages, so if this in an interactive
@@ -2084,7 +2084,7 @@ session_pty_req(Session *s)
2084 tty_parse_modes(s->ttyfd, &n_bytes); 2084 tty_parse_modes(s->ttyfd, &n_bytes);
2085 2085
2086 if (!use_privsep) 2086 if (!use_privsep)
2087 pty_setowner(s->pw, s->tty); 2087 pty_setowner(s->pw, s->tty, s->authctxt->role);
2088 2088
2089 /* Set window size from the packet. */ 2089 /* Set window size from the packet. */
2090 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 2090 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
diff --git a/session.h b/session.h
index cbb8e3a32..cb4f19600 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(Session *); 78void session_close(Session *);
79void do_setusercontext(struct passwd *); 79void do_setusercontext(struct passwd *, const char *);
80void child_set_env(char ***envp, u_int *envsizep, const char *name, 80void child_set_env(char ***envp, u_int *envsizep, const char *name,
81 const char *value); 81 const char *value);
82 82
diff --git a/sshd.c b/sshd.c
index 4eddeb8d8..e5c983514 100644
--- a/sshd.c
+++ b/sshd.c
@@ -753,7 +753,7 @@ privsep_postauth(Authctxt *authctxt)
753 RAND_seed(rnd, sizeof(rnd)); 753 RAND_seed(rnd, sizeof(rnd));
754 754
755 /* Drop privileges */ 755 /* Drop privileges */
756 do_setusercontext(authctxt->pw); 756 do_setusercontext(authctxt->pw, authctxt->role);
757 757
758 skip: 758 skip:
759 /* It is safe now to apply the key state */ 759 /* It is safe now to apply the key state */
diff --git a/sshpty.c b/sshpty.c
index bbbc0fefe..8cc26a249 100644
--- a/sshpty.c
+++ b/sshpty.c
@@ -200,7 +200,7 @@ pty_change_window_size(int ptyfd, u_int row, u_int col,
200} 200}
201 201
202void 202void
203pty_setowner(struct passwd *pw, const char *tty) 203pty_setowner(struct passwd *pw, const char *tty, const char *role)
204{ 204{
205 struct group *grp; 205 struct group *grp;
206 gid_t gid; 206 gid_t gid;
@@ -227,7 +227,7 @@ pty_setowner(struct passwd *pw, const char *tty)
227 strerror(errno)); 227 strerror(errno));
228 228
229#ifdef WITH_SELINUX 229#ifdef WITH_SELINUX
230 ssh_selinux_setup_pty(pw->pw_name, tty); 230 ssh_selinux_setup_pty(pw->pw_name, tty, role);
231#endif 231#endif
232 232
233 if (st.st_uid != pw->pw_uid || st.st_gid != gid) { 233 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 *);