This is an automated email from the ASF dual-hosted git repository. stigahuang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/impala.git
commit d4707ff1973255ed29f2d7b7740d809f26d80703 Author: Arnab Karmakar <[email protected]> AuthorDate: Tue Nov 25 15:00:43 2025 +0530 IMPALA-13941: Add helper to format file permissions as UNIX-style string This change introduces a utility method FormatPermissions() that converts mode_t permission bits into a human-readable string (e.g., "drwxrwxrwt"). It correctly handles file type indicators, owner/group/other read-write-execute bits, and special bits such as setuid, setgid, and sticky. This improves log readability and debugging for file metadata-related operations by providing consistent, ls-style permission formatting. Testing: - Added unit tests validating permission string output for: - Regular files, directories, symlinks, sockets - All rwx combinations for user/group/other - setuid, setgid, and sticky bit behavior Change-Id: Ib53dbecd5c202e33b6e3b5cd3a372a77d8b1703a Reviewed-on: http://gerrit.cloudera.org:8080/23714 Reviewed-by: Riza Suminto <[email protected]> Reviewed-by: Michael Smith <[email protected]> Tested-by: Michael Smith <[email protected]> --- be/src/rpc/authentication-test.cc | 70 +++++++++++++++++++++++++++++++++++++++ be/src/rpc/authentication.cc | 42 +++++++++++++++++++++-- 2 files changed, 109 insertions(+), 3 deletions(-) diff --git a/be/src/rpc/authentication-test.cc b/be/src/rpc/authentication-test.cc index 308e8d55c..7df006a21 100644 --- a/be/src/rpc/authentication-test.cc +++ b/be/src/rpc/authentication-test.cc @@ -61,6 +61,9 @@ int SaslAuthorizeInternal(sasl_conn_t* conn, void* context, const char* def_realm, unsigned urlen, struct propctx* propctx); +// Expose the FormatPermissions function for testing +string FormatPermissions(mode_t mode); + TEST(Auth, PrincipalSubstitution) { string hostname; ASSERT_OK(GetHostname(&hostname)); @@ -388,6 +391,73 @@ TEST(Auth, UserUtilities) { } } +// Test for IMPALA-13941: FormatPermissions correctly formats file permissions +TEST(Auth, FormatPermissions) { + // Test directory with standard /var/tmp permissions (01777 = drwxrwxrwt) + mode_t mode = S_IFDIR | 01777; + ASSERT_EQ("drwxrwxrwt", FormatPermissions(mode)); + + // Test directory with common permissions (0755 = drwxr-xr-x) + mode = S_IFDIR | 0755; + ASSERT_EQ("drwxr-xr-x", FormatPermissions(mode)); + + // Test directory with restricted permissions (0700 = drwx------) + mode = S_IFDIR | 0700; + ASSERT_EQ("drwx------", FormatPermissions(mode)); + + // Test directory with sticky bit but not world-writable (01755 = drwxr-xr-t) + mode = S_IFDIR | 01755; + ASSERT_EQ("drwxr-xr-t", FormatPermissions(mode)); + + // Test regular file with common permissions (0644 = -rw-r--r--) + mode = S_IFREG | 0644; + ASSERT_EQ("-rw-r--r--", FormatPermissions(mode)); + + // Test executable file (0755 = -rwxr-xr-x) + mode = S_IFREG | 0755; + ASSERT_EQ("-rwxr-xr-x", FormatPermissions(mode)); + + // Test file with setuid bit (04755 = -rwsr-xr-x) + mode = S_IFREG | S_ISUID | 0755; + ASSERT_EQ("-rwsr-xr-x", FormatPermissions(mode)); + + // Test file with setgid bit (02755 = -rwxr-sr-x) + mode = S_IFREG | S_ISGID | 0755; + ASSERT_EQ("-rwxr-sr-x", FormatPermissions(mode)); + + // Test file with setuid but no execute (04644 = -rwSr--r--) + mode = S_IFREG | S_ISUID | 0644; + ASSERT_EQ("-rwSr--r--", FormatPermissions(mode)); + + // Test symbolic link (0777 = lrwxrwxrwx) + mode = S_IFLNK | 0777; + ASSERT_EQ("lrwxrwxrwx", FormatPermissions(mode)); + + // Test block device (0660 = brw-rw----) + mode = S_IFBLK | 0660; + ASSERT_EQ("brw-rw----", FormatPermissions(mode)); + + // Test character device (0666 = crw-rw-rw-) + mode = S_IFCHR | 0666; + ASSERT_EQ("crw-rw-rw-", FormatPermissions(mode)); + + // Test FIFO/pipe (0644 = prw-r--r--) + mode = S_IFIFO | 0644; + ASSERT_EQ("prw-r--r--", FormatPermissions(mode)); + + // Test socket (0755 = srwxr-xr-x) + mode = S_IFSOCK | 0755; + ASSERT_EQ("srwxr-xr-x", FormatPermissions(mode)); + + // Test no permissions (0000 = d---------) + mode = S_IFDIR | 0000; + ASSERT_EQ("d---------", FormatPermissions(mode)); + + // Test sticky bit without execute (01776 = drwxrwxrwT) + mode = S_IFDIR | 01776; + ASSERT_EQ("drwxrwxrwT", FormatPermissions(mode)); +} + } int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/be/src/rpc/authentication.cc b/be/src/rpc/authentication.cc index 8a879d57f..a282ac1fe 100644 --- a/be/src/rpc/authentication.cc +++ b/be/src/rpc/authentication.cc @@ -1237,6 +1237,41 @@ Status InitAuth(const string& appname) { return Status::OK(); } +// Helper function to format file permissions as a string (e.g., "drwxrwxrwt"). +string FormatPermissions(mode_t mode) { + string result(10, '-'); + + // File type + if (S_ISDIR(mode)) result[0] = 'd'; + else if (S_ISLNK(mode)) result[0] = 'l'; + else if (S_ISBLK(mode)) result[0] = 'b'; + else if (S_ISCHR(mode)) result[0] = 'c'; + else if (S_ISFIFO(mode)) result[0] = 'p'; + else if (S_ISSOCK(mode)) result[0] = 's'; + + // Owner permissions + if (mode & S_IRUSR) result[1] = 'r'; + if (mode & S_IWUSR) result[2] = 'w'; + if (mode & S_IXUSR) result[3] = 'x'; + + // Group permissions + if (mode & S_IRGRP) result[4] = 'r'; + if (mode & S_IWGRP) result[5] = 'w'; + if (mode & S_IXGRP) result[6] = 'x'; + + // Other permissions + if (mode & S_IROTH) result[7] = 'r'; + if (mode & S_IWOTH) result[8] = 'w'; + if (mode & S_IXOTH) result[9] = 'x'; + + // Special bits (setuid, setgid, sticky) + if (mode & S_ISUID) result[3] = (mode & S_IXUSR) ? 's' : 'S'; + if (mode & S_ISGID) result[6] = (mode & S_IXGRP) ? 's' : 'S'; + if (mode & S_ISVTX) result[9] = (mode & S_IXOTH) ? 't' : 'T'; + + return result; +} + // Ensure that /var/tmp (the location of the Kerberos replay cache) has drwxrwxrwt // permissions. If it doesn't, Kerberos will be unhappy in a way that's very difficult // to debug. We do this using direct stat() calls because boost doesn't support the @@ -1254,9 +1289,10 @@ Status CheckReplayCacheDirPermissions() { } if ((st.st_mode & 01777) != 01777) { - return Status("Error: The permissions on /var/tmp must precisely match " - "\"drwxrwxrwt\". This directory is used by the Kerberos replay cache. To " - "rectify this issue, run \"chmod 01777 /var/tmp\" as root."); + return Status(Substitute("Error: The permissions on /var/tmp must precisely match " + "\"drwxrwxrwt\". This directory is used by the Kerberos replay cache. " + "Current permissions: \"$0\". To rectify this issue, run " + "\"chmod 01777 /var/tmp\" as root.", FormatPermissions(st.st_mode))); } return Status::OK();
