Using smb-kotlin with Samba Servers

Protocol Compatibility

smb-kotlin supports SMB2 and SMB3 protocols with automatic version negotiation. When connecting to a Samba server, smb-kotlin will negotiate the highest protocol version both sides support. Modern Samba 4.x releases support both SMB2 and SMB3, so connections will typically negotiate SMB3 automatically.

No special configuration is needed on the client side. smb-kotlin treats Samba servers the same as Windows servers or NAS devices — the SMB protocol is the same regardless of the underlying operating system.

Tested Configurations

Platform Samba Version Status
Ubuntu / Debian Samba 4.x Works
CentOS / RHEL Samba 4.x Works
macOS (built-in SMB) Apple SMB (Samba-derived) Works
Synology DSM Samba 4.x Works
QNAP QTS Samba 4.x Works

Connection Example

Connecting to a Samba share on a Linux server is identical to connecting to any other SMB server.

import com.ctreesoft.smb.SmbClient
import kotlinx.coroutines.flow.collect

suspend fun listSambaShare() {
    val client = SmbClient()
    val share = client.connectShare(
        host = "linux-server.local",
        shareName = "shared",
        username = "sambauser",
        password = "mypassword",
        domain = "WORKGROUP"
    )

    try {
        share.listDirectory("").collect { entry ->
            println("${entry.name} (${entry.size} bytes)")
        }
    } finally {
        share.close()
        client.close()
    }
}

Authentication

smb-kotlin uses NTLMv2 authentication, which is Samba's default authentication mechanism. No additional configuration is needed on either the client or server side for password-based authentication to work.

The domain parameter in smb-kotlin maps to the Samba workgroup setting. For standalone Samba servers, this is typically "WORKGROUP" (the default). For Samba servers joined to an Active Directory domain, use the AD domain name.

// Standalone Samba server
val share = client.connectShare(
    host = "samba-box",
    shareName = "files",
    username = "boris",
    password = "hunter2",
    domain = "WORKGROUP"  // matches Samba's "workgroup" setting
)

// Samba joined to Active Directory
val share = client.connectShare(
    host = "samba-box",
    shareName = "files",
    username = "boris",
    password = "hunter2",
    domain = "CORP"  // AD domain name
)

SMB3 Encryption with Samba

Samba 4.x supports SMB3 encryption using AES-128-CCM. You can enable encryption from either the server side or the client side.

Server-Side (smb.conf)

To require encryption for all connections to a share, add the following to your Samba configuration:

[confidential]
    path = /srv/confidential
    smb encrypt = required

When the server requires encryption, smb-kotlin will automatically enable it during session setup. No client configuration is needed.

Client-Side

To force encryption from the client regardless of server settings:

val config = SmbConfig(
    forceEncryption = true
)

val client = SmbClient(config)
val share = client.connectShare(
    host = "samba-box",
    shareName = "files",
    username = "boris",
    password = "hunter2"
)

If the server does not support SMB3, forcing encryption will cause the connection to fail with an error indicating that the server cannot satisfy the encryption requirement.

Common Issues

Guest Access Disabled

Recent versions of Samba disable guest access by default. If you see authentication errors when connecting without credentials, make sure you are providing a valid username and password. To check if guest access is enabled on the server, look for map to guest in the Samba configuration.

File Permissions

Samba maps SMB access to Unix file permissions. If you can authenticate but get "access denied" errors on file operations, check that the Unix user mapped to your Samba account has appropriate read/write permissions on the underlying filesystem.

Firewall (Port 445)

SMB uses TCP port 445. If you cannot connect to a Samba server, verify that port 445 is open in the firewall. On systems using ufw:

sudo ufw allow 445/tcp

On systems using firewalld:

sudo firewall-cmd --permanent --add-service=samba
sudo firewall-cmd --reload