1 /*
2  * Copyright (c) 1997-8,2007,2011 Andrew G Morgan <morgan@kernel.org>
3  *
4  * This file deals with getting and setting capabilities on processes.
5  */
6 
7 #include <sys/prctl.h>
8 
9 #include "libcap.h"
10 
cap_get_proc(void)11 cap_t cap_get_proc(void)
12 {
13     cap_t result;
14 
15     /* allocate a new capability set */
16     result = cap_init();
17     if (result) {
18 	_cap_debug("getting current process' capabilities");
19 
20 	/* fill the capability sets via a system call */
21 	if (capget(&result->head, &result->u[0].set)) {
22 	    cap_free(result);
23 	    result = NULL;
24 	}
25     }
26 
27     return result;
28 }
29 
cap_set_proc(cap_t cap_d)30 int cap_set_proc(cap_t cap_d)
31 {
32     int retval;
33 
34     if (!good_cap_t(cap_d)) {
35 	errno = EINVAL;
36 	return -1;
37     }
38 
39     _cap_debug("setting process capabilities");
40     retval = capset(&cap_d->head, &cap_d->u[0].set);
41 
42     return retval;
43 }
44 
45 /* the following two functions are not required by POSIX */
46 
47 /* read the caps on a specific process */
48 
capgetp(pid_t pid,cap_t cap_d)49 int capgetp(pid_t pid, cap_t cap_d)
50 {
51     int error;
52 
53     if (!good_cap_t(cap_d)) {
54 	errno = EINVAL;
55 	return -1;
56     }
57 
58     _cap_debug("getting process capabilities for proc %d", pid);
59 
60     cap_d->head.pid = pid;
61     error = capget(&cap_d->head, &cap_d->u[0].set);
62     cap_d->head.pid = 0;
63 
64     return error;
65 }
66 
67 /* allocate space for and return capabilities of target process */
68 
cap_get_pid(pid_t pid)69 cap_t cap_get_pid(pid_t pid)
70 {
71     cap_t result;
72 
73     result = cap_init();
74     if (result) {
75 	if (capgetp(pid, result) != 0) {
76 	    int my_errno;
77 
78 	    my_errno = errno;
79 	    cap_free(result);
80 	    errno = my_errno;
81 	    result = NULL;
82 	}
83     }
84 
85     return result;
86 }
87 
88 /* set the caps on a specific process/pg etc.. */
89 
capsetp(pid_t pid,cap_t cap_d)90 int capsetp(pid_t pid, cap_t cap_d)
91 {
92     int error;
93 
94     if (!good_cap_t(cap_d)) {
95 	errno = EINVAL;
96 	return -1;
97     }
98 
99     _cap_debug("setting process capabilities for proc %d", pid);
100     cap_d->head.pid = pid;
101     error = capset(&cap_d->head, &cap_d->u[0].set);
102     cap_d->head.version = _LIBCAP_CAPABILITY_VERSION;
103     cap_d->head.pid = 0;
104 
105     return error;
106 }
107 
108 /* get a capability from the bounding set */
109 
cap_get_bound(cap_value_t cap)110 int cap_get_bound(cap_value_t cap)
111 {
112     int result;
113 
114     result = prctl(PR_CAPBSET_READ, cap);
115     return result;
116 }
117 
118 /* drop a capability from the bounding set */
119 
cap_drop_bound(cap_value_t cap)120 int cap_drop_bound(cap_value_t cap)
121 {
122     int result;
123 
124     result = prctl(PR_CAPBSET_DROP, cap);
125     return result;
126 }
127