枚举域组用户 [英] enumerage domain group users

查看:110
本文介绍了枚举域组用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用C ++获取本地组的用户列表.到目前为止,一切都很好.但是我可以为域用户组获得相同的结果吗?对于将groupName参数设置为"Administrators",但对于"DOMAIN \\ Domain Admin"而言,以下方法效果很好.

在文档中有一句话:"NetLocalGroupGetMembers函数检索安全数据库中特定本地组成员的列表,该数据库是安全帐户管理器(SAM)数据库,对于域控制器,则是Active Directory本地组成员可以是用户或全局组.",但我承认我还不了解:)

I''m trying to get list of users of local group using C++. So far so good. But can I get the same for domain user groups? The following works well for groupName parameter set to "Administrators" but not for "DOMAIN\\Domain Admin".

There''s a sentence in doc: "The NetLocalGroupGetMembers function retrieves a list of the members of a particular local group in the security database, which is the security accounts manager (SAM) database or, in the case of domain controllers, the Active Directory. Local group members can be users or global groups.", but I admit I do not understand it yet:)

#include <Lm.h>

#pragma comment (lib,"Netapi32.lib")

void WalkGroup(LPCTSTR computerName,LPCTSTR groupName)
{
	NET_API_STATUS stat;
	LOCALGROUP_MEMBERS_INFO_2 *buff;
	DWORD entriesread=0;
	DWORD totalentries=0;
	DWORD resume=0;
	do
	{
		stat= NetLocalGroupGetMembers(computerName,groupName,2,(LPBYTE *)&buff,MAX_PREFERRED_LENGTH,&entriesread,&totalentries,&resume);
		switch(stat)
		{
		case ERROR_MORE_DATA:
		case ERROR_SUCCESS:
			{
				for(int i=0;i<entriesread;i++)
				{
					switch(buff[i].lgrmi2_sidusage)
					{
					case SidTypeUser:
						KINFO(TEXT("User: %s\r\n"),buff[i].lgrmi2_domainandname);
						break;
					case SidTypeGroup:
						KINFO(TEXT("Group: %s\r\n"),buff[i].lgrmi2_domainandname);
						//doesn''t work on domain groups and well known groups, local groups cannot be nested
						//nice try, but not working
						WalkGroup1(computerName,buff[i].lgrmi2_domainandname);
						break;
					case SidTypeWellKnownGroup:
						KINFO(TEXT("WellKnownGroup: %s\r\n"),buff[i].lgrmi2_domainandname);
						break;
					case SidTypeDeletedAccount:
						KINFO(TEXT("Deleted: %s\r\n"),buff[i].lgrmi2_domainandname);
						break;
					case SidTypeUnknown:
						KINFO(TEXT("Unknown: %s\r\n"),buff[i].lgrmi2_domainandname);
						break;
					}
				}
			}
			break;
		}
	}while(stat==ERROR_MORE_DATA);
}

推荐答案

这可能是访问权限问题.
以域管理员身份登录后,请尝试运行该程序.
It is probably a access rights issue.
Try running the program after logging in as a domain administrator.


假设我以域用户身份登录(或者我是一个人),以下操作似乎可以正常进行.我仍然有兴趣使用NetLocalGroupGetMembers或从LM.h获取其他功能.
The following seems to work OK supposing I''m logged on as domain user (or that I inpersonalize one). I''m still interested if it is possible to get the same using NetLocalGroupGetMembers or something else from LM.h

#include <string>
#include <iads.h>
#include <adshlp.h>

#pragma comment (lib,"Activeds.lib")
#pragma comment (lib,"ADSIid.lib")

void WalkGroup(int level,LPCTSTR objectName);

HRESULT EnumMembers(int level,IADsMembers *pMembers)
{
    IUnknown *pUnk;
    HRESULT hr;
    hr = pMembers->get__NewEnum(&pUnk);
    if(FAILED(hr))
	{
		KINFO(TEXT("Cannot get enum object\r\n"));
		goto Cleanup;
	}

    IEnumVARIANT *pEnum;
    hr = pUnk->QueryInterface(IID_IEnumVARIANT,(void**)&pEnum);
    if(FAILED(hr))
	{
		KINFO(TEXT("Cannot get enum variant\r\n"));
		goto Cleanup;
	}
    // Now Enumerate
    VARIANT var;
    IADs *pADs;
    ULONG lFetch;
    IDispatch *pDisp;

    VariantInit(&var);
    hr = pEnum->Next(1, &var, &lFetch);
    if(FAILED(hr))
	{
		KINFO(TEXT("Cannot get next member\r\n"));
		goto Cleanup;
	}
	while(hr == S_OK)
	{
		if (lFetch == 1)
		{
			BSTR bstrName=NULL;
			BSTR bstrClass=NULL;
			BSTR bstrPath=NULL;
			pDisp = V_DISPATCH(&var);
			pDisp->QueryInterface(IID_IADs, (void**)&pADs);
			pADs->get_Name(&bstrName);
			pADs->get_Class(&bstrClass);
			pADs->get_ADsPath(&bstrPath);
			KINFO(TEXT("%d %s %s %s\n"),level,bstrClass, bstrName, bstrPath);
			if(!_tcscmp(bstrClass,TEXT("Group")))
			{
				WalkGroup(level+1,bstrPath);
			}
			SysFreeString(bstrName);
			SysFreeString(bstrClass);
			SysFreeString(bstrPath);
		}
		VariantClear(&var);
		pDisp=NULL;
		hr = pEnum->Next(1, &var, &lFetch);
		if(FAILED(hr))
		{
			KINFO(TEXT("Cannot get next member\r\n"));
			goto Cleanup;
		}
	};

Cleanup:
    if(pADs) pADs->Release();
    if(pDisp) pDisp->Release();
    if(pUnk) pUnk->Release();
    if(pEnum) pEnum->Release();
    VariantClear(&var);
    return hr;
}


void WalkGroup(int level,LPCTSTR objectName)
{
	HRESULT hr;
	IADsGroup *pGroup=NULL;
	IADsMembers *pMembers=NULL;
	hr = ADsGetObject(objectName,IID_IADsGroup,(void**)&pGroup);
	if(FAILED(hr))
	{
		KINFO(TEXT("Cannot get object %s. Priviledges? Domain?\r\n"),objectName);
		goto Cleanup;
	}
	hr = pGroup->Members(&pMembers);
		if(FAILED(hr))
	{
		KINFO(TEXT("Cannot get members\r\n"));
		goto Cleanup;
	}
	EnumMembers(level,pMembers);
Cleanup:
	if(pMembers)
		pMembers->Release();
	if(pGroup)
		pGroup->Release();
}

int wmain(int argc, wchar_t *argv[], wchar_t *envp[])
{
	CoInitialize(NULL);

	TCHAR computerName[MAX_COMPUTERNAME_LENGTH + 1];
	TCHAR objectName[MAX_COMPUTERNAME_LENGTH + 256];
	DWORD computerNameSize=MAX_COMPUTERNAME_LENGTH + 1;
	GetComputerName(computerName,&computerNameSize);

	swprintf_s( objectName,MAX_COMPUTERNAME_LENGTH + 256,_T("WinNT://%s/Administrators"),computerName);
	
	WalkGroup(0,objectName);

	CoUninitialize();
	return (0);
}


</adshlp.h></iads.h></string>


这篇关于枚举域组用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆