我正在使用pysmb 库来查询 SMB/CIFS 网络共享上的共享/目录结构。
def ListShares(Server, Username=None, Password=None, Domain=None):
Ip = socket.gethostbyname(Server)
conn = SMBConnection(Username,
Password,
'MyApp',
Server,
Domain,
use_ntlm_v2=True,
sign_options=SMBConnection.SIGN_WHEN_SUPPORTED,
is_direct_tcp=True)
assert conn.connect(Ip)
Response = conn.listShares(timeout=30)
return [{'Name': x.name,
'Type': x.type,
'IsTemporary': x.isTemporary,
'Comments': x.comments} for x in Response if not x.isSpecial]
当连接到运行 samba 的 linux 机器时,我可以正常连接并且一切正常。当我尝试连接到 Win7/SBS2008/Server2008 共享时,出现错误。
如果is_direct_tcp=True
,我得到一个Invalid protocol header for Direct TCP session message
File ".../MyApp/Managers/SmbHelper.py", line 38, in ListShares assert conn.connect(Ip)
File "/opt/pyenv/lib/python3.3/site-packages/smb/SMBConnection.py", line 111, in connect self._pollForNetBIOSPacket(timeout)
File "/opt/pyenv/lib/python3.3/site-packages/smb/SMBConnection.py", line 504, in _pollForNetBIOSPacket self.feedData(data)
File "/opt/pyenv/lib/python3.3/site-packages/nmb/base.py", line 49, in feedData length = self.data_nmb.decode(self.data_buf, offset)
File "/opt/pyenv/lib/python3.3/site-packages/nmb/nmb_structs.py", line 60, in decode raise NMBError("Invalid protocol header for Direct TCP session message")
如果is_direct_tcp=False
,我得到一个NotConnectedError
File ".../MyApp/Managers/SmbHelper.py", line 38, in ListShares assert conn.connect(Ip)
File "/opt/pyenv/lib/python3.3/lib/site-packages/smb/SMBConnection.py", line 111, in connect self._pollForNetBIOSPacket(timeout)
File "/opt/pyenv/lib/python3.3/lib/site-packages/smb/SMBConnection.py", line 466, in _pollForNetBIOSPacket raise NotConnectedError
我撞到了一块砖墙。我怎样才能找出究竟是什么错误并修复它?
进一步诊断...
smbclient -L linux.domain.local -U MyUsername -W domain //Works
smbclient -L linux.domain.local -U MyUsername@domain //Doesn't work (Auth failed)
smbclient -L windows.domain.local -U MyUsername -W domain //Doesn't work (Auth failed)
smbclient -L windows.domain.local -U MyUsername@domain //Works
smbclient -L [either].domain.local -U MyUsername@domain -W domain //Works, despite redundancy
因此,似乎 Linux 从-W
参数中获取域,Windows 从Username@Domain
语法中获取域,并提供两者使smbclient
调用成功到任一服务器。不幸的是,即使我使用@Domain
语法,在 pysmb 中连接到 Windows 也不会成功
解决方案
有 3 个问题......首先,当use_direct_tcp
=时True
,port
需要是445
。当它是时False
,端口应该是139
。使用 Python3 中的模块时还有一个错误(字节编码不正确)。最后,它与服务器通信的方式存在问题(至少在连接到 Windows 机器而不是 linux samba 服务器时)。
该模块的作者 Michael Teo 开发了一个修复程序,我们已经对其进行了测试和工作。他计划很快更新软件包。