
[[server-cfg]]
The XUUDB server
----------------


[[sec_certdn]]
Normal mode vs. DN mode
~~~~~~~~~~~~~~~~~~~~~~~

The XUUDB Database supports two mode, 'normal' and 'dn', controlled by
a setting in the server configuration file. Those modes are only relevant
for the static mappings stored in XUUDB; the dynamic mappings are done using 
DNs or other attributes always. 

Running in normal mode uses the whole X.509 PEM encoded certificate of
the user to perform a match. This particularly means, if a user
certificate is not valid any more the user has to be readded with a
new certificate.  When running in dn mode, only the DN of the x509
certificate is stored in the database, so a user can access UNICORE
with a new certificate, if the DN is equal to the old one. Therefore
the dn mode is usually better. Also note that in some (although rare) cases
the UNICORE server performing authorisation may know only the user's DN. Then
the certificate check won't be possible and the user will be banned.


Security
~~~~~~~~

XUUDB server may be run using a plain HTTP port. Then there is no access control
at all, so this mode is useful only in environments where XUUDB port is fully 
protected otherwise against unauthorised access. 

Typically client-authenticated SSL is used to protect the XUUDB. For this you
will need certificates for the XUUDB server and all Grid components that want
to talk to the XUUDB.  In general the UNICORE servers (like UNICORE/X) 
and the XUUDB-admin client need to connect to the XUUDB-server. 
To make the SSL connections possible, you have to put the following certificates as trusted 
certs into the XUUDB's server truststore:

- CA certificate(s) of the UNICORE/X server(s) that query the XUUDB
- CA certificate(s) of the XUUDB-admin user certificate(s)

and XUUDB's CA certificate in the truststores of its clients.

Administrative access
~~~~~~~~~~~~~~~~~~~~~

The XUUDB provides two kinds of web service interfaces, one for querying the XUUDB 
(i.e. mapping Grid users to local users), and a second
one for administration of the XUUDB (i.e. adding and editing entries).
All access to the XUUDB (including the administration utility!) is through these
web services. To prevent arbitrary Grid users from modifying the XUUDB, 
the administrative interface has to be protected. 

Starting with UNICORE 6.3, the access control mechanism
of the administrative interface has been simplified. An ACL file is used, 
which is a text file containing the distinguished names of the 
administrators. At least it has to contain the DN of the certificate used by 
the administration utility.

As the static XUUDB data is rather sensitive (at least if privacy of the users 
is a concern) and dynamic mappings often require some local modifications (e.g.
assigning an account from a pool) it is often desirable to protect also the
query operations. XUUDB server since version 2, offers such option 
(see <<base-settings>>). 

The ACL file can be changed at runtime to easily add or remove administrators.

To change the location of the ACL file, edit the server
configuration and set a configuration parameter (see <<base-settings>>).
 
The ACL entries are expected in the RFC 2253 format. To get the name 
of a certificate in the correct format using openssl, you can use the 
following OpenSSL command:

 $> openssl x509 -in demouser.pem -noout -subject -nameopt RFC2253




Configuration
~~~~~~~~~~~~~

By default, the configuration is defined in the file
+CONF/xuudb_server.conf+. To use a different configuration file, edit the start script, or use
+--start <config_file>+ as command line arguments when starting.

The server's configuration file allows for setting the general XUUDB settings, 
database backend settings, advanced HTTP server settings and finally 
(for secure HTTPS URLs) the server's truststore and credential. The available 
properties are described in the following sections. 

For production deployments you should review the listen 
address and setup correctly truststore and credential. 
Defaults for the embedded database configuration and HTTP server settings are usually fine.
In case if you plan to use dynamic mappings, also the dynamic mapping rules need to be provided.


[[base-settings]]
Base server settings
^^^^^^^^^^^^^^^^^^^^

include::xuudb-ref-main.txt[]

Database settings
^^^^^^^^^^^^^^^^^

XUUDB can be configured to use different database backends. Currently an embedded H2 database and external MySQL 
are supported. H2 database (the default) requires no additional configuration actions. In any case XUUDB will
automatically create the required database tables. 

For MySQL you have to properly set up the server and create a database. After installing and starting 
the MySQL server login to its using MySQL client as administrator and using a commands similar to the below ones, 
create a database and assign full access to a xuudb user.  

    create database xuudb;
    grant all on xuudb.* to 'xuudbuser'@'127.0.0.1' identified by 'pass';

Of course you are free to choose different names for the user, password and database. If XUUDB server is 
installed on other host then the proper address must be set instead of localhost. 

Use the following properties to configure database connection from the XUUDB server. In case of external database
pay attention to enter proper values.  

include::xuudb-ref-dbProperties.txt[]



:leveloffset: 2

include::sec-jetty.txt[]

[[authtrust]]
include::sec-authtrustcfg.txt[]

:leveloffset: 0


[[dynamic]]
Dynamic mappings configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Dynamic mappings are configured with a set of rules. When designing rules it is good
to remember that all users, which will be evaluated, were already successfully authorized.

Each rule has a condition which selects users and a list of mappings which should be 
applied for the selected users. Example conditions (in English): 

- all members of a '/vo.wonderworld.gov'
- all (authorized) users
- all users having extra attribute 'matlabAllowed' with any value AND being member of a subgroup of
 '/vo.wonderworld.gov/dynamic/'
 
Example mappings (in English):

- add user a supplementary group 'matlab' 
- assign uid from a pool of existing uids
- assign a fixed gid 'grid'
- invoke an external program and use its standard output as users gid 

Precisely speaking, a mapping must have defined:

- what attribute it maps: _uid_, (primary)_gid_ or _supplementaryGids_,
- using what method: _fixed_, _pool_ or _script_
 
Additionally one can define an optional parameter stating if the mapping should overwrite
an attribute value which was previously set (either by an earlier rule or assigned using a different
attribute source).

As it was mentioned there are three kinds of mappings. Let's shortly introduce them one by one.

Fixed mappings
^^^^^^^^^^^^^^

_Fixed mappings_ are the most basic option. The mapping is formed by a simple assignment of a fixed value.
It can be used to:

- assign a common (shared!) uid to selected users (rarely used)
- assign a fixed gid to selected users (very useful to assign a gid to all Grid users, or
 all members of a VO)
- assign some supplementary gids to selected users (useful to provide additional local permissions
 to users having a special role/attributes/etc.).

The example in the pool mappings section contains also a fixed mapping. 
 
Script mappings
^^^^^^^^^^^^^^^

_Script mappings_ are the "Do It Yourself" mechanism. You can provide a command line which will be parsed
and invoked. The application must return (on its standard output) a string with a mapping result 
(depending on what is mapped - gid, uid or a space separated list of supplementary gids).
Of course the script can be informed who is actually being mapped, by using parameters enclosed in +${}+.
The list of available parameters is given below.

- +userDN+ user's DN
- +issuerDN+ user's certificate issuer's DN
- +role+ user's role
- +vo+ user's selected VO
- +extraAttributes+ map with extra attributes, names are the keys
- +xlogin+ user's uid (if already established)
- +gid+ user's gid (if already established)
- +supplementaryGids+  user's supplementary gids (if already established)
- +xloginSet+ whether uid was set
- +gidSet+ whether gid was set
- +dryRun+ whether the current invocation is only a simulation, and shouldn't 
affect any persisted system settings.

The example below contains also a script mapping. 

Pool mappings
^^^^^^^^^^^^^

Finally the _pool mappings_ are both flexible and relatively easy to use --- it is the most advanced
mapping type. Using the pool mapping you have to prepare a set of reserved identifiers (uids or gids
depending on what is mapped). The related system accounts can be precreated or can be created on-demand.
The pool mapping is configured with an additional, very important parameter: pool key. Pool key is 
a name of one of the user's attributes: _userDN_, _issuerDN_ (DN of CA which issued user's certificate), 
_role_, _vo_ or any other generic user's attribute. 

To explain how the pool works let's assume that key is set to _userDN_. Then
the pool will map a user as follows: first it is checked if there is an existing mapping 
bound to the user's DN. If it is found then it is simply returned. If not (the user is trying to use 
the site for the first time) a new identifier is selected from the pool, and stored under the key
being the user's DN. Then the new identifier is returned. 

Therefore all users having the same value of the pool key will get the same mapping and vice versa. 
If DN is the key then all users will have a distinct mapping (useful for uids or for gids, if every
user should get a unique one). If for instance a VO is the key then all VO members will have the same 
mapping (useful for gid, or for uid if all VO members should have the same user account).

The following example should help to understand those concepts and is also providing
a basic syntax reference:

---------------
<?xml version="1.0" encoding="UTF-8"?>
<dynamicAttributes xmlns="http://unicore.eu/xuudb/dynamicAttributesRules"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       
  <rules>
    <!-- all members of the vo /vo.wonderworld.gov should have a common uid 'shared_user'-->
    <rule>
      <condition>vo.matches("/vo.wonderworld.gov/.*")</condition>
      <mapping type="fixed" maps="uid">shared_user</mapping>
    </rule>

    <!-- all users with a role 'admin' should get a primary gid from the 'admins-pool' pool.
    For pools the 'maps' parameter is optional - it is better to specify it in the pool definition, 
    below. -->  
    <rule>
      <condition>role="admin"</condition>
      <mapping type="pool">admins-pool</mapping>
    </rule>
    
    <!-- all users from the /biology VO get an uid from the pool and a fixed primary gid 'biol' -->
    <rule>
      <condition>vo.matches("/biology/.*")</condition>
      <mapping type="pool">biology-uids-pool</mapping>
      <mapping type="fixed" maps="gid">biol</mapping>
    </rule>
    
    <!-- complicated condition: all users who have a generic attribute 'matlabAllowed' set AND the value
	of this attribute is 'true' get a supplementary group 'matlab' --> 
    <rule>
      <condition>attributes["matlabAllowed"] != null and attributes["matlabAllowed"].contains("true")</condition>
      <mapping type="fixed" maps="supplementaryGids">matlab</mapping>
    </rule>
    
    <!-- all (authorized) users, who do not have an uid set (overwriteExisting=false)
	should have an uid assigned by a script /usr/local/bin/create-mapping.pl. The script will be called
	with two arguments: user's DN and VO.
    <rule>
      <condition>true</condition>
      <mapping type="script" maps="uid" overwriteExisting="false">/usr/local/bin/create-mapping.pl "${userDN}" "${vo}" </mapping>
    </rule>
  </rules>

  <!-- Here come pools -->
  <pools>
    <!-- pool 'admins-pool' maps gids. The list of gids provides groups which were 
    pre-created in the system. The gids will be stored per-user dn, so every admin will get another group.
    Finally the list of gids uses special expressions where number ranges are provided.
    -->
    <pool id="admins-pool" type="gid" key="dn" precreated="true">
      <id>admin_grp[1-100]</id>
      <id>admin_grp[200-1000]</id>
    </pool>
    <!-- This pool identifiers are loaded from an external file -->
    <pool id="biology-uids-pool" type="uid" key="dn" precreated="true">
      <file>src/test/resources/externalUidsPool</file>
    </pool>
  </pools>
</dynamicAttributes>
-------------

Usage of pools brings several issues regarding old mappings removal and notifications about pools
getting empty. In the first case it suggested not to remove the users for the time a VO or Grid is 
supported: it is a simplest approach, and nowadays operating systems can support thousands of uids
without any problem (Linux can have 32bit uid numbers). 

In case a site wants to recycle mappings, XUUDB offers the following mechanism:

- Inactive mappings can be automatically (after a configurable time threshold) or manually 
 (using the admin client) _frozen_. An identifier belonging to a frozen mapping is still 
 assumed to be occupied, but the mapped user won't have it assigned (in the unprobable case that she
 returns to the site). Freezing is introduced to give a time for tidying up local resources assigned to 
 the identifier. Such cleaning must be done manually and should include removal of all owned 
 files and killing any processes. Of course this depends whether the identifier was a gid or uid.
 Also please note that in case of clusters, all nodes should be cleaned up. 
- After the clean up is done, the frozen mapping can be removed, again manually using the admin client
 or automatically, after staying in the frozen state for a specified amount of time. Note that
 it is impossible to remove an alive mapping.
 
If administrator is able to provide scripts which performs cleanup, then it is possible to invoke
them upon pool mapping freezing and automate the whole process. In a similar way other handlers
may be configured and XUUDB will invoke them to notify about mappings removal, assignment of a new mapping
(useful when accounts are not pre-created but should be created on demand) and also when 
a pool is getting empty. 

The following example shows all the possible handlers and lists arguments which are passed to them. 
As it can be seen all pool options including handlers, can be configured globally or per-pool.

---------
<?xml version="1.0" encoding="UTF-8"?>
<dynamicAttributes xmlns="http://unicore.eu/xuudb/dynamicAttributesRules"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <!-- how often (in s) pools should be checked for old or inactive mappings -->
  <poolMonitoringDelay>300</poolMonitoringDelay>
  <defaultConfiguration>
	<!-- in seconds: automatic freezeing (time measured from last mapping use)... -->
	<automaticFreezeAfter>3600000</automaticFreezeAfter>
	<!-- ... and final removal (time measurd from mapping freeze) -->
	<automaticDeleteAfter>36000</automaticDeleteAfter>
	<!-- when less then this free mappings are left generate a warning -->
	<emptyWarningAbsolute>20</emptyWarningAbsolute>
	<!-- when less then this percent of free mappings is left generate a warning -->
	<emptyWarningPercent>5</emptyWarningPercent>
	
	<!-- timeout for running ALL external programms -->
	<handlerInvocationTimeLimit>10000</handlerInvocationTimeLimit>
	
	<!-- Various handlers. Arguments are pool.getId(), pool.getType().toString(), 
					bean.getEntry(), oldSec+"" -->

	<!-- Handler invoked before freezing an account. 
     Arguments: <poolId> <poolType> <identifier> <inactiveForInSeconds>
     If handler returns a non-zero exit status then the freezing is skipped
     (unless invoked by admin-client). 
	-->
	<handlerAboutToFreeze>/opt/handlers/releaseAccountResources.sh</handlerAboutToFreeze>

	<!-- Handler invoked before deleting a frozen identifier. 
	     Arguments: <poolId> <poolType> <identifier> <frozenForInSeconds>
	     If handler returns a non-zero exit status then the deletion is skipped
	     (unless invoked by admin-client). 
	     -->
	<handlerAboutToDelete>/opt/handlers/notifyAccountRecycled.sh</handlerAboutToDelete>

	<!-- Handler invoked when an identified from the uids pool is going to be used for the first time
	(or for the first time after deleting it), if the pool is set as not pre-created. 
		Arguments: <poolId> <uid> <key>
	-->
	<handlerCreateSystemUid>/opt/handlers/adduser.sh</handlerCreateSystemUid>

	<!-- Handler invoked when an identified from the gids pool is going to be used for the first time
	(or for the first time after deleting it), if the pool is set as not pre-created. 
		Arguments: <poolId> <gid> <key>
	-->
	<handlerCreateSystemGid>/opt/handlers/addgroup.sh</handlerCreateSystemGid>

	<!-- Handler invoked when a pool warning threshold is exceeded. 
	     Arguments: <poolId> <poolType> <remainingFreeIds>
	-->
	<handlerPoolGettingEmpty>/opt/handlers/notifyNearlyEmpty.sh</handlerPoolGettingEmpty>

	<!-- Handler invoked when a pool gets empty. 
	     Arguments: <poolId> <poolType>
	-->
	<handlerPoolEmpty>/opt/handlers/notifyEmpty.sh</handlerPoolEmpty>
  </defaultConfiguration>
         
  <rules>
  	<!-- some rules ........ -->
  </rules>

  <pools>
  	<!-- Pool can overwrite any of the global configuration options -->
    <pool id="admins-pool" type="gid" key="dn" precreated="true">
      <configuration>
         <!-- disable automatic freezing for this pool -->
		 <automaticFreezeAfter>-1</automaticFreezeAfter>      	
      </configuration>
      <id>admin_grp[1-100]</id>
      <id>admin_grp[200-1000]</id>
    </pool>
  </pools>
</dynamicAttributes>
---------

 
   


Starting the XUUDB server
~~~~~~~~~~~~~~~~~~~~~~~~~

Start the server with

  BIN/start.sh

In case if XUUDB was installed with binary package use:

  /etc/init.d/unicore-xuudb start

Stopping the server
~~~~~~~~~~~~~~~~~~~

Stop the server with

  BIN/stop.sh
 
This sends a TERM signal to the XUUDB process. Please do not use +kill -9+
to stop XUUDB, to avoid corrupting the database.

In case if XUUDB was installed with binary package use:

  /etc/init.d/unicore-xuudb stop


:leveloffset: 1
include::sec-logging.txt[]
:leveloffset: 0

Several logging categories common in XUUDB:

[options="header"]
|===============================
|Log category      			| Description
|unicore           			| All of UNICORE 
|unicore.security  			| Security layer 
|unicore.client    			| Client calls (to other servers) 
|unicore.xuudb     			| XUUDB related
|unicore.xuudb.server     	| XUUDB server
|unicore.xuudb.server.db    | XUUDB server database layer
|unicore.xuudb.client     	| XUUDB admin client
|====================================================================


