00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 # include "ink_config.h"
00025 # include "Diags.h"
00026 # include "ink_cap.h"
00027 # include "ink_thread.h"
00028
00029 # if TS_USE_POSIX_CAP
00030 # include <sys/capability.h>
00031 # include <sys/prctl.h>
00032 # endif
00033
00034 # if !TS_USE_POSIX_CAP
00035 ink_mutex ElevateAccess::lock = INK_MUTEX_INIT;
00036 #endif
00037
00038 void
00039 DebugCapabilities(char const* tag) {
00040 if (is_debug_tag_set(tag)) {
00041 # if TS_USE_POSIX_CAP
00042 cap_t caps = cap_get_proc();
00043 char* caps_text = cap_to_text(caps, 0);
00044 # endif
00045
00046 # if TS_USE_POSIX_CAP
00047 Debug(tag, "uid=%u, gid=%u, euid=%u, egid=%u, caps %s core=%s thread=0x%llx",
00048 static_cast<unsigned int>(getuid()),
00049 static_cast<unsigned int>(getgid()),
00050 static_cast<unsigned int>(geteuid()),
00051 static_cast<unsigned int>(getegid()),
00052 caps_text,
00053 prctl(PR_GET_DUMPABLE) != 1 ? "disabled" : "enabled",
00054 (unsigned long long)pthread_self() );
00055 cap_free(caps_text);
00056 cap_free(caps);
00057 #else
00058 Debug(tag, "uid=%u, gid=%u, euid=%u, egid=%u",
00059 static_cast<unsigned int>(getuid()),
00060 static_cast<unsigned int>(getgid()),
00061 static_cast<unsigned int>(geteuid()),
00062 static_cast<unsigned int>(getegid()) );
00063 #endif
00064 }
00065 }
00066
00067 int
00068 PreserveCapabilities() {
00069 int zret = 0;
00070 # if TS_USE_POSIX_CAP
00071 zret = prctl(PR_SET_KEEPCAPS, 1);
00072 # endif
00073 Debug("proxy_priv", "[PreserveCapabilities] zret : %d\n", zret);
00074 return zret;
00075 }
00076
00077
00078 int
00079 RestrictCapabilities() {
00080 int zret = 0;
00081 # if TS_USE_POSIX_CAP
00082 cap_t caps = cap_init();
00083
00084 cap_value_t perm_list[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE, CAP_IPC_LOCK, CAP_DAC_OVERRIDE};
00085 static int const PERM_CAP_COUNT = sizeof(perm_list)/sizeof(*perm_list);
00086 cap_value_t eff_list[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE, CAP_IPC_LOCK};
00087 static int const EFF_CAP_COUNT = sizeof(eff_list)/sizeof(*eff_list);
00088
00089 cap_set_flag(caps, CAP_PERMITTED, PERM_CAP_COUNT, perm_list, CAP_SET);
00090 cap_set_flag(caps, CAP_EFFECTIVE, EFF_CAP_COUNT, eff_list, CAP_SET);
00091 zret = cap_set_proc(caps);
00092 cap_free(caps);
00093 # endif
00094 Debug("proxy_priv", "[RestrictCapabilities] zret : %d\n", zret);
00095 return zret;
00096 }
00097
00098 int
00099 EnableCoreFile(bool flag) {
00100 int zret = 0;
00101 # if defined(linux)
00102 int state = flag ? 1 : 0;
00103 if (0 > (zret = prctl(PR_SET_DUMPABLE, state, 0, 0, 0))) {
00104 Warning("Unable to set PR_DUMPABLE : %s", strerror(errno));
00105 } else if (state != prctl(PR_GET_DUMPABLE)) {
00106 zret = ENOSYS;
00107 Warning("Call to set PR_DUMPABLE was ineffective");
00108 }
00109 # endif // linux check
00110 Debug("proxy_priv", "[EnableCoreFile] zret : %d\n", zret);
00111 return zret;
00112 }
00113
00114 #if TS_USE_POSIX_CAP
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 bool
00129 elevateFileAccess(bool state)
00130 {
00131 Debug("proxy_priv", "[elevateFileAccess] state : %d\n", state);
00132
00133 bool zret = false;
00134 cap_t cap_state = cap_get_proc();
00135
00136 cap_value_t cap_list[] = { CAP_DAC_OVERRIDE };
00137 static int const CAP_COUNT = sizeof(cap_list)/sizeof(*cap_list);
00138
00139 cap_set_flag(cap_state, CAP_EFFECTIVE, CAP_COUNT, cap_list, state ? CAP_SET : CAP_CLEAR);
00140 zret = (0 == cap_set_proc(cap_state));
00141 cap_free(cap_state);
00142 Debug("proxy_priv", "[elevateFileAccess] zret : %d\n", zret);
00143 return zret;
00144 }
00145 #else
00146
00147
00148
00149
00150 bool
00151 removeRootPriv(uid_t euid)
00152 {
00153 if (seteuid(euid) < 0) {
00154 Debug("proxy_priv", "[removeRootPriv] seteuid failed : %s\n", strerror(errno));
00155 return false;
00156 }
00157
00158 Debug("proxy_priv", "[removeRootPriv] removed root privileges. Euid is %d\n", euid);
00159 return true;
00160 }
00161
00162
00163
00164
00165
00166 bool
00167 restoreRootPriv(uid_t *old_euid)
00168 {
00169 if (old_euid)
00170 *old_euid = geteuid();
00171 if (seteuid(0) < 0) {
00172 Debug("proxy_priv", "[restoreRootPriv] seteuid root failed : %s\n", strerror(errno));
00173 return false;
00174 }
00175
00176 Debug("proxy_priv", "[restoreRootPriv] restored root privileges. Euid is %d\n", 0);
00177
00178 return true;
00179 }
00180 #endif