获取域控制器名称
Get Domain Controller Name
总结: 我只想使用 WinAPI 获取域控制器的名称,计算机不在网络上,这可能会使我的代码失败 "NERR_DCNotFound" ?
我正在尝试获取联网计算机所属的域控制器的名称。
我正在试验的计算机只是一台个人计算机,我从未设置过域控制器或任何可能会使测试变得困难的东西?目前它在 VirtualBox 中,与互联网隔离。
当我从命令行 运行 执行此操作时,我得到以下输出,其中似乎包含一个域名:
C:\Users\lone>gpresult /Z
Microsoft (R) Windows (R) Operating System Group Policy Result tool v2.0
© 2016 Microsoft Corporation. All rights reserved.
Created on 31/01/2018 at 12:24:12
RSOP data for DESKTOP-I53IU6C\lone on DESKTOP-I53IU6C : Logging Mode
---------------------------------------------------------------------
OS Configuration: Standalone Workstation
OS Version: 10.0.10586
Site Name: N/A
Roaming Profile: N/A
Local Profile: C:\Users\lone
Connected over a slow link?: No
USER SETTINGS
--------------
Last time Group Policy was applied: 31/01/2018 at 10:30:38
Group Policy was applied from: N/A
Group Policy slow link threshold: 500 kbps
Domain Name: DESKTOP-I53IU6C
Domain Type: <Local Computer>
Applied Group Policy Objects
-----------------------------
N/A
The following GPOs were not applied because they were filtered out
-------------------------------------------------------------------
Local Group Policy
Filtering: Not Applied (Empty)
The user is a part of the following security groups
---------------------------------------------------
None
Everyone
Local account and member of Administrators group
HelpLibraryUpdaters
BUILTIN\Administrators
BUILTIN\Users
NT AUTHORITY\INTERACTIVE
CONSOLE LOGON
NT AUTHORITY\Authenticated Users
This Organization
Local account
LOCAL
NTLM Authentication
High Mandatory Level
The user has the following security privileges
----------------------------------------------
Resultant Set Of Policies for User
-----------------------------------
Software Installations
----------------------
N/A
Logon Scripts
-------------
N/A
Logoff Scripts
--------------
N/A
Public Key Policies
-------------------
N/A
Administrative Templates
------------------------
N/A
Folder Redirection
------------------
N/A
Internet Explorer Browser User Interface
----------------------------------------
N/A
Internet Explorer Connection
----------------------------
N/A
Internet Explorer URLs
----------------------
N/A
Internet Explorer Security
--------------------------
N/A
Internet Explorer Programs
--------------------------
N/A
我从上面的输出中得到这个:
Domain Name: DESKTOP-I53IU6C
也许我将域名与域控制器名称混淆了?
我从 MSDN 复制并粘贴代码 tutorial:
#ifndef UNICODE
#define UNICODE
#endif
#include <stdio.h>
#include <stdlib.h> // for _wtoi function
#include <assert.h>
#include <windows.h>
#include <lm.h>
// Need to link with netapi32.lib
#pragma comment(lib, "netapi32.lib")
int wmain(int argc, wchar_t * argv[])
{
NET_API_STATUS nStatus;
LPCWSTR lpServer = NULL;
LPCWSTR lpDomain = NULL;
LPCWSTR lpDcName = NULL;
if (argc != 3 ) {
wprintf(L"Usage: %ws <ServerName> <DomainName>\n",
argv[0]);
wprintf(L" %ws Myserver Domain\n", argv[0]);
exit(1);
}
// lpServer = argv[1];
// lpDomain = argv[2];
wprintf(L"Calling NetGetDCName with parameters\n");
wprintf(L" lpServer = %ws\n", lpServer);
wprintf(L" lpDomain = %ws\n", lpDomain);
//
// Call the NetGetDCName function
//
nStatus = NetGetDCName(lpServer, lpDomain, (LPBYTE *) &lpDcName);
//
// If the call succeeds,
//
if (nStatus == NERR_Success) {
wprintf(L"NetGetDCName was successful\n", nStatus);
wprintf(L"DC Name = %ws\n", lpDcName);
// Need to free the returned buffer
nStatus = NetApiBufferFree( (LPVOID) lpDcName);
if (nStatus != NERR_Success)
wprintf(L"NetApiBufferFree failed with error: %lu (0x%lx)\n",
nStatus, nStatus);
} else {
wprintf(L"NetGetDCName failed with error: %lu (0x%lx)\n", nStatus,
nStatus);
wprintf(L" Error = ");
switch (nStatus) {
case ERROR_INVALID_PARAMETER:
wprintf(L"ERROR_INVALID_PARAMETER\n");
break;
case ERROR_NO_SUCH_DOMAIN:
wprintf(L"ERROR_NO_SUCH_DOMAIN\n");
break;
case ERROR_NOT_SUPPORTED:
wprintf(L"ERROR_NOT_SUPPORTED\n");
break;
case ERROR_BAD_NETPATH:
wprintf(L"ERROR_BAD_NETPATH\n");
break;
case ERROR_INVALID_COMPUTERNAME:
wprintf(L"ERROR_INVALID_COMPUTERNAME\n");
break;
case DNS_ERROR_INVALID_NAME_CHAR:
wprintf(L"DNS_ERROR_INVALID_NAME_CHAR\n");
break;
case DNS_ERROR_NON_RFC_NAME:
wprintf(L"DNS_ERROR_NON_RFC_NAME\n");
break;
case ERROR_INVALID_NAME:
wprintf(L"ERROR_INVALID_NAME\n");
break;
case NERR_DCNotFound:
wprintf(L"NERR_DCNotFound\n");
break;
case NERR_WkstaNotStarted:
wprintf(L"NERR_WkstaNotStarted\n");
break;
case RPC_S_SERVER_UNAVAILABLE:
wprintf(L"RPC_S_SERVER_UNAVAILABLE\n");
break;
case RPC_E_REMOTE_DISABLED:
wprintf(L"RPC_E_REMOTE_DISABLED\n");
break;
default:
wprintf(L"Other error, see Winerror.h or lmerr.h)\n");
break;
}
}
return nStatus;
}
我只注释掉命令行参数以将它们保留为 NULL:
// lpServer = argv[1];
// lpDomain = argv[2];
A pointer to a constant string that specifies the DNS or NetBIOS name
of the remote server on which the function is to execute. If this
parameter is NULL, the local computer is used.
A pointer to a constant string that specifies the name of the domain.
The domain name must be a NetBIOS domain name (for example,
microsoft). NetGetDCName does not support DNS-style names (for
example, microsoft.com). If this parameter is NULL, the function
returns the name of the domain controller for the primary domain.
错误我得到:
NERR_DCNotFound
为什么命令行参数给了我一个域名,但 WinAPI 失败了,或者它们是两个具有相似名称的不同事物?
谢谢!
您可以使用电话LsaQueryInformationPolicy
first with PolicyDnsDomainInformation
or PolicyPrimaryDomainInformation
for get the computer primary domain。
如果 POLICY_DNS_DOMAIN_INFO
or POLICY_PRIMARY_DOMAIN_INFO
(the SID of the primary domain) is 0 - this meant that system has no primary domain. in this case we need query account domain 的 Sid 成员:
On a system that is not part of a network and therefore has no primary
domain, the account domain is used to house all accounts that provide
access to the computer.
为此我们需要调用LsaQueryInformationPolicy
with PolicyAccountDomainInformation
and got POLICY_ACCOUNT_DOMAIN_INFO
结构
#include <Ntsecapi.h>
NTSTATUS PrintDomainName()
{
LSA_HANDLE PolicyHandle;
static LSA_OBJECT_ATTRIBUTES oa = { sizeof(oa) };
NTSTATUS status = LsaOpenPolicy(0, &oa, POLICY_VIEW_LOCAL_INFORMATION, &PolicyHandle);
if (LSA_SUCCESS(status))
{
union {
PPOLICY_DNS_DOMAIN_INFO ppddi;
PPOLICY_ACCOUNT_DOMAIN_INFO ppadi;
};
if (LSA_SUCCESS(status = LsaQueryInformationPolicy(PolicyHandle, PolicyDnsDomainInformation, (void**)&ppddi)))
{
if (ppddi->Sid)
{
DbgPrint("DnsDomainName: %wZ\n", &ppddi->DnsDomainName);
}
else
{
DbgPrint("%wZ: not domain controller !!\n", &ppddi->Name);
status = -1;
}
LsaFreeMemory(ppddi);
if (0 > status)
{
if (LSA_SUCCESS(status = LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation, (void**)&ppadi)))
{
DbgPrint("DomainName: %wZ\n", &ppadi->DomainName);
LsaFreeMemory(ppadi);
}
}
}
LsaClose(PolicyHandle);
}
return status;
}
我得到下一个输出:
WORKGROUP: not domain controller !!
DomainName: DESKTOP-2N5ODLB
总结: 我只想使用 WinAPI 获取域控制器的名称,计算机不在网络上,这可能会使我的代码失败 "NERR_DCNotFound" ?
我正在尝试获取联网计算机所属的域控制器的名称。
我正在试验的计算机只是一台个人计算机,我从未设置过域控制器或任何可能会使测试变得困难的东西?目前它在 VirtualBox 中,与互联网隔离。
当我从命令行 运行 执行此操作时,我得到以下输出,其中似乎包含一个域名:
C:\Users\lone>gpresult /Z
Microsoft (R) Windows (R) Operating System Group Policy Result tool v2.0
© 2016 Microsoft Corporation. All rights reserved.
Created on 31/01/2018 at 12:24:12
RSOP data for DESKTOP-I53IU6C\lone on DESKTOP-I53IU6C : Logging Mode
---------------------------------------------------------------------
OS Configuration: Standalone Workstation
OS Version: 10.0.10586
Site Name: N/A
Roaming Profile: N/A
Local Profile: C:\Users\lone
Connected over a slow link?: No
USER SETTINGS
--------------
Last time Group Policy was applied: 31/01/2018 at 10:30:38
Group Policy was applied from: N/A
Group Policy slow link threshold: 500 kbps
Domain Name: DESKTOP-I53IU6C
Domain Type: <Local Computer>
Applied Group Policy Objects
-----------------------------
N/A
The following GPOs were not applied because they were filtered out
-------------------------------------------------------------------
Local Group Policy
Filtering: Not Applied (Empty)
The user is a part of the following security groups
---------------------------------------------------
None
Everyone
Local account and member of Administrators group
HelpLibraryUpdaters
BUILTIN\Administrators
BUILTIN\Users
NT AUTHORITY\INTERACTIVE
CONSOLE LOGON
NT AUTHORITY\Authenticated Users
This Organization
Local account
LOCAL
NTLM Authentication
High Mandatory Level
The user has the following security privileges
----------------------------------------------
Resultant Set Of Policies for User
-----------------------------------
Software Installations
----------------------
N/A
Logon Scripts
-------------
N/A
Logoff Scripts
--------------
N/A
Public Key Policies
-------------------
N/A
Administrative Templates
------------------------
N/A
Folder Redirection
------------------
N/A
Internet Explorer Browser User Interface
----------------------------------------
N/A
Internet Explorer Connection
----------------------------
N/A
Internet Explorer URLs
----------------------
N/A
Internet Explorer Security
--------------------------
N/A
Internet Explorer Programs
--------------------------
N/A
我从上面的输出中得到这个:
Domain Name: DESKTOP-I53IU6C
也许我将域名与域控制器名称混淆了?
我从 MSDN 复制并粘贴代码 tutorial:
#ifndef UNICODE
#define UNICODE
#endif
#include <stdio.h>
#include <stdlib.h> // for _wtoi function
#include <assert.h>
#include <windows.h>
#include <lm.h>
// Need to link with netapi32.lib
#pragma comment(lib, "netapi32.lib")
int wmain(int argc, wchar_t * argv[])
{
NET_API_STATUS nStatus;
LPCWSTR lpServer = NULL;
LPCWSTR lpDomain = NULL;
LPCWSTR lpDcName = NULL;
if (argc != 3 ) {
wprintf(L"Usage: %ws <ServerName> <DomainName>\n",
argv[0]);
wprintf(L" %ws Myserver Domain\n", argv[0]);
exit(1);
}
// lpServer = argv[1];
// lpDomain = argv[2];
wprintf(L"Calling NetGetDCName with parameters\n");
wprintf(L" lpServer = %ws\n", lpServer);
wprintf(L" lpDomain = %ws\n", lpDomain);
//
// Call the NetGetDCName function
//
nStatus = NetGetDCName(lpServer, lpDomain, (LPBYTE *) &lpDcName);
//
// If the call succeeds,
//
if (nStatus == NERR_Success) {
wprintf(L"NetGetDCName was successful\n", nStatus);
wprintf(L"DC Name = %ws\n", lpDcName);
// Need to free the returned buffer
nStatus = NetApiBufferFree( (LPVOID) lpDcName);
if (nStatus != NERR_Success)
wprintf(L"NetApiBufferFree failed with error: %lu (0x%lx)\n",
nStatus, nStatus);
} else {
wprintf(L"NetGetDCName failed with error: %lu (0x%lx)\n", nStatus,
nStatus);
wprintf(L" Error = ");
switch (nStatus) {
case ERROR_INVALID_PARAMETER:
wprintf(L"ERROR_INVALID_PARAMETER\n");
break;
case ERROR_NO_SUCH_DOMAIN:
wprintf(L"ERROR_NO_SUCH_DOMAIN\n");
break;
case ERROR_NOT_SUPPORTED:
wprintf(L"ERROR_NOT_SUPPORTED\n");
break;
case ERROR_BAD_NETPATH:
wprintf(L"ERROR_BAD_NETPATH\n");
break;
case ERROR_INVALID_COMPUTERNAME:
wprintf(L"ERROR_INVALID_COMPUTERNAME\n");
break;
case DNS_ERROR_INVALID_NAME_CHAR:
wprintf(L"DNS_ERROR_INVALID_NAME_CHAR\n");
break;
case DNS_ERROR_NON_RFC_NAME:
wprintf(L"DNS_ERROR_NON_RFC_NAME\n");
break;
case ERROR_INVALID_NAME:
wprintf(L"ERROR_INVALID_NAME\n");
break;
case NERR_DCNotFound:
wprintf(L"NERR_DCNotFound\n");
break;
case NERR_WkstaNotStarted:
wprintf(L"NERR_WkstaNotStarted\n");
break;
case RPC_S_SERVER_UNAVAILABLE:
wprintf(L"RPC_S_SERVER_UNAVAILABLE\n");
break;
case RPC_E_REMOTE_DISABLED:
wprintf(L"RPC_E_REMOTE_DISABLED\n");
break;
default:
wprintf(L"Other error, see Winerror.h or lmerr.h)\n");
break;
}
}
return nStatus;
}
我只注释掉命令行参数以将它们保留为 NULL:
// lpServer = argv[1]; // lpDomain = argv[2];
A pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is NULL, the local computer is used.
A pointer to a constant string that specifies the name of the domain. The domain name must be a NetBIOS domain name (for example, microsoft). NetGetDCName does not support DNS-style names (for example, microsoft.com). If this parameter is NULL, the function returns the name of the domain controller for the primary domain.
错误我得到:
NERR_DCNotFound
为什么命令行参数给了我一个域名,但 WinAPI 失败了,或者它们是两个具有相似名称的不同事物?
谢谢!
您可以使用电话LsaQueryInformationPolicy
first with PolicyDnsDomainInformation
or PolicyPrimaryDomainInformation
for get the computer primary domain。
如果 POLICY_DNS_DOMAIN_INFO
or POLICY_PRIMARY_DOMAIN_INFO
(the SID of the primary domain) is 0 - this meant that system has no primary domain. in this case we need query account domain 的 Sid 成员:
On a system that is not part of a network and therefore has no primary domain, the account domain is used to house all accounts that provide access to the computer.
为此我们需要调用LsaQueryInformationPolicy
with PolicyAccountDomainInformation
and got POLICY_ACCOUNT_DOMAIN_INFO
结构
#include <Ntsecapi.h>
NTSTATUS PrintDomainName()
{
LSA_HANDLE PolicyHandle;
static LSA_OBJECT_ATTRIBUTES oa = { sizeof(oa) };
NTSTATUS status = LsaOpenPolicy(0, &oa, POLICY_VIEW_LOCAL_INFORMATION, &PolicyHandle);
if (LSA_SUCCESS(status))
{
union {
PPOLICY_DNS_DOMAIN_INFO ppddi;
PPOLICY_ACCOUNT_DOMAIN_INFO ppadi;
};
if (LSA_SUCCESS(status = LsaQueryInformationPolicy(PolicyHandle, PolicyDnsDomainInformation, (void**)&ppddi)))
{
if (ppddi->Sid)
{
DbgPrint("DnsDomainName: %wZ\n", &ppddi->DnsDomainName);
}
else
{
DbgPrint("%wZ: not domain controller !!\n", &ppddi->Name);
status = -1;
}
LsaFreeMemory(ppddi);
if (0 > status)
{
if (LSA_SUCCESS(status = LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation, (void**)&ppadi)))
{
DbgPrint("DomainName: %wZ\n", &ppadi->DomainName);
LsaFreeMemory(ppadi);
}
}
}
LsaClose(PolicyHandle);
}
return status;
}
我得到下一个输出:
WORKGROUP: not domain controller !!
DomainName: DESKTOP-2N5ODLB