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