Welcome to Dream.In.Code
Getting C# Help is Easy!

Join 136,169 C# Programmers for FREE! Get instant access to thousands of C# experts, tutorials, code snippets, and more! There are 1,876 people online right now. Registration is fast and FREE... Join Now!




Can you help me with the correct code

 
Reply to this topicStart new topic

Can you help me with the correct code, Error handling with AD Connection

dping28
17 Dec, 2007 - 05:00 AM
Post #1

New D.I.C Head
*

Joined: 17 Dec, 2007
Posts: 6


My Contributions
First of all, hello! smile.gif I have a project where I would like to interface with Active Directory and started it off following this and after alot of alterations I managed to get it working. I currently have a form with 3 text boxes (1 for server, 1 for username, 1 for password) and then the text box that link wants and the listbox for displaying the users groups. If I enter an actual user it works. However it crashes when I enter a user that doesnt exist. Here is the code I have for the Find Groups button:

CODE

private void button1_Click(object sender, EventArgs e)
        {
            string strUserADsPath = "LDAP://" + txtServer.Text + "/cn=" + textBox1.Text + ",ou=Accounts,dc=Gotham,dc=local";
            DirectoryEntry oUser;
            oUser = new DirectoryEntry(strUserADsPath,txtUserName.Text,txtPassword.Text);
                listBox1.Items.Add("Groups to which " + oUser.Name + " belongs:");
                // Invoke IADsUser::Groups method.
                object groups = oUser.Invoke("Groups");
                foreach (object group in (System.Collections.IEnumerable)groups)
                {
                    // Get the Directory Entry.
                    DirectoryEntry groupEntry = new DirectoryEntry(group);
                    listBox1.Items.Add(groupEntry.Name);
                }
        }


Im guessing I need some kind of :

IF (no user found) THEN
AlertBox of some kind saying "No user found!"
ELSE
The above code

I just not sure the correct way to lay it out. Would someone be so kind to help me with this? Once I have a single example that would work in this situation I think I would be ok as I go on experimenting and adding to this. I just havent been able to find what I need so far, maybe because I dont know how to phrase my searches yet.

Thanks!

-D
User is offlineProfile CardPM
+Quote Post

baavgai
RE: Can You Help Me With The Correct Code
17 Dec, 2007 - 07:06 AM
Post #2

Dreaming Coder
Group Icon

Joined: 16 Oct, 2007
Posts: 2,019



Thanked: 105 times
Dream Kudos: 475
Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua

My Contributions
Something like:
CODE

DirectoryEntry oUser = new DirectoryEntry(strUserADsPath,txtUserName.Text,txtPassword.Text);
if(oUser!=null) {
...
}


If you're still crashing horribly, Extra insurance would be:
CODE

DirectoryEntry oUser = null;
try {
   oUser = new DirectoryEntry(strUserADsPath,txtUserName.Text,txtPassword.Text);
} catch {
}
if(oUser!=null) {
...
}


Hope this helps.
User is offlineProfile CardPM
+Quote Post

dping28
RE: Can You Help Me With The Correct Code
17 Dec, 2007 - 10:10 AM
Post #3

New D.I.C Head
*

Joined: 17 Dec, 2007
Posts: 6


My Contributions
Thanks for the reply! I tried both of those and I got the same result as before. basicly its getting to this line:

CODE
listBox1.Items.Add("Groups to which " + oUser.Name + " belongs:");


Even when its enclosed in the if oUser != null, and comes up with DirectoryServicesCOMException was unhandled , There is no such object on the server.
User is offlineProfile CardPM
+Quote Post

dping28
RE: Can You Help Me With The Correct Code
18 Dec, 2007 - 02:10 AM
Post #4

New D.I.C Head
*

Joined: 17 Dec, 2007
Posts: 6


My Contributions
My apologizes, I was doing it wrong. I didnt put all of the code in the try. I got it working after messing with your examples and reading this page.

CODE

private void button1_Click(object sender, EventArgs e)
        {
            string strUserADsPath = "LDAP://" + txtServer.Text + "/cn=" + textBox1.Text + ",ou=Accounts,dc=Gotham,dc=local";
            DirectoryEntry oUser = new DirectoryEntry(strUserADsPath, txtUserName.Text, txtPassword.Text);
            try
            {
                listBox1.Items.Add("Groups to which " + oUser.Name + " belongs:");
                // Invoke IADsUser::Groups method.
                object groups = oUser.Invoke("Groups");
                foreach (object group in (System.Collections.IEnumerable)groups)
                {
                    // Get the Directory Entry.
                    DirectoryEntry groupEntry = new DirectoryEntry(group);
                    listBox1.Items.Add(groupEntry.Name);
                }
            }
            catch
            {
                listBox1.Items.Add("User NOT found!");
            }
        }


Thanks again!!!!

-D
User is offlineProfile CardPM
+Quote Post

baavgai
RE: Can You Help Me With The Correct Code
18 Dec, 2007 - 05:46 AM
Post #5

Dreaming Coder
Group Icon

Joined: 16 Oct, 2007
Posts: 2,019



Thanked: 105 times
Dream Kudos: 475
Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua

My Contributions
For active directory lookups it's unusual to know their adsPath explicitly. User entries are often spread out across organizational units. Thats why most examples use a search mechanism instead.

Here's some code I use for this.

First, a simple class to hold the user info:
CODE

public class UserInfo {
    public string UserName;
    public string DisplayName;
    public List<string> Groups = new List<string>();
    public bool IsValid = false;
    public UserInfo(string userName) { this.UserName = userName; }
}


Now, a factory to get users from Active Directory:
CODE

public class UserInfoFactory {
    protected DirectoryEntry rootEntry;

    public UserInfoFactory(string domain, string rootPath, string username, string password) {
        this.rootEntry = new DirectoryEntry("LDAP://" + domain + "/" + rootPath,
            domain + @"\" + username, password
            );
    }

    protected string GetFirstValue(DirectoryEntry entry, string propertyName) {
        ICollection props = entry.Properties[propertyName];
        if (props == null || props.Count == 0) { return null; }
        IEnumerator e = props.GetEnumerator();
        e.MoveNext();
        return (e.Current == null) ? null : e.Current.ToString();
    }


    protected void AddGroups(UserInfo info, DirectoryEntry entry) {
        // Invoke IADsUser::Groups method.
        foreach (object group in (System.Collections.IEnumerable)entry.Invoke("Groups")) {
            string groupName = new DirectoryEntry(group).Name;
            int equalsIndex = groupName.IndexOf("=", 1);
            if (equalsIndex != -1) {
                groupName = groupName.Substring((equalsIndex + 1));
            }
            info.Groups.Add(groupName);
        }
    }

    public UserInfo GetUser(string sAMAccountName) {
        UserInfo info = new UserInfo(sAMAccountName);
        try {
            DirectorySearcher search = new DirectorySearcher(this.rootEntry);
            search.Filter = "(SAMAccountName=" + sAMAccountName + ")";
            search.PropertiesToLoad.Add("displayName");
            SearchResult result = search.FindOne();
            if (result==null) { return info; }
            DirectoryEntry entry = result.GetDirectoryEntry();
            info.DisplayName = GetFirstValue(entry, "displayName");
            if (info.DisplayName == null) { info.DisplayName = info.UserName; }
            AddGroups(info, entry);
            info.IsValid = true;
        } catch (Exception ex) {
            Debug.WriteLine(ex.Message);
        }
        return info;
    }


This has some additional code you'll find useful if you deal with AD pulls, e.g. displayName.

To use this code in with what you have, you could do something like this:
CODE

private void button1_Click(object sender, EventArgs e) {
    UserInfoFactory factory = new UserInfoFactory(txtServer.Text, "dc=Gotham,dc=local", txtUserName.Text, txtPassword.Text);
    UserInfo oUser = factory.GetUser(textBox1.Text);
    if (!oUser.IsValid) {
        listBox1.Items.Add("User NOT found!");
    } else {
        listBox1.Items.Add("Groups to which " + oUser.DisplayName + " belongs:");
        foreach (string groupName in oUser.Groups) {
            listBox1.Items.Add(groupName);
        }
        // since it's a List, this might also work, didn't try it
        //listBox1.Items.AddRange(oUser.Groups);
    }
}


Hope this helps.

User is offlineProfile CardPM
+Quote Post

dping28
RE: Can You Help Me With The Correct Code
18 Dec, 2007 - 10:29 PM
Post #6

New D.I.C Head
*

Joined: 17 Dec, 2007
Posts: 6


My Contributions
Thank you VERY much baavgai! This gives me alot to mess around with and learn! I especially like how with your ver I dont have to type in the users full name!
User is offlineProfile CardPM
+Quote Post

dping28
RE: Can You Help Me With The Correct Code
19 Dec, 2007 - 04:18 AM
Post #7

New D.I.C Head
*

Joined: 17 Dec, 2007
Posts: 6


My Contributions
Using what you gave me above I managed to create a couple variables and get it to display givenName and sn on thier own lines before the groups. However I cant seem to get it to display parent or dn. Do I need to do something special to get the others?
User is offlineProfile CardPM
+Quote Post

baavgai
RE: Can You Help Me With The Correct Code
19 Dec, 2007 - 05:47 AM
Post #8

Dreaming Coder
Group Icon

Joined: 16 Oct, 2007
Posts: 2,019



Thanked: 105 times
Dream Kudos: 475
Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua

My Contributions
QUOTE(dping28 @ 19 Dec, 2007 - 07:18 AM) *

However I cant seem to get it to display parent or dn.


I don't know about parent, that should be fine. Using the debugger, pause the code after you get the DirectoryEntry and take a look at what's in there. That may give an idea of what's going on. It is concievable you don't have right to the parent, if you're not a domain admin.

Dn is kind of neat. Microsoft, in their wisdom, don't use alias "dn" and prefer the longer version. Look to the property "distinguishedName". Here's some simple code to see what else is hiding in the properties.

CODE

        public void DumpEntryProps(DirectoryEntry entry) {
            foreach (PropertyValueCollection pvc in entry.Properties) {
                Debug.WriteLine(pvc.PropertyName + "(" + pvc.Count + ")");
                for (int i = 0; i < pvc.Count; i++) {
                    object obj = pvc[i];
                    if (obj != null) {
                        Debug.WriteLine("\t" + obj.ToString());
                    }
                }
            }
        }


It should be noted that using the "memberOf" property you can also write a get groups function. I didn't even know DirectoryServices implement a "Groups" method, albeit in a round about way. This is some code I've used for years. You must first find the PropertyValueCollection for "memberOf" and pass that:
CODE

        protected string[] GetGroups(ICollection pvc) {
            List<string> list = new List<string>();
            if ( (pvc!=null) && (pvc.Count>0) ) {
                foreach(string groupName in pvc) {
                    int equalsIndex = groupName.IndexOf("=", 1);
                    int commaIndex = groupName.IndexOf(",", 1);
                    if (equalsIndex!=-1) {
                        string roleName = groupName.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1);
                        list.Add(roleName);
                    }
                }
            }
            return list.ToArray();
        }


Also, for a real user authentication system, I use this as my user object:
CODE

    public interface IUserInfo : IPrincipal, IIdentity {
        string UserName { get; set; }
        string DisplayName { get; set; }
        string RoleAttributeName { get; }
        string[] GetAttributes();
        string[] GetAttributeValues(string attrName);
        void AddAttribute(string attrName, string attrValue);
        void AddAttribute(string attrName, string[] attrValues);
        void DropAttribute(string attrName);
    }


Have fun.

User is offlineProfile CardPM
+Quote Post

dping28
RE: Can You Help Me With The Correct Code
19 Dec, 2007 - 08:15 AM
Post #9

New D.I.C Head
*

Joined: 17 Dec, 2007
Posts: 6


My Contributions
Yeah im using the admin account to read the info and parent doesnt work. odd.. However distinguishedName does. I was really just wanting the OU the account was in. Might have to try some stuff with distinguishedName .. Thanks! smile.gif

I havent had alot of experience in C#, only took an intro class, lol I am probobly jumping in a little deep going straight into AD stuff smile.gif but I have a tool I want to make for AD so figure this should be the best way to learn smile.gif
User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic
Time is now: 12/2/08 12:22AM

Live C# Help!

C# Tutorials

Reference Sheets

C# Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month