blob: 8cea18d25dba73777e58831a07890adc21519424 [file] [log] [blame] [edit]
/* Author: James Athey
*/
%module selinux
%{
#include "selinux/selinux.h"
%}
%pythoncode %{
import shutil, os, errno, stat
DISABLED = -1
PERMISSIVE = 0
ENFORCING = 1
def restorecon(path, recursive=False):
""" Restore SELinux context on a given path """
try:
mode = os.lstat(path)[stat.ST_MODE]
status, context = matchpathcon(path, mode)
except OSError:
path = os.path.realpath(os.path.expanduser(path))
mode = os.lstat(path)[stat.ST_MODE]
status, context = matchpathcon(path, mode)
if status == 0:
try:
status, oldcontext = lgetfilecon(path)
except OSError as e:
if e.errno != errno.ENODATA:
raise
oldcontext = None
if context != oldcontext:
lsetfilecon(path, context)
if recursive:
for root, dirs, files in os.walk(path):
for name in files + dirs:
restorecon(os.path.join(root, name))
def chcon(path, context, recursive=False):
""" Set the SELinux context on a given path """
lsetfilecon(path, context)
if recursive:
for root, dirs, files in os.walk(path):
for name in files + dirs:
lsetfilecon(os.path.join(root,name), context)
def copytree(src, dest):
""" An SELinux-friendly shutil.copytree method """
shutil.copytree(src, dest)
restorecon(dest, recursive=True)
def install(src, dest):
""" An SELinux-friendly shutil.move method """
shutil.move(src, dest)
restorecon(dest, recursive=True)
%}
/* security_get_boolean_names() typemap */
%typemap(argout) (char ***names, int *len) {
PyObject* list = PyList_New(*$2);
int i;
for (i = 0; i < *$2; i++) {
PyList_SetItem(list, i, PyBytes_FromString((*$1)[i]));
}
$result = SWIG_Python_AppendOutput($result, list);
}
/* return a sid along with the result */
%typemap(argout) (security_id_t * sid) {
if (*$1) {
%append_output(SWIG_NewPointerObj(*$1, $descriptor(security_id_t), 0));
} else {
Py_INCREF(Py_None);
%append_output(Py_None);
}
}
%typemap(in,numinputs=0) security_id_t *(security_id_t temp) {
$1 = &temp;
}
%typemap(in, numinputs=0) void *(char *temp=NULL) {
$1 = temp;
}
/* Makes security_compute_user() return a Python list of contexts */
%typemap(argout) (char ***con) {
PyObject* plist;
int i, len = 0;
if (*$1) {
while((*$1)[len])
len++;
plist = PyList_New(len);
for (i = 0; i < len; i++) {
PyList_SetItem(plist, i,
PyBytes_FromString((*$1)[i])
);
}
} else {
plist = PyList_New(0);
}
$result = SWIG_Python_AppendOutput($result, plist);
}
/* Makes functions in get_context_list.h return a Python list of contexts */
%typemap(argout) (char ***list) {
PyObject* plist;
int i;
if (*$1) {
plist = PyList_New(result);
for (i = 0; i < result; i++) {
PyList_SetItem(plist, i,
PyBytes_FromString((*$1)[i])
);
}
} else {
plist = PyList_New(0);
}
/* Only return the Python list, don't need to return the length anymore */
$result = plist;
}
%typemap(in,noblock=1,numinputs=0) char ** (char * temp = 0) {
$1 = &temp;
}
%typemap(freearg,match="in") char ** "";
%typemap(argout,noblock=1) char ** {
if (*$1) {
%append_output(SWIG_FromCharPtr(*$1));
freecon(*$1);
}
else {
Py_INCREF(Py_None);
%append_output(Py_None);
}
}
%typemap(in,noblock=1,numinputs=0) char ** (char * temp = 0) {
$1 = &temp;
}
%typemap(freearg,match="in") char ** "";
%typemap(argout,noblock=1) char ** {
if (*$1) {
%append_output(SWIG_FromCharPtr(*$1));
free(*$1);
}
else {
Py_INCREF(Py_None);
%append_output(Py_None);
}
}
%typemap(in) char * const [] {
int i, size;
PyObject * s;
if (!PySequence_Check($input)) {
PyErr_SetString(PyExc_ValueError, "Expected a sequence");
return NULL;
}
size = PySequence_Size($input);
$1 = (char**) malloc(size + 1);
for(i = 0; i < size; i++) {
if (!PyBytes_Check(PySequence_GetItem($input, i))) {
PyErr_SetString(PyExc_ValueError, "Sequence must contain only bytes");
return NULL;
}
}
for(i = 0; i < size; i++) {
s = PySequence_GetItem($input, i);
$1[i] = (char*) malloc(PyBytes_Size(s) + 1);
strcpy($1[i], PyBytes_AsString(s));
}
$1[size] = NULL;
}
%typemap(freearg,match="in") char * const [] {
int i = 0;
while($1[i]) {
free($1[i]);
i++;
}
free($1);
}
%include "selinuxswig_python_exception.i"
%include "selinuxswig.i"