9 static const char rcsid[] __attribute__((used)) =
"$Id: Privilege.cpp 1805 2016-12-01 19:16:37Z sella $";
11 #include "Privilege.h"
16 #include <sys/prctl.h>
18 using namespace sella::util;
20 Privilege::Privilege() throw () : uid(-1), gid(-1) {
24 capabilities = cap_get_proc();
27 Privilege::Privilege(
const Privilege &other) :
33 capabilities = cap_get_proc();
36 Privilege::~Privilege() {
39 cap_free(capabilities);
44 this->ouid = other.ouid;
45 this->uid = other.uid;
46 this->ogid = other.ogid;
47 this->gid = other.gid;
53 void Privilege::applyIdentity(
void)
const throw (PrivilegeException) {
54 if (prctl(PR_SET_KEEPCAPS, 1L)) {
55 THROW(PrivilegeException,
"Failed to retain capabilities");
58 if ((
signed) gid != -1) {
59 if (setgid(gid) != 0) {
60 THROW(PrivilegeException,
"Failed to set gid to %d", gid);
64 if ((
signed) uid != -1) {
65 if (setuid(uid) != 0) {
66 THROW(PrivilegeException,
"Failed to set uid to %d", uid);
71 void Privilege::applyEffectiveIdentity(
void)
const throw (PrivilegeException) {
72 if ((
signed) gid != -1) {
73 if (setegid(gid) != 0) {
74 THROW(PrivilegeException,
"Failed to set effective gid to %d", gid);
78 if ((
signed) uid != -1) {
79 if (seteuid(uid) != 0) {
80 THROW(PrivilegeException,
"Failed to set effective uid to %d", uid);
85 void Privilege::restoreIdentity(
void)
const throw (PrivilegeException) {
86 if (setgid(ogid) != 0) {
87 THROW(PrivilegeException,
"Failed to restore original gid of %d", ogid);
90 if (setuid(ouid) != 0) {
91 THROW(PrivilegeException,
"Failed to restore original uid of %d", ouid);
95 void Privilege::restoreEffectiveIdentity(
void)
const throw (PrivilegeException) {
96 if (setegid(ogid) != 0) {
97 THROW(PrivilegeException,
"Failed to restore original effective gid of %d", ogid);
100 if (seteuid(ouid) != 0) {
101 THROW(PrivilegeException,
"Failed to restore original effective uid of %d", ouid);
105 void Privilege::setUID(uid_t &uid,
bool setGID)
throw (PrivilegeException) {
106 struct passwd pw, *p;
109 if (getpwuid_r(uid, &pw, buf,
sizeof(buf), &p) != 0) {
110 THROW2(PrivilegeException,
"getpwuid_r");
116 this->gid = pw.pw_gid;
120 void Privilege::setUID(
const std::string &user,
bool setGID)
throw (PrivilegeException) {
121 struct passwd pw, *p;
124 if (getpwnam_r(user.c_str(), &pw, buf,
sizeof(buf), &p) != 0) {
125 THROW2(PrivilegeException,
"getpwnam_r");
128 this->uid = pw.pw_uid;
131 this->gid = pw.pw_gid;
135 void Privilege::setGID(gid_t &gid)
throw () {
139 void Privilege::setGID(
const std::string &group)
throw (PrivilegeException) {
143 if (getgrnam_r(group.c_str(), &gr, buf,
sizeof(buf), &g) != 0) {
144 THROW2(PrivilegeException,
"getgrnam_r");
147 this->gid = gr.gr_gid;
150 const uid_t& Privilege::getUID(
void)
const throw () {
154 const uid_t Privilege::getCurrentUID(
void)
const throw () {
158 const uid_t Privilege::getEffectiveUID(
void)
const throw () {
162 const uid_t& Privilege::getOriginalUID(
void)
const throw () {
166 const gid_t& Privilege::getGID(
void)
const throw () {
170 const gid_t Privilege::getCurrentGID(
void)
const throw () {
174 const gid_t Privilege::getEffectiveGID(
void)
const throw () {
178 const gid_t& Privilege::getOriginalGID(
void)
const throw () {
182 bool Privilege::isRoot(
void)
const throw () {
183 return (getEffectiveUID() == 0);
186 bool Privilege::isRootGroup(
void)
const throw () {
187 return (getEffectiveGID() == 0);
190 bool Privilege::wasRoot(
void)
const throw () {
191 return (getOriginalUID() == 0);
194 bool Privilege::wasRootGroup(
void)
const throw () {
195 return (getOriginalGID() == 0);
198 void Privilege::clear(
void) throw () {
203 bool Privilege::setAll(
void) throw () {
207 void Privilege::applyCapabilities(
bool retain)
const throw (PrivilegeException) {
209 if (prctl(PR_SET_KEEPCAPS, 1L)) {
210 THROW(PrivilegeException,
"Failed to retain capabilities");
214 if (cap_set_proc(this->capabilities) == -1) {
215 THROW(PrivilegeException,
"Failed to apply capabilities");
219 void Privilege::clearRetain(
void)
const throw (PrivilegeException) {
220 if (prctl(PR_SET_KEEPCAPS, 0L)) {
221 THROW(PrivilegeException,
"Failed to retain capabilities");
225 bool Privilege::setCapability(cap_value_t cap)
throw () {
226 cap_value_t capability[1] = { cap };
228 return setFlags(capability, 1, CAP_SET);
231 bool Privilege::setChown(
void) throw () {
232 cap_value_t capability[1] = { CAP_CHOWN };
234 return setFlags(capability, 1, CAP_SET);
237 bool Privilege::setSetGid(
void) throw () {
238 cap_value_t capability[1] = { CAP_SETGID };
240 return setFlags(capability, 1, CAP_SET);
243 bool Privilege::setSetUid(
void) throw () {
244 cap_value_t capability[1] = { CAP_SETUID };
246 return setFlags(capability, 1, CAP_SET);
249 bool Privilege::setProcessCapability(
void) throw () {
250 cap_value_t capability[1] = { CAP_SETPCAP };
252 return setFlags(capability, 1, CAP_SET);
255 bool Privilege::setLinuxImmutable(
void) throw () {
256 cap_value_t capability[1] = { CAP_LINUX_IMMUTABLE };
258 return setFlags(capability, 1, CAP_SET);
261 bool Privilege::setNetBroadcast(
void) throw () {
262 cap_value_t capability[1] = { CAP_NET_BROADCAST };
264 return setFlags(capability, 1, CAP_SET);
267 bool Privilege::setNetAdmin(
void) throw () {
268 cap_value_t capability[1] = { CAP_NET_ADMIN };
270 return setFlags(capability, 1, CAP_SET);
273 bool Privilege::setIPCOwner(
void) throw () {
274 cap_value_t capability[1] = { CAP_IPC_OWNER };
276 return setFlags(capability, 1, CAP_SET);
279 bool Privilege::setSysModule(
void) throw () {
280 cap_value_t capability[1] = { CAP_SYS_MODULE };
282 return setFlags(capability, 1, CAP_SET);
285 bool Privilege::setSysProcessTrace(
void) throw () {
286 cap_value_t capability[1] = { CAP_SYS_PTRACE };
288 return setFlags(capability, 1, CAP_SET);
291 bool Privilege::setSysProcessAccount(
void) throw () {
292 cap_value_t capability[1] = { CAP_SYS_PACCT };
294 return setFlags(capability, 1, CAP_SET);
297 bool Privilege::setSysAdmin(
void) throw () {
298 cap_value_t capability[1] = { CAP_SYS_ADMIN };
300 return setFlags(capability, 1, CAP_SET);
303 bool Privilege::setSysBoot(
void) throw () {
304 cap_value_t capability[1] = { CAP_SYS_BOOT };
306 return setFlags(capability, 1, CAP_SET);
309 bool Privilege::setSysTime(
void) throw () {
310 cap_value_t capability[1] = { CAP_SYS_TIME };
312 return setFlags(capability, 1, CAP_SET);
315 bool Privilege::setSysTTYConfig(
void) throw () {
316 cap_value_t capability[1] = { CAP_SYS_TTY_CONFIG };
318 return setFlags(capability, 1, CAP_SET);
321 bool Privilege::setMakeNode(
void) throw () {
322 cap_value_t capability[1] = { CAP_MKNOD };
324 return setFlags(capability, 1, CAP_SET);
327 bool Privilege::setLease(
void) throw () {
328 cap_value_t capability[1] = { CAP_LEASE };
330 return setFlags(capability, 1, CAP_SET);
333 bool Privilege::setAuditWrite(
void) throw () {
334 cap_value_t capability[1] = { CAP_AUDIT_WRITE };
336 return setFlags(capability, 1, CAP_SET);
339 bool Privilege::setAuditControl(
void) throw () {
340 cap_value_t capability[1] = { CAP_AUDIT_CONTROL };
342 return setFlags(capability, 1, CAP_SET);
345 bool Privilege::setSetFileCapability(
void) throw () {
346 cap_value_t capability[1] = { CAP_SETFCAP };
348 return setFlags(capability, 1, CAP_SET);
351 bool Privilege::setMACOverride(
void) throw () {
352 cap_value_t capability[1] = { CAP_MAC_OVERRIDE };
354 return setFlags(capability, 1, CAP_SET);
357 bool Privilege::setMACAdmin(
void) throw () {
358 cap_value_t capability[1] = { CAP_MAC_ADMIN };
360 return setFlags(capability, 1, CAP_SET);
363 bool Privilege::setSyslog(
void) throw () {
364 cap_value_t capability[1] = { CAP_SYSLOG };
366 return setFlags(capability, 1, CAP_SET);
369 bool Privilege::setWakeAlarm(
void) throw () {
370 cap_value_t capability[1] = { CAP_WAKE_ALARM };
372 return setFlags(capability, 1, CAP_SET);
375 bool Privilege::setBlockSuspend(
void) throw () {
376 cap_value_t capability[1] = { CAP_BLOCK_SUSPEND };
378 return setFlags(capability, 1, CAP_SET);
381 bool Privilege::setDACOverride(
void) throw () {
382 cap_value_t capability[1] = { CAP_DAC_OVERRIDE };
384 return setFlags(capability, 1, CAP_SET);
387 bool Privilege::setDACReadSearch(
void) throw () {
388 cap_value_t capability[1] = { CAP_DAC_READ_SEARCH };
390 return setFlags(capability, 1, CAP_SET);
393 bool Privilege::setFileOwner(
void) throw () {
394 cap_value_t capability[1] = { CAP_FOWNER };
396 return setFlags(capability, 1, CAP_SET);
399 bool Privilege::setFileSetId(
void) throw () {
400 cap_value_t capability[1] = { CAP_FSETID };
402 return setFlags(capability, 1, CAP_SET);
405 bool Privilege::setIPCLock(
void) throw () {
406 cap_value_t capability[1] = { CAP_IPC_LOCK };
408 return setFlags(capability, 1, CAP_SET);
411 bool Privilege::setKill(
void) throw () {
412 cap_value_t capability[1] = { CAP_KILL };
414 return setFlags(capability, 1, CAP_SET);
417 bool Privilege::setNetBindService(
void) throw () {
418 cap_value_t capability[1] = { CAP_NET_BIND_SERVICE };
420 return setFlags(capability, 1, CAP_SET);
423 bool Privilege::setNetRaw(
void) throw () {
424 cap_value_t capability[1] = { CAP_NET_RAW };
426 return setFlags(capability, 1, CAP_SET);
429 bool Privilege::setSetUID(
void) throw () {
430 cap_value_t capability[1] = { CAP_SETUID };
432 return setFlags(capability, 1, CAP_SET);
435 bool Privilege::setSysChroot(
void) throw () {
436 cap_value_t capability[1] = { CAP_SYS_CHROOT };
438 return setFlags(capability, 1, CAP_SET);
441 bool Privilege::setSysNice(
void) throw () {
442 cap_value_t capability[1] = { CAP_SYS_NICE };
444 return setFlags(capability, 1, CAP_SET);
447 bool Privilege::setSysRawIO(
void) throw () {
448 cap_value_t capability[1] = { CAP_SYS_RAWIO };
450 return setFlags(capability, 1, CAP_SET);
453 bool Privilege::setSysResource(
void) throw () {
454 cap_value_t capability[1] = { CAP_SYS_RESOURCE };
456 return setFlags(capability, 1, CAP_SET);
459 bool Privilege::clearAll(
void) throw () {
460 if (cap_clear(this->capabilities) == -1) {
467 bool Privilege::clearCapability(cap_value_t cap)
throw () {
468 cap_value_t capability[1] = { cap };
470 return setFlags(capability, 1, CAP_SET);
473 bool Privilege::clearChown(
void) throw () {
474 cap_value_t capability[1] = { CAP_CHOWN };
476 return setFlags(capability, 1, CAP_CLEAR);
479 bool Privilege::clearIPCLock(
void) throw () {
480 cap_value_t capability[1] = { CAP_IPC_LOCK };
482 return setFlags(capability, 1, CAP_CLEAR);
485 bool Privilege::clearKill(
void) throw () {
486 cap_value_t capability[1] = { CAP_KILL };
488 return setFlags(capability, 1, CAP_CLEAR);
491 bool Privilege::clearNetBindService(
void) throw () {
492 cap_value_t capability[1] = { CAP_NET_BIND_SERVICE };
494 return setFlags(capability, 1, CAP_CLEAR);
497 bool Privilege::clearNetRaw(
void) throw () {
498 cap_value_t capability[1] = { CAP_NET_RAW };
500 return setFlags(capability, 1, CAP_CLEAR);
503 bool Privilege::clearSetUID(
void) throw () {
504 cap_value_t capability[1] = { CAP_SETUID };
506 return setFlags(capability, 1, CAP_CLEAR);
509 bool Privilege::clearSysChroot(
void) throw () {
510 cap_value_t capability[1] = { CAP_SYS_CHROOT };
512 return setFlags(capability, 1, CAP_CLEAR);
515 bool Privilege::clearSysNice(
void) throw () {
516 cap_value_t capability[1] = { CAP_SYS_NICE };
518 return setFlags(capability, 1, CAP_CLEAR);
521 bool Privilege::clearSysRawIO(
void) throw () {
522 cap_value_t capability[1] = { CAP_SYS_RAWIO };
524 return setFlags(capability, 1, CAP_CLEAR);
527 bool Privilege::clearSysResource(
void) throw () {
528 cap_value_t capability[1] = { CAP_SYS_RESOURCE };
530 return setFlags(capability, 1, CAP_CLEAR);
533 bool Privilege::hasNone(
void)
const throw () {
537 bool Privilege::hasCapability(cap_value_t cap)
const throw () {
538 cap_flag_value_t value;
540 if (!getFlag(cap, value)) {
544 return (value == CAP_SET);
547 bool Privilege::hasChown(
void)
const throw () {
548 return hasCapability(CAP_CHOWN);
551 bool Privilege::hasIPCLock(
void)
const throw () {
555 bool Privilege::hasKill(
void)
const throw () {
559 bool Privilege::hasNetBindService(
void)
const throw () {
563 bool Privilege::hasNetRaw(
void)
const throw () {
567 bool Privilege::hasSetUID(
void)
const throw () {
571 bool Privilege::hasSysChroot(
void)
const throw () {
575 bool Privilege::hasSysNice(
void)
const throw () {
576 return hasCapability(CAP_SYS_NICE);
579 bool Privilege::hasSysRawIO(
void)
const throw () {
583 bool Privilege::hasSysResource(
void)
const throw () {
587 const Privilege::shared Privilege::shared_ptr(
void) throw () {
588 return std::make_shared<Privilege>();
591 bool Privilege::setFlags(cap_value_t capability[],
int ncap, cap_flag_value_t value)
throw () {
592 if (cap_set_flag(this->capabilities, CAP_EFFECTIVE, ncap, capability, value) == -1) {
596 if (cap_set_flag(this->capabilities, CAP_PERMITTED, ncap, capability, value) == -1) {
600 if (cap_set_flag(this->capabilities, CAP_INHERITABLE, ncap, capability, value) == -1) {
607 bool Privilege::getFlag(cap_value_t capability, cap_flag_value_t &value)
const throw () {
608 if (cap_get_flag(capabilities, capability, CAP_EFFECTIVE, &value) == -1) {