All of lore.kernel.org
 help / color / mirror / Atom feed
* Yet another pass at libselinux/matchpathcon fix.
@ 2006-06-21 19:50 Daniel J Walsh
  0 siblings, 0 replies; only message in thread
From: Daniel J Walsh @ 2006-06-21 19:50 UTC (permalink / raw)
  To: Stephen Smalley, SE Linux

[-- Attachment #1: Type: text/plain, Size: 478 bytes --]

functions renamed to
selinux_file_context_cmp and selinux_file_context_verify

Translation is postponed until last second.  I think for matchpathcon 
the default should be NOTRANS.

Tools that display should have to translate.  I think we had the other 
default because of upgrade from FC4?  Which we will need to handle when 
upgrading RHEL4 if
we decide to change default.

This change will slow down apps that call matchpathcon many times with 
translations turned on.


Dan

[-- Attachment #2: libselinux-rhat.patch --]
[-- Type: text/x-patch, Size: 7842 bytes --]

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-21 15:26:36.000000000 -0400
@@ -429,8 +429,19 @@
    Caller must free the returned strings via free. */
 extern int getseuserbyname(const char *linuxuser, char **seuser, char **level);
 
+/* This function compares two file context, ignoring the user component */
+int selinux_file_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 0 on match non 0 on failure */
+int selinux_file_context_verify(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-21 15:26:36.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 <dwalsh@redhat.com>.
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-21 15:37:18.000000000 -0400
@@ -20,10 +20,12 @@
 #endif
 default_printf(const char *fmt, ...) 
 {
+#ifdef DEBUG
 	va_list ap;
 	va_start(ap, fmt);
 	vfprintf(stderr, fmt, ap);
 	va_end(ap);
+#endif
 }
 
 static void 
@@ -50,7 +52,7 @@
 static int default_canoncon(const char *path, unsigned lineno, char **context)
 {
 	char *tmpcon;
-	if (security_canonicalize_context(*context, &tmpcon) < 0) {
+	if (security_canonicalize_context_raw(*context, &tmpcon) < 0) {
 		if (errno == ENOENT)
 			return 0;
 		if (lineno)
@@ -74,7 +76,7 @@
 		mycanoncon = &default_canoncon;
 }
 
-static unsigned int myflags;
+static __thread unsigned int myflags;
 
 void set_matchpathcon_flags(unsigned int flags)
 {
@@ -552,21 +554,6 @@
 		
 	skip_type:
 		if (strcmp(context, "<<none>>")) {
-			char *tmpcon = NULL;
-
-			if (myflags & MATCHPATHCON_NOTRANS)
-				goto skip_trans;
-
-			if (selinux_raw_to_trans_context(context, &tmpcon)) {
-				myprintf("%s: line %u has invalid "
-					 "context %s\n",
-					 path, lineno, context);
-				return 0;
-			}
-			free(context);
-			context = tmpcon;
-
-skip_trans:
 			if (myflags & MATCHPATHCON_VALIDATE) {
 				if (myinvalidcon) {
 					/* Old-style validation of context. */
@@ -831,7 +818,12 @@
 		spec_arr[i].context_valid = 1;
 	}
 
-	*con = strdup(spec_arr[i].context);
+	if (myflags & MATCHPATHCON_NOTRANS) {
+		*con = strdup(spec_arr[i].context);
+	} else {
+		if (selinux_raw_to_trans_context(spec_arr[i].context, con)) 
+			return -1;
+	}
 	if (!(*con))
 		return -1;
 
@@ -877,3 +869,72 @@
 		}
 	}
 }
+
+/* Compare two contexts to see if their differences are "significant",
+ * or whether the only difference is in the user. */
+int selinux_file_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_file_context_verify(const char *path, mode_t mode)
+{
+ 	security_context_t con = NULL;
+ 	security_context_t fcontext = NULL;
+	unsigned int localflags=myflags;
+	int rc=0;
+
+	rc = lgetfilecon_raw(path, &con);
+	if (rc == -1) {
+		if (errno != ENOTSUP)
+			return 1;
+	        else
+			return 0;
+	}
+
+	set_matchpathcon_flags(myflags | MATCHPATHCON_NOTRANS);
+	if (matchpathcon(path,mode,&fcontext) != 0)  {
+		if (errno != ENOENT) 
+			rc = 1;
+		else
+			rc = 0;
+	} 
+	else 
+		rc = (selinux_file_context_cmp(fcontext, con) == 0);
+	set_matchpathcon_flags(localflags);
+	freecon(con);
+	freecon(fcontext); 
+	return rc;
+}
+
+
+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;
+
+	set_matchpathcon_flags(myflags | MATCHPATHCON_NOTRANS);
+
+	/* 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 (errno == ENOENT) rc = 0;
+	} else 	{
+		rc = lsetfilecon_raw(path, scontext);
+		freecon(scontext);
+	}
+	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-21 15:26:36.000000000 -0400
@@ -12,19 +12,44 @@
 	exit(1);
 }
 
+int printmatchpathcon(char *path, int header) {
+	char *buf;
+	int rc = matchpathcon(path, 0, &buf);
+	if (rc < 0) {
+		fprintf(stderr, "matchpathcon(%s) failed: %s\n", path, strerror(errno));
+		return 1;
+	}
+	if (header)
+		printf("%s\t%s\n", path, buf);
+	else
+		printf("%s\n", buf);
+	
+	freecon(buf);
+	return 0;
+}
+
 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;
+	int error=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,18 +79,30 @@
 		}
 	}
 	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_file_context_verify(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);
+					error += printmatchpathcon(argv[i], 0);
+					freecon(con);
+				} else {
+					printf("actual context unknown: %s, should be ", strerror(errno));
+					error += printmatchpathcon(argv[i], 0);
+				}
+			}
+		} else {
+			error += printmatchpathcon(argv[i], header);
+		}
 	}
 	matchpathcon_fini();
-	return 0;
+	return error;
 }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2006-06-21 19:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-21 19:50 Yet another pass at libselinux/matchpathcon fix Daniel J Walsh

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.