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 #include #include +#ifdef TRANSSELINUX /*GAN6May06 SELinux MLS */ +# include +#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; }