diff options
author | Manoj Srivastava <srivasta@debian.org> | 2014-02-09 16:09:49 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2017-10-04 13:54:48 +0100 |
commit | 4b276122c04aed0726803a92c8ca955e614a4d3a (patch) | |
tree | 5c5638fad9f6edf9ada6a4661f6c5cbb1bec2696 | |
parent | cdd9076a145a95c21538eedb3f728a897480c5de (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: 2017-10-04
Patch-Name: selinux-role.patch
-rw-r--r-- | auth.h | 1 | ||||
-rw-r--r-- | auth2.c | 10 | ||||
-rw-r--r-- | monitor.c | 32 | ||||
-rw-r--r-- | monitor.h | 2 | ||||
-rw-r--r-- | monitor_wrap.c | 22 | ||||
-rw-r--r-- | monitor_wrap.h | 3 | ||||
-rw-r--r-- | openbsd-compat/port-linux.c | 27 | ||||
-rw-r--r-- | openbsd-compat/port-linux.h | 4 | ||||
-rw-r--r-- | platform.c | 4 | ||||
-rw-r--r-- | platform.h | 2 | ||||
-rw-r--r-- | session.c | 10 | ||||
-rw-r--r-- | session.h | 2 | ||||
-rw-r--r-- | sshd.c | 2 | ||||
-rw-r--r-- | sshpty.c | 4 | ||||
-rw-r--r-- | sshpty.h | 2 |
15 files changed, 97 insertions, 30 deletions
@@ -63,6 +63,7 @@ struct Authctxt { | |||
63 | char *service; | 63 | char *service; |
64 | struct passwd *pw; /* set if 'valid' */ | 64 | struct passwd *pw; /* set if 'valid' */ |
65 | char *style; | 65 | char *style; |
66 | char *role; | ||
66 | 67 | ||
67 | /* Method lists for multiple authentication */ | 68 | /* Method lists for multiple authentication */ |
68 | char **auth_methods; /* modified from server config */ | 69 | char **auth_methods; /* modified from server config */ |
@@ -221,7 +221,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) | |||
221 | { | 221 | { |
222 | Authctxt *authctxt = ssh->authctxt; | 222 | Authctxt *authctxt = ssh->authctxt; |
223 | Authmethod *m = NULL; | 223 | Authmethod *m = NULL; |
224 | char *user, *service, *method, *style = NULL; | 224 | char *user, *service, *method, *style = NULL, *role = NULL; |
225 | int authenticated = 0; | 225 | int authenticated = 0; |
226 | 226 | ||
227 | if (authctxt == NULL) | 227 | if (authctxt == NULL) |
@@ -233,8 +233,13 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) | |||
233 | debug("userauth-request for user %s service %s method %s", user, service, method); | 233 | debug("userauth-request for user %s service %s method %s", user, service, method); |
234 | debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); | 234 | debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); |
235 | 235 | ||
236 | if ((role = strchr(user, '/')) != NULL) | ||
237 | *role++ = 0; | ||
238 | |||
236 | if ((style = strchr(user, ':')) != NULL) | 239 | if ((style = strchr(user, ':')) != NULL) |
237 | *style++ = 0; | 240 | *style++ = 0; |
241 | else if (role && (style = strchr(role, ':')) != NULL) | ||
242 | *style++ = '\0'; | ||
238 | 243 | ||
239 | if (authctxt->attempt++ == 0) { | 244 | if (authctxt->attempt++ == 0) { |
240 | /* setup auth context */ | 245 | /* setup auth context */ |
@@ -261,8 +266,9 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) | |||
261 | use_privsep ? " [net]" : ""); | 266 | use_privsep ? " [net]" : ""); |
262 | authctxt->service = xstrdup(service); | 267 | authctxt->service = xstrdup(service); |
263 | authctxt->style = style ? xstrdup(style) : NULL; | 268 | authctxt->style = style ? xstrdup(style) : NULL; |
269 | authctxt->role = role ? xstrdup(role) : NULL; | ||
264 | if (use_privsep) | 270 | if (use_privsep) |
265 | mm_inform_authserv(service, style); | 271 | mm_inform_authserv(service, style, role); |
266 | userauth_banner(); | 272 | userauth_banner(); |
267 | if (auth2_setup_methods_lists(authctxt) != 0) | 273 | if (auth2_setup_methods_lists(authctxt) != 0) |
268 | packet_disconnect("no authentication methods enabled"); | 274 | packet_disconnect("no authentication methods enabled"); |
@@ -127,6 +127,7 @@ int mm_answer_sign(int, Buffer *); | |||
127 | int mm_answer_pwnamallow(int, Buffer *); | 127 | int mm_answer_pwnamallow(int, Buffer *); |
128 | int mm_answer_auth2_read_banner(int, Buffer *); | 128 | int mm_answer_auth2_read_banner(int, Buffer *); |
129 | int mm_answer_authserv(int, Buffer *); | 129 | int mm_answer_authserv(int, Buffer *); |
130 | int mm_answer_authrole(int, Buffer *); | ||
130 | int mm_answer_authpassword(int, Buffer *); | 131 | int mm_answer_authpassword(int, Buffer *); |
131 | int mm_answer_bsdauthquery(int, Buffer *); | 132 | int mm_answer_bsdauthquery(int, Buffer *); |
132 | int mm_answer_bsdauthrespond(int, Buffer *); | 133 | int mm_answer_bsdauthrespond(int, Buffer *); |
@@ -204,6 +205,7 @@ struct mon_table mon_dispatch_proto20[] = { | |||
204 | {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, | 205 | {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, |
205 | {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, | 206 | {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, |
206 | {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, | 207 | {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, |
208 | {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, | ||
207 | {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, | 209 | {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, |
208 | {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, | 210 | {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, |
209 | #ifdef USE_PAM | 211 | #ifdef USE_PAM |
@@ -799,6 +801,7 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
799 | 801 | ||
800 | /* Allow service/style information on the auth context */ | 802 | /* Allow service/style information on the auth context */ |
801 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); | 803 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); |
804 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1); | ||
802 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); | 805 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); |
803 | 806 | ||
804 | #ifdef USE_PAM | 807 | #ifdef USE_PAM |
@@ -829,14 +832,37 @@ mm_answer_authserv(int sock, Buffer *m) | |||
829 | 832 | ||
830 | authctxt->service = buffer_get_string(m, NULL); | 833 | authctxt->service = buffer_get_string(m, NULL); |
831 | authctxt->style = buffer_get_string(m, NULL); | 834 | authctxt->style = buffer_get_string(m, NULL); |
832 | debug3("%s: service=%s, style=%s", | 835 | authctxt->role = buffer_get_string(m, NULL); |
833 | __func__, authctxt->service, authctxt->style); | 836 | debug3("%s: service=%s, style=%s, role=%s", |
837 | __func__, authctxt->service, authctxt->style, authctxt->role); | ||
834 | 838 | ||
835 | if (strlen(authctxt->style) == 0) { | 839 | if (strlen(authctxt->style) == 0) { |
836 | free(authctxt->style); | 840 | free(authctxt->style); |
837 | authctxt->style = NULL; | 841 | authctxt->style = NULL; |
838 | } | 842 | } |
839 | 843 | ||
844 | if (strlen(authctxt->role) == 0) { | ||
845 | free(authctxt->role); | ||
846 | authctxt->role = NULL; | ||
847 | } | ||
848 | |||
849 | return (0); | ||
850 | } | ||
851 | |||
852 | int | ||
853 | mm_answer_authrole(int sock, Buffer *m) | ||
854 | { | ||
855 | monitor_permit_authentications(1); | ||
856 | |||
857 | authctxt->role = buffer_get_string(m, NULL); | ||
858 | debug3("%s: role=%s", | ||
859 | __func__, authctxt->role); | ||
860 | |||
861 | if (strlen(authctxt->role) == 0) { | ||
862 | free(authctxt->role); | ||
863 | authctxt->role = NULL; | ||
864 | } | ||
865 | |||
840 | return (0); | 866 | return (0); |
841 | } | 867 | } |
842 | 868 | ||
@@ -1471,7 +1497,7 @@ mm_answer_pty(int sock, Buffer *m) | |||
1471 | res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); | 1497 | res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); |
1472 | if (res == 0) | 1498 | if (res == 0) |
1473 | goto error; | 1499 | goto error; |
1474 | pty_setowner(authctxt->pw, s->tty); | 1500 | pty_setowner(authctxt->pw, s->tty, authctxt->role); |
1475 | 1501 | ||
1476 | buffer_put_int(m, 1); | 1502 | buffer_put_int(m, 1); |
1477 | buffer_put_cstring(m, s->tty); | 1503 | buffer_put_cstring(m, s->tty); |
@@ -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 | ||
73 | struct monitor { | 75 | struct monitor { |
diff --git a/monitor_wrap.c b/monitor_wrap.c index 0e171a6a6..d806bb2e7 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c | |||
@@ -336,10 +336,10 @@ mm_auth2_read_banner(void) | |||
336 | return (banner); | 336 | return (banner); |
337 | } | 337 | } |
338 | 338 | ||
339 | /* Inform the privileged process about service and style */ | 339 | /* Inform the privileged process about service, style, and role */ |
340 | 340 | ||
341 | void | 341 | void |
342 | mm_inform_authserv(char *service, char *style) | 342 | mm_inform_authserv(char *service, char *style, char *role) |
343 | { | 343 | { |
344 | Buffer m; | 344 | Buffer m; |
345 | 345 | ||
@@ -348,12 +348,30 @@ mm_inform_authserv(char *service, char *style) | |||
348 | buffer_init(&m); | 348 | buffer_init(&m); |
349 | buffer_put_cstring(&m, service); | 349 | buffer_put_cstring(&m, service); |
350 | buffer_put_cstring(&m, style ? style : ""); | 350 | buffer_put_cstring(&m, style ? style : ""); |
351 | buffer_put_cstring(&m, role ? role : ""); | ||
351 | 352 | ||
352 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m); | 353 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m); |
353 | 354 | ||
354 | buffer_free(&m); | 355 | buffer_free(&m); |
355 | } | 356 | } |
356 | 357 | ||
358 | /* Inform the privileged process about role */ | ||
359 | |||
360 | void | ||
361 | mm_inform_authrole(char *role) | ||
362 | { | ||
363 | Buffer m; | ||
364 | |||
365 | debug3("%s entering", __func__); | ||
366 | |||
367 | buffer_init(&m); | ||
368 | buffer_put_cstring(&m, role ? role : ""); | ||
369 | |||
370 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m); | ||
371 | |||
372 | buffer_free(&m); | ||
373 | } | ||
374 | |||
357 | /* Do the password authentication */ | 375 | /* Do the password authentication */ |
358 | int | 376 | int |
359 | mm_auth_password(Authctxt *authctxt, char *password) | 377 | mm_auth_password(Authctxt *authctxt, char *password) |
diff --git a/monitor_wrap.h b/monitor_wrap.h index 7b2e89452..a9ccb243e 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h | |||
@@ -41,7 +41,8 @@ int mm_is_monitor(void); | |||
41 | DH *mm_choose_dh(int, int, int); | 41 | DH *mm_choose_dh(int, int, int); |
42 | int mm_key_sign(struct sshkey *, u_char **, u_int *, const u_char *, u_int, | 42 | int mm_key_sign(struct sshkey *, u_char **, u_int *, const u_char *, u_int, |
43 | const char *); | 43 | const char *); |
44 | void mm_inform_authserv(char *, char *); | 44 | void mm_inform_authserv(char *, char *, char *); |
45 | void mm_inform_authrole(char *); | ||
45 | struct passwd *mm_getpwnamallow(const char *); | 46 | struct passwd *mm_getpwnamallow(const char *); |
46 | char *mm_auth2_read_banner(void); | 47 | char *mm_auth2_read_banner(void); |
47 | int mm_auth_password(struct Authctxt *, char *); | 48 | int mm_auth_password(struct Authctxt *, char *); |
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c index e4c5d1b7c..e26faf08c 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c | |||
@@ -27,6 +27,12 @@ | |||
27 | #include <string.h> | 27 | #include <string.h> |
28 | #include <stdio.h> | 28 | #include <stdio.h> |
29 | 29 | ||
30 | #ifdef WITH_SELINUX | ||
31 | #include "key.h" | ||
32 | #include "hostfile.h" | ||
33 | #include "auth.h" | ||
34 | #endif | ||
35 | |||
30 | #include "log.h" | 36 | #include "log.h" |
31 | #include "xmalloc.h" | 37 | #include "xmalloc.h" |
32 | #include "port-linux.h" | 38 | #include "port-linux.h" |
@@ -56,7 +62,7 @@ ssh_selinux_enabled(void) | |||
56 | 62 | ||
57 | /* Return the default security context for the given username */ | 63 | /* Return the default security context for the given username */ |
58 | static security_context_t | 64 | static security_context_t |
59 | ssh_selinux_getctxbyname(char *pwname) | 65 | ssh_selinux_getctxbyname(char *pwname, const char *role) |
60 | { | 66 | { |
61 | security_context_t sc = NULL; | 67 | security_context_t sc = NULL; |
62 | char *sename = NULL, *lvl = NULL; | 68 | char *sename = NULL, *lvl = NULL; |
@@ -71,9 +77,16 @@ ssh_selinux_getctxbyname(char *pwname) | |||
71 | #endif | 77 | #endif |
72 | 78 | ||
73 | #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL | 79 | #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL |
74 | r = get_default_context_with_level(sename, lvl, NULL, &sc); | 80 | if (role != NULL && role[0]) |
81 | r = get_default_context_with_rolelevel(sename, role, lvl, NULL, | ||
82 | &sc); | ||
83 | else | ||
84 | r = get_default_context_with_level(sename, lvl, NULL, &sc); | ||
75 | #else | 85 | #else |
76 | r = get_default_context(sename, NULL, &sc); | 86 | if (role != NULL && role[0]) |
87 | r = get_default_context_with_role(sename, role, NULL, &sc); | ||
88 | else | ||
89 | r = get_default_context(sename, NULL, &sc); | ||
77 | #endif | 90 | #endif |
78 | 91 | ||
79 | if (r != 0) { | 92 | if (r != 0) { |
@@ -103,7 +116,7 @@ ssh_selinux_getctxbyname(char *pwname) | |||
103 | 116 | ||
104 | /* Set the execution context to the default for the specified user */ | 117 | /* Set the execution context to the default for the specified user */ |
105 | void | 118 | void |
106 | ssh_selinux_setup_exec_context(char *pwname) | 119 | ssh_selinux_setup_exec_context(char *pwname, const char *role) |
107 | { | 120 | { |
108 | security_context_t user_ctx = NULL; | 121 | security_context_t user_ctx = NULL; |
109 | 122 | ||
@@ -112,7 +125,7 @@ ssh_selinux_setup_exec_context(char *pwname) | |||
112 | 125 | ||
113 | debug3("%s: setting execution context", __func__); | 126 | debug3("%s: setting execution context", __func__); |
114 | 127 | ||
115 | user_ctx = ssh_selinux_getctxbyname(pwname); | 128 | user_ctx = ssh_selinux_getctxbyname(pwname, role); |
116 | if (setexeccon(user_ctx) != 0) { | 129 | if (setexeccon(user_ctx) != 0) { |
117 | switch (security_getenforce()) { | 130 | switch (security_getenforce()) { |
118 | case -1: | 131 | case -1: |
@@ -134,7 +147,7 @@ ssh_selinux_setup_exec_context(char *pwname) | |||
134 | 147 | ||
135 | /* Set the TTY context for the specified user */ | 148 | /* Set the TTY context for the specified user */ |
136 | void | 149 | void |
137 | ssh_selinux_setup_pty(char *pwname, const char *tty) | 150 | ssh_selinux_setup_pty(char *pwname, const char *tty, const char *role) |
138 | { | 151 | { |
139 | security_context_t new_tty_ctx = NULL; | 152 | security_context_t new_tty_ctx = NULL; |
140 | security_context_t user_ctx = NULL; | 153 | security_context_t user_ctx = NULL; |
@@ -145,7 +158,7 @@ ssh_selinux_setup_pty(char *pwname, const char *tty) | |||
145 | 158 | ||
146 | debug3("%s: setting TTY context on %s", __func__, tty); | 159 | debug3("%s: setting TTY context on %s", __func__, tty); |
147 | 160 | ||
148 | user_ctx = ssh_selinux_getctxbyname(pwname); | 161 | user_ctx = ssh_selinux_getctxbyname(pwname, role); |
149 | 162 | ||
150 | /* XXX: should these calls fatal() upon failure in enforcing mode? */ | 163 | /* XXX: should these calls fatal() upon failure in enforcing mode? */ |
151 | 164 | ||
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h index 3c22a854d..c88129428 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h | |||
@@ -19,8 +19,8 @@ | |||
19 | 19 | ||
20 | #ifdef WITH_SELINUX | 20 | #ifdef WITH_SELINUX |
21 | int ssh_selinux_enabled(void); | 21 | int ssh_selinux_enabled(void); |
22 | void ssh_selinux_setup_pty(char *, const char *); | 22 | void ssh_selinux_setup_pty(char *, const char *, const char *); |
23 | void ssh_selinux_setup_exec_context(char *); | 23 | void ssh_selinux_setup_exec_context(char *, const char *); |
24 | void ssh_selinux_change_context(const char *); | 24 | void ssh_selinux_change_context(const char *); |
25 | void ssh_selinux_setfscreatecon(const char *); | 25 | void ssh_selinux_setfscreatecon(const char *); |
26 | #endif | 26 | #endif |
diff --git a/platform.c b/platform.c index 18c7751de..380ee3a41 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 | */ |
145 | void | 145 | void |
146 | platform_setusercontext_post_groups(struct passwd *pw) | 146 | platform_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 ea4f9c584..60d72ffe7 100644 --- a/platform.h +++ b/platform.h | |||
@@ -25,7 +25,7 @@ void platform_post_fork_parent(pid_t child_pid); | |||
25 | void platform_post_fork_child(void); | 25 | void platform_post_fork_child(void); |
26 | int platform_privileged_uidswap(void); | 26 | int platform_privileged_uidswap(void); |
27 | void platform_setusercontext(struct passwd *); | 27 | void platform_setusercontext(struct passwd *); |
28 | void platform_setusercontext_post_groups(struct passwd *); | 28 | void platform_setusercontext_post_groups(struct passwd *, const char *); |
29 | char *platform_get_krb5_client(const char *); | 29 | char *platform_get_krb5_client(const char *); |
30 | char *platform_krb5_get_principal_name(const char *); | 30 | char *platform_krb5_get_principal_name(const char *); |
31 | int platform_sys_dir_uid(uid_t); | 31 | int platform_sys_dir_uid(uid_t); |
@@ -1312,7 +1312,7 @@ safely_chroot(const char *path, uid_t uid) | |||
1312 | 1312 | ||
1313 | /* Set login name, uid, gid, and groups. */ | 1313 | /* Set login name, uid, gid, and groups. */ |
1314 | void | 1314 | void |
1315 | do_setusercontext(struct passwd *pw) | 1315 | do_setusercontext(struct passwd *pw, const char *role) |
1316 | { | 1316 | { |
1317 | char *chroot_path, *tmp; | 1317 | char *chroot_path, *tmp; |
1318 | 1318 | ||
@@ -1340,7 +1340,7 @@ do_setusercontext(struct passwd *pw) | |||
1340 | endgrent(); | 1340 | endgrent(); |
1341 | #endif | 1341 | #endif |
1342 | 1342 | ||
1343 | platform_setusercontext_post_groups(pw); | 1343 | platform_setusercontext_post_groups(pw, role); |
1344 | 1344 | ||
1345 | if (!in_chroot && options.chroot_directory != NULL && | 1345 | if (!in_chroot && options.chroot_directory != NULL && |
1346 | strcasecmp(options.chroot_directory, "none") != 0) { | 1346 | strcasecmp(options.chroot_directory, "none") != 0) { |
@@ -1477,7 +1477,7 @@ do_child(struct ssh *ssh, Session *s, const char *command) | |||
1477 | 1477 | ||
1478 | /* Force a password change */ | 1478 | /* Force a password change */ |
1479 | if (s->authctxt->force_pwchange) { | 1479 | if (s->authctxt->force_pwchange) { |
1480 | do_setusercontext(pw); | 1480 | do_setusercontext(pw, s->authctxt->role); |
1481 | child_close_fds(ssh); | 1481 | child_close_fds(ssh); |
1482 | do_pwchange(s); | 1482 | do_pwchange(s); |
1483 | exit(1); | 1483 | exit(1); |
@@ -1499,7 +1499,7 @@ do_child(struct ssh *ssh, Session *s, const char *command) | |||
1499 | /* When PAM is enabled we rely on it to do the nologin check */ | 1499 | /* When PAM is enabled we rely on it to do the nologin check */ |
1500 | if (!options.use_pam) | 1500 | if (!options.use_pam) |
1501 | do_nologin(pw); | 1501 | do_nologin(pw); |
1502 | do_setusercontext(pw); | 1502 | do_setusercontext(pw, s->authctxt->role); |
1503 | /* | 1503 | /* |
1504 | * PAM session modules in do_setusercontext may have | 1504 | * PAM session modules in do_setusercontext may have |
1505 | * generated messages, so if this in an interactive | 1505 | * generated messages, so if this in an interactive |
@@ -1891,7 +1891,7 @@ session_pty_req(struct ssh *ssh, Session *s) | |||
1891 | tty_parse_modes(s->ttyfd, &n_bytes); | 1891 | tty_parse_modes(s->ttyfd, &n_bytes); |
1892 | 1892 | ||
1893 | if (!use_privsep) | 1893 | if (!use_privsep) |
1894 | pty_setowner(s->pw, s->tty); | 1894 | pty_setowner(s->pw, s->tty, s->authctxt->role); |
1895 | 1895 | ||
1896 | /* Set window size from the packet. */ | 1896 | /* Set window size from the packet. */ |
1897 | pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); | 1897 | pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); |
@@ -76,7 +76,7 @@ void session_pty_cleanup2(Session *); | |||
76 | Session *session_new(void); | 76 | Session *session_new(void); |
77 | Session *session_by_tty(char *); | 77 | Session *session_by_tty(char *); |
78 | void session_close(struct ssh *, Session *); | 78 | void session_close(struct ssh *, Session *); |
79 | void do_setusercontext(struct passwd *); | 79 | void do_setusercontext(struct passwd *, const char *); |
80 | 80 | ||
81 | const char *session_get_remote_name_or_ip(struct ssh *, u_int, int); | 81 | const char *session_get_remote_name_or_ip(struct ssh *, u_int, int); |
82 | 82 | ||
@@ -677,7 +677,7 @@ privsep_postauth(Authctxt *authctxt) | |||
677 | reseed_prngs(); | 677 | reseed_prngs(); |
678 | 678 | ||
679 | /* Drop privileges */ | 679 | /* Drop privileges */ |
680 | do_setusercontext(authctxt->pw); | 680 | do_setusercontext(authctxt->pw, authctxt->role); |
681 | 681 | ||
682 | skip: | 682 | skip: |
683 | /* It is safe now to apply the key state */ | 683 | /* It is safe now to apply the key state */ |
@@ -187,7 +187,7 @@ pty_change_window_size(int ptyfd, u_int row, u_int col, | |||
187 | } | 187 | } |
188 | 188 | ||
189 | void | 189 | void |
190 | pty_setowner(struct passwd *pw, const char *tty) | 190 | pty_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) { |
@@ -24,5 +24,5 @@ int pty_allocate(int *, int *, char *, size_t); | |||
24 | void pty_release(const char *); | 24 | void pty_release(const char *); |
25 | void pty_make_controlling_tty(int *, const char *); | 25 | void pty_make_controlling_tty(int *, const char *); |
26 | void pty_change_window_size(int, u_int, u_int, u_int, u_int); | 26 | void pty_change_window_size(int, u_int, u_int, u_int, u_int); |
27 | void pty_setowner(struct passwd *, const char *); | 27 | void pty_setowner(struct passwd *, const char *, const char *); |
28 | void disconnect_controlling_tty(void); | 28 | void disconnect_controlling_tty(void); |