aa39c1
diff --exclude-from=exclude -N -u -r nsalibselinux/include/selinux/av_permissions.h libselinux-2.0.47/include/selinux/av_permissions.h
328ee6
--- nsalibselinux/include/selinux/av_permissions.h	2007-11-15 15:52:46.000000000 -0500
aa39c1
+++ libselinux-2.0.47/include/selinux/av_permissions.h	2008-01-11 10:55:14.000000000 -0500
328ee6
@@ -900,6 +900,8 @@
328ee6
 #define PACKET__SEND                              0x00000001UL
328ee6
 #define PACKET__RECV                              0x00000002UL
328ee6
 #define PACKET__RELABELTO                         0x00000004UL
328ee6
+#define PACKET__FLOW_IN                           0x00000008UL
328ee6
+#define PACKET__FLOW_OUT                          0x00000010UL
328ee6
 #define KEY__VIEW                                 0x00000001UL
328ee6
 #define KEY__READ                                 0x00000002UL
328ee6
 #define KEY__WRITE                                0x00000004UL
aa39c1
diff --exclude-from=exclude -N -u -r nsalibselinux/src/audit2why.c libselinux-2.0.47/src/audit2why.c
f76abb
--- nsalibselinux/src/audit2why.c	1969-12-31 19:00:00.000000000 -0500
79486e
+++ libselinux-2.0.47/src/audit2why.c	2008-01-22 16:23:59.000000000 -0500
bd4c7a
@@ -0,0 +1,460 @@
f76abb
+#include <unistd.h>
f76abb
+#include <stdlib.h>
f76abb
+#include <ctype.h>
f76abb
+#include <errno.h>
f76abb
+#include <getopt.h>
f76abb
+#include <limits.h>
f76abb
+#include <sepol sepol.h="">
f76abb
+#include <sepol policydb="" services.h="">
f76abb
+#include <python.h>
f76abb
+#include <selinux selinux.h="">
f76abb
+
f76abb
+#define UNKNOWN -1
f76abb
+#define BADSCON -2
f76abb
+#define BADTCON -3
f76abb
+#define BADTCLASS -4
f76abb
+#define BADPERM -5
f76abb
+#define BADCOMPUTE -6
f76abb
+#define NOPOLICY -7
f76abb
+#define ALLOW 0
f76abb
+#define DONTAUDIT 1
f76abb
+#define TERULE 2
f76abb
+#define BOOLEAN 3
f76abb
+#define CONSTRAINT 4
f76abb
+#define RBAC 5
f76abb
+
f76abb
+struct boolean_t {
f76abb
+	char *name;
f76abb
+	int active;
f76abb
+};
f76abb
+
f76abb
+static struct boolean_t **boollist = NULL;
f76abb
+static int boolcnt = 0;
f76abb
+
f76abb
+struct avc_t {
f76abb
+	sepol_handle_t *handle;
f76abb
+	policydb_t policydb;
f76abb
+	sepol_security_id_t ssid;
f76abb
+	sepol_security_id_t tsid;
f76abb
+	sepol_security_class_t tclass;
f76abb
+	sepol_access_vector_t av;
f76abb
+};
f76abb
+
f76abb
+static struct avc_t *avc = NULL;
f76abb
+
f76abb
+static sidtab_t sidtab;
f76abb
+
f76abb
+static int load_booleans(const sepol_bool_t * boolean,
f76abb
+			 void *arg __attribute__ ((__unused__)))
f76abb
+{
f76abb
+	boollist[boolcnt] =
f76abb
+	    (struct boolean_t *)malloc(sizeof(struct boolean_t));
f76abb
+	boollist[boolcnt]->name = strdup(sepol_bool_get_name(boolean));
f76abb
+	boollist[boolcnt]->active = sepol_bool_get_value(boolean);
f76abb
+	boolcnt++;
f76abb
+	return 0;
f76abb
+}
f76abb
+
f76abb
+static int check_booleans(struct avc_t *avc, struct boolean_t ***bools)
f76abb
+{
f76abb
+	char errormsg[PATH_MAX];
f76abb
+	struct sepol_av_decision avd;
f76abb
+	unsigned int reason;
f76abb
+	int rc;
f76abb
+	int i;
f76abb
+	sepol_bool_key_t *key = NULL;
f76abb
+	sepol_bool_t *boolean = NULL;
f76abb
+	int fcnt = 0;
f76abb
+	int *foundlist = calloc(boolcnt, sizeof(int));
f76abb
+	if (!foundlist) {
f76abb
+		PyErr_SetString( PyExc_MemoryError, "Out of memory\n");
f76abb
+		return fcnt;
f76abb
+	}
f76abb
+	for (i = 0; i < boolcnt; i++) {
f76abb
+		char *name = boollist[i]->name;
f76abb
+		int active = boollist[i]->active;
f76abb
+		rc = sepol_bool_key_create(avc->handle, name, &key);
f76abb
+		if (rc < 0) {
f76abb
+			PyErr_SetString( PyExc_RuntimeError, 
f76abb
+					 "Could not create boolean key.\n");
f76abb
+			break;
f76abb
+		}
f76abb
+		rc = sepol_bool_query(avc->handle,
f76abb
+				      (sepol_policydb_t *) & avc->policydb,
f76abb
+				      key, &boolean);
f76abb
+
f76abb
+		if (rc < 0) {
f76abb
+			snprintf(errormsg, sizeof(errormsg), 
f76abb
+				 "Could not find boolean %s.\n", name);
f76abb
+			PyErr_SetString( PyExc_RuntimeError, errormsg);
f76abb
+			break;
f76abb
+		}
f76abb
+
f76abb
+		sepol_bool_set_value(boolean, !active);
f76abb
+
f76abb
+		rc = sepol_bool_set(avc->handle,
f76abb
+				    (sepol_policydb_t *) & avc->policydb,
f76abb
+				    key, boolean);
f76abb
+		if (rc < 0) {
f76abb
+			snprintf(errormsg, sizeof(errormsg), 
f76abb
+				 "Could not set boolean data %s.\n", name);
f76abb
+			PyErr_SetString( PyExc_RuntimeError, errormsg);
f76abb
+			break;
f76abb
+		}
f76abb
+
f76abb
+		/* Reproduce the computation. */
f76abb
+		rc = sepol_compute_av_reason(avc->ssid, avc->tsid, avc->tclass,
f76abb
+					     avc->av, &avd, &reason);
f76abb
+		if (rc < 0) {
f76abb
+			snprintf(errormsg, sizeof(errormsg), 
f76abb
+				 "Error during access vector computation, skipping...");
f76abb
+			PyErr_SetString( PyExc_RuntimeError, errormsg);
f76abb
+
f76abb
+			sepol_bool_free(boolean);
f76abb
+			break;
f76abb
+		} else {
f76abb
+			if (!reason) {
f76abb
+				foundlist[fcnt] = i;
f76abb
+				fcnt++;
f76abb
+			}
f76abb
+			sepol_bool_set_value((sepol_bool_t *) boolean, active);
f76abb
+			rc = sepol_bool_set(avc->handle,
f76abb
+					    (sepol_policydb_t *) & avc->
f76abb
+					    policydb, key,
f76abb
+					    (sepol_bool_t *) boolean);
f76abb
+			if (rc < 0) {
f76abb
+				snprintf(errormsg, sizeof(errormsg), 
f76abb
+					 "Could not set boolean data %s.\n",
f76abb
+					 name);
f76abb
+			
f76abb
+				PyErr_SetString( PyExc_RuntimeError, errormsg);
f76abb
+				break;
f76abb
+			}
f76abb
+		}
f76abb
+		sepol_bool_free(boolean);
f76abb
+		sepol_bool_key_free(key);
f76abb
+		key = NULL;
f76abb
+		boolean = NULL;
f76abb
+	}
f76abb
+	if (key)
f76abb
+		sepol_bool_key_free(key);
f76abb
+
f76abb
+	if (boolean)
f76abb
+		sepol_bool_free(boolean);
f76abb
+
f76abb
+	if (fcnt > 0) {
f76abb
+		*bools = (struct boolean_t **)
f76abb
+			calloc(sizeof(struct boolean_t), fcnt + 1);
f76abb
+		struct boolean_t *b = (struct boolean_t *) *bools;
f76abb
+		for (i = 0; i < fcnt; i++) {
f76abb
+			int ctr = foundlist[i];
f76abb
+			b[i].name = strdup(boollist[ctr]->name);
f76abb
+			b[i].active = !boollist[ctr]->active;
f76abb
+		}
f76abb
+	}
f76abb
+	free(foundlist);
f76abb
+	return fcnt;
f76abb
+}
f76abb
+
f76abb
+static PyObject *finish(PyObject *self __attribute__((unused)), PyObject *args) {
f76abb
+	PyObject *result = 0;
f76abb
+  
f76abb
+	if (PyArg_ParseTuple(args,(char *)":finish")) {
f76abb
+		int i = 0;
f76abb
+		for (i = 0; i < boolcnt; i++) {
f76abb
+			free(boollist[i]->name);
f76abb
+			free(boollist[i]);
f76abb
+		}
f76abb
+		free(boollist);
f76abb
+		sepol_sidtab_shutdown(&sidtab);
f76abb
+		sepol_sidtab_destroy(&sidtab);
f76abb
+		policydb_destroy(&avc->policydb);
f76abb
+		sepol_handle_destroy(avc->handle);
f76abb
+		free(avc);
f76abb
+		avc = NULL;
f76abb
+		boollist = NULL;
f76abb
+		boolcnt = 0;
f76abb
+	  
f76abb
+		/* Boilerplate to return "None" */
f76abb
+		Py_RETURN_NONE;
f76abb
+	}
f76abb
+	return result;
f76abb
+}
f76abb
+
f76abb
+
f76abb
+static int __policy_init(const char *init_path)
f76abb
+{
f76abb
+	FILE *fp;
f76abb
+	int vers = 0;
f76abb
+	char path[PATH_MAX];
f76abb
+	char errormsg[PATH_MAX];
f76abb
+	struct policy_file pf;
f76abb
+	int rc;
f76abb
+	unsigned int cnt;
f76abb
+
f76abb
+	if (init_path) {
f76abb
+		strncpy(path, init_path, PATH_MAX);
f76abb
+		fp = fopen(path, "r");
f76abb
+		if (!fp) {
f76abb
+			snprintf(errormsg, sizeof(errormsg), 
f76abb
+				 "unable to open %s:  %s\n",
f76abb
+				 path, strerror(errno));
f76abb
+			PyErr_SetString( PyExc_ValueError, errormsg);
f76abb
+			return 0;    // trigger exception
f76abb
+		}
f76abb
+	} else {
f76abb
+		vers = security_policyvers();
f76abb
+		if (vers < 0) {
f76abb
+			snprintf(errormsg, sizeof(errormsg), 
f76abb
+				 "Could not get policy version:  %s\n",
f76abb
+				 strerror(errno));
f76abb
+			PyErr_SetString( PyExc_ValueError, errormsg);
f76abb
+			return 1;
f76abb
+		}
f76abb
+		snprintf(path, PATH_MAX, "%s.%d",
f76abb
+			 selinux_binary_policy_path(), vers);
f76abb
+		fp = fopen(path, "r");
f76abb
+		while (!fp && errno == ENOENT && --vers) {
f76abb
+			snprintf(path, PATH_MAX, "%s.%d",
f76abb
+				 selinux_binary_policy_path(), vers);
f76abb
+			fp = fopen(path, "r");
f76abb
+		}
f76abb
+		if (!fp) {
f76abb
+			snprintf(errormsg, sizeof(errormsg), 
f76abb
+				 "unable to open %s.%d:  %s\n",
f76abb
+				 selinux_binary_policy_path(),
f76abb
+				 security_policyvers(), strerror(errno));
f76abb
+			PyErr_SetString( PyExc_ValueError, errormsg);
f76abb
+			return 1;
f76abb
+		}
f76abb
+	}
f76abb
+
f76abb
+	avc = calloc(sizeof(struct avc_t), 1);
f76abb
+	if (!avc) {
f76abb
+		PyErr_SetString( PyExc_MemoryError, "Out of memory\n");
f76abb
+		return 1;
f76abb
+	}
f76abb
+
f76abb
+	/* Set up a policydb directly so that we can mutate it later
f76abb
+	   for booleans and user settings.  Otherwise we would just use
f76abb
+	   sepol_set_policydb_from_file() here. */
f76abb
+	pf.fp = fp;
f76abb
+	pf.type = PF_USE_STDIO;
f76abb
+	if (policydb_init(&avc->policydb)) {
f76abb
+		snprintf(errormsg, sizeof(errormsg), 
f76abb
+			 "policydb_init failed: %s\n", strerror(errno));
f76abb
+		PyErr_SetString( PyExc_RuntimeError, errormsg);
f76abb
+		fclose(fp);
f76abb
+		return 1;
f76abb
+	}
f76abb
+	if (policydb_read(&avc->policydb, &pf, 0)) {
f76abb
+		snprintf(errormsg, sizeof(errormsg), 
f76abb
+			 "invalid binary policy %s\n", path);
f76abb
+		PyErr_SetString( PyExc_ValueError, errormsg);
f76abb
+		fclose(fp);
f76abb
+		return 1;
f76abb
+	}
f76abb
+	fclose(fp);
f76abb
+	sepol_set_policydb(&avc->policydb);
f76abb
+	if (!init_path) {
f76abb
+		/* If they didn't specify a full path of a binary policy file,
f76abb
+		   then also try loading any boolean settings and user
f76abb
+		   definitions from the active locations.  Otherwise,
f76abb
+		   they can use genpolbools and genpolusers to build a
f76abb
+		   binary policy file that includes any desired settings
f76abb
+		   and then apply audit2why -p to the resulting file. 
f76abb
+		   Errors are non-fatal as such settings are optional. */
f76abb
+		sepol_debug(0);
f76abb
+		(void)sepol_genbools_policydb(&avc->policydb,
f76abb
+					      selinux_booleans_path());
f76abb
+		(void)sepol_genusers_policydb(&avc->policydb,
f76abb
+					      selinux_users_path());
f76abb
+	}
f76abb
+	avc->handle = sepol_handle_create();
f76abb
+
f76abb
+	rc = sepol_bool_count(avc->handle,
f76abb
+			      (sepol_policydb_t *) & avc->policydb, &cnt);
f76abb
+	if (rc < 0) {
f76abb
+		PyErr_SetString( PyExc_RuntimeError, "unable to get bool count\n");
f76abb
+		return 1;
f76abb
+	}
f76abb
+
f76abb
+	boollist = calloc(cnt, sizeof(struct boolean_t));
f76abb
+	if (!boollist) {
f76abb
+		PyErr_SetString( PyExc_MemoryError, "Out of memory\n");
f76abb
+		return 1;
f76abb
+	}
f76abb
+
f76abb
+	sepol_bool_iterate(avc->handle,
f76abb
+			   (const sepol_policydb_t *)&avc->policydb,
f76abb
+			   load_booleans, (void *)NULL);
f76abb
+
f76abb
+	/* Initialize the sidtab for subsequent use by sepol_context_to_sid
f76abb
+	   and sepol_compute_av_reason. */
f76abb
+	rc = sepol_sidtab_init(&sidtab);
f76abb
+	if (rc < 0) {
f76abb
+		PyErr_SetString( PyExc_RuntimeError, "unable to init sidtab\n");
f76abb
+		free(boollist);
f76abb
+		return 1;
f76abb
+	}
f76abb
+	sepol_set_sidtab(&sidtab);
f76abb
+	return 0;
f76abb
+}
f76abb
+
f76abb
+static PyObject *init(PyObject *self __attribute__((unused)), PyObject *args) {
f76abb
+  int result;
f76abb
+  char *init_path=NULL;
f76abb
+  if (PyArg_ParseTuple(args,(char *)"|s:policy_init",&init_path)) 
f76abb
+	  result = __policy_init(init_path);
f76abb
+  return Py_BuildValue("i", result);
f76abb
+}
f76abb
+
f76abb
+#define RETURN(X) \
bd4c7a
+	PyTuple_SetItem(result, 0, Py_BuildValue("i", X));	\
f76abb
+	return result;						
f76abb
+
f76abb
+static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args) {
f76abb
+	security_context_t scon; 
f76abb
+	security_context_t tcon;
f76abb
+	char *tclassstr; 
f76abb
+	PyObject *listObj;
f76abb
+	PyObject *strObj;
f76abb
+	int numlines;
f76abb
+	struct boolean_t **bools;
f76abb
+	unsigned int reason;
f76abb
+	sepol_security_id_t ssid, tsid;
f76abb
+	sepol_security_class_t tclass;
f76abb
+	sepol_access_vector_t perm, av;
f76abb
+	struct sepol_av_decision avd;
f76abb
+	int rc;
f76abb
+	int i=0;
bd4c7a
+	PyObject *result = PyTuple_New(2);
f76abb
+	if (!result) return NULL;
f76abb
+	Py_INCREF(Py_None);
bd4c7a
+	PyTuple_SetItem(result, 1, Py_None);
f76abb
+
f76abb
+	if (!PyArg_ParseTuple(args,(char *)"sssO!:audit2why",&scon,&tcon,&tclassstr,&PyList_Type, &listObj)) 
f76abb
+		return NULL;
f76abb
+  
f76abb
+	/* get the number of lines passed to us */
f76abb
+	numlines = PyList_Size(listObj);
f76abb
+
f76abb
+	/* should raise an error here. */
f76abb
+	if (numlines < 0)	return NULL; /* Not a list */
f76abb
+
f76abb
+	if (!avc) {
f76abb
+		RETURN(NOPOLICY)
f76abb
+	}
f76abb
+
f76abb
+	rc = sepol_context_to_sid(scon, strlen(scon) + 1, &ssid);
f76abb
+	if (rc < 0) {
f76abb
+		RETURN(BADSCON)
f76abb
+	}
f76abb
+	rc = sepol_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
f76abb
+	if (rc < 0) {
f76abb
+		RETURN(BADTCON)
f76abb
+	}
f76abb
+	tclass = string_to_security_class(tclassstr);
f76abb
+	if (!tclass) {
f76abb
+		RETURN(BADTCLASS)
f76abb
+	}
f76abb
+	/* Convert the permission list to an AV. */
f76abb
+	av = 0;
f76abb
+
f76abb
+	/* iterate over items of the list, grabbing strings, and parsing
f76abb
+	   for numbers */
f76abb
+	for (i=0; i
f76abb
+		char *permstr;
f76abb
+
f76abb
+		/* grab the string object from the next element of the list */
f76abb
+		strObj = PyList_GetItem(listObj, i); /* Can't fail */
f76abb
+		
f76abb
+		/* make it a string */
f76abb
+		permstr = PyString_AsString( strObj );
f76abb
+		
f76abb
+		perm = string_to_av_perm(tclass, permstr);
f76abb
+		if (!perm) {
f76abb
+			RETURN(BADPERM)
f76abb
+		}
f76abb
+		av |= perm;
f76abb
+	}
f76abb
+
f76abb
+	/* Reproduce the computation. */
f76abb
+	rc = sepol_compute_av_reason(ssid, tsid, tclass, av, &avd, &reason);
f76abb
+	if (rc < 0) {
f76abb
+		RETURN(BADCOMPUTE)
f76abb
+	}
f76abb
+
f76abb
+	if (!reason) {
f76abb
+		RETURN(ALLOW)
f76abb
+	}
f76abb
+	if (reason & SEPOL_COMPUTEAV_TE) {
f76abb
+		avc->ssid = ssid;
f76abb
+		avc->tsid = tsid;
f76abb
+		avc->tclass = tclass;
f76abb
+		avc->av = av;
f76abb
+		if (check_booleans(avc, &bools) == 0) {
f76abb
+			if (av & ~avd.auditdeny) {
f76abb
+				RETURN(DONTAUDIT)
f76abb
+			} else {
f76abb
+				RETURN(TERULE)
f76abb
+			}
f76abb
+		} else {
bd4c7a
+			PyTuple_SetItem(result, 0, Py_BuildValue("i", BOOLEAN));
f76abb
+			struct boolean_t *b=(struct boolean_t *) bools;
f76abb
+			int len=0;
f76abb
+			while (b->name) {
f76abb
+				len++; b++;
f76abb
+			}
f76abb
+			b = (struct boolean_t *) bools;
bd4c7a
+			PyObject *boollist = PyTuple_New(len);
f76abb
+			len=0;
f76abb
+			while(b->name) {
bd4c7a
+				PyObject *bool = Py_BuildValue("(si)", b->name, b->active);
bd4c7a
+				PyTuple_SetItem(boollist, len++, bool);
f76abb
+				b++;
f76abb
+			}
f76abb
+			free(bools);
bd4c7a
+			PyTuple_SetItem(result, 1, boollist);
f76abb
+			return result;
f76abb
+		}
f76abb
+	}
f76abb
+
f76abb
+	if (reason & SEPOL_COMPUTEAV_CONS) {
f76abb
+		RETURN(CONSTRAINT);
f76abb
+	}
f76abb
+
f76abb
+	if (reason & SEPOL_COMPUTEAV_RBAC) {
f76abb
+		RETURN(RBAC)
f76abb
+	}
f76abb
+        RETURN(BADCOMPUTE)
f76abb
+}
f76abb
+
f76abb
+static PyMethodDef audit2whyMethods[] = {
f76abb
+    {"init",  init, METH_VARARGS,
f76abb
+     "Initialize policy database."},
f76abb
+    {"analyze",  analyze, METH_VARARGS,
f76abb
+     "Analyze AVC."},
f76abb
+    {"finish",  finish, METH_VARARGS,
f76abb
+     "Finish using policy, free memory."},
f76abb
+    {NULL, NULL, 0, NULL}        /* Sentinel */
f76abb
+};
f76abb
+
f76abb
+PyMODINIT_FUNC
f76abb
+initaudit2why(void)
f76abb
+{
f76abb
+	PyObject *m = Py_InitModule("audit2why", audit2whyMethods);
f76abb
+	PyModule_AddIntConstant(m,"UNKNOWN", UNKNOWN);
f76abb
+	PyModule_AddIntConstant(m,"BADSCON", BADSCON);
f76abb
+	PyModule_AddIntConstant(m,"BADTCON", BADTCON);
f76abb
+	PyModule_AddIntConstant(m,"BADTCLASS", BADTCLASS);
f76abb
+	PyModule_AddIntConstant(m,"BADPERM", BADPERM);
f76abb
+	PyModule_AddIntConstant(m,"BADCOMPUTE", BADCOMPUTE);
f76abb
+	PyModule_AddIntConstant(m,"NOPOLICY", NOPOLICY);
f76abb
+	PyModule_AddIntConstant(m,"ALLOW", ALLOW);
f76abb
+	PyModule_AddIntConstant(m,"DONTAUDIT", DONTAUDIT);
f76abb
+	PyModule_AddIntConstant(m,"TERULE", TERULE);
f76abb
+	PyModule_AddIntConstant(m,"BOOLEAN", BOOLEAN);
f76abb
+	PyModule_AddIntConstant(m,"CONSTRAINT", CONSTRAINT);
f76abb
+	PyModule_AddIntConstant(m,"RBAC", RBAC);
f76abb
+}
aa39c1
diff --exclude-from=exclude -N -u -r nsalibselinux/src/Makefile libselinux-2.0.47/src/Makefile
aa39c1
--- nsalibselinux/src/Makefile	2008-01-11 10:52:37.000000000 -0500
79486e
+++ libselinux-2.0.47/src/Makefile	2008-01-23 14:19:11.000000000 -0500
f76abb
@@ -18,6 +18,7 @@
f76abb
 SWIGSO=_selinux.so
f76abb
 SWIGFILES=$(SWIGSO) selinux.py 
f76abb
 LIBSO=$(TARGET).$(LIBVERSION)
f76abb
+AUDIT2WHYSO=audit2why.so
f76abb
 
f76abb
 ifeq ($(DISABLE_AVC),y)
f76abb
 	UNUSED_SRCS+=avc.c avc_internal.c avc_sidtab.c mapping.c stringrep.c checkAccess.c
f76abb
@@ -28,7 +29,7 @@
f76abb
 ifeq ($(DISABLE_RPM),y)
f76abb
 	UNUSED_SRCS+=rpm.c
f76abb
 endif
f76abb
-SRCS= $(filter-out $(UNUSED_SRCS), $(filter-out $(SWIGCOUT),$(wildcard *.c)))
f76abb
+SRCS= $(filter-out $(UNUSED_SRCS), $(filter-out audit2why.c $(SWIGCOUT),$(wildcard *.c)))
f76abb
 
f76abb
 OBJS= $(patsubst %.c,%.o,$(SRCS))
f76abb
 LOBJS= $(patsubst %.c,%.lo,$(SRCS))
f76abb
@@ -47,7 +48,7 @@
f76abb
 
f76abb
 all: $(LIBA) $(LIBSO) 
f76abb
 
f76abb
-pywrap: all $(SWIGSO)
f76abb
+pywrap: all $(SWIGSO) $(AUDIT2WHYSO)
f76abb
 
f76abb
 $(LIBA):  $(OBJS)
f76abb
 	$(AR) rcs $@ $^
f76abb
@@ -63,6 +64,12 @@
f76abb
 	$(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -ldl -L$(LIBDIR) -Wl,-soname,$(LIBSO),-z,defs,-z,relro
f76abb
 	ln -sf $@ $(TARGET) 
f76abb
 
f76abb
+audit2why.lo: audit2why.c
f76abb
+	$(CC) $(CFLAGS) -I$(PYINC) -fPIC -DSHARED -c -o $@ $<
f76abb
+
f76abb
+$(AUDIT2WHYSO): audit2why.lo
f76abb
+	$(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -L. -lselinux ${LIBDIR}/libsepol.a -L$(LIBDIR) -Wl,-soname,$@
f76abb
+
f76abb
 %.o:  %.c policy.h
f76abb
 	$(CC) $(CFLAGS) $(TLSFLAGS) -c -o $@ $<
f76abb
 
aa39c1
@@ -83,14 +90,16 @@
4e565f
 	cd $(LIBDIR) && ln -sf ../../`basename $(SHLIBDIR)`/$(LIBSO) $(TARGET)
4e565f
 
4e565f
 install-pywrap: pywrap
f76abb
-	test -d $(PYTHONLIBDIR)/site-packages || install -m 755 -d $(PYTHONLIBDIR)/site-packages
4e565f
-	install -m 755 $(SWIGFILES) $(PYTHONLIBDIR)/site-packages
79486e
+	test -d $(PYTHONLIBDIR)/site-packages/selinux || install -m 755 -d $(PYTHONLIBDIR)/site-packages/selinux
f76abb
+	install -m 755 $(SWIGSO) $(PYTHONLIBDIR)/site-packages/selinux
f76abb
+	install -m 755 $(AUDIT2WHYSO) $(PYTHONLIBDIR)/site-packages/selinux
424125
+	install -m 644  selinux.py $(PYTHONLIBDIR)/site-packages/selinux/__init__.py
4e565f
 
4e565f
 relabel:
4e565f
 	/sbin/restorecon $(SHLIBDIR)/$(LIBSO)
f76abb
 
f76abb
 clean: 
f76abb
-	-rm -f $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) $(TARGET) 
f76abb
+	-rm -f $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) $(TARGET) $(AUDIT2WHYSO) *.o *.lo *~
f76abb
 
f76abb
 distclean: clean
f76abb
 	rm -f $(SWIGCOUT) $(SWIGFILES)
aa39c1
diff --exclude-from=exclude -N -u -r nsalibselinux/src/matchpathcon.c libselinux-2.0.47/src/matchpathcon.c
39606e
--- nsalibselinux/src/matchpathcon.c	2007-09-28 09:48:58.000000000 -0400
aa39c1
+++ libselinux-2.0.47/src/matchpathcon.c	2008-01-11 10:55:14.000000000 -0500
71cd13
@@ -2,6 +2,7 @@
71cd13
 #include <string.h>
71cd13
 #include <errno.h>
71cd13
 #include <stdio.h>
71cd13
+#include <syslog.h>
71cd13
 #include "selinux_internal.h"
71cd13
 #include "label_internal.h"
71cd13
 #include "callbacks.h"
0fa749
@@ -57,7 +58,7 @@
71cd13
 {
71cd13
 	va_list ap;
71cd13
 	va_start(ap, fmt);
71cd13
-	vfprintf(stderr, fmt, ap);
0fa749
+	vsyslog(LOG_ERR, fmt, ap);
71cd13
 	va_end(ap);
71cd13
 }
71cd13
 
aa39c1
diff --exclude-from=exclude -N -u -r nsalibselinux/src/selinuxswig.i libselinux-2.0.47/src/selinuxswig.i
79486e
--- nsalibselinux/src/selinuxswig.i	2008-01-23 14:36:29.000000000 -0500
aa39c1
+++ libselinux-2.0.47/src/selinuxswig.i	2008-01-11 10:55:14.000000000 -0500
79486e
@@ -14,6 +14,7 @@
1dd1cd
 
1dd1cd
 %typedef unsigned mode_t;
79486e
 %typedef unsigned pid_t;
79486e
+%typedef char * security_context_t;
1dd1cd
 
1dd1cd
 %typemap(in, numinputs=0) (char ***names, int *len) (char **temp1, int temp2) {
1dd1cd
 	$1 = &temp1;