All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel J Walsh <dwalsh@redhat.com>
To: Stephen Smalley <sds@tycho.nsa.gov>
Cc: SE Linux <selinux@tycho.nsa.gov>
Subject: I have redone the original patch for libselinux
Date: Tue, 20 Jun 2006 16:28:56 -0400	[thread overview]
Message-ID: <44985A88.809@redhat.com> (raw)
In-Reply-To: <1150826101.17557.183.camel@moss-spartans.epoch.ncsc.mil>

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

Now have a function called selinux_context_cmp which will compare two 
context ignoring the user componant for equivalency.

Fixed selinux_verify_file_context to work properly,  default_canoncon 
now checks myflags for MATCHPATHCON_NOTRANS

Added selinux_lsetfilecon_default(const char* path)

to set a file context to match the entry in file_contexts file.  
Changing install command to use this function improved perfomance

# time install resolv.conf /etc/

real    0m0.251s
user    0m0.176s
sys     0m0.040s
# ls -lZ /etc/resolv.conf
-rwxr-xr-x  root root system_u:object_r:net_conf_t     /etc/resolv.conf
# time ./ginstall resolv.conf /etc/

real    0m0.007s
user    0m0.000s
sys     0m0.008s
# ls -lZ /etc/resolv.conf
-rwxr-xr-x  root root system_u:object_r:net_conf_t     /etc/resolv.conf


[-- Attachment #2: diff --]
[-- Type: text/plain, Size: 7261 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-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);
 
+/* 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 <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-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;
 }
 
-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;
+}
+
+
+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 (scontext == NULL && 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-20 11:30:26.000000000 -0400
@@ -12,19 +12,43 @@
 	exit(1);
 }
 
+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;
+}
+
 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;

  reply	other threads:[~2006-06-20 20:28 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <4497FCCF.1030805@redhat.com>
     [not found] ` <1150812243.17557.79.camel@moss-spartans.epoch.ncsc.mil>
2006-06-20 15:33   ` New patch for libselinux Daniel J Walsh
2006-06-20 16:49     ` Stephen Smalley
2006-06-20 17:11       ` Daniel J Walsh
2006-06-20 17:33         ` Stephen Smalley
2006-06-20 17:55           ` Stephen Smalley
2006-06-20 20:28             ` Daniel J Walsh [this message]
2006-06-21 17:50               ` I have redone the original " Stephen Smalley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=44985A88.809@redhat.com \
    --to=dwalsh@redhat.com \
    --cc=sds@tycho.nsa.gov \
    --cc=selinux@tycho.nsa.gov \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.