# Chapter 8. Advanced Disk Shares

This chapter continues our discussion of configuring Samba from Chapter 6. We will cover some more advanced issues regarding the integration of Unix and Windows filesystems, including hidden files, Unix links, file permissions, name mangling, case sensitivity of filenames, file locking, opportunistic locking (oplocks), connection scripts, supporting Microsoft Dfs (Distributed filesystem) shares, and using NIS home directories.

## Filesystem Differences

One of the biggest issues for which Samba has to correct is the difference between Unix and Microsoft filesystems. This includes items such as handling symbolic links, hidden files, and dot files. In addition, file permissions can also be a headache if not properly accounted for.

### Hiding and Vetoing Files

Sometimes you need to ensure that a user cannot see or access a file at all. Other times, you don't want to keep users from accessing a file—you just want to hide it when they view the contents of the directory. On Windows systems, an attribute of files allows them to be hidden from a folder listing. With Unix, the traditional way of hiding files in a directory is to use a dot (.) as the first character in the filename. This prevents items such as configuration files from being seen when performing an ordinary ls command. Keeping a user from accessing a file at all, however, involves working with permissions on files and directories.

The first option we should discuss is the Boolean `hide` `dot` `files`. When it is set to `yes`, Samba reports files beginning with a period (.) as having their hidden attribute set. If the user has chosen to show all hidden files while browsing (e.g., using the Folder Options menu item under the View menu in Windows 98), he will still be able to see the files, although his icons will appear "ghosted," or slightly grayed-out. If the client is configured not to show hidden files, the files will not appear at all.

Instead of simply hiding files beginning with a dot, you can also specify a string pattern to Samba for files to hide, using the `hide` `files` option. For example, let's assume you specified the following in our example `[data]` share:

>     [data]
>         hide files = /*.java/*README*/

Each entry for this option must begin, end, or be separated from another with a slash ( / ) character, even if only one pattern is listed. This convention allows spaces to appear in filenames. The slashes have nothing to do with Unix directories; they are instead acting as delimiters for the `hide` `files` values.

If you want to prevent users from seeing files completely, you can instead use the `veto` `files` option. This option, which takes the same syntax as the `hide` `files` option, specifies a list of files that should never be seen by the user. For example, let's change the `[data]` share to the following:

>     [data]
>         veto files = /*.java/*README*/

The syntax of this option is identical to the `hide` `files` configuration option: each entry must begin, end, or be separated from another with a slash (`/`) character, even if only one pattern is listed. If you do so, files that match the pattern, such as hello.java and README.txt, will simply disappear from the directory, and the user cannot access them through SMB.

We need to address one other question. What happens if the user tries to delete a directory that contains vetoed files? This is where the `delete` `veto` `files` option comes in. If this Boolean option is set to `yes`, the user can delete both the regular files and the vetoed files in the directory, and the directory itself is removed. If the option is set to `no`, the user cannot delete the vetoed files, and consequently the directory is not deleted either. From the user's perspective, the directory appears empty, but cannot be removed.

The `dont` `descend` directive specifies a list of directories whose contents Samba should not make visible. Note that we say contents, not the directory itself. Users can enter a directory marked as such, but they are prohibited from descending the directory tree any farther—they always see an empty folder. For example, let's use this option with a more basic form of the share that we defined earlier in the chapter:

>     [data]
>         dont descend = config defaults

In addition, let's assume that the /home/samba/data directory has the following contents:

>     drwxr-xr-x   6 tom      users     1024 Jun 13 09:24 .
>     drwxr-xr-x   8 root     root      1024 Jun 10 17:53 ..
>     -rw-r--r--   2 tom      users     1024 Jun  9 11:43 README
>     drwxr-xr-x   3 tom      users     1024 Jun 13 09:28 config
>     drwxr-xr-x   3 tom      users     1024 Jun 13 09:28 defaults
>     drwxr-xr-x   3 tom      users     1024 Jun 13 09:28 market

If the user then connects to the share, she would see the directories in the share. However, the contents of the /config and /defaults directories would appear empty to her, even if other folders or files existed in them. In addition, users cannot write any data to the folder (which prevents them from creating a file or folder with the same name as one that is already there but invisible). If a user attempts to do so, she will receive an "Access Denied" message. The `dont` `descend` option is an administrative option—not a security option—and is not a substitute for good file permissions.

### Links

When a client tries to open a symbolic link on a Samba server share, Samba attempts to follow the link to find the real file and let the client open it, as if the user were on a Unix machine. If you don't want to allow this, set the `follow` `symlinks` option like this:

>     [data]
>         follow symlinks = no

You can test this by setting up and trying to access a symbolic link. Create a directory on the Unix server inside the share, acting as the user under which you will log in to Samba. Enter the following commands:

>     $ echo "This is a test" >hello.txt
>     $ ln -s hello.txt hello-link.txt

This results in the text file hello.txt and a symbolic link to it called hello-link.txt. Normally, if you double-click either one, you will receive a file that has the text "This is a test" inside of it. However, with the `follow` `symlinks` option set to `no`, you will receive an error dialog if you double-click hello-link.txt.

The `wide` `links` option, if set to `no`, prevents the client user from following symbolic links that point outside the shared directory tree. For example, let's assume that we modified the `[data]` share as follows:

>     [data]
>         follow symlinks = yes
>         wide links = no

As long as the `follow` `symlinks` option is disabled, Samba will refuse to follow any symbolic links outside the current share tree. If we create a file outside the share (for example, in someone's home directory) and then create a link to it in the share as follows:

>     ln -s ~tom/datafile ./datafile

the client cannot open the file in Tom's home directory.

### Filesystem Options

Table 8-1 shows a breakdown of the options we discussed earlier. We recommend the defaults for most, except those listed in the following descriptions.

#### Table 8-1. Filesystem configuration options

Option | Parameters | Function | Default | Scope
--- | --- | --- | --- | ---
`dont descend` | string (list of directories) | Indicates a list of directories whose contents Samba should make invisible to clients. | None | Share
`follow` `symlinks` | Boolean | If set to `no`, will not honor symbolic links. | `yes` | Share
`getwd cache` | Boolean | If set to `yes`, will use a cache for `getwd( )` calls. | `yes` | Global
`wide links` | Boolean | If set to `yes`, will follow symbolic links outside the share. | `yes` | Share
`hide dot files` | Boolean | If set to `yes`, treats Unix hidden files as hidden files in Windows. | `yes` | Share
`hide files` | string (list of files) | List of file patterns to treat as hidden. | None | Share
`veto files` | string (list of files) | List of file patterns to never show. | None | Share
`delete veto` `files` | Boolean | If set to `yes`, will delete files matched by `veto files` when the directory they reside in is deleted. | `no` | Share

### dont descend

The `dont` `descend` option can be used to specify various directories that should appear empty to the client. Note that the directory itself will still appear. However, Samba will not show any of the contents of the directory to the client user. This is not a good option to use as a security feature; it is really meant only as a convenience to keep users from casually browsing into directories that might have sensitive files. See our example earlier in this section.

### follow symlinks

This option controls whether Samba will follow a symbolic link in the Unix operating system to the target or if it should return an error to the client user. If the option is set to `yes`, the target of the link will be interpreted as the file. If set to `no`, an error will be generated if the symbolic link is accessed.

### getwd cache

This global option specifies whether Samba should use a local cache for the Unix getwd( ) ( get current working directory) system call. You can override the default value of `yes` as follows:

>     [global]
>         getwd cache = no

Setting this option to `no` can significantly increase the time it takes to resolve the working directory, especially if the `wide` `links` option is set to `no`. You should normally not need to alter this option.

### wide links

This option specifies whether the client user can follow symbolic links that point outside the shared directory tree. This includes any files or directories at the other end of the link, as long as the permissions are correct for the user. The default value for this option is `yes`. Note that this option will not be honored if the `follow` `symlinks` options is set to `no`. Setting this option to `no` slows smbd considerably because it will have to check each link it encounters.

### hide dot files

The `hide` `dot` `files` option hides any files on the server that begin with a dot (.) character to mimic the functionality behind several shell commands that are present on Unix systems. Like `hide` `files`, those files that begin with a dot have the DOS hidden attribute set, which doesn't guarantee that a client cannot view them. The default value for this option is `yes`.

### hide files

The `hide` `files` option provides one or more directory or filename patterns to Samba. Any file matching this pattern will be treated as a hidden file from the perspective of the client. Note that this simply means that the DOS hidden attribute is set, which might or might not mean that the user can actually see it while browsing.

Each entry in the list must begin, end, or be separated from another entry with a slash (`/`) character, even if only one pattern is listed. This allows spaces to appear in the list. Asterisks can be used as a wildcard to represent zero or more characters. Questions marks can be used to represent exactly one character. For example:

>     hide files = /.jav*/README.???/

### veto files

More stringent than the hidden files state is the state provided by the `veto` `files` configuration option. Samba won't even admit these files exist. You cannot list or open them from the client. This should not be used as a means of implementing security. It is actually a mechanism to keep PC programs from deleting special files, such as ones used to store the resource fork of a Macintosh file on a Unix filesystem. If both Windows and Macs are sharing the same files, this can prevent ill-advised power users from removing files the Mac users need.

The syntax of this option is identical to that of the `hide` `files` configuration option: each entry must begin, end, or be separated from another with a slash ( / ) character, even if only one pattern is listed. Asterisks can be used as a wildcard to represent zero or more characters. Question marks can be used to represent exactly one character. For example:

>     veto files = /*config/*default?/

This option is primarily administrative and is not a substitute for good file permissions.

### delete veto files

This option tells Samba to delete vetoed files when a user attempts to delete the directory in which they reside. The default value is `no`. This means that if a user tries to delete a directory that contains a vetoed file, the file (and the directory) will not be deleted. Instead, the directory remains and appears empty from the perspective of the user. If set to `yes`, the directory and the vetoed files will be deleted.

## File Permissions and Attributes on MS-DOS and Unix

Originally, DOS was not intended to be a multiuser, networked operating system. Unix, on the other hand, was designed for multiple users from the start. Consequently, Samba must not only be aware of, but also provide special solutions for, inconsistencies and gaps in coverage between the two filesystems. One of the biggest gaps is how Unix and DOS handle permissions on files.

Let's take a look at how Unix assigns permissions. All Unix files have read, write, and execute bits for three classifications of users: owner, group, and world. These permissions can be seen at the extreme lefthand side when an ls -al command is issued in a Unix directory. For example:

>     -rwxr--r--   1 tom     users   2014 Apr 13 14:11 access.conf

Windows, on the other hand, has four principal bits that it uses with any file: read-only, system, hidden, and archive. You can view these bits by right-clicking the file and choosing the Properties menu item. You should see a dialog similar to Figure 8-1.[1]

#### Figure 8-1. DOS and Windows file properties

The definition of each bit follows:

Read-only

  The file's contents can be read by a user but cannot be written to.

System

  This file has a specific purpose required by the operating system.

Hidden

  This file has been marked to be invisible to the user, unless the operating system is explicitly set to show it.

Archive

  This file has been touched since the last DOS backup was performed on it.

Note that there is no bit to specify that a file is executable. DOS and Windows NT filesystems identify executable files by giving them the extensions .exe, .com, .cmd, or .bat.

Consequently, there is no use for any of the three Unix executable bits that are present on a file in a Samba disk share. DOS files, however, have their own attributes that need to be preserved when they are stored in a Unix environment: the archive, system, and hidden bits. Samba can preserve these bits by reusing the executable permission bits of the file on the Unix side—if it is instructed to do so. Mapping these bits, however, has an unfortunate side effect: if a Windows user stores a file in a Samba share, and you view it on Unix with the ls -al command, some of the executable bits won't mean what you'd expect them to.

Three Samba options decide whether the bits are mapped: `map` `archive`, `map` `system` , and `map` `hidden`. These options map the archive, system, and hidden attributes to the owner, group, and world execute bits of the file, respectively. You can add these options to the `[data]` share, setting each of their values as follows:

>     [data]
>         map archive = yes
>         map system = yes
>         map hidden = yes

After that, try creating a file in the share under Unix—such as hello.java—and change the permissions of the file to 755. With these Samba options set, you should be able to check the permissions on the Windows side and see that each of the three values has been checked in the Properties dialog box. What about the read-only attribute? By default, Samba sets this whenever a file does not have the Unix owner write permission bit set. In other words, you can set this bit by changing the permissions of the file to 555.

The default value of the `map` `archive` option is `yes`, while the other two options have a default value of `no`. This is because many programs do not work properly if the archive bit is not stored correctly for DOS and Windows files. The system and hidden attributes, however, are not critical for a program's operation and are left to the discretion of the administrator.

Figure 8-2 summarizes the Unix permission bits and illustrates how Samba maps those bits to DOS attributes. Note that the group read/write and world read/write bits do not directly translate to a DOS attribute, but they still retain their original Unix definitions on the Samba server.

#### Figure 8-2. How Samba and Unix view the permissions of a file

### Creation Masks

File and directory creation masks are similar to umasks you have probably encountered while working with Unix systems. They are used to help define the permissions that will be assigned to a file or directory at the time it is created. Samba's masks work differently in that the bits that can be set are set in the creation mask, while in Unix umasks, the bits cannot be set are set in the umask. We think you will find Samba's method to be much more intuitive. Once in a while you might need to convert between a Unix umask and the equivalent Samba mask. It is simple: one is just the bitwise complement of the other. For example, an octal umask of 0022 has the same effect as a Samba mask of 0755.

Unix umasks are set on a user-by-user basis, usually while executing the GUI's or command-line shell's startup scripts. When users connect to a Samba share from a network client, these scripts are not executed, so Samba supplies the ability to set the creation masks for files and directories. By default, this is done on a share-by-share basis, although you can use the `include` parameter in the Samba configuration file (as explained in Chapter 6) to assign masks on a user-by-user basis, thus matching conventional Unix behavior.

To show how Samba's create masks work, suppose we have a Windows Me user connecting to his Unix home directory through Samba, and Samba is configured with `create` `mask` `=` `777` in the `[homes]` share. With this value, `create` `mask` will not affect the bits that are set on new files. If the user creates a file with Wordpad, it will appear in the Unix filesystem like this:

>     $ ls -l file.doc
>     -rwxrw-rw-    1 jay      jay             0 Sep 21 11:02 file.doc

Wordpad created the file with read/write permissions (i.e., the MS-DOS read-only attribute was not set), so Samba mapped the MS-DOS attributes to Unix read/write permissions for user, group, and other. The execute bit is set for the owner because by default, the `map` `archive` parameter is set to `yes`. The other execute bits are not set because `map` `system` and `map` `hidden` are set to `no` by default. You can customize this behavior as you see fit, and unless you do backups from MS-DOS or Windows systems, you might want to specify `map` `archive` `=` `no` to avoid Windows files from appearing as executables on the Unix system.

Now suppose we set `create` `mask` to have an effect. For example:

>     [homes]
>         create mask = 664

This is equivalent to a Unix umask of 113. If the user creates the Wordpad document as before, it will show up as:

>     $ ls -l file.doc
>     -rw-rw-r--    1 jay      jay             0 Sep 22 16:38 file.doc

Comparing this to the previous example, notice that not only has the write permission for other disappeared as we expected, but so has the execute permission for owner. This happened because the value of `create` `mask` logically ANDs the owner's permissions with a 6, which has masked off the execute bit. The lesson here is that if you want to enable any of `map` `archive`, `map` `system`, or `map` `hidden`, you must be careful not to mask off the corresponding execute bit with your `create` `mask`.

The `directory` `mask` option works similarly, masking permissions for newly created directories. The following example will allow the permissions of a newly created directory to be, at most, 755:

>     [data]
>         directory mask = 755

Also, you can force various bits with the `force` `create` `mode` and `force` `directory` `mode` options. These options will perform a logical OR against the file and directory creation masks, ensuring that those bits that are specified will always be set. You would typically set these options globally to ensure that group and world read/write permissions have been set appropriately for new files or directories in each share.

In the same spirit, if you wish to set explicitly the Unix user and group attributes of a file created on the Windows side, you can use the `force` `user` and `force` `group` options. For example:

>     [data]
>         create mask = 744
>         directory mask = 755
>         force user = joe
>         force group = accounting

These options assign the same Unix username and group to every client that connects to the share. However, this occurs after the client authenticates; it does not allow free access to a share. These options are frequently used for their side effects of assigning a specific user and group to each new file or directory that is created in a share. Use these options with discretion.

Finally, one of the capabilities of Unix that DOS lacks is the ability to delete a read-only file from a writable directory. In Unix, if a directory is writable, a read-only file in that directory can still be removed. This could permit you to delete files in any of your directories, even if the file was left by someone else.

DOS filesystems are not designed for multiple users, and so its designers decided that read-only means "protected against accidental change, including deletion," rather than "protected against some other user on a single-user machine." So the designers of DOS prohibited removal of a read-only file. Even today, Windows filesystems exhibit the same behavior.

Normally, this is harmless. Windows programs don't try to remove read-only files because they know it's a bad idea. However, a number of source-code control programs—which were first written for Unix—run on Windows and require the ability to delete read-only files. Samba permits this behavior with the `delete` `readonly` option. To enable this functionality, set the option to `yes`:

>     [data]
>         delete readonly = yes

### File and Directory Permission Options

The options for file and directory permissions are summarized in Table 8-2; each option is then described in detail.

#### Table 8-2. File and directory permission options

Option | Parameters | Function | Default | Scope
--- | --- | --- | --- | ---
`create mask` `(create mode)` | numeric | Maximum permissions for files created by Samba. | `0744` | Share
`directory mask` `(directory mode)` | numeric | Maximum permissions for directories created by Samba. | `0744` | Share
`force create mode` | numeric | Forces the specified permissions (bitwise `or`) for directories created by Samba. | `0000` | Share
`force directory` `mode` | numeric | Forces the specified permissions (bitwise `or`) for directories created by Samba. | `0000` | Share
`force group` `(group)` | string ( group name) | Effective group for a user accessing this share. | None | Share
`force user` | string (username) | Effective username for a user accessing this share. | None | Share
`delete readonly` | Boolean | Allows a user to delete a read-only file from a writable directory. | `no` | Share
`map archive` | Boolean | Preserve DOS archive attribute in user execute bit (0100). | `yes` | Share
`map system` | Boolean | Preserve DOS system attribute in group execute bit (0010). | `no` | Share
`map hidden` | Boolean | Preserve DOS hidden attribute in world execute bit (0001). | `no` | Share
`inherit permissions` | Boolean | If `yes`, permissions on new files and directories are inherited from parent directory. | no | Share

### create mask

The argument for this option is an octal number indicating which permission flags can be set at file creation by a client in a share. The default is 0744, which means that the Unix owner can at most read, write, and optionally execute her own files, while members of the user's group and others can only read or execute them. If you need to change it for nonexecutable files, we recommend 0644, or `rw-r--r--`. Keep in mind that the execute bits can be used by the server to map certain DOS file attributes, as described earlier. If you're altering the create mask, those bits have to be part of the create mask as well.

### directory mask

The argument for this option is an octal number indicating which permission flags can be set at directory creation by a client in a share. The default is 0744, which allows everyone on the Unix side to, at most, read and traverse the directories, but allows only you to modify them. We recommend the mask 0750, removing access by "the world."

### force create mode

This option sets the permission bits that Samba will set when a file permission change is made. It's often used to force group permissions, as mentioned previously. It can also be used to preset any of the DOS attributes we mentioned: archive (0100), system (0010), or hidden (0001).

> #### TIP

> When saving documents, many Windows applications rename their datafiles with a .bak extension and create new ones. When the files are in a Samba share, this changes their ownership and permissions so that members of the same Unix group can't edit them. Setting `force` `create mode = 0660` will keep the new file editable by members of the group.

### force directory mode

This option sets the permission bits that Samba will set when a directory permission change is made or a directory is created. It's often used to force group permissions, as mentioned previously. This option defaults to 0000 and can be used just like the `force` `create` `mode` to add group or other permissions if needed.

### force group

This option, sometimes called `group`, assigns a static group ID that will be used on all connections to a share after the client has successfully authenticated. This assigns a specific group to each new file or directory created from an SMB client.

### force user

The `force` `user` option assigns a static user ID that will be used on all connections to a share after the client has successfully authenticated. This assigns a specific user to each new file or directory created from an SMB client.

### delete readonly

This option allows a user to delete a directory containing a read-only file. By default, DOS and Windows will not allow such an operation. You probably will want to leave this option turned off unless a program (for example, an RCS program) needs this capability; many Windows users would be appalled to find that they'd accidentally deleted a file that they had set as read-only.

### map archive

The DOS archive bit is used to flag a file that has been changed since it was last archived (e.g., backed up with the DOS archive program). Setting the Samba option `map` `archive` `=` `yes` maps the DOS archive flag to the Unix execute-by-owner (0100) bit. It's best to leave this option on if your Windows users are doing their own backups or are using programs that require the archive bit. Unix lacks the notion of an archive bit entirely. Backup programs typically keep a file that lists what files were backed up on what date, so comparing file-modification dates serves the same purpose.

Setting this option to `yes` causes an occasional surprise on Unix when a user notices that a datafile is marked as executable, but rarely causes harm. If a user tries to run it, he will normally get a string of error messages as the shell tries to execute the first few lines as commands. The reverse is also possible; an executable Unix program looks like it hasn't been backed up recently on Windows. But again, this is rare and usually harmless.

For map archive to work properly, the execute bit for owner must not be masked off with the `create` `mask` parameter.

### map system

The DOS system attribute indicates files that are required by the operating system and should not be deleted, renamed, or moved without special effort. Set this option only if you need to store Windows system files on the Unix fileserver. Executable Unix programs will appear to be nonremovable, special Windows files when viewed from Windows clients. This might prove mildly inconvenient if you want to move or remove one. For most sites, however, this is fairly harmless.

For map archive to work properly, the execute bit for group must not be masked off with the `create` `mask` parameter.

### map hidden

DOS uses the hidden attribute to indicate that a file should not ordinarily be visible in directory listings. Unix doesn't have such a facility; it's up to individual programs (notably, the shell) to decide what to display and what not to display. Normally, you won't have any DOS files that need to be hidden, so the best thing to do is to leave this option turned off.

Setting this option to `yes` causes the server to map the hidden flag onto the executable-by-others bit (0001). This feature can produce a rather startling effect. Any Unix program that is executable by world seems to vanish when you look for it from a Windows client. If this option is not set, however, and a Windows user attempts to mark a file hidden on a Samba share, it will not work—Samba has no place to store the hidden attribute!

For map archive to work properly, the execute bit for other must not be masked off with the `create` `mask` parameter.

### inherit permissions

When the `inherit` `permissions` option is set to `yes`, the `create` `mask`, `directory` `mask`, `force` `create` `mode`, and `force` `directory` `mode` are ignored. The normal behavior of setting the permissions on newly created files is overridden such that the new files and directories take on permissions from their parent directory. New directories will have exactly the same permissions as the parent, and new files will inherit the read and write bits from the parent directory, while the execute bits are determined as usual by the values of the `map` `archive`, `map` `hidden`, and `map` `system` parameters.

By default, this option is set to `no`.

## Windows NT/2000/XP ACLs

Unix and Windows have different security models, and Windows NT/2000/XP has a security model that is different from Windows 95/98/Me. One area in which this is readily apparent is file protections. On Unix systems, the method used has traditionally been the 9-bit "user, group, other" system, in which read, write, and execute bits can be set separately for the owner of the file, the groups to which the owner belongs, and everyone else, respectively.

Windows 95/98/Me has a file-protection system that is essentially no protection at all. This family of operating systems was developed from MS-DOS, which was implemented as a non-networked, single-user system. Multiuser security simply was never added. One apparent exception to this is user-level security for shared files, which we will discuss in Chapter 9. Here, separate access permissions can be assigned to individual network client users or groups. However, user-level security on Windows 95/98/Me systems requires a Windows NT/2000 or Samba server to perform the actual authentication.

On Windows NT/2000/XP, user-level security is an extension of the native file security model, which involves access control lists (ACLs). This system is somewhat more extensive than the Unix security model, allowing the access rights on individual files to be set separately for any number of individual users and/or any number of arbitrary groups of users. Figure 8-3, Figure 8-4, and Figure 8-5 show the dialog boxes on a Windows 2000 system in which the ACL is set for a file. By right-clicking a file's icon and selecting Properties, then selecting the Security tab, we get to the dialog box shown in Figure 8-3. Here, we can set the basic permissions for a file, which are similar to Unix permissions, although not identical.

#### Figure 8-3. The Security tab of the file Properties dialog

By clicking the Advanced tab, we can bring up the dialog box shown in Figure 8-4, which shows the list of access control entries (ACEs) in the ACL. In this dialog, ACEs can be added to or deleted from the ACL, or an existing ACE can be viewed and modified. Each ACE either allows or denies a set of permissions for a specific user or group.

#### Figure 8-4. The Permissions tab of the Access Control Settings dialog

#### Figure 8-5. Permission Entry dialog, showing the settings of an ACE

Figure 8-5 shows the dialog box for adding an ACE. As you can see, there are more options for permissions in an ACL than with the permission bits on typical Unix systems. You can learn more about these settings in Essential Windows NT System Administration, published by O'Reilly.

In a networked environment where a Samba server is serving files to Windows NT/2000/XP clients, Samba has to map Unix permissions for files and directories to Windows NT/2000/XP access control lists. When a Windows NT/2000/XP client accesses a shared file or directory on a Samba server, Samba translates the object's ownership, group, and permissions into an ACL and returns them to the client.

Figure 8-6 shows the Properties dialog box for the file shopping_list.doc that resides on the Samba server.

#### Figure 8-6. The Properties dialog for a file on the Samba server

From Unix, this file appears as:

>     $ ls -l shopping_list.doc
>     -rw-------    1 adilia   users          49 Mar 29 11:58 shopping_list.doc

Notice that because the file has read permissions for the owner, the Read-only checkbox will show as cleared, even though the user on the Windows client (who is not `adilia` in this example) does not have read access permissions. The checkboxes here show only DOS attributes. By clicking the Security tab, we can start to examine the ACLs, as shown in Figure 8-7.

#### Figure 8-7. The Security tab of the Properties dialog for a file on the Samba server

The owner of the file (`adilia`) is shown as one entry, while the group (`users`) and other permissions are presented as the groups called `users` and `Everyone`. Clicking one of the items in the upper windows causes the simplified view of the permissions in that item to appear in the bottom window. Here, the read/write permissions for `adilia` appear in a manner that makes the security model of Unix and Windows seem similar. However, clicking the Advanced . . . button brings up the additional dialog box shown in Figure 8-8.

#### Figure 8-8. The Access Control Settings dialog for a file on the Samba server

In this dialog box, we see the actual ACL of the file. The ACEs for `users` and `Everyone` are listed with Take Ownership in the Permission column. This is a trick used by Samba for ACLs that have no permissions on the Unix side. On Windows, an ACL with nothing set results in no ACL at all, so Samba sets the Take Ownership permission to make sure that all the ACLs corresponding to the Unix "user, group, other" permissions will show up on Windows. The Take Ownership permission has no corresponding Unix attribute, so the setting on Windows does not affect the actual file on the Unix system in any way. Although Windows client users might be misled into thinking they can take ownership of the file (that is, change the ownership of the file to themselves), an actual attempt to do so will fail.

The Permissions column for the `adilia` ACL is listed as Special because Samba reports permissions for the file that do not correspond to settings for which Windows has a more descriptive name. Clicking the entry and then clicking the View/Edit . . . button brings up the dialog box shown in Figure 8-9, in which the details of the ACL permissions can be viewed and perhaps modified.

#### Figure 8-9. Permission Entry dialog for a file served by Samba

We say "perhaps" here because checking or unchecking boxes in this dialog box might not result in settings that Samba is able to map back into the Unix security model. When a user attempts to modify a setting (either permissions or ownership) that she does not have authority to change, or does not correspond to a valid setting on the Unix system, Samba will respond with an error dialog or by quietly ignoring the unmappable settings.

The ACLs for a directory are slightly different. Figure 8-10 shows the ACL view after clicking the Advanced button.

#### Figure 8-10. The Access Control Settings dialog for a directory on the Samba server

Here, there are two ACLs each for `users` and `Everyone`. One ACL specifies the permissions for the directory itself, and the other specifies permissions for the directory's contents. When changing settings in the View/Edit... dialog, there is an extra drop-down menu to apply the settings either to just the directory or to some combination of the directory and the files and directories it contains. If settings are applied to more than just the directory, Samba will match the behavior of a Windows server and change the permissions on the contents of the directory, as specified in the dialog.

### Unix ACLs

In most cases, users of Windows clients will find the Unix security model to be sufficient. However, in some cases, people might want the Samba server to support the full Windows ACL security model. Even if they don't need the fine-grained control over file and directory permissions, they might find Samba's translation between ACLs and Unix permissions to be a source of confusion or frustration.

When the underlying Unix host operating system supports POSIX.1e ACLs, Samba provides much better support of Windows NT/2000/XP ACLs. Versions of Unix that offer the necessary support include the following:

- Solaris 2.6 and later

- SGI Irix

- Linux, with Andreas Grünbacher's kernel patch from http://acl.bestbits.at that adds ACL support to the Linux ext2 and ext3 filesystems

- Linux, with the XFS filesystem

- AIX

- FreeBSD 5.0 and later

- HP/UX 11.0 and later, with the JFS 3.3 filesystem layout Version 4

If you are fortunate enough to have a Unix host operating system with ACL support already provided, all you need to do is recompile Samba using the `--with-acl-support` configure option, as we described in Chapter 2. If you are running Linux and need to patch your kernel, things are much more complicated. We suggest you refer to the documentation that comes with the patch for details on using it.

### Configuration Options for ACLs

Table 8-3 shows the Samba configuration options for working with Windows NT/2000/XP access control lists.

#### Table 8-3. ACL configuration options

Option | Parameters | Function | Default | Scope
--- | --- | --- | --- | ---
`nt acl support` | Boolean | If `yes`, allows users on Windows NT/2000/XP clients to modify ACL settings | `yes` | Share
`security mask` | numeric | Bitmask that allows or denies permission settings on files | `0777` | Share
`force security` `mode` | numeric | Bits that are always set when modifying file permissions | `0000` | Share
`directory` `security mask` | numeric | Bitmask that allows or denies permission settings on directories | `0777` | Share
`force directory` `security mode` | numeric | Bits that are always set when modifying directory permissions | `0000` | Share

### nt acl support

This parameter defaults to `yes`, which allows users on Windows NT/2000/XP clients to modify ACL settings for files on the Samba server. When set to `no`, files show up as owned by `Everyone`, with permissions appearing as "Full Control". However, actual ownership and permissions are enforced as whatever they are set to on the Samba server, and the user on the Windows client cannot view or modify them with the dialog boxes used for managing ACLs.

When enabled, support for Windows NT/2000/XP ACLs is limited to whatever ownerships and permissions can map into valid users and permissions on the Samba server. If the server supports ACLs (either "out of the box" or with an additional patch to enhance the filesystem), Samba's ACL support more closely matches that of a Windows NT/2000/XP server.

### security mask

Using the `security` `mask` option, it is possible to define which file permissions users can modify from Windows NT/2000/XP clients. This is for files only and not directories, which are handled with the `directory` `security` `mask` option. The parameter is assigned a numeric value that is a Unix-style permissions mask. For bits in the mask that are set, the client can modify the corresponding bits in the files' permissions. If the bit is zero, the client cannot modify that permission. For example, if `security` `mask` is set as:

>     [data]
>         security mask = 0777

the client can modify all the user/group/other permissions for the files in the share. This is the default. A value of `0` would deny clients from changing any of the permissions, and setting `security` `mask` as:

>     [data]
>         security mask = 0666

would allow client users to modify the read and write permissions, but not the execute permissions.

Do not count on `security` `mask` for complete control because if the user can access the files on the Samba server through any other means (for example, by logging directly into the Unix host), he can modify the permissions using that method.

### force security mode

The `force` `security` `mode` option can be used to define a set of permissions that are always set whenever the user on a Windows NT/2000/XP client modifies a file's permissions. (See the `force` `directory` `security` `mode` option for handling directories.)

Be careful to understand this properly. The mask given as the parameter's value is not necessarily equal to the resulting permissions on the file. The permissions that the client user attempts to modify are logically OR'd with the `force` `security` `mode` `mask` option, and any bits that are turned on will cause the file's corresponding permissions to be set. As an example, suppose `force` `security` `mode` is set in a share thusly:

>     [data]
>         force security mode = 0440

(This sets the read bit for owner and group, but not other.) If a user on a Windows NT/2000/XP client modifies an ACL on a file in the `[data]` share and attempts to remove all read permissions, the read permission for other (`Everyone`) will be removed, but the read permission for the owner and group will remain. Note that this parameter cannot force a permission bit to be turned off.

As with the `security` `mask` option, if a user can access the files in the share through any means other than Samba, she can easily work around Samba's enforcement of this parameter.

The default value of `force` `security` `mode` is `0000`, which allows users to remove any permission from files.

### directory security mask

This option works exactly the same as the `security` `mask` option, except that it operates on directories rather than files. As with `security` `mask`, it has a default value of `0777`, which allows Windows NT/2000/XP client users to modify all Unix permissions on directories in the share.

### force directory security mode

This option works exactly the same as the `force` `security` `mode` option, except that it operates on directories rather than files. It also has a default value of `0000`, which allows Windows NT/2000/XP client users to remove any permissions from directories in the share.

## Name Mangling and Case

Back in the days of DOS and Windows 3.1, every filename was limited to eight uppercase characters, followed by a dot, and three more uppercase characters. This was known as the 8.3 format and was a huge nuisance. Windows 95/98/Me, Windows NT/2000/XP, and Unix have since relaxed this problem by allowing longer, sometimes case-sensitive, filenames. Table 8-4 shows the current naming state of several popular operating systems.

#### Table 8-4. Operating system filename limitations

Operating system | File-naming rules
--- | ---
DOS 6.22 or below | Eight characters followed by a dot followed by a three-letter extension (8.3 format); case-insensitive
Windows 3.1 for Workgroups | Eight characters followed by a dot followed by a three-letter extension (8.3 format); case-insensitive
Windows 95/98/Me | 255 characters; case-insensitive but case-preserving
Windows NT/2000/XP | 255 characters; case-insensitive but case-preserving
Unix | 255 characters; case-sensitive

Samba still has to remain backward-compatible with network clients that store files in just the 8.3 format, such as Windows for Workgroups. If a user creates a file on a share called antidisestablishmentarianism.txt, a Windows for Workgroups client cannot tell it apart from another file in the same directory called antidisease.txt. Like Windows 95/98/Me and Windows NT/2000/XP, Samba has to employ a special method for translating a long filename to an 8.3 filename in such a way that similar filenames will not cause collisions. This is called name mangling, and Samba deals with this in a manner that is similar, but not identical to, Windows 95 and its successors.

### The Samba Mangling Operation

Here is how Samba mangles a long filename into an 8.3 filename:

- If the original filename does not begin with a dot, the first five characters before the dot (if there is one) are converted to uppercase. These characters are used as the first five characters of the 8.3 mangled filename.

- If the original filename begins with a dot, the dot is removed and then the previous step is performed on what is left.

- These characters are immediately followed by a special mangling character: by default, a tilde (~), although Samba allows you to change this character.

- The base of the long filename before the last period is hashed into a two-character code; parts of the name after the last dot can be used if necessary. This two-character code is appended to the filename after the mangling character.

- The first three characters after the last dot (if there is one) of the original filename are converted to uppercase and appended onto the mangled name as the extension. If the original filename began with a dot, three underscores ( `_ _ _` ) are used as the extension instead.

Here are some examples:

>     virtuosity.dat                       VIRTU~F1.DAT
>     .htaccess                            HTACC~U0._ _ _
>     hello.java                           HELLO~1F.JAV
>     team.config.txt                      TEAMC~04.TXT
>     antidisestablishmentarianism.txt     ANTID~E3.TXT
>     antidisease.txt                      ANTID~9K.TXT

Using these rules will allow Windows for Workgroups to differentiate the two files on behalf of the poor individual who is forced to see the network through the eyes of that operating system. Note that the same long filename should always hash to the same mangled name with Samba; this doesn't always happen with Windows. The downside of this approach is that there can still be collisions; however, the chances are greatly reduced.

You generally want to use the mangling configuration options with only the oldest clients. We recommend doing this without disrupting other clients by adding an `include` directive to the smb.conf file:

>     [global]
>         include = /usr/local/samba/lib/smb.conf.%a

This resolves to smb.conf.WfWg when a Windows for Workgroups client attaches. Now you can create a file /usr/local/samba/lib/smb.conf.WfWg, which might contain these options:

>     [global]
>         case sensitive = no
>         default case = upper
>         preserve case = no
>         short preserve case = no
>         mangle case = yes
>         mangled names= yes

If you are not using Windows for Workgroups, you probably do not need to change any of these options from their defaults.

### Representing and resolving filenames with Samba

Another item that we should point out is that there is a difference between how an operating system represents a file and how it resolves it. For example, you have likely run across a file on a Windows system called README.TXT. The file can be represented by the operating system entirely in uppercase letters. However, if you open an MS-DOS command prompt and enter the command:

>     C:\> notepad readme.txt

the all-caps file is loaded into the editing program, even though you typed the name in lowercase letters.

This is because the Windows 95/98/Me and Windows NT/2000/XP families of operating systems resolve filenames in a case-insensitive manner, even though the files are represented in a case-sensitive manner. Unix-based operating systems, on the other hand, always resolve files in a case-sensitive manner; if you try to edit README.TXT with the command:

>     $ vi readme.txt

you will likely be editing the empty buffer of a new file.

Here is how Samba handles case: if the `preserve` `case` is set to `yes`, Samba will always use the case provided by the operating system for representing (not resolving) filenames. If it is set to `no`, it will use the case specified by the `default` `case` option. The same is true for `short` `preserve` `case`. If this option is set to `yes`, Samba will use the default case of the operating system for representing 8.3 filenames; otherwise, it will use the case specified by the `default` `case` option. Finally, Samba will always resolve filenames in its shares based on the value of the `case` `sensitive` option.

### Mangling Options

Samba allows more refined instructions on how it should perform name mangling, including those controlling the case sensitivity, the character inserted to form a mangled name, and the ability to map filenames manually from one format to another. These options are shown in Table 8-5.

#### Table 8-5. Name-mangling options

Option | Parameters | Function | Default | Scope
--- | --- | --- | --- | ---
`case sensitive` `(casesignames)` | Boolean | If `yes`, treats filenames as case-sensitive (Windows doesn't). | `no` | Share
`default case` | string (`upper` or `lower`) | Case to assume as default (used only when preserve case is `no`). | Lower | Share
`preserve case` | Boolean | If `yes`, keep the case the client supplied (i.e., do not convert to `default` `case`). | `yes` | Share
`short preserve case` | Boolean | If `yes`, preserve case of 8.3-format names that the client provides. | `yes` | Share
`mangled names` | Boolean | Mangles long names into 8.3 DOS format. | `yes` | Share
`mangle case` | Boolean | Mangle a name if it is mixed case. | `no` | Share
`mangling char` | string (single character) | Gives mangling character. | `~` | Share
`mangled stack` | numeric | Number of mangled names to keep on the local mangling stack. | `50` | Global
`mangled map` | string (list of patterns) | Allows mapping of filenames from one format into another. | None | Share

### case sensitive

This share-level option, which has the obtuse synonym `casesignames`, specifies whether Samba should preserve case when resolving filenames in a specific share. The default value for this option is `no`, which is how Windows handles file resolution. If clients are using an operating system that takes advantage of case-sensitive filenames, you can set this configuration option to `yes` as shown here:

>     [accounting]
>         case sensitive = yes

Otherwise, we recommend that you leave this option set to its default.

### default case

The `default` `case` option is used with `preserve` `case`. This specifies the default case (upper or lower) Samba uses to create a file on one of its shares on behalf of a client. The default case is `lower`, which means that newly created files will have lowercase names. If you need to, you can override this global option by specifying the following:

>     [global]
>         default case = upper

If you specify this value, the names of newly created files are translated into uppercase and cannot be overridden in a program. We recommend that you use the default value unless you are dealing with a Windows for Workgroups or other 8.3 client, in which case it should be `upper`.

### preserve case

This option specifies whether a file created by Samba on behalf of the client is created with the case provided by the client operating system or the case specified by the earlier `default` `case` configuration option. The default value is `yes`, which uses the case provided by the client operating system. If it is set to `no`, the value of the `default` `case` option (upper or lower) is used.

Note that this option does not handle 8.3 file requests sent from the client—see the upcoming `short` `preserve` `case` option. You might want to set this option to `yes`, for example, if applications that create files on the Samba server demand the file be all uppercase. If instead you want Samba to mimic the behavior of a Windows NT filesystem, you can leave this option set to its default, `yes`.

### short preserve case

This option specifies whether an 8.3 filename created by Samba on behalf of the client is created with the default case of the client operating system or the case specified by the `default` `case` configuration option. The default value is `yes`, which uses the case provided by the client operating system. You can let Samba choose the case through the `default` `case` option by setting it as follows:

>     [global]
>         short preserve case = no

If you want to force Samba to mimic the behavior of a Windows NT filesystem, you can leave this option set to its default, `yes`.

### mangled names

This share-level option specifies whether Samba will mangle filenames for 8.3 clients. If the option is set to `no`, Samba will not mangle the names, and (depending on the client) they will either be invisible or appear truncated to those using 8.3 operating systems. The default value is `yes`. You can override it per share as follows:

>     [data]
>         mangled names = no

### mangle case

This option tells Samba whether it should mangle filenames that are not composed entirely of the case specified using the `default` `case` configuration option. The default for this option is `no`. If you set it to `yes`, you should be sure that all clients can handle the mangled filenames that result. You can override it per share as follows:

>     [data]
>         mangle case = yes

We recommend that you leave this option alone unless you have a well-justified need to change it.

### mangling char

This share-level option specifies the mangling character used when Samba mangles filenames into the 8.3 format. The default character used is a tilde (~). You can reset it to whatever character you wish. For instance:

>     [data]
>         mangling char = #

### mangled stack

Samba maintains a local stack of recently mangled 8.3 filenames; this stack can be used to reverse-map mangled filenames back to their original state. This is often needed by applications that create and save a file, close it, and need to modify it later. The default number of long filename/mangled filename pairs stored on this stack is 50. However, if you want to cut down on the amount of processor time used to mangle filenames, you can increase the size of the stack to whatever you wish, at the expense of memory and slightly slower file access:

>     [global]
>         mangled stack = 100

### mangled map

If the default behavior of name mangling is not sufficient, you can give Samba further instructions on how to behave using the `mangled` `map` option. This option allows you to specify mapping patterns that can be used in place of name mangling performed by Samba. For example:

>     [data]
>         mangled map =(*.database *.db) (*.class *.cls)

Here, Samba is instructed to search each encountered file for characters that match the first pattern specified in the parenthesis and convert them to the modified second pattern in the parenthesis for display on an 8.3 client. This is useful in the event that name mangling converts the filename incorrectly or converts it to a format that the client cannot understand readily. Patterns are separated by whitespaces.

## Locks and Oplocks

Concurrent writes to a single file are not desirable in any operating system. To prevent this, most operating systems use locks to guarantee that only one process can write to a file at a time. Operating systems traditionally lock entire files, although newer ones allow a range of bytes within a file to be locked. If another process attempts to write to a file (or section of one) that is already locked, it receives an error from the operating system and will have to wait until the lock is released.

Samba supports the standard DOS and NT filesystem (deny-mode) locking requests—which allow only one process to write to an entire file on a server at a given time—as well as byte-range locking. In addition, Samba supports a locking mechanism known in the Windows NT world as opportunistic locking, or oplock for short.

### Opportunistic Locking

Opportunistic locking allows a client to notify the Samba server that it will not only be the exclusive writer of a file, but will also cache its changes to that file locally to speed up access by reducing network activity. This can result in a large performance gain—typically 30%—while at the same time reserving network bandwidth for other purposes.

Because exclusive access can be obtained using regular file locks, the value of opportunistic locks is not so much to lock the file as it is to cache it. In fact, a better name for opportunistic locking might be opportunistic caching.

When Samba knows that a file in one of its shares has been oplocked by a client, it marks its version as having an opportunistic lock and waits for the client to complete work on the file, at which point it expects the client to send its changes back to the Samba server for synchronization with the copy on the server.

If a second client requests access to that file before the first client has finished working on it, Samba sends an oplock break request to the first client. This tells the client to stop caching its changes and return the current state of the file to the server so that the interrupting client can use it as it sees fit. An opportunistic lock, however, is not a replacement for a standard deny-mode lock. It is not unheard of for the interrupting process to be granted an oplock break only to discover that the original process also has a deny-mode lock on a file as well. Figure 8-11 illustrates this opportunistic locking process.

#### Figure 8-11. Opportunistic locking

In most cases, the extra performance resulting from the use of oplocks is highly desirable. However, allowing the client to cache data can be a big risk if either the client or network hardware are unreliable. Suppose a client opens a file for writing, creating an oplock on it. When another client also tries to open the file, an oplock break request is sent to the first client. If this request goes unfulfilled for any reason and the second client starts writing to the file, the file can be easily corrupted as a result of the two processes writing to it concurrently. Unfortunately, this scenario is very real. Uncoordinated behavior such as this has been observed many times among Windows clients in SMB networks (with files served by Windows NT/2000 or Samba). Typically, the affected files are database files, which multiple clients open concurrently for writing.

A more concrete example of oplock failure occurs when database files are very large. If a client is allowed to oplock this kind of file, there can be a huge delay while the client copies the entire file from the server to cache it, even though it might need to update only one record. The situation goes from bad to worse when another client tries to open the oplocked file. The first client might need to write the entire file back to the server before the second client's file open request can succeed. This results in another huge delay (for both clients), which in practice often results in a failed open due to a timeout on the second client, perhaps along with a message warning of possible database corruption!

If you are having problems of this variety, you can turn off oplocks for the affected files by using the `veto` `oplock` `files` parameter:

>     [dbdata]
>         veto oplock files = /*.dbm/

Use the value of the parameter (a list of filename-matching patterns separated by slash characters) to match all the files in the share that might be a source of trouble. The syntax of this parameter is similar to that of the `veto` `files` parameter.

If you want to be really careful and can live with reduced performance, you can turn off oplocks altogether, preventing the oplock break problem from ever occurring:

>     [global]
>         oplocks = no

This disables oplocks for all files in all shares served by the Samba server. If you wish to disable oplocks in just a specific share, you can specify the `oplocks` `=` `no` parameter in just that share:

>     [database]
>         oplocks = no

This example allows other shares, which might have less sensitive data, to attain better performance, while trading performance for better data integrity for files in the `[database]` share.

### Unix and Oplocks

Most of the time, oplocks help Windows client systems cooperate to avoid overwriting each other's changes. Unix systems also have file-locking mechanisms to allow Unix processes to cooperate with each other. But if a file stored on a Samba system is accessed by both a Windows network client and a local Unix process—without an additional coordination between the two systems—the Unix process could easily ride roughshod over an oplock.

Some Unix systems have enhanced kernels that understand the Windows oplocks maintained by Samba. Currently the support exists only in SGI Irix and Linux.

If you leave oplocks enabled and your Unix system does not support kernel oplocks, you could end up with corrupted data when somebody runs a Unix process that reads or writes a file that Windows users also access. This is another case where the `veto` `oplock` `files` parameter can be used, assuming you can anticipate which Samba files are used by both Windows users and Unix users. For example, suppose the `[usrfiles]` share contains some ASCII text files with the .txt filename extension and OpenOffice word processor documents with the .doc filename extension, which Unix and Windows users both modify. We can use `veto` `oplock` `files` like this:

>     [usrfiles]
>         veto oplock files = /*.txt/*.doc/

This will suppress the use of oplocks on .txt and .doc files, which will suppress client caching, while allowing the Windows and Unix programs to use regular file locking to prevent concurrent writes to the same file.

### Locks and Oplocks Configuration Options

Samba's options for locks and oplocks are given in Table 8-6.

#### Table 8-6. Locks and oplocks configuration options

Option | Parameters | Function | Default | Scope
--- | --- | --- | --- | ---
`locking` | Boolean | If `yes`, turns on byte-range locks. | `yes` | Share
`strict` `locking` | Boolean | If `yes`, denies access to an entire file if a byte-range lock exists in it. | `no` | Share
`posix locking` | Boolean | If `yes`, maps oplocks to POSIX locks on the local system. | `yes` | Share
`oplocks` | Boolean | If `yes`, turns on local caching of files on the client for this share. | `yes` | Share
`kernel` `oplocks` | Boolean | If `yes`, indicates that the kernel supports oplocks. | `yes` | Global
`level2 oplocks` | Boolean | If `yes`, allows oplocks to downgrade to read-only. | `yes` | Share
`fake oplocks` | Boolean | If `yes`, tells client the lock was obtained, but doesn't actually lock it. | `no` | Share
`blocking` `locks` | Boolean | Allows lock requestor to wait for the lock to be granted. | `yes` | Share
`veto oplock` `files` | string (list of filenames) | Does not oplock specified files. | None | Share
`lock` `directory` | string (fully qualified pathname) | Sets the location where various Samba files, including locks, are stored. | As specified in Samba makefile | Global

### locking

The `locking` option can be used to tell Samba to engage or disengage server-side byte-range locks on behalf of the client. Samba implements byte-range locks on the server side with normal Unix advisory locks and consequently prevents other properly behaved Unix processes from overwriting a locked byte range.

This option can be specified per share as follows:

>     [accounting]
>         locking = yes

If the `locking` option is set to `yes`, the requestor is delayed until the holder of either type of lock releases it (or crashes). If, however, the option is set to `no`, no byte-range locks are kept for the files, although requests to lock and unlock files will appear to succeed. The option is set to `yes` by default; however, you can turn this option off if you have read-only media.

### strict locking

This option checks every file access for a byte-range lock on the range of bytes being accessed. This is typically not needed if a client adheres to all the locking mechanisms in place. This option is set to `no` by default; however, you can reset it per share as follows:

>     [accounting]
>         strict locking = yes

If this option is set to `yes`, mandatory locks are enforced on any file with byte-range locks.

### posix locking

On systems that support POSIX locking, Samba automatically maps oplocks to POSIX locks. This behavior can be disabled by setting `posix` `locking` `=` `no`. You should never need to change the default behavior, which is `posix` `locking` `=` `yes`.

### oplocks

This option enables or disables support for oplocks on the client. The option is enabled by default. However, you can disable it with the following command:

>     [data]
>         oplocks = no

If you are in an extremely unstable network environment or have many clients that cannot take advantage of opportunistic locking, it might be better to shut this Samba feature off. If the host operating system does not support kernel oplocks, oplocks should be disabled if users are accessing the same files from both Unix applications (such as vi) and SMB clients.

### kernel oplocks

If a Unix application on the Samba host system (that is not part of the Samba suite) tries to open a file for writing that Samba has oplocked to a Windows client, it is likely to succeed (depending on the operating system), and both Samba and the client are never aware of it.

Some versions of Unix have support for oplocks in the kernel that can work along with Samba's oplocks. In this case, the Unix process trying to open the file is suspended while Samba directs the client to write its copy back. After that has happened, the operating system allows the open to complete. At the time of this writing, this feature is supported only by SGI Irix and Linux.

### level2 oplocks

Windows NT/2000/XP clients can downgrade their read-write oplocks to read-only oplocks when another client opens the same file. This can result in significant improvements in performance on files that are written infrequently or not at all—especially executables—because all clients can then maintain a read-ahead cache for the file. By default, `level2` `oplocks` is set to `yes`, and you probably won't need to change it.

Currently, Samba cannot support level 2 oplocks along with kernel oplocks and automatically disables level 2 oplocks when kernel oplocks are in use. (This might change in future releases as improved support for oplocks is added by the Samba developers.) If you are running Samba on a host system that supports kernel oplocks, you must set `kernel` `oplocks` `=` `no` to enable support for level 2 oplocks.

Disabling oplocks with `oplocks` `=` `no` also disables level 2 oplocks.

Samba can automatically detect its Unix host's support of kernel oplocks and will set the value of `kernel` `oplocks` automatically. You should never need to set this option in your Samba configuration file.

### fake oplocks

When this option is set to `yes`, Samba pretends to allow oplocks rather than actually supporting them. If this option is enabled on a read-only share (such as a shared CD-ROM drive), all clients are told that the files are available for opportunistic locking and never warned of simultaneous access. As a result, Windows clients cache more of the file's data and obtain much better performance.

This option was added to Samba before opportunistic-locking support was available, and it is now generally considered better to use real oplocks. Do not ever enable `fake` `oplocks` on a read/write share.

### blocking locks

Samba also supports blocking locks, a minor variant of range locks. Here, if the range of bytes is not available, the client specifies an amount of time that it's willing to wait. The server then caches the lock request, periodically checking to see if the file is available. If it is, it notifies the client; however, if time expires, Samba will tell the client that the request has failed. This strategy prevents the client from continually polling to see if the lock is available.

You can disable this option per share as follows:

>     [accounting]
>         blocking locks = no

When set to `yes`, blocking locks are enforced on the file. If this option is set to `no`, Samba behaves as if normal locking mechanisms are in place on the file. The default is `yes`.

### veto oplock files

You can provide a list of filenames that are never granted opportunistic locks with the `veto` `oplock` `files` option. This option can be set either globally or on a per-share basis. For example:

>     veto oplock files = /*.bat/*.htm/

The value of this option is a series of patterns. Each pattern entry must begin, end, or be separated from another with a slash ( / ) character, even if only one pattern is listed. Asterisks can be used as a wildcard to represent zero or more characters. Questions marks can be used to represent exactly one character.

We recommend that you disable oplocks on any files that are meant to be updated by Unix or are intended for simultaneous sharing by several processes.

### lock directory

This option (sometimes called `lock` `dir`) specifies the location of a directory where Samba will store SMB deny-mode lock files. Samba stores other files in this directory as well, such as browse lists and its shared memory file. If WINS is enabled, the WINS database is written to this directory as well. The default for this option is specified in the Samba makefile; it is typically /usr/local/samba/var/locks. You can override this location as follows:

>     [global]
>         lock directory = /usr/local/samba/locks

You typically would not need to override this option, unless you want to move the lock files to a more standard location, such as /var/spool/locks.

## Connection Scripts

Samba supports a mechanism called connection scripts, by which commands can be executed on the server as clients connect to a share or later disconnect from it. By using configuration file variables along with some custom programming, you can create connection scripts that perform a wide range of functions. As a simple example, here is a "quick and dirty" way to monitor connections to shares on the Samba server in real time. First, the value of the `preexec` parameter is set as follows:

>     [global]
>         preexec = /bin/echo %u at %m connected to //%L/%S on %T >>/tmp/smblog

This causes information about the user and the connection to be written to the file /tmp/smblog whenever any client connects to any share. To watch clients connect, run the following command:

>     $ tail -f /tmp/smblog
>     jay at maya connected to //toltec/data on 2002/11/21 21:21:15
>     david at apache connected to //toltec/techs on 2002/11/21 21:21:57
>     sally at seminole connected to //toltec/payroll on 2002/11/21 21:22:16
>     martha at dine connected to //toltec/profiles on 2002/11/21 21:23:38
>     martha at dine connected to //toltec/netlogon on 2002/11/21 21:23:39
>     martha at dine connected to //toltec/martha on 2002/11/21 21:23:40
>     aaron at huastec connected to //toltec/netlogon on 2002/11/21 21:24:19
>     aaron at huastec connected to //toltec/aaron on 2002/11/21 21:24:20

With the -f option, the tail command monitors /tmp/smblog and prints additional output as new data is appended to the file. Every time a new connection is made, an additional line is printed, showing the output of the `preexec` command. Notice the lines resulting from connections by user `martha` and `aaron`. User `martha` logged on to the domain from a Windows NT client, which accessed the `[profiles]` share to download her profile, then the `[netlogon]` share to read the logon script, and then her home directory (because her logon script contains a `net` `use` `H`: `/home` command) to connect her home directory to drive letter H. The connections from `aaron` are similar, except that he connected from a Windows 98 system, which does not use the `[profiles]` share. (See Chapter 4 for more information about domain logons.)

A more advanced use of connection scripts is to monitor the contents of users' home directories and/or other shared directories and perform checks ensuring that local administrative policies are followed. Checked items might include the following:

- Disk usage, on a per-share, per-directory, or per-file basis

- Types of files stored on the server

- Whether filenames follow naming guidelines

- Whether viruses have copied themselves to the Samba server

To handle this kind of task, a shell script or other program would be written to perform the checks and take appropriate actions, such as removing offending files. The `root` `preexec` parameter would be used to run the command as the root user, using configuration file variables to pass arguments. For example:

>     [homes]
>         root preexec = admin_checks %S
>         root preexec close = yes

In this example, a specially written administrative checking program (admin_checks) is used to monitor users' home directories on the Samba server. The `%S` variable is used to pass the name of the home directory to the script. The `root` `preexec` `close` parameter has been set to `yes` so that if admin_checks detects a serious violation of local policy, it can exit with a nonzero status, and the client is prevented from connecting.

### Connection Script Options

Table 8-7 introduces some of the configuration options provided for setting up users.

#### Table 8-7. Connection script options

Option | Parameters | Function | Default | Scope
--- | --- | --- | --- | ---
`root preexec` | string (Unix command) | Sets a Unix command to run as `root`, before connecting to the share. | None | Share
`root preexec close` | Boolean | If set to `yes`, nonzero exit status of `root preexec` command will disconnect. | `no` | Share
`preexec` `(exec)` | string (Unix command) | Sets a Unix command to run as the user before connecting to the share. | None | Share
`preexec close` | Boolean | If set to `yes`, nonzero exit status of `preexec` command will disconnect. | `no` | Share
`postexec` | string (Unix command) | Sets a Unix command to run as the user after disconnecting from the share. | None | Share
`root` `postexec` | string (Unix command) | Sets a Unix command to run as `root` after disconnecting from the share. | None | Share

### root preexec

This option specifies as its value a Unix command to be run as the root user before any connection to a share is completed. You should use this option specifically for performing actions that require root privilege.

To ensure security, users should never be able to modify the target of the `root` `preexec` command. In addition, unless you explicitly redirect it, any information the command sends to standard output will be discarded. If you intend to use any `preexec` or `postexec` script, you should ensure that it will run correctly before having Samba invoke it.

### root preexec close

Sometimes you might want the share to disconnect if the `root` `preexec` script fails, giving the client an error rather than allowing it to connect. For example, if you are using `root` `preexec` to mount a CD-ROM or filesystem, it would make no sense to connect the client to it in the event that the mount fails. If you specify `root` `preexec` `close` `=` `yes`, the share will fail to connect if the `root` `preexec` script returns a nonzero exit status.

### preexec

Sometimes just called `exec`, this option defines an ordinary unprivileged command run by Samba as the user specified by the variable `%u`. For example, a common use of this option is to perform logging, such as the following:

>     [homes]
>         preexec = echo "%u connected from %m (%I)\" >>/tmp/.log

You must redirect the standard output of the command if you want to use it. Otherwise, it is discarded. This warning also applies to the command's standard error output. If you intend to use a `preexec` script, you should ensure that it will run correctly before having Samba invoke it.

### preexec close

This is similar to `root` `preexec` `close`, except that it goes with the `preexec` option. By setting `preexec` `close` `=` `yes`, a `preexec` script that returns nonzero will cause the share to disconnect immediately.

### postexec

Once the user disconnects from the share, the command specified with `postexec` is run as the user on the Samba server to do any necessary cleanup. This option is essentially the same as the `preexec` option. Again, remember that the command is run as the user represented by `%u`, and any information sent to standard output will be ignored.

### root postexec

Following the `postexec` option, the `root` `postexec` command is run, if one has been specified. Again, this option specifies as its value a Unix command to be run as the root user before disconnecting from a share. You should use this option specifically for performing actions that require root privilege.

## Microsoft Distributed Filesystems

In a large network where many shared folders are spread out over a large number of servers, it can be difficult for users to locate the resources they are trying to find. Browsing through Network Neighborhood or My Network Places can become an ordeal rather than a time-saving convenience. To mitigate this problem, Microsoft added an extension to file sharing called Distributed filesystem (Dfs). Using Dfs, it is possible to organize file shares on the network so that they appear to users as organized in a single directory tree on a single server, regardless of which servers on the network actually contain the resources. Instead of having to browse the entire network, users can go to the Dfs share and locate their data much more easily.

Dfs can also help administrators because it provides a level of indirection between the name of a shared folder and its actual location. The Dfs share contains references to resources on the network, and when a resource is accessed, the Dfs server hands the client off to the actual server of the resource. When moving resources to another computer, the reference to the resource in the Dfs share can be redirected to the new location in one step, with the change being entirely seamless for users.

To a limited extent, Dfs also can help improve performance for read-only shares because it provides load balancing. It is possible to set up a Dfs reference to point to identical shares on two or more servers. The Dfs server then divides requests between the servers, dividing the client load among them. However, this works well only for static, read-only data because no provision is included in Dfs for synchronization among the servers when changes are made on any of them.

### Windows Dfs Clients

Modern versions of Windows come with client-side support for Dfs, and no extra configuration is required. Support is more limited for older versions, however. Windows for Workgroups cannot function as a Dfs client at all. Windows NT 4.0 must be upgraded to at least Service Pack 3 to act as a Dfs client, and the Dfs Client must be installed. Later service packs (such as Service Pack 6) include the Dfs Client. Windows 95 must also have the Dfs Client software installed to act as a Dfs client. Without the Dfs Client software, double-clicking a remote folder in a Dfs share will show an empty folder, and no error message will appear.

> #### TIP

> To use the Dfs Client for Windows 95 or Windows NT, you must first download and install it. See the web page http://microsoft.com/ntserver/nts/downloads/winfeatures/NTSDistrFile/default.asp for a link to download the installation program and instructions on how to install the Dfs Client.

### Configuring Samba for Dfs

To act as a Dfs server, Samba 2.2 must be compiled with the `--with-msdfs` configure option. (See Chapter 2 for instructions on configuring and compiling Samba.) Samba 3.0 includes Dfs support by default and does not need to be compiled with the `--with-msdfs` configure option.

Once a Dfs-enabled Samba server is running, there are just two steps to serving a Dfs share. First we will set up a Dfs root directory on the server, and then we will modify the smb.conf configuration file to enable the share.

### Setting up the Dfs root

First we need to create a directory to act as the Dfs root:

>     # mkdir /usr/local/samba/dfs

This can be any directory, but it is important that it be owned by root and given the proper permissions:

>     # chown root:root /usr/local/samba/dfs
>     # chmod 755 /usr/local/samba/dfs

The Dfs directory tree can have subdirectories and files, just like any other shared directory. These will function just as they would in any other share, allowing clients to access the directories and files on the Samba server. The whole idea of Dfs, though, is to gather together shares on other servers by making references to them in the Dfs tree. The way this is implemented with Samba involves a clever use of symbolic links, which can be in the Dfs root directory or any subdirectory in the Dfs tree.

You are probably familiar with using symbolic links to create references to files that exist on the same system, and perhaps crossing a local filesystem boundary (which ordinary Unix links cannot do). But maybe you didn't know that symbolic links have a more general functionality. Although we can't display its contents directly, as we could with a text or binary file, a symbolic link "contains" an ASCII text string naming what the link points to. For example, take a look at the listing for these symbolic links:

>     $ ls -l wrdlnk alnk
>     lrwxrwxrwx    1 jay      jay            15 Mar 14 06:50 wrdlnk -> /usr/dict/words
>     lrwxrwxrwx    1 jay      jay             9 Mar 14 06:53 alnk -> dreamtime

As you can infer from the size of the wrdlnk link (15 bytes), the string `/usr/dict/words` is encoded into it. The size of alnk (9 bytes) is smaller, corresponding to the shorter name of dreamtime.

Now let's create a link in our Dfs root for an SMB share:

>     # cd /usr/local/samba/dfs
>     # ln -s 'msdfs:maya\e' maya-e
>     # ls -l maya-e
>     lrwxrwxrwx    1 root     root           12 Mar 13 17:34 maya-e -> msdfs:maya\e

This link might appear as a "broken" link in a directory listing because it points to something that isn't a file on the local system. For example, the file command will report:

>     $ file maya-e
>     maya-e: broken symbolic link to msdfs:maya\e

However, maya-e is a valid reference to the \\maya\e share when used with Samba's Dfs support. When Samba encounters this file, it sees the leading `msdfs`: and interprets the rest as the name of a remote share. The client is then redirected to the remote share.

When creating links in the Dfs root directory, simply follow the same format, which in general is `msdfs`:server\share. Note that this is similar to a UNC appended onto the `msdfs`: string, except that in this case, the two backslashes preceding the server's name are omitted.

> #### TIP

> The names for the symbolic links in Dfs shares must be in all lowercase.

In addition to regular network shares, you can use symbolic links of this type to reference Dfs shares on other Dfs servers. However, referencing printer shares does not work. Dfs is for sharing files only.

### Load balancing

To set up a load-balancing Dfs share, create the symbolic link like this:

>     # ln -s 'msdfs:toltec\data,msdfs:mixtec\data' lb-data

That is, simply use a list of shares separated by commas as the reference. Remember, it is up to you to make sure the shared folders remain identical. Set up permissions on the servers to make the shares read-only to users.

The last thing we need to do is to modify the smb.conf file to define the Dfs root share and add Dfs support. The Dfs root is added as a share definition:

>     [dfs]
>         path = /usr/local/samba/dfs
>         msdfs root = yes

You can use any name you like for the share. The path is set to the Dfs root directory we just set up, and the parameter `msdfs` `root` `=` `yes` tells Samba that this share is a Dfs root.

To enable support for Dfs in the server, we need to add one line to the `[global]` section:

>     [global]
>         host msdfs = yes

Restart the Samba daemons—or just wait a minute for them to reread the configuration file—and you will see the new share from Windows clients. If you have trouble accessing any of the remote shares in the Dfs share, recheck your symbolic links to make sure they were created correctly.

> #### TIP

> If you previously had a share by the same name as your Dfs share, you might need to reboot Windows clients before they can access the share as a Dfs share.

## Working with NIS

In networks where NIS and NFS are in use, it is common for users' home directories to be mounted over the network by NFS. If a Samba server being used to authenticate user logons is running on a system with NFS-mounted home directories shared with a `[homes]` share, the additional overhead can result in poor performance—about 30% of normal Samba speed.

Samba has the ability to work with NIS and NIS+ to find the server on which the home directories actually reside so that they can be shared directly from that server. For this to work, the server that holds the home directories must also have Samba running, with a `[homes]` share of its own.

### NIS Configuration Options

Table 8-8 introduces the NIS configuration options specifically for setting up users.

#### Table 8-8. NIS options

Option | Parameters | Function | Default | Scope
--- | --- | --- | --- | ---
`nis homedir` | Boolean | If `yes`, uses NIS instead of /etc/passwd to look up the path of a user's home directory. | `no` | Global
`homedir map` | string (NIS map name) | Sets the NIS map to use to look up a user's home directory. | None | Global

### nis homedir, homedir map

The `nis` `homedir` and `homedir` `map` options are for Samba servers on network sites where Unix home directories are provided using NFS, the automounter, and NIS.

The `nis` `homedir` option indicates that the home-directory server for the user needs to be looked up in NIS. The `homedir` `map` option tells Samba in which NIS map to look for the server that has the user's home directory. The server needs to be a Samba server so that the client can do an SMB connect to it, and the other Samba servers need to have NIS installed so that they can do the lookup.

For example, if user `joe` asks for a share called `[joe]`, and the `nis` `homedir` option is set to `yes`, Samba will look in the file specified by `homedir` `map` for a home directory for `joe`. If it finds one, Samba will return the associated system name to the client. The client will then try to connect to that machine and get the share from there. Enabling NIS lookups looks like the following:

>     [globals]
>         nis homedir = yes
>         homedir map = amd.map

#### Footnotes

> [1] The system checkbox will probably be grayed for your file. Don't worry about that—you should still be able to see when the box is checked and when it isn't.

#### TOC