cryptohome: Delete the right path when overriding with a passthrough dir.

The relative path |tracked_dir| now starts from "root/" or "user/",
hence the base directory must be one level up from the "user" directory.

BUG=chromium:729997
TEST=crs_workon_make cryptohome --test
TEST=Manual step shown in the bug

Change-Id: If91d17c8897c4d4c8c77c86d4e46d62f429c75dd
Reviewed-on: https://chromium-review.googlesource.com/526833
Commit-Ready: Kazuhiro Inaba <kinaba@chromium.org>
Tested-by: Kazuhiro Inaba <kinaba@chromium.org>
Reviewed-by: Ryo Hashimoto <hashimoto@chromium.org>
(cherry picked from commit 51dd8de2eea1697ce6f0e4b813751000998cd147)
Reviewed-on: https://chromium-review.googlesource.com/527744
Reviewed-by: Kazuhiro Inaba <kinaba@chromium.org>
Commit-Queue: Kazuhiro Inaba <kinaba@chromium.org>
Trybot-Ready: Kazuhiro Inaba <kinaba@chromium.org>
diff --git a/cryptohome/mount.cc b/cryptohome/mount.cc
index ba7f809..3d0040a 100644
--- a/cryptohome/mount.cc
+++ b/cryptohome/mount.cc
@@ -980,7 +980,7 @@
      return false;
   }
 
-  const FilePath user_home(GetMountedUserHomePath(obfuscated_username));
+  const FilePath mount_dir(GetUserMountDirectory(obfuscated_username));
 
   // The call is allowed to partially fail if directory creation fails, but we
   // want to have as many of the specified tracked directories created as
@@ -989,7 +989,7 @@
   for (const auto& tracked_dir : GetTrackedSubdirectories()) {
     const FilePath tracked_dir_path = dest_dir.Append(tracked_dir);
     if (mount_type_ == MountType::ECRYPTFS) {
-      const FilePath userside_dir = user_home.Append(tracked_dir);
+      const FilePath userside_dir = mount_dir.Append(tracked_dir);
       // If non-pass-through dir with the same name existed - delete it
       // to prevent duplication.
       if (!is_new && platform_->DirectoryExists(userside_dir) &&
diff --git a/cryptohome/mount.h b/cryptohome/mount.h
index 3467446..c89911a 100644
--- a/cryptohome/mount.h
+++ b/cryptohome/mount.h
@@ -846,6 +846,7 @@
   FRIEND_TEST(MountTest, TwoWayKeysetMigrationTest);
   FRIEND_TEST(MountTest, BothFlagsMigrationTest);
   FRIEND_TEST(MountTest, CreateTrackedSubdirectories);
+  FRIEND_TEST(MountTest, CreateTrackedSubdirectoriesReplaceExistingDir);
 
   DISALLOW_COPY_AND_ASSIGN(Mount);
 };
diff --git a/cryptohome/mount_unittest.cc b/cryptohome/mount_unittest.cc
index bd9f0d9..f71018e 100644
--- a/cryptohome/mount_unittest.cc
+++ b/cryptohome/mount_unittest.cc
@@ -1574,6 +1574,57 @@
   EXPECT_TRUE(mount_->CreateTrackedSubdirectories(up, true /* is_new */));
 }
 
+TEST_P(MountTest, CreateTrackedSubdirectoriesReplaceExistingDir) {
+  EXPECT_TRUE(DoMountInit());
+  InsertTestUsers(&kDefaultUsers[0], 1);
+  TestUser *user = &helper_.users[0];
+  UsernamePasskey up(user->username, user->passkey);
+
+  FilePath dest_dir;
+  if (ShouldTestEcryptfs()) {
+    dest_dir = user->vault_path;
+    mount_->mount_type_ = Mount::MountType::ECRYPTFS;
+  } else {
+    dest_dir = user->vault_mount_path;
+    mount_->mount_type_ = Mount::MountType::DIR_CRYPTO;
+  }
+  EXPECT_CALL(platform_, DirectoryExists(dest_dir))
+    .WillOnce(Return(true));
+  // Expectations for each tracked subdirectory.
+  for (const auto& tracked_dir : Mount::GetTrackedSubdirectories()) {
+    const FilePath tracked_dir_path = dest_dir.Append(tracked_dir);
+    const FilePath userside_dir = user->vault_mount_path.Append(tracked_dir);
+    // Simulate the case there already exists a non-passthrough-dir
+    if (ShouldTestEcryptfs()) {
+      // For ecryptfs, delete and replace the existing directory.
+      EXPECT_CALL(platform_, DirectoryExists(userside_dir))
+        .WillOnce(Return(true));
+      EXPECT_CALL(platform_, DeleteFile(userside_dir, true))
+        .WillOnce(Return(true));
+      EXPECT_CALL(platform_, DirectoryExists(tracked_dir_path))
+        .WillOnce(Return(false))
+        .WillOnce(Return(false));
+      EXPECT_CALL(platform_, CreateDirectory(tracked_dir_path))
+        .WillOnce(Return(true));
+      EXPECT_CALL(
+          platform_,
+          SetOwnership(tracked_dir_path, chronos_uid_, chronos_gid_, true))
+        .WillOnce(Return(true));
+    } else {
+      // For dircrypto, just skip the directory creation.
+      EXPECT_CALL(platform_, DirectoryExists(tracked_dir_path))
+        .WillOnce(Return(true));
+      EXPECT_CALL(platform_, SetExtendedFileAttribute(
+          tracked_dir_path,
+          kTrackedDirectoryNameAttribute,
+          StrEq(tracked_dir_path.BaseName().value()),
+          tracked_dir_path.BaseName().value().size())).WillOnce(Return(true));
+    }
+  }
+  // Run the method.
+  EXPECT_TRUE(mount_->CreateTrackedSubdirectories(up, false /* is_new */));
+}
+
 TEST_P(MountTest, MountCryptohomePreviousMigrationIncomplete) {
   // Checks that if both ecryptfs and dircrypto home directories
   // exist, fails with an error.