| Eric Paris | 8faf23d | 2011-08-03 14:02:37 -0400 | [diff] [blame] | 1 | /* Workaround for http://bugs.python.org/issue4835 */ | 
 | 2 | #ifndef SIZEOF_SOCKET_T | 
 | 3 | #define SIZEOF_SOCKET_T SIZEOF_INT | 
 | 4 | #endif | 
 | 5 |  | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 6 | #include <Python.h> | 
 | 7 | #include <unistd.h> | 
 | 8 | #include <stdlib.h> | 
 | 9 | #include <ctype.h> | 
 | 10 | #include <errno.h> | 
 | 11 | #include <getopt.h> | 
 | 12 | #include <limits.h> | 
 | 13 | #include <sepol/sepol.h> | 
 | 14 | #include <sepol/policydb.h> | 
 | 15 | #include <sepol/policydb/services.h> | 
 | 16 | #include <selinux/selinux.h> | 
 | 17 |  | 
 | 18 | #define UNKNOWN -1 | 
 | 19 | #define BADSCON -2 | 
 | 20 | #define BADTCON -3 | 
 | 21 | #define BADTCLASS -4 | 
 | 22 | #define BADPERM -5 | 
 | 23 | #define BADCOMPUTE -6 | 
 | 24 | #define NOPOLICY -7 | 
 | 25 | #define ALLOW 0 | 
 | 26 | #define DONTAUDIT 1 | 
 | 27 | #define TERULE 2 | 
 | 28 | #define BOOLEAN 3 | 
 | 29 | #define CONSTRAINT 4 | 
 | 30 | #define RBAC 5 | 
 | 31 |  | 
 | 32 | struct boolean_t { | 
 | 33 | 	char *name; | 
 | 34 | 	int active; | 
 | 35 | }; | 
 | 36 |  | 
 | 37 | static struct boolean_t **boollist = NULL; | 
 | 38 | static int boolcnt = 0; | 
 | 39 |  | 
 | 40 | struct avc_t { | 
 | 41 | 	sepol_handle_t *handle; | 
 | 42 | 	sepol_policydb_t *policydb; | 
 | 43 | 	sepol_security_id_t ssid; | 
 | 44 | 	sepol_security_id_t tsid; | 
 | 45 | 	sepol_security_class_t tclass; | 
 | 46 | 	sepol_access_vector_t av; | 
 | 47 | }; | 
 | 48 |  | 
 | 49 | static struct avc_t *avc = NULL; | 
 | 50 |  | 
 | 51 | static sidtab_t sidtab; | 
 | 52 |  | 
 | 53 | static int load_booleans(const sepol_bool_t * boolean, | 
 | 54 | 			 void *arg __attribute__ ((__unused__))) | 
 | 55 | { | 
 | 56 | 	boollist[boolcnt] = malloc(sizeof(struct boolean_t)); | 
 | 57 | 	boollist[boolcnt]->name = strdup(sepol_bool_get_name(boolean)); | 
 | 58 | 	boollist[boolcnt]->active = sepol_bool_get_value(boolean); | 
 | 59 | 	boolcnt++; | 
 | 60 | 	return 0; | 
 | 61 | } | 
 | 62 |  | 
 | 63 | static int check_booleans(struct boolean_t **bools) | 
 | 64 | { | 
 | 65 | 	char errormsg[PATH_MAX]; | 
 | 66 | 	struct sepol_av_decision avd; | 
 | 67 | 	unsigned int reason; | 
 | 68 | 	int rc; | 
 | 69 | 	int i; | 
 | 70 | 	sepol_bool_key_t *key = NULL; | 
 | 71 | 	sepol_bool_t *boolean = NULL; | 
 | 72 | 	int fcnt = 0; | 
 | 73 | 	int *foundlist = calloc(boolcnt, sizeof(int)); | 
 | 74 | 	if (!foundlist) { | 
 | 75 | 		PyErr_SetString( PyExc_MemoryError, "Out of memory\n"); | 
 | 76 | 		return fcnt; | 
 | 77 | 	} | 
 | 78 | 	for (i = 0; i < boolcnt; i++) { | 
 | 79 | 		char *name = boollist[i]->name; | 
 | 80 | 		int active = boollist[i]->active; | 
 | 81 | 		rc = sepol_bool_key_create(avc->handle, name, &key); | 
 | 82 | 		if (rc < 0) { | 
 | 83 | 			PyErr_SetString( PyExc_RuntimeError,  | 
 | 84 | 					 "Could not create boolean key.\n"); | 
 | 85 | 			break; | 
 | 86 | 		} | 
 | 87 | 		rc = sepol_bool_query(avc->handle, | 
 | 88 | 				      avc->policydb, | 
 | 89 | 				      key, &boolean); | 
 | 90 |  | 
 | 91 | 		if (rc < 0) { | 
 | 92 | 			snprintf(errormsg, sizeof(errormsg),  | 
 | 93 | 				 "Could not find boolean %s.\n", name); | 
 | 94 | 			PyErr_SetString( PyExc_RuntimeError, errormsg); | 
 | 95 | 			break; | 
 | 96 | 		} | 
 | 97 |  | 
 | 98 | 		sepol_bool_set_value(boolean, !active); | 
 | 99 |  | 
 | 100 | 		rc = sepol_bool_set(avc->handle, | 
 | 101 | 				    avc->policydb, | 
 | 102 | 				    key, boolean); | 
 | 103 | 		if (rc < 0) { | 
 | 104 | 			snprintf(errormsg, sizeof(errormsg),  | 
 | 105 | 				 "Could not set boolean data %s.\n", name); | 
 | 106 | 			PyErr_SetString( PyExc_RuntimeError, errormsg); | 
 | 107 | 			break; | 
 | 108 | 		} | 
 | 109 |  | 
 | 110 | 		/* Reproduce the computation. */ | 
 | 111 | 		rc = sepol_compute_av_reason(avc->ssid, avc->tsid, avc->tclass, | 
 | 112 | 					     avc->av, &avd, &reason); | 
 | 113 | 		if (rc < 0) { | 
 | 114 | 			snprintf(errormsg, sizeof(errormsg),  | 
 | 115 | 				 "Error during access vector computation, skipping..."); | 
 | 116 | 			PyErr_SetString( PyExc_RuntimeError, errormsg); | 
 | 117 |  | 
 | 118 | 			sepol_bool_free(boolean); | 
 | 119 | 			break; | 
 | 120 | 		} else { | 
 | 121 | 			if (!reason) { | 
 | 122 | 				foundlist[fcnt] = i; | 
 | 123 | 				fcnt++; | 
 | 124 | 			} | 
 | 125 | 			sepol_bool_set_value(boolean, active); | 
 | 126 | 			rc = sepol_bool_set(avc->handle, | 
 | 127 | 					    avc->policydb, key, | 
 | 128 | 					    boolean); | 
 | 129 | 			if (rc < 0) { | 
 | 130 | 				snprintf(errormsg, sizeof(errormsg),  | 
 | 131 | 					 "Could not set boolean data %s.\n", | 
 | 132 | 					 name); | 
 | 133 | 			 | 
 | 134 | 				PyErr_SetString( PyExc_RuntimeError, errormsg); | 
 | 135 | 				break; | 
 | 136 | 			} | 
 | 137 | 		} | 
 | 138 | 		sepol_bool_free(boolean); | 
 | 139 | 		sepol_bool_key_free(key); | 
 | 140 | 		key = NULL; | 
 | 141 | 		boolean = NULL; | 
 | 142 | 	} | 
 | 143 | 	if (key) | 
 | 144 | 		sepol_bool_key_free(key); | 
 | 145 |  | 
 | 146 | 	if (boolean) | 
 | 147 | 		sepol_bool_free(boolean); | 
 | 148 |  | 
 | 149 | 	if (fcnt > 0) { | 
 | 150 | 		*bools = calloc(sizeof(struct boolean_t), fcnt + 1); | 
 | 151 | 		struct boolean_t *b = *bools; | 
 | 152 | 		for (i = 0; i < fcnt; i++) { | 
 | 153 | 			int ctr = foundlist[i]; | 
 | 154 | 			b[i].name = strdup(boollist[ctr]->name); | 
 | 155 | 			b[i].active = !boollist[ctr]->active; | 
 | 156 | 		} | 
 | 157 | 	} | 
 | 158 | 	free(foundlist); | 
 | 159 | 	return fcnt; | 
 | 160 | } | 
 | 161 |  | 
 | 162 | static PyObject *finish(PyObject *self __attribute__((unused)), PyObject *args) { | 
 | 163 | 	PyObject *result = 0; | 
 | 164 |    | 
 | 165 | 	if (PyArg_ParseTuple(args,(char *)":finish")) { | 
 | 166 | 		int i = 0; | 
| rhatdan | 019e6fd | 2012-10-15 15:25:31 -0400 | [diff] [blame] | 167 | 		if (! avc) | 
 | 168 | 			Py_RETURN_NONE; | 
 | 169 |  | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 170 | 		for (i = 0; i < boolcnt; i++) { | 
 | 171 | 			free(boollist[i]->name); | 
 | 172 | 			free(boollist[i]); | 
 | 173 | 		} | 
 | 174 | 		free(boollist); | 
 | 175 | 		sepol_sidtab_shutdown(&sidtab); | 
 | 176 | 		sepol_sidtab_destroy(&sidtab); | 
 | 177 | 		sepol_policydb_free(avc->policydb); | 
 | 178 | 		sepol_handle_destroy(avc->handle); | 
 | 179 | 		free(avc); | 
 | 180 | 		avc = NULL; | 
 | 181 | 		boollist = NULL; | 
 | 182 | 		boolcnt = 0; | 
| rhatdan | 019e6fd | 2012-10-15 15:25:31 -0400 | [diff] [blame] | 183 |  | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 184 | 		/* Boilerplate to return "None" */ | 
 | 185 | 		Py_RETURN_NONE; | 
 | 186 | 	} | 
 | 187 | 	return result; | 
 | 188 | } | 
 | 189 |  | 
 | 190 |  | 
 | 191 | static int __policy_init(const char *init_path) | 
 | 192 | { | 
 | 193 | 	FILE *fp; | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 194 | 	char path[PATH_MAX]; | 
 | 195 | 	char errormsg[PATH_MAX]; | 
 | 196 | 	struct sepol_policy_file *pf = NULL; | 
 | 197 | 	int rc; | 
 | 198 | 	unsigned int cnt; | 
 | 199 |  | 
| Eric Paris | 933840a | 2012-12-04 15:23:57 -0500 | [diff] [blame] | 200 | 	path[PATH_MAX-1] = '\0'; | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 201 | 	if (init_path) { | 
| Eric Paris | 933840a | 2012-12-04 15:23:57 -0500 | [diff] [blame] | 202 | 		strncpy(path, init_path, PATH_MAX-1); | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 203 | 		fp = fopen(path, "r"); | 
 | 204 | 		if (!fp) { | 
 | 205 | 			snprintf(errormsg, sizeof(errormsg),  | 
 | 206 | 				 "unable to open %s:  %s\n", | 
 | 207 | 				 path, strerror(errno)); | 
 | 208 | 			PyErr_SetString( PyExc_ValueError, errormsg); | 
 | 209 | 			return 1; | 
 | 210 | 		} | 
 | 211 | 	} else { | 
| Stephen Smalley | 914e591 | 2015-02-13 10:15:34 -0500 | [diff] [blame] | 212 | 		const char *curpolicy = selinux_current_policy_path(); | 
 | 213 | 		if (!curpolicy) { | 
 | 214 | 			/* SELinux disabled, must use -p option. */ | 
 | 215 | 			snprintf(errormsg, sizeof(errormsg), | 
 | 216 | 				 "You must specify the -p option with the path to the policy file.\n"); | 
 | 217 | 			PyErr_SetString( PyExc_ValueError, errormsg); | 
 | 218 | 			return 1; | 
 | 219 | 		} | 
 | 220 | 		fp = fopen(curpolicy, "r"); | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 221 | 		if (!fp) { | 
 | 222 | 			snprintf(errormsg, sizeof(errormsg),  | 
| Dan Walsh | 7eec00a | 2013-10-09 16:18:15 -0400 | [diff] [blame] | 223 | 				 "unable to open %s:  %s\n", | 
| Stephen Smalley | 914e591 | 2015-02-13 10:15:34 -0500 | [diff] [blame] | 224 | 				 curpolicy, | 
| Dan Walsh | 7eec00a | 2013-10-09 16:18:15 -0400 | [diff] [blame] | 225 | 				 strerror(errno)); | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 226 | 			PyErr_SetString( PyExc_ValueError, errormsg); | 
 | 227 | 			return 1; | 
 | 228 | 		} | 
 | 229 | 	} | 
 | 230 |  | 
 | 231 | 	avc = calloc(sizeof(struct avc_t), 1); | 
 | 232 | 	if (!avc) { | 
 | 233 | 		PyErr_SetString( PyExc_MemoryError, "Out of memory\n"); | 
| Dan Walsh | 74a9a52 | 2011-10-27 10:00:21 -0400 | [diff] [blame] | 234 | 		fclose(fp); | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 235 | 		return 1; | 
 | 236 | 	} | 
 | 237 |  | 
 | 238 | 	/* Set up a policydb directly so that we can mutate it later | 
 | 239 | 	   for testing what booleans might have allowed the access. | 
 | 240 | 	   Otherwise, we'd just use sepol_set_policydb_from_file() here. */ | 
 | 241 | 	if (sepol_policy_file_create(&pf) || | 
 | 242 | 	    sepol_policydb_create(&avc->policydb)) { | 
 | 243 | 		snprintf(errormsg, sizeof(errormsg),  | 
 | 244 | 			 "policydb_init failed: %s\n", strerror(errno)); | 
 | 245 | 		PyErr_SetString( PyExc_RuntimeError, errormsg); | 
 | 246 | 		fclose(fp); | 
 | 247 | 		return 1; | 
 | 248 | 	} | 
 | 249 | 	sepol_policy_file_set_fp(pf, fp);	 | 
 | 250 | 	if (sepol_policydb_read(avc->policydb, pf)) { | 
 | 251 | 		snprintf(errormsg, sizeof(errormsg),  | 
 | 252 | 			 "invalid binary policy %s\n", path); | 
 | 253 | 		PyErr_SetString( PyExc_ValueError, errormsg); | 
 | 254 | 		fclose(fp); | 
 | 255 | 		return 1; | 
 | 256 | 	} | 
 | 257 | 	fclose(fp); | 
 | 258 | 	sepol_set_policydb(&avc->policydb->p); | 
 | 259 | 	avc->handle = sepol_handle_create(); | 
| Eric Paris | 802369f | 2011-07-05 00:27:41 -0400 | [diff] [blame] | 260 | 	/* Turn off messages */ | 
 | 261 | 	sepol_msg_set_callback(avc->handle, NULL, NULL); | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 262 |  | 
 | 263 | 	rc = sepol_bool_count(avc->handle, | 
 | 264 | 			      avc->policydb, &cnt); | 
 | 265 | 	if (rc < 0) { | 
 | 266 | 		PyErr_SetString( PyExc_RuntimeError, "unable to get bool count\n"); | 
 | 267 | 		return 1; | 
 | 268 | 	} | 
 | 269 |  | 
| Eric Paris | aa62cd6 | 2012-11-29 09:41:38 -0500 | [diff] [blame] | 270 | 	boollist = calloc(cnt, sizeof(*boollist)); | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 271 | 	if (!boollist) { | 
 | 272 | 		PyErr_SetString( PyExc_MemoryError, "Out of memory\n"); | 
 | 273 | 		return 1; | 
 | 274 | 	} | 
 | 275 |  | 
 | 276 | 	sepol_bool_iterate(avc->handle, avc->policydb, | 
 | 277 | 			   load_booleans, (void *)NULL); | 
 | 278 |  | 
 | 279 | 	/* Initialize the sidtab for subsequent use by sepol_context_to_sid | 
 | 280 | 	   and sepol_compute_av_reason. */ | 
 | 281 | 	rc = sepol_sidtab_init(&sidtab); | 
 | 282 | 	if (rc < 0) { | 
 | 283 | 		PyErr_SetString( PyExc_RuntimeError, "unable to init sidtab\n"); | 
 | 284 | 		free(boollist); | 
 | 285 | 		return 1; | 
 | 286 | 	} | 
 | 287 | 	sepol_set_sidtab(&sidtab); | 
 | 288 | 	return 0; | 
 | 289 | } | 
 | 290 |  | 
 | 291 | static PyObject *init(PyObject *self __attribute__((unused)), PyObject *args) { | 
 | 292 |   int result; | 
 | 293 |   char *init_path=NULL; | 
| Eric Paris | d09bcb7 | 2012-11-19 12:42:38 -0500 | [diff] [blame] | 294 |   if (avc) { | 
 | 295 | 	  PyErr_SetString( PyExc_RuntimeError, "init called multiple times"); | 
 | 296 | 	  return NULL; | 
 | 297 |   } | 
| Eric Paris | 2ea80c2 | 2011-06-29 00:29:21 -0400 | [diff] [blame] | 298 |   if (!PyArg_ParseTuple(args,(char *)"|s:policy_init",&init_path)) | 
 | 299 |     return NULL; | 
 | 300 |   result = __policy_init(init_path); | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 301 |   return Py_BuildValue("i", result); | 
 | 302 | } | 
 | 303 |  | 
 | 304 | #define RETURN(X) \ | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 305 | 	{ \ | 
 | 306 | 		return Py_BuildValue("iO", (X), Py_None);	\ | 
 | 307 | 	} | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 308 |  | 
 | 309 | static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args) { | 
| Dan Walsh | 6d0f111 | 2013-10-28 10:09:55 -0400 | [diff] [blame] | 310 | 	char *reason_buf = NULL; | 
| Stephen Smalley | 9eb9c93 | 2014-02-19 09:16:17 -0500 | [diff] [blame] | 311 | 	char * scon; | 
 | 312 | 	char * tcon; | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 313 | 	char *tclassstr;  | 
 | 314 | 	PyObject *listObj; | 
 | 315 | 	PyObject *strObj; | 
 | 316 | 	int numlines; | 
 | 317 | 	struct boolean_t *bools; | 
 | 318 | 	unsigned int reason; | 
 | 319 | 	sepol_security_id_t ssid, tsid; | 
 | 320 | 	sepol_security_class_t tclass; | 
 | 321 | 	sepol_access_vector_t perm, av; | 
 | 322 | 	struct sepol_av_decision avd; | 
 | 323 | 	int rc; | 
 | 324 | 	int i=0; | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 325 |  | 
 | 326 | 	if (!PyArg_ParseTuple(args,(char *)"sssO!:audit2why",&scon,&tcon,&tclassstr,&PyList_Type, &listObj))  | 
 | 327 | 		return NULL; | 
 | 328 |    | 
 | 329 | 	/* get the number of lines passed to us */ | 
 | 330 | 	numlines = PyList_Size(listObj); | 
 | 331 |  | 
 | 332 | 	/* should raise an error here. */ | 
 | 333 | 	if (numlines < 0)	return NULL; /* Not a list */ | 
 | 334 |  | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 335 | 	if (!avc) | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 336 | 		RETURN(NOPOLICY) | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 337 |  | 
 | 338 | 	rc = sepol_context_to_sid(scon, strlen(scon) + 1, &ssid); | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 339 | 	if (rc < 0) | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 340 | 		RETURN(BADSCON) | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 341 |  | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 342 | 	rc = sepol_context_to_sid(tcon, strlen(tcon) + 1, &tsid); | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 343 | 	if (rc < 0) | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 344 | 		RETURN(BADTCON) | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 345 |  | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 346 | 	tclass = string_to_security_class(tclassstr); | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 347 | 	if (!tclass) | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 348 | 		RETURN(BADTCLASS) | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 349 |  | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 350 | 	/* Convert the permission list to an AV. */ | 
 | 351 | 	av = 0; | 
 | 352 |  | 
 | 353 | 	/* iterate over items of the list, grabbing strings, and parsing | 
 | 354 | 	   for numbers */ | 
 | 355 | 	for (i=0; i<numlines; i++){ | 
 | 356 | 		char *permstr; | 
 | 357 |  | 
 | 358 | 		/* grab the string object from the next element of the list */ | 
 | 359 | 		strObj = PyList_GetItem(listObj, i); /* Can't fail */ | 
 | 360 | 		 | 
 | 361 | 		/* make it a string */ | 
| Daniel J Walsh | 874bac8 | 2011-06-24 16:43:11 -0400 | [diff] [blame] | 362 | #if PY_MAJOR_VERSION >= 3 | 
 | 363 | 		permstr = _PyUnicode_AsString( strObj ); | 
 | 364 | #else | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 365 | 		permstr = PyString_AsString( strObj ); | 
| Daniel J Walsh | 874bac8 | 2011-06-24 16:43:11 -0400 | [diff] [blame] | 366 | #endif | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 367 | 		 | 
 | 368 | 		perm = string_to_av_perm(tclass, permstr); | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 369 | 		if (!perm) | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 370 | 			RETURN(BADPERM) | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 371 |  | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 372 | 		av |= perm; | 
 | 373 | 	} | 
 | 374 |  | 
 | 375 | 	/* Reproduce the computation. */ | 
| Dan Walsh | 6d0f111 | 2013-10-28 10:09:55 -0400 | [diff] [blame] | 376 | 	rc = sepol_compute_av_reason_buffer(ssid, tsid, tclass, av, &avd, &reason, &reason_buf, 0); | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 377 | 	if (rc < 0) | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 378 | 		RETURN(BADCOMPUTE) | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 379 |  | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 380 | 	if (!reason) | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 381 | 		RETURN(ALLOW) | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 382 |  | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 383 | 	if (reason & SEPOL_COMPUTEAV_TE) { | 
 | 384 | 		avc->ssid = ssid; | 
 | 385 | 		avc->tsid = tsid; | 
 | 386 | 		avc->tclass = tclass; | 
 | 387 | 		avc->av = av; | 
 | 388 | 		if (check_booleans(&bools) == 0) { | 
 | 389 | 			if (av & ~avd.auditdeny) { | 
 | 390 | 				RETURN(DONTAUDIT) | 
 | 391 | 			} else { | 
 | 392 | 				RETURN(TERULE) | 
 | 393 | 			} | 
 | 394 | 		} else { | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 395 | 			PyObject *outboollist; | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 396 | 			struct boolean_t *b = bools; | 
 | 397 | 			int len=0; | 
 | 398 | 			while (b->name) { | 
 | 399 | 				len++; b++; | 
 | 400 | 			} | 
 | 401 | 			b = bools; | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 402 | 			outboollist = PyList_New(len); | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 403 | 			len=0; | 
 | 404 | 			while(b->name) { | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 405 | 				PyObject *bool_ = Py_BuildValue("(si)", b->name, b->active); | 
 | 406 | 				PyList_SetItem(outboollist, len++, bool_); | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 407 | 				b++; | 
 | 408 | 			} | 
 | 409 | 			free(bools); | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 410 | 			/* 'N' steals the reference to outboollist */ | 
 | 411 | 			return Py_BuildValue("iN", BOOLEAN, outboollist); | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 412 | 		} | 
 | 413 | 	} | 
 | 414 |  | 
 | 415 | 	if (reason & SEPOL_COMPUTEAV_CONS) { | 
| Dan Walsh | 6d0f111 | 2013-10-28 10:09:55 -0400 | [diff] [blame] | 416 | 		if (reason_buf) { | 
 | 417 | 			PyObject *result = NULL; | 
 | 418 | 			result = Py_BuildValue("is", CONSTRAINT, reason_buf); | 
 | 419 | 			free(reason_buf); | 
 | 420 | 			return result; | 
 | 421 | 		} | 
| Dan Walsh | 756013e | 2013-10-09 15:11:05 -0400 | [diff] [blame] | 422 | 		RETURN(CONSTRAINT) | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 423 | 	} | 
 | 424 |  | 
| Dan Walsh | 7504bbd | 2012-11-21 14:25:17 -0500 | [diff] [blame] | 425 | 	if (reason & SEPOL_COMPUTEAV_RBAC) | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 426 | 		RETURN(RBAC) | 
| Dan Walsh | 7504bbd | 2012-11-21 14:25:17 -0500 | [diff] [blame] | 427 |  | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 428 |         RETURN(BADCOMPUTE) | 
 | 429 | } | 
 | 430 |  | 
 | 431 | static PyMethodDef audit2whyMethods[] = { | 
 | 432 |     {"init",  init, METH_VARARGS, | 
 | 433 |      "Initialize policy database."}, | 
 | 434 |     {"analyze",  analyze, METH_VARARGS, | 
 | 435 |      "Analyze AVC."}, | 
 | 436 |     {"finish",  finish, METH_VARARGS, | 
 | 437 |      "Finish using policy, free memory."}, | 
 | 438 |     {NULL, NULL, 0, NULL}        /* Sentinel */ | 
 | 439 | }; | 
 | 440 |  | 
| Daniel J Walsh | 874bac8 | 2011-06-24 16:43:11 -0400 | [diff] [blame] | 441 | #if PY_MAJOR_VERSION >= 3 | 
 | 442 | /* Module-initialization logic specific to Python 3 */ | 
 | 443 | struct module_state { | 
 | 444 | 	/* empty for now */ | 
 | 445 | }; | 
 | 446 | static struct PyModuleDef moduledef = { | 
 | 447 | 	PyModuleDef_HEAD_INIT, | 
 | 448 | 	"audit2why", | 
 | 449 | 	NULL, | 
 | 450 | 	sizeof(struct module_state), | 
 | 451 | 	audit2whyMethods, | 
 | 452 | 	NULL, | 
 | 453 | 	NULL, | 
 | 454 | 	NULL, | 
 | 455 | 	NULL | 
 | 456 | }; | 
 | 457 |  | 
| Eric Paris | 9b3055a | 2012-04-19 15:09:56 -0400 | [diff] [blame] | 458 | PyMODINIT_FUNC PyInit_audit2why(void); /* silence -Wmissing-prototypes */ | 
 | 459 | PyMODINIT_FUNC PyInit_audit2why(void) | 
| Daniel J Walsh | 874bac8 | 2011-06-24 16:43:11 -0400 | [diff] [blame] | 460 | #else | 
| Eric Paris | 9b3055a | 2012-04-19 15:09:56 -0400 | [diff] [blame] | 461 | PyMODINIT_FUNC initaudit2why(void); /* silence -Wmissing-prototypes */ | 
 | 462 | PyMODINIT_FUNC initaudit2why(void) | 
| Daniel J Walsh | 874bac8 | 2011-06-24 16:43:11 -0400 | [diff] [blame] | 463 | #endif | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 464 | { | 
| Daniel J Walsh | 874bac8 | 2011-06-24 16:43:11 -0400 | [diff] [blame] | 465 | 	PyObject *m; | 
 | 466 | #if PY_MAJOR_VERSION >= 3 | 
 | 467 | 	m = PyModule_Create(&moduledef); | 
 | 468 | 	if (m == NULL) { | 
 | 469 | 		return NULL; | 
 | 470 | 	} | 
 | 471 | #else | 
 | 472 | 	m  = Py_InitModule("audit2why", audit2whyMethods); | 
 | 473 | #endif | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 474 | 	PyModule_AddIntConstant(m,"UNKNOWN", UNKNOWN); | 
 | 475 | 	PyModule_AddIntConstant(m,"BADSCON", BADSCON); | 
 | 476 | 	PyModule_AddIntConstant(m,"BADTCON", BADTCON); | 
 | 477 | 	PyModule_AddIntConstant(m,"BADTCLASS", BADTCLASS); | 
 | 478 | 	PyModule_AddIntConstant(m,"BADPERM", BADPERM); | 
 | 479 | 	PyModule_AddIntConstant(m,"BADCOMPUTE", BADCOMPUTE); | 
 | 480 | 	PyModule_AddIntConstant(m,"NOPOLICY", NOPOLICY); | 
 | 481 | 	PyModule_AddIntConstant(m,"ALLOW", ALLOW); | 
 | 482 | 	PyModule_AddIntConstant(m,"DONTAUDIT", DONTAUDIT); | 
 | 483 | 	PyModule_AddIntConstant(m,"TERULE", TERULE); | 
 | 484 | 	PyModule_AddIntConstant(m,"BOOLEAN", BOOLEAN); | 
 | 485 | 	PyModule_AddIntConstant(m,"CONSTRAINT", CONSTRAINT); | 
 | 486 | 	PyModule_AddIntConstant(m,"RBAC", RBAC); | 
| Daniel J Walsh | 874bac8 | 2011-06-24 16:43:11 -0400 | [diff] [blame] | 487 |  | 
 | 488 | #if PY_MAJOR_VERSION >= 3 | 
 | 489 | 	return m; | 
 | 490 | #endif | 
| Joshua Brindle | 13cd4c8 | 2008-08-19 15:30:36 -0400 | [diff] [blame] | 491 | } |