By Michael Adam
As most Linux users know, Samba [1] is an open source file and print system that provides interoperability with Windows environments. For more that 15 years, Samba has managed configuration settings through the plain-text file smb.conf. With the release of Samba 3.2.0 in July 2008, this paradigm of plain-text-only configuration is no longer the only option. A new configuration back end can store the configuration data in Samba's internal registry database. The default behavior is the same as before, but if you explicitly enable registry-based configuration through smb.conf, you can manage your Samba settings through a Windows-style registry.
Registry-based configuration opens many new options, such as remote administration and administration of Samba from Windows computers.
Samba has always maintained a registry database so that Windows clients could access the registry over the WINREG RPC interface to retrieve information for the connection. (Figure 1 shows WINREG access of a Windows client connecting to a Windows server.) Until recently, however, Samba did not use the registry for any other purposes.
The conventional text-based configuration system (see the box titled "Traditional Samba") is very flexible, very convenient, and very easy to use. In fact, you can configure your Samba implementation with nothing more than your favorite text editor. However, some special use cases create new demands that reduce the effectiveness of the text configuration model.
Traditional Samba |
Samba's traditional plain-text configuration uses the very simple syntax of INI files well known to Windows users. This approach is also used by several Linux/Unix programs. The smb.conf configuration file consists of sections and parameters. The file format is line oriented: Each line represents a comment, a configuration parameter, or the beginning of a new section.
Sections can be started multiple times, and the same parameter can be specified several times. The last occurrence of a parameter in one section overrides earlier instances of it in the same section. The section [global] has a special meaning. Whereas all other sections define shared resources, the [global] section contains the parameters that control the overall behavior of the Samba daemon and the default values for the share parameters. The two other share names that have a special meaning are [homes] and [printers]. These sections dynamically create shares when they are configured appropriately. The manual page of the smb.conf configuration file has all the details on the syntax and the semantics. The text configuration can be structured with the meta directives include and config file. Whereas config file simply drops all configuration data read so far and switches the configuration source to the specified file, the include directive builds up a whole tree of config files. An include file is parsed when its include statement is encountered within the parent file. The options read from the included file are activated in place of the include file. This means that options read before the include could be overwritten by parameters inside the include; on the other hand, side parameters set inside the include can be overwritten by parameters that occur after the include. An interesting dynamic aspect is added with the possibility of expanding run-time macros in the configuration file. Table 1 shows some of the most important macros. These macros are useful for tasks such as configuring individual logging for specific clients. Listing 1 shows an example configuration file that demonstrates sections, comments, includes, and macros. It should be noted that the server reads the complete configuration at startup and builds up the list of shares. Then the server periodically checks to see whether one of the configuration files has changed and, if so, reloads the whole configuration. |
Listing 1: Sample smb.conf |
01 [global] 02 netbios name = fileserver 03 work group = samba 04 passdb backend = user 05 06 ; debugging options 07 log level = 3 08 max log size = 10000 09 debug hires timestamp = yes 10 11 # include client specific configuration 12 include = /etc/samba/smb.conf.%I 13 14 [homes] 15 valid users = %S 16 brosweable = no 17 writeable = yes 18 19 [share1] 20 path = /data/share1 21 read only = no |
One disadvantage that often appears on large networks is memory consumption: A client is only connected to one share, but the Samba daemon process that serves this connection builds up the entire list of shares the same. On a 64-bit machine, a share structure internally consumes about 1KB of memory. So when the configuration contains a thousand shares, the smbd daemon wastes around 1MB of RAM. When a thousand clients are connected to the server, 1GB of RAM is wasted.
Worse still, when the configuration file is changed, a thousand clients will start re-reading smb.conf, which will be some 250KB or more. All these near-simultaneous read operations will have a noticeable effect not only on the I/O performance of the server, but also on the CPU load because the thousand shares read from the file must be compared with and integrated into the internal list of shares already constructed the first time. These performance problems have hit production servers in the past, and admins have created workarounds, but these improvised solutions are just band-aids.
Usability issues include:
These disadvantages disappear when the configuration parameters are stored in a database. The cluster configuration would suggest a Trival Database (TDB) [3] structure, which could then be distributed to all cluster nodes automatically by CTDB [4]. The approach that had been started in 2007 and was officially released in July 2008 with Samba 3.2 is to use Samba's registry database, because it has a data model that fits pretty nicely on the schema of sections and parameters of smb.conf. Samba stores its registry in a TDB database called registry.tdb
The registry organizes its data in a tree structure of keys: a registry key consists of a name, a list of its subkeys, and a list of its registry values. A value comprises a name and the value data. Samba now stores the configuration data in the following registry key
HKLM\Software\Samba\smbconf
which is sometimes called the smbconf key. The sections in an smb.conf file correspond to the subkeys in this key; the configuration parameters match the registry values in the corresponding subkey.
One should imagine the contents of the smbconf key as a parsed but not otherwise interpreted or activated smb.conf file. Just like the smb.conf file syntax, the registry does not differentiate between the global section and the share definitions. Because the registry is a database with keys and values, it does not support a fixed order or multiple parameter records.
The include statements need special treatment - they are not configuration parameters as such, but meta directives that are activated at the time of parsing. An include directive can be specified multiple times with different values, and the order and placement of the real parameters are very important in this case. Because the parameters stored in the registry do not have a guaranteed order, registry configuration can only offer a compromise with respect to the treatment of include statements: For registry configuration, Samba maintains one ordered list of include statements per section that is only evaluated at the end of the section, after the parameters have been activated.
In current Samba code, the smb.conf text configuration file is still the initial source of configuration. The administrator can enable the registry configuration in three stages, always starting with smb.conf.
The parameter registry shares = yes in the [global] section of smb.conf tells Samba to read share definitions from the registry. In contrast to the text-based configuration, smbd does not read all registry-based share definitions when launching; it only picks up the individual shares at run time - a share is loaded just as the client connects to it.
This approach solves the memory consumption problem. If a share is defined in the registry and also in smb.conf, these definitions are not merged, and the text-based variant wins.
smbd does not pick this list up from the registry when launching, in contrast to shares defined in a configuration file, but loads it at run time. If shares with the same name are in the registry and in smb.conf, the text-based variant wins. So when registry shares are active, it is advisable not to use text-defined shares at all in order to avoid confusion.
A special new semantic for the directive include = registry in the [global] section of the smb.conf file, which is frequently used for clustering, mixes global registry options with the text-based configuration. The full semantics of the include statement are kept for the global options: parameters that occur before include = registry in smb.conf can be overwritten by registry parameters, and global parameters from the registry can be overwritten by global parameters from smb.conf that are specified after include = registry.
Setting include = registry implicitly activates registry shares. Be careful when you mix text and registry-based configurations - for example, the lock directory parameter is a sure-fire way of telling the registry to shoot itself in the foot because, among other things, it sets the location where Samba looks for its registry database.
The recommended way of using include = registry is to have an initial portion of configuration in the [global] section of smb.conf and conclude the section and the file with include = registry. Listing 2 shows a minimal configuration for use in clustered environments.
Listing 2: smb.conf for a Cluster |
01 [global] 02 clustering = yes 03 include = registry |
To change the whole configuration file using config file, admins can use a new meta directive, config backend = registry in the global section of smb.conf, to stipulate a registry-only configuration. This directive tells Samba to discard any settings it has parsed from smb.conf and rely entirely on the global parameters read from the registry. Again, the directive implies registry shares = yes.
A cluster setup faces the inherent chicken and egg problem: The registry is stored in the registry.tdb database, and CTDB has to distribute it across the cluster. To enable distribution of the registry, the administrator initially needs to configure Samba with the clustering = yes option set before registry globals are read. So unfortunately, the registry-only configuration with config backend = registry is not an option here. Instead, the admin should copy the minimal smb.conf file in Listing 2 as a default configuration to all cluster nodes once. Afterwards, the whole Samba cluster can be configured centrally through the registry.
Samba provides several approaches for editing the registry. Before you can modify the Samba registry, you need to enable remote access for your designated management account using the following command:
net rpc rights grant user SeDiskOperatorPrivilege
Because the registry is available remotely over the WINREG RPC interface when the Samba daemon smbd is running, the most obvious method of access is through the Windows registry editor regedit.exe (Figure 2).
The advantage of the registry editor is that it gives the Windows admin the opportunity to configure a samba server with familiar tools. But in the long run, this method will probably be too awkward, even for hard-core Windows addicts.
Samba's swiss army knife net basically has built-in command line versions of regedit: net registry to access the local registry and net rpc registry to access a remote registry over RPC. Although these tools are almost as clumsy as regedit, they do allow the administrator to produce more convenient custom tools with Unix shell scripts. Table 2 shows the available subcommands of net registry, and Listing 3 demonstrates an example of configuration tasks. The use of net rpc registry is completely analogous - you just call it as net -Uuser rpc registry ... or even net -Uuser%password rpc registry ... when it is too inconvenient to type the password at the prompt for each call.
Listing 3: Example net registry Session |
01 # net registry 02 enumerate HKLM/software/samba/smbconf 03 Keyname = share1 04 Modtime = Thu, 01 Jan 1970 01:00:00 CET 05 06 Keyname = global 07 Modtime = Thu, 01 Jan 1970 01:00:00 CET 08 09 # net registry enumerate HKLM/software/samba/smbconf/global 10 Valuename = netbios name 11 Type = REG_SZ 12 Value = "nirvana" 13 14 Valuename = workgroup 15 Type = REG_SZ 16 Value = "samba" 17 18 Valuename = security 19 Type = REG_SZ 20 Value = "user" 21 22 # net registry setvalue HKLM/software/samba/smbconf/global "passdb backend" SZ tdbsam 23 # net registry enumerate HKLM/software/samba/smbconf/global 24 Valuename = netbios name 25 Type = REG_SZ 26 Value = "nirvana" 27 28 Valuename = workgroup 29 Type = REG_SZ 30 Value = "samba" 31 32 Valuename = security 33 Type = REG_SZ 34 Value = "user" 35 36 Valuename = passdb backend 37 Type = REG_SZ 38 Value = "tdbsam" 39 40 # net registry deletevalue HKLM/software/samba/smbconf/global security 41 # net registry enumerate HKLM/software/samba/smbconf/global 42 Valuename = netbios name 43 Type = REG_SZ 44 Value = "nirvana" 45 46 Valuename = workgroup 47 Type = REG_SZ 48 Value = "samba" 49 50 Valuename = passdb backend 51 Type = REG_SZ 52 Value = "tdbsam" |
net registry is pretty chatty and clumsy for day-to-day administration tasks, so net now comes with a dedicated registry configuration interface offered by the new net conf command. Table 3 provides a summary of net conf options.
The net conf list command outputs the complete configuration in smb.conf format, whereas net conf import imports a smb.conf text file into the registry, dropping all previous data. This way, one can easily switch back and forth between registry- and text-based configuration if necessary (Listing 4).
Listing 4: Example net conf Session |
01 # net conf list 02 # cat smb.conf.input 03 [global] 04 netbios name = nirvana 05 workgroup = samba 06 passdb backend = tdbsam 07 security = user 08 09 [share1] 10 path = /data/samba/shares/share1 11 read only = no 12 vfs objects = recycle 13 14 # net conf import smb.conf.input 15 # net conf list 16 [global] 17 netbios name = nirvana 18 workgroup = samba 19 passdb backend = tdbsam 20 security = user 21 22 [share1] 23 path = /data/samba/shares/share1 24 read only = no 25 vfs objects = recycle 26 27 # net conf setparm global "log level" 10 28 # net conf delparm global security 29 # net conf setincludes global /etc/samba/smb.conf.%I 30 # net conf setparm share2 path /data/samba/shares/share2 31 # net conf list 32 [global] 33 netbios name = nirvana 34 workgroup = samba 35 passdb backend = tdbsam 36 log level = 10 37 include = /etc/samba/smb.conf.%I 38 39 [share1] 40 path = /data/samba/shares/share1 41 read only = no 42 vfs objects = recycle 43 44 [share2] 45 path = /data/samba/shares/share2 46 47 # net conf drop 48 # net conf list 49 # |
An abstraction layer called libsmbconf presents all necessary methods to access Samba's registry configuration from C code. net conf and the server use libsmbconf to access the registry. The Samba project site has more details on the API [5]. libsmbconf is not published as a shared library because of linking dependencies to a lot of Samba internal code that is not yet properly chopped into shared libraries. Eventually the idea is to release libsmbconf so that it's easy to write third-party applications to configure Samba. A first example application called netdomjoin-gui is available with the Samba code. netdomjoin-gui is a Gtk program that joins your Samba into an active directory domain, modifying the registry configuration accordingly. It is modeled on the native Windows join dialog. The code is under lib/netapi/examples/netdomjoin-gui in Samba's source tree.
To compile the application, use make -C lib/netapi/examples; afterwards, you will find the binary in lib/netapi/examples/bin/netdomjoin-gui. Starting with a smb.conf file that contains config backend = registry and an empty registry configuration, the administrator calls netdomjoin-gui (Figure 3). Listing 5 shows the registry configuration after the process is finished.
Listing 5: Registry Configuration after the Join |
01 [global] 02 workgroup = ADSVMW 03 security = ads 04 realm = ads.vmware.private |
With Samba 3.2 and newer, the administrator can choose between traditional text-based configuration and the new registry configuration that brings many new features and opens up many new options. Even though the configuration is stored in a database, net conf lets you manage the configuration easily. This feature is extremely convenient in clustered environments with CTDB. The new configuration system also allows for remote configuration of Samba servers.
With additional work, it will be possible to create dedicated Samba configuration tools for Windows that use the remote registry interface. Then a Windows admin could configure samba servers without learning too much about the underlying Unix systems. At that stage, you might wonder whether you have reached too much interoperability.
INFO |
[1] Samba project: http://www.samba.org/
[2] Samba team: http://www.samba.org/samba/team/ [3] TDB: http://tdb.samba.org/ [4] CTDB project: http://ctdb.samba.org [5] "Samba's New Registry Based Configuration" by Michael Adam http://www.samba.org/~obnox/presentations/linux-kongress-2008/lk2008-obnox.pdf |
THE AUTHOR |
Michael Adam is a member of the international Samba developer team [2] and also the maintainer of the Samba software branches with cluster extensions. He works as a software developer and consultant for SerNet GmbH in Göttingen, Germany. He spends his leisure time with his wonderful wife and kids. |