2012-01-28 4 views
2

У меня есть код ниже, который работает для различных изменений ACE и добавляет и отменяет - он просто НЕ работает, когда я пытаюсь удалить ACE, находящийся в ACL (явно там), но этот ACE наследуется.REVOKE_ACCESS: как удалить «аннулировать» унаследованный ACE?

SetEntriesInAcl() для отзыва ненаследуемых ACE работает, уменьшает счет 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

Маски прав доступа и настройки наследования идентичны ACE, которые были отозваны - на руководство по MS (единственное руководство, которое я нашел.) - Установка этого ACE с приведенным выше кодом приводит к новому ACE, который соответствует тому, что я установил - но исходный унаследованный ACE остается - ACL вырос на 1 для этого теста - тогда отмена этого теста ACE работала корректно - снова исходный унаследованный ACE остается. – kevinwaite

+1

Удаление унаследованной ACE нарушает правила для списков ACL. API-интерфейсы высокого уровня не позволят вам это сделать; низкоуровневые API будут, но вы не должны. Вместо этого отключите наследование целевого объекта и скопируйте те ACE, которые вы хотите сохранить, или вместо этого используйте запись «Запретить». –

+0

Спасибо Гарри - программно (через API) ** как ** отключить наследование на моем целевом объекте? - Я не смог это сделать (grrr) ..... Как только наследование отключено - я знаю, как копировать ACE - в своем комментарии, который вы говорите, чтобы скопировать ACE, который я хочу сохранить, скопируйте их туда, где ? и как только вы вернетесь в «дескриптор безопасности» папки - я знаю некоторые API для этого - мне любопытно, что касается ваших мыслей/проницательности ... еще раз спасибо, привет Kevin Waite – kevinwaite

ответ

1

В настоящее время выглядит так, как будто вы извлекаете существующий ACL из папки и изменяете его. В вашей ситуации вам будет лучше строить новый ACL с нуля. Для этого создайте массив структур EXPLICIT_ACCESS, описывающих необходимые разрешения, и вызовите SetEntriesInAcl, передавая NULL для OldAcl.

Чтобы применить новый DACL, вызовите SetNamedSecurityInfo так же, как и в своем коде, но передайте DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION для SecurityInfo. Флаг PROTECTED_DACL_SECURITY_INFORMATION отключает наследование от родителя.

+0

Спасибо, Гарри! Это сработало. Для тех, кто ищет более глубокое чтение/информацию, проверьте эти два URL-адреса. http://msdn.microsoft.com/en-us/magazine/cc163885.aspx#S3 -and- http://www.tenouk.com/ModuleH.html – kevinwaite

 Смежные вопросы

  • Нет связанных вопросов^_^