dcsimg

Using Samba Pseudo-Printers

The Linux Samba server supports the Server Message Block (SMB) protocol (also known as the Common Internet File System, or CIFS, protocol). Microsoft Windows uses SMB natively to share files and printers. Thus, Samba is most commonly used to turn a Linux box into a file and print server for Windows clients. Indeed, Samba is so effective that Samba enables Linux to sneak into otherwise Windows-domainated shops, with management none the wiser. However, Samba can be employed as much more than a file and print server. Samba supports many configuration options and it can perform a variety of complex tasks.

The Linux Samba server supports the Server Message Block (SMB) protocol (also known as the Common Internet File System, or CIFS, protocol). Microsoft Windows uses SMB natively to share files and printers. Thus, Samba is most commonly used to turn a Linux box into a file and print server for Windows clients. Indeed, Samba is so effective that Samba enables Linux to sneak into otherwise Windows-domainated shops, with management none the wiser. However, Samba can be employed as much more than a file and print server. Samba supports many configuration options and it can perform a variety of complex tasks.

One of the most powerful — and most often — overlooked Samba features is the print command parameter. With a little creativity and a supporting script or two, you can create a “utility” share that looks to the network like a printer share, but actually performs a wholly different task. For example, you can create “pseudo-printer” shares that enable Samba clients to create PDF files or burn CD-Rs. The Samba print command option is so flexible that it’s limited mainly by your imagination. One additional point deserves emphasis: you can use these techniques with clients that run any OS that supports SMB/CIFS operations, including Linux.

Let’s find out how to create pseudo-printer shares. Before reading further, you should be familiar with basic Samba configuration. If you’ve never set up a Samba server, consult the copious documentation that comes with the server, or read, “Introducing Samba,” in the April 2000 issue of Linux Magazine (available online at http://www.linux-mag.com/2000-04/newbies_01.html).

Basic Principles

A Samba printer share is much like a file share, but there’s one important difference: a printer share includes the option printable = Yes in the share’s smb.conf definition. Advanced printer shares sometimes include a print command line, as well. This line tells Samba how to print the file. If it’s omitted, Samba uses a fairly ordinary call to lpr to do the job. However, you can substitute another printing command if you’ve replaced your normal printing system with something more exotic.

But you can take that customization further: rather than replace the call to lpr with another printing utility, you can replace lpr with a script that you write. This script can do anything that you’d like with the “printed” file. In fact, by having the client submit an archive file such as a tarball or a .zip file, you can have the Linux Samba server process a large set of files submitted by the client. All of this works because printing in SMB/CIFS works just like storing a file on a file share — the client passes a single file to the server, which processes it in some way.

Of course, there are a few rules to obey. The print command line can accept several Samba variables, the most important of which are summarized in Table One. To be effective, you must normally pass at least the %s parameter to your custom script. %s specifies the name of the file sent by the client — your own script needs this information. You may also want to include some other parameters if you want your share to return information to the user or permanently store files in the user’s home directory. No matter how many parameters you specify, your script must extract the Samba parameters as command-line parameters.





Table One: Important Samba variables and their meanings













VariableMeaning
%gPrimary group of %u
%GPrimary group of %U
%HHome directory of %u
%jPrint job number
%MDNS name of client
%PPath to the root directory of the share (does not work with all versions of Samba)
%sFilename of the file to be printed
%SName of the share
%uEffective Linux username
%URequested Linux username

Some pseudo-printer shares may also require access to hardware resources such as a tape drive. Two users can’t simultaneously write to a tape, so you’ll have to accept the risk of conflict, use the max connections parameter to limit the risk by limiting how many users can simultaneously connect to one share, or write a queueing mechanism to handle the conflict. A queueing system is too complex to describe in this article, so let’s use max connections alone. This is fine for a small network where it’s obvious when the resource in question is being used.

Once the script is written and the share is ready for use, you must have some way to submit a job to the print queue. On Linux clients, you can use smbprint, which is actually a script that calls smbclient to submit a print job. In Windows, you can use the COPY command to send a file to the print queue without passing it through a Windows printer driver. In either case, you can use a script to help automate the process.

Creating PDFs

With the background out of the way, it’s time to look at an example. Suppose you want to provide a pseudo-printer to create PDF files from documents generated in any type of application. Listing One demonstrates a Samba share that accomplishes the job. (Listing One is just part of a larger smb.conf file.)




Listing One: Creating A PDF-creation share


[smbpdf]
comment = PDF Generator
path = /var/spool/samba
printable = Yes
print command = gs -dNOPAUSE -dBATCH -q – \
sDEVICE=pdfwrite -sOutputFile=%H/%s.pdf; rm %s

This configuration is very similar to a conventional printer share. The main difference is that it uses Ghostscript (gs) to process the file rather than lpr or a similar printer queueing tool. Listing One sends the file through Ghostscript using the pdfwrite driver, which generates PDF output. The -sOutputFile parameter tells Ghostscript where to save the file — in this case, it’s the user’s home directory (%H), using a name that’s based on the Samba print queue name. The script also includes rm %s to delete the file from the queue. Without this command, files would build up in the queue, clogging the hard disk. When you restart Samba, the share should be available and ready for use. (You can restart Samba on most distributions by typing /etc/rc.d/init.d/ samba restart or something similar.)

To use this share, a user configures a printer queue on the client system as if smbpdf were a real printer. The standard Apple LaserWriter drivers on a Windows system tend to produce fairly clean PostScript code that Ghostscript can parse without difficulty. You can print to this share from other Linux systems by configuring the Linux print clients to use an SMB/CIFS printer share. In all cases, users must hunt for their print jobs in their home directories on the Samba server system.

Using a pseudo-printer share to generate PDF files is just the beginning. With a custom script, you can perform much more complex operations, and can also process arbitrary types of data files.

Creating CD-Rs

CD-Recordable (CD-R) and CD-Rewritable (CD-RW) drives are now fairly common, but not universal. Many computers still lack these devices. On a small network, it’s quite possible that just one computer will have a CD-R(W) drive, but it’s desirable to let any user access that drive. One way to share the drive is to use a Samba pseudo-printer share to automate the task of creating CD-Rs.

Listing Two shows a Samba pseudo-printer share that, in conjunction with the shell script shown in Listing Three, creates a CD-R from files sent in a .zip archive file from the client. (Like Listing One, Listing Two is only one share in a larger smb.conf file.) Add Listing Two to your smb.conf file and copy Listing Three into its own file, /usr/local/bin/smbcdr. Set execute permissions on this file by typing chmod a+x /usr/local/bin/smbcdr. You must restart Samba to make the share accessible.




Listing Two: Defining a Samba CD-R share


[smbcdr]
comment = Create a CD-R
path = /var/spool/samba
printable = Yes
max connections = 1
print command = /usr/local/bin/smbcdr %H %s %U /var/spool/samba




Listing Three: The smbcdr script burns files to a shared CD-R(W) drive


#!/bin/sh
HomeDir=$1
ArchiveFilename=$2
Username=$3
SharePath=$4
TempPath=/tmp/cdr/$ArchiveFilename
MaxCdrSize=665600

mkdir -p $TempPath
cd $TempPath
unzip $SharePath/$ArchiveFilename
rm $SharePath/$ArchiveFilename

# Check to see if CD-R is small enough to burn
CdrSize=`du -sk $TempPath | cut -f 1`
if [ $CdrSize -lt $MaxCdrSize ]
then
mkisofs -J -r -o $HomeDir/image-$ArchiveFilename.iso \
-log-file /tmp/$ArchiveFilename ./
cdrecord speed=2 dev=4,0 $HomeDir/image-$ArchiveFilename.iso
cat /tmp/$ArchiveFilename | mail -s “CD-R Creation finished” \
$Username
rm $HomeDir/image-$ArchiveFilename.iso /tmp/$ArchiveFilename
else
mail -s “Too many files to burn CD-R ($CdrSize kilobytes)!” \
$Username
fi
cd ..
rm -r $TempPath

As you can see, the actual Samba share isn’t very complex, although it passes several variables to the script it uses to actually burn the CD-R. (With Samba 2.0.x, you can pass the %P variable instead of the share’s home directory as set on the path line, but in the 2.2.x versions, %P doesn’t work in this context.) Most of the actual work is done in the smbcdr script shown in Listing Three. This script does several things:


  • The script sets the name of the temporary directory that will hold the files to burn, and sets the $MaxCdrSize variable to the maximum CD-R size in kilobytes. Listing Three assumes a 650MB CD-R.

  • The script sets up a directory to hold the CD-R files and unzips the archive received from the client in this directory. The script also removes the original archive file.

  • The script computes the size of the files in the CD-R holding directory and assigns this value to the $CdrSize variable.

  • The script uses the computed size of all files to determine whether or not to try to burn a CD-R. If the files fit on a CD-R, the script creates an image file using mkisofs, and then burns the file to CD-R using cdrecord. You must customize the cdrecord command for your system! Specifically, you must set the speed value to something appropriate for your burner and set the SCSI ID of the burner with the dev parameter.

This configuration, or something very close to it, should work for most Linux systems that have CD-R(W) burners. You must, however, set the cdrecord binary to be SUID root (typing chmod o+s /usr/bin/cdrecord should do the trick on most systems). Alternatively, you could use force user in the Samba share definition to set the username to a user who can run cdrecord.

An important caveat is that your Samba server must have adequate free disk space in critical directories. Listing Two and Listing Three store potentially large temporary files in /var/spool/samba, /tmp, and the user’s home directory. You can change these directory locations to wherever your system has space, but in all cases, you should have enough disk space to store two CD-Rs worth of data.

You can use this pseudo-printer from Windows, too, by typing a command such as the following in a DOS window:


C:> COPY FILE.ZIP
\\LINUXSERVER\SMBCDR

Of course, the Samba server’s CD-R drive must contain a blank CD-R before you type this command, or it won’t work.

You can use this share from Linux clients, too. Use the Linux zip utility to create an archive file, then transfer it using smbclient or the smbprint script. For instance, you might type smbclient //linuxserver/smbcdr to make the initial connection, then type putfile.zip to create a CD-R from the files in file.zip.

The Sky’s the Limit

The examples presented here are just that — examples. You can create Samba pseudo-printer shares to do just about any type of data processing you like.

In many cases, other tools can perform the job as well as Samba. But if you already need to use Samba, creating Samba shares that run your own scripts can simplify your configuration and reduce the number of servers running on the system, which is a valuable security boon.




Listing Four: A DOS/Windows script to burn a CD-R on a Linux pseudo-printer share


C:\APPS\INFOZIP\ZIP.EXE -r0 C:\WINDOWS\TEMP\CDR.ZIP %1
COPY C:\WINDOWS\TEMP\CDR.ZIP \\LINUXSERVER\SMBCDR
DEL C:\WINDOWS\TEMP\CDR.ZIPx



Roderick W. Smith is the author or co-author of ten books, including Linux Samba Server Administration and Advanced Linux Networking. He can be reached at rodsmith@rodsbooks.com. You can download the code used in this article from http://www.linux-mag.com/downloads/2003-01/guru.

Comments are closed.