SMB Protocol Library
smbprotocol is a Python library designed to interact with servers using the SMB 2/3 Protocol. It provides low-level access to SMB operations, allowing for file and directory manipulation, session management, and authentication against SMB/CIFS shares. The current version is 1.16.1, and the project maintains an active release cadence with multiple updates per year.
Warnings
- breaking SMBv1 (Server Message Block version 1) support was completely removed starting from smbprotocol version 1.0.0. This library now exclusively supports SMBv2 and SMBv3.
- gotcha All `smbprotocol` objects representing server resources (e.g., `Connection`, `Session`, `TreeConnect`, `Open`) require explicit disconnection or closing. Failing to call `.disconnect()` or `.close()` will lead to resource leaks on both the client and server.
- gotcha Authentication can be complex, especially with Active Directory domains or specific security policies. Incorrectly providing the username (e.g., missing domain prefix for domain accounts, using UPN instead of samAccountName) or incorrect password hashing can lead to failed connections.
- gotcha The `smbprotocol` library provides a synchronous API. While it can be used within an `asyncio` application, it does not directly support `await` and will block the event loop if not run in a separate thread or process.
Install
-
pip install smbprotocol
Imports
- Connection
from smbprotocol.connection import Connection
- Session
from smbprotocol.session import Session
- TreeConnect
from smbprotocol.tree import TreeConnect
- Open
from smbprotocol.open import Open
- FilePipe
from smbprotocol.file import FilePipe
- CreateDisposition
from smbprotocol.file import CreateDisposition
Quickstart
import os
from smbprotocol.connection import Connection
from smbprotocol.session import Session
from smbprotocol.tree import TreeConnect
from smbprotocol.open import Open, CreateDisposition
# Replace with your SMB server details
SERVER_IP = os.environ.get('SMB_SERVER_IP', '127.0.0.1')
USERNAME = os.environ.get('SMB_USERNAME', 'guest')
PASSWORD = os.environ.get('SMB_PASSWORD', '')
SHARE_NAME = os.environ.get('SMB_SHARE_NAME', 'share') # e.g., 'myshare'
def list_share_contents():
connection = None
session = None
tree_connect = None
try:
print(f"Connecting to {SERVER_IP}...")
connection = Connection(SERVER_IP, port=445)
connection.connect()
print("Connection established.")
print(f"Authenticating as {USERNAME}...")
session = Session(connection, USERNAME, PASSWORD)
session.connect()
print("Authentication successful.")
print(f"Connecting to share \\{SERVER_IP}\{SHARE_NAME}...")
# SMB paths use backslashes, but smbprotocol handles forward slashes too
tree_connect = TreeConnect(connection, session, f'\\\\{SERVER_IP}\\{SHARE_NAME}')
tree_connect.connect()
print(f"Connected to share '{SHARE_NAME}'.")
print(f"Listing contents of '{SHARE_NAME}':")
# Open the directory itself to enumerate its contents
dir_open = Open(tree_connect, '/*', CreateDisposition.FILE_OPEN, access_mask=0x80000000) # FILE_LIST_DIRECTORY
dir_open.create()
for entry in dir_open.query_directory():
print(f" - {entry.file_name}")
dir_open.close()
except Exception as e:
print(f"An error occurred: {e}")
finally:
if tree_connect:
print("Disconnecting from tree connect...")
tree_connect.disconnect()
if session:
print("Logging off session...")
session.logoff()
if connection:
print("Disconnecting connection...")
connection.disconnect()
print("Cleanup complete.")
if __name__ == '__main__':
list_share_contents()