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