Index: base/file_util_unittest.cc |
diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc |
index c44b804f00949c85b4fd877c261e85f45a9155a6..b81985fdd7dadd477164bd40083fa7fdc331c318 100644 |
--- a/base/file_util_unittest.cc |
+++ b/base/file_util_unittest.cc |
@@ -110,6 +110,27 @@ bool DeleteReparsePoint(HANDLE source) { |
} |
#endif |
+#if defined(OS_POSIX) |
+// Provide a simple way to change the permissions bits on |path| in tests. |
+// ASSERT failures will return, but not stop the test. Caller should wrap |
+// calls to this function in ASSERT_NO_FATAL_FAILURE(). |
+void ChangePosixFilePermissions(const FilePath& path, |
+ mode_t mode_bits_to_set, |
+ mode_t mode_bits_to_clear) { |
+ ASSERT_EQ(0u, mode_bits_to_set & mode_bits_to_clear) |
+ << "Can't set and clear the same bit."; |
+ |
+ struct stat stat_buf; |
+ ASSERT_EQ(0, stat(path.value().c_str(), &stat_buf)); |
+ |
+ mode_t new_mode_bits = stat_buf.st_mode; |
+ new_mode_bits |= mode_bits_to_set; |
+ new_mode_bits &= ~mode_bits_to_clear; |
+ |
+ ASSERT_EQ(0, chmod(path.value().c_str(), new_mode_bits)); |
+} |
+#endif // defined(OS_POSIX) |
+ |
const wchar_t bogus_content[] = L"I'm cannon fodder."; |
const file_util::FileEnumerator::FileType FILES_AND_DIRECTORIES = |
@@ -1813,4 +1834,104 @@ TEST_F(FileUtilTest, IsDirectoryEmpty) { |
EXPECT_FALSE(file_util::IsDirectoryEmpty(empty_dir)); |
} |
+#if defined(OS_POSIX) |
+TEST_F(FileUtilTest, IsPathControlledByUser) { |
+ // Testing IsPathControlledByAdmin() is hard, because there is no |
+ // way a test can make a file owned by root, or change file paths |
+ // at the root of the file system. IsPathControlledByAdmin() |
+ // is implemented as a call to IsPathControlledByUser, which gives |
+ // us the ability to test with paths under the test's temp directory, |
+ // using a user id we control. |
+ |
+ FilePath base_dir = temp_dir_.path().AppendASCII("base_dir"); |
+ ASSERT_TRUE(file_util::CreateDirectory(base_dir)); |
+ |
+ FilePath sub_dir = base_dir.AppendASCII("sub_dir"); |
+ ASSERT_TRUE(file_util::CreateDirectory(sub_dir)); |
+ |
+ FilePath text_file = sub_dir.AppendASCII("file.txt"); |
+ CreateTextFile(text_file, L"This text file has some text in it."); |
+ |
+ // Get our uid, and another uid, so that we can test both a |
+ // matching and non-matching uid. |
+ uid_t our_uid = getuid(); |
+ uid_t not_our_uid = our_uid + 1; |
+ |
+ // Make all files and directories non-world-writable. |
+ ASSERT_NO_FATAL_FAILURE( |
+ ChangePosixFilePermissions(base_dir, 0u, S_IWOTH)); |
+ ASSERT_NO_FATAL_FAILURE( |
+ ChangePosixFilePermissions(sub_dir, 0u, S_IWOTH)); |
+ ASSERT_NO_FATAL_FAILURE( |
+ ChangePosixFilePermissions(text_file, 0u, S_IWOTH)); |
+ |
+ // We control these paths. |
+ ASSERT_TRUE( |
+ file_util::IsPathControlledByUser(base_dir, sub_dir, our_uid)); |
+ ASSERT_TRUE( |
+ file_util::IsPathControlledByUser(base_dir, text_file, our_uid)); |
+ ASSERT_TRUE( |
+ file_util::IsPathControlledByUser(sub_dir, text_file, our_uid)); |
+ |
+ // Another user does not control these paths. |
+ ASSERT_FALSE( |
+ file_util::IsPathControlledByUser(base_dir, sub_dir, not_our_uid )); |
+ ASSERT_FALSE( |
+ file_util::IsPathControlledByUser(base_dir, text_file, not_our_uid)); |
+ ASSERT_FALSE( |
+ file_util::IsPathControlledByUser(sub_dir, text_file, not_our_uid)); |
+ |
+ // Make base_dir world-writable. No change, because the base dir should |
+ // not be tested. |
+ ASSERT_NO_FATAL_FAILURE( |
+ ChangePosixFilePermissions(base_dir, S_IWOTH, 0u)); |
+ ASSERT_TRUE( |
+ file_util::IsPathControlledByUser(base_dir, sub_dir, our_uid)); |
+ ASSERT_TRUE( |
+ file_util::IsPathControlledByUser(base_dir, text_file, our_uid)); |
+ ASSERT_TRUE( |
+ file_util::IsPathControlledByUser(sub_dir, text_file, our_uid)); |
+ |
+ // Make sub_dir world writable. |
+ ASSERT_NO_FATAL_FAILURE( |
+ ChangePosixFilePermissions(sub_dir, S_IWOTH, 0u)); |
+ ASSERT_FALSE( |
+ file_util::IsPathControlledByUser(base_dir, sub_dir, our_uid)); |
+ ASSERT_FALSE( |
+ file_util::IsPathControlledByUser(base_dir, text_file, our_uid)); |
+ ASSERT_TRUE( |
+ file_util::IsPathControlledByUser(sub_dir, text_file, our_uid)); |
+ |
+ // Make text_file world writable. |
+ ASSERT_NO_FATAL_FAILURE( |
+ ChangePosixFilePermissions(text_file, S_IWOTH, 0u)); |
+ ASSERT_FALSE( |
+ file_util::IsPathControlledByUser(base_dir, sub_dir, our_uid)); |
+ ASSERT_FALSE( |
+ file_util::IsPathControlledByUser(base_dir, text_file, our_uid)); |
+ ASSERT_FALSE( |
+ file_util::IsPathControlledByUser(sub_dir, text_file, our_uid)); |
+ |
+ // Make sub_dir non-world writable. |
+ ASSERT_NO_FATAL_FAILURE( |
+ ChangePosixFilePermissions(sub_dir, 0u, S_IWOTH)); |
+ ASSERT_TRUE( |
+ file_util::IsPathControlledByUser(base_dir, sub_dir, our_uid)); |
+ ASSERT_FALSE( |
+ file_util::IsPathControlledByUser(base_dir, text_file, our_uid)); |
+ ASSERT_FALSE( |
+ file_util::IsPathControlledByUser(sub_dir, text_file, our_uid)); |
+ |
+ // Make base_dir non-world-writable. |
+ ASSERT_NO_FATAL_FAILURE( |
+ ChangePosixFilePermissions(base_dir, 0u, S_IWOTH)); |
+ ASSERT_TRUE( |
+ file_util::IsPathControlledByUser(base_dir, sub_dir, our_uid)); |
+ ASSERT_FALSE( |
+ file_util::IsPathControlledByUser(base_dir, text_file, our_uid)); |
+ ASSERT_FALSE( |
+ file_util::IsPathControlledByUser(sub_dir, text_file, our_uid)); |
+} |
+#endif // defined(OS_POSIX) |
+ |
} // namespace |