[Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

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

Posted on 2009-03-31
11
Medium Priority
?
1,278 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 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
Get your Conversational Ransomware Defense e‑book

This e-book gives you an insight into the ransomware threat and reviews the fundamentals of top-notch ransomware preparedness and recovery. To help you protect yourself and your organization. The initial infection may be inevitable, so the best protection is to be fully prepared.

 
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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

Compliance and data security require steps be taken to prevent unauthorized users from copying data.  Here's one method to prevent data theft via USB drives (and writable optical media).
Transferring FSMO roles is done when an admin wants to split roles between certain Domain Controllers or the Domain Controller holding the Roles has been forcefully demoted using dcpromo / forceremoval
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
Suggested Courses

864 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