【问题标题】:Reading the SECURITY_ENABLED flag of Group in Active Directory读取 Active Directory 中组的 SECURITY_ENABLED 标志
【发布时间】:2013-05-15 13:16:35
【问题描述】:

我正在尝试读取组 groupType 属性的 SECURITY_ENABLED 标志。问题是我使用

检索的值
DirectoryEntry entry...
entry.Properties["groupType"].Value;

是一个int32,其范围是-2,147,483,647 to 2,147,483,648 (or -0x7FFFFFFF to 0x80000000)

因此,只要设置了GROUP_TYPE_SECURITY_ENABLED 和任何其他仲裁标志,数值就会超出 int32 的范围并发生溢出。

有谁知道如何避免这种溢出以读取正确的值?

【问题讨论】:

  • 标志是否必须是一个 int 0x80000000 很好地适合一个单元。
  • 默认情况下,Int32 已签名。你可以使用 UInt32 吗??
  • Entry.Properties["groupType"].Value 返回 -2147483646。当我尝试将其转换为 uint 时,我得到一个 InvalidCastException

标签: c# active-directory ldap integer-overflow active-directory-group


【解决方案1】:

参考@fourpastmidnight 的回答和这些文章object-group-attribute-grouptypemsdn Group-Type attribute,我能够找到不需要转换为uint 或通过if ... else if 语句解析的解决方案。

从第一个链接和@wodzu 对 -2147483646 返回值的评论中看到负值,我尝试将 SECURITY_ENALBED 值反转为 -0x80000000。

[System.Flags]
public enum GroupType
{
    BUILTIN_LOCAL_GROUP = 0x00000001,
    ACCOUNT_GROUP       = 0x00000002,
    RESOURCE_GROUP      = 0x00000004,
    UNIVERSAL_GROUP     = 0x00000008,
    APP_BASIC_GROUP     = 0x00000010,
    APP_QUERY_GROUP     = 0x00000020,
    SECURITY_ENABLED    = -0x80000000
}

现在获取值并转换为 GroupType 时

var groupType = (GroupType)this.Entry.Properties["groupType"].Value

然后您可以在 GroupType 值上使用 .ToString() ,这将返回每个标志的逗号分隔字符串。
或者你可以使用 .HasFlag 方法来检查它是否是一个安全组

bool IsSecurityGroup = groupType.HasFlag(GroupType.SECURITY_ENABLED);

【讨论】:

    【解决方案2】:

    我认为您需要使用UInt32 作为您的枚举类型GroupType,如下所示:

    [Flags]
    public enum GroupType : uint
    {
        BUILTIN_LOCAL_GROUP = 0x00000001,
        ACCOUNT_GROUP       = 0x00000002,
        RESOURCE_GROUP      = 0x00000004,
        UNIVERSAL_GROUP     = 0x00000008,
        APP_BASIC_GROUP     = 0x00000010,
        APP_QUERY_GROUP     = 0x00000020,
        SECURITY_ENABLED    = 0x80000000
    }
    

    如果这能解决您的问题,请告诉我。

    编辑:好的,我不确定Entry 是您创建的对象,还是 Active Directory API 的一部分。话虽如此,我在我目前正在处理的项目中快速创建了以下变量,并编译如下:

    // I only made it static so I could get my compiler to compile this in something I'm currently
    // working on. It's not necessary for it to be static.
    static int SECURITY_ENABLED = 0x80000000;
    
    int newValue = SECURITY_ENABLED | 1;
    

    我没有收到任何编译时错误。事实上,再看0x80000000的值,它在Int32的范围内很好。

    重新查看上面的代码,究竟在哪一行,你得到错误了吗?我看到了这个可疑代码:

    if (groupTypes.Count == 1)
    {
        var  firstFlag = (int) groupTypes[0];
    
        // What is this checking, exactly?
        // Is this where the error is occurring?
        var longFlag = -(((long) flag) - firstFlag);
    
        if ((longFlag == 0x80000000)) // Extra parentheses here...just a formatting thing
            groupTypes.Add(GroupType.SECURITY_ENABLED);
    }
    

    也许这段代码可以简化?

    public List<GroupType> GetGroupType()
    {
        var groupTypes = new List<GroupType>();
        var flag = (GroupType) this.Entry.Properties["groupType"].Value;
    
        if (flag & GroupType.ACCOUNT_GROUP > 0)
            groupTypes.Add(GroupType.ACCOUNT_GROUP;
        else if (flag & GroupType.APP_BASIC_GROUP > 0)
            groupTypes.Add(GroupType.APP_BASIC_GROUP);
    
        // ... Other else if ad nauseum ...
    
        else if (flag & GroupType.SERUCITY_ENABLED > 0)
            groupTypes.Add(GroupType.SECURITY_ENABLED);
    
        return groupTypes;
    }
    

    如果您出于某种原因确实需要ArrayList(),那么您可以直接使用return groupTypes.ToArray&lt;int&gt;();

    HTH。

    【讨论】:

    • 如前所述:Entry.Properties["groupType"].Value 返回 -2147483646。当我尝试将其转换为 uint 时,我得到一个 InvalidCastException。所以我什至不能将返回值与枚举结合起来
    • 在调试模式下可以看到,它是一个有符号整数img845.imageshack.us/img845/2369/grouptype.png
    • “可疑”代码是一种解决方法,即使存在缓冲区溢出,也可以读取标志。如果设置了两个标志,现在它可以工作。首先我得到标志,那不是 SERUCITY_ENABLED 标志。然后我转换给定的标志值并将其转换为 long 以恢复初始值,方法是减去第一个标志的值,这样我就可以检查是否设置了 SERUCITY_ENABLED 标志。具体来说,当我尝试像这样设置标志时,我得到一个 COMException: var val = (long) ((int) this.Entry.Properties["groupType"].Value); this.Entry.Properties["groupType"].Value = val & ~0x80000000;
    • 此屏幕截图显示,当我尝试将 0x80000000 分配给 int img692.imageshack.us/img692/6046/errorowc.png 时出现编译器错误
    • 有趣的是你得到了那个小弹出窗口。在我编译之前,我没有收到这样的编译错误(并且我确实编译了),我什至没有收到来自 Visual Studio 的警告。该弹出窗口看起来不像标准的 Visual Studio 类型错误。会不会是您正在使用的工具让您误以为您无法分配此值?我向你保证,我可以,我刚刚执行了有问题的代码。
    【解决方案3】:

    一个小 Python 解码 groupType AD 属性值

    1. 准备一本包含所有已定义组合的字典。 (参考Microsoft

       gt_decode_dict = {
           "0x00000001": "SYSTEM CREATED",     # Specifies a group that is created by the system.
           "0x00000002": "GLOBAL",             # Specifies a group with global scope.
           "0x00000004": "LOCAL",              # Specifies a group with domain local scope.
           "0x00000008": "UNIVERSAL",          # Specifies a group with universal scope.
           "0x00000010": "APP_BASIC",          # Specifies an APP_BASIC group for Windows Server Authorization Manager.
           "0x00000020": "APP_QUERY",          # Specifies an APP_QUERY group for Windows Server Authorization Manager.
           "0x80000000": "SECURITY"}           # Specifies a security group. If this flag is not set, then the group is a distribution group.
      
    2. 定义一个函数来解码 groupType 值

       def decode_gt(_group_type):
       #
       # Decode groupType attribute.
       # 
       global gt_decode_dict
       _delta = 0
      
       _translatedGT = ""
       if _group_type > 0:
           _hex_gt = hex(_group_type)
           _gt_work = int(_hex_gt[2:])
           _gt_work = str(_gt_work).rjust(8, "0")
           _gt_key = r'0x' + str(_gt_work)
           _translatedGT += "DISTRIBUTION - "
       else:
           _delta = 2147483648 - abs(_group_type)
           if (_delta % 2) > 0:
               _translatedGT = "SECURITY - SYSTEM CREATED - "
               _gt_key = r'0x' + str(_delta - 1).rjust(8, "0")
           else:
               _translatedGT = "SECURITY - "
               _gt_key = r'0x' + str(_delta).rjust(8, "0")
      
       if _gt_key in gt_decode_dict.keys():
           _translatedGT += gt_decode_dict[_gt_key]
       else:
           notification("   Invalid groupType key: " + str(_gt_key) + ". Values dec: " + str(_group_type) + " delta:" + str(_delta) + ", for group " + _group_dn, 4)
           _translatedGT += " Error "
      
       return _translatedGT
      
    3. 调用将 groupType 作为 Integer 传递的函数

      结果 = _groupType = decode_gt(int(_groupType))

    【讨论】:

      猜你喜欢
      • 2011-02-27
      • 1970-01-01
      • 2017-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多