让Win服务已当前登录用户的身份来执行函数
2014-12-29 14:54
267 查看
我们新建了一个网络映射,现在需要在我们的服务进程中访问这个远程磁盘,结果发现QueryDosDevice、NetUseEnum、GetLogicalDriveStrings均不可用。怎么办?
因为磁盘映射是和当前账户关联的,当账户登录之后才会存在这个盘符。(可以试试在同一个系统上建立两个账户,它们可以将不同的网络位置映射成同一个盘符。当然盘符只是一个逻辑符号,系统正真的符号是\Device\Mup和\Device\LanmanRedirector
的UNC形式标识,这样系统内部是不会重复的)。
我们的磁盘映射是Administrator账户创建的,而服务进程是SYSTEM账户。试了好多种方法都没有解决如何高效的在SYSTEM账户下的访问远程磁盘。
于是想能不能在SYSTEM账户下模拟Administrator的账户访问呢,问了公司的大神后觉得可行。就上网查找相关的资料。顺便这里记录一下以备以后查看。
方法如下:
1.得到当前登录用户的Token。
WTSGetActiveConsoleSessionId()
WTSQueryUserToken()
2.模拟当前登录用户
ImpersonateLoggedOnUser()
3.接下来可以使用本地磁盘的函数进行操作了
。。。。。。。。。
4.操作完成之后别忘了RevertToSelf。再换回SYSTEM。
程序中的代码:
头文件
1.如果当前账户是SYSTEM,需要切换到当前激活账户的环境来执行
2.用完后
注意事项:
1.该功能可能不支持Win2003以下版本的系统,我还没测试。
2.这里说的当前登录用户指的是哪个用户?看MSDN上的这一段话:
The session identifier of the session that is attached to the physical console. If there is no session attached to the physical console, (for example, if the physical console session is in the process of being
attached or detached), this function returns 0xFFFFFFFF.
参考资料:
http://www.programlife.net/impersonateloggedonuser.html
http://hi.baidu.com/robinwjbgui/blog/item/7ab0a213b2b2bf866438db10.html
http://msdn.microsoft.com/en-us/library/windows/desktop/aa378612(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/aa383835(v=vs.85).aspx
===============================
2014-11-26更新:
接受老大的建议:上述代码中有一处不严谨。判断是否有SYSTEM权限比判用户名更好。
判断代码如下:
参考资料:
http://support.microsoft.com/kb/118626/zh-cn
因为磁盘映射是和当前账户关联的,当账户登录之后才会存在这个盘符。(可以试试在同一个系统上建立两个账户,它们可以将不同的网络位置映射成同一个盘符。当然盘符只是一个逻辑符号,系统正真的符号是\Device\Mup和\Device\LanmanRedirector
的UNC形式标识,这样系统内部是不会重复的)。
我们的磁盘映射是Administrator账户创建的,而服务进程是SYSTEM账户。试了好多种方法都没有解决如何高效的在SYSTEM账户下的访问远程磁盘。
于是想能不能在SYSTEM账户下模拟Administrator的账户访问呢,问了公司的大神后觉得可行。就上网查找相关的资料。顺便这里记录一下以备以后查看。
方法如下:
1.得到当前登录用户的Token。
WTSGetActiveConsoleSessionId()
WTSQueryUserToken()
2.模拟当前登录用户
ImpersonateLoggedOnUser()
3.接下来可以使用本地磁盘的函数进行操作了
。。。。。。。。。
4.操作完成之后别忘了RevertToSelf。再换回SYSTEM。
程序中的代码:
头文件
#include <Wtsapi32.h> #pragma comment(lib, "Wtsapi32.lib")
1.如果当前账户是SYSTEM,需要切换到当前激活账户的环境来执行
HANDLE hTokenUser = NULL; DWORD ConsoleSessionId = 0; BOOL bImpersonateLoggedOnUser = FALSE; char userName[256] = {0}; DWORD userNameLen = sizeof(userName); GetUserName(userName, &userNameLen); if (0 == stricmp("SYSTEM", userName)) { // 得到当前激活用户的会话ID ConsoleSessionId = WTSGetActiveConsoleSessionId(); // 得到当前登录用户的令牌 if (WTSQueryUserToken(ConsoleSessionId, &hTokenUser)) { // 模仿成当前登录用户 bImpersonateLoggedOnUser = ImpersonateLoggedOnUser(hTokenUser); } }
2.用完后
// 终止模拟,返回 if (bImpersonateLoggedOnUser) { RevertToSelf(); }
注意事项:
1.该功能可能不支持Win2003以下版本的系统,我还没测试。
2.这里说的当前登录用户指的是哪个用户?看MSDN上的这一段话:
The session identifier of the session that is attached to the physical console. If there is no session attached to the physical console, (for example, if the physical console session is in the process of being
attached or detached), this function returns 0xFFFFFFFF.
参考资料:
http://www.programlife.net/impersonateloggedonuser.html
http://hi.baidu.com/robinwjbgui/blog/item/7ab0a213b2b2bf866438db10.html
http://msdn.microsoft.com/en-us/library/windows/desktop/aa378612(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/aa383835(v=vs.85).aspx
===============================
2014-11-26更新:
接受老大的建议:上述代码中有一处不严谨。判断是否有SYSTEM权限比判用户名更好。
判断代码如下:
BOOL CurrentUserIsLocalSystem() { BOOL bIsLocalSystem = FALSE; PSID psidLocalSystem; SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY; BOOL fSuccess = ::AllocateAndInitializeSid(&ntAuthority, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &psidLocalSystem); if (fSuccess) { fSuccess = ::CheckTokenMembership(0, psidLocalSystem, &bIsLocalSystem); ::FreeSid(psidLocalSystem); } return bIsLocalSystem; }
参考资料:
http://support.microsoft.com/kb/118626/zh-cn
相关文章推荐
- Windows:服务程序用当前登录用户来执行函数
- 登录服务器windows2008出现:远程桌面服务当前正忙,因此无法完成您尝试执行的任务。请在几分钟后重试。其他用户应该仍然能够登录
- 登录服务器windows2008出现:远程桌面服务当前正忙,因此无法完成您尝试执行的任务。请在几分钟后重试。其他用户应该仍然能够登录
- 登录服务器windows2008出现:远程桌面服务当前正忙,因此无法完成您尝试执行的任务。请在几分钟后重试。其他用户应该仍然能够登录
- 服务应用程序如何访问当前登录用户的信息
- 服务程序中如何以当前登陆用户身份运行程序
- 服务中打开当前登录用户注册表项方法
- Win7中如何在服务中启动一个当前用户的进程——函数CreateProcessAsUser()的一次使用记录
- 【登录】身份认证(用户名密码/accountToken)->用户授权(authToken)->换服务Token(serviceToken)
- Linux 命令 - w: 显示登录的用户及其当前执行的任务
- (转载)服务应用程序如何访问当前登录用户的信息
- 登录服务器windows2008出现:远程桌面服务当前正忙,因此无法完成您尝试执行的任务。(或者出现黑屏界面)
- administrator用户进程模拟当前登录用户进程执行系统API
- 在服务中以当前用户身份启动一个程序
- 在服务中模拟当前登录用户读取HKEY_CURRENT_USER
- 服务程序中如何以当前登陆用户身份运行程序
- 在服务中以当前用户身份启动一个程序
- 服务应用程序如何访问当前登录用户的信息
- 服务应用程序如何访问当前登录用户的信息
- 单一登录:Active Directory 联合身份验证服务开发简介