5

I'm trying to use the GetGroups method of UserPrincipal. If the User account is in an OU that contains a forward slash, the call to GetGroups fails with the COM Unknown Error 0x80005000. The user account is found just find and I can access other properties. If I remove the slash in the OU name then everything works. I found a reference to escaping the slash in the name but that's wrapped under the GetGroups method. I also found making sure to use the PrincipalContext(ContextType, String) constructor which I've done. I've also tried using the FQDN with an escaped slash and get the same results. I have some example code below in C#:

I'm using Visual Studio 2012. The code is running on Windows 10 Enterprise x64. The .net Target version is 4.5

using System;
using System.Linq;
using System.DirectoryServices.AccountManagement;

string SamAccountName = "user1";
//The OUs the user is in:
//Broken OU:  "OU=Test / Test,DC=contoso,DC=com"
//Working OU: "OU=Test & Test,DC=contoso,DC=com"

PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, Environment.UserDomainName);
UserPrincipal user = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, SamAccountName);

//The user was found so this works
Console.WriteLine("User Found: {0}", user.DistinguishedName);

//This causes COM Exception: Unknown Error 0x80005000                
string output = string.Join(Environment.NewLine, user.GetGroups().Select(x => x.Name).ToArray());
Console.WriteLine(output);

Ultimately I just replace any of these types of special characters in the OU name because that's by far the easiest solution. I'm mainly just curious about making sure the code I'm writing doesn't explode down the road.

jalbert
  • 63
  • 4

1 Answers1

4

I believe this is a bug.

The source code of the .NET Core implementation of the AccountManagement namespace is available online now. I would imagine the .NET Framework version is much the same.

I believe the problem is on line 1218 of ADStoreCtx.cs:

roots.Add(new DirectoryEntry("GC://" + gc.Name + "/" + p.DistinguishedName, this.credentials != null ? this.credentials.UserName : null, this.credentials != null ? this.credentials.Password : null, this.AuthTypes));

That is dropping the user's distinguished name into an LDAP path, which uses slashes as separators, without escaping any slashes in the DN.

I know bugs for .NET Core can be reported in GitHub, but I'm not sure where to report a bug with .NET Framework.

Gabriel Luci
  • 38,328
  • 4
  • 55
  • 84
  • 2
    I was able to reproduce this, so I've reported the bug for .NET Core: https://github.com/dotnet/corefx/issues/29090 And I also asked where to report the bug for the full .NET Framework. – Gabriel Luci Apr 13 '18 at 13:07
  • Has this been fixed in the latest .NET Framework? Otherwise, I guess will need to code an alternative way of getting "Memberships" a group is in with LDAP. – C Sharp Conner Jan 17 '19 at 21:33
  • 2
    @CSharpConner Not that I know of. Since this question, I ended up writing an article about the different methods of finding the groups for a user: [Finding all of a user's groups](https://www.gabescode.com/active-directory/2018/06/08/finding-all-of-a-users-groups.html). There are code examples in there. `DirectoryEntry` is [almost always faster](https://www.gabescode.com/active-directory/2018/12/15/better-performance-activedirectory.html) anyway, although it is a little more complicated to use. – Gabriel Luci Jan 17 '19 at 22:19
  • Thanks for the reply. It appears it hasn't been as of .NET 4.8. I ended up using the System.DirectoryServices.Protocol.LdapConnection as it supports paging the way I needed it to and I have already built many things around it. You can even get the SecurityDescriptors of objects by adding a SecurityDescriptorFlagControl to the SearchRequest and for AttributeList string array you include "ntSecurityDescriptor" – C Sharp Conner Jan 22 '19 at 13:39