00001
00002
00003
00004
00005
00006
00007
00008
00009 static const char rcsid[] __attribute__((used)) = "$Id: Privilege.cpp 1197 2014-10-14 22:26:11Z sella $";
00010
00011 #include "Privilege.h"
00012
00013 #include <string.h>
00014 #include <pwd.h>
00015 #include <grp.h>
00016
00017 using namespace sella::util;
00018
00019 Privilege::Privilege() throw () : uid(-1), gid(-1) {
00020 ouid = getuid();
00021 ogid = getgid();
00022 }
00023
00024 Privilege::Privilege(const Privilege &other) :
00025 ouid(other.ouid),
00026 uid(other.uid),
00027 ogid(other.ogid),
00028 gid(other.gid)
00029 { }
00030
00031 Privilege::~Privilege() {
00032 clear();
00033 }
00034
00035 Privilege& Privilege::operator=(const Privilege &other) throw () {
00036 if (this != &other) {
00037 this->ouid = other.ouid;
00038 this->uid = other.uid;
00039 this->ogid = other.ogid;
00040 this->gid = other.gid;
00041 }
00042
00043 return *this;
00044 }
00045
00046 void Privilege::applyIdentity(void) const throw (PrivilegeException) {
00047 if ((signed) gid != -1) {
00048 if (setgid(gid) != 0) {
00049 THROW(PrivilegeException, "Failed to set gid to %d", gid);
00050 }
00051 }
00052
00053 if ((signed) uid != -1) {
00054 if (setuid(uid) != 0) {
00055 THROW(PrivilegeException, "Failed to set uid to %d", uid);
00056 }
00057 }
00058 }
00059
00060 void Privilege::applyEffectiveIdentity(void) const throw (PrivilegeException) {
00061 if ((signed) gid != -1) {
00062 if (setegid(gid) != 0) {
00063 THROW(PrivilegeException, "Failed to set effective gid to %d", gid);
00064 }
00065 }
00066
00067 if ((signed) uid != -1) {
00068 if (seteuid(uid) != 0) {
00069 THROW(PrivilegeException, "Failed to set effective uid to %d", uid);
00070 }
00071 }
00072 }
00073
00074 void Privilege::restoreIdentity(void) const throw (PrivilegeException) {
00075 if (setgid(ogid) != 0) {
00076 THROW(PrivilegeException, "Failed to restore original gid of %d", ogid);
00077 }
00078
00079 if (setuid(ouid) != 0) {
00080 THROW(PrivilegeException, "Failed to restore original uid of %d", ouid);
00081 }
00082 }
00083
00084 void Privilege::restoreEffectiveIdentity(void) const throw (PrivilegeException) {
00085 if (setegid(ogid) != 0) {
00086 THROW(PrivilegeException, "Failed to restore original effective gid of %d", ogid);
00087 }
00088
00089 if (seteuid(ouid) != 0) {
00090 THROW(PrivilegeException, "Failed to restore original effective uid of %d", ouid);
00091 }
00092 }
00093
00094 void Privilege::setUID(uid_t &uid, bool setGID) throw (PrivilegeException) {
00095 struct passwd pw, *p;
00096 char buf[200];
00097
00098 if (getpwuid_r(uid, &pw, buf, sizeof(buf), &p) != 0) {
00099 THROW2(PrivilegeException, "getpwuid_r");
00100 }
00101
00102 this->uid = uid;
00103
00104 if (setGID) {
00105 this->gid = pw.pw_gid;
00106 }
00107 }
00108
00109 void Privilege::setUID(const std::string &user, bool setGID) throw (PrivilegeException) {
00110 struct passwd pw, *p;
00111 char buf[200];
00112
00113 if (getpwnam_r(user.c_str(), &pw, buf, sizeof(buf), &p) != 0) {
00114 THROW2(PrivilegeException, "getpwnam_r");
00115 }
00116
00117 this->uid = pw.pw_uid;
00118
00119 if (setGID) {
00120 this->gid = pw.pw_gid;
00121 }
00122 }
00123
00124 void Privilege::setGID(gid_t &gid) throw () {
00125 this->gid = gid;
00126 }
00127
00128 void Privilege::setGID(const std::string &group) throw (PrivilegeException) {
00129 struct group gr, *g;
00130 char buf[200];
00131
00132 if (getgrnam_r(group.c_str(), &gr, buf, sizeof(buf), &g) != 0) {
00133 THROW2(PrivilegeException, "getgrnam_r");
00134 }
00135
00136 this->gid = gr.gr_gid;
00137 }
00138
00139 const uid_t& Privilege::getUID(void) const throw () {
00140 return this->uid;
00141 }
00142
00143 const uid_t Privilege::getCurrentUID(void) const throw () {
00144 return getuid();
00145 }
00146
00147 const uid_t Privilege::getEffectiveUID(void) const throw () {
00148 return geteuid();
00149 }
00150
00151 const uid_t& Privilege::getOriginalUID(void) const throw () {
00152 return this->ouid;
00153 }
00154
00155 const gid_t& Privilege::getGID(void) const throw () {
00156 return this->gid;
00157 }
00158
00159 const gid_t Privilege::getCurrentGID(void) const throw () {
00160 return getgid();
00161 }
00162
00163 const gid_t Privilege::getEffectiveGID(void) const throw () {
00164 return getegid();
00165 }
00166
00167 const gid_t& Privilege::getOriginalGID(void) const throw () {
00168 return this->ogid;
00169 }
00170
00171 bool Privilege::isRoot(void) const throw () {
00172 return (getEffectiveUID() == 0);
00173 }
00174
00175 bool Privilege::isRootGroup(void) const throw () {
00176 return (getEffectiveGID() == 0);
00177 }
00178
00179 bool Privilege::wasRoot(void) const throw () {
00180 return (getOriginalUID() == 0);
00181 }
00182
00183 bool Privilege::wasRootGroup(void) const throw () {
00184 return (getOriginalGID() == 0);
00185 }
00186
00187 void Privilege::clear(void) throw () {
00188 this->uid = -1;
00189 this->gid = -1;
00190 }
00191
00192 #ifdef HAVE_LINUX_CAPABILITY_H
00193 void Privilege::applyCapabilities(void) throw (PrivilegeException) {
00194 if (capng_apply(CAPNG_SELECT_BOTH) != 0) {
00195 THROW(PrivilegeException, "Failed to apply capabilities.");
00196 }
00197 }
00198
00199 void Privilege::setAll(void) throw () {
00200 capng_fill(CAPNG_SELECT_BOTH);
00201 }
00202
00203 bool Privilege::setCapability(int capability) throw () {
00204 return (capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE|CAPNG_PERMITTED), capability) == 0);
00205 }
00206
00207 bool Privilege::setChown(void) throw () {
00208 return setCapability(CAP_CHOWN);
00209 }
00210
00211 bool Privilege::setKill(void) throw () {
00212 return setCapability(CAP_KILL);
00213 }
00214
00215 bool Privilege::setNetBindService(void) throw () {
00216 return setCapability(CAP_NET_BIND_SERVICE);
00217 }
00218
00219 bool Privilege::setNetRaw(void) throw () {
00220 return setCapability(CAP_NET_RAW);
00221 }
00222
00223 bool Privilege::setSetUID(void) throw () {
00224 return setCapability(CAP_SETUID);
00225 }
00226
00227 bool Privilege::setSysChroot(void) throw () {
00228 return setCapability(CAP_SYS_CHROOT);
00229 }
00230
00231 bool Privilege::setSysNice(void) throw () {
00232 return setCapability(CAP_SYS_NICE);
00233 }
00234
00235 bool Privilege::setSysRawIO(void) throw () {
00236 return setCapability(CAP_SYS_RAWIO);
00237 }
00238
00239 bool Privilege::setSysResource(void) throw () {
00240 return setCapability(CAP_SYS_RESOURCE);
00241 }
00242
00243 void Privilege::clearAll(void) throw () {
00244 capng_clear(CAPNG_SELECT_BOTH);
00245 }
00246
00247 bool Privilege::clearCapability(int capability) throw () {
00248 return (capng_update(CAPNG_DROP, (capng_type_t) (CAPNG_EFFECTIVE|CAPNG_PERMITTED), capability) == 0);
00249 }
00250
00251 bool Privilege::clearChown(void) throw () {
00252 return clearCapability(CAP_CHOWN);
00253 }
00254
00255 bool Privilege::clearKill(void) throw () {
00256 return clearCapability(CAP_KILL);
00257 }
00258
00259 bool Privilege::clearNetBindService(void) throw () {
00260 return clearCapability(CAP_NET_BIND_SERVICE);
00261 }
00262
00263 bool Privilege::clearNetRaw(void) throw () {
00264 return clearCapability(CAP_NET_RAW);
00265 }
00266
00267 bool Privilege::clearSetUID(void) throw () {
00268 return clearCapability(CAP_SETUID);
00269 }
00270
00271 bool Privilege::clearSysChroot(void) throw () {
00272 return clearCapability(CAP_SYS_CHROOT);
00273 }
00274
00275 bool Privilege::clearSysNice(void) throw () {
00276 return clearCapability(CAP_SYS_NICE);
00277 }
00278
00279 bool Privilege::clearSysRawIO(void) throw () {
00280 return clearCapability(CAP_SYS_RAWIO);
00281 }
00282
00283 bool Privilege::clearSysResource(void) throw () {
00284 return clearCapability(CAP_SYS_RESOURCE);
00285 }
00286
00287 bool Privilege::hasNone(void) const throw () {
00288 return !(capng_have_capabilities(CAPNG_SELECT_CAPS) > CAPNG_NONE);
00289 }
00290
00291 bool Privilege::hasCapability(int capability) const throw () {
00292 return (bool) capng_have_capability(CAPNG_EFFECTIVE, capability);
00293 }
00294
00295 bool Privilege::hasChown(void) const throw () {
00296 return hasCapability(CAP_CHOWN);
00297 }
00298
00299 bool Privilege::hasKill(void) const throw () {
00300 return hasCapability(CAP_KILL);
00301 }
00302
00303 bool Privilege::hasNetBindService(void) const throw () {
00304 return hasCapability(CAP_NET_BIND_SERVICE);
00305 }
00306
00307 bool Privilege::hasNetRaw(void) const throw () {
00308 return hasCapability(CAP_NET_RAW);
00309 }
00310
00311 bool Privilege::hasSetUID(void) const throw () {
00312 return hasCapability(CAP_SETUID);
00313 }
00314
00315 bool Privilege::hasSysChroot(void) const throw () {
00316 return hasCapability(CAP_SYS_CHROOT);
00317 }
00318
00319 bool Privilege::hasSysNice(void) const throw () {
00320 return hasCapability(CAP_SYS_NICE);
00321 }
00322
00323 bool Privilege::hasSysRawIO(void) const throw () {
00324 return hasCapability(CAP_SYS_RAWIO);
00325 }
00326
00327 bool Privilege::hasSysResource(void) const throw () {
00328 return hasCapability(CAP_SYS_RESOURCE);
00329 }
00330 #endif
00331
00332 const Privilege::shared Privilege::shared_ptr(void) throw () {
00333 return std::make_shared<Privilege>();
00334 }
00335
00336
00337
00338