Given Linux's immense attraction as an inexpensive server operating system, it's becoming increasingly common for organisations – particularly SMEs – to adopt Linux for their fileserving needs. In this HOW TO, we'll go through how you set up a Linux server to provide file sharing service to Windows machines. File sharing protocols
The most sensible way to proceed is to use the Windows SMB approach to file sharing – it's the standard way Windows works, and thanks to the Samba add-on package, most Linux distributions are able to support SMB out of the box. We don't need to do anything to the Windows clients, as they inherently support Windows filesharing, all we have to do is set up the server and it'll all magically work. Before we start
Before setting up Samba, we need to consider a few key system parameters. Domain or workgroup?
The majority of installations of Linux filesharing that I've done are in a workgroup setup, because in an SME there's not a massive amount of benefit to be gained from using Windows domains (it's harder and the server goes slower). So we'll stick with workgroups. Fileshares
We also need to decide what shared folders we want. A common one is to give each user their own "private" directory and to have a communal "shared" directory into which people can temporarily drop stuff so others can grab it. We'll also pretend we have a directory set aside to which only the Accounts department have access, so they can share files among themselves but non-Accounts people can't see them. Basic setup
On our installation (a Red Hat 9.0 PC) the Samba configuration file lives in /etc/samba and is called smb.conf. So we need to edit this file and tell it about our world. The first section in the config file reflects the system-wide preferences – the domain/workgroup name, logging details and so on.
[global]
   workgroup = KORANA
   server string = DSC-LAB
We've told the system that it'll live in workgroup "KORANA" (the name of the workgroup in the lab we're using), and that it will appear in people's Network Neighbourhoods as "DSC-LAB".
   log file = /var/log/samba/%m.log
   max log size = 0
Samba logs can become big and sprawling, and when there's a lot of activity it can be hard to debug an individual session. Here, we've told Samba to create an individual log file for each connecting PC – so if a user is having a problem we can find the right log file, as long as we know which PC they're sitting at. Also, by setting the log file size as 0 we're telling it that the log files can grow to whatever size the system wishes. In a non-lab environment you'd want to make the maximum logging size something relevant to the amount of disk space you can afford.
   security = user
We're going implement security based on the username.
   encrypt passwords = yes
   smb passwd file = /etc/samba/smbpasswd
   unix password sync = Yes
   passwd program = /usr/bin/passwd %u
   passwd chat = *New*password* %n\n *Retype*new*password* %n\n *passwd:*all*authentication*tokens*updated*successfully*
   pam password change = yes
This is all password-related and although it looks awkward you don't have to change anything – it's all in the config file. Basically, it tells the system where to keep the password file, and to keep Samba-specific password entries in sync with the Linux ones. Now we're going to define the directory access itself.
[homes]
   comment = Home Directories
   browseable = no
   writable = yes
   valid users = %S
   create mode = 0664
   directory mode = 0775
   printable = no
This is the entry for individuals' personal directories. The [homes] section is a special one for Samba, since for this chunk (and only this chunk) it presents the logged-in user with a directory whose name is the user's ID and whose location is whatever Linux thinks the user's home directory is. By setting browseable=no we're making the system present the user's directory as a top-level share (if we set it to yes it would present a share called homes). The valid users line uses a "macro", "%S", to denote that the only valid user for a given home directory is the current logged-in user. Note that the printable=no clause tells Windows not to regard this item as a printer share – i.e. it's not the container for one or more printers, so Windows won't bother putting a printer icon in the directory window or searching this share when you select "Add new printer". File modes The file modes need a little explanation. Unix permissions can be represented using a numeric notation, as we see in the create mode and directory mode items. Ignoring the leading zero for a moment, each the three remaining digits represents the file/directory permissions for the file/directory's owner, the file/directory's group, and other users. Permissions are worked out as the sum of: • 4 for read permission • 2 for write permission • 1 for execute permission So a mode of 6 equals 4+2, or read and write permission. 4 is read-only, 7 is full access, and 5 is read and execute only. Note that for a directory, the "execute" permission is actually the browsability permission – in a non-browseable directory, you can't actually list the files, though with the correct read/write permissions you can read and write them. In our example, we're saying create mode 0644 – which means that all files created will, by default, have read/write permission for the other and the group the file belongs to, and will be read-only for others. Directories created will have full permissions for the user and group, and only read/browse for others. If these access rights are too permissive, just change them to whatever you like.
[Shared]
   comment = Shared filestore
   path = /tmp
   read only = no
   public = yes
   printable = no
This is our shared directory, which everyone can read and write to. Because Linux has a temporary directory with all the properties we want (world-writable and cleaned out at every reboot) we'll simply point our "Shared" item at it, and flag it as public=yes.
[Accounts]
   comment = Accounts department
   path = /home/accounts
   public = no
   writable = yes
   printable = no
   write list = @accounts
Now we have our Accounts-only directory. We've pointed it at directory /home/accounts, flagged it as non-public and non-printable, and said write list = @accounts. The latter command tells Samba that the only people permitted to write to this directory are members of the "accounts" group under Linux (and the public=no item tells it that nobody outside this group can read stuff, either). Samba passwords
As we've already hinted, Samba has its own separate password file from Linux, and so you need to set up your users' accounts under Samba. It's dead easy to do – you use the smbpasswd command:
smbpasswd –a testuser
The –a flag tells the system that we're creating a new user – it'd give an error otherwise. There are loads of options to smbpasswd, including ones to temporarily enable and disable users, plus the –x flag that deletes a user ID entirely. Because we're using a basic, non-domain setup, the password control is relatively simple (and the password-related gubbins we left in the config file earlier means it'll synchronise people's Samba and Linux password for us). If you're working as part of a domain, it gets a little more complicated but not overly so. Access rights
When you've set the Samba control file up, you do need to double-check that you set up your various directory permissions and ownership correctly. The 'Shared' and home directories are probably set OK anyway, because Linux will have created them and they'll have the right permissions. The /home/accounts directory should be given the right permissions, though.
chmod –R 770 /home/accounts
The owner and group have full rights, everyone else gets none.
chown root.accounts /home/accounts
The owner is the "root" user, and the group is "accounts". Off we go
The first thing you want to do is run the testparm application before you try out the new settings. This checks the syntax (and some of the semantics) of the configuration file for silly errors. Once you've done this, it's simply a case (under Red Hat, anyway), of kicking off the service:
/etc/init.d/smb stop
/etc/init.d/smb start