summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManoj Srivastava <srivasta@debian.org>2014-02-09 16:09:49 +0000
committerColin Watson <cjwatson@debian.org>2014-10-07 14:26:47 +0100
commitc9638aa44d787849cea1ae273f0908c6313fd19b (patch)
tree6b8681822821aad0dcc92575411f0e6fdfb994bf
parentb25d6dd3b6b5a2cb93723586c56d6fa0277ea56a (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 d081c94a6..f099e9807 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#ifdef BSD_AUTH 65#ifdef BSD_AUTH
diff --git a/auth1.c b/auth1.c
index 50388285c..52b17dbef 100644
--- a/auth1.c
+++ b/auth1.c
@@ -381,7 +381,7 @@ void
381do_authentication(Authctxt *authctxt) 381do_authentication(Authctxt *authctxt)
382{ 382{
383 u_int ulen; 383 u_int ulen;
384 char *user, *style = NULL; 384 char *user, *style = NULL, *role = NULL;
385 385
386 /* Get the name of the user that we wish to log in as. */ 386 /* Get the name of the user that we wish to log in as. */
387 packet_read_expect(SSH_CMSG_USER); 387 packet_read_expect(SSH_CMSG_USER);
@@ -390,11 +390,17 @@ do_authentication(Authctxt *authctxt)
390 user = packet_get_cstring(&ulen); 390 user = packet_get_cstring(&ulen);
391 packet_check_eom(); 391 packet_check_eom();
392 392
393 if ((role = strchr(user, '/')) != NULL)
394 *role++ = '\0';
395
393 if ((style = strchr(user, ':')) != NULL) 396 if ((style = strchr(user, ':')) != NULL)
394 *style++ = '\0'; 397 *style++ = '\0';
398 else if (role && (style = strchr(role, ':')) != NULL)
399 *style++ = '\0';
395 400
396 authctxt->user = user; 401 authctxt->user = user;
397 authctxt->style = style; 402 authctxt->style = style;
403 authctxt->role = role;
398 404
399 /* Verify that the user is a valid user. */ 405 /* Verify that the user is a valid user. */
400 if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) 406 if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
diff --git a/auth2.c b/auth2.c
index 2f0d565ab..fa1a5886d 100644
--- a/auth2.c
+++ b/auth2.c
@@ -217,7 +217,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
217{ 217{
218 Authctxt *authctxt = ctxt; 218 Authctxt *authctxt = ctxt;
219 Authmethod *m = NULL; 219 Authmethod *m = NULL;
220 char *user, *service, *method, *style = NULL; 220 char *user, *service, *method, *style = NULL, *role = NULL;
221 int authenticated = 0; 221 int authenticated = 0;
222 222
223 if (authctxt == NULL) 223 if (authctxt == NULL)
@@ -229,8 +229,13 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
229 debug("userauth-request for user %s service %s method %s", user, service, method); 229 debug("userauth-request for user %s service %s method %s", user, service, method);
230 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); 230 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
231 231
232 if ((role = strchr(user, '/')) != NULL)
233 *role++ = 0;
234
232 if ((style = strchr(user, ':')) != NULL) 235 if ((style = strchr(user, ':')) != NULL)
233 *style++ = 0; 236 *style++ = 0;
237 else if (role && (style = strchr(role, ':')) != NULL)
238 *style++ = '\0';
234 239
235 if (authctxt->attempt++ == 0) { 240 if (authctxt->attempt++ == 0) {
236 /* setup auth context */ 241 /* setup auth context */
@@ -254,8 +259,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
254 use_privsep ? " [net]" : ""); 259 use_privsep ? " [net]" : "");
255 authctxt->service = xstrdup(service); 260 authctxt->service = xstrdup(service);
256 authctxt->style = style ? xstrdup(style) : NULL; 261 authctxt->style = style ? xstrdup(style) : NULL;
262 authctxt->role = role ? xstrdup(role) : NULL;
257 if (use_privsep) 263 if (use_privsep)
258 mm_inform_authserv(service, style); 264 mm_inform_authserv(service, style, role);
259 userauth_banner(); 265 userauth_banner();
260 if (auth2_setup_methods_lists(authctxt) != 0) 266 if (auth2_setup_methods_lists(authctxt) != 0)
261 packet_disconnect("no authentication methods enabled"); 267 packet_disconnect("no authentication methods enabled");
diff --git a/monitor.c b/monitor.c
index b0896ef7f..94b194d56 100644
--- a/monitor.c
+++ b/monitor.c
@@ -148,6 +148,7 @@ int mm_answer_sign(int, Buffer *);
148int mm_answer_pwnamallow(int, Buffer *); 148int mm_answer_pwnamallow(int, Buffer *);
149int mm_answer_auth2_read_banner(int, Buffer *); 149int mm_answer_auth2_read_banner(int, Buffer *);
150int mm_answer_authserv(int, Buffer *); 150int mm_answer_authserv(int, Buffer *);
151int mm_answer_authrole(int, Buffer *);
151int mm_answer_authpassword(int, Buffer *); 152int mm_answer_authpassword(int, Buffer *);
152int mm_answer_bsdauthquery(int, Buffer *); 153int mm_answer_bsdauthquery(int, Buffer *);
153int mm_answer_bsdauthrespond(int, Buffer *); 154int mm_answer_bsdauthrespond(int, Buffer *);
@@ -229,6 +230,7 @@ struct mon_table mon_dispatch_proto20[] = {
229 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, 230 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
230 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, 231 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
231 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, 232 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
233 {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole},
232 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, 234 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
233 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, 235 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
234#ifdef USE_PAM 236#ifdef USE_PAM
@@ -841,6 +843,7 @@ mm_answer_pwnamallow(int sock, Buffer *m)
841 else { 843 else {
842 /* Allow service/style information on the auth context */ 844 /* Allow service/style information on the auth context */
843 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); 845 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
846 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1);
844 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); 847 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
845 } 848 }
846#ifdef USE_PAM 849#ifdef USE_PAM
@@ -871,14 +874,37 @@ mm_answer_authserv(int sock, Buffer *m)
871 874
872 authctxt->service = buffer_get_string(m, NULL); 875 authctxt->service = buffer_get_string(m, NULL);
873 authctxt->style = buffer_get_string(m, NULL); 876 authctxt->style = buffer_get_string(m, NULL);
874 debug3("%s: service=%s, style=%s", 877 authctxt->role = buffer_get_string(m, NULL);
875 __func__, authctxt->service, authctxt->style); 878 debug3("%s: service=%s, style=%s, role=%s",
879 __func__, authctxt->service, authctxt->style, authctxt->role);
876 880
877 if (strlen(authctxt->style) == 0) { 881 if (strlen(authctxt->style) == 0) {
878 free(authctxt->style); 882 free(authctxt->style);
879 authctxt->style = NULL; 883 authctxt->style = NULL;
880 } 884 }
881 885
886 if (strlen(authctxt->role) == 0) {
887 free(authctxt->role);
888 authctxt->role = NULL;
889 }
890
891 return (0);
892}
893
894int
895mm_answer_authrole(int sock, Buffer *m)
896{
897 monitor_permit_authentications(1);
898
899 authctxt->role = buffer_get_string(m, NULL);
900 debug3("%s: role=%s",
901 __func__, authctxt->role);
902
903 if (strlen(authctxt->role) == 0) {
904 free(authctxt->role);
905 authctxt->role = NULL;
906 }
907
882 return (0); 908 return (0);
883} 909}
884 910
@@ -1485,7 +1511,7 @@ mm_answer_pty(int sock, Buffer *m)
1485 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); 1511 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
1486 if (res == 0) 1512 if (res == 0)
1487 goto error; 1513 goto error;
1488 pty_setowner(authctxt->pw, s->tty); 1514 pty_setowner(authctxt->pw, s->tty, authctxt->role);
1489 1515
1490 buffer_put_int(m, 1); 1516 buffer_put_int(m, 1);
1491 buffer_put_cstring(m, s->tty); 1517 buffer_put_cstring(m, s->tty);
diff --git a/monitor.h b/monitor.h
index 7f32b0c0c..4d5e8fabe 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 e476f0dbc..6dc890a77 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -324,10 +324,10 @@ mm_auth2_read_banner(void)
324 return (banner); 324 return (banner);
325} 325}
326 326
327/* Inform the privileged process about service and style */ 327/* Inform the privileged process about service, style, and role */
328 328
329void 329void
330mm_inform_authserv(char *service, char *style) 330mm_inform_authserv(char *service, char *style, char *role)
331{ 331{
332 Buffer m; 332 Buffer m;
333 333
@@ -336,12 +336,30 @@ mm_inform_authserv(char *service, char *style)
336 buffer_init(&m); 336 buffer_init(&m);
337 buffer_put_cstring(&m, service); 337 buffer_put_cstring(&m, service);
338 buffer_put_cstring(&m, style ? style : ""); 338 buffer_put_cstring(&m, style ? style : "");
339 buffer_put_cstring(&m, role ? role : "");
339 340
340 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m); 341 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
341 342
342 buffer_free(&m); 343 buffer_free(&m);
343} 344}
344 345
346/* Inform the privileged process about role */
347
348void
349mm_inform_authrole(char *role)
350{
351 Buffer m;
352
353 debug3("%s entering", __func__);
354
355 buffer_init(&m);
356 buffer_put_cstring(&m, role ? role : "");
357
358 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m);
359
360 buffer_free(&m);
361}
362
345/* Do the password authentication */ 363/* Do the password authentication */
346int 364int
347mm_auth_password(Authctxt *authctxt, char *password) 365mm_auth_password(Authctxt *authctxt, char *password)
diff --git a/monitor_wrap.h b/monitor_wrap.h
index a4e9d24b3..9c2ee49ba 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 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 3e96557b8..6f389ac66 100644
--- a/session.c
+++ b/session.c
@@ -1486,7 +1486,7 @@ safely_chroot(const char *path, uid_t uid)
1486 1486
1487/* Set login name, uid, gid, and groups. */ 1487/* Set login name, uid, gid, and groups. */
1488void 1488void
1489do_setusercontext(struct passwd *pw) 1489do_setusercontext(struct passwd *pw, const char *role)
1490{ 1490{
1491 char *chroot_path, *tmp; 1491 char *chroot_path, *tmp;
1492#ifdef USE_LIBIAF 1492#ifdef USE_LIBIAF
@@ -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 (options.chroot_directory != NULL && 1522 if (options.chroot_directory != NULL &&
1523 strcasecmp(options.chroot_directory, "none") != 0) { 1523 strcasecmp(options.chroot_directory, "none") != 0) {
@@ -1676,7 +1676,7 @@ do_child(Session *s, const char *command)
1676 1676
1677 /* Force a password change */ 1677 /* Force a password change */
1678 if (s->authctxt->force_pwchange) { 1678 if (s->authctxt->force_pwchange) {
1679 do_setusercontext(pw); 1679 do_setusercontext(pw, s->authctxt->role);
1680 child_close_fds(); 1680 child_close_fds();
1681 do_pwchange(s); 1681 do_pwchange(s);
1682 exit(1); 1682 exit(1);
@@ -1703,7 +1703,7 @@ do_child(Session *s, const char *command)
1703 /* When PAM is enabled we rely on it to do the nologin check */ 1703 /* When PAM is enabled we rely on it to do the nologin check */
1704 if (!options.use_pam) 1704 if (!options.use_pam)
1705 do_nologin(pw); 1705 do_nologin(pw);
1706 do_setusercontext(pw); 1706 do_setusercontext(pw, s->authctxt->role);
1707 /* 1707 /*
1708 * PAM session modules in do_setusercontext may have 1708 * PAM session modules in do_setusercontext may have
1709 * generated messages, so if this in an interactive 1709 * generated messages, so if this in an interactive
@@ -2114,7 +2114,7 @@ session_pty_req(Session *s)
2114 tty_parse_modes(s->ttyfd, &n_bytes); 2114 tty_parse_modes(s->ttyfd, &n_bytes);
2115 2115
2116 if (!use_privsep) 2116 if (!use_privsep)
2117 pty_setowner(s->pw, s->tty); 2117 pty_setowner(s->pw, s->tty, s->authctxt->role);
2118 2118
2119 /* Set window size from the packet. */ 2119 /* Set window size from the packet. */
2120 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 2120 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 3a6be65ab..48a14dded 100644
--- a/sshd.c
+++ b/sshd.c
@@ -772,7 +772,7 @@ privsep_postauth(Authctxt *authctxt)
772 explicit_bzero(rnd, sizeof(rnd)); 772 explicit_bzero(rnd, sizeof(rnd));
773 773
774 /* Drop privileges */ 774 /* Drop privileges */
775 do_setusercontext(authctxt->pw); 775 do_setusercontext(authctxt->pw, authctxt->role);
776 776
777 skip: 777 skip:
778 /* It is safe now to apply the key state */ 778 /* It is safe now to apply the key state */
diff --git a/sshpty.c b/sshpty.c
index a2059b76d..3512ec801 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;
@@ -214,7 +214,7 @@ pty_setowner(struct passwd *pw, const char *tty)
214 strerror(errno)); 214 strerror(errno));
215 215
216#ifdef WITH_SELINUX 216#ifdef WITH_SELINUX
217 ssh_selinux_setup_pty(pw->pw_name, tty); 217 ssh_selinux_setup_pty(pw->pw_name, tty, role);
218#endif 218#endif
219 219
220 if (st.st_uid != pw->pw_uid || st.st_gid != gid) { 220 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 *);