Blob Blame History Raw
Index: dump/configure.in
===================================================================
RCS file: /cvsroot/dump/dump/configure.in,v
retrieving revision 1.40
diff -u -p -r1.40 configure.in
--- dump/configure.in	2 May 2005 15:10:44 -0000	1.40
+++ dump/configure.in	17 Jun 2006 01:14:39 -0000
@@ -253,6 +253,29 @@ fi
 echo "Not including Mac OSX restore compatibility code by default"
 )
 
+dnl
+dnl Handle --enable-transselinux
+dnl
+AC_ARG_ENABLE([transselinux],
+[  --enable-transselinux      restore can translate SELinux EAs (default is YES)],
+if test "$enableval" = "yes"
+then
+	LTRANSSELINUX="-lselinux"
+	CCTRANSSELINUX="-DTRANSSELINUX"
+	echo "restore can translate SELinux EAs"
+else
+	LTRANSSELINUX=""
+	CCTRANSSELINUX=""
+	echo "restore can not translate SELinux EAs"
+fi
+,
+LTRANSSELINUX="-lselinux"
+CCTRANSSELINUX="-DTRANSSELINUX"
+echo "restore can translate SELinux EAs by default"
+)
+AC_SUBST(LTRANSSELINUX)
+AC_SUBST(CCTRANSSELINUX)
+
 
 dnl
 dnl set $(CC) from --with-cc=value
Index: dump/restore/Makefile.in
===================================================================
RCS file: /cvsroot/dump/dump/restore/Makefile.in,v
retrieving revision 1.13
diff -u -p -r1.13 Makefile.in
--- dump/restore/Makefile.in	2 May 2005 15:10:46 -0000	1.13
+++ dump/restore/Makefile.in	17 Jun 2006 01:14:39 -0000
@@ -7,9 +7,9 @@ top_builddir=	..
 @MCONFIG@
 
 INC=		-I$(top_srcdir)/restore
-ALL_CFLAGS=	@CPPFLAGS@ @CFLAGS@ @CCOPTS@ -pipe $(OPT) $(GINC) $(INC) $(DEFS) @RESTOREDEBUG@
+ALL_CFLAGS=	@CPPFLAGS@ @CFLAGS@ @CCOPTS@ @CCTRANSSELINUX@ -pipe $(OPT) $(GINC) $(INC) $(DEFS) @RESTOREDEBUG@
 ALL_LDFLAGS=	@LDFLAGS@ @LDOPTS@ @STATIC@
-LIBS=		$(GLIBS) -le2p @READLINE@ @ZLIB@ @BZLIB@
+LIBS=		$(GLIBS) -le2p @READLINE@ @ZLIB@ @BZLIB@ @LTRANSSELINUX@
 DEPLIBS=	../compat/lib/libcompat.a
 
 PROG=		restore
Index: dump/restore/main.c
===================================================================
RCS file: /cvsroot/dump/dump/restore/main.c,v
retrieving revision 1.50
diff -u -p -r1.50 main.c
--- dump/restore/main.c	7 Jul 2005 09:16:08 -0000	1.50
+++ dump/restore/main.c	17 Jun 2006 01:14:39 -0000
@@ -127,6 +127,11 @@ unsigned long qfadumpdate;
 long long curtapepos;
 #endif /* USE_QFA */
 
+#ifdef TRANSSELINUX			/*GAN6May06 SELinux MLS */
+int	transselinuxflag = 0;
+char	*transselinuxarg = NULL;
+#endif
+
 long smtc_errno;
 
 #if defined(__linux__) || defined(sunos)
@@ -157,6 +162,9 @@ main(int argc, char *argv[])
 	tapeposflag = 0;
 	createtapeposflag = 0;
 #endif /* USE_QFA */
+#ifdef TRANSSELINUX			/*GAN6May06 SELinux MLS */
+	char transselinuxopt;
+#endif
 
 	/* Temp files should *not* be readable.  We set permissions later. */
 	orig_umask = umask(FORCED_UMASK);
@@ -178,7 +186,11 @@ main(int argc, char *argv[])
 		;                                                               
 	obsolete(&argc, &argv);
 	while ((ch = getopt(argc, argv, 
-		"aA:b:CcdD:f:F:hH:i"
+		"aA:b:CcdD:"
+#ifdef TRANSSELINUX			/*GAN6May06 SELinux MLS */
+		"eE:"
+#endif
+		"f:F:hH:i"
 #ifdef KERBEROS
 		"k"
 #endif
@@ -211,6 +223,17 @@ main(int argc, char *argv[])
 			strncpy(filesys, optarg, NAMELEN);
 			filesys[NAMELEN - 1] = '\0';
 			break;
+#ifdef TRANSSELINUX			/*GAN6May06 SELinux MLS */
+		case 'e':
+			transselinuxflag = 1;
+			transselinuxopt = ch;
+			break;
+		case 'E':
+			transselinuxflag = 1;
+			transselinuxarg = optarg;
+			transselinuxopt = ch;
+			break;
+#endif
 		case 'T':
 			tmpdir = optarg;
 			break;
@@ -340,6 +363,11 @@ main(int argc, char *argv[])
 	if (Afile && command != 'i' && command != 'x' && command != 't')
 		errx(1, "A option is not valid for %c command", command);
 
+#ifdef TRANSSELINUX			/*GAN6May06 SELinux MLS */
+	if (transselinuxflag && !strchr("CirRx", command))
+		errx(1, "%c option is not valid for %c command", transselinuxopt, command);
+#endif
+
 	if (signal(SIGINT, onintr) == SIG_IGN)
 		(void) signal(SIGINT, SIG_IGN);
 	if (signal(SIGTERM, onintr) == SIG_IGN)
@@ -447,7 +475,7 @@ main(int argc, char *argv[])
 		comparedirmodes();
 		checkrestore();
 		if (compare_errors) {
-			printf("Some files were modified!\n");
+			printf("Some files were modified!  %d compare errors\n", compare_errors);
 			exit(2);
 		}
 		break;
@@ -685,24 +713,31 @@ usage(void)
 #define qfaflag
 #endif
 
+#ifdef TRANSSELINUX			/*GAN6May06 SELinux MLS */
+# define tseflag "e"
+# define tsEflag "[-E mls] "
+#else
+# define tseflag
+# define tsEflag
+#endif
 	fprintf(stderr,
 		"usage:"
-		"\t%s -C [-cdH" kerbflag "lMvVy] [-b blocksize] [-D filesystem] [-f file]\n"
-		"\t%s    [-F script] [-L limit] [-s fileno]\n"
-		"\t%s -i [-acdhH" kerbflag "lmMouvVy] [-A file] [-b blocksize] [-f file]\n"
-		"\t%s    [-F script] " qfaflag "[-s fileno]\n"
+		"\t%s -C [-cd" tseflag "H" kerbflag "lMvVy] [-b blocksize] [-D filesystem] " tsEflag"\n"
+		"\t%s    [-f file] [-F script] [-L limit] [-s fileno]\n"
+		"\t%s -i [-acd" tseflag "hH" kerbflag "lmMouvVy] [-A file] [-b blocksize] " tsEflag"\n"
+		"\t%s    [-f file] [-F script] " qfaflag "[-s fileno]\n"
 #ifdef USE_QFA
 		"\t%s -P file [-acdhH" kerbflag "lmMuvVy] [-A file] [-b blocksize]\n"
 		"\t%s    [-f file] [-F script] [-s fileno] [-X filelist] [file ...]\n"
 #endif
-		"\t%s -r [-cdH" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script]\n"
-		"\t%s    [-s fileno] [-T directory]\n"
-		"\t%s -R [-cdH" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script]\n"
-		"\t%s    [-s fileno] [-T directory]\n"
-		"\t%s -t [-cdhH" kerbflag "lMuvVy] [-A file] [-b blocksize] [-f file]\n"
-		"\t%s    [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]\n"
-		"\t%s -x [-acdhH" kerbflag "lmMouvVy] [-A file] [-b blocksize] [-f file]\n"
-		"\t%s    [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]\n",
+		"\t%s -r [-cd" tseflag "H" kerbflag "lMuvVy] [-b blocksize] " tsEflag"\n"
+		"\t%s    [-f file] [-F script] [-s fileno] [-T directory]\n"
+		"\t%s -R [-cd" tseflag "H" kerbflag "lMuvVy] [-b blocksize] " tsEflag"\n"
+		"\t%s    [-f file] [-F script] [-s fileno] [-T directory]\n"
+		"\t%s -t [-cdhH" kerbflag "lMuvVy] [-A file] [-b blocksize]\n"
+		"\t%s    [-f file] [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]\n"
+		"\t%s -x [-acd" tseflag "hH" kerbflag "lmMouvVy] [-A file] [-b blocksize] " tsEflag"\n"
+		"\t%s    [-f file] [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]\n",
 		__progname, white, 
 		__progname, white, 
 #ifdef USE_QFA
Index: dump/restore/restore.h
===================================================================
RCS file: /cvsroot/dump/dump/restore/restore.h,v
retrieving revision 1.33
diff -u -p -r1.33 restore.h
--- dump/restore/restore.h	7 Jul 2005 09:16:08 -0000	1.33
+++ dump/restore/restore.h	17 Jun 2006 01:14:39 -0000
@@ -190,6 +190,11 @@ char	smtcpath[2048];
 #endif
 #endif /* USE_QFA */
 
+#ifdef TRANSSELINUX			/*GAN6May06 SELinux MLS */
+extern int	transselinuxflag;
+extern char	*transselinuxarg;
+#endif
+
 #define do_compare_error \
 	if (++compare_errors >= Lflag && Lflag) { \
 		printf("Compare errors limit reached, exiting...\n"); \
Index: dump/restore/tape.c
===================================================================
RCS file: /cvsroot/dump/dump/restore/tape.c,v
retrieving revision 1.90
diff -u -p -r1.90 tape.c
--- dump/restore/tape.c	8 Jun 2005 13:24:11 -0000	1.90
+++ dump/restore/tape.c	17 Jun 2006 01:14:39 -0000
@@ -570,6 +570,8 @@ again:
 	}
 	if (haderror || (bot_code && !Mflag)) {
 		haderror = 0;
+		if (compare_errors)
+			fprintf(stderr, "%d compare errors so far\n", compare_errors);
 #ifdef sunos
 		fprintf(stderr, "Mount volume %ld\n", (long)newvol);
 #else
Index: dump/restore/xattr.c
===================================================================
RCS file: /cvsroot/dump/dump/restore/xattr.c,v
retrieving revision 1.3
diff -u -p -r1.3 xattr.c
--- dump/restore/xattr.c	8 Jun 2005 13:24:12 -0000	1.3
+++ dump/restore/xattr.c	17 Jun 2006 01:14:39 -0000
@@ -43,6 +43,9 @@ static const char rcsid[] =
 #include <errno.h>
 #include <bsdcompat.h>
 #include <protocols/dumprestore.h>
+#ifdef TRANSSELINUX			/*GAN6May06 SELinux MLS */
+# include <selinux/selinux.h>
+#endif
 #include "restore.h"
 #include "extern.h"
 #include "pathnames.h"
@@ -195,12 +198,12 @@ struct ext2_xattr_entry {
 static int lsetxattr __P((const char *, const char *, void *, size_t, int));
 static ssize_t lgetxattr __P((const char *, const char *, void *, size_t));
 static ssize_t llistxattr __P((const char *, char *, size_t));
-static int xattr_cb_list __P((char *, char *, int, void *));
-static int xattr_cb_set __P((char *, char *, int, void *));
-static int xattr_cb_compare __P((char *, char *, int, void *));
+static int xattr_cb_list __P((char *, char *, int, int, void *));
+static int xattr_cb_set __P((char *, char *, int, int, void *));
+static int xattr_cb_compare __P((char *, char *, int, int, void *));
 static int xattr_verify __P((char *));
 static int xattr_count __P((char *, int *));
-static int xattr_walk __P((char *, int (*)(char *, char *, int, void *), void *));
+static int xattr_walk __P((char *, int (*)(char *, char *, int, int, void *), void *));
 
 static int
 lsetxattr(const char *path, const char *name, void *value, size_t size, int flags)
@@ -406,8 +409,9 @@ fail:
  */
 
 static int
-xattr_cb_list(char *name, char *value, int valuelen, void *private)
+xattr_cb_list(char *name, char *value, int valuelen, int isSELinux, void *private)
 {
+	isSELinux;
 	value[valuelen] = '\0';
 	printf("EA: %s:%s\n", name, value);
 
@@ -415,37 +419,64 @@ xattr_cb_list(char *name, char *value, i
 }
 
 static int
-xattr_cb_set(char *name, char *value, int valuelen, void *private)
+xattr_cb_set(char *name, char *value, int valuelen, int isSELinux, void *private)
 {
 	char *path = (char *)private;
-
-	if (lsetxattr(path, name, value, valuelen, 0) < 0) {
-		warn("lsetxattr %s failed", path);
+	int err;
+	
+	isSELinux;
+#ifdef TRANSSELINUX			/*GAN6May06 SELinux MLS */
+	if (isSELinux)
+		err = lsetfilecon(path, value);
+	else
+#endif
+		err = lsetxattr(path, name, value, valuelen, 0);
+	
+	if (err) {
+		warn("%s: EA set %s:%s failed", path, name, value);
 		return FAIL;
 	}
+	
 	return GOOD;
 }
 
 static int
-xattr_cb_compare(char *name, char *value, int valuelen, void *private)
+xattr_cb_compare(char *name, char *value, int valuelen, int isSELinux, void *private)
 {
 	char *path = (char *)private;
 	char valuef[XATTR_MAXSIZE];
 	int valuesz;
-
-	valuesz = lgetxattr(path, name, valuef, XATTR_MAXSIZE);
-	if (valuesz < 0) {
-		warn("%s: lgetxattr failed\n", path);
-		return FAIL;
+	
+	isSELinux;
+#ifdef TRANSSELINUX			/*GAN6May06 SELinux MLS */
+	if (isSELinux)
+	{
+		security_context_t con = NULL;
+		
+		if (lgetfilecon(path, &con) < 0) {
+			warn("%s: EA compare lgetfilecon failed\n", path);
+			return FAIL;
+		}
+		
+		valuesz = strlen(con) + 1;
+		valuef[0] = 0;
+		strncat(valuef, con, sizeof valuef);
+		freecon(con);
 	}
-
-	if (valuesz != valuelen) {
-		fprintf(stderr, "%s: EA %s value changed\n", path, value);
-		return FAIL;
+	else {
+#endif
+		valuesz = lgetxattr(path, name, valuef, XATTR_MAXSIZE);
+		if (valuesz < 0) {
+			warn("%s: EA compare lgetxattr failed\n", path);
+			return FAIL;
+		}
+#ifdef TRANSSELINUX			/*GAN6May06 SELinux MLS */
 	}
-
-	if (memcmp(value, valuef, valuelen)) {
-		fprintf(stderr, "%s: EA %s value changed\n", path, value);
+#endif
+	
+	if (valuesz != valuelen || memcmp(value, valuef, valuelen)) {
+		/* GAN24May06: show name and new value for user to compare */
+		fprintf(stderr, "%s: EA %s:%s value changed to %s\n", path, name, value, valuef);
 		return FAIL;
 	}
 
@@ -508,7 +539,7 @@ xattr_count(char *buffer, int *count)
 }
 
 static int
-xattr_walk(char *buffer, int (*xattr_cb)(char *, char *, int, void *), void *private)
+xattr_walk(char *buffer, int (*xattr_cb)(char *, char *, int, int, void *), void *private)
 {
 	struct ext2_xattr_entry *entry;
 
@@ -518,6 +549,7 @@ xattr_walk(char *buffer, int (*xattr_cb)
 	     	char name[XATTR_MAXSIZE], value[XATTR_MAXSIZE];
 		int off;
 		int convertacl = 0;
+		int convertcon = 0;
 
 		switch (entry->e_name_index) {
 		case EXT2_XATTR_INDEX_USER:
@@ -539,6 +571,9 @@ xattr_walk(char *buffer, int (*xattr_cb)
 			break;
 		case EXT2_XATTR_INDEX_SECURITY:
 			strcpy(name, "security.");
+#ifdef TRANSSELINUX			/*GAN6May06 SELinux MLS */
+			convertcon = transselinuxflag;
+#endif
 			break;
 		default:
 			fprintf(stderr, "Unknown EA index\n");
@@ -564,8 +599,36 @@ xattr_walk(char *buffer, int (*xattr_cb)
 			entry->e_value_size = size;
 			free(acl);
 		}
+		
+#ifdef TRANSSELINUX			/*GAN6May06 SELinux MLS */
+		if (convertcon  &&  strcmp(name, "security.selinux"))
+			convertcon = 0;	/*GAN24May06 only for selinux */
+		
+		if (convertcon)
+		{
+			security_context_t con = NULL;
+			int err;
+			
+			if (!transselinuxarg)
+				err = security_canonicalize_context(value, &con);
+			else {
+				strncat(value, transselinuxarg, sizeof value);
+				err = security_canonicalize_context_raw(value, &con);
+			}
+			
+			if (err < 0) {
+				warn("%s: EA canonicalize failed\n", value);
+				return FAIL;
+			}
+
+			entry->e_value_size = strlen(con) + 1;
+			value[0] = 0;
+			strncat(value, con, sizeof value);
+			freecon(con);
+		}
+#endif
 
-		if (xattr_cb(name, value, entry->e_value_size, private) != GOOD)
+		if (xattr_cb(name, value, entry->e_value_size, convertcon, private) != GOOD)
 			return FAIL;
 	}