瀏覽代碼

Resolves: bug 489360
Bug Description: Replication Bind Failure After Migration from DS 7.1
Reviewed by: nkinder (Thanks!)
Fix Description: We have to quote shell metacharacters before passing them to the shell. I added a new function shellEscape to use for this purpose. We really should shell escape anything passed to system() or back ticks ``. Certainly passwords should contain shell meta characters so I changed places where we use passwords to use shellEscape to pass them to pwdhash or migratecred. I also chomp() the output of migratecred to remove the trailing newline. With the fix, I was able to run setup with a root password of `~!@#$%^&*()\\|[]{}:;<>?/"\ and successfully authenticate.
Platforms tested: RHEL5
Flag Day: no
Doc impact: no

Rich Megginson 16 年之前
父節點
當前提交
a0ab21a70e
共有 2 個文件被更改,包括 23 次插入6 次删除
  1. 6 3
      ldap/admin/src/scripts/DSMigration.pm.in
  2. 17 3
      ldap/admin/src/scripts/Util.pm.in

+ 6 - 3
ldap/admin/src/scripts/DSMigration.pm.in

@@ -222,19 +222,22 @@ sub getNewDbDir {
 sub migrateCredentials {
 sub migrateCredentials {
     my ($ent, $attr, $mig, $inst) = @_;
     my ($ent, $attr, $mig, $inst) = @_;
     my $oldval = $ent->getValues($attr);
     my $oldval = $ent->getValues($attr);
+    my $qoldval = shellEscape($oldval);
 
 
     # Older versions of the server on x86 systems and other systems that do not use network byte order
     # Older versions of the server on x86 systems and other systems that do not use network byte order
     # stored the credentials incorrectly.  The first step is to determine if this is the case.  We
     # stored the credentials incorrectly.  The first step is to determine if this is the case.  We
     # migrate using the same server root to see if we get the same output as we input.
     # migrate using the same server root to see if we get the same output as we input.
     debug(3, "In migrateCredentials - see how old credentials were encoded.\n");
     debug(3, "In migrateCredentials - see how old credentials were encoded.\n");
-    my $testval = `@bindir@/migratecred -o $mig->{actualsroot}/$inst -n $mig->{actualsroot}/$inst -c \'$oldval\'`;
+    my $testval = `@bindir@/migratecred -o $mig->{actualsroot}/$inst -n $mig->{actualsroot}/$inst -c $qoldval`;
+    chomp($testval);
     if ($testval ne $oldval) { # need to turn on the special flag
     if ($testval ne $oldval) { # need to turn on the special flag
         debug(3, "Credentials not encoded correctly.  oldval $oldval not equal to testval $testval.  The value will be re-encoded correctly.\n");
         debug(3, "Credentials not encoded correctly.  oldval $oldval not equal to testval $testval.  The value will be re-encoded correctly.\n");
         $ENV{MIGRATE_BROKEN_PWD} = "1"; # decode and re-encode correctly
         $ENV{MIGRATE_BROKEN_PWD} = "1"; # decode and re-encode correctly
     }
     }
         
         
-    debug(3, "Executing @bindir@/migratecred -o $mig->{actualsroot}/$inst -n @instconfigdir@/$inst -c \'$oldval\' . . .\n");
-    my $newval = `@bindir@/migratecred -o $mig->{actualsroot}/$inst -n @instconfigdir@/$inst -c \'$oldval\'`;
+    debug(3, "Executing @bindir@/migratecred -o $mig->{actualsroot}/$inst -n @instconfigdir@/$inst -c $qoldval . . .\n");
+    my $newval = `@bindir@/migratecred -o $mig->{actualsroot}/$inst -n @instconfigdir@/$inst -c $qoldval`;
+    chomp($newval);
     delete $ENV{MIGRATE_BROKEN_PWD}; # clear the flag, if set
     delete $ENV{MIGRATE_BROKEN_PWD}; # clear the flag, if set
     debug(3, "Converted old value [$oldval] to new value [$newval] for attr $attr in entry ", $ent->getDN(), "\n");
     debug(3, "Converted old value [$oldval] to new value [$newval] for attr $attr in entry ", $ent->getDN(), "\n");
     return $newval;
     return $newval;

+ 17 - 3
ldap/admin/src/scripts/Util.pm.in

@@ -47,11 +47,11 @@ require Exporter;
 @ISA       = qw(Exporter);
 @ISA       = qw(Exporter);
 @EXPORT    = qw(portAvailable getAvailablePort isValidDN addSuffix getMappedEntries
 @EXPORT    = qw(portAvailable getAvailablePort isValidDN addSuffix getMappedEntries
                 process_maptbl check_and_add_entry getMappedEntries
                 process_maptbl check_and_add_entry getMappedEntries
-                getHashedPassword debug createInfFromConfig
+                getHashedPassword debug createInfFromConfig shellEscape
                 isValidServerID isValidUser makePaths getLogin remove_tree remove_pidfile);
                 isValidServerID isValidUser makePaths getLogin remove_tree remove_pidfile);
 @EXPORT_OK = qw(portAvailable getAvailablePort isValidDN addSuffix getMappedEntries
 @EXPORT_OK = qw(portAvailable getAvailablePort isValidDN addSuffix getMappedEntries
                 process_maptbl check_and_add_entry getMappedEntries
                 process_maptbl check_and_add_entry getMappedEntries
-                getHashedPassword debug createInfFromConfig
+                getHashedPassword debug createInfFromConfig shellEscape
                 isValidServerID isValidUser makePaths getLogin remove_tree remove_pidfile);
                 isValidServerID isValidUser makePaths getLogin remove_tree remove_pidfile);
 
 
 use strict;
 use strict;
@@ -679,6 +679,20 @@ sub process_maptbl
     return $mapper;
     return $mapper;
 }
 }
 
 
+# given a string, escape the characters in the string
+# so that it can be safely passed to the shell via
+# the system() call or `` backticks
+sub shellEscape {
+    my $val = shift;
+    # first, escape the double quotes and slashes
+    $val =~ s/([\\"])/\\$1/g; # " font lock fun
+    # next, escape the rest of the special chars
+    my $special = '!$\' @#%^&*()|[\]{};:<>?/`';
+    $val =~ s/([$special])/\\$1/g;
+
+    return $val;
+}
+
 sub getHashedPassword {
 sub getHashedPassword {
     my $pwd = shift;
     my $pwd = shift;
     my $alg = shift;
     my $alg = shift;
@@ -691,7 +705,7 @@ sub getHashedPassword {
     if ($alg) {
     if ($alg) {
         $cmd .= " -s $alg";
         $cmd .= " -s $alg";
     }
     }
-    $cmd .= " \'$pwd\'";
+    $cmd .= " " . shellEscape($pwd);
     my $hashedpwd = `$cmd`;
     my $hashedpwd = `$cmd`;
     chomp($hashedpwd);
     chomp($hashedpwd);