Implemented native capability dropping, eliminated capsh dependency
[lxc-userspace.git] / setns.c
1 #include <Python.h>
2 #include <fcntl.h>
3 #include <stdio.h>
4 #include <asm/unistd.h>
5 #include <sys/mount.h>
6 #include <errno.h>
7 #include <sys/prctl.h>
8 #include <linux/capability.h>
9
10 static PyObject *
11 drop_caps(PyObject *self, PyObject *args)
12 {
13         unsigned int to_drop[128] = {CAP_NET_ADMIN,CAP_SYS_ADMIN,CAP_SYS_BOOT,CAP_MKNOD,CAP_MAC_ADMIN,CAP_SYS_MODULE};
14         unsigned int i;
15         for (i = 0;i<6;i++) {
16                 if (prctl(PR_CAPBSET_DROP, to_drop[i], 0, 0, 0) == -1) {
17                         perror("prctl");
18                         return Py_BuildValue("i", 2);
19                 }
20         }
21         return Py_BuildValue("i", 0);
22 }
23
24 static PyObject *
25 proc_mount(PyObject *self, PyObject *args)
26 {
27     int sts; 
28     sts = mount("none","/proc","proc",0,NULL);
29
30     return Py_BuildValue("i", sts);
31 }
32
33 static PyObject *
34 proc_umount(PyObject *self, PyObject *args)
35 {
36     int sts; 
37     sts = umount("/proc");
38
39     return Py_BuildValue("i", sts);
40 }
41
42 static PyObject *
43 chfscontext(PyObject *self, PyObject *args)
44 {
45     const char *filepath;
46     int sts;
47
48     if (!PyArg_ParseTuple(args, "s", &filepath))
49         return NULL;
50
51     int fd = open(filepath, O_RDONLY);
52     if (fd < 0) {
53         sts = -errno;
54         goto out;
55     }
56     
57     if (setns(fd, 0)) {
58         sts = -errno;
59     }
60     close(fd);
61     sts = 0;
62
63 out:
64     return Py_BuildValue("i", sts);
65 }
66
67 static PyObject *
68 chcontext(PyObject *self, PyObject *args)
69 {
70     const char *filepath;
71     int sts;
72
73     if (!PyArg_ParseTuple(args, "s", &filepath))
74         return NULL;
75
76     int fd = open(filepath, O_RDONLY);
77     if (fd < 0) {
78         sts = -errno;
79         goto out;
80     }
81     
82     if (setns(fd, 0)) {
83         sts = -errno;
84     }
85     close(fd);
86     sts = 0;
87
88 out:
89     return Py_BuildValue("i", sts);
90 }
91
92 static PyMethodDef SetnsMethods[] =
93 {
94          {"proc_mount", proc_mount, METH_VARARGS, "Mount a volume via the mount system call."},
95          {"proc_umount", proc_umount, METH_VARARGS, "Umount a volume via the umount system call."},
96          {"chcontext", chcontext, METH_VARARGS, "Switch into an lxc container."},
97          {"drop_caps", drop_caps, METH_VARARGS, "Drop dangerous capabilities."},
98          {"chfscontext", chfscontext, METH_VARARGS, "Switch into an lxc container."},
99               {NULL, NULL, 0, NULL}
100 };
101  
102 PyMODINIT_FUNC
103  
104 initsetns(void)
105 {
106          (void) Py_InitModule("setns", SetnsMethods);
107 }