Solved

System.DirectoryServices - Retrieving Manager's email and stripping path information

Posted on 2009-03-31
11
1,250 Views
Last Modified: 2012-05-06
Hi experts,

I am designing a web-based ASP.NET 2.0 (VB.NET) holiday request form for the office which grabs the current logged on user's username and searches Active Directory for this user, then echoes specific information into text labels where I require them. This almost all works well, but I have hit a snag.

As you can see in the snippet, I call a function called GetUserInfo, and then use the results in text labels (at the bottom).

But the text label "lblManager" displays not just the user's manager's name, but the whole path to it (i.e: CN=John Smith,OU=MYOU,DC=MYDOMAIN,DC=co,DC=uk).

How can I do the following:

1. Remove all the path information so only "John Smith" is displayed.
2. Retrieve said manager's email address.

Thanks

Jon
Public Function GetUserInfo(ByVal inSAM As String, ByVal inType As String) As String

        Try
 

            Dim sPath As String = "LDAP://MYDOMAIN.co.uk/OU=Staff,DC=MYDOMAIN,DC=co,DC=uk"

            Dim SamAccount As String = Right(inSAM, Len(inSAM) - InStr(inSAM, "\"))

            Dim myDirectory As New DirectoryEntry(sPath, "MYACC", "MYPASS")

            Dim mySearcher As New DirectorySearcher(myDirectory)

            Dim mySearchResultColl As SearchResultCollection

            Dim mySearchResult As SearchResult

            Dim myResultPropColl As ResultPropertyCollection

            Dim myResultPropValueColl As ResultPropertyValueCollection
 

            mySearcher.Filter = ("(&(objectClass=user)(samaccountname=" & SamAccount & "))")

            mySearchResultColl = mySearcher.FindAll()
 

            Select Case mySearchResultColl.Count

                Case 0

                    Return "Null"

                    Exit Function

                Case Is > 1

                    Return "Null"

                    Exit Function

            End Select
 

            mySearchResult = mySearchResultColl.Item(0)

            myResultPropColl = mySearchResult.Properties

            myResultPropValueColl = myResultPropColl.Item(inType)

            Return CStr(myResultPropValueColl.Item(0))
 

        Catch ex As System.Exception

            pnlNonUser.Visible = True

            pnldisplay.Visible = False

            pnlsubmitted.Visible = False

        End Try

    End Function
 

Dim sManager As String = GetUserInfo(UserId, "manager")

lblManager.Text = sManager

Open in new window

0
Comment
Question by:Jon Winterburn
  • 6
  • 5
11 Comments
 
LVL 70

Accepted Solution

by:
Chris Dent earned 500 total points
ID: 24030300

Hi Jon,

Because of requirement 2 you probably want to create a DirectoryEntry for the manager to pull the name and mail attributes.

e.g.

Dim sManager As String = GetUserInfo(UserId, "manager")
Dim oManager As New DirectoryEntry("LDAP://" & sManager, "MYACC", "MYPASS")
lblManager.Text = oManager.Properties("name").Value.ToString()
lblManagerMail.Text = oManager.Properties("mail").Value.ToString()

That will be very inefficient if you have to do it for a large number of managers at the same time, but for a one-off it should work well.

Chris
0
 
LVL 11

Author Comment

by:Jon Winterburn
ID: 24030630
Thanks - that makes sense. However, when I add that to my code, although it builds fine, I get an error on the page "Unknown error (0x80005000)", and it refers to the line:

lblManager1.Text = oManager.Properties("name").Value.ToString()
0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 24037311

Hmm Null, didn't expect that for "name" since it's a mandatory field. Can you have it echo out the value for sManager so we can check it's going to be able to connect?

Chris
0
 
LVL 11

Author Comment

by:Jon Winterburn
ID: 24037604
Echoing sManager results in:

CN=John Smith,OU=MYOU,DC=MYDOMAIN,DC=co,DC=uk

...which is the other issue I'm having - how to strip out the unnecessary stuff.
0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 24037636

That's why we were requesting "Name" from the attribute set. It would just be "John Smith". It is, of course, possible to parse the string for that, but since you needed mail as well it was cleaner to retrieve both from the directory.

Ignoring "name" for a moment, does "mail" return the same error message when requested?

Chris
0
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 
LVL 11

Author Comment

by:Jon Winterburn
ID: 24037684
Indeed it does.
0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 24037701

Okay, so our connection isn't working. I think I see why.

It's likely to be because I didn't include the domain name in the string, which suggests it cannot find the servers.

Could you try this version? Just added on the "mydomain.co.uk" so it can hopefully find the LDAP servers. Once it has that successfully it should be able to return the two attributes we're requesting.

Chris
Dim sManager As String = GetUserInfo(UserId, "manager")

Dim oManager As New DirectoryEntry("LDAP://MYDOMAIN.CO.UK/" & sManager, "MYACC", "MYPASS")

lblManager.Text = oManager.Properties("name").Value.ToString()

lblManagerMail.Text = oManager.Properties("mail").Value.ToString()

Open in new window

0
 
LVL 11

Author Comment

by:Jon Winterburn
ID: 24037864
I'm afraid I already thought of that and had amended the ldap string to match that of my domain, but still no joy.
0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 24037931

Well that's annoying, it works fine for me (of course) :)

There are possibilities that we should consider. If the string sManager has any reserved characters in it we can get unexpected behaviour when trying to connect to the account with a Directory Entry.

Here's my sample code, just runs as a console application (just in case).

Chris
Dim oUser As New DirectoryEntry("CN=test,CN=Users,DC=domain,DC=net")

Dim sManager As String = domainUser.Properties("manager").Value.ToString()
 

Dim oManager As New DirectoryEntry("LDAP://" & sManager)

Console.WriteLine(oManager.Properties("name").Value.ToString())

Console.WriteLine(oManager.Properties("mail").Value.ToString())

Open in new window

0
 
LVL 11

Author Comment

by:Jon Winterburn
ID: 24049642
Okay, I gave up on that direction and read a VB.NET forum article and used their example. It works perfectly, and gives me the manager name and email as expected.

But...if I visit the page from another computer in the domain, as any logged on user (admin or not) - none of the fields show up!

So I copied the files to the Intranet server (Windows Server 2003) and accessed it locally, and all fields show up fine - but if I visit it from my workstation, all fields except the manager and manager email fields show up. Why is this??? I have posted the code, if you could take a look please.

(yes, integrated Windows auth is switched on in IIS and web.config)
'first I set the user as logged on user:

Dim User As System.Security.Principal.IPrincipal

User = System.Web.HttpContext.Current.User
 

'this function I use to remove the domain part of the logged on username:

Private Shared Function StripDomain(ByVal username As String) As String

        Return username.Remove(0, username.IndexOf("\") + 1)

    End Function
 

'this function I use to get the user's info from AD:

Private Function GetUserInfo(ByVal Results As System.DirectoryServices.SearchResult, ByVal PropName As String) As String

        Try

            If Results.Properties(PropName).Count > 0 Then

                Return Results.Properties(PropName)(0).ToString.Trim

            End If

        Catch

            Return String.Empty

        End Try

    End Function
 

'and this is the sub that calls the above functions:

   Public Sub getADuser()

        Try

            Dim entry As New DirectoryEntry("LDAP://mydomain.co.uk/DC=mydom,DC=co,DC=uk", "admin", "password")
 

            Dim mySearcher As New System.DirectoryServices.DirectorySearcher(entry)

            mySearcher.SearchScope = SearchScope.Subtree

            Dim results As System.DirectoryServices.SearchResult

            Dim UserId As String = StripDomain(User.Identity.Name)
 

            mySearcher.Filter = ("(&(objectCategory=person)(objectClass=user)(samaccountname=" & UserId & "))")

            mySearcher.PropertiesToLoad.Add("samAccountName")

            mySearcher.PropertiesToLoad.Add("displayName")

            mySearcher.PropertiesToLoad.Add("sn")

            mySearcher.PropertiesToLoad.Add("givenName")

            mySearcher.PropertiesToLoad.Add("mail")

            mySearcher.PropertiesToLoad.Add("department")

            mySearcher.PropertiesToLoad.Add("manager")
 

            For Each results In mySearcher.FindAll()

                If results.GetDirectoryEntry().Path <> "" Then
 

                    lblUser1.Text = GetUserInfo(results, "displayName")

                    lblEmail1.Text = GetUserInfo(results, "mail")

                    lblDept1.Text = GetUserInfo(results, "department")
 

                    If results.Properties("manager").Count > 0 Then

                        Dim managerName As New DirectoryEntry("LDAP://" & results.Properties("manager")(0).ToString.Trim)

                        lblManager1.Text = managerName.Properties("displayName").Value

                        lblManagerEmail1.Text = managerName.Properties("mail").Value

                    End If
 

                End If

            Next

        Catch 

        End Try

    End Sub

Open in new window

0
 
LVL 11

Author Comment

by:Jon Winterburn
ID: 24050280
Aha! It was throwing the error: "The authentication mechanism is unknown" when I removed the try-catch statement. I read up on this and it seems that I have to specify the credentials in web.config for identity impersonation (even though I programatically define the credentials for connection to AD!)

So this is why your suggested code did not work either. So now I know, I award you the points as your code was fine, but the authentication on my server was invalid.

Thanks for your help.
0

Featured Post

Zoho SalesIQ

Hassle-free live chat software re-imagined for business growth. 2 users, always free.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Disabling the Directory Sync Service Account in Office 365 will stop directory synchronization from working.
This tutorial will walk an individual through the process of transferring the five major, necessary Active Directory Roles, commonly referred to as the FSMO roles from a Windows Server 2008 domain controller to a Windows Server 2012 domain controlle…
This tutorial will walk an individual through the process of configuring their Windows Server 2012 domain controller to synchronize its time with a trusted, external resource. Use Google, Bing, or other preferred search engine to locate trusted NTP …

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now