0

I have a very weird problem and a question about a possible solution. I need to get a fully qualified distinguished name on a Windows computer from a program written in C++ (using native WinAPIs.) For that I use the following API:

TCHAR buff[256];
DWORD dwSz = 256;
GetUserNameEx(NameFullyQualifiedDN, buff, &dwSz);

The code above works at no time if I run it from a user-mode process (from a user desktop.) But when I call that API from a system service it does not return for 3-4 seconds! (I should say that the code above may be called on a system that is not a member of an Active Directory domain.)

So my first question is, why would calling it from a service be an issue?

And second question, if I call that API when my service starts and later cache the result in a global variable and later on use it instead, what are the chances that a Distinguished Name changes on that system?

ahmd0
  • 16,633
  • 33
  • 137
  • 233
  • You are asking for information that normally requires a domain controller. You don't have one. So don't be surprised if it takes a while to figure out that you don't have one, network timeouts are always long. Services run in their own session with their own user account so anything cached in the user session won't be useful. – Hans Passant Apr 18 '12 at 15:21

1 Answers1

1

If the system isn't a member of the domain, the API call is going to fail.

Exactly what's happening when you run it as local system versus a user context is hard to say - I'd likely start with a network trace and see what is happening.

I wouldn't make any assumption that the user's DN is static. It's something the administrator could change at any time.

Adding DsCrackNames workflow:

  1. Call DsBind - pass NULL to the first two parameters to get a handle
  2. Call DsCrackNames with the handle from #1, DS_NAME_NO_FLAGS, DS_FQDN_1779_NAME, and the computer's name. You might have to append a $ on the name of the machine.
  3. Call DsFreeNameResult so you don't leak the results
  4. Call DsUnBind so you don't leak the handle from #1
Brian Desmond
  • 4,473
  • 1
  • 13
  • 11
  • Thanks. Is there any other way to obtain the DN with WinAPI? – ahmd0 Apr 18 '12 at 18:11
  • Yes. You want `DsCrackNames`. http://msdn.microsoft.com/en-us/library/windows/desktop/ms675970(v=vs.85).aspx – Brian Desmond Apr 18 '12 at 19:31
  • Well, you see I don't have any DS handles for that API. For my purpose I just need to know the distinguished name of a machine my code is running on. – ahmd0 Apr 18 '12 at 20:36
  • What are you actually trying to do? To get the handle, you need to call `DSBind` or `DSBindWithCred`. – Brian Desmond Apr 18 '12 at 21:56
  • Brian, my knowledge of AD APIs is not that great. Can you post a code sample how I can get a DN on a system that the code runs on? – ahmd0 Apr 18 '12 at 23:43
  • I don't do a whole lot of native code anymore, so, I'll give you the steps above, and I imagine you can piece them together. – Brian Desmond Apr 19 '12 at 15:44
  • Sorry, it didn't work. I called DsCrackNames(hDS, DS_NAME_NO_FLAGS, DS_UNKNOWN_NAME, DS_FQDN_1779_NAME, 1, &pCompName, &pNR) giving the 3rd parameter all possible flags, also preceding comp name with $ and all of that resulted in DS_NAME_ERROR_NOT_FOUND – ahmd0 Apr 20 '12 at 02:08
  • Try replacing `DS_UNKNOWN_NAME` with `DS_NT4_ACCOUNT_NAME` and specifying `pCompName` in domain\name format. – Brian Desmond Apr 20 '12 at 15:56