Linux in a Windows World/Sharing Files and Printers/Linux as an SMB/CIFS Client
Linux often functions as a tool for running Samba as a server on a network that's otherwise dominated by Windows systems. Sometimes, though, you might need to reverse this role and have Linux function as the client in an SMB/CIFS environment. Perhaps a few Linux desktop systems must access Windows servers; maybe a Linux system that works as a server for other protocols must do so. Whatever the details, the Samba package includes client tools, and the Linux kernel also supports accessing SMB/CIFS file shares. Thus, Linux can function in the client role, using Windows, Samba, or other SMB/CIFS servers on other computers.
This chapter covers several specific client roles for Linux on an SMB/CIFS network: using NetBIOS name resolution, accessing file and printer shares, and using GUI network browsers for Linux.
Using NetBIOS Name Resolution
As described in Chapter 3 and Chapter 5, NetBIOS provides a computer-naming system that's independent of DNS, which is used by most TCP/IP protocols. In fact, Windows enables its clients to use these NetBIOS names in place of DNS names for most protocols, at least for local computers. For this reason, some LANs rely heavily on these names, and if you want to refer to computers by name rather than by IP address from Linux, you may need to know how to configure Linux utilities to use these addresses. For the most part, this task can be handled with a setting or two in smb.conf. If your LAN doesn't use DNS hostnames for its local computers, though, you may want to expand this configuration to enable Linux to use NetBIOS names in non-SMB/CIFS tools, such as web browsers and email clients.
Setting Name Resolution Options in smb.conf
Most SMB/CIFS client tools in Linux support the use of NetBIOS names. These tools rely on libraries that ship with Samba and that are configured in the [global] section of your smb.conf file. In particular, you should review the name resolve order, wins server, and hostname lookups parameters, all of which are described in Chapter 3. For the most part, the default settings work well on small LANs that are configured to use broadcast name resolution. You might want to set hostname lookups = Yes if you want to specify computers by their DNS hostnames in smb.conf, though. If your network hosts an NBNS system, you may also want to point Linux systems to it with wins server.
If a computer functions as an NBNS system, do not set wins server. Even pointing the server to itself with this parameter can result in odd behavior.
The parameter that requires the most attention is name resolve order. This parameter takes one to four of several values: lmhosts, hosts, wins, and bcast. The default lookup order is lmhosts host wins bcast, which minimizes the use of network resources. You can change this order if you like, though, or even omit options entirely. For instance, suppose you know your lmhosts file is empty, and suppose you don't want to use DNS except as a last resort because of possible name conflicts. You might then include these lines in smb.conf:
name resolve order = wins bcast hosts wins server = 192.168.24.1
Using NetBIOS Name Resolution in Non-Samba Programs
In most cases, the NetBIOS name-resolution methods you set with name resolve order and other options in smb.conf apply only to Samba and related tools. These name-resolution methods have been split off into a library, though, and it's possible to splice this library into Linux's normal name-resolution system. When you configure Linux this way, you can use NetBIOS names in any Linux program that employs the normal name-resolution system, such as web browsers, mail clients, FTP clients, and so on. This can be a handy way to get name resolution working on a small network that doesn't have its own DNS server. (You'd presumably use your ISP's DNS server for handling names on the Internet, but it might not have entries for your local computers.)
Using NetBIOS names for non-SMB/CIFS tools can be convenient, but it can also cause problems. NetBIOS names lack Internet domain names, and so a few programs that rely on Internet domain names can choke if they're fed NetBIOS names. If DNS and NetBIOS names don't match, you can also cause problems when reverse lookups don't match forward lookups or when one name masks another one. These problems aren't always serious, but if you see strange error messages about failed lookups, you might want to consider using local /etc/hosts files or running your own DNS server for local use, as described in Chapter 15.
The first step to using NetBIOS name resolution in non-Samba programs is to check for the presence of the necessary support libraries. These appear under the name libnss_wins.so (typically with a symbolic link called libnss_wins.so.2), usually in /lib. If you can't find these files, you may need to install additional or newer Samba packages for your distribution. If you compiled Samba from source code, try typing make nsswitch from the Samba source directory, copying the resulting nsswitch/libnss_wins.so file to /lib, and creating a symbolic link called libnss_wins.so.2. Usually, you will need to type ldconfig to have the system recognize the new library.
Once the library is installed, you must configure Linux to use it. This task can be accomplished by editing /etc/nsswitch.conf. Look for the hosts line in this file. It probably contains entries for files, dns, and perhaps other name-resolution methods. Add wins to this list:
hosts: files dns wins
Linux tries name lookups in the order specified, so this example uses NetBIOS name lookups as the last resort. You might want to move wins earlier in the list, but doing so increases the odds for problems should a name be resolved in multiple ways and a program needs an Internet domain name.
Although the option in /etc/nsswitch.conf is called wins, the name-resolution system it enables works with both NBNS systems and broadcast name lookups. The libnss_wins.so library uses the NBNS computer specified by the wins server parameter in smb.conf, but it ignores the name resolve order parameter.
Accessing File Shares
One of the most complex topics in Linux SMB/CIFS client operations is file share access. Several tools exist to handle such accesses: the Samba smbclient utility, the smbmount tool for mounting shares, the standard Linux mount command, and the standard Linux /etc/fstab file. (These final three methods are all closely related to one another.) No matter what method you use, you should be aware of some of the limitations of file accesses using SMB/CIFS, as described later.
The smbclient program ships with Samba and is usually installed in the main samba package or in a package called samba-clients. This program is modelled after text-mode FTP client programs such as ftp. Basic use is fairly straightforward: type 'smbclient, followed by a NetBIOS name and share name in the form // SERVER/SHARE. The result is a prompt for a password followed by smbclients own prompt. You can then type FTP-style commands, such as dir, get, put, and exit. A typical session looks like this:
$ smbclient //MANDRAGORA/DDRIVE Password: smb: \> put chapter06.xml putting file chapter06.xml as \chapter06.xml (613.4 kb/s) (average 613.4 kb/s) smb: \> dir _Restore DHS 0 Sat Oct 18 13:15:50 2003 Recycled DHS 0 Sat Oct 18 13:17:28 2003 utils D 0 Sat Oct 18 13:37:28 2003 APPS D 0 Sun Oct 19 00:07:20 2003 drivers D 0 Sat Oct 18 15:47:42 2003 chapter06.xml A 11935 Fri May 14 22:20:28 2004 chapter05.xml A 64236 Fri May 14 22:19:50 2004 flashplayer7installer.exe A 658586 Sat Oct 25 11:20:54 2003 RECYCLED D 0 Sun Nov 2 12:07:38 2003 Font Navigator D 0 Mon Mar 1 12:55:40 2004 47889 blocks of size 65536. 44706 blocks available smb: \> del chapter05.xml smb: \> exit
By default, smbclient uses your login username as the SMB/CIFS username. You can change this detail, and several others, with smbclient parameters, including:
- -I IP-address
- If you use this parameter, smbclient connects to the IP address you specify, rather than resolving the machine name.
- This parameter suppresses the normal prompt for a password, which can be handy if you know the share doesn't require one.
- -U username[%password]
- If your username on the server is different from your Linux username, you can specify the correct username with this parameter. If you like, you can also include your password after the username, using a percent symbol (%) as a separator.
- -A auth-file
- The auth-file specified with this parameter contains a username, password, and optionally a domain, one to a line and labeled, as in username = linnaeus. You can use this option to deliver authentication information to smbclient in scripts.
- -c command string
- This option passes a series of commands to smbclient, separated by semicolons (;). This feature is most commonly used by scripts. It implies -N, so you must usually deliver a password to smbclient in some other way, such as via -A.
- -L server
- This parameter causes smbclient to display a list of services available on the specified server. You omit the usual server and share specification if you use this parameter.
- -M server
- You can send text to another system to appear as a WinPopUp message with this parameter. When you use this option, smbclient accepts text you type until you press Ctrl-D. Alternatively, you can use redirection operators to send a file to another computer. When you use this parameter, you omit the usual server and share specification.
This list of options only hits on the highlights; smbclient supports many more options, some of which are highly specialized. Consult the smbclient manpage for more details.
Once smbclient is running, you can type any of about 50 FTP-style commands. The most useful of these commands are:
- ? or help
- You can obtain a list of commands by typing one of these commands. If you follow it by the name of a command (as in help cd), smbclient displays basic usage information on the requested command.
- cd [ directory ]
- Type this command to change into a directory on the server.
- lcd [ directory ]
- This command changes the working directory on the Linux client.
- put local-name [ remote-name ]
- Upload a file from the client to the server with this command.
- get remote-name [ local-name ]
- This command transfers a file from the server to the client.
- ls [ mask ] or dir [ mask ]
- These commands are equivalent; they produce a directory listing from the server, optionally of a subset of files or from a subdirectory if you include an appropriate mask.
- rm mask
- This command deletes a file or set of files matching the specified mask on the server.
- rmdir directory
- This command deletes the specified directory on the server.
- rename old-name new-name
- Unsurprisingly, this command renames a file on the server.
- print filename
- This command submits a local file as a print job to a printer share. It's covered in more detail in Section 6.3.1.
These commands should be sufficient for most casual uses of smbclient. For information on more exotic commands, consult the smbclient manpage or use its internal ? or help commands.
Mounting Shares Using smbmount
Accessing SMB/CIFS shares with smbclient is sufficient in some cases, but sometimes you need more. For instance, you might want to directly access a clip art collection using a word processor or graphics program, without having to copy files to the local computer using a separate program. For this purpose, Linux supports mounting SMB/CIFS shares as filesystems in the Linux directory tree. You can do this using the smbmount or mount commands or by adding an entry to /etc/fstab.
All these SMB/CIFS mounting options rely on your kernel having SMB/CIFS client support. In 2.6.x kernels, this option appears in the File Systems → Network File Systems menu in the kernel configuration system, under the name SMB File System Support. (One option relies on the CIFS Support option instead, as described in Section 188.8.131.52.) Most distributions' stock kernels include this support, but if yours doesn't, you need to recompile your kernel or at least add this support as a module and compile it that way. Once you've added the necessary support to the kernel, you can use smbmount, which takes the following syntax:
smbmount //SERVER/SHARE mount-point [-o options]
As an example, typing smbmount //MANDRAGORA/DDRIVE /home/linnaeus/mandragora mounts the DDRIVE share from MANDRAGORA on /home/linnaeus/mandragora. Normally, though, this command prompts you for a password, so you must enter it. What's more, like smbclient, smbmount passes your current Linux username as the username for the server. Because only root may run smbmount by default, this means you may need to pass another username to the command or change the default in order to run it as an ordinary user. The former task can be accomplished by passing a parameter to smbmount with the -o parameter. Some of the more useful options you can pass in this way include:
- username= user
- You can specify a remote username other than your current username with this option.
- password= pass
- You can specify a password to be used with this option. (If you omit it, smbmount normally prompts for a password.)
Delivering a password on the command line is potentially risky; it briefly appears in ps outputs and also appears in your shell's command history. For this reason, you should avoid using the password option whenever possible.
- credentials= auth-file
- You can deliver a username and password in a file with this option, which points to a file with the same format as the credentials file for smbclient—the string username= followed by the username, and the string password= followed by the password on the next line.
- uid= UID
- This option sets the user ID (UID) that will own all the files on the share you mount. If you omit this option, files are owned by the user who runs smbmount.
- gid= GID
- This option works like uid, but it sets the group ID (GID) rather than the UID.
- fmask= mode
- You can set the mode (specified in octal format) of files on the remote share with this parameter. The default—if you omit this option—is based on the current umask.
- dmask= mode
- This option works like fmask, but it sets the mode for directories on the share.
- Pass this option if you know the share doesn't require a password; smbmount won't prompt for one.
- This option causes smbmount to mount a share read-only, even if the share supports write access.
- This option attempts a read/write mount and is the default.
The smbmount command accepts several additional parameters, most of which set fairly obscure options. Consult its manpage if you need more details.
As an example, consider this scenario: you want to mount the DDRIVE share from MANDRAGORA at /usr/share/clipart in such a way that all users can read the share and the user with a UID of 1027 can write to it. You want to use the username linnaeus and the password bu9N!nEp on the server. The following command accomplishes this goal:
# smbmount //MANDRAGORA/DDRIVE /usr/share/clipart \ -o uid=1027,fmask=644,dmask=755,credentials=/etc/samba/mandragora.creds
This command requires a credentials file (/etc/samba/mandragora.creds) with the following contents:
Credentials files are extremely sensitive. They should be set to be readable only by the user who'll use the SMB/CIFS client programs that read them.
When you're done using a share, you can unmount it with the smbumount command, which works much like the standard Linux umount command:
# smbumount /usr/share/clipart
One problem with the smbmount command as just described is that only root may use it. This problem can be overcome by setting the set-user-ID (SUID) bit on the smbmnt helper program and on smbumount:
# chmod a+s /usr/bin/smbmnt /usr/bin/smbumount
After you make this change, ordinary users may run smbmount and smbumount. They must, however, own their mount points. This configuration can be handy on multiuser systems or when shares should be mounted and unmounted on a regular basis. On the other hand, any SUID root program is a potential security risk, so you shouldn't set this option unless it's necessary. If a share should be mounted at all times, you might consider adding it to /etc/fstab, as described in Section 6.2.4.
Some versions of smbumount often have problems identifying shares that are mounted by smbmount. If you see the error message:
/mount/point probably not smb-filesystem
you need to use umount as root to unmount the filesystem.
Mounting Shares Using mount
An alternative to smbmount that's very similar is to use the standard Linux mount command. To use this command, specify the smbfs or cifs filesystem type codes. These codes correspond to two different SMB/CIFS clients in the Linux kernel. The first, smbfs, is the older of the two. It works with any common SMB/CIFS server, using TCP port 139 and NetBIOS over TCP/IP, and is quite reliable. The cifs code is much newer (it was only added as a standard part of the kernel with the 2.6.x series) and isn't quite as reliable. This driver works using newer "raw" SMB/CIFS over port 445, which isn't supported by older servers such as those that ship with Windows 9x/Me. The cifs driver supports some more recent low-level SMB/CIFS features, though, and so it might eventually provide faster operation.
Ordinary users can't use mount as described here; however, if you add an entry to /etc/fstab, as described in Section 6.2.4 Section 6.2.4, and if that entry includes the user, users, or owners option, ordinary users can use mount to mount a share. To do so, users specify the mount point only, rather than the full set of options mount normally accepts.
Using the smbfs driver
To use the smbfs driver, you must include support for it in the kernel, as described in Section 6.2.2. Once that's done, you can use mount to do the job by passing it a filesystem type code of smbfs and a share specification like the one you'd pass to smbmount. You can also use the same options that smbmount supports. For instance, you might issue a command like this:
# mount -t smbfs //MANDRAGORA/DDRIVE /usr/share/clipart \ -o uid=1027,fmask=644,dmask=755,credentials=/etc/samba/mandragora.creds
This command is equivalent to the similar one shown in the previous section. Like that command, it relies on a credentials file (/etc/samba/mandragora.creds). In fact, as a practical matter, the two commands are virtually identical. One practical difference, when typed at a shell prompt by root, is that you use umount rather than smbumount to unmount a share mounted via mount. Using mount also enables you to use mount-specific options not provided by smbmount, such as the remount option to -o, which tells Linux to remount a filesystem with different options.
Using the cifs driver
The cifs driver was added to the 2.6.x kernel series as a way to support certain features not supported by the smbfs driver. Most of these are low-level features relating to protocol operational details, though, so they have no obvious consequences to users or system administrators. (Some features, such as Kerberos and DFS support, are under development or are important in some environments, though.) This driver works exclusively with recent servers, such as Samba and Windows 200x/XP. The driver uses "raw" SMB/CIFS over TCP port 445, rather than the port 139 that's used by earlier SMB/CIFS implementations. As a practical matter, the main reason to use the cifs driver is if you want to close off port 139 on the server (say, for security reasons). One other practical difference between the drivers is that cifs accepts DNS hostnames but not NetBIOS names for the server specification; smbfs accepts both name forms. (However, if you configure NetBIOS name resolution for Linux TCP/IP applications, as described in Section 6.1.2, cifs will accept NetBIOS names.)
The cifs driver works with a helper application, mount.cifs. Recent distributions and versions of Linux ship with this tool. If yours didn't, you can find it at http://linux-cifs.samba.org, along with assorted other cifs documentation and tools, including the latest version of the driver. (This may be more recent than the version included in the latest Linux kernel.)
In theory, cifs accepts basically the same set of mount options as smbfs, so you should be able to use it in precisely the same way. In practice, though, cifs is still new enough (at least, as of the 2.6.7 kernel) that some options don't work or have only recently begun working. The credentials option didn't work properly until somewhere between the 2.6.4 and 2.6.6 kernel, for instance. If you run into problems with the cifs driver, therefore, you may want to drop back to the smbfs driver, at least for troubleshooting purposes.
My experience with cifs is that it's not as stable as smbfs. Sometimes it refuses to mount a share for no apparent reason, and when a share does mount, file accesses are sometimes unreliable. All in all, then, I recommend you avoid cifs if possible. On the other hand, raw SMB/CIFS over TCP port 445 supports features that aren't supported using the older NetBIOS over TCP port 139, such as Unicode filenames, better locking, and so on. Thus, it's possible that cifs will one day provide superior features and performance, compared to smbfs.
Both smbmount and mount can be used by root to mount shares on an as-needed basis, and smbmount can be used by ordinary users if its support programs are given SUID root status. What if you want to make a share available at all times, though? You can place a mount or smbmount command in a startup script, of course, but as a general rule, the way filesystems are mounted automatically in Linux is to use entries in /etc/fstab. You can do the same with SMB/CIFS shares, using the filesystem type codes smbfs or cifs, just as you would with the mount command.
An /etc/fstab entry for an SMB/CIFS share looks much like any other /etc/fstab entry, except that it uses an SMB/CIFS server/share specification rather than a device filename and smbfs or cifs options—which are the same as those for smbmount, as described earlier. All told, entries might resemble these:
//MANDRAGORA/SHARED /mnt/shared smbfs \ credentials=/etc/samba/creds/shared,uid=1027,gid=100,fmask=666,dmask=777 0 0 //tulip/CLIPART /mnt/clipart cifs guest 0 0
This example mounts two shares: //MANDRAGORA/SHARED is mounted using smbfs at /mnt/shared, while //tulip/CLIPART is mounted using cifs at /mnt/clipart.
The first mount's options are so lengthy that the /etc/fstab entry is split across two lines in this book, using a backslash (\) as a line-continuation indicator. You'd replace this character with the second line's contents in a real /etc/fstab file. This entry uses credentials stored in the specified file, assigns ownership of all files to the user with UID 1027, and gives everybody full read and write access to the share. The idea is that this is a share to which everybody should be able to write, probably on an old Windows 9x/Me system, although it could be a Windows NT/200x/XP server or a Samba share.
The second mount's options are shorter because the assumption is that file ownership and permissions will be acquired from the server using Unix extensions (as described in the next section). Thus, there's no need for the uid, gid, fmask, or dmask options. This share supports guest access, and so this entry uses the guest option to access the share. (This option began working between the 2.6.4 and 2.6.6 kernels; on earlier versions, the guest option didn't work with the cifs driver.)
If a share requires a password, you should store it in a credentials file and restrict access to that file. Storing anything but bogus passwords in /etc/fstab is potentially quite risky because it's readable to all users of the system.
After making changes to /etc/fstab, you should unmount the shares if they're already mounted. You can then type mount -a to have Linux mount all your filesystems using the new values. If the operation doesn't succeed, check the /var/log/messages file on the client and the relevant Samba log files on the server for clues to what went wrong. The cifs filesystem can be particularly troublesome, in my experience; you might want to try smbfs instead, at least for testing purposes.
Normally, shares specified in /etc/fstab are mounted at boot time. (Some distributions seem to have problems mounting SMB/CIFS shares at boot time, though. To do so, you may need to add a call to mount -a to a startup script.) If you include the noauto option along with user, users, or owner, though, the share doesn't mount automatically. However, users can mount the share by typing mount /mount/point, where /mount/point is the mount point specified in /etc/fstab. The user and users parameters both permit any user to mount a share. They differ in that users enables any user to unmount the share, whereas user gives this authority only to root and the user who mounted the share. The owner option requires that the user who mounts the share own the mount point.
File Share Access Limitations
SMB/CIFS was originally designed with non-Unix systems in mind, and so most SMB/CIFS servers don't support Unix-style filesystem features, such as ownership, permissions, and symbolic links. (SMB/CIFS does support NT-style equivalents to some of these features, but they don't yet integrate cleanly with Linux clients.) Some features, such as ownership and permissions, are fundamental to Linux filesystem handling, so Linux SMB/CIFS mounting tools provide parameters to set these options on a filesystem-wide basis—effectively, giving ownership of all files to a particular user and setting all files' permissions identically. (Setting the DOS-style read-only bit, though, removes all write permissions.)
Depending on how you want to use an SMB/CIFS share, these limitations might or might not be a problem. For instance, if you want to give individual users access to their home shares on a remote server, you can enable them to mount their own shares with smbmount. These shares are then owned by the users in question, which is probably just fine for access to ordinary files. Setting up such access in /etc/fstab can be tedious, though. You probably can't simply mount all a server's home shares with one entry, and even if a server were set up to enable such access, the ownership of all files would be assigned to a single user, which is probably unacceptable. Thus, you need to create separate /etc/fstab entries for each user, and give users some way to set their passwords (presumably in a credentials file in their own home directories). Maintaining such a configuration is tedious at best. If the server is a Unix or Linux system, chances are you should use NFS rather than SMB/CIFS.
On the surface, Unix extensions can help with these problems. These are extensions to the SMB/CIFS parameters that support Unix-style ownership, permissions, symbolic links, and so on. On a Samba server, you can enable Unix extensions by setting unix extensions = Yes, which is the default as of Samba 3.0. These extensions aren't available on Windows servers, though.
When the cifs driver, or recent versions of smbfs or the smbmount command mount a share that's delivered by a remote server that supports Unix extensions, the server delivers ownership and file permissions information to the client. Unfortunately, this system only goes so far; the server still authenticates a single user for file accesses. Therefore, files are accessed in that user's name, which may not be the same as the user who's really accessing the file. For instance, suppose you use the linnaeus account to mount a remote share. If mendel tries to access a file that's owned by mendel with 600 (rw-------) permissions, access is denied, because from the server's point of view, it's linnaeus, not mendel, who's trying to access the file, and linnaeus lacks appropriate permissions. Samba's developers are working to overcome this limitation, but it still exists, at least as of the 2.6.8 kernel and Samba 3.0.7.
Nonetheless, using Unix extensions can still be a useful security tool for preventing unauthorized access to files. You can change ownership and permissions on the server to restrict access to files from the client in ways that can't be done using SMB/CIFS alone. File owners can set their Unix-style permissions, including the execute bit, within limits imposed by the create mask and directory mask parameters on the server, which can be handy if users need to store program executable files on the server. The Unix extensions also support hard and symbolic links. On the other hand, if you prefer to rely on Samba's server-side security features, you can set unix extensions = No to disable this support, in which case client-side options, such as the uid and fmask mount options, begin working again.
Printing to Printer Shares
A popular SMB/CIFS client feature on Linux is the ability to print to printers that are connected to Windows systems or to other systems that support SMB/CIFS printing. (Many dedicated print server appliances support SMB/CIFS printing, for instance.) Precisely how this task is accomplished depends on the software installed on your Linux system. One way that should always work, given an appropriately formatted file, is to use smbclient to submit a print job. You can also configure your Linux print queue to submit jobs to a remote server via SMB/CIFS, but the details vary with your local print queue. This section describes how to configure CUPS to configure an SMB/CIFS printer, as well as how to do the job with BSD LPD or LPRng.
Printing Using smbclient
If you have a one-time need to print to a Windows printer from Linux, you may want to consider using smbclient to do the job directly. As described earlier, smbclient is a basic text-mode tool for transferring files using SMB/CIFS. Many smbclient features and commands are modelled after those in text-mode FTP clients. One command in particular, though, is of interest here: print. Once you've started smbclient and connected to a print server, you can use this command to transfer a print job to the server. The transaction looks something like this:
$ smbclient //MANDRAGORA/HP4000 Password: Domain=[GREENHOUSE] OS=[Unix] Server=[Samba 3.0.3] smb: \> print myoutput.ps putting file myoutput.ps as myoutput.ps (29.8 kb/s) (average 29.8 kb/s) smb: \> quit
This operation is fairly straightforward for printing a single file (or even a few files), but it does have a few caveats. Most obviously, it requires that you have a file on hand. Most Linux programs that can print can also "print" to a file, so this requirement is seldom a problem. A more important caveat is that the file you submit (myoutput.ps in this example) must be in a format that the remote printer can parse. Most Linux programs generate PostScript output, so if you're printing to a PostScript printer, this will probably work fine. If the printer isn't a PostScript model, though, you may be in a bind. Many printers can handle ASCII (a.k.a. plain text) files, so if you want to print simple text (such as the output of an ls command), you may be fine; just put the information in a text file and submit it. For more complex data, you may need to use Ghostscript (gs) to convert PostScript to the remote printer's native format. For instance, to convert PostScript to PCL, which is used by many mid-range laser printers, you might type a command like this:
$ gs -dNOPAUSE -dBATCH -sDEVICE=ljet4 -sOutputFile=myoutput.pcl myoutput.ps
The -sDEVICE option sets the output driver; ljet4 stands for LaserJet 4—one of Hewlett-Packard's (HP's) PCL printers (and for which one PCL version's Ghostscript driver is named). If you don't know what driver to use, you may need to check http://www.linuxprinting.org for advice, or at least type gs --help to obtain a list of drivers available in your Ghostscript executable. With luck, one of the abbreviations will be familiar to you.
Using smbclient directly can become tedious. If you need to print to an SMB/CIFS printer on a regular basis, you can configure your local Linux printing queue to do so automatically. To do so, manually configure a queue or use a configuration tool, as described in the next two sections.
Defining SMB/CIFS Printers Using CUPS
Most Linux distributions today ship with the Common Unix Printing System, which provides both local and remote printing services for Linux systems. Chapter 4 describes basic CUPS configuration, so if you're not already familiar with CUPS, you should consult the relevant section of that chapter before proceeding.
Configuring an SMB/CIFS printer from CUPS works much like configuring a local printer. Instead of selecting the local printer port (such as a parallel or USB port), though, you pick the "Windows Printer via SAMBA" option as the device. Once you do this, the CUPS GUI asks you for the printer device's uniform resource identifier (URI). In theory, this is the same as the share name, as delivered to smbclient and other tools, except that it's preceded by smb:. This basic form, though, works only with printers that are shared for anonymous users. If your printer share requires a username and password, you must add this information to the URI, so that it takes the form smb:// username:password@NetBIOS-name/share-name. For instance, you might enter smb://linnaeus:bu9N!nEp@BIRCH/EPSON to print to the EPSON share on BIRCH using the linnaeus account and the password bu9N!nEp. Several variants on this form are possible; consult the smbspool manpage for details (smbspool is a part of the Samba package that helps CUPS by submitting the print job to the remote server). If you include a username and password in the device URI, they won't appear in subsequent pages of the CUPS web-based configuration tool; they're hidden from view, but used internally.
When you enter the password as part of the device URI, it appears in the web browser's text-entry field. Worse, the username and password are both stored in /etc/cups/printers.conf. For these reasons, it's best to use a dedicated printing-only account that has no other access to the print server. (Windows 9x/Me print servers normally ignore the username and provide share-level access to the printer, using a password only.)
When printing to a printer on a Windows server, you should normally select a CUPS printer definition for the printer in question, as described in Chapter 4. This causes the Linux system to pass programs' output through Ghostscript, if necessary, and turn it into a form that's acceptable to the remote printer. If the server is a Linux or Unix system running Samba, though, a raw queue may work better than a printer-specific queue. This is true even for genuine PostScript printers and their printer-specific definitions; sometimes these definitions add lines to the PostScript file that can confuse the server's print queue and cause it to print PostScript code rather than the file you want to see. Of course, when printing from Linux to another Linux or Unix system, chances are you'll use Unix-centric printing protocols rather than SMB/CIFS, but you can use SMB/CIFS if you have some reason to do so.
Defining SMB/CIFS Printers Using LPRng or BSD LPD
Although CUPS has become the most popular printing package in Linux, some distributions still provide an option to use LPRng or even BSD LPD. These printing systems weren't designed with much thought for printing to non-LPD remote printers, but they can do so by bypassing the normal local printer queue and calling a remote-printing tool as part of a print filter. For instance, a normal local printer queue using LPRng or BSD LPD is defined by a set of lines in /etc/printcap:
lp|lp0|hp4000:\ :sd=/var/spool/lpd/hp4000:\ :mx#0:\ :sh:\ :lp=/dev/lp0:\ :if=/var/spool/lpd/hp4000/filter:
The if line defines an input filter for the queue—a program that processes the print jobs for printing. Normally, this filter attempts to identify the file's type and passes it through programs such as Ghostscript to convert it to a format that's appropriate for the printer, whereupon the print job continues on to the output device specified by lp. To print to an SMB/CIFS printer, you instead point if at a program that delivers the print job to the remote queue, bypassing the lp line entirely.
Normally the task of submitting the print job to an SMB/CIFS queue is fairly complex: the submitted file's type must be identified, the file must be converted into a format suitable for the printer, and the file is delivered via an SMB/CIFS client program. Printer configuration tools can handle all these tasks. In the past, distributions such as Red Hat and SuSE shipped with distribution-specific tools for printer configuration. (These tools frequently called smbprint as part of their operation, but this detail was hidden from the user.) Most such tools have now been altered to configure CUPS rather than BSD LPD or LPRng, though, or omitted entirely in favor of CUPS web-based tools. If you're still using a non-CUPS print queue, you should check your distribution's documentation and look for options akin to those provided by CUPS.
If you've deliberately installed BSD LPD or LPRng on a distribution that normally uses CUPS, you may want to look into Apsfilter (http://www.apsfilter.org). This package is a set of configuration tools and smart filters that can identify various file types and apply appropriate transformations to them. Once you've installed Apsfilter, you should be able to launch its configuration utility by typing /usr/share/apsfilter/SETUP (the SETUP utility might exist in another directory on some systems, though). When you set up a queue, select the Windows/NT (Samba) option and then enter the appropriate information about the server's name, the queue name, etc.
Configuring GUI Workgroup Browsers
If you're migrating desktop users from Windows to Linux, chances are your users will be familiar with the Windows Network Neighborhood or My Network Places network browsers. These browsers enable users to easily locate network resources in a friendly visual manner. The core Linux SMB/CIFS client tools, though, are purely textual, and hence decidedly unfriendly to users who aren't comfortable with text-mode commands. Fortunately, some tools exist that provide GUI frontends to the text-based tools or that integrate SMB/CIFS functionality into primarily GUI tools. Installing and configuring such tools can help make former Windows users feel at home on a Linux desktop system.
A Rundown of GUI Network Browsers
Fitting with the Unix tradition of creating small programs that work together, many SMB/CIFS network browsers serve as frontends to the text-mode tools. Others use functions that are now provided in Samba libraries to handle much of the grunt work of SMB/CIFS interactions. These tools differ in their levels of sophistication and precise feature sets. Examples include:
- This program is the file manager and web browser in the K Desktop Environment (KDE; http://www.kde.org) package. It supports accessing SMB/CIFS shares when the user enters an SMB/CIFS URI, such as smb://MANDRAGORA/SHARED, in a window's path specification. Konqueror doesn't actually mount shares on the Linux filesystem.
- The GNOME file manager, Nautilus, supports SMB/CIFS access. You may need to select the File → Open Location option in the program and enter a URI for your share. Like Konqueror, Nautilus doesn't actually mount the SMB/CIFS share, but it does provide drag-and-drop access to files.
- This program provides a GUI frontend to several Samba and related utilities, the end result being a system that's similar to Network Neighborhood or My Network Places in overall capabilities. It uses smbclient to mount remote shares, so they're accessible to all programs. If LinNeighborhood doesn't ship with your distribution, you can obtain it from http://www.bnro.de/~schmidjo/.
- Like LinNeighborhood, Gnomba is an SMB/CIFS network browser that supports mounting shares you discover in the Linux filesystem tree. You can obtain it from its home page, http://gnomba.sourceforge.net.
- This program doesn't actually mount remote shares, but it enables easy browsing of the network. Check the project's home page, http://www.public.iastate.edu/~chadspen/, for more information.
- This tool is unusual in that it's an interface between HTTP, which is used by web browsers, and SMB/CIFS. The program runs as a Common Gateway Interface (CGI) program from a web server, giving web browsers that access the server the ability to browse the local SMB/CIFS network. You can obtain more information and download the program from http://www.scintilla.utwente.nl/users/frank/smb2www/.
There are several more GUI tools for Linux SMB/CIFS interfacing, including some very specialized ones. Check http://www.samba.org/samba/GUI/ for brief descriptions and links to those tools that have been registered with the main Samba project.
LinNeighborhood provides fairly typical network-browsing features, although its user interface isn't quite as polished as some users might expect. Still, it works with a variety of desktop environments, which can be a big plus. Before you can use it in any significant way, you must install and configure it:
- Check your distribution or the LinNeighborhood web site itself for the program. The web page includes binaries in several different formats, or you can download and install the source code.
- As an ordinary user, type LinNeighborhood in an xterm or similar window. The result is the main LinNeighborhood window.
- Click the Prefs button in the LinNeighborhood window. LinNeighborhood displays its main Preferences dialog box, as shown in Figure 6-1.
- Enter the information in the Scan tab. The workgroup is particularly important, but you may want to enter the IP address of your NBNS system. LinNeighborhood should be able to find the primary master browser automatically, and because this can change unexpectedly, it's probably best to leave this field alone. Adjusting the various checkboxes can also help in some cases; for instance, you might want to perform scans as your logon user rather than anonymously.
- Click the Programs tab, and check the entries there; they relate to the programs LinNeighborhood uses to do the real work. Chances are you won't need to adjust these entries.
- Click the Miscellaneous tab, and check the items there. Particularly if you checked "Always scan as user" on the Scan tab, you may want to enter a default user. If you enter a default password, be aware that LinNeighborhood will store it in a plain-text file, ~/.LinNeighborhood/password, in your home directory. Be sure that file is readable only to you!
- Click the Post Mount tab, and adjust the items there. This tab enables you to launch a file manager on shares you mount, or conceivably perform other arbitrary actions.
- When you're done with the Preferences dialog box, click Save, followed by Close.
The LinNeighborhood configuration files are in the ~/.LinNeighborhood directory, and in particular, in the preferences file. You can configure LinNeighborhood as you like and then copy this file to all users' home directories. You may need to omit or customize the default_user line from this file, though.
LinNeighborhood should now be configured and ready to function. If you don't yet see a list of systems in the main window, as shown in Figure 6-2, try right-clicking the machine name, and select Rescan Groups from the resulting pop-up menu.
You can browse the network in a way that should be familiar to those with GUI file manager or network browser experience: double-click machine names (such as HALRLOPRILLALAR and LOUISWU in Figure 6-2) to open them, or click the plus or minus symbol next to the name to open or close a machine that's already been visited. Depending on your settings, you may be asked to enter a username and password when you do this. Double-clicking a share's folder under a machine (such as CDRIVE or EDRIVE in Figure 6-2) brings up a mount dialog box in which you specify the mount point, username, password, and so on. LinNeighborhood then mounts the share and displays it in the bottom pane of its main window, along with other SMB/CIFS mounts. If you configured LinNeighborhood to launch a file manager after mounting a share, your file manager window should appear.
To mount shares, LinNeighborhood requires that you either enter the root password in the mount dialog box or set the SUID bit on the smbmount binary, as described in Section 6.2.2.
To unmount a share, right-click the share or its mount point in the bottom pane of the window, and select Unmount from the resulting pop-up menu. LinNeighborhood should unmount the share—if it can. If any programs have open files on the share, LinNeighborhood won't be able to comply.
On some systems, smbumount won't be able to unmount the filesystem, despite the fact that it was mounted with smbmount. This appears to be a bug in smbumount.
Konqueror, the primary web browser and file manager for KDE, also supports SMB/CIFS; however, this support is fairly recent and is still improving. Konqueror's support also doesn't actually mount the share in the Linux filesystem. This means that if you attempt to directly access a file (say, by double-clicking it), either Konqueror must copy the file to a temporary local location and then copy it back when you're through or the application used to access the file must implement its own SMB/CIFS support. Konqueror, like other GUI SMB/CIFS tools, also relies on other support libraries. For the most part, these are installed with your main Samba or Samba clients package.
To use Konqueror's SMB/CIFS features, you should first launch it. Most Linux distributions place a link for Konqueror in a menu or on the desktop, particularly when you run KDE rather than GNOME or some other desktop environment. If you can't find a link, type konqueror in an xterm or similar window.
Once Konqueror is running, type a URI (beginning with smb://) for the machine or share you want to access in the Location field. If you enter a complete share specification, Konqueror asks for a username and password, which you must enter correctly. (If you enter a machine name without a share name, Konqueror defers asking for a username and password until you try to access a share.) Konqueror should then present a list of file shares on a server or files and folders in a share. For instance, Figure 6-3 shows Konqueror's display of the shares on the SPEAKER server. You can browse your entire network by entering smb:/ as the device URI (the number of slashes is critically important: you must place one slash after smb:).
In theory, you should be able to use an SMB/CIFS share much as you'd use a local directory, by clicking folders to open them and clicking files to launch applications that will read the files. In practice, though, this sometimes doesn't work correctly. Konqueror may hang during file transfers to temporary locations, or programs may fail to load the files. These problems will likely diminish as Konqueror's SMB/CIFS support matures.
Although Linux often functions as an SMB/CIFS server with the help of Samba, the Samba suite and Linux kernel both provide support for SMB/CIFS client operations. You can use these features to enable NetBIOS name resolution for ordinary TCP/IP applications, to access files on Windows or other SMB/CIFS file servers, and to print to shared printers. An array of GUI tools can also make accessing SMB/CIFS resources easy for less computer-savvy users, although these tools may require configuration by more experienced users.