Solved

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

Posted on 2009-03-31
11
1,243 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
Comment Utility

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
Comment Utility
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
Comment Utility

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
Comment Utility
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
Comment Utility

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
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 11

Author Comment

by:Jon Winterburn
Comment Utility
Indeed it does.
0
 
LVL 70

Expert Comment

by:Chris Dent
Comment Utility

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
Comment Utility
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
Comment Utility

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
Comment Utility
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
Comment Utility
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

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

I know all systems administrator at some time or another has had to create a script to copy file from a server share to a desktop. Well now there is an easy way to do this in Group Policy. Using Group policy preferences is not hard. The first thing …
Mapping Drives using Group policy preferences Are you still using old scripts to map your network drives if so this article will show you how to get away for old scripts and move toward Group Policy Preference for mapping them. First things f…
This tutorial will walk an individual through the steps necessary to join and promote the first Windows Server 2012 domain controller into an Active Directory environment running on Windows Server 2008. Determine the location of the FSMO roles by lo…
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…

762 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

8 Experts available now in Live!

Get 1:1 Help Now