Search code examples
c#active-directoryldapinteger-overflowactive-directory-group

Reading the SECURITY_ENABLED flag of Group in Active Directory


I'm trying to read the SECURITY_ENABLED flag of a groups groupType property. The problem is that the value I retreive by using

DirectoryEntry entry...
entry.Properties["groupType"].Value;

is an int32, whose range is -2,147,483,647 to 2,147,483,648 (or -0x7FFFFFFF to 0x80000000)

quickWatch

So anytime there is the GROUP_TYPE_SECURITY_ENABLED and any other arbitraty flag set, the numeric value exceeds the the range of an int32 and an overflow happens.

groupTypeScreen

Does anyone know how to avoid this overflow in order to read the correct value?


Solution

  • I think you need to use UInt32 as the type of your enumeration GroupType as follows:

    [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
    }
    

    Let me know if that solves your problem.

    EDIT: OK, I wasn't sure if Entry was an object you created, or part of the Active Directory API. Having said that, I quick created the following variables in a project I'm currently working on and compiled as follows:

    // 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;
    

    I did not get any compile-time errors. In fact, re-looking at the value 0x80000000, it's well with in the range of an Int32.

    Re-looking at your code above, on what line exactly, are you getting the error? I see this suspicios code:

    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);
    }
    

    Perhaps this code could be simplified?

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

    If you really need an ArrayList() for whatever reason, you could then just do return groupTypes.ToArray<int>();

    HTH.