Example Shares

Knowing what the parameters are that control Samba share definitions and knowing how to use those parameters are two different things. Failing to see the forest for the trees, as it were, is easy to do when confronted with a list of Samba parameters. For this reason, this chapter concludes with a look at several common uses of Samba file and printer shares: the [homes] share, which provides users with data storage space for their own files; a share that can store program files, templates, and other shared read-only files; shares for exchanging files between users; a closer look at the [printers] share introduced earlier; and a “printer” share that generates PDF files rather than paper printouts.

The [homes] Share

Many Samba server computers function, in whole or in part, as centralized storage locations for users’ files. Users store their important files on the Samba server, enabling them to store more or larger files than would fit on their clients’ disks and to move from one client to another and access their own home files. This strategy can also greatly simplify backup; if users’ data files are on a single server, that server can be backed up more easily than can an entire network’s worth of files, thus providing more reliable insurance in case of hardware failure.

The user data storage function is so important that Samba provides a special share name just for this purpose: [homes]. This share functions much like an ordinary file share but with several important differences:

  • The share can be accessed via the user’s username, as in LINNAEUS for the user linnaeus. The share can also be accessed by the name HOMES, but this name is usually considered secondary.

  • In a Windows-dominated network, the username-based share name is typically what appears in network browsers. The HOMES name might not appear in browsers; this detail depends on configuration options, as described shortly.

  • The default path for the share is the user’s home directory, as specified in /etc/passwd or other account-definition files.

A typical [homes] share definition can be quite short:

[homes]
   comment = Home Directories
   writeable = Yes
   create mask = 644
   browseable = No

The Samba default is to make shares read-only, but because the intended [homes] shares enable users to store files that they create, changing this default is particularly important for these shares. The create mask = 644 parameter isn’t necessary, and, in fact, it’s undesirable if you want to preserve the archive bit on files. Using this parameter keeps the owner execute bit from being set, though, which may be desirable if users make heavy use of shell access or access via NFS or some other means that preserves this bit as such.

Ordinarily, shares on which you set browseable = No aren’t visible in file browsers, but [homes] shares are exceptions to this rule. Specifically, the browseable parameter applies to the share called HOMES; if you omit the browseable = No parameter or set it to Yes, a share called HOMES appears in clients’ network browsers. Part of the definition of the [homes] share is that a share named after the user who accesses the server appears in the user’s browse lists. (Only the home share for the user who accesses the server is displayed; users won’t see other users’ home shares, although they can be accessed by entering their names directly.)

This example share doesn’t specify a directory or path; it relies on the [homes] default. Although you can set a directory for the share, setting a static directory is usually undesirable. If you want to provide users with different home directories for remote text-mode or GUI logins than for Samba access, you can specify a Samba directory that is unique for each user by including variables such as %S, %u, or %U; these variables all expand to values related to the username. (In many cases, they expand to the same value.) For instance, you might set the path like this:

path = /home/samba/%u

Tip

Some clients, such as the BeOS network browser, don’t deliver a username until after they’ve retrieved lists of shares. For these network browsers, a [homes] share will be invisible unless you set browseable = Yes. Such clients might also not work well if you use a %S (share name) variable in a [homes] share’s path or directory parameter.

Many sample smb.conf files include [homes] shares, so this share may already exist on your server. Of course, if you don’t need it, you can delete it or change the definition to suit your particular needs.

A Windows Program Share

Samba servers can also be used as central repositories for files that many clients must access in a read-only manner—program executables, templates, clip art, fonts, and so on. Most users have no need to write to such shares, so most users receive read-only access. Somebody must maintain these shares, though, so a write list parameter provides an exception to the rule:

[programs]
   comment = Program Files for All Users
   path = /usr/share/samba/windows-programs
   write list = linnaeus, mendel
   force user = linnaeus
   force group = users
   read only = Yes
   create mask = 660
   directory mask = 770

In addition to the write list, this example share includes force user and force group parameters. These parameters force all files to be owned by a single user and group; even those files written by mendel will be owned by linnaeus, which makes for a cleaner on-server set of ownerships; however, this also means you can’t track whoever installed a particular file. These parameters also guarantee that all users will be able to read the files in the share, at least assuming that no files are written to the share through non-Samba means. Note that the force user parameter in conjunction with write list does not give all users write access to the share; write list applies to users’ true logon usernames, not their identities as determined by force user.

If you create a share like this, be sure to set appropriate permissions on the share’s directory (/usr/share/samba/windows-programs in this example). If you don’t give linnaeus write access to the directory, neither linnaeus nor mendel can store files in the share. You may also want to consider local Samba server security issues. For instance, if the share contains files that shouldn’t be accessible to some non-Samba users of the server, you should set create mask and directory mask parameters that deny world access (as in the example) and ensure that these users aren’t in the group specified by force group.

File-Exchange Shares

A read-only share such as the [programs] share is relatively straightforward to configure. A share that’s used for data exchange between users is much more complex because you must decide how to set ownership and permissions that enable those who should be able to write to files to do so, while preventing those who shouldn’t. Several approaches to solving this problem exist:

Shared access to [homes] directories

You can set permissions on users’ home directories such that they can read each others’ files. If necessary, you can create local Linux groups and enable read access to group members while denying world access, thus providing support for groups of users. One drawback to this approach is that users will have to type in their collaborators’ usernames when accessing shares; they won’t be able to browse directly to those directories. (Creating symbolic links between users’ home directories from Linux may provide a partial fix to this problem.)

Multiple file exchange shares

You can create several shares for file exchange, giving different groups access to different shares. You can use valid users or invalid users to control access. Using Linux groups and permissions on files in shares also works to this end. Depending on your needs, using multiple sharing directories can be awkward because it clutters your list of shares if you need to create shares for many different groups

One big happy file exchange share

You can create a single share with lenient permissions—say, setting create mask=666 and directory mask=777 or using force user to set ownership of all files to a single user. The effect is that all users can read and write all files in the share. This can be a good approach on servers on which you don’t need to worry too much about keeping files from particular groups of local users. Even if that’s the case, judicious use of such a share may be acceptable, but users will have to be warned against placing sensitive files on the data-exchange share.

One big exchange share with internal security

If you use the inherit permissions = Yes parameter, you can use a single file-exchange share but maintain internal security by setting up subdirectories with different ownership and modes. For instance, one subdirectory might have 777 (rwxrwxrwx) permissions, enabling anybody to read and write it, whereas another subdirectory might have 770 (rwxrwx---) permissions, enabling members of its group to use it to exchange files while keeping it off-limits to other users. This approach is very flexible, but you need to give some thought to the local Linux permissions on the subdirectories. You also need to create these subdirectories from Linux. Users are likely to find this scheme confusing, but giving the subdirectories descriptive names, such as dna-analysis-group or instructors-only, should help on that score.

Precisely how you would configure such a share depends on which approach you take and on your Linux server’s local security configuration. For one example, consider this file share:

[sanescientists]
   comment = Share for Use by Sane Scientists Only
   path = /usr/share/samba/sane
   valid users = @sane, linnaeus, mendel, curie
   writeable = Yes
   force group = sane
   create mask = 660
   directory mask = 770

[madscientists]
   comment = Share for Use by Mad Scientists Only
   path = /usr/share/samba/mad
   valid users = @mad, morbius, moreau, frankenstein
   writeable = Yes
   force group = mad
   create mask = 660
   directory mask = 770

These two shares, in combination, provide separate file-exchange areas for two groups of users. The first grants access to all members of the Linux sane group, plus three others who might or might not be members of that group. The second share does the same for the mad group and three other users. You can include a user in both groups if you like, in which case that user has access to both shares. For instance, you can place the user jekyl in both the sane and mad groups, or add the user explicitly to one or both shares’ valid users lines. If you want to give one group read-only access to another group’s shares, add the members of both groups to the share’s valid users line but use read list to restrict some users’ access to the share.

Another way to implement a similar system is to create a single share:

[scientists]
   comment = Share for Use by All Scientists
   path = /usr/share/samba/scientists
   valid users = @sane, @mad
   writeable = Yes
   inherit permissions = Yes

You then create subdirectories within the share’s directory with appropriate permissions set to enable only members of particular groups to access the directories. The result might look like this, as viewed using Linux’s ls:

# ls -l /usr/share/samba/scientists
total 8
drwxrwx---  2 root mad  4096 May  2 14:47 mad
drwxrwx---  2 root sane 4096 May  2 14:47 sane

The result is that members of the mad group can exchange files in the mad subdirectory, and members of the sane group can exchange files in the sane subdirectory. As configured, members of each group can’t view the contents of or read files from the other group’s subdirectory unless the individual is a member of both Linux groups. By changing permissions on the directories to 775 (rwxrwxr-x) rather than 770 (rwxrwx---), you can enable members of the groups to read but not write files in each others’ directories. Because of the reliance on the local Linux groups, this scheme doesn’t work well if some users aren’t members of the underlying groups; this is the reason the individual users (linnaeus, morbius, and so on) were omitted from the valid users line in the share definition. You should also attend to ownership and permissions on the share directory itself; depending on its settings, users could create new subdirectories, which can complicate your security settings.

Tip

Both examples omit the nt acl support parameter, which defaults to Yes. As a result, Windows NT/200x/XP users can set ACLs on their files, which will complicate access permissions. Of course, these ACLs won’t help users read files if the users can’t read the shares or directories in which they’re stored, but if users can read the directories, ACLs can broaden or restrict access to specific files, particularly if the underlying filesystem supports ACLs.

These are just two examples of common-access file shares. Many variants and alternatives are possible, that use Samba’s security features, Linux’s security features, or an interaction of the two. As a general rule, it’s best to start with a simple security system; trying to use too many sophisticated features can lead you into trouble if you forget an important consequence or interaction.

The [printers] Share

Most print servers use a single [printers] share to make all printers available. This share can consist of just a few lines, but it relies on a few global settings, and some of its implications deserve elaboration. First, before defining a [printers] share, be sure to set the following parameters in the [global] section of smb.conf:

printing = CUPS
printcap name = CUPS
load printers = Yes
printer admin = gutenberg
guest ok = Yes

In this example, the printing and printcap name parameters are both set to CUPS, which tells Samba to use CUPS for printing, including using CUPS’ own API for determining what printers are available. Of course, if you use another printing system, you’ll change these parameters appropriately—say, to printing = LPRng and printcap name = /etc/printcap.

Tip

Samba provides CUPS support as a compile-time option. If Samba wasn’t compiled on a system with appropriate CUPS development libraries installed, or if CUPS support was explicitly disabled, Samba won’t include the necessary tools to use the CUPS API. In this case, you can still use printing = CUPS (Samba will use old-style printing commands rather than the CUPS API to submit print jobs). You may need to set printcap name = /etc/printcap, though. If Samba doesn’t find your printers, try making this change. In fact, CUPS provides compatibility commands, so it should work even if you set printing = LPRng, printing = BSD, or certain other values.

The load printers = Yes parameter tells Samba to read information on available local printers from the file pointed to by printcap name (or, if printcap name = CUPS, to read the data using the CUPS API). By itself, this doesn’t do anything; only if you provide an explicit [printers] share does this parameter have any effect.

The printer admin line is optional; it sets the Linux username of a printer administrator—a user whose accesses to printer shares are done as if by root. This user should be able to delete others’ print jobs and otherwise perform maintenance on the queues.

The guest ok = Yes parameter tells Samba to accept guest access to the printer shares. This can be handy if you don’t want to maintain a user database on a dedicated print server, but you’ll need to adjust the global map to guest and guest account parameters. Enabling guest access also opens the system to potential abuses, particularly if the server is accessible to the Internet at large. (Imagine coming in one morning to discover that a high-speed, high-capacity printer has printed its entire load of paper with completely black pages, wasting both paper and toner or ink.)

Once you’ve set the global options, you can create a [printers] share. This share is likely to be fairly uninteresting on the surface:

[printers]
   comment = All Printers
   path = /var/spool/samba
   printable = Yes

Once this share is defined, and Samba either detects the changes (which it should do after a few minutes) or is restarted, you should see printer shares corresponding to all of your local printers that appear in clients’ network browsers. The shares won’t be usable, though; you must first install printer drivers on the clients, as described in Section 4.4.

Using a [printers] share doesn’t mean that you’re restricted from creating other printer shares. You can do so in either of two ways:

  • You can create a separate printer share using a name that doesn’t correspond to a print queue on the underlying Linux computer. This share will be presented to users in addition to the shares created by the [printers] share.

  • You can create a printer share that uses the same name as one of the printer queues on the underlying Linux computer. This share will override the share of the same name created by the [printers] share.

The shares generated by [printers] may be PostScript printers, non-PostScript printers that appear to clients as PostScript printers because of the use of Ghostscript in the Linux printer queue, or non-PostScript printers with raw Linux printer queues for which native printer drivers are necessary on the clients. In fact, you can provide a mixture of share types; the [printers] share simply doesn’t care.

A PDF-Generation Printer Share

Samba printer shares can be unusually flexible. This flexibility is derived, in part, from the print command parameter, which enables you to bypass the usual print processing. In fact, you can do some extremely complex and unusual things with this parameter, but in this section I describe a use that’s at least related to printing: creating Portable Document Format (PDF) files.

Several tools exist to generate PDF files from various formats. One of these is almost certainly already installed on your Linux computer: Ghostscript. In addition to generating output in formats that can be printed by your printer, Ghostscript can generate several common file formats, such as Tagged Image File Format (TIFF), Portable Network Graphics (PNG), and PDF. To create a Samba share that generates a PDF file, you call Ghostscript (with appropriate parameters) as the print command:

[makepdf]
   comment = Share to Make PDFs
   path = /var/spool/samba
   printable = Yes
   print command = gs -dNOPAUSE -dBATCH -q -sDEVICE=pdfwrite \
                   -sOutputFile=%H/%s.pdf; rm %s

When the MAKEPDF share receives a PostScript file, it passes it through Ghostscript (gs), specifying various parameters to generate PDF output without prompts and saving the output as %H/%s.pdf. Because %H is the user’s home directory and %s is the print job’s filename, the result is a file whose name begins with the Samba print job name and ends in .pdf. This filename is likely to be ugly, but it will at least be unique. The print command line ends with rm %s, which deletes the original print job, keeping it from cluttering the disk.

Of course, the [makepdf] share, as just presented, requires users to have access to their home directories, presumably through a [homes] share. If this isn’t true of your system, you can deliver the results in some other ways. For instance, you might have Samba email the PDF files to users. If necessary, you can write a script that passes the file through Ghostscript, looks up users’ email addresses in a list, and sends the file. Then call the script on the print command line, passing it whatever Samba variables you need, such as the print job filename (%s) and the username (%u or %U).

To clients, this particular share is indistinguishable from a real printer’s share. Because it expects PostScript input, you should install PostScript drivers on clients—ideally a fairly generic PostScript driver. Instead of printed output, though, users will find PDF files in their home directories soon after printing documents. This share can be a good way to provide basic PDF-generation capabilities to all users in all their programs that can print. It might not be enough for all functions; some dedicated PDF-generation tools support features that aren’t available through Ghostscript or Windows PostScript printer drivers.

Tip

You may want to install drivers in Samba for the share for automated delivery to clients, as described in Section 4.4. You can do so from a Windows client, as described in the Section 4.4.3.2. If you create a CUPS queue with the name of the PDF-generation share and set it up using a generic PPD file, you can then install the CUPS PostScript drivers for Windows as described in Section 4.4.3.1. You can then delete the bogus CUPS queue. Alternatively, you can generate the queue to print to a networked SMB/CIFS queue to begin with and point it as the Samba queue you’re creating. If you do the latter, CUPS clients can create PDFs by printing to CUPS, which then submits the print job to Samba.

Get Linux in a Windows World now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.