MacDevCenter    
 Published on MacDevCenter (http://www.macdevcenter.com/)
 See this if you're having trouble printing code examples


Inside Samba: Windows Sharing for the Mac

by Jason Deraleau
03/18/2003

Beginning with 10.1, Apple started shipping support for the SMB protocol in Mac OS X. SMB is the protocol used by Windows machines to provide file and print sharing in a local area network. Mac OS X 10.1 had limited client capabilities, but 10.2 brought enhanced client and server facilities to the OS. The server facilities are provided by a Unix daemon known as Samba. Samba is one of the most successful open source projects around and has been ported to Linux, various BSDs, and Darwin/Mac OS X. Started by Andrew Tridgell, the Samba team works to provide as many features of the Windows server products as possible. Currently Samba can provide disk shares, print shares, act as a WINS server, and perform NT4 primary domain controller duties.

Enabling Basic Windows Sharing

Enabling Windows file sharing in Mac OS X 10.2 is pretty easy. By default, your computer will be a part of the SMB workgroup "WORKGROUP" and have an SMB hostname that is the same as your computer name. If you want the machine to appear in the Windows Network Neighborhood, you may need to adjust these settings. Consult your Windows documentation to find out what workgroup your Windows machine is using.

Setting the Workgroup

Fig. 1 - Configuring the Workgroup
Configuring the Workgroup

To change the workgroup your Mac will use, open the Directory Access utility. This tool is located in /Applications/Utilities. Once you have it open, authenticate by clicking the padlock in the lower left corner. You should be prompted to enter your user password. Once you've authenticated, select SMB from the Services list and click the 'Configure...' button. This will present you with a dialog box that allows you to specify your workgroup. Once you have set it to match your Windows machine, click the 'OK' button. This is all we'll need to set in Directory Access, so go ahead and close it.

Setting the Hostname

Fig. 2 - Setting the Hostname
Setting the Hostname

To change the SMB hostname, open the Sharing pane of System Preferences by selecting System Preferences from the Apple menu and clicking on the Sharing icon. Here you can specify your computer's name and Rendezvous name. The name should be unique on your network. I also recommend using only one word for the hostname (no spaces!) and having both the Computer Name and Rendezvous Name match. While in the Sharing pane, you should also see a listing of Services available. Start Windows File Sharing by enabling its checkbox. Samba will start up using the workgroup and hostname you've chosen.

Configuring Individual User Access

Fig. 3 - Configuring User Access
Configuring User Access

Now that Samba is running, you can enable a user's access to your Mac from Windows on a per-user basis. To do this, switch to the Accounts pane of System Preferences. Once there, select the user you wish to permit access to and click the 'Edit User...' button. If necessary, enter the user's password to enable editing of the user's information. Toward the bottom you'll see a checkbox labeled 'Allow user to log in from Windows'. Since users' home directories are shared by default, enabling this checkbox will allow that user to access his home directory from a Windows machine. The address to do this is \\HOSTNAME\USERNAME, which you would enter in the Windows Explorer. The user should also see his home directory in the Network Neighborhood.

Adding More Shares

The Mac OS X install of Samba is only configured for home directory shares by default. This is done using the special [homes] share of the smb.conf configuration file. This is fine if you only want to share files that are in your home directory, but what if you have some MP3s or AppleWorks documents in another folder? Perhaps you want to allow others to access your /Users/Shared folder from Windows. These are possible as well, but require some changes in the smb.conf file.

Samba's configuration information is stored in a file called smb.conf in the /etc directory. This file contains a [global] section, which has general directives for Samba to use. You will also see the [homes] section, which lists directives for sharing your users' home directories. In order to demonstrate how to create more disk shares, I'll show you how to share your /Users/Shared folder with Windows users. The first thing to do is to create a backup of your original file. To do this, we're going to go into the command line interface of Mac OS X and use some basic Unix commands.

Backing Up Your Samba Configuration

Open the Terminal application, located in /Applications/Utilities. Once it's open, enter cd /etc to change to the /etc directory. If you now enter the command ls, you'll see all the files and folders that are in the /etc directory. One of these files is smb.conf. To backup the file, type the command sudo cp smb.conf smb.conf.back. Because these files are all owned by root, you must have root permissions to make the backup. The sudo command temporarily gives you root permissions. You will be prompted for your user password. Enter it and the backup file will be created. To double check, enter the ls command again and look for a file named smb.conf.back. If it's there, you've successfully created the backup.

Adding a New Share

Now that you have a backup of your smb.conf file, we're going to open the original smb.conf file for editing using the pico editor. Since we need root permissions to save changes, we'll again use the sudo command to gain the necessary credentials: sudo pico /etc/smb.conf. If you're prompted for your user password, enter it. You should now see the contents of your smb.conf file, complete with the [global] and [homes] sections described above, as well as some sample sections for [public] and [printers]. The pico editor is very simple. To move around the file, use the arrow keys on your keyboard. Making changes to the file is very similar to the TextEdit application. The first step to add a new share is to give it a section title. The section title is the same as the actual share's name. In this case, we're just going to call it "shared". Give yourself some space after the [homes] section by moving the cursor below it and pressing the enter key a few times. Now type in exactly what appears below:


[shared]
  comment = Shared Directory
  path = /Users/Shared 
  read only = no
  browseable = yes
  create mode = 755

The [shared] line tells Samba that a new disk share is being defined. It is named "shared". The comment line will display the text "Shared Directory" in Windows Explorer. The next line declares the path to the share. In this case, it is the /Users/Shared folder. Since we want to be able to save changes to this share's files, we declare it with a read only value of no. The browseable attribute determines whether a share is displayed in the Windows Explorer. Even if you set this to no, it can still be accessed, the user would just have to know the full path to the share (in this case, \\HOSTNAME\SHARED ). The last line, create mode, defines the permissions that files being created on the share will have. These are presented in Unix numeric permissions. In this case, the permissions are read/write/execute for owner and read/execute for group and other.

Once you've entered these changes, press Ctrl+O and then enter to save the file, then press Ctrl+X to quit pico. To verify that your changes were saved successfully, use the command cat /etc/smb.conf and read through to be sure everything is there. Now the changes don't immediately take effect. To make Samba aware of the changes, use the command sudo killall -HUP smbd. This will tell the Samba daemon to reload its configuration information.

One important thing to remember is that a user must still have a valid account on your machine to access these shares. She must also have the 'Allow user to log in from Windows' option enabled on her account. On a Windows machine, you should now be able to see your "shared" share and a share named with your user's username in the Network Neighborhood. This user titled share contains the user's home directory. It is shared using the [homes] section.

The [homes] Share

Fig. 4 - User Home Directories
User Home Directories

The [homes] share is a special directive. It doesn't correspond so much to a specific folder on your drive, like the [shared] share does above, but is more of an internal mechanism to indicate to Samba you want to share user home directories. Below is the default [homes] declaration:


[homes]
   comment = User Home Directories
   browseable = no
   read only = no
   create mode = 0750

You'll notice that the declaration starts out much like the [shared] declaration does, with the name of the share enclosed in brackets. You might be wondering at this point why there isn't a share labeled "homes" in the Network Neighborhood. Note that the browseable property for this share is set to no. This is what prevents the share labeled "homes" from appearing in Network Neighborhood. The other properties for this share are similar to our [shared] share above, though the default create mode is different. In this case, any new files will be read/write/execute by owner and read/execute by group, but no one else will have any access to the file. These are more conservative permissions for a user's home directory, while the [shared] share would want to be a little less secure due to its public nature.

Common Samba Directives

So far we've seen how to configure your machine's SMB settings, enable Windows sharing, and create additional disk shares. When configuring Samba, there are a lot of different directives you can use. Some of these directives affect Samba as a whole, others are specific to disk shares or print shares. Below I'll discuss some of the more commonly used directives and their intended uses.

Securing Samba

SMB isn't the most secure protocol. It is designed to work on a local area network and tends to trust security to be handled by user authentication. This can be bad if your machine is directly connected to the Internet. A malicious person can examine what shares are available on your machine and attempt to access them. In order to lock things down a bit, it is possible to restrict only certain hosts to connect to Samba. To do this, add a "hosts allow" directive to your [global] section:


[global]
   hosts allow = localhost 192.168.1.
. . .

This example will only allow access to those on the 192.168.1 network or from the machine itself. You can take this a step further by binding the Samba daemons to your LAN interface only by using the "interfaces" and "bind interfaces only" directives:


[global]
   interfaces = 192.168.1.29/255.255.255.0
   bind interfaces only = yes
. . .

The interface method can be difficult to maintain if you are using DHCP at all, since your interface's IP address might change, requiring a change to your configuration file. The hosts allow/hosts deny method is much easier. Many ISPs will filter the SMB ports as a security precaution. If you're attempting to use SMB over the Internet and wondering why it's not working, that could be why.

Hiding Files

When accessing your Mac's shares from a Windows machine, you might see a lot of files that begin with a period. Starting a file with a period is a Unix convention, which is used to hide a folder or file in most casual directory listings. A good example of this is the .DS_Store file. The .DS_Store file is used to store Finder view preferences on Mac OS X. In order to keep these files from showing up, you can use the "hide dot files" directive in your smb.conf file:


[global]
   hide dot files = yes
. . .

This will hide any files or folders which begin with a period. You can also use the "hide files" directive with a pattern to hide certain files. For example, to hide all files that have a .log extension:


[homes]
   hide files = /*.log/
. . .

Something important to note here is that these files are just hidden, they are still able to be accessed from the Windows machine. The files are given the equivalent of the FAT file system hidden attribute. This means that anyone who has "Show hidden files" or "Show hidden and system files" enabled in the Windows Explorer will still see these files. If you'd like to keep the files from being accessed at all, you can use the "veto files" directive:


[homes]
   veto files = /*passwd*/
. . .

This entry would keep all files that contain "passwd" in their file name from being shown at all. The Windows user would not even be able to tell they exist, unlike the "hide files" directive, which still allows access to a savvy user.

Restricting Directory Access

Samba also allows you to restrict access to directories within a share. For example, let's say I want to restrict access to the mp3 folder of my [shared] share. I have other folders in the share that Windows users need access to, but I only want users who access the machine directly to have access to the mp3 folder. I can use the "dont descend" directive to prevent this folder from being accessible by Windows users:


[shared]
   dont descend = mp3
. . .

The folder would still appear, but any Windows user who attempts to open the folder will be denied access. All other folders on the share would remain unaffected.

File and Directory Access

Earlier I mentioned the "create mode" directive. This directive is used to determine what permissions should be used when creating a file. Its companion directive, "directory mask", does the same thing for directories. One thing I want to clarify is how the masks are created. The masks are broken up into four positions. A single digit represents each position. The first position can be left out completely and often is. The next three positions represent owner, group, other, respectively. The owner corresponds to the user who is creating the file. The group will be that user's primary group. Other is everyone else.

To determine what digits to use, figure out what kind of access you want to give in each situation. The three types of access are read, write, and execute. In most cases, read/write will be sufficient for the owner. For the group and other permissions, think about who else might need to access the file and go from there. Once you know what kind of access is needed, follow this procedure: Start with 0, add 4 for read access, 2 for write access, and 1 for execute access. Thus if you want the owner to have read and write access, his group to have read access, and other to have no access, you'd use 640. If you want to give the owner and group read and write access, but other only read access, use 664.

For directories, it's the same procedure, but directories always require execute access in order to be opened. Thus if you want to create a directory that only he owner can use read and write to, you'd want 0700. If you are granting execute access, the user will need read access as well (you can't execute what you can't read). The file and directory masks can only be specified at the share level, it's not possible to have a folder within the share have a different mask. Also, there is no way from Windows to change these, but you can change them using the Inspector in the Finder or chmod in the Terminal.

Sharing a Printer

Samba also supports sharing a Unix-based printer with Windows machines. Luckily Mac OS X now uses the Common Unix Printing System (CUPS) for printing, so the lpr, lpq, and other Unix printing commands will work with a printer you've added in Print Center. You can also access the CUPS control panel by entering the URL http://localhost:631 in your web browser. Sharing your printer is a fairly easy process. The hardest part is configuring the Windows machines with the proper driver. I've found that the Generic/Text print driver works, but encountered problems when printing PostScript using the Apple Color LaserWriter driver. These problems were alleviated with a small shell script and portions of the ESP Ghostscript package. I'll discuss this below, but your mileage may vary.

The [printers] Share

The [printers] share is quite similar to the [homes] share. Both shares are special in that they tell Samba to attempt to create a share based on another field. In the case of the [homes] share, that field is a username. With the [printers] share, that field is a printer. Samba gets its list of printers from the /etc/printcap file. This file contains a list of all printers that the machine currently knows about. On Mac OS X, this usually corresponds to any local printers as well as any discovered through Rendezvous. While it may be possible to share a printer that is not directly attached to your Mac, for best results you should only try to share printers that are connected right to your machine.

The Samba directive that helps distinguish between a disk share and a print share is "printable". If the printable property is set to true (or yes), Samba will treat that share as a printer. With a print share, the "path" directive is used to determine where the temporary print file should be stored. The default is /tmp and should work just fine on Mac OS X. Samba handles printing by receiving the document from the remote machine and storing it in a file in the folder specified by the path directive. Samba will then use the command specified by the "print command" directive to add the file to the print queue. The excerpt below will use the /tmp directory for all print files and will create a share for each entry in /etc/printcap:


[printers]
   comment = All Printers
   path = /tmp
   browseable = no
   printable = yes
   guest ok = yes

As you can see, this share looks a lot like a disk share. The printable directive determines how the share is treated. Notice that the browseable property is set to no, much like how we set the [homes] share with the same value to prevent a ghost share from appearing. To specify which command is used to manipulate print jobs, you use the "print command" directive.

The print command directive is used to declare which program sends print jobs to the print system. On Mac OS X, this command is lpr, which is in the /usr/bin directory. To use lpr, you must specify which printer should handle the job and what file is to be printed on its command line. In order to pass the correct printer and filename to lpr, Samba offers two variables: %p and %s. These represent the printer and the file respectively. In Samba, you would end up with a print command directive that looks something like /usr/bin/lpr -P%p -r %s. Samba will substitute the real printer and filenames and execute the command. lpr then takes the job and passes it to the printing system. Here is an example of the print command directive in use:


[global]
. . .
   print command = /usr/bin/lpr -P%p -r %s

Configuring Windows for Printing

Fig. 5 -
The Shared Printer

Now that you have configured Samba to share your printer, it should appear in the Windows Explorer along with the rest of your shares. To install the printer on the Windows machine, double click it in Explorer. A dialog box stating that the server did not have the drivers for the printer should open. Once you've closed the error, you'll be presented with a list of printer drivers available on your system.

If you want basic text printing, select the Generic/Text Only driver from the Generic manufacturer listing. This driver is excellent for debugging purposes, since most printers will handle plain text easily. If you want Postscript printing, select one of the Apple Color LaserWriter drivers from the Apple manufacturer listing. These drivers have the most neutral implementation of Postscript. Once you've selected the desired driver, click OK. The Windows machine should now be able to print to the shared printer on your Macintosh.

It's worth noting that sometimes Windows will send Postscript formatted files that, for some reason, won't print through your printer. I believe this is caused by differences in the way the operating systems handle printing. I resolved this issue by installing the GIMP Print package and writing a short shell script. I then configured Samba to use my shell script as the print command. Below is the script:


#!/bin/sh
#
# /usr/local/bin/printsmb
#
# Print script for Postscript files.
#

/usr/local/bin/ps2pdf13 /tmp/$2
rm /tmp/$2
/usr/bin/lpr -P$1 -r /tmp/$2.pdf

This script makes use of the GIMP Print package's ps2pdf tool, which will convert the Postscript file from the Windows machine into a PDF file. The script then removes the temporary Postscript file and sends the resulting PDF file to the printer using lpr. I placed the script in /usr/local/bin and gave it 0755 permissions with chmod. To use this script with Samba, make the following change to your [printers] section:


[printers]
. . .
   print command = /usr/local/bin/printsmb %p %s

Now Samba is configured to call the script and pass the desired printer and the temporary file's path as parameters. The script converts the file and prints it. Postscript printing should give you the same capabilities as printing right from your Mac. With Samba sharing your printer, you can easily let Windows clients print through your system. You can even manage their print jobs through the Print Center or the CUPS control center. Samba also allows you to configure a printer driver share so that your Windows machines will automatically download and install the appropriate software to print to your shared printer, bypassing the driver selection dialog box. Such configuration is a bit beyond the scope of this article, but I recommend taking a look through Using Samba, published by O'Reilly and Associates.

The Samba Web Administration Tool

Now that you're familiar with the common configuration options used to create disk and printer shares, I'm going to introduce you to a faster and easier way to work with your Samba configuration file. The Samba distribution includes a web-based tool that allows you to manipulate your Samba settings. Mac OS X includes this tool as well, but it first needs to be enabled.

Enabling SWAT

To enable the Samba Web Administration Tool, you must configure one of the Internet superdaemons that is included with Mac OS X. Mac OS X includes both inetd and xinetd. However, Mac OS X itself only seems to use xinetd. This is the superdaemon that responds for the FTP Sharing features.

Configuring xinetd to launch swat requires just a few steps. You first need to check that your /etc/services file contains a port entry for swat. To do this, enter the following command in the Terminal: cat /etc/services | grep swat. This command should return one result, which will list the swat service as running on port 901/tcp. If you do not get a result for this, add such an entry to your /etc/services file by editing it with pico running under sudo or as root. Add an entry that lists the information above and then save your changes.

Now that your machine knows about the daemon's TCP information, create a file in /etc/xinetd.d with the name swat and put the following in it:


service swat
{
   disable         = no        
   only_from       = 127.0.0.1
   socket_type     = stream
   wait            = no
   user            = root
   server          = /usr/sbin/swat
   server_args     = -s /etc/smb.conf
   groups          = yes
   flags           = REUSE
}

You will need to be the superuser or use the sudo command to create this file in the proper directory. For more information on customizing xinetd, take a look at the man page for xinetd.conf. The only setting you might want to change is the "only_from" entry. The example entry allows access only from the computer itself. You can enter an IP address or network address here to open up access a bit more. Once you have saved your entry, reboot the machine (or HUP the xinetd daemon if you are more Unix savvy).

Using SWAT

Fig. 6 -
The SWAT interface

Once you have xinetd configured to share swat, open up your web browser and enter the address http://127.0.0.1:901/. If you are prompted to enter a username and password, enter those of your root user (please note that the root user is disabled by default on Mac OS X. To enable it, enter the command sudo passwd root in the Terminal.). You will see the SWAT entry page as shown in Figure 6. Notice along the top there are several different sections of the tool to use. The Home section has Samba related documentation. On the Globals section, you will find many directives for the [global] section of the smb.conf file. SWAT edits the file for you, allowing you to easily fill in desired fields and then committing changes.

Most of the sections are self-explanatory. At the top you will find a button to Commit Changes and some will have an Advanced button that will show you the more advanced Samba directives. The Status section has buttons that allow you to start, restart, and stop the smbd and nmbd daemons. Remember that you need to restart the daemons after any changes are made to the smb.conf file, whether by SWAT or hand editing. Below the daemon control buttons, you will see a listing of active network connections and individual buttons to force them closed.

The last two sections of SWAT are less often used with Mac OS X. The first is the View section. This section will display your smb.conf file so you can see how SWAT handles the file and makes changes. The last section is the Password section, which allows you to create the encrypted usernames and passwords required by most recent versions of Windows. You shouldn't need to use this tool at all, when you enable a user's Windows access in the System Preferences it generates this information for you.

SWAT is very useful for controlling your Samba daemons and working with their configuration. By making changes to the xinetd configuration file, you can access SWAT remotely using any browser. The various sections of SWAT make it much easier to keep your smb.conf file in order and learn a bit more about its syntax. Once you become more comfortable with the sections of smb.conf, you might choose to edit your configuration by hand, but for those of us in a bit of a rush SWAT is always a great way to go.

Final Thoughts

Now that you're familiar with the configuration of Samba, you should be able to create more advanced shares than the Apple provided GUI tools allow you. Using the SWAT interface will help you keep your configuration error free and easily allow you to restart Samba to see your changes. Overall, Apple has been smart enough to include the best Unix implementation of Windows sharing around and provided all of the necessary tools to get it up and running in a variety of configurations. Samba is invaluable in helping your Mac integrate with a Windows network. Your Windows associates won't even be able to tell the difference.

Jason Deraleau works as a systems administrator by day, IT consultant and technical writer by night, and is the coauthor of the upcoming Running Mac OS X Tiger.


Return to the Mac DevCenter

Copyright © 2009 O'Reilly Media, Inc.