【问题标题】:Getting access denied with GetEffectiveRightsFromAcl()..?使用 GetEffectiveRightsFromAcl() 拒绝访问..?
【发布时间】:2008-12-12 20:48:10
【问题描述】:

我正在尝试检查特定文件的特定权限 受托人并且正在使用 win32 API GetEffectiveRightsFromAcl()。什么时候 该文件可由域组访问,该函数 当本地帐户(管理员或其他)被访问时返回 5(拒绝访问) 用于执行函数。

这三个陈述总结了我所看到的行为 GetEffectiveRightsFromAcl():

  • 当域组对文件具有权限并且程序在 本地帐户:拒绝访问。
  • 当域组对文件具有权限并且程序运行时 在域帐户或本地系统下:成功
  • 当域组没有文件的权限和 程序在任何帐户下运行:成功

有人知道这背后的原因吗?在我看来这是 与 Active Directory 安全性有关。哪些设置可能会影响这一点 什么是调试这个的好方法?

另外,我听说 GetEffectiveRightsFromAcl() 通常可能存在问题,因此请改用 AccessCheck()。但是,我需要能够获取任意 SID 并检查它对文件的访问,因为 AccessCheck() 需要一个模拟令牌,所以我不知道如何从任意 SID 中获取一个令牌......有什么想法吗?谢谢

鲍勃

【问题讨论】:

    标签: c winapi


    【解决方案1】:

    我在 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;
            }
        }
    }
    

    【讨论】:

    • 您好,我对此没有太多经验——您如何知道 dacl 的值以及所需的访问 uint 值?你会参考哪个资源来找出这些东西?
    【解决方案2】:
    • 如果域组有权访问 文件,这个函数必须访问 要枚举的活动目录 受托人的组成员身份 (至少如果它是域用户)。 如果您的程序在 本地账户,然后是这个账户 无权访问 活动目录,因此错误 返回码。
    • 域帐户和本地系统有 访问活动目录。 本地系统是计算机帐户 在活动目录中(计算机 就像 AD 中的用户)。
    • 如果没有域组可以访问 文件,函数不必 检查活动目录。所以 本地用户也成功了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-08
      • 2015-07-01
      • 2016-01-02
      • 2016-06-12
      • 2021-06-26
      • 2015-08-07
      • 2014-12-21
      相关资源
      最近更新 更多