讨论枚举当前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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
这个错误通常表示您提供的用户名或密码不正确,或者您没有足够的权限访问共享目录。请确保您提供的用户名和密码是正确的,并且您具有访问该共享目录的权限。 如果您确定您的用户名和密码是正确的,并且您仍然无法访问共享目录,则可能需要检查以下内容: 1. 确认您的用户名和密码是否区分大小写。 2. 确认您的用户名和密码是否包含特殊字符或空格。 3. 确认您与远程计算机连接的网络是否可靠。 4. 如果您在 Windows 计算机上运行 Samba 服务器,请确保您的用户名和密码与您在 Linux 计算机上使用的相同,并且您已经启用了 SMB1 协议。 5. 确认您的用户名和密码是否被锁定或禁用。 如果您仍然无法访问共享目录,请尝试使用以下命令来连接到共享目录: ``` sudo mount -t cifs //servername/sharename /mnt/mountpoint -o user=username,password=password,domain=domainname,sec=ntlm ``` 将 `servername` 替换为远程服务器的名称或 IP 地址,将 `sharename` 替换为您要挂载的远程共享目录的名称,`/mnt/mountpoint` 替换为您要将共享目录挂载到的本地目录,`username` 替换为您在远程服务器上的用户名,`password` 替换为您的密码,`domainname` 替换为您的域名(如果需要)。 `sec=ntlm` 参数可强制使用 NTLMv1 身份验证,这可能会解决某些连接问题。但请注意,NTLMv1 身份验证不是安全的,因为它容易受到中间人攻击。建议您尽快升级到更安全的 SMB 版本,例如 SMB2 或 SMB3。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值