15.6 Understanding SMB

The Server Message Block (SMB) protocol is the standard DOS and Windows approach to network file and printer sharing. SMB is a client/server protocol that provides a mechanism for clients to access server filesystems (as well as printers and other input/output abstractions).

What's SMB doing in a book about Unix security? Although many sites run networks composed entirely of Unix workstations and servers, heterogeneous networks that contain both Windows-based and Unix-based hosts have become very common. Thanks to Samba, the free Unix implementation of the SMB protocol, Unix systems can participate in SMB networks as either clients or servers, and in this section we focus on the security implications of this participation for those Unix hosts.

Solaris offers support for SMB using its Solstice PC-NetLink product, whereas Mac OS Version 10.2 and above include native support for SMB.

15.6.1 SMB History

The SMB protocol has been in use since the mid 1980s, and has gone through several major revisions. It was available for DOS-based PCs in the form of LAN Manager, and was broadly introduced in Microsoft Windows for Workgroups 3.11. The early versions of SMB provided a useful, if relatively unsecure, peer-to-peer file-sharing system.

Later protocol dialects, introduced with Windows 95, Windows 98, and Windows NT (and present in even later versions of Windows, including XP), provided several security improvements. SMB clients and servers negotiate with one another to determine the protocol dialect to use for the ensuing conversation.

In a typically expansive fashion, Microsoft began referring to the latest revisions of the protocol as the Common Internet File System (CIFS) in the 1990s. Microsoft's collection of CIFS documentation is at ftp://ftp.microsoft.com/developr/drg/cifs/cifs.html.

15.6.2 Protocols

SMB is an application layer protocol that can be run over several kinds of network transport. Its most common modern implementation runs over TCP/IP networks through the use of an intermediate NetBIOS session layer. The NetBIOS layer is responsible for managing name service?enabling machines to locate one another by name.[19] NetBIOS can also be run directly on top of Ethernet, although such use is declining.

[19] According to the CIFS 1.0 specification, CIFS may, in principle, run on any network transport, including TCP/IP, without the NetBIOS API (using, for example, DNS for name service). Name service

NetBIOS over TCP/IP (sometimes called NBT) is a complex protocol that can operate in several different ways. In the simplest model, NetBIOS nodes (hosts) discover each other and register their names on the network by using broadcast packets. In addition to being difficult to scale up to larger networks, this mode makes it relatively simple for nodes to "steal" one another's registered names and effectively impersonate one another.

A more secure mode of operation requires the NetBIOS nodes to communicate (point-to-point) with hosts designated as NetBIOS name service nodes (sometimes called WINS servers) to register and look up names, and with NetBIOS datagram distribution nodes to broadcast packets at the NetBIOS level. The NetBIOS name servers can provide safeguards against machines spoofing each other's names. Samba can act as a NetBIOS name server.

Internet RFCs 1001 and 1002 describe NetBIOS over TCP/IP in great detail. Authentication

In most cases, users who wish to use a resource must first log into the SMB server providing that resource. The login process in modern SMB dialects uses challenge/response authentication.[20] When a user requests to log in, the SMB server sends a unique challenge string to the client. The client encrypts this string using a session key computed from a cryptographic hash of the user's password and returns the response to the SMB server. The SMB server performs the same computation and compares its results to the client's. If they match, the user is authenticated. The exact form of the computation depends on the SMB dialect in use; two approaches ("LM" and "NT") are currently defined.

[20] Older SMB dialects (e.g., those used in Windows for Workgroups) allowed plaintext passwords to be sent over the network, and Samba defaults to doing so. Some SMB servers will refuse to communicate with clients in these dialects, which is prudent behavior.

Note that this approach implies that the SMB server (or some other authentication server with which it communicates) has the user's hashed password available to it (but not necessarily the cleartext password). If this server is compromised, all the user's hashed passwords are compromised (so the attacker may be able to masquerade as the user and connect to other SMB servers). On the other hand, this approach prevents the cleartext or hashed password from ever traveling over the network.[21]

[21] Both vulnerabilities could be eliminated if SMB were to use public key cryptography, but it doesn't.

The SMB protocol includes a password-change request, in which the new password is encrypted with the old password and then transmitted over the network. Thus, if an attacker knows your password and is monitoring all of your network traffic, the attacker will be able to know your new password as well! File access

The SMB protocol is implemented as a client/server model. Clients send requests to the SMB server, and the server sends a response to each request. The first exchange (once a NetBIOS session has been established) involves the client sending a list of dialects that it supports to the server, and the server choosing the dialect that the remainder of the session will use (or refusing to communicate with the client if it does not offer a sufficiently secure dialect). The most recent dialect (with the best security features) is NT LM 0.12, and, except where noted, we focus on this dialect in this chapter.

After a protocol dialect is agreed upon, the client makes a series of requests, and server responses to successful requests provide the client with useful information. For example, a client might request to log in with a username and password, and, if successful, the server will return a user ID number that the client must send with future requests. Using the user ID, the client can then request to connect to a particular resource (e.g., a share), and the server returns the resource's tree ID. Using the user ID and tree ID, the client can then request to open a file, and the server returns the file ID. Using all of these IDs, the client can then send requests to read from or write to the file.

Unlike NFS, SMB transactions are not stateless: the client and server each maintain a synchronized sequence number that is used in the generation of message authentication codes (MACs) to prevent replay attacks.

Each message sent between client and server can be authenticated with a MAC, which is a cryptographic hash of the session key, the message text, and the sequence number. This code establishes the authenticity of the message source (because it is derived from the session key and sequence number), and the integrity of the message (because it is derived from the message text).

15.6.3 Configuring the Samba Server

Samba is a free software implementation of an SMB/CIFS server (smbd) and client (smbclient) for Unix systems that speak the NT LM 0.12 dialect of the SMB protocol. It also provides NetBIOS name services through the nmbd daemon. Since the time of its introduction, it has proven to be a stable, efficient, and portable way for Unix systems to participate in Windows networking. At the time of this writing, the latest version of Samba is 2.2.5.[22]

[22] There are other non-free SMB implementations for Unix, such as Solaris Solstice PC-NetLink, although they are not as widely distributed as Samba.

The Samba daemons run as root and are configured through the file smb.conf, a text file that can either be edited in the usual manner or maintained with a web browser by running the swat HTTP-based configuration server on port 901.[23] The usual location for smb.conf is in /etc, but on some systems, it may appear in /etc/samba, /usr/local/etc, or other locations.

[23] The swat daemon runs as root, and requires the user to provide the root password to the web browser to use it. In the default setup, this password is transmitted in the clear, so if you choose to use it, swat should be configured to permit access only from localhost to avoid the risk of password sniffing. An even better idea is to use stunnel to create an SSL tunnel for encrypted access to swat.

Here's an example of a simple smb.conf file configured to provide read/write network access to the /opt/book directory through a share called book. The Samba server will appear in the AUTHORS workgroup for the purposes of browsing, and is only accessible to hosts in the 192.168.*.* subnet(s).

        workgroup = AUTHORS
        encrypt passwords = Yes
        hosts allow =,
        hosts deny = ALL

        path = /opt/book
        read only = No

The [global] section of smb.conf includes options that apply globally to the server. Each share also has its own section of smb.conf for per-share options.

15.6.4 Samba Server Security

Several smb.conf directives have important security implications. Here, we consider directives that affect network access to the Samba server itself, user authentication, authorization for file operations within a share, and data integrity and privacy.[24] We'll generally assume that the users access their files only through Samba. If users also log into the server and access their files directly (or access them through NFS), they are subject to different restrictions from those imposed by Samba, thereby circumventing several of Samba's protections.

[24] There are also directives related to visibility of the Samba server and its shares on the network, but as it is possible to access a Samba server's shares even if they are not visible to the client, this "security by obscurity" adds less to the overall security of the server than might be expected. Connecting to the server

By default, the Samba daemons listen for NetBIOS or SMB traffic on all of the server's interfaces, and accept traffic from any source that can get an SMB packet to the server. At many sites, firewalls are used to restrict which hosts can communicate with SMB servers (ports 137, 138, 139, and 445 are all used to carry traffic for the protocols involved). However, Samba itself provides directives to restrict who can connect to the server and can be used to provide defense in depth. These include:


A space-separated list of interfaces (either device names or IP addresses) that Samba will use to broadcast NetBIOS traffic. By default, Samba uses all broadcast-capable interfaces.

bind interfaces only

If set to yes, only interfaces listed in the interfaces directive will be allowed to receive SMB traffic. Combining this directive with interfaces can prevent Samba from listening on some interfaces on a multi-homed server. Defaults to no.

hosts allow, hosts deny

These directives can be used to specify comma-separated lists of IP addresses (or address ranges) that are explicitly allowed or denied access to the server. The syntax is the same as that used by TCP Wrappers (see Chapter 12 for details on this syntax). The allow list is checked first. By default all hosts are allowed access and none are denied. User authentication

Samba supports all of the recognized modes of SMB authentication, including those that present serious security problems. In its default configuration, however, Samba attempts to use relatively secure options:


The security directive is the most important directive in determining how user authentication will take place, although it interacts with several other directives. It can take four values: user (the default), share, server, and domain.

When security is set to user, clients must log into the Samba server with a username and password to be authenticated, typically through the SMB challenge/response protocol described earlier. The user is associated with a Unix user ID that is used for authorization purposes.

When security is set to share, clients send the Samba server a password associated with each share they wish to access, and the server determines which Unix user ID to use for authorization based on a complicated decision process. This security mode is used to make "guest" shares (especially printers and read-only file shares) accessible to anyone on the network who has the share password; other directives then specify the Unix user ID that will be used for guest access. This model has much in common with anonymous FTP, and the same cautions apply. For example, writable guest shares allow anyone with the share password to create files on the share, and anyone else to modify or delete them. On the other hand, making guest shares available under any other security mode requires some additional work.

When security is set to server, Samba passes the username and password information to another SMB server to authenticate (and, if unsuccessful, then tries to authenticate the user itself as if in user mode). The password server directive is used to list the NetBIOS names of password servers.

When security is set to domain, Samba passes the username and password information to one or more primary or secondary domain controllers for authentication (which can be either a Windows NT/2000 server or another Samba server). The password server directive is used to list the NetBIOS names of password servers.

encrypt passwords

This directive controls whether Samba uses the SMB challenge/response password algorithm or plaintext passwords. It defaults to no (plaintext passwords), which is less secure but convenient, as Samba can check plaintext passwords against the standard Unix /etc/passwd (or /etc/shadow) files. Setting this directive to yes provides increased security, but requires the Samba administrator to maintain a separate file of passwords for Samba access, /etc/smbpasswd. The Samba password file is maintained by the smbpasswd command and, like /etc/shadow, should only be readable by root. If users have shell access to the Samba server, they can set their initial passwords. Otherwise, the Samba administrator must set them and distribute them (securely!) to the users.[25]

[25] When users have no shell access, the administrator can stay out of the loop in one of several ways. The first is by setting user passwords to be null and configuring Samba to accept null passwords for users. Users can then use the SMB protocol to change their own passwords. Until they do, however, the server will allow unpassworded access to those users, so we strongly discourage this approach. A second approach is to disable encrypted passwords and use the update encrypted directive to create SMB-encrypted passwords from the plaintext passwords with which users log in. After all users have logged in at least once with plaintext passwords, update encrypted can be disabled, and encrypt passwords can be enabled. This approach exposes plaintext passwords on the network for some time, however, and trades security for convenience unless all network connections are encrypted at a lower level (e.g., by IPsec). A third approach is to create an out-of-band system for users to create their initial SMB password; for example, a web page can be set up that runs the smbpasswd program.

Microsoft Windows 95 defaults to unencrypted passwords. Microsoft Windows 98, NT4, Windows 2000, Windows XP, and later versions of Windows all require encrypted passwords unless a specific registry value is changed.

unix password sync

When this directive is set to yes, the Samba server will attempt to keep the user's Unix password and Samba password synchronized by changing the Unix password any time it receives an SMB password-change request. The default is no.

min protocol

This directive can be used to specify a minimal level of SMB dialect that the server will allow clients to negotiate. It can, for example, be used to prevent clients from negotiating a dialect that allows plaintext passwords to be transmitted or that doesn't provide other security features. Possible values for this directive (from highest to lowest) are: NT1, LANMAN2, LANMAN1, COREPLUS, and CORE.

map to guest

This directive can be used to let Samba associate failed logins with a guest account, and is useful in providing guest shares when the security directive is set to anything other than share. By default, its value is never, which does no mapping. When set to bad user, attempts to log in with a nonexistent username are treated as guest logins. When set to bad password, attempts to log in that provide an invalid password are treated as guest logins (which is likely to confuse users who mistype their passwords). Authorization

Once users have logged in, Samba must decide whether they should be granted access to files they request. The key concept in Samba authorization is simple. At login, a user is associated with some Unix user ID, and her access rights are determined by the privileges of that user ID and the Unix file permissions on the exported files.

In all but the share security mode, users are typically associated with the user ID of the Unix user in /etc/passwd that matches the client's username, though the directives described in the following list can be used to modify that assignment or assign an appropriate user ID when the connection is treated as a "guest."

username map

This directive specifies a file (often named smbusers) that associates Unix usernames with usernames supplied by clients in SMB. For example, if Jane Starr uses "Jane" as her SMB client login, but her Unix account name is "jstarr", the smbusers file might contain this line:

jstarr = jane

A single Unix username should appear on the left side of the equal sign. Client names are listed on the right side, separated by spaces and enclosed in double quotes if the client name itself contains spaces. The special client name @group refers to all the Unix user names in the group group; the special client name * refers to any name. The file is matched line-by-line, and multiple lines may match, but matching stops if a line beginning with ! is matched. For example, using the following file, a client logging in as "Jane" would be mapped to the Unix user ID for the staff account, and a client logging in as "Sam" would be mapped to the Unix user ID of the guest account.

# Sample smbusers file
jstarr = jane
!staff = jstarr pkrantz
guest = *
obey pam restrictions

If your Unix system uses PAM, setting this directive to yes will cause any PAM account or session restrictions on the client's associated Unix user ID to apply (such as maximum simultaneous logins, maximum file size, etc.).

restrict anonymous

Some earlier dialects of SMB allowed requests to be sent without usernames. When this directive is set to yes, such anonymous requests are always rejected. If all of the clients run Windows NT/2000, restricting anonymous requests can provide some additional security. This directive defaults to no.

hide local users

Samba responds to several Microsoft-defined RPC calls, including those associated with the Security Accounts Manager (SAM). Some of these calls look up usernames from user IDs, or return lists of users who are in a given group. When this directive is set to yes, only users explicitly listed in the smbusers file are ever returned; local Unix users are hidden. The directive defaults to no.

Most of the authorization directives apply on a per-share basis, rather than globally. One set focuses on file permissions, and the other set focuses on user authorization. The permission directives include:

read only

Setting this directive to yes (or, equivalently, setting writeable, writable, or write ok to no) prevents users from writing to the share through SMB.

map archive

By default, this directive is set to yes, and Samba converts the DOS archive mode on files into the Unix user-execute permission. As a result, files created on the share through a Windows client are often created as executable, which at best is annoying, and at worst poses a potential security danger to the user if he accidentally executes a malicious file posing as a Windows document. Generally, it's wise to change this directive to no. There are similar map directives for the DOS system mode (map system) and hidden mode (map hidden) that map these modes to group- and world-executable permissions, but they default to no.

Modes, security modes, and forced modes

Typically, two sets of four directives control permissions for files and directories on a share.

The create mask (or create mode) directive specifies a bitmask that the server will combine (using a bitwise AND) with any mappings from DOS modes when a file is created. The effect of this directive is to prevent clients from creating files with particular permissions. It defaults to 0744, which prohibits clients from creating files with the group- or world-executable or group- or world-writable permissions.

After applying the create mask, the server applies the value of the force create mode directive using a bitwise OR. The effect of this directive is to specify permissions that will always be set when a file is created. It defaults to 0.

The security mask and force security mode directives work in a similar way to create mask and force create mask, but apply when a client is attempting to change the permissions on a file using the Windows NT security dialog box. They default to 0777 (client can change any permissions) and 0 (client is not forced to set any permissions when changing permissions).

A second set of four directives applies to directories rather than files. These include directory mask, force directory mode, directory security mask, and force directory security mode. They are analogous to their file counterparts, except that directory mask defaults to 0755.

inherit permissions

When this directive is set to yes, the create and directory masks and modes listed above no longer determine the permissions on newly created files and directories. Instead, permissions are inherited from the parent directory in which the file or directory is created. Newly created files inherit their read and write permissions from their parent directory, and newly created directories inherit the exact mode of their parent directory. This directive defaults to no.

veto files

Vetoed files are not accessible or visible to any client. The veto files directive specifies a set of patterns to match (using DOS-style wildcards) for files to veto, separated (and surrounded) by slashes. For example, to veto any files that start with a dot or end with a tilde, the directive would be set to /.*/*~/.

Vetoing files imposes a performance penalty on the Samba server, but provides strong protection against information leaking?if you can enumerate all the files that should be vetoed.

hide unreadable

Setting this directive to yes causes files that the user does not have permission to read to be inaccessible and invisible, as if they were vetoed. It defaults to no.

Directives that control per-share user authorization features include:

valid users, invalid users

These two directives control which users may log in to access the share. Each can be set to a comma-separated list of users, NIS netgroups (prefaced by the "&" character), Unix groups (prefaced by the "+" character), or NIS or Unix groups (prefaced by the "@" character). By default, any user who can authenticate himself can access a share. If any users are listed in the valid users directive, only those users can access the share (unless they also appear in the invalid users directive). Otherwise, any user that does not appear in the invalid users directive can access the share. Because user IDs are used to authorize file access, it may be wise to make system users like root and bin invalid, or to explicitly list valid users for each share.

guest account, guest ok, and guest only

A guest share does not require a password for access. The guest account directive sets the username that will be associated with guest access and used for permission checks for the share. Shares in which guest ok is set to yes permit access without passwords; shares in which guest only is also set to yes permit only access via the guest account. An anonymous FTP structure might be served to clients via Samba using a share like this:

security = user
map to guest = bad user

guest account = ftp
guest ok = yes
guest only = yes
read only = yes
valid users = ftp

Because we want to use the user security mode for other shares, we must use map to guest to ensure that any invalid login name is considered to be a guest login. For the anonftpdownload share, the guest login is mapped to the Unix user ftp, and only guest logins are permitted to access this share. The share is served read only, and as an extra protection, only the Unix user ftp is considered valid for accessing this share.

admin users

Any username listed in this directive will be permitted to access all files on the share as root. Accordingly, this directive is very dangerous and defaults to no. Data integrity and privacy

Samba can be compiled to support SSL-encrypted connections, present clients with a server certificate, to require clients to use SSL to connect, and even require clients to present valid SSL client certificates. When compiled with SSL, Samba's own client program, smbclient, can make secure connections and present certificates. Unfortunately, no version of the Windows SMB client uses SSL, so this feature is largely limited to connections between Samba clients and Samba servers.[26]

[26] Objective Development's commercial Unix SMB client Sharity also supports SSL connections to Samba servers. There is also a port of stunnel to Windows NT by Kai Engert that can be used to provide a Samba-compatible SSL wrapper around Windows's own SMB client and server.

15.6.5 Samba Client Security

With smbclient, Unix users can mount SMB shares and access their files. smbclient operates more like an FTP client than an NFS client, however. The shares are not actually mounted as filesystems. Instead, smbclient provides a means of transferring files between the Unix filesystem and a remote share. Accordingly, it offers fewer security concerns than NFS clients (and much less transparency in use).

The Linux 2.4 kernel does include native support for smbfs, SMB filesystems under Linux. Samba provides the associated user programs for mounting an SMB share under smbfs (smbmount). The commercial SMB client Sharity also mounts SMB filesystems much as NFS does. In these configurations, the same caveats apply to SMB filesystems as to those mounted through NFS.

Some BSD-based systems also support SMB in the kernel. You can mount SMB shares on the local filesystem with the mount_smbfs command.

Mac OS 10.2 and above include a native implementation of SMB that allows it to mount SMB file servers.

15.6.6 Improving Samba Security

Some of the techniques for improving NFS security also apply to Samba servers, but several recommendations are specific to Samba:

  • Limit the use of SMB by limiting the machines to which shares are exported. Limit which interfaces Samba listens on, and which hosts Samba will respond to.

  • Use a packet-filtering firewall to prevent NetBIOS and SMB traffic from passing out of your network.

  • Export shares read-only if possible.

  • Configure your network to use a NetBIOS name server for name registration and queries, rather than broadcast packets.

  • Do not map the archive bit to the Unix user-executable permission.

  • Do not share the server's executables.

  • Do not share home directories.

  • Do not allow users to log into the Samba server.

  • Do not provide guest shares; define valid users for each share and always require passwords.

  • Use user-, domain-, or server-level security rather than share-level security.

  • Enforce minimum protocol levels that prohibit plaintext passwords, and disallow anonymous requests.

  • Veto files that could leak important server information to users, and hide files that would be unreadable to the users.

    Part VI: Appendixes