Получение доступа запрещено с помощью GetEffectiveRightsFromAcl () ..?

Я пытаюсь проверить права на определенный файл для конкретного доверенного лица и использую Win32 API GetEffectiveRightsFromAcl (). Когда файл доступен для группы домена, функция возвращает 5 (доступ запрещен), когда для выполнения функции используется локальная учетная запись (администратор или другая).

Эти три утверждения суммируют поведение, которое я наблюдаю с GetEffectiveRightsFromAcl ():

  • Когда группа домена имеет права на файл и программа запускается под локальной учетной записью: Доступ запрещен.
  • Когда группа домена имеет права на файл и программа запускается под учетной записью домена или в локальной системе: успех
  • Когда у группы домена нет прав на файл, и программа запускается под любой учетной записью: Успех

Кто-нибудь знает причину этого? Мне кажется, это связано с безопасностью Active Directory. Какие настройки могут повлиять на это, и что будет хорошим способом отладки этого?

Кроме того, я слышал, что GetEffectiveRightsFromAcl (), как правило, может быть проблематичным и использовать вместо этого AccessCheck (). Однако мне нужно иметь возможность взять произвольный SID и проверить его доступ к файлу, а поскольку AccessCheck () требует токен олицетворения, я не знаю, как я мог бы выделить токен из произвольного SID ... Есть идеи? Спасибо

боб

12.12.2008 20:48:10
2 ОТВЕТА
  • если доменная группа имеет право на файл, эта функция должна получить доступ к активному каталогу, чтобы перечислить членство в группе опекуна (по крайней мере, если это пользователь домена). Если ваша программа работает под локальной учетной записью, то эта учетная запись не имеет права доступа к активному каталогу, поэтому код возврата ошибки.
  • Учетная запись домена и локальная система имеют доступ к активному каталогу. Локальная система - это учетная запись компьютера в активном каталоге (компьютеры похожи на пользователей в AD).
  • Если ни одна доменная группа не имеет доступа к файлу, функция не должна проверять активный каталог. Так что локальные пользователи тоже преуспевают.
2
12.12.2008 23:28:54

Я использовал в C #, и он хорошо работает для меня.

using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.AccessControl;

namespace DACL
{
    class Class1
    {
        private enum MULTIPLE_TRUSTEE_OPERATION
        {
            NO_MULTIPLE_TRUSTEE,
            TRUSTEE_IS_IMPERSONATE
        }

        private enum TRUSTEE_FORM
        {
            TRUSTEE_IS_SID,
            TRUSTEE_IS_NAME,
            TRUSTEE_BAD_FORM,
            TRUSTEE_IS_OBJECTS_AND_SID,
            TRUSTEE_IS_OBJECTS_AND_NAME
        }

        private enum TRUSTEE_TYPE
        {
            TRUSTEE_IS_UNKNOWN,
            TRUSTEE_IS_USER,
            TRUSTEE_IS_GROUP,
            TRUSTEE_IS_DOMAIN,
            TRUSTEE_IS_ALIAS,
            TRUSTEE_IS_WELL_KNOWN_GROUP,
            TRUSTEE_IS_DELETED,
            TRUSTEE_IS_INVALID,
            TRUSTEE_IS_COMPUTER
        }

        private struct TRUSTEE
        {
            public IntPtr pMultipleTrustee;
            public MULTIPLE_TRUSTEE_OPERATION MultipleTrusteeOperation;
            public TRUSTEE_FORM TrusteeForm;
            public TRUSTEE_TYPE TrusteeType;
            public IntPtr ptstrName;
        }

        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern void BuildTrusteeWithSid(
            ref TRUSTEE pTrustee,
            byte[] sid
        );

        [DllImport("advapi32.dll")]
        private static extern uint GetEffectiveRightsFromAcl(byte[] pacl, ref TRUSTEE pTrustee, ref uint pAccessRights);

        public bool HasAccess(SecurityIdentifier sid)
        {
            DiscretionaryAcl dacl = <DACL from somewhere>;

            byte[] daclBuffer = new byte[dacl.BinaryLength];
            dacl.GetBinaryForm(daclBuffer, 0);

            byte[] sidBuffer = new byte[sid.BinaryLength];
            sid.GetBinaryForm(sidBuffer, 0);

            TRUSTEE t = new TRUSTEE();
            BuildTrusteeWithSid(ref t, sidBuffer);

            uint access = 0;
            uint hr = GetEffectiveRightsFromAcl(daclBuffer, ref t, ref access);

            int i = Marshal.Release(t.ptstrName);

            return ((access & <Desired Access>) == <Desired Access>) ? true : false;
        }
    }
}
3
9.12.2013 17:22:38
Привет, у меня нет большого опыта с этим - откуда вы знаете значения для dacl, а также желаемое значение uint для доступа? На какой ресурс вы бы ссылались, чтобы узнать эти вещи?
Shane 23.04.2018 04:49:43