Options

NAV 2016 Determining which Windows Groups / Active Directory Groups a User belongs to

rsaritzkyrsaritzky Member Posts: 469
Hi all,

There are a couple of dozen posts here on MIBUSO that ask the same question in a variety of ways: "How can I see/list/determine which Windows (Active Directory) groups a user belongs to from inside NAV via C/AL code?

The method that works successfully in 2009 is to use the "User SID" virtual table - this works great as long as you are looking at the current user. It doesn't work if you are trying to determine if a different user's groups. However, the "User SID" virtual table does not exist in NAV2016

Other suggestions say to use DotNet functions - but I haven't seen any C/AL code that actually does this except for one example - and that example parses the entire Active Directory, so if you have lots of users and lots of groups, this takes a very long time to process.

Another suggestion is to create a linked SQL server and ADO to query active directory.

So, has anyone seen or created an efficient way to return a list of Windows Groups for a User from within C/AL code?

Thanks

Ron
Ron

Answers

  • Options
    saravanans87saravanans87 Member Posts: 36
    There is a field called User Security ID in the Virtual Table (2000000053 Access Control) that might be what you are looking for if my understanding is correct.
    Software Developer,
    Archerpoint India Pvt. Ltd,Chennai.
  • Options
    rsaritzkyrsaritzky Member Posts: 469
    "User Security ID" in the Access Control table is the SID that represents the user ID. This would be useful if there were another table that listed the Windows Groups Members by this same ID, but I do not believe that such a table within NAV exists.

    But thank you for taking the time to reply.

    Ron
    Ron
  • Options
    _tg_tg Member Posts: 2
    I actually developed a component for this which runs off a NAS. It maintains the user groups and users automatically based on designated Windows Security Groups as the NAV roles. It adds / removes the users and the user setup config automatically across the companies using a template record also in the user setup for the security group.

    The simplified code here calls a .NET dll I wrote in VS. This is the best way for me to get access to the full LDAP object of the security group or user, their details and groups. You could also e.g. use it to get the manager and add it to the approval setup automatically also.


    I used this to assess what to do with the user. The user is already in place after getting the users from the security group first.

    SecurityGroups := SecurityGroups.SecurityGroups(); // instantiate .NET
    MyText := SecurityGroups.GetADUsersGroups(FORMAT(UserName)); // Send the user as a parameter

    Separator := '|'; // agreed separator with dll code.
    ValueArray := MyText.Split(Separator.ToCharArray()); // return the list
    IF ValueArray.ToString <> '' THEN BEGIN
    FOREACH Value IN ValueArray DO BEGIN
    //DoSomething like compare NAV groups to Windows groups of the user
    END;
    END;

    in the dll I would search the LDAP e.g:

    public string GetADUsersGroups(string loginName)
    {

    returnstring = SearchUserbyLDAPDomain(loginName, "LDAP://region.companynet.org:123");
    if (returnstring != "")
    {
    return returnstring;
    }

    }

    private string SearchUserbyLDAPDomain(string loginName, string domain)
    {

    DirectoryEntry entry = new DirectoryEntry(domain);
    DirectorySearcher search = new DirectorySearcher(entry);
    SearchResult result;
    string cnname = "";
    string returnstring = "";
    string userName = ExtractUserName(loginName);
    search.Filter = String.Format("(SAMAccountName={0})", userName);
    search.PropertiesToLoad.Add("cn");

    try
    {
    result = search.FindOne();
    cnname = (string)result.Properties["cn"][0];

    search.Filter = String.Format("(cn={0})", cnname);
    search.PropertiesToLoad.Add("memberOf");
    StringBuilder groupsList = new StringBuilder();

    result = search.FindOne();

    if (result != null)
    {
    int groupCount = result.Properties["memberOf"].Count;

    for (int counter = 0; counter < groupCount; counter++)
    {
    string group = (string)result.Properties["memberOf"][counter];
    group = group.Substring(group.IndexOf("CN=") + 3);
    int index = group.IndexOf(",");
    if (index > 0)
    group = group.Substring(0, index);
    groupsList.Append((string)group);
    groupsList.Append("|");
    }
    }

    if (groupsList.Length > 1)
    {
    groupsList.Length -= 1;
    returnstring = groupsList.ToString();
    }
    return returnstring.ToString();
    }
    catch
    {
    return returnstring.ToString();
    }

    }

    private string ExtractUserName(string path)
    {
    string[] userPath = path.Split(new char[] { '\\' });
    return userPath[userPath.Length - 1];
    }

    I hope this helps
  • Options
    rsaritzkyrsaritzky Member Posts: 469
    Thanks _tg - I have seen some other DotNet solutions to this also, but it seems that you don't have easy native access to Windows group within NAV, so a DotNet solution is the only option.

    Ron
    Ron
Sign In or Register to comment.