2012-01-28 1 views
2

아래의 코드는 다양한 ACE 변경 및 추가 및 취소를 위해 작동합니다. ACL에 분명히있는 ACE를 제거하려고 시도하면 작동하지 않지만이 ACE는 상속됩니다.REVOKE_ACCESS : 상속 된 ACE를 '취소'하는 방법은 무엇입니까?

상속되지 않은 ACE를 해지하는 경우 SetEntriesInAcl()이 작동하면 ACL ACE 수가 감소하고 다음은 SetNamedSecurityInfo()으로 해지되고 ACE는 사라집니다.

ACE가 상속되는 경우 (이 두 API는 모두 SUCCESS을 반환하지만 ACE는 제거/취소되지 않음) ACL ACE 수가 동일하게 유지됩니다.

또한 DeleteAce()을하고 코딩했지만 그 DACL이 SetNamedSecurityInfo()에서 사용되는 경우 다시 RC는 SUCCESS (돌아올 수없는 코드)이며, ACE 내가 처리하고있는 폴더에 대한 유지 - 분명히을 제거하는 방법에 트릭이 상속 된 ACE.

Btw SUBINACL 명령 줄 도구는 문제없이이 상속 된 ACE를 해지합니다.

    if(EqualSid(pSid_for_ace, pSid) ) 
        { /* ACE SID matched edit SID */ 

        if(cmd_se_edit == SE_REM) 
         { /* remove */ 

         rem_lst[ ace_idx ] = x; 

         exp_ace[ ace_idx ].grfAccessPermissions = dwAccessRights; 
         exp_ace[ ace_idx ].grfAccessMode  = REVOKE_ACCESS; 
         exp_ace[ ace_idx ].grfInheritance  = dwInheritance; 
         exp_ace[ ace_idx ].Trustee.TrusteeForm = TRUSTEE_IS_SID; 
         exp_ace[ ace_idx ].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; 
         exp_ace[ ace_idx ].Trustee.ptstrName = pSid; 

         if(ace_idx < (REMMAX-1)) ++ace_idx; 

         } /* remove */ 

        } /* ACE SID matched edit SID */ 

       pBA = (BYTE *)p_aceHdr; 

       ace_sz = p_aceHdr->AceSize; 

       p_aceHdr = (PACE_HEADER)&pBA[ ace_sz ]; 

       } /* loop through ACEs */ 


      // Create a new ACL that merges the new ACE 
      // into the existing DACL. 

      if(ace_idx) 
       { /* ACEs to remove */ 

       dwRes = SetEntriesInAcl(ace_idx, &exp_ace[0], 
                 pDacl, &pNewDacl); 
       if(ERROR_SUCCESS != dwRes) 
       { 
       printf("SetEntriesInAcl Error %u\n", dwRes); 
       goto Cleanup2; 
       } 

       // Attach the new ACL as the object's DACL. 

       dwRes = SetNamedSecurityInfo( ObjName, 
               ObjectType, 
               DACL_SECURITY_INFORMATION, 
               NULL, 
               NULL, 
               pNewDacl, 
               NULL); 

       if(ERROR_SUCCESS != dwRes) 
       { 
       rc3 = GetLastError(); 
       printf("SetNamedSecurityInfo Error %u\n", dwRes); 
       goto Cleanup2; 
       } 

       } /* ACEs to remove */ 
+0

액세스 권한 마스크 및 상속 설정은 MS 지침 (검색 한 유일한 지침)에 따라 취소되는 ACE와 동일합니다. 위의 코드로이 ACE를 설정하면 설정 한 것과 일치하는 새 ACE가 생성됩니다. 원래의 상속 된 ACE는 그대로 유지됩니다.이 테스트에서는 ACL이 1 씩 증가했습니다. 그런 다음이 테스트 ACE의 해지가 올바르게 수행되었습니다. 다시 한 번 원래 상속 된 ACE가 그대로 유지됩니다. – kevinwaite

+1

상속 된 ACE를 제거하면 ACL에 대한 규칙이 적용되지 않습니다. 높은 수준의 API로는이 작업을 수행 할 수 없습니다. 낮은 수준의 API는 가능하지만 그렇지 않아야합니다. 대신 대상 개체에서 상속을 해제하고 보관하려는 ACE를 복사하거나 대신 거부 항목을 사용하는 것이 좋습니다. –

+0

해리에게 감사드립니다 - 프로그래밍 방식으로 (API를 통해) ** 어떻게 ** 목표 대상 개체에서 상속을 해제합니까? -이 작업을 수행 할 수 없었습니다. (grrr) ..... 일단 상속이 해제되면 - ACE를 복사하는 방법을 알고 있습니다. - 계속 하시겠습니까? ? 한 번 거기에 "폴더의"보안 설명자를 어떻게 다시 넣을 것인가 - 나는 그것을 할 수있는 몇 가지 API를 안다. - 나는 당신의 생각/통찰력에 대해 호기심이있다 .... Kevin Waite에게 감사한다. – kevinwaite

답변

1

현재 폴더에서 기존 ACL을 검색하고 수정하는 것처럼 보입니다. 자신의 상황에서 처음부터 새로운 ACL을 만드는 것이 더 낫습니다. 이렇게하려면 원하는 사용 권한을 설명하는 EXPLICIT_ACCESS 구조체 배열을 만들고 OldAcl에 NULL을 전달하는 SetEntriesInAcl을 호출합니다.

새 DACL을 적용하려면 코드에서와 같은 방식으로 SetNamedSecurityInfo를 호출하고 SecurityInfo에 DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION을 전달합니다. PROTECTED_DACL_SECURITY_INFORMATION 플래그는 부모로부터의 상속을 비활성화합니다.

+0

고마워요 해리! 이것은 효과가 있었다. 더 많은 독서/정보를 찾으려면이 두 개의 URL을 확인하십시오. http://msdn.microsoft.com/en-us/magazine/cc163885.aspx#S3 - 및 - http://www.tenouk.com/ModuleH.html – kevinwaite