Package: smbprotocol
smbprotocolSMBv2 and v3 Client for Python.SMB is a network file sharing protocol and has numerous iterations over the
years. This library implements the SMBv2 and SMBv3 protocol based on theMS-SMB2document.FeaturesNegotiation of the SMB 2.0.2 protocol to SMB 3.1.1 (Windows 10/Server 2016)Authentication with both NTLM and KerberosMessage signingMessage encryption (SMB 3.x.x+)Connect to a Tree/ShareOpening of files, pipes and directoriesSet create contexts when opening filesRead and writing of files and pipesSending IOCTL commandsSending of multiple messages in one packet (compounding)Experimental support for both standalone and DFS server sharesThis is definitely not feature complete as SMB is quite a complex protocol, see
backlog for features that would be nice to have in this library.RequirementsPython 3.7+For Kerberos auth on Linuxpython-gssapipykrb5To use Kerberos authentication on Linux, further dependencies are required, to install these dependencies run# for Debian/Ubuntu/etc:sudoapt-getinstallgccpython-devlibkrb5-dev
pipinstallsmbprotocol[kerberos]# for RHEL/CentOS/etc:sudoyuminstallgccpython-develkrb5-develkrb5-workstationpython-devel
pipinstallsmbprotocol[kerberos]Kerberos auth with Windows should just work out of the box with thepyspnegolibrary but on Linux, thepython-gssapilibrary must be installed andsmbprotocolrequires a particular GSSAPI extension to be available to
work. This extension should be installed on the majority of MIT or Heimdal Kerberos installs but that is not a
guarantee. To verify that Kerberos is available on Linux you can run the following check in a Python console:try:fromgssapi.rawimportinquire_sec_context_by_oidprint("python-gssapi extension is available")exceptImportErrorasexc:print(f"python-gssapi extension is not available:{exc}")If it isn't available, then either a newer version of the system's gssapi implementation needs to be setup and
python-gssapi compiled against that newer version. In the absence of this extension, only NTLM auth is used.InstallationTo install smbprotocol, simply runpipinstallsmbprotocol# To install with Kerberos supportpipinstallsmbprotocol[kerberos]This will download the required packages that are used in this package and get
your Python environment ready to go.Additional InfoOne of the first steps as part of the SMB protocol is to negotiate the dialect
used and other features that are available. Currently smbprotocol supports
the following dialects;2.0.0: Added with Server 2008/Windows Vista2.1.0: Added with Server 2008 R2/Windows 73.0.0: Added with Server 2012/Windows 83.0.2: Added with Server 2012 R2/Windows 8.13.1.1: Added with Server 2016/Windows10Each dialect adds in more features to the protocol where some are minor but
some are major. One major changes is in Dialect 3.x where it added message
encryption. Message encryption is set to True by default and needs to be
overridden when creating a Session object for the older dialects.By default, the negotiation process will use the latest dialect that is
supported by the server but this can be overridden if required. When this is
done by the following codeimportuuidfromsmbprotocol.connectionimportConnection,Dialectsconnection=Connection(uuid.uuid4(),"server",445)connection.connect(Dialects.SMB_3_0_2)While you shouldn't want to downgrade to an earlier version, this does allow
you to set a minimum dialect version if required.ExamplesThere are 2 different APIs you can use with this library.smbprotocol: Low level interface that can do whatever you want but quite verbosesmbclient: Higher level interface that implements the builtinosandos.pathfile system functions but for SMB supportTheexamplesfolder contains some examples of both the high and low level
interface but for everyday user's it is recommended to usesmbclientas it
is a lot simpler.smbclient InterfaceThe higher level interfacesmbclientis designed to make this library easier
for people to use for simple and common use cases. It is designed to replicate
the builtinosandos.pathfilesystem functions likeos.open(),os.stat(), andos.path.exists(). It is also designed to handle connections
to a DFS target unlikesmbprotocol.A connection made bysmbclientis kept in a pool and re-used for future
requests to the same server until the Python process exists. This makes
authentication simple and only required for the first call to the server. Any
DFS referrals are also cached in that Python process. This optimises any
future requests to that same DFS namespace.The functions insmbclienthave a global config object that can be used to
set any connection defaults to use for any future connections. It can also be
used to specify any domain based DFS settings for more advanced setups. It is
recommended to useClientConfig()to set any global credentials like so:importsmbclientsmbclient.ClientConfig(username='user',password='password')TheClientConfigis a singleton and any future instanciations of that
object will just update the keys being set. You can set the following keys on
theClientConfig:client_guid: The client GUID to identify the client to the server on a new connectionusername: The default username to use when creating a new SMB session if explicit credentials weren't setpassword: The default password to use for authenticationdomain_controller: The domain controller hostname. This is useful for environments with DFS servers as it is used to identify the DFS domain information automaticallyskip_dfs: Whether to skip doing any DFS resolution, useful if there is a bug or you don't want to waste any roundtrip requesting referralsauth_protocol: The authentication protocol to use;negotiate(default),kerberos, orntlmrequire_secure_negotiate: Control whether the client validates the negotiation info when connecting to a share (default:True).More information can be found onSMB3 Secure Dialect NegotiationAs well as setting the default credentials on theClientConfigyou can also
specify the credentials and other connection parameters on eachsmbclientfunction or when registering a new server. These functions accept the
following kwargs:username: The username used to connect to the sharepassword: The password used to connect to the shareport: Override the default port (445) to connect toencrypt: Whether to force encryption on the connection, requires SMBv3 or newer on the remote server (default:False)connection_timeout: Override the connection timeout in seconds (default:60)If using Kerberos authentication and a Kerberos ticket has already set bykinitthensmbclientwill automatically use those credentials without
having to be explicitly set. If no ticket has been retrieved or you wish to use
different credentials then set the default credentials on theClientConfigor specifyusernameandpasswordon the first request to the server.For example I only need to set the credentials on the first request to create
the directory and not for the subsequent file creation in that dir.importsmbclient# Optional - specify the default credentials to use on the global config objectsmbclient.ClientConfig(username='user',password='pass')# Optional - register the credentials with a server (overrides ClientConfig for that server)smbclient.register_session("server",username="user",password="pass")smbclient.mkdir(r"\\server\share\directory",username="user",password="pass")withsmbclient.open_file(r"\\server\share\directory\file.txt",mode="w")asfd:fd.write(u"file contents")If you wish to reset the cache you can either start a new Python process or
callsmbclient.reset_connection_cache()to close all the connections that
have been cached by the client.LoggingThis library makes use of the builtin Python logging facilities. Log messages
are logged to thesmbprotocolnamed logger as well assmbprotocol.*where*is each python script in thesmbprotocoldirectory.These logs are really useful when debugging issues as they give you a more
step by step snapshot of what it is doing and what may be going wrong. The
debug side will also print out a human readable string of each SMB packet that
is sent out from the client so it can get very verbose.TestingTo this module, you need to install some pre-requisites first. This can be done
by running;pipinstall-rrequirements-dev.txt# you can also run tox by installing toxpipinstalltoxFrom there to run the basic tests run;py.test-v--pep8--covsmbprotocol--cov-reportterm-missing# or with tox 2.7, 2.7, 3.4, 3.5, and 3.6toxThere are extra tests that only run when certain environment variables are set.
To run these tests set the following variables;SMB_USER: The username to authenticate withSMB_PASSWORD: The password to authenticate withSMB_SERVER: The IP or hostname of the server to authenticate withSMB_PORT: The port the SMB server is listening on, default is445SMB_SHARE: The name of the share to connect to, a share with this name must exist as well as a share with the name$SMB_SHARE-encryptedmust also exist that forces encryptionFrom here runningtoxorpy.testwith these environment variables set will
activate the integration tests.This requires either Windows 10 or Server 2016 as they support Dialect 3.1.1
which is required by the tests.If you don't have access to a Windows host, you can use Docker to setup a
Samba container and use that as part of the tests. To do so run the following
bash commands;source./build_helpers/lib.sh

lib::setup::smb_serverThis command will also set the requiredSMB_*env vars used in testing.BacklogHere is a list of features that I would like to incorporate, PRs are welcome
if you want to implement them yourself;Multiple channel support to speed up large data transfersLots and lots more...