1/* $Id: port-linux.c,v 1.3 2006/09/01 05:38:41 djm Exp $ */
| 1/* $Id: port-linux.c,v 1.5 2008/03/26 20:27:21 dtucker 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#include <errno.h> 27#include <stdarg.h> 28#include <string.h> 29 30#ifdef WITH_SELINUX 31#include "log.h" 32#include "port-linux.h" 33 34#include <selinux/selinux.h> 35#include <selinux/flask.h> 36#include <selinux/get_context_list.h> 37 38/* Wrapper around is_selinux_enabled() to log its return value once only */
| 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#include <errno.h> 27#include <stdarg.h> 28#include <string.h> 29 30#ifdef WITH_SELINUX 31#include "log.h" 32#include "port-linux.h" 33 34#include <selinux/selinux.h> 35#include <selinux/flask.h> 36#include <selinux/get_context_list.h> 37 38/* Wrapper around is_selinux_enabled() to log its return value once only */
|
39static int
| 39int
|
40ssh_selinux_enabled(void) 41{ 42 static int enabled = -1; 43 44 if (enabled == -1) { 45 enabled = is_selinux_enabled(); 46 debug("SELinux support %s", enabled ? "enabled" : "disabled"); 47 } 48 49 return (enabled); 50} 51 52/* Return the default security context for the given username */ 53static security_context_t 54ssh_selinux_getctxbyname(char *pwname) 55{ 56 security_context_t sc; 57 char *sename = NULL, *lvl = NULL; 58 int r; 59 60#ifdef HAVE_GETSEUSERBYNAME 61 if (getseuserbyname(pwname, &sename, &lvl) != 0) 62 return NULL; 63#else 64 sename = pwname; 65 lvl = NULL; 66#endif 67 68#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL 69 r = get_default_context_with_level(sename, lvl, NULL, &sc); 70#else 71 r = get_default_context(sename, NULL, &sc); 72#endif 73 74 if (r != 0) { 75 switch (security_getenforce()) { 76 case -1: 77 fatal("%s: ssh_selinux_getctxbyname: " 78 "security_getenforce() failed", __func__); 79 case 0: 80 error("%s: Failed to get default SELinux security " 81 "context for %s", __func__, pwname);
| 40ssh_selinux_enabled(void) 41{ 42 static int enabled = -1; 43 44 if (enabled == -1) { 45 enabled = is_selinux_enabled(); 46 debug("SELinux support %s", enabled ? "enabled" : "disabled"); 47 } 48 49 return (enabled); 50} 51 52/* Return the default security context for the given username */ 53static security_context_t 54ssh_selinux_getctxbyname(char *pwname) 55{ 56 security_context_t sc; 57 char *sename = NULL, *lvl = NULL; 58 int r; 59 60#ifdef HAVE_GETSEUSERBYNAME 61 if (getseuserbyname(pwname, &sename, &lvl) != 0) 62 return NULL; 63#else 64 sename = pwname; 65 lvl = NULL; 66#endif 67 68#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL 69 r = get_default_context_with_level(sename, lvl, NULL, &sc); 70#else 71 r = get_default_context(sename, NULL, &sc); 72#endif 73 74 if (r != 0) { 75 switch (security_getenforce()) { 76 case -1: 77 fatal("%s: ssh_selinux_getctxbyname: " 78 "security_getenforce() failed", __func__); 79 case 0: 80 error("%s: Failed to get default SELinux security " 81 "context for %s", __func__, pwname);
|
| 82 break;
|
82 default: 83 fatal("%s: Failed to get default SELinux security " 84 "context for %s (in enforcing mode)", 85 __func__, pwname); 86 } 87 } 88 89#ifdef HAVE_GETSEUSERBYNAME 90 if (sename != NULL) 91 xfree(sename); 92 if (lvl != NULL) 93 xfree(lvl); 94#endif 95 96 return (sc); 97} 98 99/* Set the execution context to the default for the specified user */ 100void 101ssh_selinux_setup_exec_context(char *pwname) 102{ 103 security_context_t user_ctx = NULL; 104 105 if (!ssh_selinux_enabled()) 106 return; 107 108 debug3("%s: setting execution context", __func__); 109 110 user_ctx = ssh_selinux_getctxbyname(pwname); 111 if (setexeccon(user_ctx) != 0) { 112 switch (security_getenforce()) { 113 case -1: 114 fatal("%s: security_getenforce() failed", __func__); 115 case 0: 116 error("%s: Failed to set SELinux execution " 117 "context for %s", __func__, pwname);
| 83 default: 84 fatal("%s: Failed to get default SELinux security " 85 "context for %s (in enforcing mode)", 86 __func__, pwname); 87 } 88 } 89 90#ifdef HAVE_GETSEUSERBYNAME 91 if (sename != NULL) 92 xfree(sename); 93 if (lvl != NULL) 94 xfree(lvl); 95#endif 96 97 return (sc); 98} 99 100/* Set the execution context to the default for the specified user */ 101void 102ssh_selinux_setup_exec_context(char *pwname) 103{ 104 security_context_t user_ctx = NULL; 105 106 if (!ssh_selinux_enabled()) 107 return; 108 109 debug3("%s: setting execution context", __func__); 110 111 user_ctx = ssh_selinux_getctxbyname(pwname); 112 if (setexeccon(user_ctx) != 0) { 113 switch (security_getenforce()) { 114 case -1: 115 fatal("%s: security_getenforce() failed", __func__); 116 case 0: 117 error("%s: Failed to set SELinux execution " 118 "context for %s", __func__, pwname);
|
| 119 break;
|
118 default: 119 fatal("%s: Failed to set SELinux execution context " 120 "for %s (in enforcing mode)", __func__, pwname); 121 } 122 } 123 if (user_ctx != NULL) 124 freecon(user_ctx); 125 126 debug3("%s: done", __func__); 127} 128 129/* Set the TTY context for the specified user */ 130void 131ssh_selinux_setup_pty(char *pwname, const char *tty) 132{ 133 security_context_t new_tty_ctx = NULL; 134 security_context_t user_ctx = NULL; 135 security_context_t old_tty_ctx = NULL; 136 137 if (!ssh_selinux_enabled()) 138 return; 139 140 debug3("%s: setting TTY context on %s", __func__, tty); 141 142 user_ctx = ssh_selinux_getctxbyname(pwname); 143 144 /* XXX: should these calls fatal() upon failure in enforcing mode? */ 145 146 if (getfilecon(tty, &old_tty_ctx) == -1) { 147 error("%s: getfilecon: %s", __func__, strerror(errno)); 148 goto out; 149 } 150 151 if (security_compute_relabel(user_ctx, old_tty_ctx, 152 SECCLASS_CHR_FILE, &new_tty_ctx) != 0) { 153 error("%s: security_compute_relabel: %s", 154 __func__, strerror(errno)); 155 goto out; 156 } 157 158 if (setfilecon(tty, new_tty_ctx) != 0) 159 error("%s: setfilecon: %s", __func__, strerror(errno)); 160 out: 161 if (new_tty_ctx != NULL) 162 freecon(new_tty_ctx); 163 if (old_tty_ctx != NULL) 164 freecon(old_tty_ctx); 165 if (user_ctx != NULL) 166 freecon(user_ctx); 167 debug3("%s: done", __func__); 168} 169#endif /* WITH_SELINUX */
| 120 default: 121 fatal("%s: Failed to set SELinux execution context " 122 "for %s (in enforcing mode)", __func__, pwname); 123 } 124 } 125 if (user_ctx != NULL) 126 freecon(user_ctx); 127 128 debug3("%s: done", __func__); 129} 130 131/* Set the TTY context for the specified user */ 132void 133ssh_selinux_setup_pty(char *pwname, const char *tty) 134{ 135 security_context_t new_tty_ctx = NULL; 136 security_context_t user_ctx = NULL; 137 security_context_t old_tty_ctx = NULL; 138 139 if (!ssh_selinux_enabled()) 140 return; 141 142 debug3("%s: setting TTY context on %s", __func__, tty); 143 144 user_ctx = ssh_selinux_getctxbyname(pwname); 145 146 /* XXX: should these calls fatal() upon failure in enforcing mode? */ 147 148 if (getfilecon(tty, &old_tty_ctx) == -1) { 149 error("%s: getfilecon: %s", __func__, strerror(errno)); 150 goto out; 151 } 152 153 if (security_compute_relabel(user_ctx, old_tty_ctx, 154 SECCLASS_CHR_FILE, &new_tty_ctx) != 0) { 155 error("%s: security_compute_relabel: %s", 156 __func__, strerror(errno)); 157 goto out; 158 } 159 160 if (setfilecon(tty, new_tty_ctx) != 0) 161 error("%s: setfilecon: %s", __func__, strerror(errno)); 162 out: 163 if (new_tty_ctx != NULL) 164 freecon(new_tty_ctx); 165 if (old_tty_ctx != NULL) 166 freecon(old_tty_ctx); 167 if (user_ctx != NULL) 168 freecon(user_ctx); 169 debug3("%s: done", __func__); 170} 171#endif /* WITH_SELINUX */
|