]>
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 <daniel.lezcano at free.fr>
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32 #include <sys/prctl.h>
37 lxc_log_define(lxc_caps
, lxc
);
41 #ifndef PR_CAPBSET_READ
42 #define PR_CAPBSET_READ 23
45 int lxc_caps_down(void)
50 /* when we are run as root, we don't want to play
51 * with the capabilities */
55 caps
= cap_get_proc();
57 ERROR("failed to cap_get_proc: %m");
61 ret
= cap_clear_flag(caps
, CAP_EFFECTIVE
);
63 ERROR("failed to cap_clear_flag: %m");
67 ret
= cap_set_proc(caps
);
69 ERROR("failed to cap_set_proc: %m");
84 /* when we are run as root, we don't want to play
85 * with the capabilities */
89 caps
= cap_get_proc();
91 ERROR("failed to cap_get_proc: %m");
95 for (cap
= 0; cap
<= CAP_LAST_CAP
; cap
++) {
97 cap_flag_value_t flag
;
99 ret
= cap_get_flag(caps
, cap
, CAP_PERMITTED
, &flag
);
101 if (errno
== EINVAL
) {
102 INFO("Last supported cap was %d", cap
-1);
105 ERROR("failed to cap_get_flag: %m");
110 ret
= cap_set_flag(caps
, CAP_EFFECTIVE
, 1, &cap
, flag
);
112 ERROR("failed to cap_set_flag: %m");
117 ret
= cap_set_proc(caps
);
119 ERROR("failed to cap_set_proc: %m");
128 int lxc_caps_init(void)
130 uid_t uid
= getuid();
131 gid_t gid
= getgid();
132 uid_t euid
= geteuid();
135 INFO("command is run as 'root'");
140 INFO("command is run as setuid root (uid : %d)", uid
);
142 if (prctl(PR_SET_KEEPCAPS
, 1)) {
143 ERROR("failed to 'PR_SET_KEEPCAPS': %m");
147 if (setresgid(gid
, gid
, gid
)) {
148 ERROR("failed to change gid to '%d': %m", gid
);
152 if (setresuid(uid
, uid
, uid
)) {
153 ERROR("failed to change uid to '%d': %m", uid
);
158 ERROR("failed to restore capabilities: %m");
164 INFO("command is run as user '%d'", uid
);
169 static int _real_caps_last_cap(void)
174 /* try to get the maximum capability over the kernel
175 * interface introduced in v3.2 */
176 fd
= open("/proc/sys/kernel/cap_last_cap", O_RDONLY
);
182 if ((n
= read(fd
, buf
, 31)) >= 0) {
185 result
= strtol(buf
, &ptr
, 10);
186 if (!ptr
|| (*ptr
!= '\0' && *ptr
!= '\n') || errno
!= 0)
193 /* try to get it manually by trying to get the status of
194 * each capability indiviually from the kernel */
197 while (prctl(PR_CAPBSET_READ
, cap
) >= 0) cap
++;
204 int lxc_caps_last_cap(void)
206 static int last_cap
= -1;
207 if (last_cap
< 0) last_cap
= _real_caps_last_cap();
212 bool lxc_cap_is_set(cap_value_t cap
, cap_flag_t flag
)
216 cap_flag_value_t flagval
;
218 caps
= cap_get_proc();
220 ERROR("Failed to perform cap_get_proc(): %s.", strerror(errno
));
224 ret
= cap_get_flag(caps
, cap
, flag
, &flagval
);
226 ERROR("Failed to perform cap_get_flag(): %s.", strerror(errno
));
232 return flagval
== CAP_SET
;