diff options
author | Damien Miller <djm@mindrot.org> | 2006-04-22 21:26:08 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2006-04-22 21:26:08 +1000 |
commit | 73b42d2bb058da914828b53f2951954560a5b6eb (patch) | |
tree | 7271e92211fab0a06b0d36f162801b073220c5bf /openbsd-compat/port-linux.c | |
parent | 2eaf37d899a55c253ad42d13534a824bce9c8ed2 (diff) |
- (djm) [Makefile.in configure.ac session.c sshpty.c]
[contrib/redhat/sshd.init openbsd-compat/Makefile.in]
[openbsd-compat/openbsd-compat.h openbsd-compat/port-linux.c]
[openbsd-compat/port-linux.h] Add support for SELinux, setting
the execution and TTY contexts. based on patch from Daniel Walsh,
bz #880; ok dtucker@
Diffstat (limited to 'openbsd-compat/port-linux.c')
-rw-r--r-- | openbsd-compat/port-linux.c | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c new file mode 100644 index 000000000..54ec2910e --- /dev/null +++ b/openbsd-compat/port-linux.c | |||
@@ -0,0 +1,165 @@ | |||
1 | /* $Id: port-linux.c,v 1.1 2006/04/22 11:26:08 djm Exp $ */ | ||
2 | |||
3 | /* | ||
4 | * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com> | ||
5 | * Copyright (c) 2006 Damien Miller <djm@openbsd.org> | ||
6 | * | ||
7 | * Permission to use, copy, modify, and distribute this software for any | ||
8 | * purpose with or without fee is hereby granted, provided that the above | ||
9 | * copyright notice and this permission notice appear in all copies. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
18 | */ | ||
19 | |||
20 | /* | ||
21 | * Linux-specific portability code - just SELinux support at present | ||
22 | */ | ||
23 | |||
24 | #include "includes.h" | ||
25 | |||
26 | #ifdef WITH_SELINUX | ||
27 | #include "log.h" | ||
28 | #include "port-linux.h" | ||
29 | |||
30 | #include <selinux/selinux.h> | ||
31 | #include <selinux/flask.h> | ||
32 | #include <selinux/get_context_list.h> | ||
33 | |||
34 | /* Wrapper around is_selinux_enabled() to log its return value once only */ | ||
35 | static int | ||
36 | ssh_selinux_enabled(void) | ||
37 | { | ||
38 | static int enabled = -1; | ||
39 | |||
40 | if (enabled == -1) { | ||
41 | enabled = is_selinux_enabled(); | ||
42 | debug("SELinux support %s", enabled ? "enabled" : "disabled"); | ||
43 | } | ||
44 | |||
45 | return (enabled); | ||
46 | } | ||
47 | |||
48 | /* Return the default security context for the given username */ | ||
49 | static security_context_t | ||
50 | ssh_selinux_getctxbyname(char *pwname) | ||
51 | { | ||
52 | security_context_t sc; | ||
53 | char *sename = NULL, *lvl = NULL; | ||
54 | int r; | ||
55 | |||
56 | #ifdef HAVE_GETSEUSERBYNAME | ||
57 | if (getseuserbyname(pwname, &sename, &lvl) != 0) | ||
58 | return NULL; | ||
59 | #else | ||
60 | sename = pwname; | ||
61 | lvl = NULL; | ||
62 | #endif | ||
63 | |||
64 | #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL | ||
65 | r = get_default_context_with_level(sename, lvl, NULL, &sc); | ||
66 | #else | ||
67 | r = get_default_context(sename, NULL, &sc); | ||
68 | #endif | ||
69 | |||
70 | if (r != 0) { | ||
71 | switch (security_getenforce()) { | ||
72 | case -1: | ||
73 | fatal("%s: ssh_selinux_getctxbyname: " | ||
74 | "security_getenforce() failed", __func__); | ||
75 | case 0: | ||
76 | error("%s: Failed to get default SELinux security " | ||
77 | "context for %s", __func__, pwname); | ||
78 | default: | ||
79 | fatal("%s: Failed to get default SELinux security " | ||
80 | "context for %s (in enforcing mode)", | ||
81 | __func__, pwname); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | #ifdef HAVE_GETSEUSERBYNAME | ||
86 | if (sename != NULL) | ||
87 | xfree(sename); | ||
88 | if (lvl != NULL) | ||
89 | xfree(lvl); | ||
90 | #endif | ||
91 | |||
92 | return (sc); | ||
93 | } | ||
94 | |||
95 | /* Set the execution context to the default for the specified user */ | ||
96 | void | ||
97 | ssh_selinux_setup_exec_context(char *pwname) | ||
98 | { | ||
99 | security_context_t user_ctx = NULL; | ||
100 | |||
101 | if (!ssh_selinux_enabled()) | ||
102 | return; | ||
103 | |||
104 | debug3("%s: setting execution context", __func__); | ||
105 | |||
106 | user_ctx = ssh_selinux_getctxbyname(pwname); | ||
107 | if (setexeccon(user_ctx) != 0) { | ||
108 | switch (security_getenforce()) { | ||
109 | case -1: | ||
110 | fatal("%s: security_getenforce() failed", __func__); | ||
111 | case 0: | ||
112 | error("%s: Failed to set SELinux execution " | ||
113 | "context for %s", __func__, pwname); | ||
114 | default: | ||
115 | fatal("%s: Failed to set SELinux execution context " | ||
116 | "for %s (in enforcing mode)", __func__, pwname); | ||
117 | } | ||
118 | } | ||
119 | if (user_ctx != NULL) | ||
120 | freecon(user_ctx); | ||
121 | |||
122 | debug3("%s: done", __func__); | ||
123 | } | ||
124 | |||
125 | /* Set the TTY context for the specified user */ | ||
126 | void | ||
127 | ssh_selinux_setup_pty(char *pwname, const char *tty) | ||
128 | { | ||
129 | security_context_t new_tty_ctx = NULL; | ||
130 | security_context_t user_ctx = NULL; | ||
131 | security_context_t old_tty_ctx = NULL; | ||
132 | |||
133 | if (!ssh_selinux_enabled()) | ||
134 | return; | ||
135 | |||
136 | debug3("%s: setting TTY context on %s", __func__, tty); | ||
137 | |||
138 | user_ctx = ssh_selinux_getctxbyname(pwname); | ||
139 | |||
140 | /* XXX: should these calls fatal() upon failure in enforcing mode? */ | ||
141 | |||
142 | if (getfilecon(tty, &old_tty_ctx) == -1) { | ||
143 | error("%s: getfilecon: %s", __func__, strerror(errno)); | ||
144 | goto out; | ||
145 | } | ||
146 | |||
147 | if (security_compute_relabel(user_ctx, old_tty_ctx, | ||
148 | SECCLASS_CHR_FILE, &new_tty_ctx) != 0) { | ||
149 | error("%s: security_compute_relabel: %s", | ||
150 | __func__, strerror(errno)); | ||
151 | goto out; | ||
152 | } | ||
153 | |||
154 | if (setfilecon(tty, new_tty_ctx) != 0) | ||
155 | error("%s: setfilecon: %s", __func__, strerror(errno)); | ||
156 | out: | ||
157 | if (new_tty_ctx != NULL) | ||
158 | freecon(new_tty_ctx); | ||
159 | if (old_tty_ctx != NULL) | ||
160 | freecon(old_tty_ctx); | ||
161 | if (user_ctx != NULL) | ||
162 | freecon(user_ctx); | ||
163 | debug3("%s: done", __func__); | ||
164 | } | ||
165 | #endif /* WITH_SELINUX */ | ||