ERROR_BAD_INHERITANCE_ACL из SetNamedSecurityInfo? - PullRequest
0 голосов
/ 29 мая 2009

Что означает ERROR_BAD_INHERITANCE_ACL, возвращаемое из SetNamedSecurityInfo? В этом случае я добавляю пользователя в ACL каталога. Я посмотрел на рассматриваемый каталог и его права кажутся разумными перед звонком. Но звонки не удаются.

Есть мысли?

Вот фрагмент кода, выполняющий работу (и когда я вставляю его сюда, меня интересует значение 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); 

1 Ответ

0 голосов
/ 07 июля 2009

Пример кода определенно поможет. Легко получить логику, чтобы построить и настроить ACL немного неправильно.

У меня нет кода передо мной, но основная логика:

  1. получить токен процесса с достаточной маской доступа
  2. GetNamedSecurityInfo
  3. выделить новый ACL, достаточно большой для нового ACE, скопировать из старого в новый и вызвать AddAccessAllowedAceEx, чтобы добавить SID пользователя
  4. SetNamedSecurityInfo
...