Filesystem Differences






Filesystem Differences

The list of differences between Windows filesystems such as FAT and NTFS and those hosted by Unix servers (too numerous themselves to mention) generally fall into the following five categories:


Valid filename characters

Windows restricts such characters as colons (:) and trailing whitespace; Unix is happy to create files and directories with names such as "Where I was: or at least thought." The other major point of contention is the path separation character. Windows breaks directories paths into individual components using the backslash (\), and Unix employs the forward slash (/).


Filename length

Originally DOS and Windows clients only supported filenames that are at most eight characters in length plus a file extension of at most three characters. Today, long filenames are widely supported on Unix and Windows hosts. There are times, however, when a long filename may need to be mangled into a shorter one, as you will see when we discuss valid filename characters.


Case sensitivity

Windows preserves case in the names that users create for folders and files, but allows them to be requested in a case-insensitive manner. That is, you can refer to My Documents as MY DOCUMENTS. Unix filesystems are traditionally case-sensitive.


File locking and caching

In modern networks, the byte range-locking semantics expected by Windows clients are those provided by the Windows kernel. Thankfully, as an administrator, you don't have much to worry about here. Samba does the heavy lifting to ensure that Windows clients are kept happy. It may be necessary, however, to configure how Samba responds to caching requests by Windows clients.


Permissions and attributes

In Windows, support for permissions and attributes ranges from the FAT filesystem, which possesses no permissions, to NTFS and its elaborate ACLs. In contrast, nine simple bits (read/write/execute for user/group/other) are historically supported by Unix.

This is not a complete list of differences, but does cover about 90 percent of the issues. Examining a few common scenarios faced by administrators will help to illustrate how Samba is able to bridge this gap.

Name Mangling and Filename Lengths

Name mangling is the term given to the process of translating the name of a file (or directory) as it is stored on the server to a form acceptable by the client. There are many reasons why a filename acceptable to the server would be unacceptable to the client. Older SMB clients, such as DOS and some 16-bit applications running on Windows 9x/Me, can make use of only 8.3 filenames, also referred to as short filenames. The name "8.3" is derived from the maximum length of the filename (eight characters), which is followed by a period and up to a three-character extension (such as NOTES.TXT). The 8.3 filename convention is used for many applications, even though current operating system requirements are much more flexible. (This is why HTML files are often represented with .htm extensions, JPEG files with .jpg extensions, and executable files with .exe extensions). True 8.3 filenames are uppercase (WINWORD.EXE), as they would be appear on an MS-DOS system.

A simple way to view the mapping from long filenames to short ones is to use the Windows XP cmd.exe shell and the dir command. The default method for displaying files shows the long filename on the lefthand side of the output. To display the short filename as well, specify the /x argument. The following listing shows the contents of a Samba share named [public] mounted on the client at P:. Notice that filename Samba Notes.html has been mapped to the valid 8.3 filename SM0EEH~V.

P:\> dir /x
 Volume in drive P is public
 Volume Serial Number is 0200-0882

 Directory of P:\

05/23/2006  05:58 PM    <DIR>             .
05/23/2006  05:57 PM    <DIR>             ..
05/23/2006  05:57 PM         0 SM0EEH~V   Samba Notes.html
               1 File(s)              0 bytes
               2 Dir(s)   2,502,819,840 bytes free

The algorithm used to determine the derived 8.3 filename is controlled by Samba's mangling method global parameter. This parameter currently accepts either of two values: hash or hash2. The hash method was used in Samba 2.2, and hash2 is the default for Samba 3.0 servers. It is recommended that you do not alter the parameter from its default value unless you explicitly require backward compatibility with the Samba 2.2 installations. This would be the case if you had applications that relied upon the generated 8.3 names (a bad idea to begin with).

Any filename containing an character that is invalid on Windows, such as *, \, or :, is automatically mangled, even if the client supports long filenames.


One question that often appears on Samba-related mailing lists is how to make the server generate short files names in the same manner as Windows, for example having Program Files appear as PROGRA~1. It is not possible to configure Samba to do this, because neither the hash nor hash2 method store the generated the short filename for long term use. Unlike FAT32 and NTFS, Unix filesystems do not care about 8.3 filenames and therefore do not allocate any room in the file's metadata record for remembering the shorter variation. Therefore, Samba has to regenerate short filenames every time the server starts up.

Figure gives a short overview of the mangling method parameter and its possible values.

The mangling method parameter

Parameter

Value

Description

Default

Scope

mangling method

hash or hash2

Determines the internal hashing function used for generating an 8.3 filename in place of its long filename counterpart. It is recommended to leave this option set to its default value.

hash2

Global


Case Sensitivity and Preservation

Windows filesystems are case-preserving and case-insensitive. Native Unix filesystems are almost always case-preserving and case-sensitive. Case preservation is no problem. Samba simply creates the file or directory using the name specified by the client. But what should the server do if the client creates a file named Foo.txt and later tries to open foo.txt? Both names should map to the same file.

The way Samba solves this problem is very similar to how it attempts to solve the problems concerning login names and clear-text passwords presented by Windows 9x/Me clients (discussed in the previous chapter). When receiving a request containing a filename (open, remove, rename, etc.), smbd first attempts to locate the file using the name transmitted by the client. If this lookup fails, the daemon then continues to try various case permutations of the file name until a match is located or until all string variations fail. A successful lookup is stored in smbd's internal cache. Sometimes it may be necessary to limit the size of this stat cache to prevent smbd from allocating large amounts of memory. On a busy server, small amounts of extra memory allocated by many Samba processes can add up quickly.

The max stat cache size accepts an integer value that restricts the amount of memory in kilobytes that the stat cache can consume in an smbd process. The default is to allow as much memory as needed. In most cases this behavior is acceptable, because clients activity tends to be pretty localized to a portion of the server's filesystem. Exceptions to this rule might occur when a client's virus software is scanning a large directory tree on the server for infected files. In a worst case scenario, the stat cache parameter can be disabled altogether, although at a high cost in performance. When in doubt, it is best to make use of the default stat cache-related settings (summarized in Figure).

Stat-cache-related parameters

Parameter

Value

Description

Default

Scope

max stat cache size

integer

Restricts the maximum amount of memory in kilobytes that will be allocated to stat cache in each smbd process.

0

Global

stat cache

boolean

If yes, smbd caches successful case-insensitive filename lookups.

yes

Global


By default, smbd honors the case-preserving semantics expected by Windows clients. However, at times, this functionality must be sacrificed; Samba should adopt a single convention for representing case in file and directory names to provide better service. Historically, Unix filesystems have suffered badly when serving thousands of files from a single directory. Combine this with multiple case-insensitive lookups in Samba and you have a recipe for unhappy users impatiently waiting for their spreadsheet to open.

Beginning with Samba 3.0.12, Samba developers introduced a mechanism by which a Unix filesystem could provide case insensitivity through smbd. The trick is to convert all file and directory names into a common case format and then instruct Samba to perform a case-sensitive lookup after converting the name requested by the client to the same default case used by the share. The only downside is that you lose case preservation when creating new files.

Let's look at an example that takes an existing share named [drawings] and converts it to use case-sensitive filename lookups. The initial share definition defines a path and allows write access to its contents:

[drawings]
    path = /data/drawings
    read only = no

First, the example converts all files and directories in the share to a default case, either upper- or lowercase. This example uses lowercase. Make sure to block out client connections to the share during the conversion, either by taking Samba offline or by setting available = no in the share definition.

The NormalizePath bash function listed in the following shell script accepts a path name as its single argument and renames the last component of the path to its lower case variant. The path Foo/Bar would be renamed to Foo/bar.

#!/bin/bash
## normalize.sh - Shell script to convert a directory
## tree beginning at the current working directory to
## lower case file and directory names

## Normalize the last component of a path to lower case
function NormalizePath {
    PARENT='dirname $1'
    BASE='basename $1'
    NEWBASE='echo ${BASE} | tr [:upper:] [:lower:]'
    if [ "${BASE}" != "${NEWBASE}" ]; then
        echo ${PARENT}/${NEWBASE}
        (cd ${PARENT} && /bin/mv ${BASE} ${NEWBASE} )
    fi
}

Next, call NormalizePath for each file in the directory tree. The reverse sort (sort -r) ensures that work progresses from the bottom of the tree and towards the current directory, walking the directory tree in one pass. Processing the tree in the order returned by find or from the shortest paths first (a normal sort order) invalidates some paths, as parent directories are renamed before their subfolders and files have been processed.

## traverse the entire directory tree
for file in 'find . -print | sort -r '; do
    NormalizePath $file
done

Invoking normalize.sh products output similar to the following:

$ ./normalize.sh 
./xml/xmlhosed.xsl
./xml/xmlaffected.xsl
./xml/xmlaffecteduninstall.xsl
./xml/spssdk_info.xml
 ...remaining output deleted...

Now, reconfigure the [drawings] share to take advantage of the normalized directory tree. The preserve case and short preserve case parameters instruct smbd as to whether it should maintain the case of new file and directory names for long and short names, respectively. These per-share Boolean options default to the case-preserving semantics to which Windows clients are accustomed. Disable them both and define the share's default case to match the directory tree. Finally, configure Samba to perform a case-sensitive lookup on the normalized name. If the file or directory exists, the name must match. There is no need to retry different case combinations, and therefore the performance appears to increase from the end user's perspective. The modified [drawings] share appears as follows:

[drawings]
    path = /data/drawings
    read only = no

    ## Speed up filename lookups after normalizing the
    ## share contents
    case-sensitive = yes
    default case = lower
    preserve case = no
    short preserve case = no

Figure lists the case-related smb.conf parameters covered in this section. Each can be used by itself in a share, but we recommend not enabling case sensitivity without first normalizing the share's contents.

Case sensitivity and preservation parameters

Parameter

Value

Description

Default

Scope

case-sensitive

boolean

Should Samba assume that the client sent the file or directory name in the correct case?

no

Share

default case

upper or lower

The alphabetic case used when not preserving the file's original name.

lower

Share

preserve case

boolean

Should Samba create the long filename as transmitted by the client?

yes

Share

short preserve case

boolean

Should Samba maintain the original format of an 8.3 filename?

yes

Share


Symbolic Links

Symbolic links (symlinks) on the servers appear as normal files or directories by Windows clients. But as the administrator, you should ask:

  • Should the Samba server support following symbolic links at all?

  • Should Samba follow links outside of the share?

By default, Samba follows all symlinks, as long as the user has appropriate permission to the link target. However, under some circumstances, you may wish to restrict this behavior. If users are able to access shares only from Windows clients, the entire discussion is moot, because Windows cannot create symlinks on remote CIFS shares.[*]

[*] The Linux CIFS FS client and the Unix Extensions to the CIFS protocol covered in Chapter 11 do support the creation of symlinks on remote servers.

However, users with shell accounts on the Samba server can present a problem. The most common case is when home directories are accessible both by NFS and by Samba. A user could log on to a Unix workstation that mounts his home directory via NFS and create a symbolic link to /etc/passwd. When accessing that symbolic link from a Windows client, Samba returns the link target, which is /etc/passwd on the server. Whether this is a security hole is debatable. At the very least, it can be surprising.

To remedy this unintended access, disable wide links. This step causes Samba to refuse to follow links outside the share.

[homes]
    comment = home directory for %U
    read only = no
    wide links = no

Or if you prefer, disable support for symbolic links altogether by setting follow symlinks = no. Note that there will be a small negative impact on performance when you disable symlinks, as smbd must then perform extra checks on every attempt to open a file on a client's behalf. Figure lists the link-related options supported by Samba.

Symbolic link options

Parameter

Value

Description

Default

Scope

follow symlinks

boolean

Should Samba follow any symbolic links?

yes

Share

wide links

boolean

Should Samba follow a symbolic link if it leads outside of the root of the current share?

yes

Share


Hiding Files

Sharing disks between Unix and Windows frequently exposes files that are needed on only one operating system or the other. A prime example is the shell initialization files that exist in a user's Unix home directory (frequently referred to by Windows users as "those pesky dot files"). Preceding a filename with a period is the standard mechanism on Unix for hiding the file from normal directory listing tools. Windows uses the hidden DOS attribute bit (described in more detail later in the section "DOS Attributes) for the same purpose. By default, Samba sets the hidden bit for all dot files when returning the files DOS attributes to a client, but this behavior can be disabled by setting hide dot files = no.

The hide files option provides additional flexibility to allow you to specify a set of patterns that, if matched, cause a file or directory to be marked as hidden. The filename patterns use the Windows globbing syntax, which is a simple subset of Unix shell metacharacters: a * character matches one more more characters, and a ? character consumes a single character. Multiple patterns can be concatenated using the forward slash (/) character as the delimiter. The following example hides *.ini files and *.log files:

[homes]
    read only = no
    hide files = /*.ini/*.log/

There are other Boolean parameters for hiding certain types of files. For the following options, it's important to understand that hiding does not mean merely setting the Windows filesystem's hidden attribute on a file, but goes much further. It means Samba does not list the file or directory at all.[*] Files matched by the following options are not accessible to a user on a client system, even if she specifies the file by name on the command line or sets her folder to display hidden files. It is as though the file did not exist.

[*] This ambiguity of parameter names is a personal gripe of these authors and one that will hopefully improve in future releases.


hide unreadable and hide unwriteable

Excludes files that can not be read or written by the user, respectively.


hide special files

Prevent a user from seeing any objects except regular files, directories, and symbolic links. Thus, it excludes named pipes and other unusual objects in Unix filesystems.


veto files

This option allows the same flexible syntax option as the hide files parameter, with the more restrictive sort of hiding.

Under some circumstances, dropping files into a virtual black hole can be useful. One Samba administrator devised the following pattern to prevent the Nimba worm from using Samba hosts to propagate itself. Placing this in the [global] section insured that the veto files setting was inherited by all file shares, and that no user could download files matching the forbidden names.

[global]
    veto files = /*.eml/*.nws/riched20.dll/

Vetoing files can lead to a problem. Directories can be removed only after all files they contain have been deleted. If a user drops a file that matches the veto files patterns into a Samba folder, he will never be able to access that file again through Samba. You can understand the confusion when a user tries to remove a directory and it fails because the folder claims to not be empty, and yet no files can be seen. To work around this issue, Samba provides the delete veto files Boolean parameter, which instructs Samba to remove all vetoed files contained by a directory that a user is deleting (assuming there are no visible files there).

Figure finishes up this section with a short summary of the parameters covered in relation to hiding and excluding files from clients.

Options for hiding and excluding files

Parameter

Value

Description

Default

Scope

delete veto files

boolean

Can Samba remove vetoed files when removing a directory, if there are no nonvetoed files remaining?

no

Share

hide dot files

boolean

When enabled, Samba sets the hidden attribute on files that begin with a period.

yes

Share

hide files

filename pattern

Specifies a set of filename patterns defining files that should have the DOS hidden attribute enabled.

None

Share

hide special files

boolean

Should Samba exclude from directory listings files such as sockets, named pipes, and device files?

no

Share

hide unreadable files

boolean

Should Samba exclude from directory listings files that cannot be read by the user?

no

Share

hide unwriteable files

boolean

Should Samba exclude from directory listings files that cannot be modified by the user?

no

Share

veto files

filename pattern

Specifies a set of filename patterns defining files that should be excluded from directory listings.

None

Share


Locks and Leases

File and byte range locking is one of those topics that is often better left alone. Generally, the only people that understand how things are supposed to work are the developers themselves. For this reason, it is recommended that you do not modify the majority of locking-related parameter values in smb.conf. Samba programmers work extremely hard to ensure that smbd's locking implementation provides exactly what CIFS clients require. In fact, think of the majority of smb.conf parameters like values in the Windows registry, with the standard disclaimer: Tweaking too many things could render your Samba server inefficient or even cause it to fail.

With that in mind, there is one parameter that may be of use if you are exporting read-only filesystems, such as CD-ROMs. In this case, there is a possibility of gaining some performance benefit by faking byte range lock support. Disabling the locking parameter allows Samba to grants locks without worrying about keeping track of who has what. Because the share is marked as read-only, all clients can freely believe that they have locked whatever region of the file they desired without fear that someone else will change it out from underneath them. Before you disable the locking option, make sure that no clients can modify the contents of the share via another protocol (e.g., NFS) or the local filesystem.

Samba's byte range-locking options are designed to work well using the default settings. Sometimes, you need to tweak the oplock settings on a share. Oplock is short for opportunistic locking. The name is unfortunate, because this feature has little to do with file locking. Oplocks are an aggressive caching mechanism used by Windows clients to boost performance when accessing remote files. When an oplock is granted, the client is able to cache the entire file locally. If the oplock type allows the client to modify the file locally, these changes are flushed back to the server when the file is closed or the client receives a request from the server to break the oplock.

The major hurdle with oplocks is that on most platforms running Samba, the feature is implemented only internally, by smbd. A few operating system kernels, such as IRIX and Linux 2.4 and later, support file leases, which are the Unix equivalent of oplocks. By using the kernel to coordinate with other Unix process on these systems, Samba is able process oplock break messages when a file is accessed via another means such as NFS. Otherwise, the non-Samba process may not have a consistent view of the data as it is seen by Windows clients. If users are accessing files concurrently via Samba and another file-sharing protocol, it is probably best to disable oplocks to avoid the risk of corrupting file contents.

The Samba build procedure automatically determines at compile time whether the host operating system supports file leases. If it does, smbd is built with support for kernel oplocks, a feature that can be controlled at runtime using the kernel oplocks global parameter. Both the compile-time support and the runtime configuration file parameter are necessary for the kernel oplock feature.

There are three types of oplocks:


Exclusive

Allows the client to have sole access to the file and to perform local modifications that are flushed back to the server when the oplock is revoked or the client closes the file.


Batch

Identical to exclusive oplocks, but allows an application to open and close a file repeatedly without relinquishing the lease. Batch file processing tends to follow this multiple open-and-close pattern; hence the name.


Level 2

Allows a client to perform read caching on a file, which is particularly useful for executables run from a network file share. Only Windows NT-based clients support level 2 oplocks.

Certain application files have historically had problems with oplocks. PC database files, such as FoxPro and Microsoft Access, are among the most fragile. With such files, it is better to disable oplocks on the share or to exclude the relevant set of files from being granted an oplock. The veto oplock files parameter accepts a list of filename patterns using the same syntax as the hide files and veto files parameters covered in the previous section. The following example shows two file shares: [nooplocks] disables oplocks for all files in a share, and [access-db] oplock support only for MS Access (*.mdb) files:

[nooplocks]
    path = /data/share1
    read only = yes
    oplocks = no

[access-db]
    path = /data/share2
    read only = no
    veto oplock files = /*.mdb/

The oplocks option applies to both exclusive and batch oplocks and is a prerequisite to enabling level 2 oplocks. Very rarely does a case warrant disabling level 2 oplocks while leaving exclusive and batch oplocks enabled.

Similar to the locking parameter for byte range locks, Samba also provides fake oplocks. As mentioned earlier for the locking parameter, consider using fake oplocks only for read-only directory trees. When enabled, all requests for any oplock type will succeed and performance may increase.

Figure concludes this section by listing the byte range locking and oplock related parameters.

Locking and leasing options

Parameter

Value

Description

Default

Scope

fake oplocks

boolean

If enabled, Samba honors all oplock requests. This option should be considered only for a read-only filesystem.

no

Share

kernel oplocks

boolean

If enabled, and if the operating system's kernel provides support for file leases, Samba coordinates all oplock requests via the kernel lease mechanism.

yes

Share

level 2 oplocks

boolean

Should Samba honor requests for level 2 oplocks if possible?

yes

Share

locking

boolean

If disabled, Samba honors all byte range lock requests without enforcement. This option should be considered only for a read-only filesystem.

yes

Share

oplocks

boolean

Should Samba honor requests for exclusive and batch oplocks if possible?

yes

Share

veto oplock files

filename pattern

Defines a list of filename patterns that should be prevented from being granted exclusive or batch oplocks.

None

Share


DOS Attributes

All Microsoft clients make use of four DOS attributes: archive, hidden, system, and read-only. Newer releases of Windows support additional attributes, such as whether the file is compressed. Currently, Samba provides only support for the original four attributes, so we'll start with a simple explanation of what each one means:


Archive

Automatically set by the Windows filesystem when a file is modified. This attribute is useful primarily to back up applications, which rely upon it to determine which files have changed since the last run. Unfortunately, Unix filesystems do not set this on Samba's behalf, and Samba does not update it on its own.


Hidden

Hides files or directories from application interfaces such as the Windows Explorer. A user may choose to view these objects by enabling the appropriate folder settings in Windows.


System

Indicate items used for operating system purposes, such as a memory swap files.


ReadOnly

Similar to the immutable bit supported by Unix. The read-only setting is separate from any ACL that may deny read access to a specific user.

DOS attributes still have an impact on servers today. For example, a Windows XP client refuses to load a registry hive from a file marked as ReadOnly. This includes user profiles (ntuser.dat) and NT4 system policies (ntconfig.pol). Samba provides two mutually exclusive mechanisms for storing DOS attributes, one based on file permissions and the other utilizing the filesystem's extended attributes (EAs).

DOS attributes and Unix permissions bits

Because Unix provided only the standard nine bits of read/write/execute permission, Samba originally kept track of the attributes by mapping each one onto a bit in the Unix permission set as follows:


ReadOnly

The inverse of the owner write bit


Archive

The user execute bit


System

The group execute bit


Hidden

The world execute bit

The main limitation with this approach is that due to the semantics of the execute bits regarding directories, developers decided to apply the mapping only to files. There is no way to represent DOS attributes on folders using this permission mapping method, which is a major deficiency.

The attribute/permission mapping model is controlled by three Boolean parameters and one semiboolean option that can be enabled or disabled on each share: map archive, map hidden, map readonly, and map system. The archive, hidden, and system mapping options accept a yes or no value, which specifies whether smbd should examine the execute bits when calculating the attribute set for a file.

The map readonly parameter accepts yes, no, or permissions. The permissions value indicates that smbd should analyze the file ACL to determine whether the connected user has write permission and therefore whether to report the ReadOnly attribute. This behavior is different from specifying the option's value as yes, which examines only the owner's write bit to determine the ReadOnly attribute for all users. The map readonly parameter was added in Samba 3.0.21. Prior releases always examined the owner write bit when calculating the ReadOnly property. ACLs are covered in the next section.

The ReadOnly DOS attribute is independent of the read only share parameter.


Let's look at particular file share and permission set to see how the DOS attributes are displayed. Start with a definition of [data] from smb.conf:

[data]
    path = /data
    read only = no
    map readonly = yes
    map archive = yes
    map hidden = yes
    map system = yes

Now imagine a file named notes.txt with the following Unix permissions:

-rwxr--r-x 1 lizard users 0 2006-05-24 13:47 notes.txt

View its DOS attributes using smbclient:

$ smbclient //rain/data -U lizard%test -c 'dir notes.txt'
Domain=[GARDEN] OS=[Unix] Server=[Samba 3.0.22]
  notes.txt      AH        0  Wed May 24 13:47:08 2006

    56578 blocks of size 65536. 38189 blocks available

The Archive (A) and Hidden (H) attributes are displayed due to the owner execute and world execute permissions. Removing the owner write bit (chmod u-w notes.txt) displays the ReadOnly (R) bit as well:

$ smbclient //rain/data -U lizard -c 'dir notes.txt'
Domain=[GARDEN] OS=[Unix] Server=[Samba 3.0.22]
  notes.txt      AHR       0  Wed May 24 13:47:08 2006

    56578 blocks of size 65536. 38189 blocks available

DOS attributes and Unix extended attributes

Samba 3.0.3 introduced a means of storing DOS attributes separately from the Unix permissions, if the Unix filesystem supports extended attributes. Currently, Samba's support for filesystem EAs is limited primarily to Linux and IRIX, but efforts are underway to support other platforms, such as FreeBSD. There are a few ways to determine whether your Linux filesystem includes support for EAs. The simplest is to check whether the filesystem was mounted with the user_xattr option:

$ mount
/dev/hda2 on / type ext3 (rw,acl,user_xattr)
...

More details about configuring Linux and the Linux kernel can be found in Linux Kernel in a Nutshell, by Greg Kroah-Hartman (O'Reilly).

It is also necessary to verify that Samba detected support for a sufficient EA interface at compile time, which can be done by searching for the string XATTR in the output from smbd -b. The following output illustrates an smbd daemon with support for EAs:

$ smbd -b | grep XATTR
   HAVE_SYS_XATTR_H
   HAVE_ATTR_XATTR_H
   HAVE_FGETXATTR
   HAVE_FLISTXATTR
   HAVE_FREMOVEXATTR
   HAVE_FSETXATTR
   HAVE_GETXATTR
   HAVE_LGETXATTR
   HAVE_LISTXATTR
   HAVE_LLISTXATTR
   HAVE_LREMOVEXATTR
   HAVE_LSETXATTR
   HAVE_REMOVEXATTR
   HAVE_SETXATTR

If you find that Samba did not detect the appropriate EA support libraries at compile time, make sure that the ACL and EA development packages (normally named libacl-devel and libattr-devel) are installed correctly. If they are not, it is necessary to fix the problem and recompile Samba. Unlike Samba's ACL support, which must be manually enabled using the --with-acl-support option, the configure script detects EA support automatically. There is no need to pass additional options in most cases.

Once support for extended attributes has been verified, you can make use of the store dos attributes share parameter to store attribute sets for both files and directories. To illustrate how this parameter works, let's begin with a share named [documents] :

[documents]
    path = /data/documents
    read only = no
    store dos attributes = yes

Next create a directory named logs (assume that the share's UNC path is \\RAIN\documents) from the cmd.exe shell on a Windows XP client:

C:\> mkdir \\RAIN\documents\logs
C:\> attrib +h \\RAIN\documents\logs

You can then verify that the hidden attribute is set using the directory's properties dialog box from the Windows Explorer (shown in Figure). Make sure that you also enable viewing of hidden files through the Tools Options . . . menu in the Explorer windows.

Viewing the hidden attribute on a directory


When enabled, the store dos attributes option takes precedence over the attribute mapping parameters shown earlier. However, the DOS attribute policy can be set on a per-share basis, in case you are exporting multiple filesystem types with and without EA support.

Figure includes a list of the options related to DOS attributes.

DOS attribute options

Parameter

Value

Description

Default

Scope

delete readonly

boolean

Should Samba allow a user to delete a file marked as ReadOnly if allowed by the filesystem's permission?

no

Share

map archive

boolean

Maps the DOS Archive bit to the Unix owner execute permission.

yes

Share

map hidden

boolean

Maps the DOS Archive bit to the Unix world execute permission.

no

Share

map readonly

yes, no, or permissions

Maps the DOS Archive bit to the inverse of the Unix owner write permission or to evaluation of the file's ACL.

yes

Share

map system

boolean

Maps the DOS Archive bit to the Unix group execute permission.

no

Share

store dos attributes

boolean

If enabled, Samba stores the DOS attributes in the file or directory's extended attributes. This option is mutually exclusive with and takes precedence over the attribute mapping options.

no

Share


Permissions

There are two large-scale issues surrounding Unix permissions and Samba. The first, covered in this section, explores how Samba and its configuration file can take advantage of the Unix permission model. For example, how can Samba configure a group-accessible share or determine the initial permissions assigned to newly created files and directories? The second issue, covered in the upcoming section "Access Control Lists," concerns how Unix permissions and ACLs can be displayed in a format familiar to Windows users.

Let's begin with a common requirement: define a file share that can be used by members of a group in common for distributing files. In this example, users must be members of the Unix group named staff. Any new file or directory created within the share must be available to members of this group, so we need to ensure that new files and directories get created with the appropriate permissions.

Let's start with a basic share named [staff-docs]. We'll define a path and mark the folder writable:

[staff-docs]
    path = /data/staff-docs
    read only = no

Next we'll restrict access to the share to the staff group. The best security model involves multiple layers that reinforce the same policy. For example, if we choose to restrict access using the valid users option presented in the previous chapter, we should also make sure that the policy is effective if someone accesses the /data/staff-docs directory through a means other than Samba. This means that the filesystem permissions should be set to allow group access for staff but deny access for others outside of that group. The following series of commands (executed as root) grant ownership of the directory to root and allow access only to the group staff. Setting the setgid bit ensures that all files and subdirectories created in the share have the correct group ownership.

$ chown root /data/staff-docs
$ chgrp staff /data/staff-docs
$ chmod g+rwxs,o-rwx /data/staff-docs

The permissions should now appear as:

$ ls -ld staff-docs
drwxrws---  2 root staff 4096 2006-05-24 16:38 /data/staff-docs/

Now we can update the [staff-docs] share definition to restrict access via Samba as well:

[staff-docs]
    path = /data/staff-docs
    read only = no
    valid users = +staff

Adding the valid users option is not entirely necessary, because access to the share is ultimately determined by the filesystem permissions, but it does two things:

  • It documents the intent of the share, in case there is ever any question as to what the permissions should be.

  • It protects the share somewhat if the file permissions on /data/staff-docs are accidentally changed to something less restrictive.

The next requirement to address is that all files and directories created within the share must be modifiable by members of the Unix staff group. When you create a file or directory from a Unix shell, the umask setting frequently determines the default permission set. Samba ignores the environment umask setting and instead provides its own equivalent parameters. The create mask and create directory mask options consist of octal permission sets for files and folders, respectively, that combine with the permissions requested by the user using a logical AND. Any bit not set in the mask will be removed from the final permission set. The force create mode and force directory mode options also specify octal permission sets, but are combined with the permission set using a logical OR (after applying any creation masks). Therefore, any permission bit that is set in the force mode is included in the final permissions.

The complete list of permission filters used to derive the final set is given here in the order used by Samba:

  1. Apply any DOS attribute mapping options.

  2. Apply the create mask settings.

  3. Apply the force create mode settings.

The implication here is that the map hidden option, which acts through the world execute bit (see the earlier section "DOS Attributes"), does not work for new files if the create mask does not include this bit in its permission set.

For the sake of simplicity, assume use of the store dos attribute parameter in order to avoid any confusion with the user or group permissions. All permissions must be removed from the world set, the read and write bits must be set for files, and the read, write, and execute bits must be set for directories. The modified share definition appears as:

[staff-docs]
    path = /data/staff-docs
    read only = no
    valid users = +staff
    store dos attributes 
 
 = yes

    # permissions masks and modes
    create mask = 0770
    force create mode = 0060
    create directory mask = 0770
    force directory mode = 0070

Notice that we are not concerned with the owner permissions. This example lets the user do anything with their own files. All we care about is ensuring group access. This is a clean-cut example where all relevant users belong to the same group. How can this share be extended to include users that do not share a common group?

When a user connects to a share on a Samba host, the uid, primary gid, and list of supplementary gids comprises the user's token. This token is then examined by Samba or the operating system kernel to determine whether the user is authorized to access a resource such as a share or file. You can instruct smbd to add an additional group to the user's existing list of memberships. Thus, the force user and force group options may be used to set the uid or primary gid for a user's token when working within the content of a specific share.

Some operating systems limit the total number of groups to which a user may belong to 16 or 32. Check your operating system's documentation to determine the exact limit.


Thus, in order to allow members of the Unix helpdesk group to the [staff-docs] share, we must add that group to the valid users setting and then force a change to the primary group for every connected user to staff:

[staff-docs]
    path = /data/staff-docs
    read only = no
    valid users = +staff +helpdesk
    store dos attributes = yes
    force group = staff

    # permissions masks and modes
    create mask = 0770
    force create mode = 0060
    create directory mask = 0770
    force directory mode = 0070

Now members of both staff and helpdesk can successfully share files with each other.

This group share has one major drawback. Because the force group, create mask, and force create mode parameters define behavior for all files and within a share, we have to create a new share for every individual group. This can easily become an administrative nightmare, not to mention confusing for users who have to remember which share belongs to which group and at which drive letter the share is mounted. What is needed is a way to delegate access rights to portions of the share's directory tree.

The inherit owner and inherit permissions parameters provide the flexibility to propagate properties based on the parent of the new file or subdirectory. Using this new permission option, we can create a single file share that includes a subdirectory immediately below it for every group required. Let's look at an example using three groups: staff, helpdesk, and devel.

First, create the top-level directory of the share and one subdirectory for each of the three groups:

$ mkdir /data/groups
$ cd /data/groups
$ mkdir staff helpdesk devel

Next, restrict access (drwxrws---) in each of the three subfolders to the associated Unix group:

$ chgrp staff staff
$ chgrp helpdesk helpdesk
$ chgrp devel devel
$ chmod 2770 staff helpdesk devel

The final permissions appear as follows:

$ ls -l
total 12
drwxrws---  2 root devel    4096 2006-05-24 21:26 devel/
drwxrws---  2 root helpdesk 4096 2006-05-24 21:26 helpdesk/
drwxrws---  2 root staff    4096 2006-05-24 21:26 staff/

Finally, define the [groups] share in smb.conf like so:

[groups]
    path = /data/groups
    read only = no
    store dos attributes = yes
    inherit permissions = yes

The result is a single share that a user may mount at G: to access all folders for groups to which he belongs. This configuration is easier for both users and administrators.

However, very few things in life are free. If this new share solved all possible needs, it is unlikely that the force group and mask and mode family of options would still exist. In fact, the new [groups] share does not allow the sharing of files between users that have no groups in common. So you will be forced to choose between the two configurations shown in this section, should such conflicting requirements arise. One possible workaround is to make use of the [groups] share but also create [staff] using the /data/groups/staff directory in combination with the force group parameter:

[staff-docs]
    path = /data/groups/staff
    read only = no
    valid users = +staff +helpdesk
    force group = staff
    store dos attributes = yes
    inherit permissions = yes

Figure lists short descriptions of the inheritance parameters covered here, as well as the mask and mode parameters discussed earlier in the section.

File permissions and inherit options

Parameter

Value

Description

Default

Scope

create mask

octal permission set

Bits permitted in permissions when files are created in this share.

0744

Share

create directory mask

octal permission set

Bits permitted in permissions when directories are created in this share.

0755

Share

force create mode

octal permission set

Bits always set when a file is created in this share.

0000

Share

force directory mode

octal permission set

Bits always set when a directory is created in this share.

0000

Share

force group

Unix group

Primary group for a user connecting to the share.

None

Share

force user

Unix username

Primary user account for a user connecting to the share.

None

Share

inherit owner

boolean

Instructs Samba to set the owner of new files and directories based on the ownership of the immediate parent.

no

Share

inherit permissions

boolean

Instructs Samba to set the permissions of new files and directories based on the ownership of the immediate parent. Files do not inherit execute bits and the setuid bit is never inherited by files or directories.

no

Share




 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows