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
smbclient’s own prompt. You can
then type FTP-style commands, such as dir,
get, put, and
exit. A typical session looks like this:
$smbclient //MANDRAGORA/DDRIVEPassword: smb: \>put chapter06.xmlputting 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.xmlsmb: \>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.
-N
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.
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 6.2.3.2.) 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/SHAREmount-point[-ooptions]
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.
guest
Pass this option if you know the share doesn’t require a password; smbmount won’t prompt for one.
ro
This option causes smbmount to mount a share read-only, even if the share supports write access.
rw
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:
username=linnaeus password=bu9N!nEp
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/clipartOne 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/smbumountAfter 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/pointprobably not smb-filesystem
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.
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.
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.
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.