ACEDB Version 4_9
User Guide To Sockets-based Client/Server
Originally written by
Ed Griffiths <edgrif@sanger.ac.uk>, December 1999Background
The first implementation of the ACEDB client/server code used
RPC
for inter process communication (IPC
). This method was originally chosen because it offered the promise and portable means of making requests between the client and server. In practiceRPC
suffered from several major disadvantages:The decision was taken to switch to socket based
- although
RPC
was offered by all major unix vendors, their implementations turned out to be buggy, in different ways (ironically, this was especially true of Suns implementation).- although
RPC
offers a very simple function call interface forIPC
, error handling is not so simple and does not offer the fine grained control that other methods ofIPC
do.RPC
for MS Windows is not robust.DCE RPC
using the DCE version of RPC would help with portability for both Unix and MS Windows, but the DCE version is often not available for free.- many other code subsytems offer sockets communication (e.g. Perl) but not
RPC
.- On unix at least
RPC
requires several daemons to be running (portmapper, inetd) and this makes the system susceptible to system set up/reboot problems.IPC
because it overcomes the above difficulties. Sockets of course present their own difficulties because the interface to them is more complex to program thanRPC
, it's greater flexibility/portability and ubiquitousness made this a worthwhile trade off.Overview
The sockets based version of the server offers the same interface as the current RPC based version of the client/server but there have been several additions to the code that are either indirectly or not directly related to sockets:
- NO_RESTART option & fix for the "phoenix" bug
- READ/WRITE options for setting global access permissions to a database
- MD5 password based authentification for users
- domain name group authorisation (NO_HOSTNAME_RESOLUTION option)
- a new "admin" class of user with a set of "admin" commands
- READ ONLY database support
- DEBUG option
This document describes these new features and then goes on to describe how to:
- set up a database for use with the sockets server
- server start up options
- foreground and inetd startup of the server
- client start up
Setting up a database
The following is a brief summary to get you started, it should let you get the server/client going, after that you can tinker around to get more security etc.:
1) Options in wspec/serverconfig.wrm:
- NO_RESTART
- - turns ON no restart of server after a crash/shutdown.
- NO_HOSTNAME_RESOLUTION
- - turns OFF checking for user being in a domain specified as having permission to log in, e.g. sanger.ac.uk
- DEBUG
- - turns ON server debugging output to database/server.log
- WRITE/READ
- - set the basic database access permission levels for the read and write groups (admin users always have write access). Default is PASSWD, but NONE & WORLD can also be set.
- READONLY_DATABASE
- - allows the server to run on a database where all the file permissions have been set to read-only (unix only) for extra security.
Unless you have special needs, the default settings are suitable for either testing or a production database, but you must create the empty file wspec/serverconfig.wrm.
See Configuration options for more details.
2) Passwords in wspec/serverpasswd.wrm:
This file contains two types of record: groups/associated users records and individual user records. There are three groups: admin, write and read and to set up a database to run with the new socket server there needs to be at least one user in the admin group.
To 'bootstrap' an admin user so you can access the database via the client you need to:
- choose your admin userid (this does _not_ need to be an existing Unix userid, it can be any name you want), e.g. joebloggs
- alter the admin group line in
serverpasswd.wrm
so it looks like this:admin: joebloggs
- now use the acedb utility program makeUserPasswd to create the user entry for joebloggs (note that you won't see the password you type):
> bin.whatever/makeUserPasswd joebloggs // Please enter passwd: jumbo10 // Please re-enter passwd: jumbo10 // The following line is a valid entry for wspec/serverpasswd.wrm joebloggs ccc5b9abf592836076410cdee518c518 >
cut and paste the entry into a separate line in the
serverpasswd.wrm
file.The resulting wspec/serverpasswd.wrm file would look like this:
admin: joebloggs joebloggs ccc5b9abf592836076410cdee518c518
Once the initial admin user has been set up, all other users can be set up from the admin userid via the new admin commands.
You should now be in a position to test the server and client, it is recommended that you test the server in the foreground before trying to set it up to be run by inetd.
Server start up options
saceserver command line options are:
saceserver database_path <:port_number clientT:serverT:maxReq:autoS> database_path mandatory, gives path to the database port_number defaults to 23100 clientT client time out (secs), default = 600 serverT server time out (secs), default = 600 maxReply maximum reply size (Kbytes) that server should return autoS time between autosaves of database (secs), default = 600
timeout values
The meaning of the timeouts is:
- clientT
- the server will disconnect any clients who have not been active for this length of time.
- serverT
- once all clients are disconnected, the server will timeout after this length of time.
So if, for instance, you wanted to allow clients to be dormant for an hour but have the server close down as soon as the last client quit you could start the server like this:
saceserver your_database_path your_port 3600:1
Note that clientT and serverT can take the special value zero which means the timeout is infinite, i.e. neither the client or server will ever be timed out. This special value is provided for testing and is specifically not recommended for normal use.
maximum request size
The meaning of the maximum request field is:
- maxReply
- If the reply to a client exceeds this threshold then the server "slices" the reply up and returns it a piece at a time. This prevents a single client from hogging the server.
Note that maxReply can take the special value zero which means that there is no maximum reply threshold and the server will return in one piece the entire reply. This special value is provided for circumstances where the user wants to get large replies back in one piece, you should note that other clients requests will not be processed while a large reply is being sent.
port numbers
IANA (Internet Assigned Numbers Authority) has set aside certain ranges of port numbers for certain uses:
Port No. range Usage -------------- ----- 0 - 1023 "well-known" ports, you need super user authority to use these and they are reserved for ftp, http, X windows and basic operating system services. DO NOT USE THESE. 1024 - 49151 "registered" ports, if you setting up the server to be run by inetd you should use one of these. But you will need to check in /etc/services that your number does not clash with one already there. 49152 - 65535 "dynamic" ports, are for dynamically assigned/ephemeral use. You should use one of these if you are just trying out the server from an xterm in the foreground.
Actually its all more confused than this, not all operating systems stick to the IANA recommendations, but it is generally true that you cannot use a port less then 1024 without root permission and you should not in general choose these ports.
You should also not choose a port larger than 65535. If you do, the port number may be truncated in a way that leaves it in the range 0 - 1023 which are reserved for superuser use for well-known services.
Typically you will see these sorts of errors if you choose a port that is either below 1024 or already in use (you may have to look in the database logfile to see the error if the server is inetd started):
typical server error: % saceserver /mydatabase 777 // Database directory: /data1/GrainGenes // #### Server starts 2000-04-03_11:29:49 // #### host=(unknown) port=777 ACEDB=/data1/GrainGenes // #### clientTimeout=600 serverTimeout=600 maxKbytes=0 autoSaveInterval=600 // FATAL ERROR (www on gn) reported by program aceserver (ACEDB 4_9c), in file a cesocket.c, at line 657: Cannot bind to server listening socket system error 13 - Permission denied // Sorry for the crash, please report it, if it is reproducible // NB: changes made since the last explicit save have NOT been saved typical client error: % saceclient localhost -port 777 FATAL ERROR (www on gn) reported by program saceclient (ACEDB 4_9c), in file ace socketlib.c, at line 269: connect error system error 146 - Connection refused
Running the Server
in the foreground
To run the server in the foreground, type the following at the prompt in an xterm:
saceserver <your/data/base> <your_port_number> <time_out_options>
If the server starts correctly your xterm will "hang" because the server will be sitting waiting for clients to connect. If something goes wrong acedb will print an error message and then exit. You should correct the error and then try again.
Once the server is starting correctly then try accessing it using the client:
saceclient <host_where_server_is_running> -port <port_number_from_above> acedb> status acedb> quit
If you can connect correctly then you are ready to try running the server under the control of one of the unix inetd or xinetd controller programs.
under inetd
You can now run saceserver against any existing acedb database and/or register it under inetd by adding lines to the following files (you will need root access):
For this example we assume:
nickname for server/database - MyfirstDB port for server - 20113 user owning database - mieg path to server binary - /usr/local/bin/saceserver path to database - /home/databases/aardvarkDB timeout values for server - 200:200:0In /etc/services add the line:
MyfirstDB 20113/tcp
in /etc/inetd.conf add the line
MyfirstDB stream tcp wait mieg /usr/local/bin/saceserver saceserver /home/databases/aardvarkDB 200:200:0
Where:
MyfirstDB seen in both files, a random name of your choice to name the database server stream tcp wait mandatory, this is the way the daemon must be declared mieg user name under which the daemon runs, avoid root, choose some local user owning /home/databases/aardvarkDB /usr/local/bin/saceserver full path to saceserver executable saceserver repeat the name of the execuatble so that it is found as argv[0] by the code /home/databases/aardvark the database directory 200:200:0 server and client time out in seconds, then a blocking factor (default zero is ok)
Now get inetd to reread /etc/inetd.conf and pick up the information for MyfirstDB (you will probably need to be root to do this):
- find out the process id of inetd
> ps -A | grep inetd 545 ?? I 0:00.62 /usr/sbin/inetd- Send inetd the interrupt signal
> kill -HUP 545Sending this signal should be enough but on some old systems a reboot may be necessary.
Then access the server by starting up a client:
saceclient <host_where_server_is_running> -port 20113
under xinetd
xinetd is an open source replacement for inetd, it provides many more features and much security than inetd, you can read more about it at the xinetd website.
Its configuration is a bit different from inetd and is as follows:
For this example we assume the following:
nickname for server/database - MyfirstDB port for server - 20113 user owning database - mieg path to server binary - /usr/local/bin/saceserver path to database - /home/databases/aardvarkDB timeout values for server - 200:200:0In /etc/services add the line:
MyfirstDB 20113/tcp
xinetd keeps its configuration files in the directory /etc/xinetd.d. Create a file in this directory giving it some meaningful name such as acedb and add the following lines:
# file: /etc/xinetd.d/acedb # default: on # description: wormbase acedb database service acedb { protocol = tcp socket_type = stream port = 20113 flags = REUSE wait = yes user = mieg group = mieg log_on_success += USERID DURATION log_on_failure += USERID HOST server = /usr/local/bin/saceserver server_args = /home/databases/aardvarkDB 200:200:0 }
Note that you will need to change the port, user, group, server and server_args fields for you setup.
Warning: In the past there have been a number of problems with the way xinetd worked which prevented users from running the acedb servers with xinetd. Currently the following combination of Linux, xinetd and acedb is known to work:
Linux: Red Hat Linux release 7.3 (Valhalla), kernal: 2.4.18-27.7.xbigmem
xinetd: xinetd-2.3.7-4.7x
acedb: 4_9m
If you find that you cannot get acedb working under xinetd control then you should first check that you have up to date software.
Running the client
Usage: saceclient <host> [-port pn] [-time_out] [-ace_out] [-ace_in] [-f file_name parms] host: is a machine where the server runs or is a registered service. pn: is the port number described in the server setup section. nn: is a number of seconds to wait to receive a server answer, it defaults to 300. -ace_out: implies a clean output: .ace files or clean tables -ace_in: if the input to the client is an ace file to be parsed by the server. -f filename: say for mailing, a command file which is echoed on stdout except that %1 %2 ... %9 will be macro substituted by the parms parameters and that the construction %(xxx) where xxx is a client command will be evaluated Introduction of MD5 password encryption based authentification for users
The sockets based version comes with a new password based system. The previous versions of the server used a file based system that while not requiring users to user passwords, did require that both client and server could "see" the directory where the "magic" files used by the server for authentification were stored. This has obvious problems when the client and server are separated by a firewall, are very remote from each other or either is running on a system that does not support shared file systems.
The new system uses passwords much like any Unix system does, users have their own unique userid and must supply a password to gain access to the database. Note that userids are 'global' to a database, e.g. if two users on different machines by chance have the same userid, they cannot both use that userid to gain access to the database, one or the other will have to use a different userid for the database. This is the same restriction as applies to Unix login ids.
The new system uses a "challenge-response" protocol: the client contacts the server, the server sends the client a key, the client must then encrypt their userid, password and the key and send it back to ther server. The server then encrypts its copy of the encrypted userid/password with the key and compares them with what its been sent. At no time does the password pass in plain text across the network, nor is it stored in plain text. Furthermore, they key is changed every time the user logs on, making it more difficult to crack the password. While not perfect this method offers at least as much (actually more) security than the Unix password system. This is also essentially the method of security used in the http protocol.
There is a new file,
wspec/serverpasswd.wrm
, which holds the userids and associated passwords and also which group a userid belongs to. There are three groups of users:
- read
- users who can get read access to the database
- write
- users who can get read/write access to the database
- admin
- users who can get read/write access to the database and run administrative commands on the database (e.g. add new users, shutdown the database etc.)
Entries in this file are of two sorts: group entries and userid entries, below is a sample
wspec/serverpasswd.wrm
showing both group and userid entries (as usual lines beginning with "//" are comments):// User groups // admin: edgrif write: simon read: jean richard sanger.ac.uk // users and passwords // edgrif 38a6557860893d95c7e738c0e5cd233d simon 7d61c0b3fb23c97f6970f07683a03649 jean 52af4f5526e16c855ca14a40287d1be1 richard 9dee3b01e9adeb11f8acac16fb368d76Initially an admin user must create a new entry for a user, complete with password (see admin user section), after this a user can change their own password using the
passwd
command from the saceclient:Only rudimentary password checking is done, it is up to users/administrators to ensure that good passwords are chosen.acedb> passwd enter new passwd: reenter new passwd: Introduction of domain name group authorisation and the NO_HOSTNAME_RESOLUTION option
The previous section described the format of entries in
wspec/serverpasswd.wrm
, the "read" and "write" group entries can also contain domain names:// User groups // admin: edgrif write: simon read: jean richard sanger.ac.ukThe "read" group entry contains the entry "sanger.ac.uk", this allows any user whose internet address ends with this sub-domain to log in with read access, e.g. johnsmith@linuxbox.sanger.ac.uk, janebrown@sanger.ac.uk etc. This makes it possible to give access to groups of people logging in from different sites. This only happens if the access level for a group is
PASSWD
and the userid of the connecting client cannot be found in the group.When a client connects, the server only has the numeric version of the clients internet address, since the lookup required to convert this to the text form can be both error prone and slow, it is possible to globally disable this lookup by setting the
NO_HOSTNAME_RESOLUTION
option inwspec/serverconfig.wrm
. If this option is set, the server will not attempt to resolve the text form of a clients internet address and match it to group name entries.Introduction of an "admin" class of user and a set of "admin" commands
The introduction of a password system made it necessary to introduce some extra commands to the command line interface: because users passwords are relatively long and must be copied into the password file correctly, this is only really feasible via a program. It also became clear that there should be a special class of user who would be allowed to run these commands and not just any user with write access as in previous servers.
Some "admin" commands already existed e.g. shutdown, these commands have been supplemented with additional commands including:
- shutdown [now] [norestart]
- Shuts down the server, by default this is when the last client quits but if the now option is specified, clients connections are terminated immediately and the server is shut down. If the norestart is specified then the server will not restart until the lock file
database/SERVER_SHUTDOWN_LOCKFILE.wrm
is removed.- who
- display how many clients are currently connected.
- data_version
- data served now, as stated in wspec/server.wrm
- wspec
- export wspec directory as a tar file
- user passwd|group|new|delete userid [password group]
- This command has several forms enabling an admin user to create/update/delete userids:
- Create: user new new_userid new_group (you will be prompted for the passwd)
- Delete: user delete userid
- Change group: user group userid new_group
- Change password: user passwd userid (you will be prompted for the passwd)
- global read|write none|passwd|world
- Change global read/write permissions for database
- domain group|new|delete domain-name [group]
- This command is similar to the user command but enables the admin user to create/update/delete domain names:
- Create: domain new new_domain new_group
- Delete: domain delete domain
- Change group: domain group domain new_group
Server Configuration Options
NO_RESTART (and the "phoenix" bug)
This option can be specified in
wspec/serverconfig.wrm
and will prevent the database from restarting after either a controlled shutdown or a server crash. If the option is specified then the server will leave a lockfile in thedatabase/
on shutdown or when it crashes (either in a trappable or non-trappable way). The name of the lockfile indicates whether the file was written as a result of a crash or a shutdown:For a crash that was detected by the acedb code: database/SERVER_CRASH_LOCKFILE.wrm for a crash that could not be detected by the acedb code: database/SERVER_UNDETECTABLECRASH_LOCKFILE.wrm and for a shutdown: database/SERVER_SHUTDOWN_LOCKFILE.wrmThe server cannot be restarted either manually or automatically by inetd until the lockfile is removed from the directory (the directory would normally be set up so that only admin users would have permission to do this).
Previous acedb servers have suffered from an irritating bug when run under the control of inetd. This bug (aka the "phoenix" bug) seemed to occur sometimes when the server crashed, the system would get into a loop with the server crashing, inetd respawning the server, the server crashing, inetd respawning the server, etc. etc. The advantage of the socket based server is that the greater degree of control over the port allowed debugging to show that this happens when a client has connected, but the server crashes before it has cleared the listening socket on which the client connected. In this case, inetd finds that there is still data on the listening socket and so it restarts the server which of course crashes again before clearing the listening socket. The new server has as part of its crash routine some code to clear the listening socket and thus put a stop to inetd trying to restart the server. Note however that this bug can still occur if the server crashes in an untrappable way, this loophole will be fixed at some time in the future.
READ/WRITE options for setting global access permissions to a database
The
READ
andWRITE
options can be specified inwspec/serverconfig.wrm
and allow 'global' control of the access level for all users in the read or write groups.Three levels of control are available:
- WORLD
- any user can have access, including users not specified in
wspec/serverpasswd.wrm
- PASSWD
- only users specified in
wspec/serverpasswd.wrm
can gain access (with a password)- NONE
- no users can have access
The access level is specified on the same line as the keywords
READ
orWRITE
, e.g. to give read access to everyone and write access to no one,wspec/serverconfig.wrm
should contain the lines:READ WORLD WRITE NONEAdmin group users always have write access to the database but this access is via a password.
READONLY_DATABASE option
Normally the server must have read/write access to at least some of the files and directories within an acedb database (e.g. for logging). This option allows the server to run on a database where it only has read permission for all directories and files within the database. This can be useful as extra level of security for a database which has been made available as a "read only" copy, perhaps to any user anywhere on the internet.
You should note that when this option is specified, the server will not do any logging of requests or crashes, so there will be no record of users interactions with the server.
DEBUG option
This option can be specified in
wspec/serverconfig.wrm
and will cause the server to send debugging output todatabase/server.log
, if the server is being run in the foreground then the output will also be sent to stderr. Currently this information is patchy but this release of the server includes the basic mechanism (setting up callback routines for the messout/messerror routines) for easy output of debugging messages which was missing in previous servers.
ACEDB Version 4_9
Ed Griffiths <edgrif@sanger.ac.uk> Last modified: Tue Apr 22 16:41:50 BST 2003