Resource Manager

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Table of Contents

1. Introduction
2. Features
3. Architecture overview
4. Components

    4.1. PAM Module
    4.2. Configuration File
    4.3. Command Line Client Program
    4.4. Resource Manager Daemon
    4.5. hal-resmgr

5. Configuration Examples
6. Resource manager features overview per distro

    6.1. pre 10.0
    6.2. SUSE Linux 10.0
    6.3. SUSE Linux 10.1 / SLE 10
    6.4. openSUSE 10.2

7. FAQ
8. Location of source code
9. Author

1. Introduction

Important

The name 'Resource Manager' is historical and misleading. resmgr itself
actually does not manage any resources anymore, it's current purpose is to
track user logins. Any other jobs are carried out by external helper programs.

Normally access to device files of audio devices, CD writers, USB cameras etc.
is restricted to root by default. That means normal user's can't access them
which is not what users expect from a desktop installation.

There are several aproaches to grant normal users access nevertheless:

  ● make the devices accessible to everyone. This is probably the simplest
    approach. The downside is these devices will always be accessible, even if
    another user is sitting at the console.

  ● 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 setgid
    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 problem, but
    doesn't deal with hotplug devices that can appear and vanish any time.
    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.

  ● use a daemon that opens the devices on demand on behalf of the user and
    have it pass the file descriptor to the user's application via an AF_LOCAL
    socket. This is what resmgr did in the past. This method works without
    actually having to touch the device nodes on disk, can cope with hotplugged
    devices and supports multiple concurrent users. The disadvantage is that
    one has to patch the software to call resmgr functions instead of opening
    the devices directly. That's not always possible, e.g. most commercial
    games are binary only and do need to access sound devices.

  ● combine the previous two methods but use file system ACLs instead of chown
    or fd passing via socket. Using ACLs it's possible to grant access to
    multiple users individually without changing the owner of the device. For
    this purpose the filesystem that holds /dev must support ACLs of course.

resmgr and it's compagnon hal-resmgr implement the latter method. resmgrd
tracks user logins and executes programs when users log in and out. One of
those programs is hal-resmgr which fetches device information from hal and
installs ACLs in the file system according to the login information from
resmgr.

2. Features

  ● Optional fine grained access control. Devices are grouped in to classes
    like 'sound' or 'cdrom'. Instead of granting users access to the 'desktop'
    class which includes most other classes it's also possible to only grant
    access to selected classes based on properties like login tty, pam service
    or host name.

  ● Multiple user support. resmgr can manage sessions for multiple concurrent
    users. For example it's possible to log in with a different user on a
    second X server via kdm/gdm and still get access to sound devices.

  ● PAM integration. For tracking logins a pam module is provided. There is no
    need to patch any scripts or applications, just edit your pam config in
    order to enable resmgr support.

  ● Slim. resmgr itself is pure C without extra dependencies. hal-resmgr which
    is linked against dbus and hal libs is built separately and talks to the
    resmgr daemon via socket.

3. Architecture overview

Figure 1. resmgr Overview

resmgr Overview


(1)  When started, the resmgr daemon reads the list of available device classes
     and access control rules from it's configuration files.

(2)  When a user logs in and the login program (e.g. gdm, kdm) opens a PAM
     session the pam_resmgr PAM module tells the resmgr daemon the user name,
     tty, pam service, whether it's a remote login etc. Access control rules
     from the config file determine which classes a user gets. The daemon then
     executes programs associated with the login classes.

(3)  HAL knows the devices installed in the system. The HAL fdi file determines
     the login classes a device should be assigned to. It may for example match
     for certain USB vendor and device IDs and class a device as scanner.

(4)  hal-resmgr is a program which gets executed when a user logs in. It looks
     up device information in hal and asks resmgr which users should get access
     to which classes. It then grants access to devices according to that
     information by installing file system ACLs.

(5)  In the future PolicyKit might be used to look up class information. resmgr
     would feed login information into PolicyKit then.

4. Components

4.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 login 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 login 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

4.2. Configuration File

Description

The file /etc/resmgr.conf defines the login 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 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 login 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.

    class desktop
    class floppy
    class cdrom
    class desktop includes floppy
    class desktop includes cdrom

ongrant CLASS run COMMAND...

    Defines that when a user is granted access to class CLASS the command
    COMMAND is run. The environment variables RES_USER and RES_CLASS are set to
    the name of the involved user resp. class.

    ongrant desktop run /bin/ls

onrevoke CLASS run COMMAND...

    Works the same as ongrant but gets executed when access to a class is
    revoked

allow class acl...

    Grants all users matched by the ACL statement access to login 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 login class class.
    Any subsequent access control statements for this class will be ignored.

ACL Format

ACLs attached to a login 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 login 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

4.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.

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

    Indicates to the resource manager that user logged in on terminal tty. This
    will cause the resource manager to create a session 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.

    Example:

    # resmgr login joesix :0
    success

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.

    Example:

    # resmgr grant joesix modem
    success

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.

dump [type]

    dumps resmgrd's internal state. The output can be piped into resmgr again
    to restore the state. For example after restart of the daemon.

    Without aguments dump dumps the entire internal state. By passing any of
    classes, sessions, grants, devices, dynamic-devices or static-devices as
    type argument the output can be stricted to the specified kind of data.

    this command is restricted to the administrator.

4.4. Resource Manager Daemon

Description

resmgrd is a daemon that tracks when users log in and out. When a user logs in,
a session is opened in resmgr. When the user logs out the session is closed.

the resmgr configuration defines login classes. Users can be granted access to
such login classes either manually or by defining rules.

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.5. hal-resmgr

Introduction

hal-resmgr is an optional separate program that can be used as callout from
hald and resmgrd to install ACLs on device files. It's linked against dbus and
hal to be able to communicate with hald.

Interface to HAL

Devices that should be processed by hal-resmgr need to be tagged. The fdi file
resmgr.fdi (installed as /etc/hal/fdi/policy/90osvendor/80-resmgr.fdi) does
that by merging resmgr specific properties into hal.

The following properties are supported:

resmgr.class (string)

    the resmgr class the device should added to

resmgr.device (string)

    the path to the device node that should be used. If it's empty the
    properties block.device and linux.device_file are checked in that order
    instead.

To make hald actually run hal-resmgr one needs to add hal-resmgr to the strlist
properties info.callouts.add and info.callouts.remove. /etc/hal/fdi/policy/
90osvendor/80-resmgr.fdi does that automatically for all devices that have
resmgr.class set.

5. Configuration Examples

To tell hal-resmgr that a device with vendor id 0x1234 and product id 0x5678
should be treated as class scanner, create a file /etc/hal/fdi/policy/20user/
50-scanner.fdi (you may need to create the directory /etc/hal/fdi/policy/20user
first) with the following content:

<?xml version="1.0" encoding="ISO-8859-1"?>
<deviceinfo version="0.2">
  <device>
    <match key="info.bus" string="usb_device">
      <match key="usb_device.vendor_id" int="0x0ccd">
        <match key="usb_device.product_id" int="0x0038">
          <merge key="resmgr.class" type="string">scanner</merge>
        </match>
      </match>
    </match>
  </device>
</deviceinfo>

Another example for a fictional device that is known to hal:

# cat <<EOF > /etc/hal/fdi/policy/20user/50-missilelauncher.fdi
<?xml version="1.0" encoding="ISO-8859-1"?>
<deviceinfo version="0.2">
  <device>
    <match key="linux.device_file" string="/dev/missilelauncher">
      <merge key="resmgr.class" type="string">wmd</merge>
    </match>
  </device>
</deviceinfo>
EOF
# cat <<EOF > /etc/resmgr.conf.d/50-wmd.conf
## define a new class 'wmd'
class wmd

## grant access to class 'wmd' when access to 'desktop' is granted
## (ie everyone on a local console)
class desktop includes wmd

## maybe you want to restrict access to 'wmd' to members of a group instead
#allow wmd group=generals
EOF
# rcresmgr restart
# rchal restart


6. Resource manager features overview per distro

6.1. pre 10.0

resmgrd reads a static device list from /etc/resmgr.conf. Some rogue hotplug
scripts also add devices at run time. Access to devices only possible via
libresmgr. Mostly affects cdrecord. Programs linked against system libusb
transparently use libresmgr. Device ownership is changed independently from
resmgr by pam_devperm on login.

6.2. SUSE Linux 10.0

resmgrd no longer uses a static list of devices. Instead the helper program
hal-resmgr is called by hald to register devices in resmgrd. resmgrd now also
installs ACLs for devices in the filesystem. A fallback to chown is used for
the first user if filesystem ACLs are not available. dbus uses the files in /
var/run/resmgr/classes/desktop/ for access control (at_console).

6.3. SUSE Linux 10.1 / SLE 10

usb devices are now regular devices in /dev rather than /proc/bus/usb.
Therefore libusb no longer utilizes resmgr and relies on file system
permissions for /dev/bus/usb/*

6.4. openSUSE 10.2

resmgrd no longer knows about devices at all, it only tracks user logins and
manages the classes associated with logins. The helper program hal-resmgr now
sets ACLs on devices and gets called by both resmgrd and hald. The now obsolete
libresmgr functions for handling devices were replaced by stubs that always
fail. The fallback to chown is no longer possible with hal-resmgr, therefore
ACL support on /dev is mandatory. pam_devperm is no longer used, therefore a
working resmgr and hal are mandatory for device access. Resmgr also notifies
PolicyKit about user logins which then grants access to the 'desktop-console'
privilege.

7. FAQ

7.1. How do I find out which devices are handled by (hal-)resmgr?
7.2. How can I find out whether resmgr installed proper ACLs in the file
    system?
7.3. How do I find out whether resmgr knows that I am logged in?
7.4. How do I list the classes I have access to?
7.5. How do I grant users permanent access to serial ports like ttyS0, ttyACM0?
7.6. Should I add users to the group uucp?

7.1. How do I find out which devices are handled by (hal-)resmgr?

     openSUSE 10.2, 10.3:

         Use hal-resmgr with the --list option to list devices the current user
         has access to. The option --list-all lists all devices managed by
         hal-resmgr.

         $ /usr/sbin/hal-resmgr --list-all
         UDI /org/freedesktop/Hal/devices/pci_1106_3059_oss_pcm_0_0
         Device /dev/audio
         Class sound
         ...

     10.1/SLE10 and older

         Use resmgr with the list option to list devices the current user has
         access to. The option dump can be used to inpect resmgr's internal
         state which also contains the list of all devices known to resmgr.
         dump can only be used as root

         $ /sbin/resmgr list
         rw-- /dev/snd/pcmC0D4p
         rw-- /dev/dsp
         ...


7.2. How can I find out whether resmgr installed proper ACLs in the file
     system?

     You can check the ACLs on a file with the command getfacl. The following
     screen shows that user "fritz" has read and write access to /dev/dsp:

     $ getfacl /dev/dsp
     getfacl: Removing leading '/' from absolute path names
     # file: dev/dsp
     # owner: root
     # group: audio
     user::rw-
     user:fritz:rw-
     group::rw-
     mask::rw-
     other::---

     The ls shows that there are ACLs by appending a plus sign to the
     permissions:

     $ ls -l /dev/dsp
     crw-rw----+ 1 root audio 14, 3 Mar  7 16:42 /dev/dsp

7.3. How do I find out whether resmgr knows that I am logged in?

     Use resmgr with the sessions option to list all sessions of the current
     user. When run as root resmgr will list all sessions of all users.

     $ /sbin/resmgr sessions
     :0 fritz

7.4. How do I list the classes I have access to?

     openSUSE 10.2, 10.3:

         Use resmgr with the classes option to list all sessions of the current
         user. When run as root resmgr will list all sessions of all users.

         $ /sbin/resmgr classes
         desktop
         dvb
         v4l
         ...


7.5. How do I grant users permanent access to serial ports like ttyS0, ttyACM0?

     Modems are the most common devices that are conneted to serial ports.
     Access to such ports can cost real money if a user dials expensive
     numbers. Therefore access to serial ports is not granted by default.

     To grant the user "fritz" access to all serial ports nevertheless (replace
     "fritz" with the actual user name) you need create a new file for resmgr,
     for exapmle /etc/resmgr.conf.d/50-modem.conf. Add the following line:

     allow modem user=fritz

     If you don't want to grant access to all serial ports (good) just because
     e.g. your PDA is connected to /dev/ttyS0 you may also assign a different
     class to that device. Access to the class pda for example is granted by
     default. To change the class of /dev/ttyS0 to pda create a file /etc/hal/
     fdi/policy/20user/50-mypda.fdi with the following content:

     <?xml version="1.0" encoding="ISO-8859-1"?>
     <deviceinfo version="0.2">
       <device>
         <match key="linux.device_file" string="/dev/ttyS0">
           <merge key="resmgr.class" type="string">pda</merge>
         </match>
       </device>
     </deviceinfo>

7.6. Should I add users to the group uucp?

     No! The group uucp is reserved for use by the uucp system. Adding users to
     that group grants them access to additional directories which may lead to
     security problems with other programs.

8.  Location of source code

The resmgr source repository ist hosted at Novell Forge

9.  Author

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

