【问题标题】:Prevent WNetAddConnection2 class which allows prohibited user to access shared folder阻止允许被禁止用户访问共享文件夹的 WNetAddConnection2 类
【发布时间】:2013-02-16 01:29:44
【问题描述】:

我开发了 C# windows 应用程序。操作系统是 Windows 7

要求:是使用带有 WNetAddConnection2 类凭据的代码访问网络共享文件夹“测试”。

限制:是部分用户可以访问此共享文件夹“Test”,但对于其他用户,设置了“拒绝”共享权限。

在代码WNetAddConnection2 中验证错误的用户名/密码,它会给我错误。

例如

来自 LAN 的“用户 A”正在尝试使用 run command 访问共享文件夹“Test”,他无法访问“访问被拒绝”,因为他没有权限。

但问题是 WNetAddConnection2 类允许“用户 A”成功建立网络连接。 感染“WNetAddConnection2 允许来自域的所有用户”。类正在验证访问权限。

代码是

private void btnValidate_Click(object sender, EventArgs e)
     {
         bool valid = false;
         try
         {              
             NetworkCredential NC = new NetworkCredential(txtUserName.Text.Trim(), txtPassword.Text.Trim());  

         }
         catch (Exception ex)
         {
             MessageBox.Show(ex.Message.ToString());
         }
     }

public class NetworkConnection : IDisposable
 {
     string _networkName;
     uint dwFlags;
     public NetworkConnection(string networkName, NetworkCredential credentials)
     {
         _networkName = networkName;

         var netResource = new NetResource()
         {
             Scope = ResourceScope.GlobalNetwork,
             ResourceType = ResourceType.Disk,
             DisplayType = ResourceDisplaytype.Share,
             RemoteName = networkName
         };

         var userName = string.IsNullOrEmpty(credentials.Domain)
             ? credentials.UserName
             : string.Format(@"{0}\{1}", credentials.Domain, credentials.UserName);

         var result = WNetAddConnection2(netResource,"","",0x00000008 | 0x00000010);

         if (result != 0)
         {
             string strErrMsg = "";
             if (result == 67)
             {
                 strErrMsg = "The network name cannot be found.";
             }
             if (result == 86)
             {
                 strErrMsg = "Invalid UserName or Password for ProBiz server";
             }
             else if (result == 1219)
             {
                 strErrMsg = "Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed.Close application to Disconnect all previous connections to the server or shared resource and try again.";
             }

             throw new Win32Exception(result, "Error connecting to "+networkName+" remote share.Error Code:"+result.ToString()+"."+strErrMsg);
         }
         else
         {
             MessageBox.Show("Test connection is successful for "+ networkName);
         }
     }

     ~NetworkConnection()
     {
         Dispose(false);
     }

     public void Dispose()
     {
         Dispose(true);
         GC.SuppressFinalize(this);
     }

     protected virtual void Dispose(bool disposing)
     {
         WNetCancelConnection2(_networkName,  1, true  );
         var command = "NET USE  /delete *";
         ExecuteCommand(command, 5000);

     }
     public static int ExecuteCommand(string command, int timeout)
     {
         var processInfo = new ProcessStartInfo("cmd.exe", "/C " + command)
         {
             CreateNoWindow = true,
             UseShellExecute = false,
             WorkingDirectory = "C:\\",
         };

         var process = Process.Start(processInfo);
         process.WaitForExit(timeout);
         var exitCode = process.ExitCode;
         process.Close();
         return exitCode;
     } 

     [DllImport("mpr.dll")]
     private static extern int WNetAddConnection2(NetResource netResource,
         string password, string username, int flags);

     [DllImport("mpr.dll")]
     private static extern int WNetCancelConnection2(string name, int flags,
         bool force);
 }

 [StructLayout(LayoutKind.Sequential)]
 public class NetResource
 {
     public ResourceScope Scope;
     public ResourceType ResourceType;
     public ResourceDisplaytype DisplayType;
     public int Usage;
     public string LocalName;
     public string RemoteName;
     public string Comment;
     public string Provider;
 }

 public enum ResourceScope : int
 {
     Connected = 1,
     GlobalNetwork,
     Remembered,
     Recent,
     Context
 };

 public enum ResourceType : int
 {
     Any = 0,
     Disk = 1,
     Print = 2,
     Reserved = 8,
 }

 public enum ResourceDisplaytype : int
 {
     Generic = 0x0,
     Domain = 0x01,
     Server = 0x02,
     Share = 0x03,
     File = 0x04,
     Group = 0x05,
     Network = 0x06,
     Root = 0x07,
     Shareadmin = 0x08,
     Directory = 0x09,
     Tree = 0x0a,
     Ndscontainer = 0x0b
 }

【问题讨论】:

  • 如果您使用特定的用户名和密码连接到共享,那么登录到本地计算机的用户帐户无关紧要。如果您希望访问基于谁登录到本地计算机,请不要在调用 WNetAddConnection2 时提供用户名和密码。
  • @Harry 现在,我没有在代码中传递凭据,WNetAddConnection2 提示我并且共享文件夹连接成功,当我以没有访问权限的“用户 A”身份登录时,WNetAddConnection2 允许与“用户 A”连接的凭据。
  • 您在哪个操作系统上试用?
  • ...您能否发布构建NETRESOURCE 结构的代码和WNetAddConnection2 的声明?
  • 没有“拒绝共享权限”之类的东西,所以我怀疑您在正在共享的文件夹上设置了拒绝访问控制条目。这不会阻止用户连接到共享。能否连接到共享取决于共享权限,而不是共享文件夹的权限。

标签: c# windows networking directory shared


【解决方案1】:

按照设计,连接到共享需要访问共享 - 它确实不需要需要访问共享的根目录。

通过“运行”框打开共享会打开共享的根目录,因此它至少需要对该目录和共享的读取权限。相比之下,WNetAddConnection2() API 只需要访问共享。

它必须以这种方式工作,因为有时希望只允许某人访问某些子目录,而不是根目录。如果连接到共享需要访问根目录,这是不可能的。

连接到共享后,您可以通过尝试枚举文件来测试对根目录的访问。如果您收到拒绝访问异常,则用户没有访问权限。

【讨论】:

    【解决方案2】:

    我以前在 IIS 7.5 中部署 C# 项目时遇到了同样的问题,但是当我删除代码的注销过程时,这真是太棒了。 . .

    我的意思是删除函数LogoutFromShare(ip,folder)服务器目录。

    我只用这个LoginToOtherPC(ip, usr, pwd, folder)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-17
      • 2014-04-15
      • 2011-09-26
      • 1970-01-01
      • 2021-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多