Why did the friendly name for the Network Service account change?

A customer had a service that runs under the Network Service account.
They found that starting in Windows Vista, if the service calls
Get­User­Name,
it no longer gets "NETWORK SERVICE" back;
instead, it gets the computer name followed by a dollar sign.
Why did this change?

Well, nobody promised that it wouldn't change.

Whether the name for the Network Service account is
"NETWORK SERVICE" or "HOSTNAME$" depends on a variety of things,
including whether the service is authenticated with Active Directory
(in which case it presents itself to the Active Directory server
as the machine name).

The customer requires official documentation for the change.
Is there a document available that explains the change and why
it occurred?

The customer should not be relying on account display names
in the first place.
If you want to identify an account, use the SID.
The SID is fixed and
documented as S-1-5-20.
The display name is neither fixed nor documented.

The fact that their service is sensitive to the display name
for the Network Service kind of scares me,
because it suggests that
if I change my display name
to "NETWORK SERVICE" (my friends call me Netty for short),
their service might treat me as if I'm the Network Service
account,
and now I've gained service privileges.
Little Bobby Tables, eat your heart out!

The customer liaison explained,

The customer's application was designed to use both
user names and SIDs, and they found that their design
stopped working.
Now they need to redesign their application,
but they need to justify the work on their side,
hence their request for formal documentation confirming
the change.

Okay, so they want the document in order to make
themselves look good.
"See, Microsoft made a change and screwed us.
That's why we have this unexpected work."

Their design relied on undocumented behavior.
Undocumented behavior can change at any time.
This is one example of undocumented behavior changing.
If we had to document every undocumented behavior,
then it wouldn't be undocumented any more.

This specific change was an internal change that
does not need to be documented externally
because properly-written code should not have been
relying on it.
Any documentation that could be written on the subject
would continue to be non-contractual because
Windows is within its rights to change the behavior
at any time without warning.

I suspect the need for that sentence is now gone,
so
I need to file a documentation change request to replace
that sentence with
"Applications should use SIDs to identify well-known accounts
rather than display names."

This post should bring out the nostalgia in the fans; it has been long time since this blog tried to make a customer look like an idiot.

GetUserName function documentation page reads: “Retrieves the name of the user associated with the current thread.” This is documented behavior. “$” is not the name of the user associated with the current thread. So, this is a violation of the documented behavior.

It is a documented fact that “HOSTNAME$” is not the display name of Network Service account. The customer has observed a discrepancy between the documentation and the actual result. I don’t see why you seek to contradict and stonewall the customer instead of just solving his problem.

I honestly wouldn’t use GetUserName() at all and would instead use GetUserNameEx() so that I would have more control over what I get back (probably the SID so I can store it for future use.) Taking a look at https://msdn.microsoft.com/ja-jp/library/cc429924.aspx (which I had my browser translate), it appears that earlier versions of the documentation didn’t specify what the output format for GetUserName() would be at all!

He’s got a point, though. KB243330 (linked in Raymond’s article) documents the “names” corresponding to various SIDs, and GetUserName says it retrieves the “name”. You’d expect GetUserName to return the names listed in KB243330, and I’m pretty sure that it usually does. If one really is the “account name” and the other is the “friendly name” and these are two different concepts, the distinction should be documented.

Just so long as the documented names of NULL, “NT AUTHORITY\LOCALSERVICE”, and “NE AUTHORITY\NETWORK SERVICE” continue to work in CreateService; else you will have a rotten day for backwards compatibility. AFAIK you can’t pass SIDs there. I’m pretty sure “” works for local system too, but it’s not documented.

It’s a pity that the API that converts “NT AUTHORITY\NETWORK SERVICE” into a SID does not also accept strings of the form “S-1-a-b-c…”. Presumably Mrs Tables had a daughter called “S-1-1-0” and so there’s a compatibilty issue, but I’m sure I’m not alone in wishing that a string SID could be used in all the command line utilities that currently demand a (localisation-sensitive) name.

Whatoccurs to me is that if the display name is not important and must not be relied on, why did/does it need to change under certain circumstances ?

It’s almost as if there are some internal dependencies within Windows itself that are relying on artefacts divined from the particular name encountered to infer things or make discriminatory choices. Things which presumably are documented somewhere ?

It’s perhaps fair enough that the OS may have internal mechanisms which rely on artefacts that you do not wish application code to rely on, so you choose not to publish the documentation. So in this case I think “undocumented” likely really means “unpublished”.

More likely the visible change was a consequence of some other architectural change. Or perhaps someone just thought it made more sense, so that if you’ve got a named pipe the username you see for yourself is the same as the username the other end of the pipe sees for you.

Identifying by the SID doesn’t work, because the SID for “NETWORK SERVICE” is always the same; there’s no way to separate which service on which computer is making the request.

Same goes for using the old display name. “NETWORK SERVICE” doesn’t tell you anything about which computer is making the request.

“HOSTNAME$” is how a computer is identified in Active Directory. That name is given to the network service account when the service needs to access something in AD. The computer authenticates using “HOSTNAME$” as the username and the computer’s internal password.

account name is the shortname in UNIX speak, or the original name. It’s the name you would find on the folder in C:\Users and can’t be changed.
Friendly name is the name you can see as the display name, it can be changed at any time, but it wouldn’t affect the account’s shortname.

The customer is probably asking for documentation as form of proof in incident report.

I did that a lot while working in an “equity trading software” vendor. Each time just explaining the problem is not enough, they need downloadable documentation as proof from that offical site as reference. Lots of my time has been spent on finding documentations that seemingly related to the incident I’m creating report for. _-_

We were bitten by this because our Windows services uses e-cert stored in “Person” store of the service’s current user to encrypt data. And they use remote management software that does not support sending Ctrl-Alt-Del to remote side. This plus the fact that their audit practice require them to change all server account password every 3 months makes the server operators change the service account password with User Managment MMC instead of “Change password” in secure desktop.

This, complicated by the fact that they move the server data to another hardware via backup and restore makes the customer believe our software will not survive a “backup and restore” and think this is totally not acceptable. I quoted the link to the KB article but they rejected that because it say that this just affects WinXP.

I had spent lots of time arguing with them since WinXP and Win2003 based on same kernel, just in different SKU, this will and should affect other Windows server products. I actually spent time demonestrating this behaviour is reproducable to their technical staffs. Sadly because of this incident, this customer never grant pass the UAT.

I’m guessing this developer also didn’t do any testing with localised language editions of Windows? For example on a system installed from a German ISO file they’d have found the display name of the service to be “netzwerkdiesnte” for example.

> The customer should not be relying on account display names in the first place. If you want to identify an account, use the SID.

> The customer’s application was designed to use both user names and SIDs

Perhaps this is yet another instance of “Unix thinking”? On Unix, it’s not a good idea to rely in the UID, since it can be different; for instance, the “contoso” account might be uid 123 on one machine, but uid 456 on another (the only reliable UID is for the “root” account, which is always UID 0). Therefore, programmers raised on Unix might expect to use the account name to identify an account.

“Perhaps this is yet another instance of “Unix thinking”? […] (the only reliable UID is for the “root” account, which is always UID 0)”
I hope that’s not what Unix thinking is. While administrative accounts will be named root and have UID 0 on most Unix implementations, in general, there is nothing in the Unix specifications that requires any name or UID for an administrative account. Unix systems do exist that have neither a user named root nor a user with a UID of 0, and most software — or at least most software that’s meant to be portable across Unix systems — will run just fine on them.