2. File and Print Services

2.1. Sharing Printers with CUPS

This chapter is based on CUPS official documentation.

CUPS (Common UNIX Printing System) provides a portable printing layer for UNIX®-based operating systems. It has been developed by Easy Software Products to promote a standard printing solution for all UNIX® vendors and users. CUPS provides the System V and Berkeley command-line interfaces.

2.1.1. How Does it Work?

The first time you print to a printer, CUPS creates a queue to keep track of the current status of the printer (everything OK, out of paper, etc.) and any pages you have printed. Most of the time, the queue points to a printer connected directly to your computer via a USB or parallel port. However, it can also point to a printer on your network, a printer on the Internet, or multiple printers depending on the configuration. Regardless of where the queue points, it will look like any other printer to you and your applications.

Every time you print something, CUPS creates a job which contains the queue you are sending the print to, the name of the document you are printing, and the page descriptions. Jobs are numbered (queue-1, queue-2, and so forth) so you can monitor the job as it is printed or cancel it if you see a mistake. When CUPS gets a job for printing, it determines the best programs (filters, printer drivers, port monitors, and backends) to convert the pages into a printable format and then runs them to actually print the job.

When the print job is completely printed, CUPS removes the job from the queue and moves on to any other jobs you have submitted. You can also be notified when the job is finished, or if there are any errors during printing, in several different ways.

CUPS uses the Internet Printing Protocol ("IPP") as the basis for managing print jobs and queues. The Line Printer Daemon ("LPD") Server Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are also supported with reduced functionality. CUPS adds network printer browsing and PostScript Printer Description ("PPD") based printing options to support real-world printing under UNIX.

CUPS includes an image fileRIP that supports the printing of image files to non-PostScript printers. Sample drivers that use these filters for Dymo, EPSON, HP, and OKIDATA printers are included.

Mandriva Enterprise Server 5 provides CUPS 1.3, with new functions. Here are some of them:

  • Network Printer Discovery: CUPS can now find printers on the LAN using SNMP

  • LDAP Support: CUPS now supports printer sharing via the Lightweight Directory Access Protocol, version 3

  • Export Printers to Samba: the administration page now offers an Export Printers to Samba button which allows administrators to export printer drivers to Microsoft clients via Samba

  • Set allowed users: you can now set the list of users and/or groups that are allowed or not allowed to access a printer or class

  • Job management: you can cancel all jobs for a printer, move it for another printer

  • CUPS API: security and performance have been improved.

  • IPP support improvements

  • Scheduler improvements

For more information, visit the CUPS official web site: http://cups.org/

2.1.2. CUPS installation and file tree

Here are the packages to install to have full CUPS server and the main ppd files to support most printers.

  • cups: provides all server files

  • cups-drivers: contains special printer drivers to used with CUPS and their appropriate PPD files

  • hplip-hpijs-ppds: PPD files for the HPIJS printer driver

  • postscript-ppds: contains PPD files for older PostScript printers

  • hplip: an HP driver package to provide Linux support for most Hewlett-Packard DeskJet, LaserJet, PSC, OfficeJet, and PhotoSmart printers and all-in-one peripherals

Now Let's describe the CUPS tree:

  • /etc/cups: configuration files such as printers.conf. Overridden by the ServerRoot directive in cupsd.conf.

  • /usr/include: CUPS included files.

  • /usr/lib: CUPS library files.

  • /usr/lib/cups: server programs such as backends and filters. Overridden by the ServerBin directive in cupsd.conf.

  • /usr/share/cups: data files such as fonts. Overridden by the DataDir directive in cupsd.conf.

  • /usr/share/cups/doc: documentation files. Overridden by the DocumentRoot directive in cupsd.conf.

  • /usr/share/locale: localization files.

  • /var/cache/cups: cache files such as ppds.dat and remote.cache. Overridden by the CacheDir directive in cupsd.conf.

  • /var/log/cups: access_log, error_log, and page_log files. Overridden by the AccessLog, ErrorLog, PageLog, directive in cupsd.conf.

  • /var/run/cups: domain socket file and state data such as authentication certificates. Overridden by the StateDir directive in cupsd.conf.

  • /var/spool/cups: spooled print jobs. Overridden by the RequestRoot directive in cupsd.conf.

2.1.3. Configuring your CUPS server

You can configure CUPS both through configuration file editing and web interface. We recommend you to use web interface for basic configuration and printers management (add, modify, delete) and editing configuration file for advanced purpose, mainly for security.

2.1.3.1. Using the CUPS web interface

You can access web interface using https and port 631: https://cups_server:631.

The Jobs tab allows you to manage print jobs. The Administration tab will give you a web interface to add, modify and delete printers. Simply click on the Add printers or Manage printers buttons.

cupsd is configured by default to show printers shared by other systems and only allow local access to the system and its printers. Administration operations require Basic authentication with membership in the group "sys". Connections are accepted via domain socket (/var/run/cups/cups.sock) or "localhost" (127.0.0.1). Users are not allowed to cancel jobs that do not belong to them.

You can change these parameters in the Administration tab in the Server section: click on boxes to choose which option you want to enable or disable.

The server section will also provide access to server logs:

  • access and error logs: these contain access and errors regarding CUPS server

  • page log: this log contains all access to CUPS' web interface

Let's add a new printer. CUPS 1.2 provides an auto-detect functionality. If printers are up and connected to the network, CUPS should auto detect them, then the new New Printers Found: list will appear. Click on Add this printer and fill the fields with printer information. That's it!

[Tip] Tip

Your printer may not be recognized by CUPS because its ppd file is not in list.

  1. In the Administration tab click on Add printer.

  2. On the first screen, fill the name field for this printer and location.

  3. On the second screen, choose from the list the device to access your printer.

  4. On the third screen, fill the exact URI to access your printer.

  5. On the last screen, you will be asked to choose a printer in the list. Since you can't find it here, let's provide a ppd file for the printer. You will find it on manufacturer's CD. Click on the Browse button and select this file from tree. That's it!

This procedure may not work since some ppd files are not properly completed. Please have a look at http://linuxprinting.org to check for your hardware's compatibility.

Once your printers are added, you can modify their configuration. Click on Printers. Select a printer by clicking on the one you want to modify. You will then see the following:

  • Print Test Page: print test a page for configured printer

  • Stop Printer: completely disable a given printer

  • Reject Jobs: the printer will not be disabled but it will not accept any more jobs.

  • Move all Jobs: move all jobs from this printer to a new one you will choose

  • Cancel all Jobs: cancel all jobs for this printer

  • Unpublish Printer: hide this printer from users

  • Modify Printer: modify printer configuration, URI access, driver, etc. ...

  • Set Printer Options: modify printing option such as resolution, page size, banner...

  • Delete Printer: delete a printer completely

  • Set as Default: set this printer as the default printer for users

  • Set allowed Users: list all users that can use or not this printer

2.1.3.2. Advanced configuration through configuration file edition

You will find configuration files in /etc/cups. /etc/cups/client.conf enables you to configure client access. /etc/cups/cupsd.conf enables you to configure the CUPS server.

The /etc/cups/cupsd.conf file contains configuration directives that control how the server functions. Each directive is listed on a line by itself followed by its value. Comments are introduced using the number sign ("#") character at the beginning of a line.

General syntax of cupsd.conf looks like the one for Apache. You can specify general parameters using <directive> <parameter>.

Let's have a look at the main configuration options:

AuthType

The AuthType directive defines the type of authentication to perform:

  • None: No authentication should be performed (default)

  • Basic: Basic authentication should be performed using the UNIX password and group files

  • Digest: Digest authentication should be performed using the /etc/cups/passwd.md5 file

  • BasicDigest: Basic authentication should be performed using the /etc/cups/passwd.md5 file

When using Basic, Digest, or BasicDigest authentication, clients connecting through the localhost interface can also authenticate using certificates. The AuthType directive must appear inside a Location or Limit section.

BrowseAddress

The BrowseAddress directive specifies an address to send browsing information to. Multiple BrowseAddress directives can be specified to send browsing information to different networks or systems.

The @LOCAL name will broadcast printer information to all local interfaces. The @IF(name) name will broadcast to the named interface.

There is no default browse address.

BrowseAllow

The BrowseAllow directive specifies a system or network to accept browse packets from. The default is to accept browse packets from all hosts. Host and domain name matching require that you enable the HostNameLookups directive.

IP address matching supports exact matches, partial addresses that match networks using netmasks of 255.0.0.0, 255.255.0.0, and 255.255.255.0, or network addresses using the specified netmask or bit count. The @LOCAL name will allow browse data from all local interfaces. The @IF(name) name will allow browsing from the named interface.

You can also use the BrowseDeny directive to deny packets. It works the same way as BrowseAllow

Browsing

The Browsing directive controls whether or not network printer browsing is enabled. The default setting is On. This directive does not enable sharing of local printers by itself; you must also use the BrowseAddress or BrowseProtocols directives to advertise local printers to other systems.

DefaultShared

The DefaultShared directive specifies whether printers are shared (published) by default. The default is yes.

JobRetryInterval

The JobRetryInterval directive specifies the number of seconds to wait before retrying a job. This is typically used for fax queues but can also be used with normal print queues whose error policy is retry-job. The default is 30 seconds.

CUPS allows you also to fix access rights to server:

<Location />
     Order Deny,Allow
     Deny From All
     Allow From 127.0.0.1
     Allow From @LOCAL
     </Location>
    

In this example, we allow users to access CUPS' home web interface from localhost and from the same LAN as the CUPS server. Using this method, you can configure admin access.

Location

The Location directive specifies access control and authentication options for the specified HTTP resource or path. The Allow, AuthType, Deny, Encryption, Limit, LimitExcept, Order, Require, and Satisfy directives may all appear inside a location.

Here are common locations on CUPS server:

  • /: the path for all get operations (get-printers, get-jobs, etc.)

  • /admin: the path for all administration operations (add-printer, delete-printer, start-printer, etc.)

  • /admin/conf: path to access to the CUPS configuration files (cupsd.conf, client.conf, etc.)

  • /admin/log: path for access to the CUPS log files (access_log, error_log, page_log)

  • /classes: path for all classes

  • /classes/name: resource for class name

  • /jobs: path for all jobs (hold-job, release-job, etc.)

  • /printers: path for all printers

  • /printers/name: path for printer name

[Note] Note

More specific resources override the less specific ones. So the directives inside the /printers/name location will override the ones from /printers. Directives inside /printers will override the ones from /. None of the directives are inherited.

Allow
<Location /path>
	...
	Allow from All
	Allow from None
	Allow from *.domain.com
	Allow from .domain.com
	Allow from host.domain.com
	Allow from nnn.*
	Allow from nnn.nnn.*
	Allow from nnn.nnn.nnn.*
	Allow from nnn.nnn.nnn.nnn
	Allow from nnn.nnn.nnn.nnn/mm
	Allow from nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
	Allow from xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
	Allow from @LOCAL
	Allow from @IF(name)
	</Location>

The Allow directive specifies a hostname, IP address, or network that is allowed access to the server. Allow directives are cumulative, so multiple Allow directives can be used to allow access for multiple hosts or networks. The /mm notation specifies a CIDR netmask.

The @LOCAL name will allow access from all local interfaces. The @IF(name) name will allow access from the named interface.

2.1.4. Securing your CUPS server

In the default "standalone" configuration, there are few potential security risks - the CUPS server does not accept remote connections, and only accepts shared printer information from the local subnet. When you share printers and/or enable remote administration, you expose your system to potential unauthorized access. This help page provides an analysis of possible CUPS security concerns and describes how to better secure your server.

Authentication Issues

When you enable remote administration, the server will use Basic authentication for administration tasks. The current CUPS server supports Basic, Digest, and local certificate authentication:

  • Basic authentication essentially places the clear text of the username and password on the network. Since CUPS uses the system username and password account information, the authentication information could be used to gain access to possibly privileged accounts on the server.

    You should enable encryption to hide the username and password information - this is the default on MacOS X and systems with GNU TLS or OpenSSL installed.

  • Digest authentication uses an MD5 checksum of the username, password, and domain ("CUPS"), so the original username and password is not sent over the network. The current implementation does not authenticate the entire message and uses the client's IP address for the nonce value, making it possible to launch “man in the middle” and replay attacks from the same client.

    You should enable encryption to hide the username and password information.

  • Local certificate authentication passes 128-bit "certificates" that identify an authenticated user. Certificates are created on-the-fly from random data and stored in files under /var/run/cups/certs. They have restricted read permissions: root + system-group(s) for the root certificate, and lp + lp for CGI certificates. Because certificates are only available on the local system, the CUPS server does not accept local authentication unless the client is connected to the loopback interface (127.0.0.1 or ::1) or domain socket.

    Ensure that unauthorized users are not added to the system group(s).

Denial of Service Attacks

When printer sharing or remote administration is enabled, the CUPS server, like all Internet services, is vulnerable to a variety of denial of service attacks:

  • Establishing multiple connections to the server until the server will accept no more.

    This cannot be protected against by any known software. The MaxClientsPerHost directive can be used to configure CUPS to limit the number of connections allowed from a single host, however that does not prevent a distributed attack.

    You should limit access to trusted systems and networks.

  • Repeatedly opening and closing connections to the server as fast as possible.

    There is no easy way of protecting against this in the CUPS software. If the attack is coming from outside the local network, it may be possible to filter such an attack. However, once the connection request has been received by the server it must at least accept the connection to find out who is connecting.

  • Flooding the network with broadcast packets on port 631.

    It might be possible to disable browsing if this condition is detected by the CUPS software, however if there are large numbers of printers available on the network such an algorithm might think that an attack was occurring when instead a valid update was being received.

    You should block browse packets from foreign or untrusted networks using a router or firewall.

  • Sending partial IPP requests; specifically, sending part of an attribute value and then stopping transmission.

    The current code will wait up to 1 second before timing out the partial value and closing the connection. This will slow the server responses to valid requests and may lead to dropped browsing packets, but will otherwise not affect the operation of the server.

    You should block IPP packets from foreign or untrusted networks using a router or firewall.

  • Sending large/long print jobs to printers, preventing other users from printing.

    There are limited facilities for protecting against large print jobs (the MaxRequestSize attribute), however this will not protect printers from malicious users and print files that generate hundreds or thousands of pages.

    You should restrict printer access to known hosts or networks, and add user-level access controls as needed for expensive printers.

Encryption Issues

CUPS supports 128-bit SSL 3.0 and TLS 1.0 encryption of network connections via the OpenSSL, GNU TLS, and CDSA encryption libraries. In addition to the potential security issues posed by the SSL and TLS protocols, CUPS currently has the following issues.

Certification validation/revocation; currently CUPS does not validate or revoke server or client certificates when establishing a secure connection. This can potentially lead to "man in the middle" and impersonation/spoofing attacks over unsecured networks. Future versions of CUPS will support both validation and revocation of server certificates.

Do not rely on encryption for security when connecting to servers over the Internet or untrusted WAN links.

2.1.5. Browsing printers in LDAP directory

CUPS 1.2 allows you to browse printers in a LDAP directory so that you can add it as new printers. As many other services, you will need to specify the way CUPS server can ask LDAP directory, in /etc/cups/cupsd.conf:

BrowseLDAPBindDN

The BrowseLDAPBindDN directive specifies the LDAP domain name to use when listening for printer registrations. The default is undefined.

BrowseLDAPDN

The BrowseLDAPDN directive specifies the LDAP domain name to use when registering local shared printers. The default is undefined

BrowseLDAPPassword

The BrowseLDAPPassword directive specifies the access password to use when connecting to the LDAP server. The default is undefined.

BrowseLDAPServer

The BrowseLDAPServer directive specifies the name of the LDAP server to connect to. The default is undefined.

Let's write an example:

    BrowseLocalProtocols ldap
    BrowseRemoteProtocols ldap
    
    BrowseLDAPServer localhost
    BrowseLDAPDN ou=printers,dc=example,dc=com
    BrowseLDAPBindDN uid=Manager,dc=example,dc=com
    BrowseLDAPPassword password

2.2. Sharing Files with NFS

NFS allows you to export whole directories, even whole filesystems, through the network, therefore enabling file sharing between users. This sharing type is simple to put in place and is essentially used with GNU/Linux and UNIX® systems. NFS is not recommended if you have strong security constraints. Using NFS shouldn't be used often on a local network.

2.2.1. Installing a NFS Server

The installation is simple and only requires the nfs-utils package.

2.2.2. Configuring a NFS Server

The configuration of NFS filesystem exports is done in the /etc/exports file. It allows you to establish the access mode to data, as well as rights given to users and machines. It's mandatory to supervise rights assignment to secure data access.

2.2.3. Using NFS v4

Mandriva Enterprise Server 5 offers a NFS v4-based server. This new version brings great enhancements security-wise, and the following features:

  • Addition of file states concerning locking, read-write, between clients and the server.

  • Lease base for file locking allowing clients to recuperate file ownership during lease time. The client must contact the server if he wants to extend the length of the lease.

  • Addition of security components such as Kerberos 5 and SPKM3.

  • Extension of support for ACL files, notably adding group and user names, allowing this type of direct access.

  • Combination of many NFS protocols, allowing better management by firewalls.

  • Replication support.

  • Client capacity to maintain sessions or to recuperate them even if the server crashes or if there's a network crash.

  • Management of a “pseudo” filesystem allowing you to manage all NFS exports from a common root.

Here's a procedure allowing you to put in place a NFS exports tree structure with the help of Kerberos 5. The prerequisites: NFS needs to be installed, and you need an operational Kerberos server.

  1. Declaring the Pseudo Filesystem in /etc/fstab

    Just add the two following lines:

    rpc_pipefs /var/lib/nfs/rpc_pipefs rpc_pipefs
          defaults 0 0 nfsd /proc/fs/nfsd nfsd defaults 0
          0

    Then, as for a classic filesystem, mount it:

    # mount rpc_pipesfs
  2. Creating the Root of the Exports' Tree Structure

    Since NFS v4 provides a new, pseudo filesystem, all exports are positioned starting at the tree structure's root:

    /exports/
          |-- test1
          |-- ...
          `-- testn

    To create it, specify this parameter: fsid=0:

    # cat /etc/exports
    	/export  *(rw,fsid=0,insecure,no_subtree_check,5)
  3. Creating the Export's Tree Structure

    Then, the tree structure follows the classic scheme:

    # cat /etc/exports
    	/export  *(rw,fsid=0,insecure,no_subtree_check)
    	/export/test1  *(rw,nohide,insecure,no_subtree_check)
    	...
         

    Mounting the resource is done in relation to the NFS root:

    # mount nfs4srv:/test1 /mnt/nfs
  4. Using Kerberos

    First of all, create a principal for NFS. Also create a key for the server and client using the kadmin shell:

    kadmin.local:  addprinc -randkey nfs/nfs4srv.edge-it.subnet
    WARNING: no policy specified for nfs/nfs4srv.example.com@EXAMPLE.COM;
            defaulting to no policy
    Principal "nfs/nfs4srv.example.com@EXAMPLE.COM" created.
    
    kadmin.local:  ktadd  -e des-cbc-crc:normal nfs/nfs4srv.example.com
    Entry for principal nfs/nfs4srv.example.com with kvno 3, encryption
            type Triple DES cbc mode with HMAC/sha1 added to keytab
    	WRFILE:/etc/krb5.keytab.
    Entry for principal nfsnfs4srv.example.com with kvno 3, encryption
          type DES cbc mode with CRC-32 added to keytab
          WRFILE:/etc/krb5.keytab.
    

    Copy file krb5.keytab on the NFS server and on clients using NFSv4.

    All that's left is to create the exports using krb5, with a specific client: gss/krb5.

    # cat /etc/exports
    /export gss/krb5(rw,fsid=0,insecure,no_subtree_check,sync,5)

    Use the mount command with the sec=kbr5 option:

    # mount -t nfs4 -o sec=krb5 nfs4srv:/ /nnt/nfs

2.3. FTP File Server

ProFTPD allows you to create and configure a FTP server. You can configure it through a specific Webmin module located in the Servers category.

2.3.1. Installation and Tree Structure of ProFTPD

Two packages exist for proftpd:

  • proftpd: package containing the whole ProFTPD server;

  • proftpd-anonymous: module which activates anonymous connections to the FTP server.

For security reason, we will only install the first package.

# urpmi proftpd

The tree structure provided by proftpd is relatively simple:

  • /etc/proftpd.conf: ProFTPD's configuration file;

  • /etc/xinetd.d/proftpd-xinetd: configuration of ProFTPD's daemon launched via xinetd (not recommended);

  • /etc/rc.d/init.d/proftpd: ProFTPD's initscript configured in autonomous mode;

  • /var/log/proftpd: ProFTPD's log file directory.

2.3.2. ProFTPD Toolbox

To verify the configuration file's syntax:

# proftpd -t
    Checking syntax of configuration file
    Syntax check complete.

To verify that the server works properly:

# service proftpd status
    proftpd (pid 32445) is running ...
    # telnet 192.168.40.52 21
    Trying 192.168.40.52...
    Connected to tellure.edge-it.subnet (192.168.40.52).
    Escape character is '^]'.
    220 ProFTPD 1.2.10 Server (ProFTPD Default Installation)
    [192.168.40.52]
   

You should also test a complete session by connecting to the server.

The proftpd package installs, not counting the server daemon, a certain number of useful commands to monitor your server's state.

ftpcount

Allows you to count the number of connections on the FTP server at a given time:

$ ftpcount
Master proftpd process 32445:
Service class                      -   1 user
ftptop

Enables you to view in real time the FTP server's activity, and its connections:

ftptop/0.9: Thu Jan  5 11:54:49 2009, up for 1 min
1 Total FTP Sessions: 0 downloading, 0 uploading, 1 idle

PID   S USER     CLIENT               SERVER          TIME COMMAND
32455 I anne     test.domain.subne 0.0.0.0:21      0m47s  idle
ftpwho

Allows you to view active connections on the server at a given time, and information concerning running sessions:

$ ftpwho -v
standalone FTP daemon [32445], up for  2 hrs 18 min
  542 anne     [ 0m11s]  0m11s idle
        client: workstation.edge-it.subnet [192.168.40.140]
        server: 0.0.0.0:21 (ProFTPD Default Installation)
        location: /
Service class                      -   1 user

2.3.3. Securing a Proftpd Server

To secure a FTP server, you need to first to set up an efficient firewall. Apart that, securing your server depends on user management and your configuration's customization.

Here's a typical configuration file which we'll detail later on:

# cat /etc/proftpd.conf
    ServerName                      "FTP SERVER"
ServerType                      standalone
DeferWelcome                    off
TransferLog                     /var/log/proftpd.xferlog
DefaultRoot                     ~
RequireValidShell               off
ServerIdent                     off
RootLogin			off

ShowSymlinks                    off
DefaultServer                   on
AllowOverwrite                  off

TimeoutNoTransfer               600
TimeoutStalled                  600
TimeoutIdle                     1200

DisplayLogin                    /etc/welcome.msg
DisplayFirstChdir               .message

DenyFilter                      \*.*/
Bind                            192.168.10.55  
2.3.3.1. User Management

A great part of securing your FTP server is linked to how you manage your users. Here are critical steps.

Users without Shells

It's preferable to give FTP access to users with no shell. Here's how to create them:

# useradd -s /bin/false user

or how to modify them:

# usermod -s /bin/false user

To authorize access to the FTP server to users with no shell, add in /etc/proftpd.conf:

RequireValidShell  on
User Sessions in chroot Mode

We lock users in a fixed directory, preventing them from going up in the tree structure. To do so, add the following line in /etc/proftpd.conf:

	DefaultRoot                     ~
Prohibit FTP server access to root

Since passwords circulate in clear text, the root password could intercepted by someone. To prevent that, add the following line to /etc/proftpd.conf:

RootLogin off
Prohibit anonymous connections

This is done by default since implementing this functionality demands the installation of an additional package (proftpd-anonymous).

Limit connections to a given list of users

The Limit instruction allows to specify authorized (or not) users and groups to connect to the server.

<Limit LOGIN>
	AllowUser	workstation
	AllowGroups	devels
	DenyAll
</Limit>
2.3.3.2. Securing the Server's Configuration

All points mentioned hereafter are relative to modifications in the /etc/proftpd.conf file.

[Note] Note

ProFTPD uses root privileges only when it's necessary. In the opposite case, it uses the identity defined in the configuration. Steps which need root privileges are:

  • accessing ports less than or equal to 1024;

  • determining limitations on resources;

  • reading configuration information;

  • executing code portions associated with the network.

Hiding the banner

This consists in not displaying information about the FTP server type and version:

ServerIdent                     off

To verify this:

# telnet 192.168.40.52 21
	Trying 192.168.40.52...
	Connected to tellure.edge-it.subnet (192.168.40.52).
	Escape character is '^]'.
	220 192.168.40.52 FTP server ready
Modifying the default access port

Define a port higher than 1024 (accessible to a non-root user). You can also plan to use an iptables command to render this manipulation transparent.

Modifying default messages

The ProFTPD server sends a certain number of messages during the different steps of an FTP session. Some of them can be modified to communicate with the user (security rules reminder, rights, etc.) or to hide messages which could highlight the server type or its version.

Here's the list of instructions corresponding to those messages:

  • DisplayConnect <filename>: message displayed before the authentication procedure;

  • DisplayFirstChdir <filename>: message displayed during the first directory change;

  • DisplayLogin <filename>: message displayed during login;

  • DisplayGoAway <filename>: message displayed during a refused connection;

  • DisplayQuit <filename>: message displayed at the end of an FTP session;

  • ServerName <text>: string displayed during login messages.

To these instructions we can add DeferWelcome which, when activated, doesn't display a welcome message when a user authenticates succesfully.

Establishing timeout

These allow you to avoid having to maintain open connections which are not used. There are a certain number of levels on which we can fix timeouts:

  • TimeoutNoTransfer <seconds>: maximum number of seconds during which an authenticated client can be connected but inactive (by default: 300);

  • TimeoutStalled <seconds>: maximum number of seconds during which an FTP connection can be in stalled state (by default: 3600);

  • TimeoutIdle <seconds>: maximum number of seconds during which an FTP connection can be in idle state (by default: 600).

Controlling commands passed by users

The Limit instruction allows you to precisely list authorized commands for the FTP server users. These commands can be specified one by one, or by a group of commands.

Individual commands:

  • CWD (Change Working Directory): change directory;

  • MKD/XMKD (MaKe Directory): create a directory;

  • RNFR (ReName FRom), RNTO (ReName TO): rename a directory;

  • DELE (DELEte): destroy a file;

  • RMD / XRMD (ReMove Directory): remove a directory;

  • RETR (RETRieve): transfer a file from the server to the client;

  • STOR (STORe): transfer a file from a client to the server;

Groups of commands

  • READ ALL FTP: commands concerning file reading (doesn't concern the listing of a directory): RETR, SITE, SIZE, STAT;

  • WRITE ALL FTP: commands concerning writing, creating and deleting a directory: APPE, DELE, MKD, RMD, RNTO, STOR, XMKD, XRMD;

  • DIRS ALL FTP: commands concerning the display directory files: CDUP, CWD, LIST, MDTM, NLST, PWD, RNFR, XCUP, XCWD, XPWD;

  • ALL ALL FTP: command identical to READ WRITE DIRS.

Example:

Limit commands users can do by taking away all file and directory deleting rights in the FTP repository:

<Limit RNFR DELE RMD>
	DenyAll
	</Limit>
Managing network interfaces

In the case where the machine has many interfaces or may IP addresses, we recommend that you link the server to a unique address.

Bind		192.168.10.55
Correcting an FTP security breach

The following line allows you to prevent a breach which could be provoked by the NLST /../*/../*/../*/../*/../*/../*/../*/../*/../*/../ command:

DenyFilter		\*.*/
2.3.3.3. Customizing Access Rules to Files According to Needs

Proftpd allows you to customize the server configuration according to well-defined contexts:

  • directories

  • virtualhosts (this notion in ProFTPD is very similar to the one found in Apache).

Let's take the case of directories. The FTP repository is located in /var/lib/ftp:

  • /var/lib/ftp/datas: write-accessible application data for developer and in read-only for visitors;

  • /var/lib/ftp/pub: repository accessible by all users to place files, but no deletions possible;

The corresponding configuration would be:

<Directory /var/lib/ftp/datas>
     <Limit WRITE DIRS>
     DenyGroup visitors
     AllowGroup devels
     </Limit>
     </Directory>
     <Directory /var/lib/ftp/pub>
     <Limit ALL>
     AllowGroup visitors devels
     </Limit>
     </Directory>

2.3.4. Using LDAP Authentication on ProFTPD

By default, Proftpd contains a module allowing you to authentify users of your FTP server from an OpenLDAP directory.

The configuration is relatively simple. We'll start from the following configuration:

LDAPServer <ldap_server_ip_address> LDAPDNInfo
    "cn=Manager,dc=example,dc=com" "<password>" LDAPQueryTimeout 5
    LDAPDoAuth on "dc=example,dc=com" LDAPDoUIDLookups on
    "ou=Personnes,dc=example,dc=com" LDAPDoGIDLookups on
    "ou=Groups,dc=example,dc=com" LDAPNegativeCache off
    LDAPHomedirOnDemand off LDAPDefaultAuthScheme MD5

The configuration is based on parameters, specifying the essential data to access the LDAP server and interrogate it:

LDAPDNInfo

Holds the DN information for the initial contact to the directory.

LDAPQueryTimeout

Sets the timeout on LDAP requests.

LDAPDoAuth

Authorizes LDAP authentication.

LDAPDoUIDLookups

Sets the default GID to be assigned to users when the uidNumber attribute is not found.

LDAPDoGIDLookups

Authorizes LDAP resolution for group rights, and GID to be able to read directories.

LDAPHomedirOnDemand

Forces all LDAP-authentified users to use HomeDironDemand by default.

LDAPDefaultAuthScheme

Sets the authentication hash to be used when {hashname} is not specified.

2.4. Samba File and Print Server

This section presents the installation of a Samba server (principal domain controller, authentication and authorizations, file and print server) based on an LDAP directory to manage users. It describes the installation method, elements specified for specific services as well as the configuration put in place. You'll also find notes on basic tools used to test the service and to add the first users.

2.4.1. General Concepts and Web Reference

Announced in January 1992 by Andrew Tridgell, a student at the computer labs of the Australia National University, nbserver was only supposed to allow the mounting of Windows® shares on a UNIX machine. Since then it has become a complete set of tools to assure network resource management in heterogeneous environments. Nbserver changed its name to SaMBa (1.6.05) in April 1994 to evoke the implemented protocol. From version to version, its behavior got closer to a Windows® NT4 server (domain control, management of authentication to resources, resource sharing, SMB network path, etc.). SaMBa 2.0 was released in January 1999, and SaMBa 3.0 which finally allows you to manage Windows® user groups, was released in September 2003.

SaMBa 4 announces the possibility to put in place an Active Directory-type server.

Samba is a software suite which allows the interconnection of different systems around a common protocol called NetBIOS (Network Basic Input Output System) on which are based SMB (Server Message Block) and CIFS (Common Internet File System) to assure resource sharing (files, printers, serial and parallel ports).

The main goal of he Windows® SMB protocol is to share files. In Samba that goal is enhanced by:

  • Determining the presence of other servers by using this protocol on the network (Network Browsing);

  • Printing on the network;

  • Authentication to access shares, directories and files;

  • Lock of files in use;

  • Notification of changes made on files and directories;

  • Note of the protocol version to use (Dialect);

  • Attribute management of extended files;

  • Unicode support;

  • File-lock management.

Authentication allows notably to put in place Microsoft NT4-type domains.

Main Web references:

2.4.2. Installation and Configuration

At the end of this part, a PDC (Primary Domain Controller) server will be put in place. Users, groups and machines will be stored in an LDAP directory. We take for granted that such a directory is already functional and it's possible to add the necessary data to it. But before entering this part, it's imperative that you install the Samba package and test a simple configuration.

2.4.2.1. Necessary Packages
  • samba-server: holds the smbd daemons (authentication and management of share access) and nmbd (dialog);

  • network: name resolution, tole management. It's the basis of a Microsoft NT4 server-type service.

  • samba-client: contains the clients which allow it to access remote SMB/CIFS resources (needs mount-cifs to mount a remote CIFS-type filesystem).

  • samba-winbind: allows third-party software (PAM, domain member Samba server, Squid, Apache) to authentify themselves on a domain server (Samba or Microsoft Windows®). Such an architecture may need nss_wins (for PAM).

  • samba-smbldap-tools: this package doesn't contain the whole set of smbldap-tools, but only the /usr/share/samba/scripts/migrate-smbldap script;

  • samba-swat: Samba's Web configuration interface;

  • samba-doc: all of Samba's documentation;

  • samba-vscan-*: every VFS enabling you to scan for viruses on the fly (needs a configured server);

  • smbldap-tools: this package contains every smbldap-tools scripts which facilitate data manipulation (users, groups, machines) in the context of an authentified Samba server on an LDAP directory.

Here's Samba's tree structure:

/etc/samba

Holds all of the server's configuration files, essentially samba.conf for general configuration and shares configuration, as well as smb-winbind.conf to configure Winbind.

/usr/lib/samba/vfs

This directory lists every VFS (Virtual File System) module available on your server. In the current version, you have:

  • audit: audit tool allowing an exhaustive verification of filesystem access via defined data shares.

  • default_quota: enables you to establish by default quotas for users or groups;

  • extd_audit: same as audit but with a different log conservation method;

  • recycle: allows you to put in place network trash;

  • netatalk: permits you to manage Apple compatibility on resource shares;

  • vscan: allows you to plug an anti-virus to do on-the-fly scans on one or many shares;

You will find more information in the official documentation: VFS modules in a Samba server.

/var/cache/samba

This directory contains all cache memories in *.tdb format files. They contain information such as path to resources, the Netbios names, logins, etc. These files can be the origin of malfunctions when, for example, the cache memory stays unchanged while modifications have been done.

/var/log/samba

You will find all of Samba's logs. Be careful, this directory can rapidly reach a gigantic size, especially if you work on a network which contains many machines.

2.4.2.2. Configuring a Samba Server in Autonomous Mode
[Note] Note

In test phase, it's preferable to restart Samba completely each time you modify /etc/samba/smb.conf.

2.4.2.2.1. Pre-requisites

Here's the list of elements which must be defined to start:

Workgroup name

In autonomous mode, it's necessary to define the workgroup name to which the server belongs. It's only an arbitrary information but it's mandatory to regroup different machines in the same virtual group.

This information is given by the workgroup attribute. This option will also allow you to specify the domain name to control when the server becomes a PDC. For this example, the workgroup's name will be “example”.

# cat /etc/samba/smb.conf
[global]
...
        workgroup = example
...
[Warning] Warning

It's mandatory to specify this attribute.

NetBIOS name of the machine

It's possible to give a NetBIOS name to a machine which will be different than the name affected in the DNS. You can manage this through the netbios name attribute:

# cat /etc/samba/smb.conf
[global]
...
        netbios name = MES5
...
[Note] Note

This attribute is optional. If it's omitted, the attribute will take the machine name as defined in the DNS, by default.

Comment about the machine

Similarly, we can associate a comment to it to identify the machine more clearly:

# cat /etc/samba/smb.conf
	 [global]
	 ...
	 server string = Samba Server %v
	 ...
[Note] Note

Again, this attribute is optional. If it's omitted, it will stay empty.

2.4.2.2.2. Configuring the Service

It's the simplest and fastest way to test the installed packages. No domain notion, only one server with a few users that can connect on a personal share ([homes]), and a public share open to all (even anonymous). This simple test allows us to validate that the packages are operational and that the authentication works.

Let's use the following /etc/samba/smb.conf file:

# cat /etc/samba/smb.conf
[global]
        workgroup = example
        server string = Samba Server %v
        map to guest = Bad User
        log file = /var/log/samba/%m.log
        max log size = 50
        socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
 
[homes]
        #the [homes] block use corresponds to the default definition of
        # personal user directories
        ; the default path will then be ///home/username//
        # we could add the following attributes to define the shares
        ; comment = Home Directories
        ; browseable = no
        # and users can create/modify/delete files/directories in it
        read only = no
 
[public]
        # this share defines a public directory
        path = /home/public
        comment = Public Directory
        # we don't have to authentify to access it
        guest ok = yes
        # and users can create/modify/delete files/directories in it
        read only = no
        ; browseable = no
[Note] Note

As of version 3.4.x, Samba by default stores the account details in the tdbsam backend instead of smbpasswd backend which was the default for at least Samba 2.0.x versions. In anticipation of the arrival of Samba 3.4.x, it is advisable to use the tdbsam backend.

Indeed, the upgrade process does not migrate the accounts. It is therefore advisable to migrate now account details of Samba smbpasswd backend to tdbsam backend using the command (as root):

#pdbedit -i smbpasswd -e tdbsam

In the case, inadvisable, in which you want to keep the smbpasswd backend, do not forget to add the following option in smb.conf:

passdb backend = smbpasswd

Let's verify that it doesn't have any errors:

# testparm
      Load smb config files from /etc/samba/smb.conf
      Processing section "[homes]"
      Processing section "[public]"
      Loaded services file OK.
      WARNING: passdb expand explicit = yes is deprecated
      Server role: ROLE_STANDALONE
      Press enter to see a dump of your service definitions
 
      [global]
      workgroup = example
      server string = Samba Server %v
      map to guest = Bad User
      log file = /var/log/samba/%m.log
      max log size = 50
      socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
 
      [homes]
      read only = No
 
      [public]
      comment = Public Directory
      path = /home/public
      read only = No
      guest ok = Yes

No noticeable errors, only a warning concerning the obsolete attribute which is defined by default.

2.4.2.2.3. Starting the Service

Now the service can be started:

# service smb start
Launching SaMBa service:                                             [  OK  ]
Launching NMB service:                                               [  OK  ]
# ps aux
...
root     27843  0.0  0.7  10724  4028 ?        Ss   12:43   0:00 smbd -D
root     27844  0.0  0.7  10724  4020 ?        S    12:43   0:00 smbd -D
root     27854  0.0  0.4   6568  2068 ?        Ss   12:43   0:00 nmbd -D
...

The service is started. Let's see if it answers to requests:

# smbclient -L localhost
Password:
Domain=[MES5] OS=[Unix] Server=[Samba 3.2.7]
 
        Sharename       Type      Comment
        ---------       ----      -------
        homes           Disk
        public          Disk      Public Directory
        IPC$            IPC       IPC Service (Samba Server 3.2.7)
        ADMIN$          IPC       IPC Service (Samba Server 3.2.7)
Domain=[MES5] OS=[Unix] Server=[Samba 3.2.7]
 
        Server               Comment
        ---------            -------
 
        Workgroup            Master
        ---------            -------
        example

The service answers when we ask it to list visible resources. We can play with the browseable attribute in the shares to verify that they appear, or not. For the rest of the tests, the [homes] share will have the browseable = no attribute.

2.4.2.2.4. First Connection in Anonymous Mode

We defined a public share accessible to all, even without authentication. We must now verify that it's really the case:

# mkdir -m 777 /home/public
      #  ll /home
total 28
...
drwxrwxrwx  2 root   root   4096 jui 26 13:03 public/
# smbclient //localhost/public
Password:
Domain=[MES5] OS=[Unix] Server=[Samba 3.2.7]
smb: \> dir
  .                                   D        0  Wed Jul 26 13:03:24 2008
  ..                                  D        0  Wed Jul 26 13:03:24 2008
 
                48377 blocks of size 16384. 47347 blocks available
smb: \> mkdir test
smb: \> dir
  .                                   D        0  Wed Jul 26 13:03:56 2008
  ..                                  D        0  Wed Jul 26 13:03:24 2008
  test                                D        0  Wed Jul 26 13:03:56 2008
 
                48377 blocks of size 16384. 47347 blocks available
# ll /home/public/
total 4
drwxr-xr-x  2 nobody nogroup 4096 jui 26 13:03 test/

Everything seems OK for the moment.

2.4.2.2.5. Creating and Using a User

Let's create a user on the system and on Samba:

# useradd -g users -m qatest
# getent passwd qatest
qatest:x:1001:100::/home/qatest:/bin/bash
# ll /home/qatest/ -d
drwxr-xr-x  3 qatest users 4096 jui 26 12:34 /home/qatest//
# passwd qatest
Changing password for user qatest.
      New UNIX password: 
BAD PASSWORD: it is based on a dictionary word
Retype new UNIX password:
passwd: all authentication tokens updated successfully.
# smbpasswd -a qatest
New SMB password:
Retype new SMB password:
# cat /etc/samba/smbpasswd
qatest:1001:8B28C7EF8A97362BAAD3B435B51404EE
        :EB407C0BA4F661A80BCF6B8231A0F6F7:[U          ]:LCT-44C74D6A:

Now, let's verify our user:

# ssh qatest@localhost
Warning: Permanently added 'localhost' (RSA) to the list of known hosts.
qatest@localhost's password:
[qatest@mes5] $ smbclient -L localhost -U qatest
Password:
Domain=[MES5] OS=[Unix] Server=[Samba 3.2.7]
 
        Sharename       Type      Comment
        ---------       ----      -------
        public          Disk      Public Directory
        IPC$            IPC       IPC Service (Samba Server 3.2.7)
        ADMIN$          IPC       IPC Service (Samba Server 3.2.7)
        qatest          Disk      Home directory of qatest
Domain=[MES5] OS=[Unix] Server=[Samba 3.2.7]
 
        Server               Comment
        ---------            -------
 
        Workgroup            Master
        ---------            -------
        example            MES5

We see that the [homes] share has disappeared from the list (browseable = no attribute in place), but that a username share has also appeared (qatest. In fact, a user has the right to see his own directories if we use the standard definition of [homes].

Let's connect to that share:

$ smbclient //localhost/qatest -U qatest
Password:
Domain=[MES5] OS=[Unix] Server=[Samba 3.2.7]
smb: \> dir
  .                                   D        0  Wed Jul 26 13:14:33 2008
  ..                                  D        0  Wed Jul 26 13:03:24 2008
  tmp                                 D        0  Wed Jul 26 12:34:36 2008
  .screenrc                           H     3793  Wed Jul 26 12:34:37 2008
  .bash_logout                        H       24  Wed Jul 26 12:34:37 2008
  .bash_profile                       H      191  Wed Jul 26 12:34:37 2008
  .bashrc                             H      124  Wed Jul 26 12:34:37 2008
  .bash_completion                    H      145  Wed Jul 26 12:34:37 2008
  .bash_history                       H       33  Wed Jul 26 13:14:33 2008
 
                48377 blocks of size 16384. 47346 blocks available
smb: \> mkdir test
smb: \> dir
  .                                   D        0  Wed Jul 26 13:26:04 2008
  ..                                  D        0  Wed Jul 26 13:03:24 2008
  tmp                                 D        0  Wed Jul 26 12:34:36 2008
  .screenrc                           H     3793  Wed Jul 26 12:34:37 2008
  .bash_logout                        H       24  Wed Jul 26 12:34:37 2008
  .bash_profile                       H      191  Wed Jul 26 12:34:37 2008
  .bashrc                             H      124  Wed Jul 26 12:34:37 2008
  .bash_completion                    H      145  Wed Jul 26 12:34:37 2008
  .bash_history                       H       72  Wed Jul 26 13:24:36 2008
  test                                D        0  Wed Jul 26 13:26:04 2008
 
                48377 blocks of size 16384. 47346 blocks available
$ ll -a
total 40
drwxr-xr-x  4 qatest users 4096 jui 26 13:26 ./
drwxr-xr-x  6 root   root  4096 jui 26 13:03 ../
-rw-r--r--  1 qatest users  145 jui 26 12:34 .bash_completion
-rw-------  1 qatest users   72 jui 26 13:24 .bash_history
-rw-r--r--  1 qatest users   24 jui 26 12:34 .bash_logout
-rw-r--r--  1 qatest users  191 jui 26 12:34 .bash_profile
-rw-r--r--  1 qatest users  124 jui 26 12:34 .bashrc
-rw-r--r--  1 qatest users 3793 jui 26 12:34 .screenrc
drwxr-xr-x  2 qatest users 4096 jui 26 13:26 test/
drwx------  2 qatest users 4096 jui 26 12:34 tmp/

Now, let's see the public share:

$ smbclient //localhost/public -U qatest
Password:
Domain=[MES5] OS=[Unix] Server=[Samba 3.2.7]
smb: \> dir
  .                                   D        0  Wed Jul 26 13:03:56 2008
  ..                                  D        0  Wed Jul 26 13:03:24 2008
  test                                D        0  Wed Jul 26 13:03:56 2008
 
                48377 blocks of size 16384. 47346 blocks available
smb: \> mkdir qatest
smb: \> dir
  .                                   D        0  Wed Jul 26 13:30:35 2008
  ..                                  D        0  Wed Jul 26 13:03:24 2008
  test                                D        0  Wed Jul 26 13:03:56 2008
  qatest                              D        0  Wed Jul 26 13:30:35 2008
 
                48377 blocks of size 16384. 47346 blocks available
$ ll /home/public/
total 8
drwxr-xr-x  2 qatest users   4096 jui 26 13:30 qatest/
drwxr-xr-x  2 nobody nogroup 4096 jui 26 13:03 test/

Our autonomous Samba server is fully operational.

2.4.2.3. Samba with LDAP Authentication

The configuration that we've used up until now will be our base for this section. We will only modify the authentication. The latter will now be based on an LDAP directory.

2.4.2.3.1. Functional Samba Installation

Simply refer to the preceding section (Section 2.4.2.2, “Configuring a Samba Server in Autonomous Mode”). We'll keep the same pre-requisites concerning the domain name, the machine's NetBIOS name and the comment associated with it.

# vi /etc/samba/smb.conf
[global]
        ...
        workgroup = example
        netbios name = MES5
        server string = Samba Server %v
        ...
2.4.2.3.2. Domain SID

As long as the service hasn't been started at least once, no SID will have been attributed to the server/domain. It's for that reason that the recuperation of that information is only done after the test in autonomous mode.

The information is kept in /etc/samba/secrets.tdb, but it's not directly readable. We'll recuperate it with the net getlocalsid command:

# net getlocalsid
SID for domain dhcp110 is: S-1-5-21-1518519320-3136826138-1578965553
2.4.2.3.3. Domain Users and Groups

First of all, let's recall the list of particular SIDs recognized by Windows®. During its installation, Windows® NT4/200x/XP is configured with certain entities (users, group or alias). Each entity has an identified RID. These specific RID must be respected to preserve the integrity of operations. Samba must be fed with those essential domain entities.

[Note] Note

If Samba is configured to use tdbsam, the essential entities are automatically created. If LDAP is used, the directory administrator is responsible of their creation: you can use smbldap-tools to do so, or the smbldap-populate script.

Table 8.1. Windows Domain Entities

Declared Entity RID Type Essential
Domain Administrator 500 User No
Domain Guest 501 User No
Domain KRBTGT 502 User No
Domain Admins 512 Group Yes
Domain Users 513 Group Yes
Domain Guests 514 Group Yes
Domain Computers 515 Group No
Domain Controller 516 Group No
Domain Certificate Admins 517 Group No
Domain Schema Admins 518 Group No
Domain Enterprise Admins 519 Group No
Domain Policy Admins 520 Group No
Builtin Admins 544 Alias No
Builtin users 545 Alias No
Builtin Guests 546 Alias No
Builtin Power Users 547 Alias No
Builtin Account Operators 548 Alias No
Builtin System Operators 549 Alias No
Builtin Print Operators 550 Alias No
Builtin Backup Operators 551 Alias No
Builtin Replicator 552 Alias No
Builtin RAS Servers 553 Alias No

According to those specifications, we can deduce the mandatory entities and optional ones:

  • mandatory entries: even though it's not mandatory to have one for the PDC to work correctly, the domain administrator (Domain Administrator/500 - by default, only account to have total control on the system) is very important to manage the domain. A “nobody” user must be created if we want to use the ldapsam:trusted instruction (to diminish the dialog between Samba and the POSIX sub-system).

    Concerning groups, the following must be created: the Domain Administrator group, the Domain User group, and the Domain Guest group.

  • optional entries: according to the table, we should add the corresponding entities, and especially the Domain Computers group in order to associate the machines we'll integrate on that domain to it.

2.4.2.3.4. LDAP Directory

This section's goal is not to install a directory. Even if we describe some manipulations, they can in no case be considered as a recipe to put in place a production LDAP directory. On a server used to authentify services such as SSH/PAM, mail, and Apache, a tree structure will already exist.

For this section:

  • The basedn considered will be dc=example,dc=com

  • Users are in the ou=people,dc=example,dc=com OU

  • Groups are in the ou=group,dc=example,dc=com OU

  • A OU must be created to keep the machine accounts, if we don't want to mix them with the users (ou=hosts,dc=example,dc=com).

  • We must also have one (or many) account which will have have write-access in those OUs, as well as in the basedn to add/modify/delete information relative to Samba, and complementary tools.

You can quickly put in place an LDAP server with a script provided with the distribution. You must install the openldap-example-dit package. Then, execute the script to generate the configuration with the data that will be specified. This script creates the tree structure and the necessary accounts for Samba+LDAP, but also necessary to other applications:

# /usr/share/openldap/scripts/example-dit-setup.sh
Please enter your DNS domain name [example.com]:
example.com
 
 
Administrator account
 
The administrator account for this directory is
uid=LDAP Admin,ou=System Accounts,dc=example,dc=com
 
Please choose a password for this account:
New password:
Re-enter new password:
 
 
Summary
=======
 
Domain:        example.com
LDAP suffix:   dc=example,dc=com
Administrator: uid=LDAP Admin,ou=System Accounts,dc=example,dc=com
 
Confirm? (Y/n)
 
config file testing succeeded
Stopping ldap service
Finished, starting ldap service
Launching of /usr/bin/db_recover under /var/lib/ldap
removing /var/lib/ldap/alock
Launching of slapd (ldap + ldaps) :                     [  OK  ]
 
Your previous database directory has been backed up as /var/lib/
ldap.1155740637
All files that were backed up got the suffix "1155740637".
 
# ldapsearch -x
# extended LDIF
#
# LDAPv3
# base <> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
 
# example.com
dn: dc=example,dc=com
dc: example
objectClass: domain
objectClass: domainRelatedObject
associatedDomain: example.com
 
# People, example.com
dn: ou=People,dc=example,dc=com
ou: People
objectClass: organizationalUnit
 
# Group, example.com
dn: ou=Group,dc=example,dc=com
ou: Group
objectClass: organizationalUnit
description: Container for user accounts
 
# System Accounts, example.com
dn: ou=System Accounts,dc=example,dc=com
ou: System Accounts
objectClass: organizationalUnit
description: Container for System and Services privileged accounts
 
# System Goups, example.com
dn: ou=System Groups,dc=example,dc=com
ou: System Groups
objectClass: organizationalUnit
description: Container for System and Services privileged groups
 
# Hosts, example.com
dn: ou=Hosts,dc=example,dc=com
ou: Hosts
objectClass: organizationalUnit
description: Container for Samba machine accounts
...
# Account Admin, System Accounts, example.com
dn: uid=Account Admin,ou=System Accounts,dc=example,dc=com
uid: Account Admin
objectClass: account
objectClass: simpleSecurityObject
description: Account used to administer all users, groups, machines
        and general accounts
 
# nssldap, System Accounts, example.com
dn: uid=nssldap,ou=System Accounts,dc=example,dc=com
uid: nssldap
objectClass: account
objectClass: simpleSecurityObject
description: Unprivileged account which can be used by nss_ldap for
when anonymous searches
 are disabled...

We find Samba's OUs (People/Group/Hosts) as well as an OU (System Accounts) that contains connection accounts for the different account management tools (account admin, nssldap).

2.4.2.3.5. NSS + LDAP

In the part concerning autonomous mode (Section 2.4.2.2.5, “Creating and Using a User”), we saw that we must first create a system user and to make it be recognized by Samba. The same goes for a PDC for which users are registered on an LDAP directory.

To do so, you have to create a Posix user in the LDAP directory and to add the specific information to Samba (using smbldap-tools, for example), and the system must also be able to access this user. We must then configure an NSS (Name Service Switch).

Let's install nssldap.

# urpmi nss_ldap

For NSS to know that it must consult an LDAP directory to find users and groups, we must modify /etc/nsswitch.conf:

# /etc/nsswitch.conf
# An example Name Service Switch config file. This file should be
# sorted with the most-used services at the beginning.
#
...
passwd:         files ldap
shadow:         files
group:          files ldap
...
[Warning] Warning

It's important to keep the specified order between files and ldap in order for the administration accounts specific to this machine be found without having to interrogate the LDAP directory.

It's not enough to indicate to NSS to interrogate the LDAP directory. We must also show how to do it. To do so, we must inform /etc/ldap.conf. In this file, we can specify a user (here, uid=nssldap,ou=System Accounts,dc=example,dc=com) which will connect onto the LDAP directory to read information: it's not critical, but it can be useful to track requests or to put in place complex ACL.

# vi /etc/ldap.conf
host 127.0.0.1
base dc=example,dc=com
# We uncomment the 2 following lines to track/ACLs
#binddn uid=nssldap,ou=System Accounts,dc=example,dc=com
#bindpw nssldap
nss_base_passwd         ou=People,dc=example,dc=com?one
nss_base_passwd         ou=Hosts,dc=example,dc=com?one
nss_base_shadow         ou=People,dc=example,dc=com?one
nss_base_group          ou=Group,dc=example,dc=com?one
[Warning] Warning

In order for Samba to work correctly, it's necessary to allow NSS to read the content of the OU hosts: Samba can then identify machines wishing to connect to the domain.

We must now verify that the mechanism works. To do so, you need users and groups in the LDAP directory. If it's not already the case, here's a ldif file that you can add to do test:

# vi /root/test.ldif
# Test Group
dn: cn=test,ou=Group,dc=example,dc=com
objectClass: top
objectClass: posixGroup
gidNumber: 200
cn: test
 
# Test User
dn: uid=test,ou=People,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: test
sn: test
givenName: test
uid: test
uidNumber: 1000
gidNumber: 200
homeDirectory: /home/test
loginShell: /bin/bash
gecos: System User
userPassword: test
# ldapadd -x -D "uid=LDAP Admin,ou=System Accounts,dc=example,dc=com"
        -w <passwd> -f test.ldif
adding new entry "cn=test,ou=Group,dc=example,dc=com"
 
adding new entry "uid=test,ou=People,dc=example,dc=com"

Let's verify that it works adequately with the following commands:

# getent passwd test
test:x:1000:200:System User:/home/test:/bin/bash
# getent group test
test:x:200:
# id test
uid=1000(test) gid=200(test) groups=200(test)
2.4.2.3.6. PAM and LDAP Behavior

It's possible to allow defined users in the LDAP directory to physically connect to the machine via machine via SSH or through a login screen. To do so, we must configure PAM and the associated services through the pam_ldap package.

Let's install pam_ldap.

# urpmi pam_ldap

We must then modify the /etc/pam.d/system-auth file, since all PAM point to it.

# vi /etc/pam.d/system-auth
#%PAM-1.0
 
auth        required      pam_env.so
auth        sufficient    pam_unix.so likeauth nullok
auth        sufficient    pam_ldap.so use_first_pass
auth        required      pam_deny.so
 
account     sufficient    pam_unix.so
account     sufficient    pam_ldap.so
account     required      pam_deny.so
 
password    required      pam_cracklib.so retry=3 minlen=2  dcredit=0
        ucredit=0
password    sufficient    pam_unix.so nullok use_authtok md5 shadow
password    sufficient    pam_ldap.so
password    required      pam_deny.so
 
session     required      pam_limits.so
session     required      pam_unix.so

To verify pam-ldap's behavior, you just need to try to connect with a user you created to make sure that the configuration is OK.

# su - test
su: WARNING: can't change directory to /home/test: No file or
        directory of this type
-bash-3.00$ id test
uid=1000(test) gid=200(test) groups=200(test)
[Note] Note

A warning is displayed because the user's directory (/home/test) doesn't exist.

To do the same test but with SSH, you must modify SSH's configuration and restart it.

# vi /etc/ssh/sshd_config
...
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication mechanism.
# Depending on your PAM configuration, this may bypass the setting of
# PasswordAuthentication, PermitEmptyPasswords, and
# "PermitRootLogin without-password". If you just want the PAM account
# and session checks to run without PAM authentication, then enable
# this but set ChallengeResponseAuthentication=no
UsePAM yes
...
# service sshd restart
Stopping sshd :                                            [  OK  ]
Launching sshd :                                           [  OK  ]
# ssh test@localhost
Warning: Permanently added 'localhost' (RSA) to the list of known hosts.
Password:
Could not chdir to home directory /home/test: No such file or directory
/usr/X11R6/bin/xauth:  error in locking authority file
        /home/test/.Xauthority
-bash-3.00$ id
uid=1000(test) gid=200(test) groups=200(test)
2.4.2.3.7. Using smbldap-tools

The smbldap-tools package provides a set of tools to manipulate Samba user accounts in the LDAP directory.

# ll /usr/sbin/smbldap-*
-rwxr-xr-x  1 root root  5987 mar 21 14:41 /usr/sbin/smbldap-groupadd*
-rwxr-xr-x  1 root root  2473 mar 21 14:41 /usr/sbin/smbldap-groupdel*
-rwxr-xr-x  1 root root  8881 mar 21 14:41 /usr/sbin/smbldap-groupmod*
-rwxr-xr-x  1 root root  2005 mar 21 14:41 /usr/sbin/smbldap-groupshow*
-rwxr-xr-x  1 root root 10294 mar 21 14:41 /usr/sbin/smbldap-passwd*
-rwxr-xr-x  1 root root 14995 mar 21 14:41 /usr/sbin/smbldap-populate*
-rwxr-xr-x  1 root root 20969 mar 21 14:41 /usr/sbin/smbldap-useradd*
-rwxr-xr-x  1 root root  3244 mar 21 14:41 /usr/sbin/smbldap-userdel*
-rwxr-xr-x  1 root root  7633 mar 21 14:41 /usr/sbin/smbldap-userinfo*
-rwxr-xr-x  1 root root 18992 mar 21 14:41 /usr/sbin/smbldap-usermod*
-rwxr-xr-x  1 root root  1958 mar 21 14:41 /usr/sbin/smbldap-usershow*

To use these tools, we must configure them so they respect our structure's organization. We must also recuperate the domain's SID.

Let's install smbdap-tools:

# urpmi smbldap-tools

To use these tools, we must indicate the SID, the domain name, the name of the different OUs of the LDAP directory, the LDAP directory(ies) to use, as well as the POSIX and Samba attributes, by default. We can use the following minimum file (or copy a similar file in the file provided by default):

# vi /etc/smbldap-tools/smbldap.conf
      SID="S-1-5-21-2433760973-660784831-1051970529"
      sambaDomain="example
 
slaveLDAP="127.0.0.1"
slavePort="389"
masterLDAP="127.0.0.1"
masterPort="389"
 
ldapTLS="0"
verify="require"
cafile="/etc/ssl/cacert.pem"
clientcert=""
clientkey=""
 
suffix="dc=example,dc=com"
usersdn="ou=People,${suffix}"
computersdn="ou=Hosts,${suffix}"
groupsdn="ou=Group,${suffix}"
idmapdn="ou=Idmap,${suffix}"
 
sambaUnixIdPooldn="sambaDomainName=${sambaDomain},${suffix}"
 
scope="sub"
 
hash_encrypt="SSHA"
crypt_salt_format="%s"
 
userLoginShell="/bin/false"
userHome="/home/%U"
userHomeDirectoryMode="700"
userGecos="smbldap System User"
defaultUserGid="513"
defaultComputerGid="515"
skeletonDir="/etc/skel"
defaultMaxPasswordAge="45"
 
userSmbHome="\\MES5\%U"
userProfile="\\MES5\profiles\%U"
userHomeDrive="U:"
userScript=""
 
mailDomain="example.com"
 
with_smbpasswd="0"
smbpasswd="/usr/bin/smbpasswd"
with_slappasswd="0"
slappasswd="/usr/sbin/slappasswd"

We must also instruct the /etc/smbldap-tools/smbldap_bind.conf file: it specifies the accounts which will allow you to connect to the LDAP directory to do different manipulations.

# cat /etc/smbldap-tools/smbldap_bind.conf
slaveDN="uid=Account Admin,ou=System Accounts,dc=example,dc=com"
slavePw="passwd"
masterDN="uid=Account Admin,ou=System Accounts,dc=example,dc=com"
masterPw="passwd"

Let's check the behavior of the tools:

# smbldap-usershow test
dn: uid=test,ou=People,dc=example,dc=com
objectClass: top,person,organizationalPerson,inetOrgPerson,
        posixAccount,shadowAccount
cn: test
sn: test
givenName: test
uid: test
uidNumber: 1000
gidNumber: 200
homeDirectory: /home/test
loginShell: /bin/bash
gecos: System User
userPassword: test
# smbldap-groupshow test
dn: cn=test,ou=Group,dc=example,dc=com
objectClass: top,posixGroup
gidNumber: 200
cn: test

Let's create the domain's users and groups. The smbldap-tools provide a tool (smbldap-populate) which creates the LDAP directory's base with the necessary users and groups so it works properly.

Let's add the necessary accounts:

# smbldap-populate -a Administrator -k 500 -m 512
Populating LDAP directory for domain example (S-1-5-21-2433760973-
        660784831-1051970529)
(using builtin directory structure)
 
entry dc=example,dc=com already exist.
entry ou=People,dc=example,dc=com already exist.
entry ou=Group,dc=example,dc=com already exist.
entry ou=Hosts,dc=example,dc=com already exist.
entry ou=Idmap,dc=example,dc=com already exist.
adding new entry: uid=Administrator,ou=People,dc=example,dc=com
adding new entry: uid=nobody,ou=People,dc=example,dc=com
adding new entry: cn=Domain Admins,ou=Group,dc=example,dc=com
adding new entry: cn=Domain Users,ou=Group,dc=example,dc=com
adding new entry: cn=Domain Guests,ou=Group,dc=example,dc=com
adding new entry: cn=Domain Computers,ou=Group,dc=example,dc=com
adding new entry: cn=Administrators,ou=Group,dc=example,dc=com
adding new entry: cn=Account Operators,ou=Group,dc=example,dc=com
adding new entry: cn=Print Operators,ou=Group,dc=example,dc=com
adding new entry: cn=Backup Operators,ou=Group,dc=example,dc=com
adding new entry: cn=Replicators,ou=Group,dc=example,dc=com
adding new entry: sambaDomainName=example,dc=example,dc=com
 
Please provide a password for the domain Administrator:
Changing UNIX and samba passwords for Administrator
New password:
Retype new password:
2.4.2.3.8. Configuring the Samba Server

The [global] section /etc/samba/smb.conf must contain the following information:

[global]
...
# we can define many source types
;passdb backend = ldapsam, smbpasswd, guest
;passdb backend = ldapsam:ldap://myfirstldap.edge-it.fr,
        ldapsam:ldap://mysecondldap.edge-it.fr, guest
# here we work with a local LDAP directory
passdb backend = ldapsam:ldap://127.0.0.1
 
# we connect to the directory with the following LDAP account
ldap admin dn = uid=Account Admin,ou=System Accounts,dc=example.dc=com
# in TLS or SSL
; ldap ssl = start_tls
ldap ssl = off
 
# the basedn and the OUs where is stored the information
ldap suffix = dc=example.com
ldap machine suffix = ou=hosts
ldap user suffix = ou=people
ldap group suffix = ou=group
 
# this option allows to not have to configure PAM
# it's only valid is Samba users don't have to access directly
#      to an account on the machine
ldapsam:trusted = yes
     

The verification tells us that everything's OK.

# testparm
Load smb config files from /etc/samba/smb.conf
Processing section "[homes]"
Processing section "[public]"
Loaded services file OK.
WARNING: passdb expand explicit = yes is deprecated
Server role: ROLE_STANDALONE
Press enter to see a dump of your service definitions
 
[global]
        workgroup = EXAMPLE
        server string = Samba Server %v
        map to guest = Bad User
        passdb backend = ldapsam:ldap://127.0.0.1
        log file = /var/log/samba/%m.log
        max log size = 50
        socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
        ldap admin dn = uid=Account Admin,ou=System Accounts,
                        dc=example,dc=com
        ldap group suffix = ou=group
        ldap machine suffix = ou=hosts
        ldap suffix = dc=example,dc=com
        ldap ssl = no
        ldap user suffix = ou=people
        ldapsam:trusted = yes
 
[homes]
        read only = No
        browseable = No
 
[public]
        comment = Public Directory
        path = /home/public
        read only = No
        guest ok = Yes

Let's test the connection in anonymous mode:

# smbclient -L localhost
Password:
Domain=[MES5] OS=[Unix] Server=[Samba 3.2.7]
 
        Sharename       Type      Comment
        ---------       ----      -------
        ADMIN$          IPC       IPC Service (Samba Server 3.2.7)
        IPC$            IPC       IPC Service (Samba Server 3.2.7)
        public          Disk      Public Directory
Domain=[MES5] OS=[Unix] Server=[Samba 3.2.7]
 
        Server               Comment
        ---------            -------
 
        Workgroup            Master
        ---------            -------
        example             MES5

We must then pass the password of the directory's connection account to Samba:

# smbpasswd -W
Setting stored password for "uid=Samba Admin,ou=System Accounts,
        dc=example,dc=com" in secrets.tdb
New SMB password:
Retype new SMB password:

We can already verify that the link to the LDAP directory is in place (by typing a bad password, and then the good one).

# smbclient -L localhost -U administrator
Password:
session setup failed: NT_STATUS_LOGON_FAILURE
# smbclient -L localhost -U administrator
Password:
Domain=[MES5] OS=[Unix] Server=[Samba 3.2.7]
 
        Sharename       Type      Comment
        ---------       ----      -------
        public          Disk      Public Directory
        IPC$            IPC       IPC Service (Samba Server 3.2.7)
        ADMIN$          IPC       IPC Service (Samba Server 3.2.7)
Domain=[MES5] OS=[Unix] Server=[Samba 3.2.7]
 
        Server               Comment
        ---------            -------
 
        Workgroup            Master
        ---------            -------
        example

Now, let's define our server as a PDC because up until now, we were using it in autonomous mode:

# vi /etc/samba/smb.conf
[global]
...
        # PDC
        security = user
        # OS level > 32 to be elected
        os level = 128
        # allows election launch
        # definition of a PDC
        local master = yes
        # domain master browser
        domain master = yes
        # for ce the electios to become PDC
        preferred master = yes
        # server authenticates
        domain logons = yes
...
#  testparm
Load smb config files from /etc/samba/smb.conf
Processing section "[homes]"
Processing section "[public]"
Loaded services file OK.
WARNING: passdb expand explicit = yes is deprecated
Server role: ROLE_DOMAIN_PDC
Press enter to see a dump of your service definitions
 
[global]
        workgroup = example
        server string = Samba Server %v
        map to guest = Bad User
        passdb backend = ldapsam:ldap://127.0.0.1
        log file = /var/log/samba/%m.log
        max log size = 50
        socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
        domain logons = Yes
        os level = 128
        preferred master = Yes
        domain master = Yes
        ldap admin dn = uid=Samba Admin,ou=System Accounts,dc=edge-it,
                        dc=subnet
        ldap group suffix = ou=group
        ldap machine suffix = ou=hosts
        ldap suffix = dc=edge-it,dc=subnet
        ldap ssl = no
        ldap user suffix = ou=people
        ldapsam:trusted = yes
 
[homes]
        read only = No
        browseable = No
 
[public]
        comment = Public Directory
        path = /home/public
        read only = No
        guest ok = Yes
2.4.2.3.9. Managing Samba File Shares

Until now, we have looked at the general configuration of a Samba server and the set up of its role on the network. Let's not review the types of resource sharing that you can set up.

A share's syntax is relatively simple and must be written after the server's general parameters:

[<share_name>]
	comment = "<your comment>"
	path = <path_resource>
	browseable = <yes|no>
	writable = <yes|no>	

Just as for the general section, a share is introduced by its name being between square brackets. Here are the most common parameters:

  • comment: enter a significant comment. It appears during the resource path and enables you to identify its content quickly;

  • path: specifies the local path to the shared resource;

  • browseable: determines if the resource must appear during the resource path;

  • writable: indicates the write or read rights on the shared resource.

logon-type share

This specific share concerns netlogon scripts or connection scripts of domain users. It allows us to share netlogon scripts generated on the fly through the root preexec instruction.

[netlogon] comment = Network Logon Service
	 path = /data/samba/netlogon guest ok = yes writable = no
	 write list = @administrateurs browseable = no root preexec =
	 /data/samba/netlogon/logon_script '%m' '%U' '%a' '%g'
	 '%L'
	
profile-type share

In the situation where you use mobile profiles, these will be part of a specific Samba share which uses the keyword profiles.

[profiles] path = /data/samba/profiles
       browseable = no guest ok = yes writable = yes
homes-type share

You can make your user's home directories accessible (homes). For this, we use the reserved homes keyword. %u is a predefined variable containing the user's username.

[homes] comment = Home
	 Directories browseable = no writable = yes path =
	 /data/samba/prives/%u
group-type share

This share type enables you to define accessible resources for one or many given groups. It avoids having to define a share per group. The principle is simple: it lies on the assignation of rights in the data tree structure. The hide unreadable parameter allows to us hide to users directories for which they have no right. For example:

# ll /data/samba/groups/ total
       24 drwxrws--- 111 root commercial 4096 avr 28 17:45 clients/
       drwxrws--- 23 root utilisateurs 4096 sep 9 2008 commercial/
       drwxrws--- 6 root support 104 jui 19 14:24 support/

The share can then be written this way::

[groups] comment =
	 Storage Groups path = /data/samba/groups writable = yes
	 browseable = yes hide unreadable = yes
	
2.4.2.3.10. Managing Samba Print Shares

We saw file sharing, let's now address printer sharing. Samba allows you to share access and drivers, so you don't have to install those drivers on each client machine.

The [printers] specific share allows us to share all available printers through CUPS. The [print$] specific printing permits to share drivers.

# sharing declared printers
	[printers]
	comment = All Printers
	path = /var/spool/samba
	browseable = no
	guest ok = yes
	writable = no
	printable = yes
	create mode = 0700
	
	# share printing driver distribution
	[print$]
	path = /var/lib/samba/printers
	browseable = yes
	read only = yes
	write list = @administrateurs
      guest ok = yes

As a prerequisite you must have a functional CUPS server. It must also be declared in the [global] section:

[global]
	...
	# we use printers defined in CUPS
	# we load the list
	printcap name = cups
	load printers = yes
	
	# adding authorized printer for the admin group
	printer admin = @administrateurs

If the CUPS server is not on the same machine, you can add the cups server instruction followed by the server's address.

Once your shares are defined as well as the CUPS server to use, you need to make Samba take into account the defined printers Samba. Use the cupsaddsmb command:

cupsaddsmb -a -u
     <administrator_name>
[Warning] Warning

In the case where you want to add printers to your CUPS server, it will be necessary to relaunch the Samba server before executing the cupsaddsmb command.

2.4.2.4. Troubleshooting

Solving a Samba problem is not always an easy task. Here's a checklist to do when crashes or malfunctions occur:

  • Check the available disk space on the filesystems hosting the shares.

  • Check the available disk space for log files (watch out, if the level is high, also check the space left in /tmp). A high level can also affect the server's performance considerably.

  • Check the eventual inactivity of the Samba process to better set the timeout variable.

  • Check the memory space used by the Samba process.

Samba's official documentation offers a complete guide allowing you to identify exhaustively problem sources and tools to set up to diagnose those problems: see the Troubleshooting section.

2.4.2.5. Extended ACLs

Microsoft Windows® uses extended ACLs (Access Control Lists) and attributes in regards with “standard triplé” accessible on a GNU/Linux system (Read/Write/Execute for a user, his group, and everyone). It's possible to simulate part of those information on GNU/Linux by using a filesystem which supports such a format, and by adding the packages which facilitate ACL management.

You must then install the following packages:

  • acl: this package contains the getfacl and setfacl commands that allow you to see, add, modify and suppress extended ACLs on a file or directory.

  • attr: this package contains the getfattr and setfattr commands which enable you to see, add, modify and delete extended attributes on a file or directory.

Here are the filesystems which support those ACLs:

  • XFS supports those two extended information sets in native mode, like reiserFS and jFS.

  • ext2/3 supports these information once the filesystem is patched. It's also necessary to activate the acl attribute during the filesystem's mount.

Please read POSIX Access Control Lists on Linux for more information.

[Tip] Tip

Make sure you use XFS-512 instead if XFS-256 (the default on many GNU/Linux systems), because this way, extended information are stored in the concerned file's or directory's inode, instead of in the filesystem's metadata. Accessing the information is faster that way.