-
-
Save jborean93/13dbfbd94e83ff810afc55e178371eb9 to your computer and use it in GitHub Desktop.
Thanks for putting together this code.
I think that the biggest problem here is that this code is not SMB protocol.... this is a RPC helper.
Not all SMB servers will have this available.
I was not able to use it with Azure Files SMB cloud server.
One thing to mention... on some servers you might need to be authenticated to list the shares
def get_share_info(server: str) -> list[ShareInfo]:
+ smbclient.ClientConfig(username='YOUR-USER', password='YOUR-PASS')
with smbclient.open_file(an example of using it with a handler obtained from Open ... handler with the following requests.
handler.create(
impersonation_level=ImpersonationLevel.Impersonation,
desired_access=(
FilePipePrinterAccessMask.FILE_READ_DATA
| FilePipePrinterAccessMask.FILE_READ_ATTRIBUTES
| FilePipePrinterAccessMask.FILE_READ_EA
| FilePipePrinterAccessMask.FILE_WRITE_DATA
| FilePipePrinterAccessMask.FILE_WRITE_ATTRIBUTES
| FilePipePrinterAccessMask.FILE_WRITE_EA
),
# Fail if file doesn't exist.
create_disposition=CreateDisposition.FILE_OPEN,
file_attributes=0,
share_access=0,
create_options=0,
)def tc_get_shares(handler: Open, server_name: str) -> list[ShareInfo]:
"""
Returns the list of shares.
"""
connection = handler.connection
fid = handler.file_id
sid = handler.tree_connect.session.session_id
tid = handler.tree_connect.tree_connect_id
# Bind to DCE RPC service
bind_req = build_dce_rpc_bind(1)
handler.write(bind_req, offset=0)
_ = handler.read(offset=0, length=1024) # bind_ack - should validate this
# Send the NetShareEnumAll as part of an IOCTL request
net_share_enum_req = build_net_share_enum(2, rf"\\{server_name}")
ioctl_req = SMB2IOCTLRequest()
ioctl_req["ctl_code"] = CtlCode.FSCTL_PIPE_TRANSCEIVE
ioctl_req["file_id"] = fid
ioctl_req["flags"] = IOCTLFlags.SMB2_0_IOCTL_IS_FSCTL
ioctl_req["max_output_response"] = 8196
ioctl_req["buffer"] = net_share_enum_req
req = connection.send(ioctl_req, sid=sid, tid=tid)
resp = connection.receive(req)
ioctl_resp = SMB2IOCTLResponse()
ioctl_resp.unpack(resp["data"].get_value())
# Should validate this is a success response not a failure
net_share_enum_resp = ioctl_resp["buffer"].get_value()
return unpack_smb_share_info(memoryview(net_share_enum_resp))Thank you for your sharing. I am not so familiar with SMB protocol, but I think I can understand your concern.
Well, fortunately, in my project, we decided to use only the part belongs to SMB protocol and don't need the list feature for now.
But I still hope this feature can be migrated into the smbprotocol package although it is actually not a part of smb protocol because not every one knows the details about this and most of us want an all-in-one solution that can manipulate the shared resources based and would expect everything I can do with the Windows Shared folder can be done programmatically.
Maybe you can consider to put them into a different module with a name like extra or helper, to indicate this is actually not a part of smb protocol. 😉
Thank you for this piece of code. It would be much more helpful if you can add this feature into the smbprotocol package.
I think
smbclient.list_share(server: str, *args, **kwargs)is a pretty easy to use approach.