判断当前进程Token对应的用户是否在某一组之中

这也是我从msdn上得到的信息,当然了,得到的信息也更新了我对SID的认识,之前说,SID代表着一个用户帐号或者一个组,现在发现不然,它居然还可以代表一个Logon Session,

若又论Logon Session和Session我就整晕了,网页也没见着好的解释~,只能慢慢找了...暂时不答,贴图一张 ,右键管理员打开Process Explorer.exe程序,随便挑一个进程双击,我这儿打开了Chrome浏览器

判断当前进程Token对应的用户是否在某一组之中_第1张图片


另外更新我认知的呢~  微软在SID上还给他包装了下,如此新出现2种结构体,

Token_Groups

typedef struct _TOKEN_GROUPS {
  DWORD              GroupCount;
  SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
} TOKEN_GROUPS, *PTOKEN_GROUPS;


Token_User

typedef struct _TOKEN_USER {
  SID_AND_ATTRIBUTES User;
} TOKEN_USER, *PTOKEN_USER;

看看这命名多人性化~,比这个SID这生硬的来得易读得多吧?


typedef struct _SID_AND_ATTRIBUTES {
  PSID  Sid;
  DWORD Attributes;
} SID_AND_ATTRIBUTES, *PSID_AND_ATTRIBUTES;

看看,还给每一个SID相关了一个 属性标记组合


The Attributes members of the SID_AND_ATTRIBUTES structures can have the following values.

Attributes 成员可以有一下值的组合

Value Meaning
SE_GROUP_ENABLED
0x00000004L

The SID is enabled for access checks. When the system performs an access check, it checks for access-allowed and access-denied access control entries (ACEs) that apply to the SID.

A SID without this attribute is ignored during an access check unless the SE_GROUP_USE_FOR_DENY_ONLY attribute is set.

SE_GROUP_ENABLED_BY_DEFAULT
0x00000002L

The SID is enabled by default.

SE_GROUP_INTEGRITY
0x00000020L

The SID is a mandatory integrity SID.

Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP:  This value is not supported.

SE_GROUP_INTEGRITY_ENABLED
0x00000040L

The mandatory integrity SID is evaluated during access check.

Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP:  This value is not supported.

SE_GROUP_LOGON_ID
0xC0000000L

The SID is a logon SID that identifies the logon session associated with an access token.

SE_GROUP_MANDATORY
0x00000001L

The SID cannot have the SE_GROUP_ENABLED attribute cleared by a call to the AdjustTokenGroups function. However, you can use the CreateRestrictedToken function to convert a mandatory SID to a deny-only SID.

SE_GROUP_OWNER
0x00000008L

The SID identifies a group account for which the user of the token is the owner of the group, or the SID can be assigned as the owner of the token or objects.

SE_GROUP_RESOURCE
0x20000000L

The SID identifies a domain-local group.

SE_GROUP_USE_FOR_DENY_ONLY
0x00000010L

The SID is a deny-only SID in a restricted token. When the system performs an access check, it checks for access-denied ACEs that apply to the SID; it ignores access-allowed ACEs for the SID.

If this attribute is set, SE_GROUP_ENABLED is not set, and the SID cannot be reenabled.

你看看,这条说明,这个SID 是一个Logon SID,标识了与一个TOKEN 相关联的logon session
SE_GROUP_LOGON_ID
0xC0000000L

The SID is a logon SID that identifies the logon session associated with an access token.

以上种种标志要是测试的话,我目前还没有做过,今天只是关注如标题所示,判断一个进程的Token相关联的User是否在某一个用户组之中,这片文章可以从msdn上得到,我只不过,稍加修饰一下,组合一下,原网址 https://msdn.microsoft.com/en-us/library/windows/desktop/aa379554(v=vs.85).aspx


// TestASID_In_A_Token.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include 
#include 
#pragma comment(lib,"advapi32.lib")
#define  MAX_NAME 256

BOOL SearchTokenGroupForSID( )
{
	DWORD i,dwSize = 0,dwResult = 0;
	HANDLE hToken;
	/*
		typedef struct _TOKEN_GROUPS {
		DWORD GroupCount;
		SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
		} TOKEN_GROUPS, *PTOKEN_GROUPS;

		typedef struct _SID_AND_ATTRIBUTES {
		PSID Sid;
		DWORD Attributes;
		} SID_AND_ATTRIBUTES, * PSID_AND_ATTRIBUTES;
	*/
	PTOKEN_GROUPS pGroupInfo;


	/*
		typedef enum _SID_NAME_USE {
		SidTypeUser = 1,
		SidTypeGroup,
		SidTypeDomain,
		SidTypeAlias,
		SidTypeWellKnownGroup,
		SidTypeDeletedAccount,
		SidTypeInvalid,
		SidTypeUnknown,
		SidTypeComputer,
		SidTypeLabel
		} SID_NAME_USE, *PSID_NAME_USE;
	*/
	SID_NAME_USE SidType;
	TCHAR lpName[MAX_NAME] = {0};
	TCHAR lpDomain[MAX_NAME] = {0};
	PSID pSID = NULL;

	/*
		typedef struct _SID_IDENTIFIER_AUTHORITY {
		BYTE  Value[6];
		} SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY;
	*/
	SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;

	//Open a handle to the access token for the calling process
	//以查询方式打开	当前进程的Token,即是当前登录用户的Token
	if(!OpenProcessToken(GetCurrentProcess( ),TOKEN_QUERY,&hToken))
	{
		_tprintf(TEXT("OpenProcessToken failed with error %d\n"),GetLastError( ));
		return FALSE;
	}

	//Call GetTokenInformation to get the buffer size
	//查询Token的TokenGroups类信息
	if(!GetTokenInformation(hToken,TokenGroups,NULL,dwSize,&dwSize))
	{
		dwResult = GetLastError( );
		if(dwResult != ERROR_INSUFFICIENT_BUFFER)
		{
			_tprintf(TEXT("GetTokenInformation failed with error %d\n"),dwResult);
			return FALSE;
		}
	}

	//Allocate the buffer.
	//刚才的查询是失败的,但是我们得到了所需要的内存大小了,接下来在默认堆中分配
	pGroupInfo = (PTOKEN_GROUPS)calloc(dwSize,sizeof(1));

	//call GetTokenInformation again to get the group information
	//重新查询,这次应该成功了吧~
	if(!GetTokenInformation(hToken,TokenGroups,pGroupInfo,dwSize,&dwSize))
	{
		_tprintf(TEXT("GetTokenInformation failed with error %d\n"),GetLastError());
		return FALSE;
	}

	//Create a SID for the BUILTIN\Administrators group
	//构造一个BUILTIN\Administrators 组的SID,如果你还想构造别的组的SID,就需要去查资料了,我也不是很明白,明白了的话请告知在下一下,~_~
	//之前的文章有说明,不直接操作SID,用相关函数去操作
	//比如构造一个SID ,在如下函数,你需要给出一个 AUTHORITY 和至多8个SubAuthority
	if(!AllocateAndInitializeSid(
		&SIDAuth,2,
		SECURITY_BUILTIN_DOMAIN_RID,
		DOMAIN_ALIAS_RID_ADMINS,
		0,0,0,0,0,0,
		&pSID
		))
	{
		_tprintf(TEXT("AllocateAndInitializeSid Error %d\n"),GetLastError( ));
		return FALSE;
	}

	//Loop through the group SIDs looking for the administrator SID
	//循环遍历Token 中的TokenGroup类信息
	for(i = 0; i < pGroupInfo->GroupCount; i++)
	{
		//两SID一样的话
		if(EqualSid(pSID,pGroupInfo->Groups[i].Sid))
		{
			//Lookup the account name and printf it.
			dwSize = MAX_NAME;
			//查询SID对应的账户名或者组名,以及域名
			if(!LookupAccountSid(
				NULL,pGroupInfo->Groups[i].Sid,
				lpName,
				&dwSize,lpDomain,&dwSize,&SidType
				))
			{
				dwResult = GetLastError( );
				if(dwResult == ERROR_NONE_MAPPED)
				{
					_tprintf(TEXT("NONE_MAPPED!There isn't an account for SID specified"));
					return FALSE;
				}
				else
				{
					_tprintf(TEXT("LookupAccountSid Error %u\n"),GetLastError( ));
					return FALSE;
				}
			}
			_tprintf(TEXT("Current user is a member of the %s\\%s group\n"),lpDomain,lpName);

			//Find out whether the SID is enabled in the token

			if(pGroupInfo->Groups[i].Attributes & SE_GROUP_ENABLED)
				_tprintf(TEXT("The group SID is	enabled.\n"));
			else if(pGroupInfo->Groups[i].Attributes & SE_GROUP_USE_FOR_DENY_ONLY)
				_tprintf(TEXT("The group SID is a deny-only SID.\n"));
			else
				_tprintf(TEXT("The group SID is not enabled.\n"));
		}
	}
	if(pSID)
		FreeSid(pSID);
	if(pGroupInfo)
		free(pGroupInfo);
	return TRUE;
}


int _tmain(int argc, _TCHAR* argv[])
{
	SearchTokenGroupForSID( );
	return 0;
}

如果你管理员运行这个程序,将会得到一下图例

判断当前进程Token对应的用户是否在某一组之中_第2张图片


非管理员呢 

判断当前进程Token对应的用户是否在某一组之中_第3张图片

是不是想到了这条? 然后想想,管理员执行程序,是不是有两种Token,受限和不受限的?分别对应这是否右键管理员运行?至于其他文字暂时忽略~

SE_GROUP_USE_FOR_DENY_ONLY
0x00000010L

The SID is a deny-only SID in a restricted token. When the system performs an access check, it checks for access-denied ACEs that apply to the SID; it ignores access-allowed ACEs for the SID.

If this attribute is set, SE_GROUP_ENABLED is not set, and the SID cannot be reenabled.



你可能感兴趣的:(SID...,Token,ACCOUNT)