【问题标题】:WNetAddConnection2 from a Windows Service来自 Windows 服务的 WNetAddConnection2
【发布时间】:2010-06-03 17:41:38
【问题描述】:

我正在尝试从作为 LocalSystem 帐户运行的 Windows 服务连接到受密码保护的远程共享文件夹。 LocalSystem 帐户似乎无法使用 WNetAddConnection2() 或类似调用直接访问受密码保护的网络共享。 谁能证实这一点? 我读过冒充管理员用户可能是要走的路。 我在 WNetAddConnection2() 之前尝试过使用 LogonUser() 和 ImpersonateLoggedOnUser(),看起来网络路径的挂载成功,但是实际访问(例如远程文件夹中的文件枚举)失败。 有什么想法吗?

谢谢。

【问题讨论】:

    标签: windows service unc


    【解决方案1】:

    我也遇到了这个问题,发现如果我把远程计算机名放到用户名里面就可以了。 (我实际上并没有弄清楚这一点,我们在代码中的另一个地方已经这样做了,所以我知道这是可能的,最终找出了区别。)

    例如:

    WNetAddConnection2(&nr, "password", "SomeComputer\\Username", 0);
    

    我没有进行任何其他特殊调用,例如 LogonUser 或 ImpersonateLoggedOnUser。

    这是在 SYSTEM 帐户下运行的服务中。

    我没有尝试过使用 SomeComputer\Administrator 帐户,但这并不是一个好的做法。我在 SomeComputer 上使用普通用户帐户。

    【讨论】:

      【解决方案2】:

      为了告诉信任我一直只在域环境中工作并且没有密码保护的网络共享,但我知道建立连接有两种主要方法:WNetAddConnection2 API 和NetUseAdd API。我建议您尝试使用 Level 等于 1 (USE_INFO_1) 的 NetUseAdd 函数。我只使用了USE_INFO_2,它有ui2_usernameui2_domainnameui2_password,但USE_INFO_1只有ui1_password,所以它看起来像是一个用于连接受密码保护的共享的函数。

      顺便说一下,LogonUser() 真的没有意义,因为它使local 登录本地计算机,你需要建立与远程计算机的会话。这执行WNetAddConnection2NetUseAdd 函数。

      【讨论】:

      • 我正在尝试使用 LogonUser() 因为我在 MS 文档中读到 LocalSystem 帐户无法与远程计算机建立经过身份验证的连接,所以这个想法是首先模拟一个用户可以建立连接(即本地计算机管理员),然后尝试建立连接。
      • 只有在不使用WNetAddConnection2NetUseAdd 并尝试访问远程计算机时才会出现问题。如果您确实使用 WNetAddConnection2` 或 NetUseAdd,您将在目标计算机上进行远程登录。如果您在源计算机和目标计算机之间不信任,则使用LogonUser 进行本地登录可能会失败,因为您的本地计算机必须不知道来自远程计算机的用户。顺便说一句,如果两台计算机都在同一个域中,那么与远程计算机的连接可以使用计算机帐户(请参阅msdn.microsoft.com/en-us/library/ms677973(VS.85).aspx)进行操作。
      • 正如我所说,WNetAddConnection2() 在 Windows XP 上似乎不起作用。它确实适用于 Windows 7。这不在域中。在调用 WNetAddConnection2() 之前,我使用 LogonUser() 以普通用户身份登录到 local 计算机以模拟它。
      • 原因 WNetAddConnection2() 在 Windows XP 和早期版本的 Windows 上工作,但可能不适用于受密码保护的共享文件夹,而不是通常使用的用户授予的共享访问权限。你试过 NetUseAdd 吗?如果您在使用它时遇到问题,您应该发布您的代码。 LogonUser() 的方式绝对是错误的方式。只需在目标计算机上创建一个帐户,然后尝试使用LogonUser() 在源计算机上使用此帐户登录。它将独立于另一个本地系统帐户而失败。
      【解决方案3】:

      您可以从本地系统帐户(即“NT AUTHORITY\SYSTEM”)访问网络共享的方式:

      1. 您需要使用一些本地帐户登录,即使在非域网络中也可以访问网络。使用“NT AUTHORITY\NETWORK SERVICE”帐号即可获得此功能
      2. 添加网络共享连接并指定其访问凭据:

      这里的要点是在 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);
      

      备注

      • 模拟仅适用于当前线程。
      • 使用本地资源,它将作为 LocalSystem 运行,使用添加的共享,它将作为 WNetAddConenction2 中指定的远程计算机上的用户(在本例中为 SomeComputer 上的管理员)。
      • 您可以在 NETRESOURCE 中省略使用驱动器号,并通过“\server\share\filename.ext”表示法访问文件
      • 这可能不适用于某些旧系统(NT/2000,不知道确切列表)

      【讨论】:

        【解决方案4】:

        我现在实际上正在努力解决同样的问题,Flavio,我目前的怀疑是,如果有人以交互方式登录到机器上,它会起作用,如果没有人登录,它将返回 ERROR_NO_SUCH_LOGON_SESSION。不过,我可能是错的。更多即将到来。我已经为这个问题加注了星标,并将回来查看:)

        【讨论】:

        • 到目前为止,我发现从 LocalSystem 服务调用 WNetAddConnection2() 可以在 Windows 7 上运行,但在 XP 上失败。到目前为止,我总是尝试让用户以交互方式登录机器。我认为如果另一个用户登录到远程计算机,服务应该没关系,但我可能错了。
        【解决方案5】:

        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)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-11-03
          • 2020-06-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-23
          相关资源
          最近更新 更多