FreeBSD special-purpose users
April 14, 2009

This page details how to make special-purpose user accounts for use with FreeBSD. The accounts have a specific function, which is defined in their login script, such as "run backups" or "reboot the server".

These accounts are intended to be used by office administrators, rather than the system administrator. In an SME environment, it is not uncommon for the "Big Boss" to decide to reboot the server, in order to resolve some problem with an application. We lofty sysadmins might scoff at the crudeness of the Boss's approach - it usually works, however, as we ourselves well know. This is something that the Big Boss has picked up over 20 years of running an office IT system, and nothing is going to stop him rebooting his server anytime he wants. I have indeed discovered my customer restarting their server using the power-off switch.

Our job as sysadmin is to accomodate these user behaviours, whilst preserving system integrity. Certainly, power-cycling a live server to fix a glitch in some application software is overkill, and might corrupt databases, and is certainly not good if the server is doing other things as well as hosting the errant application. However the Big Boss does care about this sort of thing, once it is explained, and so there is hope. In fact there's a possibility we can convince the Big Boss to use our special-purpose user accounts instead.

These accounts achieve what the Big Boss wants to achieve, in a graceful, integrity-retaining manner. So far, a need for three special-purpose users has been identified, although there are almost certainly more:

The key aspect of these accounts is that their login script runs all the commands they need to execute their function, and then logs the user out. The Big Boss never sees a command prompt, and never types a single command. All the Big Boss does is enter the username and password, and the script does the rest.

Benefits:

The technique below uses sudo, as the tasks required (reboot, restart samba etc) need root-level privileges. If the commands you plan to use don't need root-level privileges, sudo may not be required. How to install it:

  1. cd /usr/ports/security/sudo
  2. make install clean
  3. don't select anything - just hit OK

How to make a special-purpose user:

  1. define the account password, and store it in a secure location
  2. login to the server as root
  3. create the user:

    1. adduser
    2. set the username to the name of the function being executed, eg. "reboot"
    3. accept all defaults (don't assign the user to the wheel group, or anything like that, leave them in their own group)
    4. use password-based authentication, and enter the password defined in step 1

  4. allocate permissions to the user (skip if not using sudo):

    1. visudo (note: if this doesn't run, try /usr/local/sbin/visudo)
    2. add a line to the end of the file, specifying the username, hostname, and command, as follows:
      username hostname=NOPASSWD: command
      

      Where username is the user who will run the command, hostname is the name of the server, and command is the command to run. An example, this gives the user "reboot" permission to run the shutdown command on the machine "myserver":

      reboot myserver=NOPASSWD: /sbin/shutdown -r now
      

      Don't get the hostname wrong. If the hostname is wrong, when the user tries to run sudo, they will see a message, "username is not permitted to run sudo on hostname", and their program will not start. The "hostname" in the error message is what the hostname SHOULD be set to in the sudo configuration file. Some documentation suggests that "localhost" can be used here, this was not the case on the test system used to make this article, however.

      Another example, this time we have a user called "zapsamba" on a server called "fileserver1", and we want to let zapsamba restart samba, so we put this in the sudo configuration file:

      zapsamba fileserver1=NOPASSWD: /usr/local/etc/rc.d/samba restart
      

      Note the use of the NOPASSWD: tag. Since the command will be executed on login, which already requires a password to be entered, in this instance, there is no point asking for the password again, as would occur if the NOPASSWD tag was not supplied.

    3. save and exit

  5. edit the user's login script:

    1. vi /home/username/.profile (where username is the username just created)
    2. scroll to the last line - comment out the fortune cookie call, if it exists
    3. insert a new line and enter the command(s) to execute - this can simply be a single command, a list of shell commands, or a call to a script.

      If the user does not have permissions to the resources used, the sudo command can be used. However, if sudo is used, the commands entered must match the commands permitted in the sudo configuration file. In the above example we're making a reboot user, which does need sudo, and we have given our reboot user permission to run the shutdown command in the sudo configuration file, so we can enter this in our login script:

      sudo /sbin/shutdown -r now
      

      If we were editing zapsamba's login script, we'd enter this instead:

      sudo /usr/local/etc/rc.d/samba restart
      sudo /usr/sbin/service samba_server restart      # for FreeBSD 10+
      
    4. make a new line BELOW the line just added, and on it, insert the logout command:
      exit
      
    5. save and exit the editor

  6. login as the new user and test

Notes: