locked
SetEntriesInAcl failed with ERROR_NONE_MAPPED RRS feed

  • Question

  • Hi All,

    We are developing a Windows service application with VC++, and using "SetEntriesInAcl" API for changing the service properties. But this API is failing on some Windows 7 machines with Error code "ERROR_NONE_MAPPED (1332)". Kindly help us to solve this case, below are the sample code which we are using:

    The system was previously added to a domain and later migrated to workgroup to check this case. Still no luck. 

    BOOL SetServicePrivilege(long lChkSum, long lUser, long lProtectService)
    {
    SECURITY_DESCRIPTOR sd;
    LPTSTR lpszUser;
    EXPLICIT_ACCESS eaPowUser;
    DWORD dwAccessPermissions = 0,
    dwError             = 0,
    dwSize              = 0;
    PACL pacl                = NULL,
    pNewAcl             = NULL;
    SC_HANDLE schManager          = NULL,
    schService          = NULL;
    PSECURITY_DESCRIPTOR psd = NULL;
    BOOL bDaclPresent        = FALSE,
    bDaclDefaulted      = FALSE,
    bSuccess            = FALSE,
    bRelease = FALSE;
    ////////////////////////////////////////////////////
    try
    {
    if(lChkSum != CHECKSUM)
    return bSuccess;

    psd = (PSECURITY_DESCRIPTOR)&psd;

    if(lUser == 1)
    {
    lpszUser = "Power Users";

    if(lProtectService == 0)
    dwAccessPermissions = SERVICE_ENUMERATE_DEPENDENTS | SERVICE_INTERROGATE | 
    SERVICE_PAUSE_CONTINUE | SERVICE_QUERY_CONFIG | 
    SERVICE_QUERY_STATUS | SERVICE_START | SERVICE_STOP | 
    SERVICE_USER_DEFINED_CONTROL | READ_CONTROL;
    else
    dwAccessPermissions = SERVICE_START | READ_CONTROL | DELETE;
    }
    else if(lUser == 2)
    {
    lpszUser = "Administrators";

    if(lProtectService == 0)
    dwAccessPermissions = SERVICE_CHANGE_CONFIG | SERVICE_ENUMERATE_DEPENDENTS | 
    SERVICE_INTERROGATE | SERVICE_PAUSE_CONTINUE | 
    SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS | SERVICE_START | 
    SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL | READ_CONTROL | 
    WRITE_OWNER | WRITE_DAC | DELETE ;
    else
    dwAccessPermissions = SERVICE_START | READ_CONTROL | DELETE;
    }
    else
    goto cleanup;

    schManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);// Obtain a handle to the Service Controller.

    if(schManager == NULL)
    goto cleanup;

    schService = OpenService(schManager, "cwClient", READ_CONTROL | WRITE_DAC);// Obtain a handle to the service.

    if(schService == NULL)
    goto cleanup;

    if(!QueryServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION, psd, 0, &dwSize))// Get the current security descriptor.
    {
    long lError = GetLastError();
    if(lError == ERROR_INSUFFICIENT_BUFFER)
    {
    psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
    if(psd == NULL)
    goto cleanup;
    else
    bRelease = TRUE;
    ///////////////////
    if(!QueryServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION, psd, dwSize, &dwSize))
    goto cleanup;
    }
    else
    goto cleanup;
    }

    if(!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl, &bDaclDefaulted))// Get the DACL.
    goto cleanup;

    BuildExplicitAccessWithName(&eaPowUser, TEXT(lpszUser), dwAccessPermissions, SET_ACCESS, NO_INHERITANCE);

    dwError = SetEntriesInAcl(1, &eaPowUser, pacl, &pNewAcl);// Failed with ERROR_NONE_MAPPED

    if(dwError != ERROR_SUCCESS)
    goto cleanup;

    if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))// Initialize a NEW Security Descriptor.
    goto cleanup;

    if(!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE))// Set the new DACL in the Security Descriptor.
    goto cleanup;

    if(!SetServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION, &sd))// Set the new DACL for the service object.
    goto cleanup;

    bSuccess = TRUE;

    cleanup:
    if(pNewAcl)
    LocalFree((HLOCAL)pNewAcl);
    if(bRelease)
    {
    if(psd)
    HeapFree(GetProcessHeap(), 0, (LPVOID)psd);
    }
    if(schService)
    CloseServiceHandle(schService);
    if(schManager)
    CloseServiceHandle(schManager);
    }
    catch(...)
    {
    }
    return bSuccess;
    }

    Thanks,

    R-VR


    • Edited by R-V-R Monday, April 16, 2018 2:15 PM
    Monday, April 16, 2018 2:11 PM

Answers

  • Instead of using BuildExplicitAccessWithName() consider filling in the members of the EXPLICIT_ACCESS structure manually while using the well-known SIDS for the Administrators and Power Users groups.  That would eliminate any need to map names to SIDS.

    • Proposed as answer by Baron Bi Tuesday, April 17, 2018 2:01 AM
    • Marked as answer by R-V-R Friday, June 22, 2018 5:45 AM
    Monday, April 16, 2018 3:04 PM

All replies

  • Instead of using BuildExplicitAccessWithName() consider filling in the members of the EXPLICIT_ACCESS structure manually while using the well-known SIDS for the Administrators and Power Users groups.  That would eliminate any need to map names to SIDS.

    • Proposed as answer by Baron Bi Tuesday, April 17, 2018 2:01 AM
    • Marked as answer by R-V-R Friday, June 22, 2018 5:45 AM
    Monday, April 16, 2018 3:04 PM
  • One additional observation -

    Declaring a pointer as LPTSTR and then assigning narrow string literals like "Power Users" or "Administrators" will only compile successfully in an MBCS build.  This is where the TEXT macro should be used, not in the call to BuildExplicitAccessWithName.

    Monday, April 16, 2018 6:16 PM
  • Hi,

    If your case has been solved, please help to mark answer. If not, just feel free to contact us.

    Your understanding and cooperation will be grateful.

    Best Regards,

    Baron Bi


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, April 24, 2018 5:20 AM