Given that my shadowmountrsync procedure allows backing up of full Windows acl's, I figured it was only fair to write something that would allow for full backing up of SElinux attributes.
Hopefully this routine will become obsolete in BackupPC 4.0 since Craig is talking about adding extended attribute support. But meanwhile feel free to use this routine. Note almost all the complexity is due to the following three elements: 1. I want to only include SElinux attributes for the actual files being backed up (i.e., include the included paths and exclude the excluded ones) 2. But unfortunately, BackupPC does not allow you to pass the corresponding BackupPC %Conf hashes to DumpPreShareCmd, so I have to encode and push them myself using perl code in the config.pl file. [NB: it would *really* be nice if future versions of backuppc allowed the Dump/Restore/Archive Pre/Post commands to access the full %Conf hash] 3. I want to be able to run the script as suidperl so I don't have to ssh as root or allow separately via /etc/sudoers So, here is the code in 2 parts: 1. First some perl code to add to your config.pl file: Don't forget to make sure that BackupPC_Dumplinux.pl is in your path. Note I have set it up to ssh as user 'root' but if running as suidperl, this is not necessary. ----------------------------------------------------------------------------- # Code to generate listing of SELinux attributes for each share my ($includepaths, $excludepaths); #Generate include/exclude paths foreach (@{$Conf{RsyncShareName}}) { my @includearr = defined($Conf{BackupFilesOnly}{$_}) ? @{$Conf{BackupFilesOnly}{$_}} : (); $includepaths .= " -i $_ " . join(" ", @includearr) if @includearr > 0; my @excludearr = defined($Conf{BackupFilesExclude}{$_}) ? @{$Conf{BackupFilesExclude}{$_}} : (); $excludepaths .= " -e $_ " . join(" ", @excludearr) if @excludearr > 0; } $includepaths =~ s#//+#/#g; #Remove redundant slashes $excludepaths =~ s#//+#/#g; $Conf{DumpPreShareCmd} = '$sshPath -q -x -l root $hostIP BackupPC_DumpSElinux.pl $share/SElinuxDump.gz $share' . $includepaths . $excludepaths; ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- 2. The shell script called to dump the SElinux attributes: Note I run it as suidperl (and note that I bypass tainting) using: chown root.backuppc BackupPC_DumpSElinux.pl chmod 4754 BackupPC_DumplSEinux.pl This allows me to run BackupPC as user backuppc without full root privileges. --------------------------------------------------------------------------- #! /usr/bin/suidperl -w # ## BackupPC_DumpSElinux.pl - suid perl script to dump SElinux context for input # share to output file for use by $Conf{DumpPreShareCmd} # # If not running as root, this script can be set suidperl # as follows: # chown root.backuppc BackupPC_DumpSElinux.pl # chmod 4754 BackupPC_DumpSElinux.pl # # Usage: BackupPC_DumpSElinux.pl <outfile> <share> # [ -i <share1> <path1a> <path1b>...] # [ -e <share1> <path1a> <path1b>...] # [ -i <share2> <path2a> <path2b>...] # [ -e <share2> <path2a> <path2b>...] # # where: # <outfile> = Place to store the (compressed) output # (prior to adding the .gz suffix # <share> = Root of the share # -i|-e = Include|Exclude paths # <pathNx> = path relative to <shareN> # <includes> = One or more arguments representing paths to *include* # <excludes> = One or more optional arguments representating paths to *exclude* # Searches only include on includes/excludes whose <shareN> matches <share> # Note: this is necessary so we can pre-evaluate variables and pass # everything to $Conf{DumpPreShareCmd} # # Jeffrey J. Kosowsky # Copyright December 2009 # Version 0.5 # $ENV{'PATH'} = ''; # This script is entirely internal, so needs no $ENV{'SHELL'} = ''; # shell or path $ENV{'IFS'} = ''; use File::Basename; use Fcntl; use strict; use warnings; map ({ /(.*)/, $_=$1 } @ARGV); #Untaint args my ($outfile, $share, @args) = @ARGV; my (@includelist, @excludelist, $path); die "Wrong number of arguments...\n" if $#ARGV < 1; my $flag = 0; $share = "/" . $share; #Add initial slash $share =~ s#/$##; #Remove trailing slash $share =~ s#//+#/#; #Remove double slashes die "Share '$share' doesn't exist...\n" unless -e $share; while (@args) { $_= shift(@args); $_ = "/" . $_; #Add initial slash if (m#^/-(i|e)$#) { #include or exclude flag $flag = $1; $_ = shift @args; $_ = "/" . $_; #Add initial slash s#//+#/#g; #Remove double slashes $flag = 0 unless m#^$share/?$#; next; } $path = $share . "/" . $_; $path =~ s#//+#/#g; #Remove double slashes if( $flag eq 'i' ) { #Include list push @includelist, $path; #Add to include } elsif( $flag eq 'e' ) { push @excludelist, "-path", "$path"; #Add to exclude push @excludelist, "-o"; } } push @includelist, $share unless @includelist; # If no includes, then just search the whole share if (@excludelist > 0) { pop @excludelist; #Pop trailing -o unshift @excludelist, "\("; push @excludelist, "\)", "-prune", "-o"; } my @findstring = ("/usr/bin/find", @includelist, "-xdev", @excludelist, "-printf", "%p %Z\\n"); $outfile =~ s#//+#/#g; #Remove redundant slashes unless ((-f $outfile && -w $outfile ) || ( ! -e $outfile && -w dirname($outfile))) { $!=10; die "Error: '$outfile' is not writable\n"; } #Note following three lines are necessary since we need to make sure file #is writable by the UID (and not just the EUID) die "Couldn't open $outfile for writing\n" unless sysopen STDOUT, $outfile, O_CREAT | O_TRUNC, 0600; #Note clobbers before opening close($outfile); chown($<,$>,$outfile); # chown $UID.$EUID where $EUID=0 (root) if suidperl die "Couldn't gzip onto $outfile\n" unless open STDOUT, "| /bin/gzip >> $outfile"; die "cannot dup STDERR to STDOUT: $!\n" unless open STDERR, ">&STDOUT"; select STDERR; $| = 1; select STDOUT; $| = 1; system(@findstring); close($outfile); #chown(0,0,$outfile); chown($>,$>,$outfile); # chown $EUID.$EUID where $EUID=0 (root) if suidperl exit 0; ---------------------------------------------------------------------------- ------------------------------------------------------------------------------ This SF.Net email is sponsored by the Verizon Developer Community Take advantage of Verizon's best-in-class app development support A streamlined, 14 day to market process makes app distribution fast and easy Join now and get one step closer to millions of Verizon customers http://p.sf.net/sfu/verizon-dev2dev _______________________________________________ BackupPC-users mailing list BackupPC-users@lists.sourceforge.net List: https://lists.sourceforge.net/lists/listinfo/backuppc-users Wiki: http://backuppc.wiki.sourceforge.net Project: http://backuppc.sourceforge.net/