One of Samba's most exciting features is the ability to run scripts. You can feed commands to Samba in various ways, and Samba will execute those commands in specified circumstances. You can use this ability to have Samba perform tasks you might not ordinarily associate with a file and print server. This section is devoted to this capability. It starts with a description of two scripting features ( preexec / postexec scripts and pseudo-printers) and concludes with several examples of how to use these features.
Using preexec and postexec Scripts
Samba provides parameters that allow it to run commands that you specify whenever a user logs into or logs out of a share. These parameters are preexec and postexec for login and logout commands, respectively. You specify the commands you want executed as the value of the parameter. For instance, if you want Samba to send e-mail to billy @harding.threeroomco.com whenever a share is accessed, you might include the following parameter in the share's definition:
preexec = mail -s "Share being used" firstname.lastname@example.org
Whenever somebody logs into the share, Samba sends a message in that user's name to email@example.com . The mail command's syntax gives the message the subject Share being used , and because the message is sent in the name of the user who made the connection, the message recipient knows who logged in.
The postexec command works in the same way, but it sends a message whenever the connection to the share is terminated . Because of the way Windows clients handle SMB/CIFS shares, this won't happen immediately after a user closes a window that was opened through Network Neighborhood or My Network Places, but it will happen eventually.
Two variants on these parameters are root preexec and root postexec . These parameters work just like their non- root namesakes, except that they execute the commands you specify as root . This can be useful if you need to execute some privileged commands, but you should be cautious in using these parameters. If you make a mistake in your command specification, you can cause problems or give a miscreant root access to your computer.
Samba supports many variables, summarized in Table 7.1, which can be used as part of a command specification. By including these variables , you can customize the operation of a preexec or postexec script for individual users, clients, client OSs, and so on. (Some of the variables in Table 7.1 are intended for use in printer shares.)
The preexec and postexec parameters are intended to let you execute commands that might be useful in preparing a share to be used, like a command to back up Linux configuration files that a Windows user might mistakenly delete from a home account. The limits of what you can accomplish with these commands are determined by your imagination , however. Some possibilities include the following:
Table 7.1. Variables Available in Samba
Some of these possibilities are more likely to be useful than others. Some (particularly the administrative help share) are potentially risky from a security point of view, but could conceivably be useful in some limited situations. The point of these descriptions isn't so much to suggest what you should do with preexec and postexec scripts, but to illustrate the range of things that are possible with them.
For some uses, you may want to limit the number of people who can use a share at once. You can do this with the max connections parameter, which tells Samba how many simultaneous connections it will accept to a share. To keep users from trampling each others' efforts, set max connections = 1 . This may have the undesirable side effect of preventing access if a user reaches a share through Network Neighborhood or My Network Places, however, because as noted earlier, Windows tends not to close such connections in a timely fashion.
Another opportunity for scripting derives from the print command parameter used in printer shares. Although intended for specifying commands to send a print job to a printer, you can put anything in this parameter that you like, just as you can specify any command in a preexec or postexec parameter. You can use this facility to operate on PostScript files to generate effects that aren't what you'd normally call printed output. By bypassing the Windows printer drivers, you can also use it to process any single-file data you care to generate on a Windows system. Possibilities for use of this parameter include:
As with preexec and postexec scripts, you can easily do dangerous things with print command . Be cautious with it, particularly if you find the need to use the force user parameter to set root privileges.
You can use the variables described in Table 7.1 with print command (in fact, some of them, like %s , don't make sense with preexec or postexec ). The %H variable is particularly helpful in delivering output back to the user who initiated the jobyou can use this to specify a path in which files are to be placed upon completion.
One advantage of print command over preexec and postexec scripts is that there's no problem with connections staying open, and thus the postexec command not executing for a while. Once the client submits the print job, the print command springs into action. Two consecutively submitted jobs could conceivably damage each others' files, though, depending on the nature of the operations involved.
Example: CD Burning
One example of scripting in action is using a Samba server as a CD creation platform. Suppose you've got a small office with a dozen clients and just one CD-R or CD-RW drive. Any of the clients may have a legitimate need to create a CD. You could put the CD-R drive on the Samba server and allow users to copy files to this server and then use a Linux CD-R creation tool to create CDs. This process requires training all the users how to use the CD-R creation software, though, and it opens the possibility for problems because users may leave files lying about, thus chewing up space on the hard disk. You can use Samba's scripting features to automate the process, eliminating many of these problems.
Burning a CD via preexec and postexec Scripts
Let's assume that you've set aside a Samba share for CD creation. This share will be used for nothing but CD creation. To burn a CD via preexec and postexec scripts, you need to have Samba perform several tasks:
The following share accomplishes these tasks, albeit with a bit of help:
[cd-create] path = /home/samba/cd-create create mask = 0666 directory mask = 0777 read only = No max connections = 1 preexec = /bin/rm -r %P/* postexec = /usr/local/bin/create-cd %H %P %U
The preexec parameter takes care of task 1. Task 2 is accomplished by normal Samba operations. Tasks 35 are handled by the postexec parameteror more precisely, by the /usr/local/bin/create-cd script, which appears in Listing 7.1.
Listing 7.1 Script to Create a CD-R Using preexec and postexec
#!/bin/sh # = Home directory of job submitter # = Directory of original files # = Username of job submitter mkisofs -J -r -o /image.iso cdrecord speed=2 dev=4,0 /image.iso mail -s "CD-R creation finished" rm /image.iso rm -r /*
To prepare this share, you must take the following steps:
When you've taken these steps, you can use the share. In Windows, you can mount the share by locating it in Network Neighborhood or My Network Places, right-clicking the share name, and choosing Map Network Drive from the pop-up menu. You'll then assign a drive letter to the share. Once you've mounted the share, copy files that you want burned on a CD to the share. You can move files around in the share, delete unwanted files, and so on. When you're ready to burn the CD, insert a blank CD-R in the CD-R drive and unmount the share by right-clicking its icon in the My Computer window and selecting Disconnect from the menu that appears.
Unfortunately, Windows sometimes doesn't disconnect the share even at this point, forcing you to log out or (in the case of Windows 9 x /Me) reboot the system. After some time (a few seconds or minutes), the server's CD-R drive should activate and eventually finish its operations, whereupon the create-cd script will e-mail the user that the job is done. It's then safe to remove the CD-R from the drive and test it.
The share definition and CD-creation script presented here are a bit rough around the edges. For instance, these scripts provide only very limited protections against two users trampling each others' work; if one tries to create a CD-R before another has removed a new disc from the CD-R drive, there'll be problems. These scripts don't report errors to the user. For instance, if the created image is too large to fit on a blank CD-R, the first indication of it may be when the disc gives problems when read. A more complex create-cd script might check for such potential problems and alert users to them or avoid the problems entirely. Finally, different versions of Samba treat the %P variable in different ways, so you may need to adjust the share accordingly .
Burning a CD via a Pseudo-Printer
Pseudo-printers provide a method of CD creation that's more convenient for Windows 9 x /Me clients, but that's somewhat less obvious than a regular file share. The idea for this share is to have the Windows client pass a zip file with the CD's intended contents. The share then calls a script that's a variant on the create-cd script to unpack the zip file and burn a CD-R from the resulting files. The basic Samba share definition looks like this:
[cd-print] path = /var/spool/samba printable = Yes print command = /usr/local/bin/print-cd %H %s %U %P; rm %s
As with the earlier share, you may need to adjust the use of %P . Specifically, you may need to replace it with /var/spool/samba . Most of the work is done by the print-cd script, shown in Listing 7.2.
You must configure this share and script in a similar manner to those used with the [cd-create] share and create-cd script. Specifically, the script needs to be executable, you should adjust the mkisofs and cdrecord commands for your system, and the cdrecord executable should be set SUID root . Once this is done, you can create a CD by sending a zip file to the share with the DOS/Windows COPY command, thus:
C:\> COPY FILE.ZIP \ SERVER \CD-PRINT
Listing 7.2 Script to Create a CD-R Using print command
#!/bin/sh # = Home directory of job submitter # = Filename of zip file # = Username of job submitter # = Path to zip file mkdir -p /cdr/samba cd /cdr/samba unzip / mkisofs -J -r -o /image.iso ./ cdrecord speed=2 dev=4,0 /image.iso mail -s "CD-R creation finished" rm /image.iso rm -r /cdr/samba
This command creates a CD-R with the contents of FILE.ZIP , assuming that SERVER is the name of the Samba server. You can place this command in a batch file (a text file whose name ends in .BAT ), using a variable for the zip filename:
COPY %1 \ SERVER \CD-PRINT
You can then call that batch file followed by the name of a zip file, as in MAKECD FILE.ZIP , if the batch file is called MAKECD.BAT . If you create a desktop icon that's a shortcut to this batch file, you can create a CD by dragging a zip file to it. Alternatively, you could create a batch file that zips a directory using a text-mode zip utility and passes that zip file to the CD- creation printer share. Windows users could then place files they want on the CD in a local directory and drag that directory to a desktop icon for the batch file to create a CD.
Like the CD-creation file share, the CD-creation printer share presented here is rough around the edges. There's no checking to be sure the image file size is reasonable, and if two users submit jobs in quick succession, there'll be problems. Using a more sophisticated print-cd script could work around these problems.
Example: Creating PDF Files
An example of using a printer queue in a more printing-oriented way is to create Adobe Portable Document Format (PDF) files from PostScript input. For this configuration, you use a Windows printer queue that's identical to what you might use when printing to a PostScript or Ghostscript-driven printer, complete with a PostScript driver. The Samba printer share looks like this:
[pdf-create] comment = Create a PDF file path = /var/spool/samba printable = Yes print command = gs -dNOPAUSE -q -dBATCH -sDEVICE=pdfwrite \ -sOutputFile=%H/%s.pdf %s; rm %s
This print command parameter calls gs , the Ghostscript executable. The -dNOPAUSE , -q , and -dBATCH options produce quiet and continuous output without requiring human intervention. The -sDEVICE=pdfwrite speci fication indicates that the output is to be a PDF file, and the -sOutputFile=%H/%s.pdf option specifies the output filename to be the same as the print job name but with .pdf appended and stored in the user's home directory. You could modify this share definition to e-mail the file back to the user or store it in some other location or under some other filename.