REVOKE_ACCESS: как удалить «отозвать» унаследованный ACE? - PullRequest
2 голосов
/ 28 января 2012

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

SetEntriesInAcl() для отзыва не унаследованных ACE работает, уменьшает количество ACE ACE, а следующее SetNamedSecurityInfo() выполняет отзыв, и ACE исчезает.

Когда ACE наследуется - оба эти API возвращают SUCCESS - но ACE не удаляется / не отменяется, ACE ACE остается неизменным.

Я также закодировал выполнение DeleteAce(), но когда этот DACL используется в SetNamedSecurityInfo() снова, RC равен SUCCESS (без кодов возврата), и ACE остается для папки, с которой я имею дело - ясно тамхитрость о том, как удалить унаследованный ACE.

Кстати, для той же самой рассматриваемой папки инструмент командной строки 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 */

1 Ответ

1 голос
/ 03 февраля 2012

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...