来自 Windows 服务的 WNetAddConnection2
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2968426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WNetAddConnection2 from a Windows Service
提问by Flavio
I'm trying to connect to a remote password protected shared folder from a Windows service, which runs as LocalSystem account. It seems that the LocalSystem account is unable to directly access password-protected network shares using WNetAddConnection2() or similar calls. Can anyone confirm this? I've read that impersonating an administrator user might be the way to go. I've tried using LogonUser() and ImpersonateLoggedOnUser() before WNetAddConnection2(), it appears that the mount of the network path succeeds, but then actual accesses (e.g. enumerating of files in remote folder) fail. Any ideas?
我正在尝试从作为 LocalSystem 帐户运行的 Windows 服务连接到远程密码保护的共享文件夹。LocalSystem 帐户似乎无法使用 WNetAddConnection2() 或类似调用直接访问受密码保护的网络共享。任何人都可以证实这一点吗?我读过模仿管理员用户可能是要走的路。我在 WNetAddConnection2() 之前尝试使用 LogonUser() 和 ImpersonateLoggedOnUser(),看起来网络路径的安装成功,但实际访问(例如枚举远程文件夹中的文件)失败。有任何想法吗?
Thanks.
谢谢。
回答by Oleg
To tell the trust I worked all time only in a domain environment and without password-protected network shares, but I know that there are two main ways to make a connection: WNetAddConnection2
API and NetUseAdd
API. I recommend you to try NetUseAdd
function with Level equal to 1 (USE_INFO_1
). I used only USE_INFO_2
which has ui2_username
, ui2_domainname
and ui2_password
, but USE_INFO_1
has only ui1_password
, so it looks like a function made for connection to a password-protected share.
告诉信任,我一直只在域环境中工作,没有受密码保护的网络共享,但我知道有两种主要的连接方式:WNetAddConnection2
API 和NetUseAdd
API。我建议您尝试NetUseAdd
使用 Level 等于 1 ( USE_INFO_1
) 的函数。我只使用USE_INFO_2
which has ui2_username
, ui2_domainname
and ui2_password
,但USE_INFO_1
只有ui1_password
,所以它看起来像是一个用于连接到受密码保护的共享的函数。
By the way, LogonUser() has really no sense, because it makes locallogin on the local computer and you need to establish a session to the remote computer. This do WNetAddConnection2
and NetUseAdd
functions.
顺便说一句,LogonUser() 真的没有意义,因为它在本地计算机上进行本地登录,并且您需要与远程计算机建立会话。这做WNetAddConnection2
和NetUseAdd
功能。
回答by Walt
I just encountered this problem as well, and found that if I put the remote computer name into the user name, it worked. (I didn't actually figure this out, we had another place in the code already doing this that worked, so I knew it was possible, and finally figured out the difference.)
我刚好也遇到这个问题,发现如果把远程计算机名放到用户名里面就可以了。(我实际上并没有弄清楚这一点,我们在代码中的另一个地方已经这样做了,所以我知道这是可能的,并最终找出了区别。)
So for example:
例如:
WNetAddConnection2(&nr, "password", "SomeComputer\Username", 0);
I'm not doing any other special calls like LogonUser or ImpersonateLoggedOnUser.
我没有执行任何其他特殊调用,例如 LogonUser 或 ImpersonateLoggedOnUser。
This is in a service running under the SYSTEM account.
这是在 SYSTEM 帐户下运行的服务中。
I haven't tried using the SomeComputer\Administrator account, but that's not exactly a good practice anyway. I'm using a normal user account on SomeComputer.
我还没有尝试过使用 SomeComputer\Administrator 帐户,但这无论如何都不是一个好的做法。我在 SomeComputer 上使用普通用户帐户。
回答by mistika
The way you can access network share from a local system account(which is "NT AUTHORITY\SYSTEM"):
从本地系统帐户(即“NT AUTHORITY\SYSTEM”)访问网络共享的方式:
- You need to log on using some local account that has access to netowork even in non-domain net. It's enough to use "NT AUTHORITY\NETWORK SERVICE" account to gain this
- Add network share connection with specifying it's access credentials:
- 即使在非域网络中,您也需要使用一些可以访问网络的本地帐户登录。使用“NT AUTHORITY\NETWORK SERVICE”账号获得这个就够了
- 添加网络共享连接并指定其访问凭据:
The main point here is to use LOGON32_LOGON_NEW_CREDENTIALSlogon type during LogonUser() call (see MSDN for details/restrictions). Otherwise you'l get ERROR_NO_SUCH_LOGON_SESSION when executing WNetAddConnection2(), even if LogonUser and impersonation succeded.
这里的要点是在 LogonUser() 调用期间使用LOGON32_LOGON_NEW_CREDENTIALS登录类型(有关详细信息/限制,请参阅 MSDN)。否则,您在执行 WNetAddConnection2() 时会得到 ERROR_NO_SUCH_LOGON_SESSION,即使 LogonUser 和模拟成功。
LogonUser("NETWORK SERVICE", "NT AUTHORITY", NULL, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, &hToken );
ImpersonateLoggedOnUser(hToken);
NETRESOURCE nr;
nr.dwScope = RESOURCE_GLOBALNET;
nr.dwType = RESOURCETYPE_DISK;
nr.dwUsage = RESOURCEUSAGE_CONNECTABLE;
nr.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
nr.lpRemoteName = "\\SomeCopmuter\C$";
nr.lpLocalName = "Z:";
WNetAddConnection2(&nr, "password", "Administrator", 0);
Notes
笔记
- Impersonation woks only for current thread.
- with local resources it will work as LocalSystem, with the added share it will work as user on remote computer specified in WNetAddConenction2 (in this case - Administrator on SomeComputer).
- You can omit using drive letter in NETRESOURCE and access files via "\server\share\filename.ext" notation
- This may not work on some old systems (NT/2000, don't know exact list)
- 模拟仅适用于当前线程。
- 使用本地资源,它将作为 LocalSystem 工作,添加共享后,它将作为 WNetAddConenction2 中指定的远程计算机上的用户工作(在这种情况下 - SomeComputer 上的管理员)。
- 您可以在 NETRESOURCE 中省略使用驱动器号并通过“\server\share\filename.ext”符号访问文件
- 这可能不适用于某些旧系统(NT/2000,不知道确切列表)
回答by joshk0
I'm actually grappling with the same problem right now, Flavio, and my current suspicion is that it works if someone is interactively logged on to the machine, and will return ERROR_NO_SUCH_LOGON_SESSION if no one is logged on. I may be wrong, though. More to come. I've starred this question and will check back :)
我现在实际上正在解决同样的问题,弗拉维奥,我目前的怀疑是,如果有人以交互方式登录到机器,它会起作用,如果没有人登录,它将返回 ERROR_NO_SUCH_LOGON_SESSION。不过,我可能错了。还有更多。我已经给这个问题加了星号,我会回来查看:)
回答by shahin
import win32wnet from win32netcon import RESOURCETYPE_DISK as DISK path="\192.168.1.11\Student" win32wnet.WNetAddConnection2(DISK,"R:","\192.168.1.11\Student",None,"Student","pass",0)
import win32wnet from win32netcon import RESOURCETYPE_DISK as DISK path="\192.168.1.11\Student" win32wnet.WNetAddConnection2(DISK,"R:","\192.168.1.11\Student",None,"Student","pass",0)