Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if user is a Domain User or Local User?

I want to be able to check if the user running the current thread is:

  • a Domain User
  • a Local User of the machine

There are some cavaets:

  • i do not know (or care) if the machine is domain joined
  • because the domain of the logged in user could be from a different from the machine domain
  • and because the domain of the user that the process is running as could from the logged in user or machine domains
  • and because the domain of the user that the thread is running as could be from the process, logged in or machine domains

In other words, i want:

public static Boolean IsLocalUser()
{
   //code here
}

Research Effort

What follows is extraneous bonus information. It adds nothing to the question, but is here solely to make the question longer.

Check if machine is domain joined using NetGetJoinInformation

I can use NetGetJoinInformation to check if the local machine is joined to a domain:

NetGetJoinInformation(null, ref domain, ref joinStatus);

Returns:

  • NetSetupUnknownStatus: The status is unknown.
  • NetSetupUnjoined: The computer is not joined.
  • NetSetupWorkgroupName: The computer is joined to a workgroup.
    • domain contains name of workgroup (e.g. WORKGROUP)
  • NetSetupDomainName: The computer is joined to a domain.
    • domain contains the legacy NetBIOS name of the domain (e.g. STACKOVERFLOW)

Check if machine is domain joined using DsRoleGetPrimaryDomainInformation

I can use DsRoleGetPrimaryDomainInformation to check if the local machine is joined to a domain:

DsRoleGetPrimaryDomainInformation(null, 
      DsRolePrimaryDomainInfoBasic, 
      DSROLE_PRIMARY_DOMAIN_INFO_BASIC);

Returns a DSROLE_PRIMARY_DOMAIN_INFO_BASIC structure:

  • MachineRole
    • DsRole_RoleStandaloneWorkstation: the machine is not domain joined
    • DsRole_RoleStandaloneServer: the machine is not domain joined
    • DsRole_RoleMemberWorkstation: the machine is domain joined
    • DsRole_RoleMemberServer: the machine is domain joined
    • DsRole_RoleBackupDomainController: the machine is domain joined
    • DsRole_RolePrimaryDomainController: the machine is domain joined
  • DomainNameDns: returns the DNS Domain name (e.g. stackoverflow.com) (optional)
  • DomainNameFlat: returns the legacy NetBIOS domain name (e.g. STACKOVERFLOW)

But, again, telling me name name of the domain that the machine is joined to doesn't help when the user is not a domain user, or the user is from a different domain

Getting the name of the current user using GetUserName

Windows does provide a GetUserName function:

GetUserName(buffer, Length(buffer));

returns the name of the user, e.g. lsimpson

Getting the name of the current user using GetUserNameEx

Windows does provide a GetUserNameEx function, that allows you to return the username in different formats:

  • NameUnknown: (nothing)
  • NameFullyQualifiedDN: CN=John Smith,OU=Stackoverflow Users,DC=stackoverflow,DC=com
  • NameSamCompatible: STACKOVERFLOW\jsmith
  • NameDisplay: John
  • NameUniqueId: {C1AF1DE6-363D-42A7-BB0D-9D1EDDC44B81}
  • NameCanonical: stackoverflow.com/Stackoverfow Users/John Smith
  • NameUserPrincipal: [email protected]
  • NameCanonicalEx: stackoverflow.com/Stackoverflow Users/John Smith
  • NameServicePrincipal: (nothing)
  • NameDnsDomain: STACKOVERFLOW.COM\jsmith

also

  • NameUnknown:
  • NameFullyQualifiedDN:
  • NameSamCompatible: HYDROGEN\john
  • NameDisplay:
  • NameUniqueId:
  • NameCanonical:
  • NameUserPrincipal:
  • NameCanonicalEx:
  • NameServicePrincipal:
  • NameDnsDomain:

KB11154: How to retrieve current user and domain name

Microsoft has a knowledge base article:

How to retrieve current user and domain names on Windows NT, Windows 2000, or Windows XP

it involves:

  • OpenThreadToken
  • OpenProcessToken (if there is no thread token)
  • GetTokenInformation - to get a TOKEN_USER
  • LookupAccountSid - to get a username and domain name from a TOKEN_USER

In the end it returns:

  • username: e.g. jsmith
  • domain: e.g. HYDROGEN, STACKOVERFLOW
like image 972
Ian Boyd Avatar asked Jun 16 '15 17:06

Ian Boyd


1 Answers

Good afternoon!

I looked into some of the other solutions posted for this problem, but most of them do not take into account the caveats that you listed. Most of the relevant solutions are from the following post:

Check if user is a Domain User or Local User

Of these solutions, the following seems to be the most in line with what you proposed:

bool IsLocalUser(string accountName)
{
  var domainContext = new PrincipalContext(ContextType.Machine);
  return Principal.FindByIdentity(domainContext, accountName) != null;
}
like image 183
Brian Gilreath Avatar answered Oct 16 '22 08:10

Brian Gilreath