~ubuntu-branches/ubuntu/quantal/lxc/quantal-201206191543

« back to all changes in this revision

Viewing changes to src/lxc/caps.c

  • Committer: Package Import Robot
  • Author(s): Daniel Baumann
  • Date: 2012-03-09 13:05:03 UTC
  • mto: (3.1.38 sid)
  • mto: This revision was merged to the branch mainline in revision 94.
  • Revision ID: package-import@ubuntu.com-20120309130503-j0prgw9tsp967bbv
Tags: upstream-0.8.0~rc1
ImportĀ upstreamĀ versionĀ 0.8.0~rc1

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
#define _GNU_SOURCE
25
25
#include <unistd.h>
 
26
#include <fcntl.h>
 
27
#include <stdlib.h>
 
28
#include <limits.h>
26
29
#include <sys/prctl.h>
27
30
#include <sys/capability.h>
28
31
 
167
170
 
168
171
        return 0;
169
172
}
 
173
 
 
174
static int _real_caps_last_cap(void)
 
175
{
 
176
        int fd;
 
177
        int result = -1;
 
178
 
 
179
        /* try to get the maximum capability over the kernel
 
180
        * interface introduced in v3.2 */
 
181
        fd = open("/proc/sys/kernel/cap_last_cap", O_RDONLY);
 
182
        if (fd >= 0) {
 
183
                char buf[32];
 
184
                char *ptr;
 
185
                int n;
 
186
 
 
187
                if ((n = read(fd, buf, 31)) >= 0) {
 
188
                        buf[n] = '\0';
 
189
                        result = strtol(buf, &ptr, 10);
 
190
                        if (!ptr || (*ptr != '\0' && *ptr != '\n') ||
 
191
                            result == LONG_MIN || result == LONG_MAX)
 
192
                                result = -1;
 
193
                }
 
194
 
 
195
                close(fd);
 
196
        }
 
197
 
 
198
        /* try to get it manually by trying to get the status of
 
199
        * each capability indiviually from the kernel */
 
200
        if (result < 0) {
 
201
                int cap = 0;
 
202
                while (prctl(PR_CAPBSET_READ, cap) >= 0) cap++;
 
203
                result = cap - 1;
 
204
        }
 
205
 
 
206
        return result;
 
207
}
 
208
 
 
209
int lxc_caps_last_cap(void)
 
210
{
 
211
        static int last_cap = -1;
 
212
        if (last_cap < 0) last_cap = _real_caps_last_cap();
 
213
 
 
214
        return last_cap;
 
215
}
 
216
 
 
217
/*
 
218
 * check if we have the caps needed to start a container.  returns 1 on
 
219
 * success, 0 on error.  (I'd prefer this be a bool, but am afraid that
 
220
 * might fail to build on some distros).
 
221
 */
 
222
int lxc_caps_check(void)
 
223
{
 
224
        uid_t uid = getuid();
 
225
        cap_t caps;
 
226
        cap_flag_value_t value;
 
227
        int i, ret;
 
228
 
 
229
        cap_value_t needed_caps[] = { CAP_SYS_ADMIN, CAP_NET_ADMIN, CAP_SETUID, CAP_SETGID };
 
230
 
 
231
#define NUMCAPS ((int) (sizeof(needed_caps) / sizeof(cap_t)))
 
232
 
 
233
        if (!uid)
 
234
                return 1;
 
235
 
 
236
        caps = cap_get_proc();
 
237
        if (!caps) {
 
238
                ERROR("failed to cap_get_proc: %m");
 
239
                return 0;
 
240
        }
 
241
 
 
242
        for (i=0; i<NUMCAPS; i++) {
 
243
                ret = cap_get_flag(caps, needed_caps[i], CAP_EFFECTIVE, &value);
 
244
                if (ret) {
 
245
                        ERROR("Failed to cap_get_flag: %m");
 
246
                        return 0;
 
247
                }
 
248
                if (!value) {
 
249
                        return 0;
 
250
                }
 
251
        }
 
252
 
 
253
        return 1;
 
254
}