susmb: unprivileged mounting of SMB/CIFS shares via FUSE

Last modification on

usmb is a program to mount SMB shares from userland via FUSE. Under-the-hood it uses Samba and exposes the network share as a regular local filesystem. Programs can just access the filesystem and for example do not need to add code for SMB support or link against Samba. It is more convenient than scripting around smbclient in some cases.
smbclient(1): https://www.samba.org/samba/docs/current/man-html/smbclient.1.html

susmb is a fork of usmb from 2013-02-04. http://repo.or.cz/w/usmb.git/snapshot/aa94e132c12faf1a00f547ea4a96b5728612dea6.tar.gz (git commit aa94e132c12faf1a00f547ea4a96b5728612dea6)

usmb has been unmaintained since 2013. Sometimes programs are finished and so being unmaintained is not so bad. I think the general idea of the code was good and it is still a useful program for some systems, probably mostly BSD systems. Linux has a SMB/CIFS driver anyway.

The two main reasons I forked usmb were performance issues with it on OpenBSD (because of hardcoded options and assumptions for FUSE for Linux) and issues by using it in non-interactive mode.

Clone

git clone git://git.codemadness.org/susmb

Browse

You can browse the source-code at:

Download releases

Releases are available at:

Build and install

$ make
# make install

Dependencies

  • C compiler.
  • libc + BSD extensions (libbsd on Linux).
  • FUSE 2.6 or later (and probably version <3).
  • Samba / libsmbclient 4.20+.

Usage example

susmb \
	-u hiltjo \
	-f \
	-o 'uid=1000,gid=1000,allow_other' \
	"smb://domain\someuser@192.168.1.1/Storage" \
	/mnt/share

Changes

susmb has the patches applied from OpenBSD ports 7.6: https://cvsweb.openbsd.org/ports/sysutils/usmb/patches

Below is a summary of the most important changes:

Performance

  • Set struct stat st.st_blksiz to a higher number for more efficient buffering for programs using the standard FILE* stdio interfaces. Huge improvement for reads and writes.
    On OpenBSD the default block size for FUSE is 512 bytes. This crippled network performance.
    On OpenBSD there is no FUSE caching layer (at time of writing 2025-09-07), so each read call had more overhead.
  • Remove the hardcoded FUSE mount option max_read=N.
    This crippled network performance.

Security

  • Many code simplifications and deletions (reducing attack surface and makes it easier to review).
  • Use unveil(2) syscall to lock down much of the filesystem except the mountpoint and required FUSE devices.
  • Optional privilege dropping support: on OpenBSD FUSE would need to run as root: (sysctl kern.usermount was removed around July 2016, around commit 65c8a8a0394483b41de8f02c862e65fb529cf538).
    After mounting the filesystem and acquiring access to the FUSE driver privileges are dropped. This is not perfect, but at least now the Samba smbclient code runs as a user again.
  • Reading the password from the terminal in a secure way using readpassphrase(3).

Cleanups

  • Merge everything into one C file for easier code review.
  • Remove Samba < 3.3 compatibility layer and code. This is hard to test nowadays anyway.
  • Use getopt for option parsing: remove dependencies on glib which was used for option parsing only.
  • Remove long option support.
  • Remove libxml2 dependency and configuration via XML. Configuration is now done via a simpler syntax as a URI from the command-line. This was also listed in the man page under the BUGS section as a wanted feature.
  • Remove autoconf and Debian-specific packaging files. Use a simple Makefile.
  • Man page rewritten from roff to mandoc.

OpenBSD port added as sysutils/susmb

An OpenBSD port was added to sysutils/susmb (thanks to Pascal Stumpf!).

Mailinglist thread: https://marc.info/?l=openbsd-ports&m=177169411929407&w=2