对Windows网络权限机制的改进

发表于:2007-07-14来源:作者:点击数: 标签:
康帕斯(中国)国际信息服务有限公司 马文骞 无论是Win9x还是NT,甚至是最新的Win2000, Windows 的网络共享权限始终仅能作用于驱动器级和文件夹级,缺乏象UNIX那样的文件级访问权限使得Windows在网络资源管理的功能上始终不能尽善尽美。本文给出了完善 Wind
康帕斯(中国)国际信息服务有限公司 马文骞  

无论是Win9x还是NT,甚至是最新的Win2000,Windows的网络共享权限始终仅能作用于驱动器级和文件夹级,缺乏象UNIX那样的文件级访问权限使得Windows在网络资源管理的功能上始终不能尽善尽美。本文给出了完善 Windows网络共享机制的设计思想,以及实现该设计的示例程序。这种扩充的机制在提高网络安全性及灵活性方面有广泛的应用。
一、网络共享权限的扩充机制
Windows 的网络共享权限有三种:“只读”、“完全”和“根据密码访问”。但这种权限并不能作用于单独的文件。这就给具体的网络应用带来了很大的局限性。
通过在服务器端及各个客户端加装 Client/Server形式的应用,可以有效地改进这种状况。其中服务器上的管理程序负责维护和校验客户权限,并对符合权限要求的客户请求提供服务。这些请求一般包括:下载服务器上的文件,将本地文件上传至服务器的指定位置,修改、移动或删除服务器上的文件,等等。
下面的示例程序给出了这种扩充机制的一个具体实现,即“上传文件”。一个远程客户即使在 Windows级不拥有服务器上某文件夹的“写”权限(甚至连“读”的权限也没有),但只要他在扩充机制中拥有该文件夹中某文件的“写”权限,他依然可以上传该文件。
1. 客户程序(Client)
下图是客户程序的外观及执行情况。在填入正确的用户名和密码后,远程用户成功上传了 Logow.sys文件。这次文件覆盖操作将导致服务器关机画面的改变。由于上述文件存在于服务器的系统目录(\Windows或\WinNT)下,将整个文件夹的“写”权限在 Windows级共享给某用户是非常危险的,因此上述扩充机制很好地化解了风险。


客户程序源代码如下(VB 6.0):
Option Explicit
Dim BlockSize As Integer
Private Sub cmdConnect_Click()
If tcpClient.State <> sckClosed Then tcpClient.Close
tcpClient.RemoteHost = txtIP.Text
tcpClient.RemotePort = 1001
tcpClient.Connect ' 连接到服务器
End Sub
?  
Private Sub cmdDisconnect_Click()
tcpClient.SendData "Close" ' 关闭连接
cmdConnect.Enabled = True
cmdUpload.Enabled = False
cmdDisconnect.Enabled = False
End Sub
??  
Private Sub cmdUpload_Click()
' 发送用户名和密码(为简单起见,未做加密)
tcpClient.SendData "ID:" + txtName + "|PASS:" + txtPass
frmClient.MousePointer = 11
End Sub
?  
Private Sub tcpClient_DataArrival(ByVal bytesTotal As Long)
Static FileID As Integer, Cur_Pos As Long, FileLen As Long
Dim strData As String, j As Long
Dim Buf() As Byte
tcpClient.GetData strData
Select Case strData
Case "Connect OK" ' 收到连接成功的通知
cmdConnect.Enabled = False
cmdUpload.Enabled = True
cmdDisconnect.Enabled = True
Case "User Check Passed" ' 用户权限验证
tcpClient.SendData "File:" + txtDestination
Case "Please Upload File" ' 开始上传文件
If Dir$(txtSource) <> "" Then
FileID = FreeFile
Open txtSource For Binary As #FileID
FileLen = LOF(FileID)
If FileLen > 3072 Then
BlockSize = 3072
Else
BlockSize = FileLen ' 若文件小于3K,则一次发送完成
End If
ReDim Buf(1 To BlockSize) As Byte
Get #FileID, , Buf
tcpClient.SendData Buf
Cur_Pos = BlockSize
End If
Case "Next Block" ' 传送文件的后续块
If Cur_Pos = FileLen Then
tcpClient.SendData "End"
Close FileID ' 上传完成
frmClient.Caption = "TCP Client Upload " + Trim(Str(FileLen)) + " bytes"
frmClient.MousePointer = 0
Exit Sub
End If
j = Cur_Pos + BlockSize
If j > FileLen Then
j = FileLen - Cur_Pos
Else
j = BlockSize
End If
ReDim Buf(1 To j) As Byte
Get #FileID, , Buf
tcpClient.SendData Buf
Cur_Pos = Cur_Pos + j
frmClient.Caption = "TCP Client " + Trim(Str(Cur_Pos)) + " Bytes Uploaded."
End Select
End Sub
2. 服务器上的管理/服务程序(Server)
Option Explicit
Dim FileName As String
?  
Private Sub Form_Load()
tcpServer.LocalPort = 1001
tcpServer.Listen ' 监听用户登录申请
End Sub
?  
Private Sub tcpServer_ConnectionRequest(ByVal requestID As Long)
If tcpServer.State <> sckClosed Then tcpServer.Close
tcpServer.Aclearcase/" target="_blank" >ccept requestID
tcpServer.SendData "Connect OK"
End Sub
?  
Private Sub tcpServer_DataArrival(ByVal bytesTotal As Long)
Static FileID As Integer
Dim strData As String, j As Long
Dim Buf() As Byte
ReDim Buf(bytesTotal) As Byte
tcpServer.GetData Buf
' 收到断开登录的申请
If Chr(Buf(0)) = "C" And Chr(Buf(1)) = "l" Then
tcpServer.Close
tcpServer.LocalPort = 1001
tcpServer.Listen
Exit Sub
End If
' 收到用户名及密码
If Chr(Buf(0)) = "I" And Chr(Buf(1)) = "D" Then
strData = ""
For j = 0 To bytesTotal - 1
strData = strData + Chr(Buf(j))
Next
If Mid$(strData, 4, InStr(4, strData, "|") - 4) = "Kompass" And _
Mid$(strData, InStr(4, strData, "|") + 6) = "ReedInfo" Then
tcpServer.SendData "User Check Passed"
End If
Exit Sub
End If
' 收到目标文件名
If Chr(Buf(0)) = "F" And Chr(Buf(1)) = "i" Then
FileName = ""
For j = 5 To bytesTotal - 1
FileName = FileName + Chr(Buf(j))
Next
' 为简单起见,未做“同名确认”操作
If Dir$(FileName) <> "" Then Kill FileName
FileID = FreeFile
Open FileName For Binary As #FileID
tcpServer.SendData "Please Upload File"
Exit Sub
End If
' 收到文件传送完毕的通知
If Chr(Buf(0)) = "E" And Chr(Buf(1)) = "n" Then
Close #FileID
Exit Sub
End If
' 收到文件(二进制形式)的一块,并申请下一块
Put #FileID, , Buf
tcpServer.SendData "Next Block"
End Sub
二、扩充机制的进一步说明
第一,数据库的使用。上述服务器端的示例程序只是象征性地验证了一下远程用户的身份,而在真实的应用环境中应使用数据库来管理“用户名/密码/资源/权限”这四者的关系。
第二,与现有机制相配合。本文的扩充机制并不依赖于 Windows现有的权限机制。即使在 Windows下所有的资源共享都被关闭时(即所有资源均不共享),上述扩充机制仍能独立发挥作用。但如果与现有机制巧妙地配合,扩充机制可大大减少程序量。
第三,控件数组的使用。服务器端的示例程序仅使用了一个 Winsock控件进行通讯,而在真实的使用环境中应将之改为 Winsock控件数组来应付多用户的同时访问。
第四,对 UNIX 方式的模拟。进一步完善扩充机制以实现UNIX式的权限管理也并非难事。这种更丰富、更灵活的权限管理机制在较大型局域网中有着广泛的应用。

原文转自:http://www.ltesting.net