windows - ERROR\_BAD\_INHERITANCE\_ACL fra SetNamedSecurityInfo?

Indlæg af Hanne Mølgaard Plasc

Problem



Hvad betyder ERROR\_BAD\_INHERITANCE\_ACL returneret fra SetNamedSecurityInfo implicere? I dette tilfælde tilføjer jeg en bruger til en mappes ACL. Jeg har kigget på den pågældende mappe, og dens rettigheder synes rimelige før opkaldet. Men opkaldene fejler.


nogen tanker?


Her er kodestykket, der gør arbejdet (og når jeg indsætter det her, undrer jeg mig om værdien NO\_MULTIPLE\_TRUSTEE:


pAAP is a pointer to a structure with the following members:
CString objName;          // name of object
SE\_OBJECT\_TYPE ObjectType;  // type of object
CString trustee;            // trustee for new ACE (explicit user name)
CString targetComputer;
bool bNeedWrite;

    DWORD dwRes = 0;
    PACL pOldDACL = NULL, pNewDACL = NULL;
    PSECURITY\_DESCRIPTOR pSD = NULL;
    EXPLICIT\_ACCESS ea = {0};
    CSID trusteeSID;

    bool bGotSID = false;
    if(0 == wcsncmp(pAAP->trustee, L"SID:", 4)) //4 = len of SID: //GLOK
        bGotSID = CSID::FromString((LPWSTR)((LPCWSTR)pAAP->trustee + 4), trusteeSID);
    else
        bGotSID = CSID::FromAccount(pAAP->targetComputer, pAAP->trustee, trusteeSID);

    if(false == bGotSID)
    {
        Log(logDEBUG, L"CSID::FromAccount failed for [\%s] on [\%s].  GLE=\%s", pAAP->trustee, pAAP->targetComputer, GetSystemErrorMessage(GetLastError()));
        \_ASSERT(0);
        goto Cleanup;
    }

    // Get a pointer to the existing DACL.
    dwRes = GetNamedSecurityInfo(pAAP->objName.LockBuffer(), pAAP->ObjectType, DACL\_SECURITY\_INFORMATION,
                                NULL, NULL, &pOldDACL, NULL, &pSD);
    pAAP->objName.UnlockBuffer();
    if (ERROR\_SUCCESS != dwRes)
    {
        Log(logDEBUG, L"GetNamedSecurityInfo failed on [\%s] for [\%s] on [\%s].  GLE=\%s", pAAP->objName, pAAP->trustee, pAAP->targetComputer, GetSystemErrorMessage(dwRes));
        //\_ASSERT(ERROR\_FILE\_NOT\_FOUND == dwRes);
        goto Cleanup; 
    }  

    // Initialize an EXPLICIT\_ACCESS structure for the new ACE. 
    ea.grfAccessPermissions = pAAP->bNeedWrite ? GENERIC\_ALL : GENERIC\_READ;
    ea.grfAccessMode = GRANT\_ACCESS;
    ea.grfInheritance= CONTAINER\_INHERIT\_ACE | OBJECT\_INHERIT\_ACE;
    ea.Trustee.TrusteeForm = TRUSTEE\_IS\_SID;
    ea.Trustee.TrusteeType = TRUSTEE\_IS\_USER;
    ea.Trustee.ptstrName = (LPWSTR)(PSID)trusteeSID;
    ea.Trustee.MultipleTrusteeOperation = NO\_MULTIPLE\_TRUSTEE;

    // Create a new ACL that merges the new ACE into the existing DACL.
    dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
    if (ERROR\_SUCCESS != dwRes)  
    {
        Log(logDEBUG, L"SetEntriesInAcl failed on [\%s] for [\%s] on [\%s].  GLE=\%s", pAAP->objName, pAAP->trustee, pAAP->targetComputer, GetSystemErrorMessage(dwRes));
        //\_ASSERT(0);
        goto Cleanup; 
    }  

    // Attach the new ACL as the object's DACL.
    dwRes = SetNamedSecurityInfo(pAAP->objName.LockBuffer(), pAAP->ObjectType, DACL\_SECURITY\_INFORMATION,
                                NULL, NULL, pNewDACL, NULL);
    if (ERROR\_SUCCESS != dwRes)  
    {
        Log(logDEBUG, L"SetNamedSecurityInfo failed on [\%s] for [\%s] on [\%s].  GLE=\%s", pAAP->objName, pAAP->trustee, pAAP->targetComputer, GetSystemErrorMessage(dwRes));
        //\_ASSERT(dwRes == ERROR\_BAD\_INHERITANCE\_ACL);
        goto Cleanup; 
    }  

Cleanup:
    if(pSD != NULL) 
        LocalFree((HLOCAL) pSD); 
    if(pNewDACL != NULL) 
        LocalFree((HLOCAL) pNewDACL); 

Bedste reference


En kodeeksempel ville helt sikkert hjælpe. Det er nemt at få logikken til at opbygge og sætte ACL'en forkert.


Jeg har ikke koden foran mig, men den grundlæggende logik er:



  1. erhverve procestoken med en tilstrækkelig adgangsmaske

  2. GetNamedSecurityInfo

  3. tildel en ny ACL stor nok til den nye ACE, kopi fra den gamle til den nye og ring AddAccessAllowedAceEx for at tilføje brugerens SID

  4. SetNamedSecurityInfo