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