The iiitAccessServer uses a XML file for configuration data. When starting, the program searches t he directories ., etc, /usr/local/etc and /etc for the file AccessServer.xml. If the script run.sh is used to start the iiitAccessServer, the current directory will be changed to the installation directory and so the search starts there. Otherwise the search starts from the current directory.
We do not want to explain the usage of XML files. You will find documentation concerning XML at http://www.xml.org.
To keep the parsing and processing of the configuration file simple, we do not use all capabilities of XML. In contrast to the usual XML notification, we do not distingiush between upper- and lower-case spelling of the names of items and attributes. The layout of the configuration file looks like the following example:
<?xml version="1.0" encoding="UTF-8"?> <AccessServer> <Element1 Attribute1 = "value1" Attribute2 = "value2" ... AttributeN = "valueN" /> <Element2 Attribute1 = "value1" Attribute2 = "value2" ... AttributeN = "valueN" > <SubElement1 Attribute1 = "value1" Attribute2 = "value2" ... AttributeN = "valueN" /> <SubElement2 Attribute1 = "value1" Attribute2 = "value2" ... AttributeN = "valueN" /> </Element2> </AccessServer>
Any item may contain any number of sub-items.
There are two waysy to configure logging. The simple way only configures the log-level by adding the attribute LogLevel to the item AccessServer:
<?xml version="1.0" encoding="UTF-8"?> <AccessServer LogLevel = "DEBUG"> ... </AccessServer>
The output will be sent to STDOUT.
A little more sophisticated the logging may be configured using an item named Logger.
<?xml version="1.0" encoding="UTF-8"?> <AccessServer> <Logger LogLevel = "INFO" LogFile = "./accessserver.log" MaxFileSize = "1000000" MaxBackupFiles = "5" /> ... </AccessServer>
The attribut LogLevel defines which kind of log messages will be printed at all. Valid values are OFF, FATAL, ERROR, WARN, INFO, DEBUG and ALL. If this attribute is missing or invalid the value DEBUG will be used as a default.
The attributes LogFile, MaxFileSize and MaxBackupFiles are used to define the name of the file to use for logging, the maximum file size and the number of old files to keep.
The item Logger should be defined only once in the configuration file. If it is found more than once, only the first one will be used.
The configuration of the built-in LDAP interface will be used by the LDAP resolver and by the CacheManager. It may be configured together with these plug-ins or for simplicity globaly as an item of its own. The configuration looks like this:
<?xml version="1.0" encoding="UTF-8"?> <AccessServer> ... <LdapConfig RootDN = "dc=iiit,dc=de" LdapPersonSearchBase = "ou=person,dc=iiit,dc=de" LdapGroupSearchBase = "ou=group,dc=iiit,dc=de" LdapFormulaSearchBase = "ou=formula,dc=iiit,dc=de" LdapPersonClass = "iiitPerson" LdapGroupClass = "iiitGroup" LdapFormulaClass = "iiitFormula" LdapExpressionField = "iiitExpression" LdapCommonNameField = "cn" LdapUserIdField = "uid" LdapMemberUserIdField = "memberUid" > <server java.naming.provider.url = "ldap://ldap1.iiit.de/" java.naming.factory.initial = "com.sun.jndi.ldap.LdapCtxFactory" java.naming.security.protocol = "" java.naming.security.authentication = "simple" java.naming.security.principal = "" java.naming.security.credentials = "" /> <server java.naming.provider.url = "ldap://ldap2.iiit.de/" java.naming.factory.initial = "com.sun.jndi.ldap.LdapCtxFactory" java.naming.security.protocol = "" java.naming.security.authentication = "simple" java.naming.security.principal = "" java.naming.security.credentials = "" /> </LdapConfig> ... </AccessServer>
The attribut RootDN defines the root of LDAP data, LdapPersonSearchBase, LdapGroupSearchBase and LdapFormulaSearchBase define where to start when searching for persons, groups and formulas. The attributes LdapPersonClass, LdapGroupClass and LdapFormulaClass are used to configure the object classes to search for inside the LDAP database. Additionally you must use the attributes LdapExpressionField, LdapCommonNameField, LdapUserIdField and LdapMemberUserIdField to define the LDAP attributes containing the information to read. All these attributes do not have any defaults. They may used to adopt the iiitAccessServer to any LDAP data structure.
Besides these base attributes you must configure how to access the LDAP server. To do this, you have to enter Server sub-items, one for every LDAP server to be used. The attributes of these items are passed through to the JNDI implementation of the Java runtime environment. You must enter them according to the JNDI documentation.
The item AccessServer has one more attribut: IgnoreCase. This attribut defines, whether the iiitAccessServer distingiushes between upper- and lower-case spelling of names of users, groups and formulas. Default for this attribut is false, which means that it will distinguish. The configuration looks like this:
<?xml version="1.0" encoding="UTF-8"?> <AccessServer IgnoreCase = "true"> ... </AccessServer>
Remark: The LDAP resolver forces this attribut to be set to true internally.
The attribute VerifyUser defines whether user IDs passed to the server with the command SETUSER shall be verified or not. When set to true, the IDs are verified. The default of this attribut is true. The ResolverPlugin is responsible for the verification. ResolverPlugins without access to an user database – like the PropertyFileResolver – set this attribute to false internally.
<?xml version="1.0" encoding="UTF-8"?> <AccessServer VerifyUser = "true"> ... </AccessServer>
The iiitAccessServer knows three kinds of plug-ins described in following chapters. The base structure of the configuration is always the same:
<?xml version="1.0" encoding="UTF-8"?> <AccessServer> ... <xxxPlugin PluginClass = [Classname] > <PluginConfig Attribute1 = "value1" Attribute2 = "value2" AttributeN = "valueN" > <Element Attribute1 = "value1" Attribute2 = "value2" AttributeN = "valueN" > <SubElement1 Attribute1 = "value1" Attribute2 = "value2" AttributeN = "valueN" /> <SubElement2 Attribute1 = "value1" Attribute2 = "value2" AttributeN = "valueN" /> </Element> </PluginConfig> </xxxPlugin> ... </AccessServer>
The name of the item is ResolverPlugin, CachePlugin or ThreadPlugin. The attribute PluginClass defines the name of the class to be used for the plug-in. CachePlugin- and ResolverPlugin-items should be used only once. Further instances will be ignored. However, there may be any number of ThreadPlugin-items.
Resolver Plug-Ins are used to resolve names requested by the application. Therefore any valid configuration file must contain exactly one ResolverPlugin-item. Currently there are two classes of ResolverPlugins implemented, which are described here.
This resolver reads its data out of a simple Java property file. Because the entries are read only once on start-up, this resolver may not be be used in production environments, but for tests and development. It must be configured like this:
<?xml version="1.0" encoding="UTF-8"?> <AccessServer> ... <ResolverPlugin PluginClass = "de.iiit.AccessServer.parser.PropertyFileResolver" > <PluginConfig FileName = "etc/expressions.properties" /> </ResolverPlugin> ... </AccessServer>
The only attribute is the name of the property file to be used. This example uses the name of the property file delivered together with the iiitAccessServer package. The layout of the property file should be like this:
ga1=a1,a2 ga2=a3,a4 ga3=a5,a6 gn= ga12=ga1+ga2 ga23=ga2+ga3 ga13=ga1+ga3 ga=ga1 + ga2 + ga3
ga1, ga2 and ga3 are groups containing two members, while gn is an empty group. ga12, ga23, ga13 and ga represent expressions.
The LDAP resolver is assumed to be used in production environments. There must be a LDAP interface configuration as shown above. The LDAP configuration may be a global item or a sub-item of the PluginConfig-item. There are no further configuration items. Therefore the configuration may look like this one:
<?xml version="1.0" encoding="UTF-8"?> <AccessServer> ... <LdapConfig ... > <server ... /> ... </LdapConfig> ... <ResolverPlugin PluginClass = "de.iiit.AccessServer.parser.LdapResolver" /> ... </AccessServer>
The iiitAccessServer contains two implementations of caches.
The simple cache is a 1st-level only cache. The configuration looks like this:
<?xml version="1.0" encoding="UTF-8"?> <AccessServer> ... <CachePlugin PluginClass = "de.iiit.AccessServer.cache.SimpleCache" > <PluginConfig InvalidationTimeout = "600" LRUTimeout = "100" SleepTime = "10" /> </CachePlugin> ... </AccessServer>
The attribute InvalidationTimeout should be used to force the cache to ignore items older than the defined amount of time. This assures that all changes in the database will be took into consideration after a defined amount of time. The attribute LRUTimeout may be used to delete cache items not used for an amount of time. To do this, the cache plug-in uses a background thread, which sleeps for SleepTime seconds after each loop. All these attributes define times with seconds.
The database cache contains a 1st- and a persistent 2nd-level cache. The last mentioned one uses a MySQL database to store its items and is therefore a little more complex in configuration. This cache will not be filled automatically, but needs a separate plug-in – the CacheManager – to read the data from the LDAP database and write it in an optimized format into the cache database.
<?xml version="1.0" encoding="UTF-8"?> <AccessServer> ... <CachePlugin PluginClass = "de.iiit.AccessServer.cache.DbCache" > <PluginConfig InvalidationTimeout = "600" LRUTimeout = "100" SleepTime = "10" Md5PatternLength = "1" > <JdbcDriver ClassName = "com.mysql.jdbc.Driver" /> <CacheDatabase Url = "jdbc:mysql://jacomo/AccessServerCache" UserName = "checker" Password = "checker" Connections = "5" /> <CacheDatabase Url = "jdbc:mysql://wuppi/AccessServerCache" UserName = "checker" Password = "checker" Connections = "5" /> </PluginConfig> </CachePlugin> ... </AccessServer>
The attributes InvalidationTimeout, LRUTimeout and SleepTime are used to control the 1st-level cache as described above. Internally the 2nd-level cache uses MD5 sums as keys. To distribute the cache data over more than one database, the attribute Md5PatternLength defines the number of bits of the MD5 sum to be used to select the database. Valid values are 0 - 8 bits corresponding to 1 - 256 databases.
Inside the plug-in configuration, you must enter items containing the database configuration. The item JdbcDriver uses the attribut ClassName to configure the JDBC driver to be used.
For every needed database, there must be one CacheDatabase-item containing the attributes Url, UserName and Password to define how to reach the database. Additionaly the parameter Connections can be used to define how many connections to the database shall be opened on startup to speed up the later accesses to the database. If this parameter is missing, no connections will be opened on startup. To help you optimizing this parameter, everytime a new connection is opened, a message will apear in the log file telling you how many connection to database are currently open.
If there are more database definitions than needed, those further databases will be ignored. It is important, that all databases are listed in exactly the same order as they are listed at the CacheManager's configuration. If the are some database servers more powerful than others, you may use them more than once to give them a bigger part of the load.
The RMI server is the prefered interface for Java applications. The only configuration option is the port number where the AccessServer's private RMI registry should listen on. The default port number is 54322.
<?xml version="1.0" encoding="UTF-8"?> <AccessServer> ... <ThreadPlugin PluginClass = "de.iiit.AccessServer.server.RMIServer" > <PluginConfig Port = "54322" /> </ThreadPlugin> ... </AccessServer>
The TCP/IP-server is currently the only interface to be used by applications not written in Java. The only configurable parameter is the number of the port, the server shall listen on. This plug-in may be configured more than once with different port numbers. The default port number is 54321.
<?xml version="1.0" encoding="UTF-8"?> <AccessServer> ... <ThreadPlugin PluginClass = "de.iiit.AccessServer.server.TcpServer" > <PluginConfig Port = "54321" /> </ThreadPlugin> ... </AccessServer>
If you have more than one instance of the iiitAccessServer running in your network, you must have exactly one instance running the CacheManager.
On its first start-up, the CacheManager reads the whole content of the LDAP databases and uses the data to fill the persistent 2nd-level cache. Afterwards all changes occuring in the LDAP database will be read and used to refresh the cache. In case of an error, the system administrator can be notified by an e-mail.
<?xml version="1.0" encoding="UTF-8"?> <AccessServer> ... <ThreadPlugin PluginClass = "de.iiit.AccessServer.cachemanager.CacheManager" > <PluginConfig ReplicationFile = "/var/lib/ldap/replication.log" RefreshInterval = "10" Md5PatternLength = "1" SMTPServer = "jacomo.iiit.de" SMTPPort = "-1" SMTPUser = "" SMTPPassword = "" SMTPMailTo = "firstname.lastname@example.org" > <JdbcDriver ClassName = "com.mysql.jdbc.Driver" /> <AdminDatabase Url = "jdbc:mysql://wuppi/AccessServerAdmin" UserName = "checker" Password = "checker" Connections = "5" /> <CacheDatabase Url = "jdbc:mysql://jacomo/AccessServerCache" UserName = "checker" Password = "checker" Connections = "5" /> <CacheDatabase Url = "jdbc:mysql://wuppi/AccessServerCache" UserName = "checker" Password = "checker" Connections = "5" /> </PluginConfig> </ThreadPlugin> ... </AccessServer>
As described at the LDAP resolver, the LDAP configuration may be entered globaly or as an sub-item of the plug-in configuration.
The attributes SMTPServer, SMTPPort, SMTPUser, SMTPPassword and SMTPMailTo are used to configure a connection to a mail server. If SMTPPort is set to -1 oder if it is missing, the default SMTP port will be used. If any other of these attributes is missing, no mail notifications will be sent at all.
The cache databases must be described the same way as they are with the database cache configuration. Additionally there must be one database used for temporary data of the CacheManager itself. This has to be configured with an AdminDatabase-item in the same way as the other databases. In a minimal environment, this may be the same database as the one used for the cache.
To refresh the persistent cache, the CacheManager reads the OpenLDAP's replication log file and acts like the slurpd program. The attribute ReplicationFile defines the name of the file to read. The attribute RefreshInterval defines the amount of time to sleep after every loop. The configuration of the LDAP server itself will explained in the next paragraph.
We do not want to explain every configuration detail of OpenLDAP, but only those special configuration items, you need to observe to use the iiitAccessServer together with OpenLDAP.
In the sub-directory ldap of iiitAccessServer's installation directory you will find a file named iiit.schema. It contains schema extensions for the LDAP server: The class definitions iiitFormula, iiitPerson and iiitGroup. These classes shall be used for all LDAP data relevant to the iiitAccessServer. The classes iiitPerson and iiitGroup are compatible to other person- and group-classes of LDAP. They shall be used together with them.
To include these extensions into the OpenLDAP server configuration, you must copy the file iiit.schema into the schema sub-directory of the OpenLDAP configuration. With SuSE-Linux, this directory is named /etc/openldap/schema. Additionaly you must instruct the LDAP server to use these extension with a line
behind all other schema definitions in the configuration file slapd.conf.
The corresponding section of the configuration file sould now look like this:
... include /etc/openldap/schema/core.schema include /etc/openldap/schema/cosine.schema include /etc/openldap/schema/inetorgperson.schema include /etc/openldap/schema/nis.schema include /etc/openldap/schema/iiit.schema ...
Together with iiitAccessServer, we found the following index definitions to be useful:
... index default pres,eq index uid index cn,sn pres,eq index objectClass eq ...
The LDAP server must be configured to use replication to allow the iiitAccessServer to read all changes. To replicate its data, the OpenLDAP server writes all changes using the LDIF format into a file, which is normaly read by the slurpd program. The iiitAccessServer takes over this role of the slurpd. Instead of sending the data to the slave LDAP servers, it uses it to refresh the persistent cache. To do this, the iiitAccessServer must have access to the replication log file, therefore it should run with the same user ID as the LDAP server.
If the iiitAccessServer runs in an environment with replicated LDAP servers, it must not run together with the master server, to avoid conflicts while reading the replication log file. In these cases, the iiitAccessServer must run together with one of the slave servers.
Important: The iiitAccessServer must not run together with slurpd on the same machine.
To switch on replication in OpenLDAP, you must enter entries like the following to the configuration file slapd.conf:
... replogfile /var/lib/ldap/replication.log replica host=AccessServer binddn="cn=Replicator,dc=iiit,dc=de" bindmethod=simple credentials=secret
You must enter these lines behind the database definition, usually at the end of the configuration file. Obviously, the entry replogfile must match the attribute ReplicationFile of the CacheManager configuration.