16cd6a6acSopenharmony_ci/* Workaround for http://bugs.python.org/issue4835 */ 26cd6a6acSopenharmony_ci#ifndef SIZEOF_SOCKET_T 36cd6a6acSopenharmony_ci#define SIZEOF_SOCKET_T SIZEOF_INT 46cd6a6acSopenharmony_ci#endif 56cd6a6acSopenharmony_ci 66cd6a6acSopenharmony_ci#include <Python.h> 76cd6a6acSopenharmony_ci#include <unistd.h> 86cd6a6acSopenharmony_ci#include <stdlib.h> 96cd6a6acSopenharmony_ci#include <ctype.h> 106cd6a6acSopenharmony_ci#include <errno.h> 116cd6a6acSopenharmony_ci#include <getopt.h> 126cd6a6acSopenharmony_ci#include <limits.h> 136cd6a6acSopenharmony_ci#include <sepol/sepol.h> 146cd6a6acSopenharmony_ci#include <sepol/policydb.h> 156cd6a6acSopenharmony_ci#include <sepol/policydb/services.h> 166cd6a6acSopenharmony_ci#include <selinux/selinux.h> 176cd6a6acSopenharmony_ci 186cd6a6acSopenharmony_ci#define UNKNOWN -1 196cd6a6acSopenharmony_ci#define BADSCON -2 206cd6a6acSopenharmony_ci#define BADTCON -3 216cd6a6acSopenharmony_ci#define BADTCLASS -4 226cd6a6acSopenharmony_ci#define BADPERM -5 236cd6a6acSopenharmony_ci#define BADCOMPUTE -6 246cd6a6acSopenharmony_ci#define NOPOLICY -7 256cd6a6acSopenharmony_ci#define ALLOW 0 266cd6a6acSopenharmony_ci#define DONTAUDIT 1 276cd6a6acSopenharmony_ci#define TERULE 2 286cd6a6acSopenharmony_ci#define BOOLEAN 3 296cd6a6acSopenharmony_ci#define CONSTRAINT 4 306cd6a6acSopenharmony_ci#define RBAC 5 316cd6a6acSopenharmony_ci#define BOUNDS 6 326cd6a6acSopenharmony_ci 336cd6a6acSopenharmony_cistruct boolean_t { 346cd6a6acSopenharmony_ci char *name; 356cd6a6acSopenharmony_ci int active; 366cd6a6acSopenharmony_ci}; 376cd6a6acSopenharmony_ci 386cd6a6acSopenharmony_cistatic struct boolean_t **boollist = NULL; 396cd6a6acSopenharmony_cistatic int boolcnt = 0; 406cd6a6acSopenharmony_ci 416cd6a6acSopenharmony_cistruct avc_t { 426cd6a6acSopenharmony_ci sepol_handle_t *handle; 436cd6a6acSopenharmony_ci sepol_policydb_t *policydb; 446cd6a6acSopenharmony_ci sepol_security_id_t ssid; 456cd6a6acSopenharmony_ci sepol_security_id_t tsid; 466cd6a6acSopenharmony_ci sepol_security_class_t tclass; 476cd6a6acSopenharmony_ci sepol_access_vector_t av; 486cd6a6acSopenharmony_ci}; 496cd6a6acSopenharmony_ci 506cd6a6acSopenharmony_cistatic struct avc_t *avc = NULL; 516cd6a6acSopenharmony_ci 526cd6a6acSopenharmony_cistatic sidtab_t sidtab; 536cd6a6acSopenharmony_ci 546cd6a6acSopenharmony_cistatic int load_booleans(const sepol_bool_t * boolean, 556cd6a6acSopenharmony_ci void *arg __attribute__ ((__unused__))) 566cd6a6acSopenharmony_ci{ 576cd6a6acSopenharmony_ci boollist[boolcnt] = malloc(sizeof(struct boolean_t)); 586cd6a6acSopenharmony_ci boollist[boolcnt]->name = strdup(sepol_bool_get_name(boolean)); 596cd6a6acSopenharmony_ci boollist[boolcnt]->active = sepol_bool_get_value(boolean); 606cd6a6acSopenharmony_ci boolcnt++; 616cd6a6acSopenharmony_ci return 0; 626cd6a6acSopenharmony_ci} 636cd6a6acSopenharmony_ci 646cd6a6acSopenharmony_cistatic int check_booleans(struct boolean_t **bools) 656cd6a6acSopenharmony_ci{ 666cd6a6acSopenharmony_ci char errormsg[PATH_MAX]; 676cd6a6acSopenharmony_ci struct sepol_av_decision avd; 686cd6a6acSopenharmony_ci unsigned int reason; 696cd6a6acSopenharmony_ci int rc; 706cd6a6acSopenharmony_ci int i; 716cd6a6acSopenharmony_ci sepol_bool_key_t *key = NULL; 726cd6a6acSopenharmony_ci sepol_bool_t *boolean = NULL; 736cd6a6acSopenharmony_ci int fcnt = 0; 746cd6a6acSopenharmony_ci int *foundlist = calloc(boolcnt, sizeof(int)); 756cd6a6acSopenharmony_ci if (!foundlist) { 766cd6a6acSopenharmony_ci PyErr_SetString( PyExc_MemoryError, "Out of memory\n"); 776cd6a6acSopenharmony_ci return fcnt; 786cd6a6acSopenharmony_ci } 796cd6a6acSopenharmony_ci for (i = 0; i < boolcnt; i++) { 806cd6a6acSopenharmony_ci char *name = boollist[i]->name; 816cd6a6acSopenharmony_ci int active = boollist[i]->active; 826cd6a6acSopenharmony_ci rc = sepol_bool_key_create(avc->handle, name, &key); 836cd6a6acSopenharmony_ci if (rc < 0) { 846cd6a6acSopenharmony_ci PyErr_SetString( PyExc_RuntimeError, 856cd6a6acSopenharmony_ci "Could not create boolean key.\n"); 866cd6a6acSopenharmony_ci break; 876cd6a6acSopenharmony_ci } 886cd6a6acSopenharmony_ci rc = sepol_bool_query(avc->handle, 896cd6a6acSopenharmony_ci avc->policydb, 906cd6a6acSopenharmony_ci key, &boolean); 916cd6a6acSopenharmony_ci 926cd6a6acSopenharmony_ci if (rc < 0) { 936cd6a6acSopenharmony_ci snprintf(errormsg, sizeof(errormsg), 946cd6a6acSopenharmony_ci "Could not find boolean %s.\n", name); 956cd6a6acSopenharmony_ci PyErr_SetString( PyExc_RuntimeError, errormsg); 966cd6a6acSopenharmony_ci break; 976cd6a6acSopenharmony_ci } 986cd6a6acSopenharmony_ci 996cd6a6acSopenharmony_ci sepol_bool_set_value(boolean, !active); 1006cd6a6acSopenharmony_ci 1016cd6a6acSopenharmony_ci rc = sepol_bool_set(avc->handle, 1026cd6a6acSopenharmony_ci avc->policydb, 1036cd6a6acSopenharmony_ci key, boolean); 1046cd6a6acSopenharmony_ci if (rc < 0) { 1056cd6a6acSopenharmony_ci snprintf(errormsg, sizeof(errormsg), 1066cd6a6acSopenharmony_ci "Could not set boolean data %s.\n", name); 1076cd6a6acSopenharmony_ci PyErr_SetString( PyExc_RuntimeError, errormsg); 1086cd6a6acSopenharmony_ci break; 1096cd6a6acSopenharmony_ci } 1106cd6a6acSopenharmony_ci 1116cd6a6acSopenharmony_ci /* Reproduce the computation. */ 1126cd6a6acSopenharmony_ci rc = sepol_compute_av_reason(avc->ssid, avc->tsid, avc->tclass, 1136cd6a6acSopenharmony_ci avc->av, &avd, &reason); 1146cd6a6acSopenharmony_ci if (rc < 0) { 1156cd6a6acSopenharmony_ci snprintf(errormsg, sizeof(errormsg), 1166cd6a6acSopenharmony_ci "Error during access vector computation, skipping..."); 1176cd6a6acSopenharmony_ci PyErr_SetString( PyExc_RuntimeError, errormsg); 1186cd6a6acSopenharmony_ci 1196cd6a6acSopenharmony_ci sepol_bool_free(boolean); 1206cd6a6acSopenharmony_ci break; 1216cd6a6acSopenharmony_ci } else { 1226cd6a6acSopenharmony_ci if (!reason) { 1236cd6a6acSopenharmony_ci foundlist[fcnt] = i; 1246cd6a6acSopenharmony_ci fcnt++; 1256cd6a6acSopenharmony_ci } 1266cd6a6acSopenharmony_ci sepol_bool_set_value(boolean, active); 1276cd6a6acSopenharmony_ci rc = sepol_bool_set(avc->handle, 1286cd6a6acSopenharmony_ci avc->policydb, key, 1296cd6a6acSopenharmony_ci boolean); 1306cd6a6acSopenharmony_ci if (rc < 0) { 1316cd6a6acSopenharmony_ci snprintf(errormsg, sizeof(errormsg), 1326cd6a6acSopenharmony_ci "Could not set boolean data %s.\n", 1336cd6a6acSopenharmony_ci name); 1346cd6a6acSopenharmony_ci 1356cd6a6acSopenharmony_ci PyErr_SetString( PyExc_RuntimeError, errormsg); 1366cd6a6acSopenharmony_ci break; 1376cd6a6acSopenharmony_ci } 1386cd6a6acSopenharmony_ci } 1396cd6a6acSopenharmony_ci sepol_bool_free(boolean); 1406cd6a6acSopenharmony_ci sepol_bool_key_free(key); 1416cd6a6acSopenharmony_ci key = NULL; 1426cd6a6acSopenharmony_ci boolean = NULL; 1436cd6a6acSopenharmony_ci } 1446cd6a6acSopenharmony_ci if (key) 1456cd6a6acSopenharmony_ci sepol_bool_key_free(key); 1466cd6a6acSopenharmony_ci 1476cd6a6acSopenharmony_ci if (boolean) 1486cd6a6acSopenharmony_ci sepol_bool_free(boolean); 1496cd6a6acSopenharmony_ci 1506cd6a6acSopenharmony_ci if (fcnt > 0) { 1516cd6a6acSopenharmony_ci *bools = calloc(sizeof(struct boolean_t), fcnt + 1); 1526cd6a6acSopenharmony_ci struct boolean_t *b = *bools; 1536cd6a6acSopenharmony_ci for (i = 0; i < fcnt; i++) { 1546cd6a6acSopenharmony_ci int ctr = foundlist[i]; 1556cd6a6acSopenharmony_ci b[i].name = strdup(boollist[ctr]->name); 1566cd6a6acSopenharmony_ci b[i].active = !boollist[ctr]->active; 1576cd6a6acSopenharmony_ci } 1586cd6a6acSopenharmony_ci } 1596cd6a6acSopenharmony_ci free(foundlist); 1606cd6a6acSopenharmony_ci return fcnt; 1616cd6a6acSopenharmony_ci} 1626cd6a6acSopenharmony_ci 1636cd6a6acSopenharmony_cistatic PyObject *finish(PyObject *self __attribute__((unused)), PyObject *args) { 1646cd6a6acSopenharmony_ci PyObject *result = 0; 1656cd6a6acSopenharmony_ci 1666cd6a6acSopenharmony_ci if (PyArg_ParseTuple(args,(char *)":finish")) { 1676cd6a6acSopenharmony_ci int i = 0; 1686cd6a6acSopenharmony_ci if (! avc) 1696cd6a6acSopenharmony_ci Py_RETURN_NONE; 1706cd6a6acSopenharmony_ci 1716cd6a6acSopenharmony_ci for (i = 0; i < boolcnt; i++) { 1726cd6a6acSopenharmony_ci free(boollist[i]->name); 1736cd6a6acSopenharmony_ci free(boollist[i]); 1746cd6a6acSopenharmony_ci } 1756cd6a6acSopenharmony_ci free(boollist); 1766cd6a6acSopenharmony_ci sepol_sidtab_shutdown(&sidtab); 1776cd6a6acSopenharmony_ci sepol_sidtab_destroy(&sidtab); 1786cd6a6acSopenharmony_ci sepol_policydb_free(avc->policydb); 1796cd6a6acSopenharmony_ci sepol_handle_destroy(avc->handle); 1806cd6a6acSopenharmony_ci free(avc); 1816cd6a6acSopenharmony_ci avc = NULL; 1826cd6a6acSopenharmony_ci boollist = NULL; 1836cd6a6acSopenharmony_ci boolcnt = 0; 1846cd6a6acSopenharmony_ci 1856cd6a6acSopenharmony_ci /* Boilerplate to return "None" */ 1866cd6a6acSopenharmony_ci Py_RETURN_NONE; 1876cd6a6acSopenharmony_ci } 1886cd6a6acSopenharmony_ci return result; 1896cd6a6acSopenharmony_ci} 1906cd6a6acSopenharmony_ci 1916cd6a6acSopenharmony_ci 1926cd6a6acSopenharmony_cistatic int __policy_init(const char *init_path) 1936cd6a6acSopenharmony_ci{ 1946cd6a6acSopenharmony_ci FILE *fp = NULL; 1956cd6a6acSopenharmony_ci const char *curpolicy; 1966cd6a6acSopenharmony_ci char errormsg[PATH_MAX+1024+20]; 1976cd6a6acSopenharmony_ci struct sepol_policy_file *pf = NULL; 1986cd6a6acSopenharmony_ci int rc; 1996cd6a6acSopenharmony_ci unsigned int cnt; 2006cd6a6acSopenharmony_ci 2016cd6a6acSopenharmony_ci if (init_path) { 2026cd6a6acSopenharmony_ci curpolicy = init_path; 2036cd6a6acSopenharmony_ci } else { 2046cd6a6acSopenharmony_ci curpolicy = selinux_current_policy_path(); 2056cd6a6acSopenharmony_ci if (!curpolicy) { 2066cd6a6acSopenharmony_ci /* SELinux disabled, must use -p option. */ 2076cd6a6acSopenharmony_ci snprintf(errormsg, sizeof(errormsg), 2086cd6a6acSopenharmony_ci "You must specify the -p option with the path to the policy file.\n"); 2096cd6a6acSopenharmony_ci PyErr_SetString( PyExc_ValueError, errormsg); 2106cd6a6acSopenharmony_ci return 1; 2116cd6a6acSopenharmony_ci } 2126cd6a6acSopenharmony_ci } 2136cd6a6acSopenharmony_ci 2146cd6a6acSopenharmony_ci fp = fopen(curpolicy, "re"); 2156cd6a6acSopenharmony_ci if (!fp) { 2166cd6a6acSopenharmony_ci snprintf(errormsg, sizeof(errormsg), 2176cd6a6acSopenharmony_ci "unable to open %s: %m\n", 2186cd6a6acSopenharmony_ci curpolicy); 2196cd6a6acSopenharmony_ci PyErr_SetString( PyExc_ValueError, errormsg); 2206cd6a6acSopenharmony_ci return 1; 2216cd6a6acSopenharmony_ci } 2226cd6a6acSopenharmony_ci 2236cd6a6acSopenharmony_ci avc = calloc(sizeof(struct avc_t), 1); 2246cd6a6acSopenharmony_ci if (!avc) { 2256cd6a6acSopenharmony_ci PyErr_SetString( PyExc_MemoryError, "Out of memory\n"); 2266cd6a6acSopenharmony_ci fclose(fp); 2276cd6a6acSopenharmony_ci return 1; 2286cd6a6acSopenharmony_ci } 2296cd6a6acSopenharmony_ci 2306cd6a6acSopenharmony_ci /* Set up a policydb directly so that we can mutate it later 2316cd6a6acSopenharmony_ci for testing what booleans might have allowed the access. 2326cd6a6acSopenharmony_ci Otherwise, we'd just use sepol_set_policydb_from_file() here. */ 2336cd6a6acSopenharmony_ci if (sepol_policy_file_create(&pf) || 2346cd6a6acSopenharmony_ci sepol_policydb_create(&avc->policydb)) { 2356cd6a6acSopenharmony_ci snprintf(errormsg, sizeof(errormsg), 2366cd6a6acSopenharmony_ci "policydb_init failed: %m\n"); 2376cd6a6acSopenharmony_ci PyErr_SetString( PyExc_RuntimeError, errormsg); 2386cd6a6acSopenharmony_ci goto err; 2396cd6a6acSopenharmony_ci } 2406cd6a6acSopenharmony_ci sepol_policy_file_set_fp(pf, fp); 2416cd6a6acSopenharmony_ci if (sepol_policydb_read(avc->policydb, pf)) { 2426cd6a6acSopenharmony_ci snprintf(errormsg, sizeof(errormsg), 2436cd6a6acSopenharmony_ci "invalid binary policy %s\n", curpolicy); 2446cd6a6acSopenharmony_ci PyErr_SetString( PyExc_ValueError, errormsg); 2456cd6a6acSopenharmony_ci goto err; 2466cd6a6acSopenharmony_ci } 2476cd6a6acSopenharmony_ci fclose(fp); 2486cd6a6acSopenharmony_ci fp = NULL; 2496cd6a6acSopenharmony_ci sepol_set_policydb(&avc->policydb->p); 2506cd6a6acSopenharmony_ci avc->handle = sepol_handle_create(); 2516cd6a6acSopenharmony_ci /* Turn off messages */ 2526cd6a6acSopenharmony_ci sepol_msg_set_callback(avc->handle, NULL, NULL); 2536cd6a6acSopenharmony_ci 2546cd6a6acSopenharmony_ci rc = sepol_bool_count(avc->handle, 2556cd6a6acSopenharmony_ci avc->policydb, &cnt); 2566cd6a6acSopenharmony_ci if (rc < 0) { 2576cd6a6acSopenharmony_ci PyErr_SetString( PyExc_RuntimeError, "unable to get bool count\n"); 2586cd6a6acSopenharmony_ci goto err; 2596cd6a6acSopenharmony_ci } 2606cd6a6acSopenharmony_ci 2616cd6a6acSopenharmony_ci boollist = calloc(cnt, sizeof(*boollist)); 2626cd6a6acSopenharmony_ci if (!boollist) { 2636cd6a6acSopenharmony_ci PyErr_SetString( PyExc_MemoryError, "Out of memory\n"); 2646cd6a6acSopenharmony_ci goto err; 2656cd6a6acSopenharmony_ci } 2666cd6a6acSopenharmony_ci 2676cd6a6acSopenharmony_ci sepol_bool_iterate(avc->handle, avc->policydb, 2686cd6a6acSopenharmony_ci load_booleans, NULL); 2696cd6a6acSopenharmony_ci 2706cd6a6acSopenharmony_ci /* Initialize the sidtab for subsequent use by sepol_context_to_sid 2716cd6a6acSopenharmony_ci and sepol_compute_av_reason. */ 2726cd6a6acSopenharmony_ci rc = sepol_sidtab_init(&sidtab); 2736cd6a6acSopenharmony_ci if (rc < 0) { 2746cd6a6acSopenharmony_ci PyErr_SetString( PyExc_RuntimeError, "unable to init sidtab\n"); 2756cd6a6acSopenharmony_ci goto err; 2766cd6a6acSopenharmony_ci } 2776cd6a6acSopenharmony_ci sepol_set_sidtab(&sidtab); 2786cd6a6acSopenharmony_ci return 0; 2796cd6a6acSopenharmony_ci 2806cd6a6acSopenharmony_cierr: 2816cd6a6acSopenharmony_ci if (boollist) 2826cd6a6acSopenharmony_ci free(boollist); 2836cd6a6acSopenharmony_ci if (avc){ 2846cd6a6acSopenharmony_ci if (avc->handle) 2856cd6a6acSopenharmony_ci sepol_handle_destroy(avc->handle); 2866cd6a6acSopenharmony_ci if (avc->policydb) 2876cd6a6acSopenharmony_ci sepol_policydb_free(avc->policydb); 2886cd6a6acSopenharmony_ci free(avc); 2896cd6a6acSopenharmony_ci } 2906cd6a6acSopenharmony_ci if (pf) 2916cd6a6acSopenharmony_ci sepol_policy_file_free(pf); 2926cd6a6acSopenharmony_ci if (fp) 2936cd6a6acSopenharmony_ci fclose(fp); 2946cd6a6acSopenharmony_ci return 1; 2956cd6a6acSopenharmony_ci} 2966cd6a6acSopenharmony_ci 2976cd6a6acSopenharmony_cistatic PyObject *init(PyObject *self __attribute__((unused)), PyObject *args) { 2986cd6a6acSopenharmony_ci int result; 2996cd6a6acSopenharmony_ci char *init_path = NULL; 3006cd6a6acSopenharmony_ci if (avc) { 3016cd6a6acSopenharmony_ci PyErr_SetString( PyExc_RuntimeError, "init called multiple times"); 3026cd6a6acSopenharmony_ci return NULL; 3036cd6a6acSopenharmony_ci } 3046cd6a6acSopenharmony_ci if (!PyArg_ParseTuple(args,(char *)"|s:policy_init",&init_path)) 3056cd6a6acSopenharmony_ci return NULL; 3066cd6a6acSopenharmony_ci result = __policy_init(init_path); 3076cd6a6acSopenharmony_ci return Py_BuildValue("i", result); 3086cd6a6acSopenharmony_ci} 3096cd6a6acSopenharmony_ci 3106cd6a6acSopenharmony_ci#define RETURN(X) \ 3116cd6a6acSopenharmony_ci { \ 3126cd6a6acSopenharmony_ci return Py_BuildValue("iO", (X), Py_None); \ 3136cd6a6acSopenharmony_ci } 3146cd6a6acSopenharmony_ci 3156cd6a6acSopenharmony_cistatic PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args) { 3166cd6a6acSopenharmony_ci char *reason_buf = NULL; 3176cd6a6acSopenharmony_ci char * scon; 3186cd6a6acSopenharmony_ci char * tcon; 3196cd6a6acSopenharmony_ci char *tclassstr; 3206cd6a6acSopenharmony_ci PyObject *listObj; 3216cd6a6acSopenharmony_ci PyObject *strObj; 3226cd6a6acSopenharmony_ci int numlines; 3236cd6a6acSopenharmony_ci struct boolean_t *bools; 3246cd6a6acSopenharmony_ci unsigned int reason; 3256cd6a6acSopenharmony_ci sepol_security_id_t ssid, tsid; 3266cd6a6acSopenharmony_ci sepol_security_class_t tclass; 3276cd6a6acSopenharmony_ci sepol_access_vector_t perm, av; 3286cd6a6acSopenharmony_ci struct sepol_av_decision avd; 3296cd6a6acSopenharmony_ci int rc; 3306cd6a6acSopenharmony_ci int i = 0; 3316cd6a6acSopenharmony_ci 3326cd6a6acSopenharmony_ci if (!PyArg_ParseTuple(args,(char *)"sssO!:audit2why",&scon,&tcon,&tclassstr,&PyList_Type, &listObj)) 3336cd6a6acSopenharmony_ci return NULL; 3346cd6a6acSopenharmony_ci 3356cd6a6acSopenharmony_ci /* get the number of lines passed to us */ 3366cd6a6acSopenharmony_ci numlines = PyList_Size(listObj); 3376cd6a6acSopenharmony_ci 3386cd6a6acSopenharmony_ci /* should raise an error here. */ 3396cd6a6acSopenharmony_ci if (numlines < 0) return NULL; /* Not a list */ 3406cd6a6acSopenharmony_ci 3416cd6a6acSopenharmony_ci if (!avc) 3426cd6a6acSopenharmony_ci RETURN(NOPOLICY) 3436cd6a6acSopenharmony_ci 3446cd6a6acSopenharmony_ci rc = sepol_context_to_sid(scon, strlen(scon) + 1, &ssid); 3456cd6a6acSopenharmony_ci if (rc < 0) 3466cd6a6acSopenharmony_ci RETURN(BADSCON) 3476cd6a6acSopenharmony_ci 3486cd6a6acSopenharmony_ci rc = sepol_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 3496cd6a6acSopenharmony_ci if (rc < 0) 3506cd6a6acSopenharmony_ci RETURN(BADTCON) 3516cd6a6acSopenharmony_ci 3526cd6a6acSopenharmony_ci rc = sepol_string_to_security_class(tclassstr, &tclass); 3536cd6a6acSopenharmony_ci if (rc < 0) 3546cd6a6acSopenharmony_ci RETURN(BADTCLASS) 3556cd6a6acSopenharmony_ci 3566cd6a6acSopenharmony_ci /* Convert the permission list to an AV. */ 3576cd6a6acSopenharmony_ci av = 0; 3586cd6a6acSopenharmony_ci 3596cd6a6acSopenharmony_ci /* iterate over items of the list, grabbing strings, and parsing 3606cd6a6acSopenharmony_ci for numbers */ 3616cd6a6acSopenharmony_ci for (i = 0; i < numlines; i++){ 3626cd6a6acSopenharmony_ci const char *permstr; 3636cd6a6acSopenharmony_ci 3646cd6a6acSopenharmony_ci /* grab the string object from the next element of the list */ 3656cd6a6acSopenharmony_ci strObj = PyList_GetItem(listObj, i); /* Can't fail */ 3666cd6a6acSopenharmony_ci 3676cd6a6acSopenharmony_ci /* make it a string */ 3686cd6a6acSopenharmony_ci#if PY_MAJOR_VERSION >= 3 3696cd6a6acSopenharmony_ci permstr = _PyUnicode_AsString( strObj ); 3706cd6a6acSopenharmony_ci#else 3716cd6a6acSopenharmony_ci permstr = PyString_AsString( strObj ); 3726cd6a6acSopenharmony_ci#endif 3736cd6a6acSopenharmony_ci 3746cd6a6acSopenharmony_ci rc = sepol_string_to_av_perm(tclass, permstr, &perm); 3756cd6a6acSopenharmony_ci if (rc < 0) 3766cd6a6acSopenharmony_ci RETURN(BADPERM) 3776cd6a6acSopenharmony_ci 3786cd6a6acSopenharmony_ci av |= perm; 3796cd6a6acSopenharmony_ci } 3806cd6a6acSopenharmony_ci 3816cd6a6acSopenharmony_ci /* Reproduce the computation. */ 3826cd6a6acSopenharmony_ci rc = sepol_compute_av_reason_buffer(ssid, tsid, tclass, av, &avd, &reason, &reason_buf, 0); 3836cd6a6acSopenharmony_ci if (rc < 0) 3846cd6a6acSopenharmony_ci RETURN(BADCOMPUTE) 3856cd6a6acSopenharmony_ci 3866cd6a6acSopenharmony_ci if (!reason) 3876cd6a6acSopenharmony_ci RETURN(ALLOW) 3886cd6a6acSopenharmony_ci 3896cd6a6acSopenharmony_ci if (reason & SEPOL_COMPUTEAV_TE) { 3906cd6a6acSopenharmony_ci avc->ssid = ssid; 3916cd6a6acSopenharmony_ci avc->tsid = tsid; 3926cd6a6acSopenharmony_ci avc->tclass = tclass; 3936cd6a6acSopenharmony_ci avc->av = av; 3946cd6a6acSopenharmony_ci if (check_booleans(&bools) == 0) { 3956cd6a6acSopenharmony_ci if (av & ~avd.auditdeny) { 3966cd6a6acSopenharmony_ci RETURN(DONTAUDIT) 3976cd6a6acSopenharmony_ci } else { 3986cd6a6acSopenharmony_ci RETURN(TERULE) 3996cd6a6acSopenharmony_ci } 4006cd6a6acSopenharmony_ci } else { 4016cd6a6acSopenharmony_ci PyObject *outboollist; 4026cd6a6acSopenharmony_ci struct boolean_t *b = bools; 4036cd6a6acSopenharmony_ci int len = 0; 4046cd6a6acSopenharmony_ci while (b->name) { 4056cd6a6acSopenharmony_ci len++; b++; 4066cd6a6acSopenharmony_ci } 4076cd6a6acSopenharmony_ci b = bools; 4086cd6a6acSopenharmony_ci outboollist = PyList_New(len); 4096cd6a6acSopenharmony_ci len = 0; 4106cd6a6acSopenharmony_ci while(b->name) { 4116cd6a6acSopenharmony_ci PyObject *bool_ = Py_BuildValue("(si)", b->name, b->active); 4126cd6a6acSopenharmony_ci PyList_SetItem(outboollist, len++, bool_); 4136cd6a6acSopenharmony_ci b++; 4146cd6a6acSopenharmony_ci } 4156cd6a6acSopenharmony_ci free(bools); 4166cd6a6acSopenharmony_ci /* 'N' steals the reference to outboollist */ 4176cd6a6acSopenharmony_ci return Py_BuildValue("iN", BOOLEAN, outboollist); 4186cd6a6acSopenharmony_ci } 4196cd6a6acSopenharmony_ci } 4206cd6a6acSopenharmony_ci 4216cd6a6acSopenharmony_ci if (reason & SEPOL_COMPUTEAV_CONS) { 4226cd6a6acSopenharmony_ci if (reason_buf) { 4236cd6a6acSopenharmony_ci PyObject *result = NULL; 4246cd6a6acSopenharmony_ci result = Py_BuildValue("is", CONSTRAINT, reason_buf); 4256cd6a6acSopenharmony_ci free(reason_buf); 4266cd6a6acSopenharmony_ci return result; 4276cd6a6acSopenharmony_ci } 4286cd6a6acSopenharmony_ci RETURN(CONSTRAINT) 4296cd6a6acSopenharmony_ci } 4306cd6a6acSopenharmony_ci 4316cd6a6acSopenharmony_ci if (reason & SEPOL_COMPUTEAV_RBAC) 4326cd6a6acSopenharmony_ci RETURN(RBAC) 4336cd6a6acSopenharmony_ci 4346cd6a6acSopenharmony_ci if (reason & SEPOL_COMPUTEAV_BOUNDS) 4356cd6a6acSopenharmony_ci RETURN(BOUNDS) 4366cd6a6acSopenharmony_ci 4376cd6a6acSopenharmony_ci RETURN(BADCOMPUTE) 4386cd6a6acSopenharmony_ci} 4396cd6a6acSopenharmony_ci 4406cd6a6acSopenharmony_cistatic PyMethodDef audit2whyMethods[] = { 4416cd6a6acSopenharmony_ci {"init", init, METH_VARARGS, 4426cd6a6acSopenharmony_ci "Initialize policy database."}, 4436cd6a6acSopenharmony_ci {"analyze", analyze, METH_VARARGS, 4446cd6a6acSopenharmony_ci "Analyze AVC."}, 4456cd6a6acSopenharmony_ci {"finish", finish, METH_VARARGS, 4466cd6a6acSopenharmony_ci "Finish using policy, free memory."}, 4476cd6a6acSopenharmony_ci {NULL, NULL, 0, NULL} /* Sentinel */ 4486cd6a6acSopenharmony_ci}; 4496cd6a6acSopenharmony_ci 4506cd6a6acSopenharmony_ci#if PY_MAJOR_VERSION >= 3 4516cd6a6acSopenharmony_ci/* Module-initialization logic specific to Python 3 */ 4526cd6a6acSopenharmony_cistatic struct PyModuleDef moduledef = { 4536cd6a6acSopenharmony_ci PyModuleDef_HEAD_INIT, 4546cd6a6acSopenharmony_ci "audit2why", 4556cd6a6acSopenharmony_ci NULL, 4566cd6a6acSopenharmony_ci 0, 4576cd6a6acSopenharmony_ci audit2whyMethods, 4586cd6a6acSopenharmony_ci NULL, 4596cd6a6acSopenharmony_ci NULL, 4606cd6a6acSopenharmony_ci NULL, 4616cd6a6acSopenharmony_ci NULL 4626cd6a6acSopenharmony_ci}; 4636cd6a6acSopenharmony_ci 4646cd6a6acSopenharmony_ciPyMODINIT_FUNC PyInit_audit2why(void); /* silence -Wmissing-prototypes */ 4656cd6a6acSopenharmony_ciPyMODINIT_FUNC PyInit_audit2why(void) 4666cd6a6acSopenharmony_ci#else 4676cd6a6acSopenharmony_ciPyMODINIT_FUNC initaudit2why(void); /* silence -Wmissing-prototypes */ 4686cd6a6acSopenharmony_ciPyMODINIT_FUNC initaudit2why(void) 4696cd6a6acSopenharmony_ci#endif 4706cd6a6acSopenharmony_ci{ 4716cd6a6acSopenharmony_ci PyObject *m; 4726cd6a6acSopenharmony_ci#if PY_MAJOR_VERSION >= 3 4736cd6a6acSopenharmony_ci m = PyModule_Create(&moduledef); 4746cd6a6acSopenharmony_ci if (m == NULL) { 4756cd6a6acSopenharmony_ci return NULL; 4766cd6a6acSopenharmony_ci } 4776cd6a6acSopenharmony_ci#else 4786cd6a6acSopenharmony_ci m = Py_InitModule("audit2why", audit2whyMethods); 4796cd6a6acSopenharmony_ci#endif 4806cd6a6acSopenharmony_ci PyModule_AddIntConstant(m,"UNKNOWN", UNKNOWN); 4816cd6a6acSopenharmony_ci PyModule_AddIntConstant(m,"BADSCON", BADSCON); 4826cd6a6acSopenharmony_ci PyModule_AddIntConstant(m,"BADTCON", BADTCON); 4836cd6a6acSopenharmony_ci PyModule_AddIntConstant(m,"BADTCLASS", BADTCLASS); 4846cd6a6acSopenharmony_ci PyModule_AddIntConstant(m,"BADPERM", BADPERM); 4856cd6a6acSopenharmony_ci PyModule_AddIntConstant(m,"BADCOMPUTE", BADCOMPUTE); 4866cd6a6acSopenharmony_ci PyModule_AddIntConstant(m,"NOPOLICY", NOPOLICY); 4876cd6a6acSopenharmony_ci PyModule_AddIntConstant(m,"ALLOW", ALLOW); 4886cd6a6acSopenharmony_ci PyModule_AddIntConstant(m,"DONTAUDIT", DONTAUDIT); 4896cd6a6acSopenharmony_ci PyModule_AddIntConstant(m,"TERULE", TERULE); 4906cd6a6acSopenharmony_ci PyModule_AddIntConstant(m,"BOOLEAN", BOOLEAN); 4916cd6a6acSopenharmony_ci PyModule_AddIntConstant(m,"CONSTRAINT", CONSTRAINT); 4926cd6a6acSopenharmony_ci PyModule_AddIntConstant(m,"RBAC", RBAC); 4936cd6a6acSopenharmony_ci PyModule_AddIntConstant(m,"BOUNDS", BOUNDS); 4946cd6a6acSopenharmony_ci 4956cd6a6acSopenharmony_ci#if PY_MAJOR_VERSION >= 3 4966cd6a6acSopenharmony_ci return m; 4976cd6a6acSopenharmony_ci#endif 4986cd6a6acSopenharmony_ci} 499