【问题标题】:How to check if user is a Domain User or Local User?如何检查用户是域用户还是本地用户?
【发布时间】:2015-06-16 17:43:35
【问题描述】:

我希望能够检查运行当前线程的用户是否是:

  • 域用户
  • 机器的本地用户

有一些注意事项:

  • 我不知道(或关心)这台机器是否已加入域
  • 因为登录用户的域可能与机器域不同
  • 并且因为进程正在运行的用户域可能来自登录的用户或计算机域
  • 并且因为线程正在运行的用户域可能来自进程、登录或机器域

换句话说,我想要:

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

研究工作

接下来是无关的奖金信息。它没有给问题增加任何内容,只是为了使问题更长。

使用NetGetJoinInformation检查机器是否加入域

我可以使用NetGetJoinInformation 来检查本地机器是否加入了域:

NetGetJoinInformation(null, ref domain, ref joinStatus);

返回:

  • NetSetupUnknownStatus:状态未知。
  • NetSetupUnjoined:计算机未加入。
  • NetSetupWorkgroupName:计算机已加入工作组。
    • domain 包含工作组的名称(例如 WORKGROUP
  • NetSetupDomainName:计算机已加入域。
    • domain 包含域的旧 NetBIOS 名称(例如 STACKOVERFLOW

使用DsRoleGetPrimaryDomainInformation检查机器是否加入域

我可以使用DsRoleGetPrimaryDomainInformation 来检查本地机器是否加入了域:

DsRoleGetPrimaryDomainInformation(null, 
      DsRolePrimaryDomainInfoBasic, 
      DSROLE_PRIMARY_DOMAIN_INFO_BASIC);

返回一个DSROLE_PRIMARY_DOMAIN_INFO_BASIC 结构:

  • MachineRole
    • DsRole_RoleStandaloneWorkstation: 机器未加入域
    • DsRole_RoleStandaloneServer: 机器未加入域
    • DsRole_RoleMemberWorkstation:机器加入域
    • DsRole_RoleMemberServer:机器加入域
    • DsRole_RoleBackupDomainController:机器加入域
    • DsRole_RolePrimaryDomainController: 机器加入域
  • DomainNameDns:返回 DNS 域名(例如 stackoverflow.com(可选)
  • DomainNameFlat:返回旧的 NetBIOS 域名(例如 STACKOVERFLOW

但是,同样,当用户不是域用户或用户来自不同域时,告诉我机器加入的域的名称也无济于事

使用GetUserName获取当前用户的名字

Windows 确实提供了GetUserName 函数:

GetUserName(buffer, Length(buffer));

返回用户名,例如lsimpson

使用GetUserNameEx获取当前用户的名字

Windows 确实提供了一个GetUserNameEx 函数,它允许您以不同的格式返回用户名:

  • NameUnknown(无)
  • NameFullyQualifiedDNCN=John Smith,OU=Stackoverflow Users,DC=stackoverflow,DC=com
  • NameSamCompatibleSTACKOVERFLOW\jsmith
  • 姓名显示John
  • NameUniqueId{C1AF1DE6-363D-42A7-BB0D-9D1EDDC44B81}
  • NameCanonicalstackoverflow.com/Stackoverfow Users/John Smith
  • NameUserPrincipaljsmith@stackoverflow.com
  • NameCanonicalExstackoverflow.com/Stackoverflow Users/John Smith
  • NameServicePrincipal(无)
  • NameDnsDomainSTACKOVERFLOW.COM\jsmith

还有

  • NameUnknown
  • NameFullyQualifiedDN
  • NameSamCompatibleHYDROGEN\john
  • 名称显示
  • NameUniqueId
  • NameCanonical
  • NameUserPrincipal
  • NameCanonicalEx
  • NameServicePrincipal
  • NameDnsDomain

KB11154:如何检索当前用户和域名

微软有一篇知识库文章:

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

涉及:

  • OpenThreadToken
  • OpenProcessToken(如果没有线程令牌)
  • GetTokenInformation - 得到TOKEN_USER
  • LookupAccountSid - 从TOKEN_USER 获取用户名和域名

最后它返回:

  • 用户名:例如jsmith
  • :例如HYDROGEN, STACKOVERFLOW

【问题讨论】:

  • 无缘无故投反对票?不错的 Stackoverflow!
  • 你好,我也需要实现这样的功能。你找到解决办法了吗?谢谢!

标签: windows security winapi


【解决方案1】:

下午好!

我查看了针对此问题发布的其他一些解决方案,但其中大多数没有考虑到您列出的注意事项。大部分相关解决方案来自以下帖子:

Check if user is a Domain User or Local User

在这些解决方案中,以下似乎最符合您的建议:

bool IsLocalUser(string accountName)
{
  var domainContext = new PrincipalContext(ContextType.Machine);
  return Principal.FindByIdentity(domainContext, accountName) != null;
}

【讨论】:

  • 我没有明确说出来,但我需要 "native" 解决方案 - 我不在 .NET 或 CLR 中。此外,如果您按照该问题回答三个链接,则基本上是关于检查用户是否存在于 Active Directory 中。出于我们的目的,我们假设用户没有查询活动目录的权限。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-20
  • 2019-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多