开发者

WNetAddConnection2 from a Windows Service

开发者 https://www.devze.com 2023-01-02 09:07 出处:网络
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 direc

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?

Thanks.


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.

This is in a service running under the SYSTEM account.

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.


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.

By the way, LogonUser() has really no sense, because it makes local login on the local computer and you need to establish a session to the remote computer. This do WNetAddConnection2 and NetUseAdd functions.


The way you can access network share from a local system account(which is "NT AUTHORITY\SYSTEM"):

  1. 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
  2. Add network share connection with specifying it's access credentials:

The main point here is to use LOGON32_LOGON_NEW_CREDENTIALS logon 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("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)


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 :)


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)

0

精彩评论

暂无评论...
验证码 换一张
取 消