1
0
Эх сурвалжийг харах

Ticket #47555 - db2bak.pl issue when specifying non-default directory

Bug description: db2bak.pl takes an option "-a backupdir", which is
supposed to be generated by the server and used as a backup directory.
But since the created directory inherits the parent's selinux context,
it fails to store the backup files in the directory.

Fix description: As the reporter agaviola suggested, it should be a
good idea to add one more level to the archive directory.
$archivedir = "${archivedir}/ID-${yr}_${mn}_${dy}_${h}_${m}_${s}";
But to keep the backward compatibility, introducing a new option "-A
backupdir" and when "-A" is given, storing the backup files in the
nested backup directory.  If the option is "-a backupdir", the backup
files are stored in the backupdir.

Respecting the selinux policy, the server and its utilities are not
supposed to create a file/directory where it is not allowed.  This
patch creates a symlink from the back up location to the specified
path by a user.  bak2db.pl follows the symlink and restore from the
back up directory.

https://fedorahosted.org/389/ticket/47555

Reviewed by rmeggins (Thank you, Rich!!)
Noriko Hosoi 12 жил өмнө
parent
commit
8db3a1ad07

+ 3 - 0
ldap/admin/src/scripts/bak2db.pl.in

@@ -112,6 +112,9 @@ if ($archivedir eq ""){
     &usage;
     exit(1);
 }
+if ((-e $archivedir) && (-l $archivedir)) { # symlink
+    $archivedir = readlink($archivedir);
+}
 
 #
 # Contruct the task entry

+ 41 - 2
ldap/admin/src/scripts/db2bak.pl.in

@@ -40,6 +40,7 @@
 #
 
 use lib qw(@perlpath@);
+use File::Basename;
 use DSUtil;
 
 DSUtil::libpath_add("@nss_libdir@");
@@ -61,6 +62,7 @@ sub usage {
     print(STDERR "        -w -          - Prompt for Directory Manager's password\n");
     print(STDERR "        -Z serverID   - Server instance identifier\n");
     print(STDERR "        -j filename   - Read Directory Manager's password from file\n");
+    print(STDERR "        -A backupdir  - Backup directory (backupdir/ID-<date_time>)\n");
     print(STDERR "        -a backupdir  - Backup directory\n");
     print(STDERR "        -t dbtype     - Database type (default: ldbm database)\n");
     print(STDERR "        -P protocol   - STARTTLS, LDAPS, LDAPI, LDAP (default: uses most secure protocol available)\n");
@@ -68,9 +70,13 @@ sub usage {
     print(STDERR "        -h            - Display usage\n");
 }
 
+$nestit = 0;
 while ($i <= $#ARGV) {
     if ("$ARGV[$i]" eq "-a") {    # backup directory
         $i++; $archivedir = $ARGV[$i];
+    } elsif ("$ARGV[$i]" eq "-A") {    # backup directory
+        $nestit = 1;
+        $i++; $archivedir = $ARGV[$i];
     } elsif ("$ARGV[$i]" eq "-D") {    # Directory Manager
         $i++; $rootdn = $ARGV[$i];
     } elsif ("$ARGV[$i]" eq "-w") {    # Directory Manager's password
@@ -114,9 +120,32 @@ $mybakdir = "@localstatedir@/lib/@PACKAGE_NAME@/slapd-$servid/bak";
 ($s, $m, $h, $dy, $mn, $yr, $wdy, $ydy, $r) = localtime(time);
 $mn++; $yr += 1900;
 $taskname = "backup_${yr}_${mn}_${dy}_${h}_${m}_${s}";
+$symname = "";
+$dirname = "";
 if ($archivedir eq "") {
     $archivedir = "${mybakdir}/$servid-${yr}_${mn}_${dy}_${h}_${m}_${s}";
+    print("Back up directory: $archivedir\n");
+} else {
+    if ($nestit == 1) {
+        $archivebase = "${servid}-${yr}_${mn}_${dy}_${h}_${m}_${s}";
+        $dirname = "${archivedir}";
+        $archivedir = "${dirname}/${archivebase}";
+    } else {
+        my @archivedirs = split(/\//, $archivedir);
+        $archivebase = $archivedirs[-1];
+        $dirname = dirname(${archivedir});
+    }
+    if ($mybakdir =~ /^$dirname/) { # $mybakdir is parent; no symlink needed
+        $symname = "";
+    } else {
+        $symname = $archivedir;
+    }
+    print("Back up directory: $archivedir\n");
+    # If an archive dir is specified, create it as a symlink pointing
+    # to the default backup dir not to violate the selinux policy.
+    $archivedir = "${mybakdir}/${archivebase}";
 }
+
 $dn = "dn: cn=$taskname, cn=backup, cn=tasks, cn=config\n";
 $misc = "objectclass: top\nobjectclass: extensibleObject\n";
 $cn = "cn: $taskname\n";
@@ -124,14 +153,24 @@ $nsarchivedir = "nsArchiveDir: $archivedir\n";
 $nsdbtype = "nsDatabaseType: $dbtype\n";
 $entry = "${dn}${misc}${cn}${nsarchivedir}${nsdbtype}";
 
-print("Back up directory: $archivedir\n");
-
 $rc = DSUtil::ldapmod($entry, %info);
 
 $dn =~ s/^dn: //;
 $dn =~ s/\n//;
 if($rc == 0){
     print "Successfully added task entry \"$dn\"\n";
+    if (($symname ne "") && ($dirname ne "")) {
+        if (!(-d $dirname)) {
+            mkdir ($dirname);
+        }
+        if (-e $symname) {
+            unlink ($symname);
+        }
+        if (!symlink($archivedir, $symname)) {
+            print "Failed to create a symlink from $archivedir to $symname\n";
+            exit(1);
+        }
+    }
 } else {
     print "Failed to add task entry \"$dn\" error ($rc)\n";
 }