]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/caps.c
2 * lxc: linux Container library
4 * (C) Copyright IBM Corp. 2007, 2008
7 * Daniel Lezcano <dlezcano at fr.ibm.com>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include <sys/prctl.h>
35 lxc_log_define(lxc_caps
, lxc
);
37 #if HAVE_SYS_CAPABILITY_H
38 #include <sys/capability.h>
40 int lxc_caps_reset(void)
42 cap_t cap
= cap_init();
46 ERROR("cap_init() failed : %m");
50 if (cap_set_proc(cap
)) {
51 ERROR("cap_set_proc() failed : %m");
59 int lxc_caps_down(void)
64 /* when we are run as root, we don't want to play
65 * with the capabilities */
69 caps
= cap_get_proc();
71 ERROR("failed to cap_get_proc: %m");
75 ret
= cap_clear_flag(caps
, CAP_EFFECTIVE
);
77 ERROR("failed to cap_clear_flag: %m");
81 ret
= cap_set_proc(caps
);
83 ERROR("failed to cap_set_proc: %m");
98 /* when we are run as root, we don't want to play
99 * with the capabilities */
103 caps
= cap_get_proc();
105 ERROR("failed to cap_get_proc: %m");
109 for (cap
= 0; cap
<= CAP_LAST_CAP
; cap
++) {
111 cap_flag_value_t flag
;
113 ret
= cap_get_flag(caps
, cap
, CAP_PERMITTED
, &flag
);
115 if (errno
== EINVAL
) {
116 INFO("Last supported cap was %d\n", cap
-1);
119 ERROR("failed to cap_get_flag: %m");
124 ret
= cap_set_flag(caps
, CAP_EFFECTIVE
, 1, &cap
, flag
);
126 ERROR("failed to cap_set_flag: %m");
131 ret
= cap_set_proc(caps
);
133 ERROR("failed to cap_set_proc: %m");
142 int lxc_caps_init(void)
144 uid_t uid
= getuid();
145 gid_t gid
= getgid();
146 uid_t euid
= geteuid();
149 INFO("command is run as 'root'");
154 INFO("command is run as setuid root (uid : %d)", uid
);
156 if (prctl(PR_SET_KEEPCAPS
, 1)) {
157 ERROR("failed to 'PR_SET_KEEPCAPS': %m");
161 if (setresgid(gid
, gid
, gid
)) {
162 ERROR("failed to change gid to '%d': %m", gid
);
166 if (setresuid(uid
, uid
, uid
)) {
167 ERROR("failed to change uid to '%d': %m", uid
);
172 ERROR("failed to restore capabilities: %m");
178 INFO("command is run as user '%d'", uid
);
183 static int _real_caps_last_cap(void)
188 /* try to get the maximum capability over the kernel
189 * interface introduced in v3.2 */
190 fd
= open("/proc/sys/kernel/cap_last_cap", O_RDONLY
);
196 if ((n
= read(fd
, buf
, 31)) >= 0) {
198 result
= strtol(buf
, &ptr
, 10);
199 if (!ptr
|| (*ptr
!= '\0' && *ptr
!= '\n') ||
200 result
== LONG_MIN
|| result
== LONG_MAX
)
207 /* try to get it manually by trying to get the status of
208 * each capability indiviually from the kernel */
211 while (prctl(PR_CAPBSET_READ
, cap
) >= 0) cap
++;
218 int lxc_caps_last_cap(void)
220 static int last_cap
= -1;
221 if (last_cap
< 0) last_cap
= _real_caps_last_cap();
227 * check if we have the caps needed to start a container. returns 1 on
228 * success, 0 on error. (I'd prefer this be a bool, but am afraid that
229 * might fail to build on some distros).
231 int lxc_caps_check(void)
233 uid_t uid
= getuid();
235 cap_flag_value_t value
;
238 cap_value_t needed_caps
[] = { CAP_SYS_ADMIN
, CAP_NET_ADMIN
, CAP_SETUID
, CAP_SETGID
};
240 #define NUMCAPS ((int) (sizeof(needed_caps) / sizeof(cap_t)))
245 caps
= cap_get_proc();
247 ERROR("failed to cap_get_proc: %m");
251 for (i
=0; i
<NUMCAPS
; i
++) {
252 ret
= cap_get_flag(caps
, needed_caps
[i
], CAP_EFFECTIVE
, &value
);
254 ERROR("Failed to cap_get_flag: %m");