libutil++  1.9.3
 All Classes Functions Variables
Privilege.cpp
1 /*
2 ** libutil++
3 ** $Id: Privilege.cpp 1805 2016-12-01 19:16:37Z sella $
4 ** Copyright (c) 2011-2016 Digital Genesis, LLC. All Rights Reserved.
5 ** Released under the LGPL Version 2.1 License.
6 ** http://www.digitalgenesis.com
7 */
8 
9 static const char rcsid[] __attribute__((used)) = "$Id: Privilege.cpp 1805 2016-12-01 19:16:37Z sella $";
10 
11 #include "Privilege.h"
12 
13 #include <string.h>
14 #include <pwd.h>
15 #include <grp.h>
16 #include <sys/prctl.h>
17 
18 using namespace sella::util;
19 
20 Privilege::Privilege() throw () : uid(-1), gid(-1) {
21  ouid = getuid();
22  ogid = getgid();
23 
24  capabilities = cap_get_proc();
25 }
26 
27 Privilege::Privilege(const Privilege &other) :
28  ouid(other.ouid),
29  uid(other.uid),
30  ogid(other.ogid),
31  gid(other.gid)
32 {
33  capabilities = cap_get_proc();
34 }
35 
36 Privilege::~Privilege() {
37  clear();
38 
39  cap_free(capabilities);
40 }
41 
42 Privilege& Privilege::operator=(const Privilege &other) throw () {
43  if (this != &other) {
44  this->ouid = other.ouid;
45  this->uid = other.uid;
46  this->ogid = other.ogid;
47  this->gid = other.gid;
48  }
49 
50  return *this;
51 }
52 
53 void Privilege::applyIdentity(void) const throw (PrivilegeException) {
54  if (prctl(PR_SET_KEEPCAPS, 1L)) { /* Retain set capabilities. */
55  THROW(PrivilegeException, "Failed to retain capabilities");
56  }
57 
58  if ((signed) gid != -1) {
59  if (setgid(gid) != 0) {
60  THROW(PrivilegeException, "Failed to set gid to %d", gid);
61  }
62  }
63 
64  if ((signed) uid != -1) {
65  if (setuid(uid) != 0) {
66  THROW(PrivilegeException, "Failed to set uid to %d", uid);
67  }
68  }
69 }
70 
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);
75  }
76  }
77 
78  if ((signed) uid != -1) {
79  if (seteuid(uid) != 0) {
80  THROW(PrivilegeException, "Failed to set effective uid to %d", uid);
81  }
82  }
83 }
84 
85 void Privilege::restoreIdentity(void) const throw (PrivilegeException) {
86  if (setgid(ogid) != 0) {
87  THROW(PrivilegeException, "Failed to restore original gid of %d", ogid);
88  }
89 
90  if (setuid(ouid) != 0) {
91  THROW(PrivilegeException, "Failed to restore original uid of %d", ouid);
92  }
93 }
94 
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);
98  }
99 
100  if (seteuid(ouid) != 0) {
101  THROW(PrivilegeException, "Failed to restore original effective uid of %d", ouid);
102  }
103 }
104 
105 void Privilege::setUID(uid_t &uid, bool setGID) throw (PrivilegeException) {
106  struct passwd pw, *p;
107  char buf[200];
108 
109  if (getpwuid_r(uid, &pw, buf, sizeof(buf), &p) != 0) {
110  THROW2(PrivilegeException, "getpwuid_r");
111  }
112 
113  this->uid = uid;
114 
115  if (setGID) {
116  this->gid = pw.pw_gid;
117  }
118 }
119 
120 void Privilege::setUID(const std::string &user, bool setGID) throw (PrivilegeException) {
121  struct passwd pw, *p;
122  char buf[200];
123 
124  if (getpwnam_r(user.c_str(), &pw, buf, sizeof(buf), &p) != 0) {
125  THROW2(PrivilegeException, "getpwnam_r");
126  }
127 
128  this->uid = pw.pw_uid;
129 
130  if (setGID) {
131  this->gid = pw.pw_gid;
132  }
133 }
134 
135 void Privilege::setGID(gid_t &gid) throw () {
136  this->gid = gid;
137 }
138 
139 void Privilege::setGID(const std::string &group) throw (PrivilegeException) {
140  struct group gr, *g;
141  char buf[200];
142 
143  if (getgrnam_r(group.c_str(), &gr, buf, sizeof(buf), &g) != 0) {
144  THROW2(PrivilegeException, "getgrnam_r");
145  }
146 
147  this->gid = gr.gr_gid;
148 }
149 
150 const uid_t& Privilege::getUID(void) const throw () {
151  return this->uid;
152 }
153 
154 const uid_t Privilege::getCurrentUID(void) const throw () {
155  return getuid();
156 }
157 
158 const uid_t Privilege::getEffectiveUID(void) const throw () {
159  return geteuid();
160 }
161 
162 const uid_t& Privilege::getOriginalUID(void) const throw () {
163  return this->ouid;
164 }
165 
166 const gid_t& Privilege::getGID(void) const throw () {
167  return this->gid;
168 }
169 
170 const gid_t Privilege::getCurrentGID(void) const throw () {
171  return getgid();
172 }
173 
174 const gid_t Privilege::getEffectiveGID(void) const throw () {
175  return getegid();
176 }
177 
178 const gid_t& Privilege::getOriginalGID(void) const throw () {
179  return this->ogid;
180 }
181 
182 bool Privilege::isRoot(void) const throw () {
183  return (getEffectiveUID() == 0);
184 }
185 
186 bool Privilege::isRootGroup(void) const throw () {
187  return (getEffectiveGID() == 0);
188 }
189 
190 bool Privilege::wasRoot(void) const throw () {
191  return (getOriginalUID() == 0);
192 }
193 
194 bool Privilege::wasRootGroup(void) const throw () {
195  return (getOriginalGID() == 0);
196 }
197 
198 void Privilege::clear(void) throw () {
199  this->uid = -1;
200  this->gid = -1;
201 }
202 
203 bool Privilege::setAll(void) throw () {
204  return false;
205 }
206 
207 void Privilege::applyCapabilities(bool retain) const throw (PrivilegeException) {
208  if (retain) {
209  if (prctl(PR_SET_KEEPCAPS, 1L)) { /* Retain set capabilities. */
210  THROW(PrivilegeException, "Failed to retain capabilities");
211  }
212  }
213 
214  if (cap_set_proc(this->capabilities) == -1) {
215  THROW(PrivilegeException, "Failed to apply capabilities");
216  }
217 }
218 
219 void Privilege::clearRetain(void) const throw (PrivilegeException) {
220  if (prctl(PR_SET_KEEPCAPS, 0L)) {
221  THROW(PrivilegeException, "Failed to retain capabilities");
222  }
223 }
224 
225 bool Privilege::setCapability(cap_value_t cap) throw () {
226  cap_value_t capability[1] = { cap };
227 
228  return setFlags(capability, 1, CAP_SET);
229 }
230 
231 bool Privilege::setChown(void) throw () {
232  cap_value_t capability[1] = { CAP_CHOWN };
233 
234  return setFlags(capability, 1, CAP_SET);
235 }
236 
237 bool Privilege::setSetGid(void) throw () {
238  cap_value_t capability[1] = { CAP_SETGID };
239 
240  return setFlags(capability, 1, CAP_SET);
241 }
242 
243 bool Privilege::setSetUid(void) throw () {
244  cap_value_t capability[1] = { CAP_SETUID };
245 
246  return setFlags(capability, 1, CAP_SET);
247 }
248 
249 bool Privilege::setProcessCapability(void) throw () {
250  cap_value_t capability[1] = { CAP_SETPCAP };
251 
252  return setFlags(capability, 1, CAP_SET);
253 }
254 
255 bool Privilege::setLinuxImmutable(void) throw () {
256  cap_value_t capability[1] = { CAP_LINUX_IMMUTABLE };
257 
258  return setFlags(capability, 1, CAP_SET);
259 }
260 
261 bool Privilege::setNetBroadcast(void) throw () {
262  cap_value_t capability[1] = { CAP_NET_BROADCAST };
263 
264  return setFlags(capability, 1, CAP_SET);
265 }
266 
267 bool Privilege::setNetAdmin(void) throw () {
268  cap_value_t capability[1] = { CAP_NET_ADMIN };
269 
270  return setFlags(capability, 1, CAP_SET);
271 }
272 
273 bool Privilege::setIPCOwner(void) throw () {
274  cap_value_t capability[1] = { CAP_IPC_OWNER };
275 
276  return setFlags(capability, 1, CAP_SET);
277 }
278 
279 bool Privilege::setSysModule(void) throw () {
280  cap_value_t capability[1] = { CAP_SYS_MODULE };
281 
282  return setFlags(capability, 1, CAP_SET);
283 }
284 
285 bool Privilege::setSysProcessTrace(void) throw () {
286  cap_value_t capability[1] = { CAP_SYS_PTRACE };
287 
288  return setFlags(capability, 1, CAP_SET);
289 }
290 
291 bool Privilege::setSysProcessAccount(void) throw () {
292  cap_value_t capability[1] = { CAP_SYS_PACCT };
293 
294  return setFlags(capability, 1, CAP_SET);
295 }
296 
297 bool Privilege::setSysAdmin(void) throw () {
298  cap_value_t capability[1] = { CAP_SYS_ADMIN };
299 
300  return setFlags(capability, 1, CAP_SET);
301 }
302 
303 bool Privilege::setSysBoot(void) throw () {
304  cap_value_t capability[1] = { CAP_SYS_BOOT };
305 
306  return setFlags(capability, 1, CAP_SET);
307 }
308 
309 bool Privilege::setSysTime(void) throw () {
310  cap_value_t capability[1] = { CAP_SYS_TIME };
311 
312  return setFlags(capability, 1, CAP_SET);
313 }
314 
315 bool Privilege::setSysTTYConfig(void) throw () {
316  cap_value_t capability[1] = { CAP_SYS_TTY_CONFIG };
317 
318  return setFlags(capability, 1, CAP_SET);
319 }
320 
321 bool Privilege::setMakeNode(void) throw () {
322  cap_value_t capability[1] = { CAP_MKNOD };
323 
324  return setFlags(capability, 1, CAP_SET);
325 }
326 
327 bool Privilege::setLease(void) throw () {
328  cap_value_t capability[1] = { CAP_LEASE };
329 
330  return setFlags(capability, 1, CAP_SET);
331 }
332 
333 bool Privilege::setAuditWrite(void) throw () {
334  cap_value_t capability[1] = { CAP_AUDIT_WRITE };
335 
336  return setFlags(capability, 1, CAP_SET);
337 }
338 
339 bool Privilege::setAuditControl(void) throw () {
340  cap_value_t capability[1] = { CAP_AUDIT_CONTROL };
341 
342  return setFlags(capability, 1, CAP_SET);
343 }
344 
345 bool Privilege::setSetFileCapability(void) throw () {
346  cap_value_t capability[1] = { CAP_SETFCAP };
347 
348  return setFlags(capability, 1, CAP_SET);
349 }
350 
351 bool Privilege::setMACOverride(void) throw () {
352  cap_value_t capability[1] = { CAP_MAC_OVERRIDE };
353 
354  return setFlags(capability, 1, CAP_SET);
355 }
356 
357 bool Privilege::setMACAdmin(void) throw () {
358  cap_value_t capability[1] = { CAP_MAC_ADMIN };
359 
360  return setFlags(capability, 1, CAP_SET);
361 }
362 
363 bool Privilege::setSyslog(void) throw () {
364  cap_value_t capability[1] = { CAP_SYSLOG };
365 
366  return setFlags(capability, 1, CAP_SET);
367 }
368 
369 bool Privilege::setWakeAlarm(void) throw () {
370  cap_value_t capability[1] = { CAP_WAKE_ALARM };
371 
372  return setFlags(capability, 1, CAP_SET);
373 }
374 
375 bool Privilege::setBlockSuspend(void) throw () {
376  cap_value_t capability[1] = { CAP_BLOCK_SUSPEND };
377 
378  return setFlags(capability, 1, CAP_SET);
379 }
380 
381 bool Privilege::setDACOverride(void) throw () {
382  cap_value_t capability[1] = { CAP_DAC_OVERRIDE };
383 
384  return setFlags(capability, 1, CAP_SET);
385 }
386 
387 bool Privilege::setDACReadSearch(void) throw () {
388  cap_value_t capability[1] = { CAP_DAC_READ_SEARCH };
389 
390  return setFlags(capability, 1, CAP_SET);
391 }
392 
393 bool Privilege::setFileOwner(void) throw () {
394  cap_value_t capability[1] = { CAP_FOWNER };
395 
396  return setFlags(capability, 1, CAP_SET);
397 }
398 
399 bool Privilege::setFileSetId(void) throw () {
400  cap_value_t capability[1] = { CAP_FSETID };
401 
402  return setFlags(capability, 1, CAP_SET);
403 }
404 
405 bool Privilege::setIPCLock(void) throw () {
406  cap_value_t capability[1] = { CAP_IPC_LOCK };
407 
408  return setFlags(capability, 1, CAP_SET);
409 }
410 
411 bool Privilege::setKill(void) throw () {
412  cap_value_t capability[1] = { CAP_KILL };
413 
414  return setFlags(capability, 1, CAP_SET);
415 }
416 
417 bool Privilege::setNetBindService(void) throw () {
418  cap_value_t capability[1] = { CAP_NET_BIND_SERVICE };
419 
420  return setFlags(capability, 1, CAP_SET);
421 }
422 
423 bool Privilege::setNetRaw(void) throw () {
424  cap_value_t capability[1] = { CAP_NET_RAW };
425 
426  return setFlags(capability, 1, CAP_SET);
427 }
428 
429 bool Privilege::setSetUID(void) throw () {
430  cap_value_t capability[1] = { CAP_SETUID };
431 
432  return setFlags(capability, 1, CAP_SET);
433 }
434 
435 bool Privilege::setSysChroot(void) throw () {
436  cap_value_t capability[1] = { CAP_SYS_CHROOT };
437 
438  return setFlags(capability, 1, CAP_SET);
439 }
440 
441 bool Privilege::setSysNice(void) throw () {
442  cap_value_t capability[1] = { CAP_SYS_NICE };
443 
444  return setFlags(capability, 1, CAP_SET);
445 }
446 
447 bool Privilege::setSysRawIO(void) throw () {
448  cap_value_t capability[1] = { CAP_SYS_RAWIO };
449 
450  return setFlags(capability, 1, CAP_SET);
451 }
452 
453 bool Privilege::setSysResource(void) throw () {
454  cap_value_t capability[1] = { CAP_SYS_RESOURCE };
455 
456  return setFlags(capability, 1, CAP_SET);
457 }
458 
459 bool Privilege::clearAll(void) throw () {
460  if (cap_clear(this->capabilities) == -1) {
461  return false;
462  }
463 
464  return true;
465 }
466 
467 bool Privilege::clearCapability(cap_value_t cap) throw () {
468  cap_value_t capability[1] = { cap };
469 
470  return setFlags(capability, 1, CAP_SET);
471 }
472 
473 bool Privilege::clearChown(void) throw () {
474  cap_value_t capability[1] = { CAP_CHOWN };
475 
476  return setFlags(capability, 1, CAP_CLEAR);
477 }
478 
479 bool Privilege::clearIPCLock(void) throw () {
480  cap_value_t capability[1] = { CAP_IPC_LOCK };
481 
482  return setFlags(capability, 1, CAP_CLEAR);
483 }
484 
485 bool Privilege::clearKill(void) throw () {
486  cap_value_t capability[1] = { CAP_KILL };
487 
488  return setFlags(capability, 1, CAP_CLEAR);
489 }
490 
491 bool Privilege::clearNetBindService(void) throw () {
492  cap_value_t capability[1] = { CAP_NET_BIND_SERVICE };
493 
494  return setFlags(capability, 1, CAP_CLEAR);
495 }
496 
497 bool Privilege::clearNetRaw(void) throw () {
498  cap_value_t capability[1] = { CAP_NET_RAW };
499 
500  return setFlags(capability, 1, CAP_CLEAR);
501 }
502 
503 bool Privilege::clearSetUID(void) throw () {
504  cap_value_t capability[1] = { CAP_SETUID };
505 
506  return setFlags(capability, 1, CAP_CLEAR);
507 }
508 
509 bool Privilege::clearSysChroot(void) throw () {
510  cap_value_t capability[1] = { CAP_SYS_CHROOT };
511 
512  return setFlags(capability, 1, CAP_CLEAR);
513 }
514 
515 bool Privilege::clearSysNice(void) throw () {
516  cap_value_t capability[1] = { CAP_SYS_NICE };
517 
518  return setFlags(capability, 1, CAP_CLEAR);
519 }
520 
521 bool Privilege::clearSysRawIO(void) throw () {
522  cap_value_t capability[1] = { CAP_SYS_RAWIO };
523 
524  return setFlags(capability, 1, CAP_CLEAR);
525 }
526 
527 bool Privilege::clearSysResource(void) throw () {
528  cap_value_t capability[1] = { CAP_SYS_RESOURCE };
529 
530  return setFlags(capability, 1, CAP_CLEAR);
531 }
532 
533 bool Privilege::hasNone(void) const throw () {
534  return false;
535 }
536 
537 bool Privilege::hasCapability(cap_value_t cap) const throw () {
538  cap_flag_value_t value;
539 
540  if (!getFlag(cap, value)) {
541  return false;
542  }
543 
544  return (value == CAP_SET);
545 }
546 
547 bool Privilege::hasChown(void) const throw () {
548  return hasCapability(CAP_CHOWN);
549 }
550 
551 bool Privilege::hasIPCLock(void) const throw () {
552  return false;
553 }
554 
555 bool Privilege::hasKill(void) const throw () {
556  return false;
557 }
558 
559 bool Privilege::hasNetBindService(void) const throw () {
560  return false;
561 }
562 
563 bool Privilege::hasNetRaw(void) const throw () {
564  return false;
565 }
566 
567 bool Privilege::hasSetUID(void) const throw () {
568  return false;
569 }
570 
571 bool Privilege::hasSysChroot(void) const throw () {
572  return false;
573 }
574 
575 bool Privilege::hasSysNice(void) const throw () {
576  return hasCapability(CAP_SYS_NICE);
577 }
578 
579 bool Privilege::hasSysRawIO(void) const throw () {
580  return false;
581 }
582 
583 bool Privilege::hasSysResource(void) const throw () {
584  return false;
585 }
586 
587 const Privilege::shared Privilege::shared_ptr(void) throw () {
588  return std::make_shared<Privilege>();
589 }
590 
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) {
593  return false;
594  }
595 
596  if (cap_set_flag(this->capabilities, CAP_PERMITTED, ncap, capability, value) == -1) {
597  return false;
598  }
599 
600  if (cap_set_flag(this->capabilities, CAP_INHERITABLE, ncap, capability, value) == -1) {
601  return false;
602  }
603 
604  return true;
605 }
606 
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) {
609  return false;
610  }
611 
612  return true;
613 }
614 
615 /*
616 ** vim: noet ts=3 sw=3
617 */