diff --git a/libselinux-rhat.patch b/libselinux-rhat.patch index 0e3fc87..b4dc163 100644 --- a/libselinux-rhat.patch +++ b/libselinux-rhat.patch @@ -1,165 +1,271 @@ -diff --exclude-from=exclude -N -u -r nsalibselinux/include/selinux/selinux.h libselinux-1.30.12/include/selinux/selinux.h ---- nsalibselinux/include/selinux/selinux.h 2006-05-18 12:11:17.000000000 -0400 -+++ libselinux-1.30.12/include/selinux/selinux.h 2006-06-09 15:29:18.000000000 -0400 -@@ -361,6 +361,13 @@ - extern int selinux_getenforcemode(int *enforce); - - /* -+ selinux_getpolicytype reads the /etc/selinux/config file and determines -+ what the default policy for the machine is. Calling application must -+ free policytype. -+ */ -+extern int selinux_getpolicytype(char **policytype); -+ -+/* - selinux_policy_root reads the /etc/selinux/config file and returns - the directory path under which the compiled policy file and context - configuration files exist. -diff --exclude-from=exclude -N -u -r nsalibselinux/src/selinux_config.c libselinux-1.30.12/src/selinux_config.c ---- nsalibselinux/src/selinux_config.c 2006-05-23 06:19:32.000000000 -0400 -+++ libselinux-1.30.12/src/selinux_config.c 2006-06-09 15:42:35.000000000 -0400 -@@ -124,6 +124,37 @@ - } - hidden_def(selinux_getenforcemode) - -+int selinux_getpolicytype(char **intype) { -+ int ret=-1; -+ char *type=NULL; -+ char *end=NULL; -+ FILE *cfg = fopen(SELINUXCONFIG,"r"); -+ char buf[4097]; -+ int len=sizeof(SELINUXTYPETAG)-1; -+ if (!cfg) { -+ cfg = fopen(SECURITYCONFIG,"r"); -+ } -+ if (cfg) { -+ while (fgets_unlocked(buf, 4096, cfg)) { -+ if (strncmp(buf,SELINUXTYPETAG,len)) -+ continue; -+ type = strdupa(buf+sizeof(SELINUXTYPETAG)-1); -+ end = type + strlen(type)-1; -+ while ((end > type) && -+ (isspace(*end) || iscntrl(*end))) { -+ *end = 0; -+ end--; -+ } -+ *intype=type; -+ ret=0; -+ break; -+ } -+ fclose(cfg); -+ } -+ return ret; -+} -+hidden_def(selinux_getpolicytype) -+ - static char *selinux_policyroot = NULL; - static char *selinux_rootpath = NULL; - -diff --exclude-from=exclude -N -u -r nsalibselinux/src/selinux_internal.h libselinux-1.30.12/src/selinux_internal.h ---- nsalibselinux/src/selinux_internal.h 2006-05-23 06:19:32.000000000 -0400 -+++ libselinux-1.30.12/src/selinux_internal.h 2006-06-09 15:29:18.000000000 -0400 -@@ -64,6 +64,7 @@ - hidden_proto(selinux_usersconf_path); - hidden_proto(selinux_translations_path); - hidden_proto(selinux_getenforcemode); -+hidden_proto(selinux_getpolicytype); - hidden_proto(selinux_raw_to_trans_context); - hidden_proto(selinux_trans_to_raw_context); - -diff --exclude-from=exclude -N -u -r nsalibselinux/src/selinux.py libselinux-1.30.12/src/selinux.py ---- nsalibselinux/src/selinux.py 2006-05-15 09:43:24.000000000 -0400 -+++ libselinux-1.30.12/src/selinux.py 2006-06-09 15:29:18.000000000 -0400 -@@ -102,6 +102,7 @@ - is_context_customizable = _selinux.is_context_customizable - selinux_trans_to_raw_context = _selinux.selinux_trans_to_raw_context - selinux_raw_to_trans_context = _selinux.selinux_raw_to_trans_context -+selinux_getpolicytype = _selinux.selinux_getpolicytype - getseuserbyname = _selinux.getseuserbyname - - -diff --exclude-from=exclude -N -u -r nsalibselinux/src/selinuxswig.i libselinux-1.30.12/src/selinuxswig.i ---- nsalibselinux/src/selinuxswig.i 2006-05-15 09:43:24.000000000 -0400 -+++ libselinux-1.30.12/src/selinuxswig.i 2006-06-09 15:29:18.000000000 -0400 -@@ -126,4 +126,5 @@ - %typemap(argout) char ** { - $result = SWIG_Python_AppendOutput($result, PyString_FromString(*$1)); - } -+extern int selinux_getpolicytype(char **enforce); +diff --exclude-from=exclude -N -u -r nsalibselinux/include/selinux/selinux.h libselinux-1.30.15/include/selinux/selinux.h +--- nsalibselinux/include/selinux/selinux.h 2006-06-16 15:08:24.000000000 -0400 ++++ libselinux-1.30.15/include/selinux/selinux.h 2006-06-20 15:48:14.000000000 -0400 +@@ -429,8 +429,20 @@ + Caller must free the returned strings via free. */ extern int getseuserbyname(const char *linuxuser, char **seuser, char **level); -diff --exclude-from=exclude -N -u -r nsalibselinux/src/selinuxswig_wrap.c libselinux-1.30.12/src/selinuxswig_wrap.c ---- nsalibselinux/src/selinuxswig_wrap.c 2006-05-15 09:43:24.000000000 -0400 -+++ libselinux-1.30.12/src/selinuxswig_wrap.c 2006-06-09 15:29:18.000000000 -0400 -@@ -4153,6 +4153,27 @@ + ++/* This function allows you to compare two security context, it will ignore the ++user component */ ++int selinux_context_cmp(const security_context_t a, const security_context_t b); ++ ++/* This function looks at the file context on disk and compares it to the ++system defaults, it returns 1 on match non 0 on failure */ ++int selinux_verify_file_context(const char *path, mode_t mode); ++ ++/* This function sets the file context on to the system defaults returns 0 on success */ ++int selinux_lsetfilecon_default(const char *path); ++ + #ifdef __cplusplus + } + #endif + + #endif ++ +diff --exclude-from=exclude -N -u -r nsalibselinux/man/man8/matchpathcon.8 libselinux-1.30.15/man/man8/matchpathcon.8 +--- nsalibselinux/man/man8/matchpathcon.8 2006-05-15 09:43:24.000000000 -0400 ++++ libselinux-1.30.15/man/man8/matchpathcon.8 2006-06-20 10:56:07.000000000 -0400 +@@ -3,13 +3,25 @@ + matchpathcon \- get the default security context for the specified path from the file contexts configuration. + + .SH "SYNOPSIS" +-.B matchpathcon [-n] filepath... +- ++.B matchpathcon [-V] [-N] [-n] [-f file_contexts_file ] [-p prefix ] filepath... + .SH "DESCRIPTION" + .B matchpathcon + Prints the file path and the default security context associated with it. ++.SH OPTIONS ++.B \-n ++Do not display path. ++.br ++.B \-N ++Do not use translations. ++.br ++.B \-f file_context_file ++Use alternate file_context file ++.br ++.B \-p prefix ++Use prefix to speed translations + .br +-If the -n option is given, do not display path. ++.B \-V ++Verify file context on disk matches defaults + + .SH AUTHOR + This manual page was written by Dan Walsh . +diff --exclude-from=exclude -N -u -r nsalibselinux/src/matchpathcon.c libselinux-1.30.15/src/matchpathcon.c +--- nsalibselinux/src/matchpathcon.c 2006-05-18 12:11:17.000000000 -0400 ++++ libselinux-1.30.15/src/matchpathcon.c 2006-06-20 15:37:25.000000000 -0400 +@@ -26,6 +26,8 @@ + va_end(ap); } ++static unsigned int myflags; ++ + static void + #ifdef __GNUC__ + __attribute__ ((format (printf, 1, 2))) +@@ -50,7 +52,12 @@ + static int default_canoncon(const char *path, unsigned lineno, char **context) + { + char *tmpcon; +- if (security_canonicalize_context(*context, &tmpcon) < 0) { ++ int rc; ++ if (myflags & MATCHPATHCON_NOTRANS) ++ rc = security_canonicalize_context_raw(*context, &tmpcon); ++ else ++ rc = security_canonicalize_context(*context, &tmpcon); ++ if ( rc < 0) { + if (errno == ENOENT) + return 0; + if (lineno) +@@ -74,8 +81,6 @@ + mycanoncon = &default_canoncon; + } -+SWIGINTERN PyObject *_wrap_selinux_getpolicytype(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { -+ PyObject *resultobj = 0; -+ char **arg1 = (char **) 0 ; -+ int result; -+ char *temp1 ; -+ -+ { -+ arg1 = &temp1; -+ } -+ if (!PyArg_ParseTuple(args,(char *)":selinux_getpolicytype")) SWIG_fail; -+ result = (int)selinux_getpolicytype(arg1); -+ resultobj = SWIG_From_int((int)(result)); -+ { -+ resultobj = SWIG_Python_AppendOutput(resultobj, PyString_FromString(*arg1)); -+ } -+ return resultobj; -+fail: -+ return NULL; +-static unsigned int myflags; +- + void set_matchpathcon_flags(unsigned int flags) + { + myflags = flags; +@@ -580,7 +585,6 @@ + spec_arr[nspec].context_valid = 1; + } + } +- + spec_arr[nspec].context = context; + + /* Determine if specification has +@@ -797,7 +801,6 @@ + errno = ENOENT; + return -1; + } +- + spec_arr[i].matches++; + + return i; +@@ -877,3 +880,73 @@ + } + } + } ++ ++/* Compare two contexts to see if their differences are "significant", ++ * or whether the only difference is in the user. */ ++int selinux_context_cmp(const security_context_t a, const security_context_t b) ++{ ++ char *rest_a, *rest_b; /* Rest of the context after the user */ ++ if (!a && !b) return 0; ++ if (!a && b) return -1; ++ if (a && !b) return 1; ++ rest_a = strchr((char *)a, ':'); ++ rest_b = strchr((char *)b, ':'); ++ if (!rest_a && !rest_b) return 0; ++ if (!rest_a && rest_b) return -1; ++ if (rest_a && !rest_b) return 1; ++ return strcmp(rest_a, rest_b); ++} ++ ++int selinux_verify_file_context(const char *path, mode_t mode) ++{ ++ security_context_t con = NULL; ++ security_context_t fcontext = NULL; ++ int rc=0; ++ ++ if (myflags & MATCHPATHCON_NOTRANS) ++ rc = lgetfilecon_raw(path, &con); ++ else ++ rc = lgetfilecon(path, &con); ++ if (rc == -1) { ++ if (errno != ENOTSUP) ++ return 1; ++ else ++ return 0; ++ } ++ ++ if (matchpathcon(path,mode,&fcontext) != 0) { ++ if (fcontext == NULL && errno != ENOENT) ++ rc = 1; ++ else ++ rc = 0; ++ } ++ else ++ rc = (selinux_context_cmp(fcontext, con) == 0); ++ freecon(con); ++ freecon(fcontext); ++ return rc; +} + + - SWIGINTERN PyObject *_wrap_getseuserbyname(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - char *arg1 = (char *) 0 ; -@@ -4253,6 +4274,7 @@ - { (char *)"is_context_customizable", _wrap_is_context_customizable, METH_VARARGS, NULL}, - { (char *)"selinux_trans_to_raw_context", _wrap_selinux_trans_to_raw_context, METH_VARARGS, NULL}, - { (char *)"selinux_raw_to_trans_context", _wrap_selinux_raw_to_trans_context, METH_VARARGS, NULL}, -+ { (char *)"selinux_getpolicytype", _wrap_selinux_getpolicytype, METH_VARARGS, NULL}, - { (char *)"getseuserbyname", _wrap_getseuserbyname, METH_VARARGS, NULL}, - { NULL, NULL, 0, NULL } - }; ---- libselinux-1.30.12/src/setrans_client.c~ 2006-06-05 13:20:37.000000000 -0400 -+++ libselinux-1.30.12/src/setrans_client.c 2006-06-12 13:39:55.000000000 -0400 -@@ -16,6 +16,9 @@ - #include "selinux_internal.h" - #include "setrans_internal.h" - -+static int mls_enabled=-1; -+#define MLSENABLED ((mls_enabled==-1) ? (mls_enabled=is_selinux_mls_enabled()) : mls_enabled) ++int selinux_lsetfilecon_default(const char *path) { ++ struct stat st; ++ int rc = -1; ++ security_context_t scontext=NULL; ++ unsigned int localflags=myflags; ++ if (lstat(path, &st) != 0) ++ return rc; + - // Simple cache - static __thread security_context_t prev_t2r_trans=NULL; - static __thread security_context_t prev_t2r_raw=NULL; -@@ -243,6 +246,12 @@ - *rawp = NULL; - return 0; - } ++ set_matchpathcon_flags(myflags | MATCHPATHCON_NOTRANS); + -+ if (! MLSENABLED) { -+ *rawp = strdup(trans); -+ return 0; ++ /* If there's an error determining the context, or it has none, ++ return to allow default context */ ++ if (matchpathcon(path, st.st_mode, &scontext)) { ++ if (scontext == NULL && errno != ENOENT) ++ rc =0; ++ } else { ++ rc = lsetfilecon_raw(path, scontext); ++ freecon(scontext); + } -+ - if (cache_trans) { - if (prev_t2r_trans && strcmp(prev_t2r_trans, trans) == 0) { - *rawp=strdup(prev_t2r_raw); -@@ -279,6 +288,11 @@ - return 0; - } ++ set_matchpathcon_flags(localflags); ++ return rc; ++} +diff --exclude-from=exclude -N -u -r nsalibselinux/utils/matchpathcon.c libselinux-1.30.15/utils/matchpathcon.c +--- nsalibselinux/utils/matchpathcon.c 2006-05-18 12:11:17.000000000 -0400 ++++ libselinux-1.30.15/utils/matchpathcon.c 2006-06-20 11:30:26.000000000 -0400 +@@ -12,19 +12,43 @@ + exit(1); + } -+ if (! MLSENABLED) { -+ *transp = strdup(raw); -+ return 0; ++int printmatchpathcon(char *path, int header) { ++ char *buf; ++ int rc = matchpathcon(path, 0, &buf); ++ if (rc < 0) { ++ fprintf(stderr, "matchpathcon(%s) failed\n", path); ++ return 2; + } ++ if (header) ++ printf("%s\t%s\n", path, buf); ++ else ++ printf("%s\n", buf); ++ ++ freecon(buf); ++ return 0; ++} + - if (cache_trans) { - if (prev_r2t_raw && strcmp(prev_r2t_raw, raw) == 0) { - *transp=strdup(prev_r2t_trans); + int main(int argc, char **argv) + { +- char *buf; +- int rc, i, init = 0; ++ int i, init = 0; + int header=1, opt; ++ int verify=0; ++ int notrans=0; + + if (argc < 2) usage(argv[0]); + +- while ((opt = getopt(argc, argv, "nf:p:")) > 0) { ++ while ((opt = getopt(argc, argv, "Nnf:p:V")) > 0) { + switch (opt) { + case 'n': + header=0; + break; ++ case 'V': ++ verify=1; ++ break; ++ case 'N': ++ notrans=1; ++ set_matchpathcon_flags(MATCHPATHCON_NOTRANS); ++ break; + case 'f': + if (init) { + fprintf(stderr, "%s: -f and -p are exclusive\n", argv[0]); +@@ -54,17 +78,29 @@ + } + } + for (i = optind; i < argc; i++) { +- rc = matchpathcon(argv[i], 0, &buf); +- if (rc < 0) { +- fprintf(stderr, "%s: matchpathcon(%s) failed\n", argv[0], argv[i]); +- return 2; +- } +- if (header) +- printf("%s\t%s\n", argv[i], buf); +- else +- printf("%s\n", buf); ++ if (verify) { ++ if (selinux_verify_file_context(argv[i], 0)) { ++ printf("%s verified.\n", argv[i]); ++ } else { ++ security_context_t con; ++ int rc; ++ if (notrans) ++ rc = lgetfilecon_raw(argv[i], &con); ++ else ++ rc = lgetfilecon(argv[i], &con); + +- freecon(buf); ++ if (rc >= 0) { ++ printf("%s has context %s, should be ", argv[i], con); ++ printmatchpathcon(argv[i], 0); ++ freecon(con); ++ } else { ++ printf("actual context unknown: %s, should be ", strerror(errno)); ++ printmatchpathcon(argv[i], 0); ++ } ++ } ++ } else { ++ printmatchpathcon(argv[i], header); ++ } + } + matchpathcon_fini(); + return 0; diff --git a/libselinux.spec b/libselinux.spec index 9fd4b9b..ffae193 100644 --- a/libselinux.spec +++ b/libselinux.spec @@ -2,10 +2,11 @@ Summary: SELinux library and simple utilities Name: libselinux Version: 1.30.15 -Release: 1 +Release: 2 License: Public domain (uncopyrighted) Group: System Environment/Libraries Source: http://www.nsa.gov/selinux/archives/%{name}-%{version}.tgz +Patch: libselinux-rhat.patch BuildRequires: libsepol-devel >= %{libsepolver} swig Requires: libsepol >= %{libsepolver} setransd @@ -47,6 +48,7 @@ needed for developing SELinux applications. %prep %setup -q +%patch -p1 -b .rhat %build make clean @@ -115,6 +117,9 @@ exit 0 %{_libdir}/python*/site-packages/selinux.py* %changelog +* Mon Jun 19 2006 Dan Walsh 1.30.15-2 +- Add function to compare file context on disk versus contexts in file_contexts file. + * Fri Jun 16 2006 Dan Walsh 1.30.15-1 - Upgrade to latest from NSA * Merged patch from Dan Walsh with: