Home | History | Annotate | Download | only in src
      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