banner Debian GNU/Linux

Linux File Sharing in a Microsoft Active Directory Domain

Doing the Samba


Introduction

This is deviation of a write-up of an attempt to use Linux as a "Small Business Server". Note that in this scenario, the Samba server is set up as a member server in an existing domain, not as a domain controller. However, it is also possible to use Samba as a domain controller.

Setting up Samba for file sharing is easy enough. But what if you want to use Samba as a convenient way to share files to clients in an existing Microsoft Active Directory domain ? In such a situation, User management and authentication is handled by a Microsoft Domain Controller, and you don't want neither having to manage separate Unix and Samba accounts for access to your network shares, nor forcing your users to having to log on to the file server separately when they're already logged on to the domain.
That can be arranged ... The samba file server will have to join the domain and rely on domain controllers for user authentication when granting access to its shares.

Functional requirements

What we want is

install Debian

Nothing extraordinary here. Make it a base install (no package / task selection), and use a sensible partition layout, eg a separate partition for the samba shares (that we will mount to /srv/smb ).

Prerequisites

You have an Active Directory Domain, with users, groups, etc, and it's all set up and running

You need DNS. Active Directory relies heavily on DNS, so you should already have a well-functioning DNS infrastructure in place.
Make sure to add A and PTR records for the file server(s) you'll be setting up.

You want NTP. The Kerberos authentication protocol (used by Microsoft AD) is time-dependent, and things may go wrong if hosts in the domain don't have their clocks synchronized. In an AD Domain, it's usually the domain controller that provides the time service, so you'll want your file server to sync its clock with the domain controller.

	# install and set up ntp to sync with timeserver
	TIME_SRV="mydc.mydomain.yx"
	apt-get install ntp-simple
	echo "server=$TIME_SRV" > /etc/ntp.conf

install Samba

You need Samba version 3 or newer. install Samba ('apt-get install samba'), but don't pay attention to its configuration yet, and don't create any (smb or linux) user accounts just yet.

What are we up against ?

Microsoft's Active Directory is an implementation of several protocols that have to do with managing account information, authentication of users, and authorization (allow or deny certain actions to specific users and groups). We want to 'integrate' or 'join' our file server to the domain, so that users that have logged on to the domain (i.e. authenticated against a domain controller) are automatically known to the file server. The file server should also be aware of (domain) group membership of the users. This should allow us to manage access to the network shares based AD accounts and group membership.

The protocols that Microsoft used are standard, open protocols, but with Microsoft-specific, proprietary modifications and extensions.

Apart from user authentication and modification, AD also provides features such as user and computer configuration (Group Policy Objects), a software distribution and management system, etc, but that's beyond the scope of this project.

Unix users and groups vs. AD Users and Groups

UNIX and Microsoft Windows have different models for representing user and group information. However, for our file-server to integrate into an AD domain, it should be able to handle the 'foreign' MS Windows Security Identifiers (SID) adequately, i.e. it should be able to interpret a user name such as MYDOMAIN\user_1 correctly, i.e. it should know that this user needs to authenticate against the MYDOMAIN domain controller, not against a local password list, it should realize that MYDOMAIN\user_1 is not the same account as a local user_1, yet it should be able to use the user name MYDOMAIN\user_1 as a "native" user, e.g. in filesystem modes (access permissions) and ownership).

This is achieved by the 'WinBind' daemon (winbindd). WinBind maps Microsoft SID (Security Identifier) to Unix UID and GID (User Identifier, Group Identifier). WinBind in itself is sufficient to integrate a Samba File Server into a Windows NT4 domain or an Active Directory Domain in "mixed mode" (a compatibility feature of Active Directory to allow pre-Windows2000 systems to participate in an AD domain).

However, "mixed mode" is merely a backward compatibility, transitional feature, so we won't count on it. We want "native" AD integration. This requires the file server to use LDAP and Kerberos, in addition to and in combination with WinBind.

LDAP

Microsoft Active Directory is a directory service that is more or less LDAP-compatible. Therefore, our file server will need to be able to use LDAP (Lightweight Directory Access Protocol) to retrieve account information from the AD Domain controller. Note that, in this scenario, you do not need to set up an LDAP server : The Microsoft domain controller is an LDAP server, the samba file server just needs to be able to query it with standard LDAP tools.
[ RFC 1777, LDAP ]

Kerberos

Kerberos is an authentication protocol. Users authenticate (eg with username/password) and are then granted a "ticket" which will be used to identify them to the servers and other resources on the network, so that they don't need to provide usernames and passwords for each and every network resource they want to access.

The Kerberos infrastructure is implemented in Active Directory, so you don't need to set up Kerberos - we only need to arrange for samba to be able to use it.
[ RFC 4120, RFC 1510, Kerberos ]

install and configure winbind

Winbind maps Windows Security Identifiers to Unix User and Group Identifiers and is the preferred method to make AD accounts know to your Linux system. setting it up is a two step process : First, install the package, ...

		apt-get install winbind

... then use NSS (Name Service Switch) to inform your Unix/Linux system where to look for account information :
edit /etc/nsswitch.conf to looked like this:

	passwd:     files winbind
	shadow:     files 
	group:      files winbind

leaving "files" as the first thing to look for allows for the use of local unix accounts (not member of the domain, eg root) and prevents logon delays should the domain controller be unavailable.

verify that your Samba has support for LDAP and Kerberos.

Support for LDAP and Kerberos needs to be build (compiled) in the Samba software, so hopefully you are using a Linux version that has Samba with LDAP and Kerberos support built-in. You can check this with the following commands (re Samba Guide : ADS support). Debian v4 should check out just fine :-) .

	cd /usr/sbin
	smbd -b | grep KRB
	smbd -b | grep LDAP

If you get output with "HAVE_KRB_..." and "HAVE_LDAP_...", you're good to go

	ix:~# cd /usr/sbin/
	ix:/usr/sbin# smbd -b |grep KRB
		HAVE_KRB5_H
		HAVE_ADDRTYPE_IN_KRB5_ADDRESS
		HAVE_DECODE_KRB5_AP_REQ
		HAVE_KRB5
   		[...]
	ix:/usr/sbin# smbd -b |grep LDAP
		HAVE_LDAP_H
		HAVE_LDAP
		HAVE_LDAP_ADD_RESULT_ENTRY
		[...]

You need at least version 1.3.1 of the MIT implementation of Kerberos, or version 0.6 of the Heimal implementation. The Debian packages qualify, but you can check with :

	dpkg -l "*krb*" |grep ii

You can now rest assured that your file server is capable of joining an AD domain. All that's left is : make it work. You have edited /etc/nsswitch.conf, so all that's left is to configure samba to set up shares and grant access to AD Users and/or Groups.

configure samba

make sure winbindd is up and running; start it if need be

	ps -ae |grep winbindd || \
	/etc/init.d/winbindd start

Remove any left-overs from previous configs which may interfere with your new, AD-integrated setup

	# backup and disable old tdb files
	mv /var/lib/samba/passdb.tdb /var/lib/samba/passdb.tdb.$(date +%y%m%d)

Validate your current smb.conf file. Correct all errors before proceeding.

	testparm

testparm -v will show ALL parameters, including those not set in smb.conf (i.e. those using default values).

Edit /etc/samba/smb.conf : the [global] section should at least contain the following statements to

	[global]
		# modifications for AD Integration
		realm = MYDOMAIN.XX		;replace with your domain name in CAPITALS
		security = ADS

		# optional modifications for AD Integration
		encrypt passwords = yes
		winbind separator =  +

		# these are needed to get domain accounts to be recognized in unix
		idmap uid = 10000-20000
		idmap gid = 10000-20000
		winbind enum users = yes
		winbind enum groups = yes

		# domain users will only use shares, no unix sessions
		template homedir = /dev/null
		template shell = /bin/true

		# these are commented out from the default conf file,  because you don't need them anymore
		;	obey pam restrictions = Yes
		;	passdb backend = tdbsam
		;	passwd program = /usr/bin/passwd %u
		;	passwd chat = *Enter\snew\sUNIX\spassword:* %n\n *Retype\snew\sUNIX\spassword:* %n\n *password\supdated\ssuccessfully* .

		## the rest - any other global directive - as you would with file sharing only
		workgroup = MYDOMAIN	; domain 'short name' or workgroup
		string = %h 

		# package defaults
		syslog = 0
		log file = /var/log/samba/log.%m
		max log size = 1000
		dns proxy = No
		ldap ssl = no
		panic action = /usr/share/samba/panic-action %d
		invalid users = root
		include = /etc/samba/dhcp.conf

You no longer need an smbpasswd file, and older clients will be authenticated as if security = domain, although it will not do any harm and allows you to have local users not in the domain.

Pay some attention to what you set as winbind 'domain separator'. Windows always uses \ and this is also the default in Debian's samba / winbind config. However, in a unix shell, \ is an escape character so when you use \ in account names, you have to double it (MYDOMAIN\\JoeRandom). + is also often used on Linux, but can create conflicts with eg the syntax of smb.conf where group names starting with "+" get special treatment. "_" is also a good choice, unless you have user or group names that already contain '_' ; eg MYDOMAIN_Betty_Boop might be too hard to handle because it appears to contain 2 separators.
No matter what you choose as separator on the linux file server, from a Windows system you'll continue to use \

Join the domain

The easiest test to see if you can join the domain is to see if you can actually join the domain.

	net ads join -UAdministrator%admin-passwd-goes-here

Samba had built-in support for Kerberos and your system should be able to determine the domain from the smb.conf file and find the appropriate domain controllers by querying the DNS for SRV records. If that doesn't seem to work (i.e. you can not join the domain because the system can't determine the domain or find the domain controller), you probably have DNS issues, and should look in to those. However, you can work around them by inserting some explicit Kerberos info. Create a /etc/krb5.conf with the following content : (syntax for MIT Kerberos - Heimal is slightly different, see links below. Replace MYDOMAIN etc. with appropriate names ; CAPITALS are required)

	[libdefaults]
		default_realm = MYDOMAIN.XX

	[realms]
		YOUR.KERBEROS.REALM = {
			kdc = domaincontroller.mydomain.xx
		}

	[domain_realms]
		.kerberos.server = DOMAIN.XX 

Don't forget to restart samba and winbind after making configuration changes !

If the "net ads join" command succeeds, all is well. (If not, look in the links below for troubleshooting tips). Next, you can run some or all of the following commands to retrieve info about domain accounts from the domain controller. If that works, there's a good chance samba and other processes on your file server will be able to communicate with the domain controller.

	#get a list of users and groups from the ADS domain controller
	wbinfo -u

	#likewise for group accounts:
	wbinfo -g

	#verify NSS is working, i.e. domain accounts are known to unix
	##	the following should produce a list of domain accounts in /etc/passwd and /etc/groups format
	getent passwd
	getent group

	#verify that communications between Samba-3 winbind and the Active Directory server is using Kerberos protocols
	net ads info			# should return LDAP and KDC server addresses
      
	# yet another query to the domain controller
	net ads status -UAdministrator%not24get

If tdbdump is installed on your system (not essential), you can look inside the *.tdb files.

	tdbdump /etc/samba/secrets.tdb
	tdbdump /var/lib/samba/winbindd_idmap.tdb
	tdbdump /var/lib/samba/winbindd_cache.tdb

create shares and manage file access

Create the directories you want to share (eg /srv/smb), and create a samba share in /etc/samba/smb.conf. The following shares /srv/smb as \\fileserver\store, and allows read access to "Domain Users".

	[filestore]
		path = /srv/smb
		#valid users = "MYDOMAIN+Domain Users"
		writable = yes
		browsable = yes

Note that we keep this extremely simple to avoid duplicate work. We will create subdirectories under /srv/smb, such as /srv/smb/finance, /srv/smb/humanresources, /srv/smb/ict, ... and use filesystem security to deny or grant access to Domain groups (MYDOMAIN\grpFinance, MYDOMAIN\grpHR, ...).
This means the subdirectories will all be shared through 1 share (less configuration in samba !), and file access is managed by the linux filesystem but using domain accounts, rather than managing access through samba accounts. This also avoids a lot of duplication.

Of course, if you like to have things complicated, you can set up multiple shares, each with elaborate samba access permissions, and filesystem modes to match (or overrule, or contradict, ...). You could use swat, a web based (tcp port 901) administration tool for samba.

In the global section of smb.conf (or on a per share basis ?) you can give the domain admin root privileges. This wil result in Administrator not being limited by permissions and ownership issues. You can do this for other accounts ad well, but the downside is that all files created by these accounts will be owned by root, not the account itself.

	admin user = MYDOMAIN+Administrator

Optional : install support for ACL

Linux uses a style of file / folder permissions which is rather different from the ACL-based security Microsoft uses. WinBind allows you to use AD user names and group names to set modes (chmod, chown, ...) to the files on your Linux filesystem. If you want Microsoft Windows style Access Control Lists, you need to install support for POSIX ACL by installing the package 'acl'.

To activate ACL, you need to (re-)mount the partition where you want to apply ACL's and add 'acl' as an option. This can be done from /etc/fstab. There's a slight risk that, if acl fails, the partition won't be mounted. If it's a partition with boot or system files, your system may be unbootable. So you'd only apply acl to the partition that holds the shares (/srv), or you mount the partition, then remount it with mount /srv -o remount,acl. This also works from init scripts, so it's a safe and adequate alternative to fstab options.

With that done, you now have Windows-like Access Control Lists supported on your windows-compatible file sharing system. The (POSIX-compliant) ACL's and the unix file modes are made compatible. Changes made through "chmod" will be represented in the ACL's, while changes in ACL's will be reflected in the unix file modes. From a Windows client, you will be able to access shared files and directories ==> get a file or directory's properties ==> security ==> edit the security settings as you would with a Windows file server.
Alternatively, you can use getfacl and setfacl (and some other commands) to manage acl's in a shell. See the man pages.

See also Samba ACL HowTo" and the comments on acl in man 5 smb.conf. Microsoft's ACLs are not completely POSIX-compliant, so managing ACL between Windows clients and a Linux server is a bit of a challenge. Here's a more in-depth discussion of managing access control for Windows clients.

Example of file access with Domain accounts and ACL

On the Linux machine : create directories, give ownership to the Domain Administrator account (and give the group root write access for unix maintenance)


	# /srv/smb (shared as \\server\store) is owned by root, change group to Domain Administrators, and set read/execute access for everyone
	chown root:root /srv/smb
	chgrp "MYDOMAIN_Domain Admins" /srv/smb
	chmod 775 /srv/smb

	cd /srv/smb
	for ITEM in finance hrm research logistics marketing ; do
		mkdir $ITEM ; 
		chown MYDOMAIN_Administrator:root $ITEM ; 
		chmod g+w $ITEM; 
	done

On a Windows machine,
- log on to the domain with the account that owns the directories you've created
- open \\fileserver\store in a file browser
- get the properties of a directory, eg hrm
- edit the security properties, eg give full control MYDOMAIN\Administrator, 'Modify' to MYDOMAIN\group_HRM, and/or any other access you find suitable.
- set the security to be inherited by all subdirs and files in the hrm folder.

Alternatively, you can view and set ACL's in a linux shell with setfacl and getfacl. See the man pages for syntax. This is similar to using cacls or xcacls on Windows.

here's a more in-depth discussion of managing access control for Windows clients.

Disk Quota

Both Samba and Linux filesystem support quota for user and group disk usage quota. We prefer the simple and straightforward linux filesystem quota, although this may cause samba to report wrong 'disk free space' to windows users. smb.conf can be edited with workarounds to make samba report available space according to quota limits, but we don't look in to that just yet.

There are excellent instructions on howto implement disk quota at the Debian-Administration website. Alternative : this Linux Filesystem Quota Tutorial/

In the context described here, you'd setup quota for Active Directory groups (eg 20 GB hard limit for each department) by using the AD accounts (made available to the linux system earlier by winbind) in your quota definitions. Group quota apply to all users of a group combined, which suits us just fine as we want to provide disk space to departments, not individual users.

You need to mount the applicable partitions with quota support; this can be done in a similar way (fstab or init remount script) as the acl support discussed earlier. In fact, you could use the same script for both acl and quota support, and apply it only to the partition that you're mounting to /srv.

FIXME : needs some work : how to notify users when the reach their quota limit ? email notification would probably require a mail transfer agent on the file server. 'Quota Exceeded' messages should be preferably be passed through samba because that's the only way the AD users interact with the file server.

Tape Backups

An easy, simply way to backup data to a tape is to just use tar. On the machine I'm using, the tape drive is known as /dev/st0, and all data is in /srv, so to make a tape backup (with gzip compression), you just go

	
	tar czf  /dev/st0 /srv

That's enough to get a copy of each file in /srv on tape. However, when you restore from this tape, it will restore immediately back to the files original location, because the path names are included and all start at /srv. The workaround is to move into a directory and let filenames start wit ./ , so that you can restore into whatever "current directory" you choose. something like
cd /srv ; tar czf ./ /dev/st0 ; . the z option adds gzip compression.

A slightly more complete backup script could look something like this. It adds some commands that control the tape (set tape type, erase it, rewind it, ...)

	#!/bin/bash
	# based on http://www.bluestream.org/Networking/TapeBackups.htm

	BACKUPTO=/dev/st0

	if mt -f /$BACKUPTO status | grep "ONLINE"; then
	        ## DDS3   - see man page for definitions for setdensity
	  	mt -f $BACKUPTO setdensity 0x25 ;
		  
		## start clean : erase old, rewind, ...
		mt -f $BACKUPTO rewind ;
		mt -f $BACKUPTO erase  ;
		mt -f $BACKUPTO rewind ;
	

		cd /srv
		tar -czf $BACKUPTO ./ 
		cd -
	
		## eject tape  - serves as visual confirmation of "script ran'
		mt -f /$BACKUPTO offline
	else
		echo "TAPE OFFLINE or NO TAPE. BACKUP WILL NOT SUCCEED"
	fi

To restore (eg to your home directory), you'd go cd /home/me ; tar -xf /dev/st0 ./path/to/file .
To view the contents of a tape tape : tar -tvf /dev/st0

Here's a more elaborate script for tape backups with tar.

To make your backup a scheduled, automated job, add the tar statement (or a script containing that tar statement) to a cron job (/etc/crontab), e.g. for daily execution (01 minutes past 8 PM) :

	01 20  * * *	root	/root/dobackup

"Works for me ..."

This worked for me with Debian 4 (stable) and the packages that come with it by default. I imagine you can do the same with Ubuntu or any other debian-derived distro. It should also work with other distro's, at least in concept. The actual implementation (which commands / files / packages / syntac to use ...) may differ.

Hardware used for this experiment : a decommissioned IBM e-series server with 1 1.8 Ghz processor, 2.5 GB RAM, a (hardware) raid 5 provided by an Adaptec AHA-2940 scsi adaptor, and a scsi DAT tape drive. I was happy to see that Debian had no trouble what so ever detecting the hardware and installing the required modules to support it.

References and Documentation


Koen Noens
September 2007