# Ressource Manager

## 1. Introduction

This is a resource manager that will provide unprivileged users access to device files. This is a common problem for people writing hardware drivers etc that should be used by "ordinary" users, such as usb cameras, scanners, CD writers, audio devices, etc etc.

There are several aproaches to this issue

- make the devices accessible to everyone. This is probably the simplest approach. The down side is these devices will always be accessible, even if another user is sitting at the console. Another problem with this approach is that it doesn't deal with hotplug devices (usb, pcmcia).

- make the devices accessible to a group. This is just a variation of the above. Adding and removing users dynamically to and from groups upon login is useless as once a user is member of a group he can create a setuid binary to regain group membership anytime.

- make applications that open devices setuid root. This is a very common approach for example for CD-burning but it's unsuitable for e.g. sound devices. The biggest problem are the security problems it causes very frequently. This approach should be considered deprecated.

- use a pam module and/or the xdm script framework (TakeConsole/GiveConsole) to change the ownership of various devices to the user logging in, and change it back to root when the user logs out. This solves the first problem above, but doesn't deal with hotplug devices either. Additionally only one user can be given ownership to the devices at a time. That means additional sessions for different users as supported by modern display managers are of limited use.

Another solution to this is to create a daemon that will open the devices on behalf of the user, and pass the file descriptor to the user's application via an AF_LOCAL socket. This is what resmgr does.

resmgr solves all problems listed above. It does create a new problem, however. You need to patch your software to call resmgr functions rather than to open devices directly. That disadvantage can be mitigated if the file system supports ACLs though.

## 2. Basic Concept

When started, the resmgr daemon reads it's access control and static device information from its configuration files and creates the server socket.

When a user logs in, a pam module (pam_resmgr) will tell resmgr to create a session for that user. Resmgr then grants access to certain groups of devices (called resource classes) according to the rules defined in the config files. Optionally, the pam module can tell resmgr to directly grant the user access to a specific ressource class. The user will then be allowed to access all devices within that class.

When hotplug devices are attached, the hotplug subsystem can tell the resource manager to dynamically add devices to a specific resource class. Likewise, when a device is detached the hotplug subsystem can call the resource manager and ask it to remove the device from the ressource class.

To access a device from within an application the application has to call `rsm_open_device` instead of `open`. `rsm_open_device` then connects to the `resmgr` socket asking `resmgrd` to pass a file descriptor for the device.

## 3. Components

### 3.1. PAM Module

#### Description

pam_resgmr is a PAM session module that can be used to register a user session with the resource manager at login, and remove it when the user logs out. It can also be configured to grant the user access to additional resources classes.

#### Synopsis

`pam_resmgr.so` [ `OPTIONS` ]

#### Options

`grant=`class``

  This option instructs pam_resmgr to tell the resource manager to grant the user access to resource class `class` in addition to any classes defined by the default access control lists given in `/etc/resmgr.conf`

`fake_ttyname`

  use a generated fake tty name when registering with resmgr. This is useful for ssh with privilege separation as it always sets the pam tty to the same string for all users.

`fake_ttyname_if_needed`

  as above but only use the fake name if the pam tty doesn't start with a slash or colon. This is useful if ssh and other services share the same pam config file.

#### Examples

Add the following line to `/etc/pam.d/sshd`:

    session optional pam_resmgr.so fake_ttyname

For XDM you might want to use

    session optional pam_resmgr.so grant=desktop

or just

    session optional pam_resmgr.so

### 3.2. Configuration File

#### Description

The file `/etc/resmgr.conf` defines the resource classes for the resource manager resmgrd. The minimal configuration is to define a single resource class and manage everything else dynamically. You may also define devices and access control lists in this configuration file though.

Additionally all files with suffix `.conf` in the directory `/etc/resmgr.conf.d/` are read in alphabetical order. This mechanism is intended for packages that want to define additional ressource classes or access control rules. The recommended name for files placed in that directory is ``NUMBER`-`PACKAGENAME`.conf` where `NUMBER` is a number between zero and 99.

Everything starting from a hash mark unto the end of the line is a com- ment, and is ignored.

The configuration file can contain the following commands:

class ``NAME``

  Defines a resource class named `NAME`

  Class names must be unique. Class names may only consist of upper or lower ASCII characters, underscores, dashes, colons and periods.

class ``NAME`` `includes` ``CHILDREN...``

  Defines that granting access to class `NAME` also grants access to `CHILDREN` classes.

add ``device`` ``class`` [ ``flags`` ]

  add the specified device to the resource class class. Optionally, one or more flags can be specified.

  The read-only flag marks the device read-only. Attempts to open the device for writing will be refused.

  The scsi flag allows clients to ask for the corresponding raw SCSI device instead of the device itself. This is useful for applications such as CD writers or scanners that need to find and open the raw SCSI device corresponding to e.g. /dev/cdrom.

  The nofacl flag prevents resmgr from installing file system ACLs for the device. Note that ACLs are only installed for devices of the file family.

exclude ``device`` ``class`` [ ``flags`` ]

  Explicitely deny access to `device`. Exclude statements are useful for example before a statement that adds `usb:any`

allow ``class`` ``acl...``

  Grants all users matched by the ACL statement access to resource class class. Any subsequent access control statements for this class will be ignored.

deny ``class`` ``acl...``

  Denies all users matched by the ACL statement access to resource class class. Any subsequent access control statements for this class will be ignored.

#### ACL Format

ACLs attached to a resource class is made up of one or more match clauses of the format name=value, where name can be one of user, group, tty, rhost or service. value can be a literal value or a glob expression, such as meissner (a user name), /dev/tty[0-9]*, or :* (for matching all logins on a local X display).

These match clauses can be combined using the standard boolean opera- tors &&, ||, and !. Note that !name=value is equivalent to name!=value.

Sub-expressions can be grouped by putting them in brackets.

Usually, an ACL will contain just a single user or group name, but you can specify several, forming an AND clause. When a name is preceded by an exclamation mark, the match result is negated.

For example, the following statements for the resource class desktop will deny access to users uucp and news, but grant access to everyone in group wheel, and everyone else as long as they're logged in at the console or a local X11 session:

    deny  desktop user=uucp || user=news
    allow desktop group=wheel
    allow desktop tty=/dev/tty[0-9]* || tty=:0

#### Device Families

resmgr supports special handling of some type of devices. For this purpose device families were introduced. When adding a device to resmgr the family name has to be prepended to the device path, separated by a colon.

The family can be omitted for device name that start with a slash. Resmgr will treat them as file unless they are opened as another family and file flags allow that. For example you may use resmgr add /dev/sr0 scsi to add a device and later open either `file:/dev/sr0` or `scsi:/dev/sr0`

file

  regular files, character and block devices. Normally device nodes in `/dev`

  resmgr accepts the following syntax:

      file:PATH

usb

  usb devices are normally not accessed via device files but via the `/proc/bus/usb` filesystem.

  resmgr accepts any of the following syntax:

      usb:/proc/bus/usb/BUSNR/DEVNR
      usb:key1=value1,key2=value2,...
      usb:BUSNR,DEVNR
      usb:BUSNR,DEVNR:/proc/bus/usb/BUSNR/DEVNR

  `key` can be any of `bus`, `dev`, `class`, `subclass`, `vendor` or `product`

scsi

  for SCSI devices applications often want to open the SCSI-generic device instead of the disk device, e.g. `sg1` instead of `sr0`. Since the numbering of both kind of devices is not related the scsi family was introduced to automatically determine with devices belong to together. So if you want to allow CD burning on your recorder with the device `/dev/sr0` you would tell resmgr to open `scsi:/dev/sr0`

  resmgr accepts any of the following syntax:

      scsi:/dev/NAME
      scsi:BUS.TARGET.LUN
      scsi:TARGET.LUN
      scsi:BUS.TARGET.LUN:/dev/NAME
      scsi:TARGET.LUN:/dev/NAME

paride

  PARIDE devices work similar to SCSI ones.

  resmgr accepts any of the following syntax:

      paride:/dev/NAME
      paride:MINOR
      paride:MINOR:/dev/NAME

socket

  the socket family deals with `AF_LOCAL` sockets.

  resmgr accepts any of the following syntax:

      socket:PATH;dgram
      socket:PATH;stream

### 3.3. Command Line Client Program

#### Description

The resmgr command is a command line client for the resource manager daemon resmgrd(8). It passes the specified command to the daemon, and prints the response.

#### Synopsis

`resmgr` [-s `socket`] [-u `user`] [-t] [`command`...]

#### Options

resmgr understands the following command line options:

-t

  By default, resmgr will not include the server's numeric response codes in its output. By using the -t option, you can force resmgr to display the server's response as-is.

-u `user`

  This option can be used by the root user when he wishes to con- tact the resource manager as user. This option is mostly for debugging and testing purposes.

-s `socket`

  specifies the name of the socket on which the resource manager is listening. This option is mostly for debugging and testing purposes.

#### Commands

Currently, the resource manager protocol supports the following commands, all of which can be performed from the command line using resmgr:

help

  Display the list of available commands.

list [``family``]

  Display the list of devices available to the user.

  The optional family argument can be used to specify a resource family. If specified, the listing will include only names from that specific family. In addition, device names will be mapped to that particular name space.

  For instance, if the resource class includes the device /dev/cdrom, listing the scsi family would return a corresponding SCSI device specifier such as scsi:0,0,1. (Of course, this assumes that /dev/cdrom uses the SCSI CD driver, and that the user has permission to open the corresponding raw SCSI device).

open [``flags``] ``device``

  Open the specified device and receive the file descriptor through the socket connection. Optionally, one or more flags can be passed.

  The flag -ro tells the server to open the device read-only. Oth- erwise, the device is opened read-write.

  If the device is flagged read-only, but the client tries to open it read-write, access is denied.

  The device parameter is usually just the path name of the device that should be opened. However, you can prefix the name with a resource family to request a different interpretation of the device name, such as scsi:/dev/cdrom. This will open the raw SCSI device associated with /dev/cdrom. The device must have the scsi flag set, otherwise the request will be refused. This is useful for scanners and CD writers.

  For the convenience of applications that want to open a device based on its SCSI ID, the scsi resource family supports an alternative device notation, which is scsi:[bus,]target,lun.

lock ``device``

  Creates a lock file for the device, and put the PID of the client process into the file. The owner of the PID file is set to the uid of the client process, allowing the application to update the contents of the lock file if it puts itself into the background, for example.

  If a conflicting lock exists, access is denied. If a stale lock file is found, the server returns error code 202 (stale lock file). This indicates that the client should perform an unlock call for this device, which will remove the stale lock.

unlock ``device``

  Removes a lock file for the device. If a lock file exists which is neither owned by the uid of the calling application, and which is not a stale lockfile, access is denied. Otherwise the lock file is removed.

login ``user`` ``tty`` [`rhost=`hostname``] [`service=`servicename``]

  Indicates to the resource manager that user logged in on termi- nal tty. This will cause the resource manager to create a ses- sion record for the, and grant the user access to all resource classes that ACLs he matches.

  This command is restricted to the administrator. Usually, the login command is executed by the pam_resmgr module when the user logs in, but you can also use it from the X11 GiveConsole script, for instance.

  The syntax of the tty parameter is mostly irrelevant, except that it must be unique. When calling login with a tty name for which a session already exists, the previous session is deleted first. This is intended to increase robustness, when for some reason the logout command was not issued.

logout ``tty``

  This will cause the resource manager to delete any session record for the indicated tty, and decrement the reference count on the user record associated with that session. If this was the last session for the user, all access rights for the user are revoked.

  This command is restricted to the administrator. Usually, the logout command is executed by the pam_resmgr module when the user logs in, but you can also use it from the X11 TakeConsole script, for instance.

logout

  This command lists all currently active sessions. It is restricted to the administrator.

grant ``user`` ``class``

  This command grants the indicated user access to the resource class class.

  This command is restricted to the administrator. Usually, the grant command is executed by the pam_resmgr module when the user logs in, but you can also use it from the X11 GiveConsole script, for instance.

revoke ``user`` [``class``]

  This command revokes a user's access rights to the given class. If no class argument is given, access to all classes is revoked.

  this command is restricted to the administrator. It is not very useful, but was added for symmetry with grant.

add ``device`` ``class`` [ ``flags`` ]

  add the specified device to the resource class class. Optionally, one or more flags can be specified.

  The read-only flag marks the device read-only. Attempts to open the device for writing will be refused.

  The scsi flag allows clients to ask for the corresponding raw SCSI device instead of the device itself. This is useful for applications such as CD writers or scanners that need to find and open the raw SCSI device corresponding to e.g. /dev/cdrom.

  The nofacl flag prevents resmgr from installing file system ACLs for the device. Note that ACLs are only installed for devices of the file family.

  This command is restricted to the administrator. It can be used by a hotplugging daemon to make a device available to local users when attached.

remove ``device`` [``class``]

  This command removes the specified device from resource class class. If no class argument is given, the device is removed from all classes.

  This command is restricted to the administrator. It can be used by a hotplugging daemon to disable access to a device when it becomes unavailable.

### 3.4. Ressource Manager Daemon

#### Description

resmgrd is a resource manager that allows applications to access and lock device files. It supports hot-plugging, i.e. devices can be added to a resource class as they become available, and can be removed when unplugged.

Devices are grouped in so-called resource classes. Each device in a resource class has an associated flag that defines whether applications are permitted to open it for reading and writing, or for reading only. The devices in a resource class can be defined in the static configura- tion file, but they can also be added and removed dynamically by a hot- plugging daemon.

For most purposes, having a single resource class will be enough, but you can have several if you want.

Access control to device files happens at the resource class level as well. Users can be granted the right to access devices from a certain resource class. Again, access control can be defined statically in the configuration file, or dynamically.

Applications communicate with resmgrd through an AF_LOCAL socket. When the client wants to access a device file, it asks the resource manager to do so. If permitted by the access control lists, the resource man- ager will open the device file and pass the open file descriptor back to the client via the AF_LOCAL socket.

Additionally, applications can use the resource manager to lock and unlock a device file. This happens via traditional UUCP-style lock files in /var/lock. The main purpose of this is to allow applications using serial devices to continue using UUCP-style locks.

All other operations, such as adding devices to a resource class, or granting a user access to a class, are restricted to the administrator.

#### Support for file ACLs

Since patching every application for resmgr support is not possible, especially not for binary only applications, resmgr also supports file system ACLs in addition to the fd-over-socket feature. When a user logs in and is granted access to a certain class, resmgr walks all devices in that class and installs an ACL entry on it in the filesystem. When the user logs out, the ACL is removed again. If multiple users log in, multiple ACLs entries are installed.

As a fallback if the underlying filesystem of a device does not support ACLs, resmgr changes the owner of the file to the first user that is granted access to it. This is bascially what pam_logindevperm and pam_console do.

#### Synopsis

`resmgrd` [-s `socket`] [-f `configfile`] [-k] [-d]

#### Options

resmgrd understands the following command line options:

-k

  Kill a running resmgr daemon.

-d

  Don't fork to become a daemon, enable debug output.

-f `configfile`

  use a different configuration file than `/etc/resmgr.conf`. This option is mostly for debugging and testing purposes.

-s `socket`

  specifies the name of the socket on which the resource manager daemon should listen. This option is mostly for debugging and testing purposes.

## 4. Location of source code

The resmgr source repository ist hosted at Novell Forge

## 5. Author

resmgr was written by Olaf Kirch and is currently maintained by Ludwig Nussel and Marcus Meissner