讨论枚举当前Logon Session的问题

     Windows提供了API函数LsaEnumerateLogonSessions 去枚举当前的Logon Session, Logon Session在msdn的定义是:

      A logon session begins whenever a user logs on to a computer. All processes in a logon session have the same primary access token. The access token contains information about the security context of the logon session, including the user's SID, thelogon identifier, and the logon SID.(请注意user‘s SID和logon SID是不同概念)。

      根据我的测试,在windows 7上,一个登录用户可以有一个以上的Logon Session,根据LogonSession -p的信息显示,有管理员运行权限的进程在一个Logon Session下,而其它的进程运行在另一个logon Session下,所以我推断一个登录用户可以有多个logon Session,每个logon session的进程有相同的访问权限(All processes in a logon session have the same primary access token)。

     LsaEnumerateLogonSessions不需要管理员权限,但是函数LsaGetLogonSessionData的调用者必须是拥有该session或者是本地的系统管理员,否则window错误码为5。

    以下为msdn的示例代码:

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

#include "stdafx.h"
#include <Windows.h>
#include <NTSecAPI.h>

#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)

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

VOID GetSessionData(PLUID session)
{
	PSECURITY_LOGON_SESSION_DATA sessionData = NULL;
	NTSTATUS retval;
	WCHAR buffer[256];
	WCHAR *usBuffer;
	int usLength;

	// Check for a valid session.
	if (!session ) {
		wprintf(L"Error - Invalid logon session identifier.\n");
		return;
	}
	// Get the session information.
	//调用者必须是拥有该session或者是本地的系统管理员,否则window错误码为5
	retval = LsaGetLogonSessionData (session, &sessionData);
	if (retval != STATUS_SUCCESS) {
		// An error occurred. Tell the world.
		wprintf (L"LsaGetLogonSessionData failed %lu \n",
			LsaNtStatusToWinError(retval));
		// If session information was returned, free it.
		if (sessionData) {
			LsaFreeReturnBuffer(sessionData);
		}
		return;
	} 
	// Determine whether there is session data to parse. 
	if (!sessionData) { // no data for session
		wprintf(L"Invalid logon session data. \n");
		return;
	}
	if (sessionData->UserName.Buffer != NULL) {
		// Get the user name.
		usBuffer = (sessionData->UserName).Buffer;
		usLength = (sessionData->UserName).Length;
		if(usLength < 256)
		{
			wcsncpy_s (buffer, 256, usBuffer, usLength);
			wcscat_s (buffer, 256, L"");
		}
		else
		{
			wprintf(L"\nUser name too long for buffer. Exiting program.");
			return;
		}

		wprintf (L"user %s was authenticated ",buffer);
	} else {
		wprintf (L"\nMissing user name.\n");
		LsaFreeReturnBuffer(sessionData);
		return;
	}
	if ((SECURITY_LOGON_TYPE) sessionData->LogonType == Interactive) {
		wprintf(L"interactively ");
	}
	if (sessionData->AuthenticationPackage.Buffer != NULL) {
		// Get the authentication package name.
		usBuffer = (sessionData->AuthenticationPackage).Buffer;
		usLength = (sessionData->AuthenticationPackage).Length;
		if(usLength < 256)
		{
			wcsncpy_s (buffer, 256, usBuffer, usLength);
			wcscat_s (buffer, 256, L"");
		}
		else
		{
			wprintf(L"\nAuthentication package too long for buffer."
				L" Exiting program.");
			return;
		}
		wprintf(L"using %s ",buffer);
	} else {
		wprintf (L"\nMissing authentication package.");
		LsaFreeReturnBuffer(sessionData);
		return;
	}
	if (sessionData->LogonDomain.Buffer != NULL) {
		// Get the domain name.
		usBuffer = (sessionData->LogonDomain).Buffer;
		usLength = (sessionData->LogonDomain).Length;
		if(usLength < 256)
		{
			wcsncpy_s (buffer, 256, usBuffer, usLength);
			wcscat_s (buffer, 256, L"");
		}
		else
		{
			wprintf(L"\nLogon domain too long for buffer."
				L" Exiting program.");
			return;
		}
		wprintf(L"in the %s domain.\n",buffer);
	} else {
		wprintf (L"\nMissing authenticating domain information. ");
		LsaFreeReturnBuffer(sessionData);
		return;
	}
	// Free the memory returned by the LSA.
	LsaFreeReturnBuffer(sessionData);
	return;
}

int _tmain(int argc, _TCHAR* argv[])
{
	//LARGE_INTEGER示例,参加CPlusplus工程

	//当前用户名称
	DWORD buflen = 256;
	TCHAR buffer[256];
	BOOL bRet = GetUserName(buffer,&buflen);
	if (bRet)
	{
		wprintf(L"Current User : %s\n",buffer);
	}
	else
	{
		wprintf(L"Call GetUserName FALSE.\n");
	}

	PLUID sessions;
	ULONG count;
	NTSTATUS retval;
	int i;

	retval = LsaEnumerateLogonSessions(&count, &sessions);

	if (retval != STATUS_SUCCESS) {
		wprintf (L"LsaEnumerate failed %lu\n",
			LsaNtStatusToWinError(retval));
		return 1;
	} 
	wprintf (L"Enumerate sessions received %lu sessions.\n", count);

	// Process the array of session LUIDs...
	for (i =0;i < (int) count; i++) 
	{
		GetSessionData (&sessions[i]);
	}

	// Free the array of session LUIDs allocated by the LSA.
	LsaFreeReturnBuffer(sessions);

	getchar();

	return 0;
}

 

再编辑编辑,要不这只能算一篇摘抄文章了

 

      我说一下我理解的logon session和terminal service session的区别,logon session是根据登录用户及访问权限分类的,而terminal service session是根据服务和登录用户分类的。
     win 7系统上,服务的会话ID为0,而登录用户的会话ID为1、2...。

     在xp上,服务及第一个登录用户的会话ID位0,以后登录的用户会话ID位1、2....。

     

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值