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
11cap_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
30int 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
49int 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
69cap_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
90int 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
110int 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
120int cap_drop_bound(cap_value_t cap)
121{
122    int result;
123
124    result = prctl(PR_CAPBSET_DROP, cap);
125    return result;
126}
127