Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

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

Posted on 2009-03-31
11
Medium Priority
?
1,265 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
11 Comments
 
LVL 71

Accepted Solution

by:
Chris Dent earned 2000 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 71

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
Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

 
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 71

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
 
LVL 11

Author Comment

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

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 71

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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

Auditing domain password hashes is a commonly overlooked but critical requirement to ensuring secure passwords practices are followed. Methods exist to extract hashes directly for a live domain however this article describes a process to extract u…
Group policies can be applied selectively to specific devices with the help of groups. Utilising this, it is possible to phase-in group policies, over a period of time, by randomly adding non-members user or computers at a set interval, to a group f…
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…

636 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