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

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

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:

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