00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00037 #include <sys/types.h>
00038 #include <unistd.h>
00039 #include <errno.h>
00040 #include <string.h>
00041
00042 #include "setuid.h"
00043 #include "threadsafe_db.h"
00044 #include "cleanuphandler.h"
00045 #include "logfile.h"
00046
00047
00048 namespace protlib {
00049
00054 using namespace log;
00055
00056 void setuid::init() {
00057 if (is_init) {
00058 Log(ERROR_LOG,LOG_CRIT, "setuid", "Tried to initialize setuid although already initialized.");
00059 } else {
00060 pthread_mutex_init(&mutex,NULL);
00061 count = 0;
00062 file_userid = ::geteuid();
00063 real_userid = ::getuid();
00064 is_setuid = (real_userid!=file_userid);
00065 file_username = tsdb::get_username(file_userid);
00066 real_username = tsdb::get_username(real_userid);
00067 is_init = true;
00068 if (is_setuid) {
00069 Log(INFO_LOG,LOG_CRIT, "setuid", "Setuid-bit is set, euid is " << file_userid << " " << file_username << ", realuid is " << real_userid << " " << real_username << ". Turning off setuid as soon as possible");
00070 count = 1;
00071 off();
00072 } else {
00073 Log(INFO_LOG,LOG_CRIT, "setuid", "Setuid-bit is not set or euid and ruid are equal. setuid::on() and setuid::off() will do nothing");
00074 }
00075 }
00076 }
00077
00078 void setuid::end() {
00079 if (is_init) {
00080 is_init = false;
00081 pthread_mutex_destroy(&mutex);
00082 count = 0;
00083
00084 if (is_setuid) {
00085 Log(INFO_LOG,LOG_CRIT, "setuid", "setuid::end() turn off setuid. Switching (maybe permamently) to " << real_userid << " " << real_username << " using setuid()");
00086 ::setuid(real_userid);
00087 }
00088 } else {
00089 Log(ERROR_LOG,LOG_CRIT, "setuid", "Tried to end setuid although not initialized.");
00090 }
00091 }
00092
00093 void setuid::on() {
00094 if (is_setuid) {
00095 if (is_init) {
00096 pthread_mutex_lock(&mutex);
00097 if (count==0) {
00098 Log(INFO_LOG,LOG_CRIT, "setuid", "setuid::on(): setting euid to " << file_userid << " " << file_username);
00099 int status;
00100 #ifdef _POSIX_SAVED_IDS
00101 status = seteuid(file_userid);
00102 #else
00103 status = setreuid(real_userid,file_userid);
00104 #endif
00105 if (status<0) {
00106 Log(ERROR_LOG,LOG_ALERT, "setuid", "setuid::on(): error " << strerror(errno));
00107 } else count++;
00108 } else {
00109 Log(INFO_LOG,LOG_CRIT, "setuid", "setuid::on(): setuid already on");
00110 count++;
00111 }
00112 pthread_mutex_unlock(&mutex);
00113 } else {
00114 Log(ERROR_LOG,LOG_CRIT, "setuid", "Tried to use setuid although not initialized.");
00115 }
00116 }
00117 }
00118
00119 void setuid::off() {
00120 if (is_setuid) {
00121 if (is_init) {
00122 pthread_mutex_lock(&mutex);
00123 if (count==1) {
00124 int status;
00125 #ifdef _POSIX_SAVED_IDS
00126 status = seteuid(real_userid);
00127 #else
00128 status = setreuid(file_userid,real_userid);
00129 #endif
00130 if (status<0) {
00131 Log(ERROR_LOG,LOG_ALERT, "setuid", "setuid::off(): error " << strerror(errno));
00132 } else {
00133 count = 0;
00134 Log(INFO_LOG,LOG_CRIT, "setuid", "setuid::off(): set euid to " << real_userid << " " << real_username);
00135 }
00136 } else if (count==0) {
00137 Log(INFO_LOG,LOG_CRIT, "setuid", "setuid::off(): setuid already off");
00138 } else {
00139 Log(INFO_LOG,LOG_CRIT, "setuid", "setuid::off(): setuid still on");
00140 count--;
00141 }
00142 pthread_mutex_unlock(&mutex);
00143 } else {
00144 Log(ERROR_LOG,LOG_CRIT, "setuid", "Tried to use setuid although not initialized.");
00145 }
00146 }
00147 }
00148
00149 bool setuid::is_init = false;
00150
00151 pthread_mutex_t setuid::mutex =
00152 #ifdef _DEBUG
00153 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
00154 #else
00155 PTHREAD_MUTEX_INITIALIZER;
00156 #endif
00157
00158 uint32 setuid::count = 0;
00159
00160 uid_t setuid::file_userid = 65534;
00161
00162 string setuid::file_username = "nobody";
00163
00164 uid_t setuid::real_userid = 65534;
00165
00166 string setuid::real_username = "nobody";
00167
00168 bool setuid::is_setuid = true;
00169
00171
00172 }