1. Introduction

Server Message Block (SMB) is a protocol for sharing resources over a network. It’s fairly widely supported and provides authentication. In particular, the main implementations of SMB are the Common Internet File System (CIFS) and Samba protocols. Both include the main definitions of SMB. In fact, Samba and Linux tools in general have many references to CIFS.

In this tutorial, we explore the Samba implementation of SMB and the mount.cifs command. First, we go over client utilities for the protocol. After that, we move on with a basic Samba server setup. Next, we discuss how to perform a fairly simple Samba mount. Then, we show credentials handling during mounting. Finally, we briefly get into version considerations and explore some SMB-specific mount options.

We tested the code in this tutorial on Debian 12 (Bookworm) with GNU Bash 5.2.15. Unless otherwise specified, it should work in most POSIX-compliant environments.

2. Install Samba Client Utilities

While there are Samba clients such as smbclient, in Linux, we usually employ the cifs-utils package in combination with mount.

So, let’s first install cifs-utils:

$ apt install cifs-utils

After doing so, we should have access to the mount.cifs command:

$ mount.cifs

Usage:  mount.cifs <remotetarget> <dir> -o <options>

Mount the remote target, specified as a UNC name, to a local directory.
[...]

In fact, there are two different versions of the mount command that relate to Samba:

  • mount.cifs: work with CIFS or SMB3 shares
  • mount.smb3: works only with SMB3 shares

This way, we can enforce the strongest possible security currently available in later SMB versions.

Further, cifs-utils contains an entire toolkit:

  • cifscreds: manage keyring NTLM credentials
  • getcifsacl, setcifsacl: handle ACL in CIFS filesystems
  • smb2-quota: display CIFS quota
  • smbinfo: display SMB-specific file information
  • cifs.idmap: map identifiers tor CIFS
  • cifs.upcall: additional helper functions for CIFS

Previously, these user-space utilities were part of the samba package. However, since they are mostly client-oriented, they were split off. They work with the in-kernel CIFS filesystem.

3. Install and Set Up Samba Server

Now, let’s create a basic Samba server to test with.

First, we install the samba package:

$ apt install samba

Next, we configure /etc/samba/smb.conf by adding a few lines:

$ cat /etc/samba/smb.conf
[...]
[smbshare]
  comment = Custom Samba Share
  path = /mnt/samba
  public = yes
  browseable = yes
  writable = yes

Lastly, we restart the smb service:

$ systemctl restart smb

At this point, /mnt/samba/ is exposed as the public, browseable, and writable //<MACHINE_IDENTIFIER>/smbshare/ share. Here, MACHINE_IDENTIFIER can be a mapping like localhost, a custom name such as xost, an IP address, or similar.

4. Basic Samba Share Mount

Due to the standardization of mount, the basic form of the mount.cifs command just takes a target and path. In case there are mount –options (-o) to pass, we can also add them accordingly.

Let’s see a basic example:

$ mount.cifs //localhost/smbshare/ /mnt/smbshare/

Alternatively, we can use the longer form:

$ mount --types cifs //localhost/smbshare/ /mnt/smbshare/

Either way, we attempt to mount //localhost/smbshare/ at /mnt/smbshare/.

After doing so, we should be able to access /mnt/smbshare/ and freely work with the path and data under it.

Of course, this fairly simple procedure usually isn’t the case for remote systems, which often require credentials.

5. Samba Mount Credentials

There are different ways to access a Samba share as a specific user, often required with remote mounts.

5.1. guest

To begin with, Samba offers the so-called guest account for unrestricted access. For that, we either add the public: yes or guest ok: yes setting to /etc/samba/smb.conf.

Once we do, we append guest to the –options of the mount command:

$ mount.cifs --options guest //localhost/smbshare/ /mnt/smbshare/

While they don’t require any credentials, guest accounts often only allow us to view just basic information. Further, not all servers enable this option. Even when it’s available, servers rarely enable guest access to all shares.

5.2. Local User

While we might be able to mount as a guest, a more common method is to use credentials.

For that, we usually get a prompt as part of the mount operation:

$ mount.cifs //localhost/smbshare/ /mnt/smbshare/
Password for baeldung@//localhost/smbshare/:

The mount command automatically assumes we want to use the current user as the remote one as well. After entering the respective password, we log in with the current local username to the remote host.

5.3. Specify User

Since remote user credentials don’t always match local ones, let’s see how to specify another username.

Critically, local system users don’t automatically have a respective Samba equivalent. To create that, we use the smbpasswd command with the [-a]dd user option:

$ smbpasswd -a baeldung
New SMB password:
Retype new SMB password:
Added user baeldung.

Notably, despite its name, the [-a]dd option of smbpasswd only includes Samba entries for users that already exist on the system.

After having a prepared username, we include it as [user]name in the –options to mount:

$ mount.cifs --options user=baeldung //localhost/smbshare/ /mnt/smbshare/
Password for baeldung@//localhost/smbshare/:

Now, the prompt and login user change due to the user= or username= option and the value we supply.

If the user is part of a specific [dom]ain, we can add that as well:

$ mount.cifs --options user=baeldung,domain=DOM1 //localhost/smbshare/ /mnt/smbshare/

This is related to the workgroup setting in the smb.conf file.

5.4. Specify Password

Indeed, we can even include a [pass]word in the mount options, although this isn’t secure:

$ mount.cifs --options user=baeldung,pass=1password //localhost/smbshare/ /mnt/smbshare/

Notably, running mount.cifs without any other arguments results in a hint with all options, which begins with the short form of the three most common ones:

$ mount.cifs
[...]
Options:
user=<arg>
pass=<arg>
dom=<arg>
[...]

One of them is [pass]word. Still, including sensitive information in commands isn’t recommended.

5.5. Credentials File

To avoid passing credentials on the command line, we can also use a credentials file.

For that, we first create a file and restrict its permissions:

$ touch .smbcreds
$ chmod 600 .smbcreds

After that, we populate the file with the respective credential information in the correct format:

$ vi .smbcreds
[...]
username=baeldung
password=1password
domain=WORKGROUP

Critically, no leading spaces are allowed at any point here.

Finally, we can specify the file after the credentials option:

$ mount.cifs --options credentials=/mnt/.smbcreds //localhost/smbshare/ /mnt/smbshare/

Thus, we automate the login process without exposing any sensitive information.

6. Samba Versioning

Over the years, Samba has evolved through several versions:

  • vers=3.1: SMB3_11
  • vers=3.0: SMB3
  • vers=2.1: SMB2_10
  • vers=2.0: SMB2_02
  • vers=1.0: NT1

Naturally, the latest one is often the most secure, but not always compatible with older versions.

Further, we indicate the desired version via the vers option:

$ mount.cifs --options vers=3.0 //localhost/smbshare/ /mnt/smbshare/

Now, let’s try with a lower version:

$ mount.cifs --options vers=1.0 //localhost/smbshare/ /mnt/smbshare/
mount error(95): Operation not supported

Evidently, the server we’re trying to connect to doesn’t support the 1.0 version of SMB. Version compatibility is one of the top reasons for connection issues.

Further, the CIFS dialect is gradually getting dropped in favor of the SMB specification.

7. Samba Mount Options

In addition to the filesystem-agnostic mount options, there are some more Samba-oriented settings we can use.

7.1. Session Parameters

Several options relate to session establishment.

While there are two possible default ports that the command tries (445 and 139), we can also specify a custom one via port=. In addition, although not mandatory due to the possible resolution mechanisms of the target, we can also indicate the ip= address of the destination.

Two settings dictate the NetBIOS name:

  • servern: server name to use
  • netbiosname: client name to use

This way, we can have finer control.

7.2. CIFS UNIX Extensions

Since CIFS wasn’t initially targeting Linux and UNIX environments, extensions to the protocol implementation became a standard part of many versions. This trend continued and POSIX extensions for SMB were specifically designed for more security.

Let’s explore some options that behave differently according to the extensions.

First, we look at the situation when the extensions aren’t supported:

  • file_mode and dir_mode force the default modes for each object type
  • setuids only caches user and group identifiers (nosetuids is the default and leaves the server to set them)
  • sfu changes the format of device and FIFO files for compatibility

Now, let’s see how the behavior differs when extensions are supported:

  • setuids attempts to set the effective user and group identifiers of the local process on new filesystem objects
  • noperm can skip client checks, usually employed when user and group identifiers don’t match

Notably, the default perm performs permission checks on the client in addition to those on the server

7.3. Security

When it comes to inherent security, the sec option has several possible values:

  • none: connect as user without a name
  • krb5: Kerberos 5
  • krb5i: Kerberos and packet signing
  • ntlm: NTLM password hashing (default)
  • ntlmi: NTLM password hashing and signing
  • ntlmv2: NTLMv2 password hashing
  • ntlmv2i: NTLMv2 password hashing and packet signing

Further, noacl disables POSIX access control list (ACL) operations.

7.4. inode Options

Since inodes are system-specific, control over them can be important when it comes to remote mounts like Samba.

For instance, directio prevents inode data caching to gain a small performance benefit. The default behavior is to read ahead and write behind inodes.

Another example is the serverino option, which prevents the client from generating inode numbers. The default is noserverino, which enables clients to generate their own inode numbers.

7.5. Character Recognition

Due to the different platforms that support CIFS, character mapping differences can cause issues in certain cases. In addition, there are reserved characters that may confuse filesystem object processing:

  • \ backslash
  • : colon
  • ? question mark
  • | pipe
  • * asterisk
  • > greather than
  • < less than

Of these, the \ backslash is fairly hard to handle due to its role as a special escape character.

Still, the mapchars option can help by remapping the other six characters to Unicode sequences. The default behavior is nomapchars, which doesn’t perform any translation.

7.6. Server Crash Behavior

Two mount options distinguish between ways of handling server crashes:

  • hard: programs hang
  • soft: programs return errors (default)

The desired behavior mainly depends on the network stability and share criticality.

7.7. Read and Write Sizes

When transmitting data via CIFS, the default read size is usually 16Kb, while the default write is 57344b, i.e., fourteen pages of 4096b.

However, we can theoretically change these parameters via rsize and wsize. In practice, wsize is limited to its default value, so we can only lower it. On the other hand, rsize depends on a compile-time parameter of the CIFS module. Usually, we can go down to 2048b and up to 127Kb without issues but may need server support for more.

8. Summary

In this article, we explored the Samba implementation of the SMB protocol along with many options to mount Samba shares.

In conclusion, although SMB is usually more common in Microsoft Windows environments, Linux provides a complete toolkit for handling the protocol and many of its intricacies.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.