来自SetNamedSecurityInfo的ERROR_BAD_INHERITANCE_ACL?

时间:2009-05-29 19:07:30

标签: windows winapi acl

从SetNamedSecurityInfo返回的ERROR_BAD_INHERITANCE_ACL意味着什么?在这种情况下,我将用户添加到目录的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 :(得分:0)

代码示例肯定会有所帮助。很容易获得构建逻辑和设置ACL的巧妙错误。

我没有在我面前的代码,但基本逻辑是:

  1. 使用足够的访问掩码获取进程令牌
  2. GetNamedSecurityInfo
  3. 为新ACE分配足够大的新ACL,从旧版复制到新版,并调用AddAccessAllowedAceEx添加用户的SID
  4. SetNamedSecurityInfo