8214545: sun/management/jmxremote/bootstrap tests hang in revokeall.exe on Windows
authordtitov
Wed, 22 May 2019 09:06:24 -0700
changeset 54987 2ffbc00d87ae
parent 54986 3b4ecc4180e0
child 54988 dd15cec077fc
8214545: sun/management/jmxremote/bootstrap tests hang in revokeall.exe on Windows Reviewed-by: dholmes, amenkov, bulasevich, dfuchs, erikj
make/test/JtregNativeJdk.gmk
test/jdk/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh
test/jdk/sun/management/windows/README
test/jdk/sun/management/windows/exerevokeall.c
test/jdk/sun/management/windows/revokeall.c
test/jdk/sun/management/windows/revokeall.exe
--- a/make/test/JtregNativeJdk.gmk	Wed May 22 09:26:48 2019 -0400
+++ b/make/test/JtregNativeJdk.gmk	Wed May 22 09:06:24 2019 -0700
@@ -62,9 +62,11 @@
   WIN_LIB_JLI := $(SUPPORT_OUTPUTDIR)/native/java.base/libjli/jli.lib
   BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeJliLaunchTest := $(WIN_LIB_JLI)
   BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := jvm.lib
+  BUILD_JDK_JTREG_EXECUTABLES_LIBS_exerevokeall := advapi32.lib
 else
   BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := -ljava
   BUILD_JDK_JTREG_LIBRARIES_LIBS_libDirectIO := -ljava
+  BUILD_JDK_JTREG_EXCLUDE += exerevokeall.c
   ifeq ($(call isTargetOs, linux), true)
     BUILD_JDK_JTREG_LIBRARIES_LIBS_libInheritedChannel := -ljava
   else ifeq ($(call isTargetOs, solaris), true)
--- a/test/jdk/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh	Wed May 22 09:26:48 2019 -0400
+++ b/test/jdk/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh	Wed May 22 09:06:24 2019 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -70,13 +70,11 @@
     if [ "$OS" = "Windows_NT" ]; then
         USER=`id -u -n`
         CACLS="$SystemRoot/system32/cacls.exe"
-        TEST_SRC=`cygpath ${TESTSRC}`
-        REVOKEALL="$TEST_SRC/../../windows/revokeall.exe"
-        if [ ! -f "$REVOKEALL" ] ; then
-            echo "$REVOKEALL missing"
+        REVOKEALL="$TESTNATIVEPATH/revokeall.exe"
+        if [ ! -x "$REVOKEALL" ] ; then
+            echo "$REVOKEALL doesn't exist or is not executable"
             exit 1
         fi
-        chmod ug+x $REVOKEALL
     fi
     ;;
 *)
--- a/test/jdk/sun/management/windows/README	Wed May 22 09:26:48 2019 -0400
+++ b/test/jdk/sun/management/windows/README	Wed May 22 09:06:24 2019 -0700
@@ -1,6 +1,29 @@
+/*
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
 
-This directory contains the source and the binary version of a Windows 
-utility to remove all non-owner Access Control Entries from a given file.
+
+This directory contains the source of a Windows utility to remove all
+non-owner Access Control Entries from a given file.
 
 The tool is used by regression tests in the following directories :-
 
@@ -10,18 +33,3 @@
 be "secured" (meaning that only the owner should have access to the 
 files). 
 
-Both the source and the binary version are checked into SCCS. If
-you require to make changes to the tool then you need to Visual
-C++ to rebuild revokeall.exe after changing the source.
-
-To rebuild the tool you need to setup your environment (by
-calling the VC++ VCVARS32.BAT script), and then executing the 
-following command :-
-
-cl /mt revokeall.c advapi32.lib
-
-This will generate revokeall.exe.
-
-Note that a 32-bit version of revokeall.exe is checked into SCCS
-- this 32-bit application is also used when running on 64-bit
-versions of Windows (AMD64 and IA64).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/management/windows/exerevokeall.c	Wed May 22 09:06:24 2019 -0700
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdio.h>
+#include <windows.h>
+#include <malloc.h>
+#include <string.h>
+
+/*
+ * Simple Windows utility to remove all non-owner access to a given file.
+ */
+
+
+/*
+ * Access mask to represent any file access
+ */
+#define ANY_ACCESS (FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE)
+
+
+/*
+ * Print error message to stderr
+ */
+static void printLastError(const char* msg) {
+    int len;
+    char buf[128];
+    DWORD errval;
+
+    buf[0] = '\0';
+    len = sizeof(buf);
+
+    errval = GetLastError();
+    if (errval != 0) {
+        int n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
+                              NULL, errval,
+                              0, buf, len, NULL);
+        if (n > 3) {
+            /* Drop final '.', CR, LF */
+            if (buf[n - 1] == '\n') n--;
+            if (buf[n - 1] == '\r') n--;
+            if (buf[n - 1] == '.') n--;
+            buf[n] = '\0';
+        }
+    }
+
+    if (strlen(buf) > 0) {
+        fprintf(stderr, "revokeall %s: %s\n", msg, buf);
+    } else {
+        fprintf(stderr, "revokeall %s\n", msg);
+    }
+}
+
+
+
+/*
+ * Return a string that includes all the components of a given SID.
+ * See here for a description of the SID components :-
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/sid_components.asp
+ */
+static char *getTextualSid(SID* sid) {
+    SID_IDENTIFIER_AUTHORITY* sia;
+    DWORD i, count;
+    DWORD len;
+    char* name;
+
+    /*
+     * Get the identifier authority and the number of sub-authorities
+     */
+    sia = GetSidIdentifierAuthority(sid);
+    count = *GetSidSubAuthorityCount(sid);
+
+    /*
+     * Allocate buffer for the string - buffer is :-
+     * S-SID_REVISION- + identifierAuthority- + subauthorities- + NULL
+     */
+    len=(15 + 12 + (12 * count) + 1) * sizeof(char);
+    name = (char*)malloc(len);
+    if (name == NULL) {
+        return NULL;
+    }
+
+    // S-SID_REVISION
+    sprintf(name, "S-%lu-", SID_REVISION );
+
+    // Identifier authority
+    if ((sia->Value[0] != 0) || (sia->Value[1] != 0))
+    {
+        sprintf(name + strlen(name), "0x%02hx%02hx%02hx%02hx%02hx%02hx",
+                (USHORT)sia->Value[0],
+                (USHORT)sia->Value[1],
+                (USHORT)sia->Value[2],
+                (USHORT)sia->Value[3],
+                (USHORT)sia->Value[4],
+                (USHORT)sia->Value[5]);
+    }
+    else
+    {
+        sprintf(name + strlen(name), "%lu",
+                (ULONG)(sia->Value[5]      )   +
+                (ULONG)(sia->Value[4] <<  8)   +
+                (ULONG)(sia->Value[3] << 16)   +
+                (ULONG)(sia->Value[2] << 24)   );
+    }
+
+    // finally, the sub-authorities
+    for (i=0 ; i<count; i++) {
+        sprintf(name + strlen(name), "-%lu",
+                *GetSidSubAuthority(sid, i) );
+    }
+
+    return name;
+}
+
+/*
+ * Returns a string to represent the given security identifier (SID).
+ * If the account is known to the local computer then the account
+ * domain is returned. The format will be \\name or domain\\name depending
+ * on if the computer belongs to a domain.
+ * If the account name is not known then the textual representation of
+ * SID is returned -- eg: S-1-5-21-2818032319-470147023-1036452850-13037.
+ */
+static char *getSIDString(SID* sid) {
+    char domain[255];
+    char name[255];
+    DWORD domainLen = sizeof(domain);
+    DWORD nameLen = sizeof(name);
+    SID_NAME_USE use;
+
+    if(!IsValidSid(sid)) {
+        return strdup("<Invalid SID>");
+    }
+
+    if (LookupAccountSid(NULL, sid, name, &nameLen, domain, &domainLen, &use)) {
+        size_t len = strlen(name) + strlen(domain) + 3;
+        char* s = (char*)malloc(len);
+        if (s != NULL) {
+            strcpy(s, domain);
+            strcat(s, "\\\\");
+            strcat(s, name);
+        }
+        return s;
+    } else {
+        return getTextualSid(sid);
+    }
+}
+
+
+
+/*
+ * Returns 1 if the specified file is on a file system that supports
+ * persistent ACLs (On NTFS file systems returns true, on FAT32 file systems
+ * returns false), otherwise 0. Returns -1 if error.
+ */
+static int isSecuritySupported(const char* path) {
+    char* root;
+    char* p;
+    BOOL res;
+    DWORD dwMaxComponentLength;
+    DWORD dwFlags;
+    char fsName[128];
+    DWORD fsNameLength;
+
+    /*
+     * Get root directory. For UNCs the slash after the share name is required.
+     */
+    root = strdup(path);
+    if (*root == '\\') {
+        /*
+         * \\server\share\file ==> \\server\share\
+         */
+        int slashskip = 3;
+        p = root;
+        while ((*p == '\\') && (slashskip > 0)) {
+            char* p2;
+            p++;
+            p2 = strchr(p, '\\');
+            if ((p2 == NULL) || (*p2 != '\\')) {
+                free(root);
+                fprintf(stderr, "Malformed UNC");
+                return -1;
+            }
+            p = p2;
+            slashskip--;
+        }
+        if (slashskip != 0) {
+            free(root);
+            fprintf(stderr, "Malformed UNC");
+            return -1;
+        }
+        p++;
+        *p = '\0';
+
+    } else {
+        p = strchr(root, '\\');
+
+        /*
+         * Relative path so use current directory
+         */
+        if (p == NULL) {
+            free(root);
+            root = malloc(255);
+            if (GetCurrentDirectory(255, root) == 0) {
+                printLastError("GetCurrentDirectory failed");
+                return -1;
+            }
+            p = strchr(root, '\\');
+            if (p == NULL) {
+                fprintf(stderr, "GetCurrentDirectory doesn't include drive letter!!!!\n");
+                return -1;
+            }
+        }
+        p++;
+        *p = '\0';
+    }
+
+    /*
+     * Get the volume information - this gives us the file system file and
+     * also tells us if the file system supports persistent ACLs.
+     */
+    fsNameLength = sizeof(fsName)-1;
+    res = GetVolumeInformation(root,
+                               NULL,        // address of name of the volume, can be NULL
+                               0,           // length of volume name
+                               NULL,        // address of volume serial number, can be NULL
+                               &dwMaxComponentLength,
+                               &dwFlags,
+                               fsName,
+                               fsNameLength);
+    if (res == 0) {
+        printLastError("GetVolumeInformation failed");
+        free(root);
+        return -1;
+    }
+
+    free(root);
+    return (dwFlags & FS_PERSISTENT_ACLS) ? 1 : 0;
+}
+
+
+/*
+ * Returns the security descriptor for a file.
+ */
+static SECURITY_DESCRIPTOR* getFileSecurityDescriptor(const char* path) {
+    SECURITY_DESCRIPTOR* sd;
+    DWORD len = 0;
+    SECURITY_INFORMATION info =
+        OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
+
+    GetFileSecurity(path, info , 0, 0, &len);
+    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+        printLastError("GetFileSecurity failed");
+        return NULL;
+    }
+    sd = (SECURITY_DESCRIPTOR *)malloc(len);
+    if (sd == NULL) {
+        fprintf(stderr, "Out of memory");
+    } else {
+        if (!GetFileSecurity(path, info, sd, len, &len)) {
+            printLastError("GetFileSecurity failed");
+            free(sd);
+            return NULL;
+        }
+    }
+    return sd;
+}
+
+
+/*
+ * Revoke all access to the specific file
+ */
+static int revokeAll(const char* path) {
+    SECURITY_DESCRIPTOR* sd;
+    SID* owner;
+    ACL *acl;
+    BOOL defaulted, present;
+    ACL_SIZE_INFORMATION acl_size_info;
+    DWORD i, count;
+    char* str;
+
+    /*
+     * Get security descriptor for file; From security descriptor get the
+     * owner SID, and the DACL.
+     */
+    sd = getFileSecurityDescriptor(path);
+    if (sd == NULL) {
+        return -1;      /* error already reported */
+    }
+    if (!GetSecurityDescriptorOwner(sd, &owner, &defaulted)) {
+        printLastError("GetSecurityDescriptorOwner failed");
+        return -1;
+    }
+    str = getSIDString(owner);
+    if (str != NULL) {
+        printf("owner: %s\n", str);
+        free(str);
+    }
+    if (!GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted)) {
+        printLastError("GetSecurityDescriptorDacl failed");
+        return -1;
+    }
+    if (!present) {
+        fprintf(stderr, "Security descriptor does not contain a DACL");
+        return -1;
+    }
+
+    /*
+     * If DACL is NULL there is no access to the file - we are done
+     */
+    if (acl == NULL) {
+        return 1;
+    }
+
+    /*
+     * Iterate over the ACEs. For each "allow" type check that the SID
+     * matches the owner - if not we remove the ACE from the ACL
+     */
+    if (!GetAclInformation(acl, (void *) &acl_size_info, sizeof(acl_size_info),
+                                  AclSizeInformation)) {
+        printLastError("GetAclInformation failed");
+        return -1;
+    }
+    count = acl_size_info.AceCount;
+    i = 0;
+    while (count > 0) {
+        void* ace;
+        ACCESS_ALLOWED_ACE *access;
+        SID* sid;
+        BOOL deleted;
+
+        if (!GetAce(acl, i, &ace)) {
+            printLastError("GetAce failed");
+            return -1;
+        }
+        if (((ACCESS_ALLOWED_ACE *)ace)->Header.AceType != ACCESS_ALLOWED_ACE_TYPE) {
+            i++;
+            count--;
+            continue;
+        }
+        access = (ACCESS_ALLOWED_ACE *)ace;
+        sid = (SID *) &access->SidStart;
+
+
+        deleted = FALSE;
+        if (!EqualSid(owner, sid)) {
+            /*
+             * If the ACE allows any access then the file then we
+             * delete it.
+             */
+            if (access->Mask & ANY_ACCESS) {
+                str = getSIDString(sid);
+                if (str != NULL) {
+                    printf("remove ALLOW %s\n", str);
+                    free(str);
+                }
+                if (DeleteAce(acl, i) == 0) {
+                    printLastError("DeleteAce failed");
+                    return -1;
+                }
+                deleted = TRUE;
+            }
+        }
+
+        if (!deleted) {
+            str = getSIDString(sid);
+            if (str != NULL) {
+                printf("ALLOW %s (access mask=%x)\n", str, access->Mask);
+                free(str);
+            }
+
+            /* onto the next ACE */
+            i++;
+        }
+        count--;
+    }
+
+    /*
+     * No changes - only owner has access
+     */
+    if (i == acl_size_info.AceCount) {
+        printf("No changes.\n");
+        return 1;
+    }
+
+    /*
+     * Create security descriptor and set its DACL to the version
+     * that we just edited
+     */
+    if (!InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) {
+        printLastError("InitializeSecurityDescriptor failed");
+        return -1;
+    }
+    if (!SetSecurityDescriptorDacl(sd, present, acl, defaulted)) {
+        printLastError("SetSecurityDescriptorDacl failed");
+        return -1;
+    }
+    if (!SetFileSecurity(path, DACL_SECURITY_INFORMATION, sd)) {
+        printLastError("SetFileSecurity failed");
+        return -1;
+    }
+
+    printf("File updated.\n");
+
+    return 1;
+}
+
+/*
+ * Convert slashes in the pathname to backslashes if needed.
+ */
+static char* convert_path(const char* p) {
+   int i = 0;
+   char* path = strdup(p);
+   while (p[i] != '\0') {
+       if (p[i] == '/') {
+           path[i] = '\\';
+       }
+       i++;
+   }
+   return path;
+}
+
+/*
+ * Usage: revokeall file
+ */
+int main( int argc, char *argv[])
+{
+    int rc;
+    const char* path;
+
+    if (argc != 2) {
+        fprintf(stderr, "Usage: %s file\n", argv[0]);
+        return -1;
+    }
+    path = convert_path(argv[1]);
+    printf("Revoking all non-owner access to %s\n", path);
+    rc = isSecuritySupported(path);
+    if (rc != 1) {
+        if (rc == 0) {
+            printf("File security not supported on this file system\n");
+        }
+        return rc;
+    } else {
+        return revokeAll(path);
+    }
+}
--- a/test/jdk/sun/management/windows/revokeall.c	Wed May 22 09:26:48 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,462 +0,0 @@
-/*
- * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <stdio.h>
-#include <windows.h>
-#include <malloc.h>
-#include <string.h>
-
-/*
- * Simple Windows utility to remove all non-owner access to a given
- * file - suitable for NT/2000/XP only.
- */
-
-
-/*
- * Access mask to represent any file access
- */
-#define ANY_ACCESS (FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE)
-
-
-/*
- * Print error message to stderr
- */
-static void printLastError(const char* msg) {
-    int len;
-    char buf[128];
-    DWORD errval;
-
-    buf[0] = '\0';
-    len = sizeof(buf);
-
-    errval = GetLastError();
-    if (errval != 0) {
-        int n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
-                              NULL, errval,
-                              0, buf, len, NULL);
-        if (n > 3) {
-            /* Drop final '.', CR, LF */
-            if (buf[n - 1] == '\n') n--;
-            if (buf[n - 1] == '\r') n--;
-            if (buf[n - 1] == '.') n--;
-            buf[n] = '\0';
-        }
-    }
-
-    if (strlen(buf) > 0) {
-        fprintf(stderr, "revokeall %s: %s\n", msg, buf);
-    } else {
-        fprintf(stderr, "revokeall %s\n", msg);
-    }
-}
-
-
-
-/*
- * Return a string that includes all the components of a given SID.
- * See here for a description of the SID components :-
- * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/sid_components.asp
- */
-static char *getTextualSid(SID* sid) {
-    SID_IDENTIFIER_AUTHORITY* sia;
-    DWORD i, count;
-    DWORD len;
-    char* name;
-
-    /*
-     * Get the identifier authority and the number of sub-authorities
-     */
-    sia = GetSidIdentifierAuthority(sid);
-    count = *GetSidSubAuthorityCount(sid);
-
-    /*
-     * Allocate buffer for the string - buffer is :-
-     * S-SID_REVISION- + identifierAuthority- + subauthorities- + NULL
-     */
-    len=(15 + 12 + (12 * count) + 1) * sizeof(char);
-    name = (char*)malloc(len);
-    if (name == NULL) {
-        return NULL;
-    }
-
-    // S-SID_REVISION
-    sprintf(name, "S-%lu-", SID_REVISION );
-
-    // Identifier authority
-    if ((sia->Value[0] != 0) || (sia->Value[1] != 0))
-    {
-        sprintf(name + strlen(name), "0x%02hx%02hx%02hx%02hx%02hx%02hx",
-                (USHORT)sia->Value[0],
-                (USHORT)sia->Value[1],
-                (USHORT)sia->Value[2],
-                (USHORT)sia->Value[3],
-                (USHORT)sia->Value[4],
-                (USHORT)sia->Value[5]);
-    }
-    else
-    {
-        sprintf(name + strlen(name), "%lu",
-                (ULONG)(sia->Value[5]      )   +
-                (ULONG)(sia->Value[4] <<  8)   +
-                (ULONG)(sia->Value[3] << 16)   +
-                (ULONG)(sia->Value[2] << 24)   );
-    }
-
-    // finally, the sub-authorities
-    for (i=0 ; i<count; i++) {
-        sprintf(name + strlen(name), "-%lu",
-                *GetSidSubAuthority(sid, i) );
-    }
-
-    return name;
-}
-
-/*
- * Returns a string to represent the given security identifier (SID).
- * If the account is known to the local computer then the account
- * domain is returned. The format will be \\name or domain\\name depending
- * on if the computer belongs to a domain.
- * If the account name is not known then the textual representation of
- * SID is returned -- eg: S-1-5-21-2818032319-470147023-1036452850-13037.
- */
-static char *getSIDString(SID* sid) {
-    char domain[255];
-    char name[255];
-    DWORD domainLen = sizeof(domain);
-    DWORD nameLen = sizeof(name);
-    SID_NAME_USE use;
-
-    if(!IsValidSid(sid)) {
-        return strdup("<Invalid SID>");
-    }
-
-    if (LookupAccountSid(NULL, sid, name, &nameLen, domain, &domainLen, &use)) {
-        int len = strlen(name) + strlen(domain) + 3;
-        char* s = (char*)malloc(len);
-        if (s != NULL) {
-            strcpy(s, domain);
-            strcat(s, "\\\\");
-            strcat(s, name);
-        }
-        return s;
-    } else {
-        return getTextualSid(sid);
-    }
-}
-
-
-
-/*
- * Returns 1 if the specified file is on a file system that supports
- * persistent ACLs (On NTFS file systems returns true, on FAT32 file systems
- * returns false), otherwise 0. Returns -1 if error.
- */
-static int isSecuritySupported(const char* path) {
-    char* root;
-    char* p;
-    BOOL res;
-    DWORD dwMaxComponentLength;
-    DWORD dwFlags;
-    char fsName[128];
-    DWORD fsNameLength;
-
-    /*
-     * Get root directory. For UNCs the slash after the share name is required.
-     */
-    root = strdup(path);
-    if (*root == '\\') {
-        /*
-         * \\server\share\file ==> \\server\share\
-         */
-        int slashskip = 3;
-        p = root;
-        while ((*p == '\\') && (slashskip > 0)) {
-            char* p2;
-            p++;
-            p2 = strchr(p, '\\');
-            if ((p2 == NULL) || (*p2 != '\\')) {
-                free(root);
-                fprintf(stderr, "Malformed UNC");
-                return -1;
-            }
-            p = p2;
-            slashskip--;
-        }
-        if (slashskip != 0) {
-            free(root);
-            fprintf(stderr, "Malformed UNC");
-            return -1;
-        }
-        p++;
-        *p = '\0';
-
-    } else {
-        p = strchr(root, '\\');
-
-        /*
-         * Relative path so use current directory
-         */
-        if (p == NULL) {
-            free(root);
-            root = malloc(255);
-            if (GetCurrentDirectory(255, root) == 0) {
-                printLastError("GetCurrentDirectory failed");
-                return -1;
-            }
-            p = strchr(root, '\\');
-            if (p == NULL) {
-                fprintf(stderr, "GetCurrentDirectory doesn't include drive letter!!!!\n");
-                return -1;
-            }
-        }
-        p++;
-        *p = '\0';
-    }
-
-    /*
-     * Get the volume information - this gives us the file system file and
-     * also tells us if the file system supports persistent ACLs.
-     */
-    fsNameLength = sizeof(fsName)-1;
-    res = GetVolumeInformation(root,
-                               NULL,        // address of name of the volume, can be NULL
-                               0,           // length of volume name
-                               NULL,        // address of volume serial number, can be NULL
-                               &dwMaxComponentLength,
-                               &dwFlags,
-                               fsName,
-                               fsNameLength);
-    if (res == 0) {
-        printLastError("GetVolumeInformation failed");
-        free(root);
-        return -1;
-    }
-
-    free(root);
-    return (dwFlags & FS_PERSISTENT_ACLS) ? 1 : 0;
-}
-
-
-/*
- * Returns the security descriptor for a file.
- */
-static SECURITY_DESCRIPTOR* getFileSecurityDescriptor(const char* path) {
-    SECURITY_DESCRIPTOR* sd;
-    DWORD len = 0;
-    SECURITY_INFORMATION info =
-        OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
-
-    GetFileSecurity(path, info , 0, 0, &len);
-    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
-        printLastError("GetFileSecurity failed");
-        return NULL;
-    }
-    sd = (SECURITY_DESCRIPTOR *)malloc(len);
-    if (sd == NULL) {
-        fprintf(stderr, "Out of memory");
-    } else {
-        if (!GetFileSecurity(path, info, sd, len, &len)) {
-            printLastError("GetFileSecurity failed");
-            free(sd);
-            return NULL;
-        }
-    }
-    return sd;
-}
-
-
-/*
- * Revoke all access to the specific file
- */
-static int revokeAll(const char* path) {
-    SECURITY_DESCRIPTOR* sd;
-    SID* owner;
-    ACL *acl;
-    BOOL defaulted, present;
-    ACL_SIZE_INFORMATION acl_size_info;
-    DWORD i, count;
-    char* str;
-
-    /*
-     * Get security descriptor for file; From security descriptor get the
-     * owner SID, and the DACL.
-     */
-    sd = getFileSecurityDescriptor(path);
-    if (sd == NULL) {
-        return -1;      /* error already reported */
-    }
-    if (!GetSecurityDescriptorOwner(sd, &owner, &defaulted)) {
-        printLastError("GetSecurityDescriptorOwner failed");
-        return -1;
-    }
-    str = getSIDString(owner);
-    if (str != NULL) {
-        printf("owner: %s\n", str);
-        free(str);
-    }
-    if (!GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted)) {
-        printLastError("GetSecurityDescriptorDacl failed");
-        return -1;
-    }
-    if (!present) {
-        fprintf(stderr, "Security descriptor does not contain a DACL");
-        return -1;
-    }
-
-    /*
-     * If DACL is NULL there is no access to the file - we are done
-     */
-    if (acl == NULL) {
-        return 1;
-    }
-
-    /*
-     * Iterate over the ACEs. For each "allow" type check that the SID
-     * matches the owner - if not we remove the ACE from the ACL
-     */
-    if (!GetAclInformation(acl, (void *) &acl_size_info, sizeof(acl_size_info),
-                                  AclSizeInformation)) {
-        printLastError("GetAclInformation failed");
-        return -1;
-    }
-    count = acl_size_info.AceCount;
-    i = 0;
-    while (count > 0) {
-        void* ace;
-        ACCESS_ALLOWED_ACE *access;
-        SID* sid;
-        BOOL deleted;
-
-        if (!GetAce(acl, i, &ace)) {
-            printLastError("GetAce failed");
-            return -1;
-        }
-        if (((ACCESS_ALLOWED_ACE *)ace)->Header.AceType != ACCESS_ALLOWED_ACE_TYPE) {
-            continue;
-        }
-        access = (ACCESS_ALLOWED_ACE *)ace;
-        sid = (SID *) &access->SidStart;
-
-
-        deleted = FALSE;
-        if (!EqualSid(owner, sid)) {
-            /*
-             * If the ACE allows any access then the file then we
-             * delete it.
-             */
-            if (access->Mask & ANY_ACCESS) {
-                str = getSIDString(sid);
-                if (str != NULL) {
-                    printf("remove ALLOW %s\n", str);
-                    free(str);
-                }
-                if (DeleteAce(acl, i) == 0) {
-                    printLastError("DeleteAce failed");
-                    return -1;
-                }
-                deleted = TRUE;
-            }
-        }
-
-        if (!deleted) {
-            str = getSIDString(sid);
-            if (str != NULL) {
-                printf("ALLOW %s (access mask=%x)\n", str, access->Mask);
-                free(str);
-            }
-
-            /* onto the next ACE */
-            i++;
-        }
-        count--;
-    }
-
-    /*
-     * No changes - only owner has access
-     */
-    if (i == acl_size_info.AceCount) {
-        printf("No changes.\n");
-        return 1;
-    }
-
-    /*
-     * Create security descriptor and set its DACL to the version
-     * that we just edited
-     */
-    if (!InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) {
-        printLastError("InitializeSecurityDescriptor failed");
-        return -1;
-    }
-    if (!SetSecurityDescriptorDacl(sd, present, acl, defaulted)) {
-        printLastError("SetSecurityDescriptorDacl failed");
-        return -1;
-    }
-    if (!SetFileSecurity(path, DACL_SECURITY_INFORMATION, sd)) {
-        printLastError("SetFileSecurity failed");
-        return -1;
-    }
-
-    printf("File updated.\n");
-
-    return 1;
-}
-
-/*
- * Convert slashes in the pathname to backslashes if needed.
- */
-static char* convert_path(const char* p) {
-   int i = 0;
-   char* path = strdup(p);
-   while (p[i] != '\0') {
-       if (p[i] == '/') {
-           path[i] = '\\';
-       }
-       i++;
-   }
-   return path;
-}
-
-/*
- * Usage: revokeall file
- */
-int main( int argc, char *argv[])
-{
-    int rc;
-    const char* path;
-
-    if (argc != 2) {
-        fprintf(stderr, "Usage: %s file\n", argv[0]);
-        return -1;
-    }
-    path = convert_path(argv[1]);
-    printf("Revoking all non-owner access to %s\n", path);
-    rc = isSecuritySupported(path);
-    if (rc != 1) {
-        if (rc == 0) {
-            printf("File security not supported on this file system\n");
-        }
-        return rc;
-    } else {
-        return revokeAll(path);
-    }
-}
Binary file test/jdk/sun/management/windows/revokeall.exe has changed