JNIEXPORT jboolean JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_isCurrentUserAdmin0()

in src/main/cpp/jnilib/windows/src/jni_WindowsNativeUtils.c [33:147]


JNIEXPORT jboolean JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_isCurrentUserAdmin0(JNIEnv* jEnv, jobject jObject) {
    BOOL result = FALSE;
    
    PACL pACL = NULL;
    PSID psidAdmin = NULL;
    HANDLE token = NULL;
    HANDLE duplToken = NULL;
    PSECURITY_DESCRIPTOR adminDescriptor = NULL;
    
    SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
    DWORD aclSize;
    
    const DWORD ACCESS_READ  = 1;
    const DWORD ACCESS_WRITE = 2;
    
    GENERIC_MAPPING mapping;
    
    PRIVILEGE_SET ps;
    DWORD status;
    DWORD structSize = sizeof(PRIVILEGE_SET);
    
    // MS KB 118626
    while (TRUE) {
        if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, TRUE, &token)) {
            if (GetLastError() != ERROR_NO_TOKEN) {
                throwException(jEnv, "Native error");
                break;
            }
            
            if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &token)) {
                throwException(jEnv, "Native error");
                break;
            }
        }
        
        if (!DuplicateToken(token, SecurityImpersonation, &duplToken)) {
            throwException(jEnv, "Native error");
            break;
        }
        
        if (!AllocateAndInitializeSid(&SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin)) {
            throwException(jEnv, "Native error");
            break;
        }
        
        adminDescriptor = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
        if (adminDescriptor == NULL) {
            throwException(jEnv, "Native error");
            break;
        }
        if (!InitializeSecurityDescriptor(adminDescriptor, SECURITY_DESCRIPTOR_REVISION)) {
            throwException(jEnv, "Native error");
            break;
        }
        
        aclSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidAdmin) - sizeof(DWORD);
        
        pACL = (PACL) LocalAlloc(LPTR, aclSize);
        if (pACL == NULL) {
            throwException(jEnv, "Native error");
            break;
        }
        if (!InitializeAcl(pACL, aclSize, ACL_REVISION2)) {
            throwException(jEnv, "Native error");
            break;
        }
        
        if (!AddAccessAllowedAce(pACL, ACL_REVISION2, ACCESS_READ | ACCESS_WRITE , psidAdmin)) {
            throwException(jEnv, "Native error");
            break;
        }
        if (!SetSecurityDescriptorDacl(adminDescriptor, TRUE, pACL, FALSE)) {
            throwException(jEnv, "Native error");
            break;
        }
        
        SetSecurityDescriptorGroup(adminDescriptor, psidAdmin, FALSE);
        SetSecurityDescriptorOwner(adminDescriptor, psidAdmin, FALSE);
        
        if (!IsValidSecurityDescriptor(adminDescriptor)) {
            throwException(jEnv, "Native error");
            break;
        }
        
        mapping.GenericRead    = ACCESS_READ;
        mapping.GenericWrite   = ACCESS_WRITE;
        mapping.GenericExecute = 0;
        mapping.GenericAll     = ACCESS_READ | ACCESS_WRITE;
        
        if (!AccessCheck(adminDescriptor, duplToken, ACCESS_READ, &mapping, &ps, &structSize, &status, &result)) {
            throwException(jEnv, "Native error");
            break;
        }
        
        break;
    }
    
    if (pACL) {
        LocalFree(pACL);
    }
    if (adminDescriptor) {
        LocalFree(adminDescriptor);
    }
    if (psidAdmin) {
        FreeSid(psidAdmin);
    }
    if (duplToken) {
        CloseHandle(duplToken);
    }
    if (token) {
        CloseHandle(token);
    }
    
    return result;
}