• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Author: James Athey
2  */
3 
4 %module selinux
5 %{
6 	#include "selinux/selinux.h"
7 %}
8 
9 %pythoncode %{
10 
11 import shutil, os, stat
12 
13 DISABLED = -1
14 PERMISSIVE = 0
15 ENFORCING = 1
16 
17 def restorecon(path, recursive=False):
18     """ Restore SELinux context on a given path """
19 
20     try:
21         mode = os.lstat(path)[stat.ST_MODE]
22         status, context = matchpathcon(path, mode)
23     except OSError:
24         path = os.path.realpath(os.path.expanduser(path))
25         mode = os.lstat(path)[stat.ST_MODE]
26         status, context = matchpathcon(path, mode)
27 
28     if status == 0:
29         status, oldcontext = lgetfilecon(path)
30         if context != oldcontext:
31             lsetfilecon(path, context)
32 
33         if recursive:
34             for root, dirs, files in os.walk(path):
35                 for name in files + dirs:
36                    restorecon(os.path.join(root, name))
37 
38 def chcon(path, context, recursive=False):
39     """ Set the SELinux context on a given path """
40     lsetfilecon(path, context)
41     if recursive:
42         for root, dirs, files in os.walk(path):
43             for name in files + dirs:
44                lsetfilecon(os.path.join(root,name), context)
45 
46 def copytree(src, dest):
47     """ An SELinux-friendly shutil.copytree method """
48     shutil.copytree(src, dest)
49     restorecon(dest, recursive=True)
50 
51 def install(src, dest):
52     """ An SELinux-friendly shutil.move method """
53     shutil.move(src, dest)
54     restorecon(dest, recursive=True)
55 %}
56 
57 /* security_get_boolean_names() typemap */
58 %typemap(argout) (char ***names, int *len) {
59 	PyObject* list = PyList_New(*$2);
60 	int i;
61 	for (i = 0; i < *$2; i++) {
62 		PyList_SetItem(list, i, PyBytes_FromString((*$1)[i]));
63 	}
64 	$result = SWIG_Python_AppendOutput($result, list);
65 }
66 
67 /* return a sid along with the result */
68 %typemap(argout) (security_id_t * sid) {
69 	if (*$1) {
70                 %append_output(SWIG_NewPointerObj(*$1, $descriptor(security_id_t), 0));
71 	} else {
72 		Py_INCREF(Py_None);
73 		%append_output(Py_None);
74 	}
75 }
76 
77 %typemap(in,numinputs=0) security_id_t *(security_id_t temp) {
78   $1 = &temp;
79 }
80 
81 %typemap(in, numinputs=0) void *(char *temp=NULL) {
82 	$1 = temp;
83 }
84 
85 /* Makes security_compute_user() return a Python list of contexts */
86 %typemap(argout) (char ***con) {
87 	PyObject* plist;
88 	int i, len = 0;
89 
90 	if (*$1) {
91 		while((*$1)[len])
92 			len++;
93 		plist = PyList_New(len);
94 		for (i = 0; i < len; i++) {
95 			PyList_SetItem(plist, i,
96                                        PyBytes_FromString((*$1)[i])
97                                        );
98 		}
99 	} else {
100 		plist = PyList_New(0);
101 	}
102 
103 	$result = SWIG_Python_AppendOutput($result, plist);
104 }
105 
106 /* Makes functions in get_context_list.h return a Python list of contexts */
107 %typemap(argout) (char ***list) {
108 	PyObject* plist;
109 	int i;
110 
111 	if (*$1) {
112 		plist = PyList_New(result);
113 		for (i = 0; i < result; i++) {
114 			PyList_SetItem(plist, i,
115                                        PyBytes_FromString((*$1)[i])
116                                        );
117 		}
118 	} else {
119 		plist = PyList_New(0);
120 	}
121 	/* Only return the Python list, don't need to return the length anymore */
122 	$result = plist;
123 }
124 
125 %typemap(in,noblock=1,numinputs=0) char ** (char * temp = 0) {
126 	$1 = &temp;
127 }
128 %typemap(freearg,match="in") char ** "";
129 %typemap(argout,noblock=1) char ** {
130 	if (*$1) {
131 		%append_output(SWIG_FromCharPtr(*$1));
132 		freecon(*$1);
133 	}
134 	else {
135 		Py_INCREF(Py_None);
136 		%append_output(Py_None);
137 	}
138 }
139 
140 %typemap(in,noblock=1,numinputs=0) char ** (char * temp = 0) {
141 	$1 = &temp;
142 }
143 %typemap(freearg,match="in") char ** "";
144 %typemap(argout,noblock=1) char ** {
145 	if (*$1) {
146 		%append_output(SWIG_FromCharPtr(*$1));
147 		free(*$1);
148 	}
149 	else {
150 		Py_INCREF(Py_None);
151 		%append_output(Py_None);
152 	}
153 }
154 
155 %typemap(in) char * const [] {
156 	int i, size;
157 	PyObject * s;
158 
159 	if (!PySequence_Check($input)) {
160 		PyErr_SetString(PyExc_ValueError, "Expected a sequence");
161 		return NULL;
162 	}
163 
164 	size = PySequence_Size($input);
165 
166 	$1 = (char**) malloc(size + 1);
167 
168 	for(i = 0; i < size; i++) {
169 		if (!PyBytes_Check(PySequence_GetItem($input, i))) {
170 			PyErr_SetString(PyExc_ValueError, "Sequence must contain only bytes");
171 
172 			return NULL;
173 		}
174 
175 	}
176 
177 	for(i = 0; i < size; i++) {
178 		s = PySequence_GetItem($input, i);
179 
180 		$1[i] = (char*) malloc(PyBytes_Size(s) + 1);
181 		strcpy($1[i], PyBytes_AsString(s));
182 
183 	}
184 	$1[size] = NULL;
185 }
186 
187 %typemap(freearg,match="in") char * const [] {
188 	int i = 0;
189 	while($1[i]) {
190 		free($1[i]);
191 		i++;
192 	}
193 	free($1);
194 }
195 
196 %include "selinuxswig_python_exception.i"
197 %include "selinuxswig.i"
198