Admin Agent
Reinhard Erich Voglmaier
Many routine system tasks require an administrator with administrative-level privileges. For instance, administrative-level privileges may be required to start or stop a network service or to reconfigure a network printer. If an organization is not willing to delegate these system tasks to everyday users (and most organizations aren't), it is often necessary to provide some uniform, reliable means of passing requests to a qualified systems administrator.
In our enterprise, users send email requests for administrators to perform restricted system tasks. Typical requests are "Please update Business Graphics for the file MarketShare.data." or "Please put my new HTML pages into production." It recently occurred to me that we could save considerable time if we let a computer, rather than a human, field and execute routine administrative requests. In this article, I discuss the solution I have implemented at the Intranet Web site of GlaxoWellcome Italy. The source code of the application I describe is not included in this article. The program code is available for download at my company's Web site:
http://www.GlaxoWellcome.it/webmaster/Sysadmin
and from Sys Admin's Web site: www.sysadminmag.com.
I will demonstrate this idea of an email-based administrative agent using the example of my Webmaster, whose users request via email the execution of standard administration activities. This same application is also used on our network to let the Webmaster himself send requests to the systems administrator to start or stop the Web server.
The First Approach
I developed an application named AdminAgent to automate the task of executing routine system requests. AdminAgent is designed for intranet use only, and it is designed for data that is not considered confidential. (This was my first implementation, and I assumed that security was a little more relaxed -- more about security aspects later.) The requirements are:
Several applications should be executed by a number of authorized users,
All these applications run under the userid of the Web administrator.
The use of these applications should be as simple as possible, since users are not IT persons.
The very first implementation was written in the C language, using a Lex-generated parser to read the email. Then I tested the scripting language, Perl, and I found the programs much easier to write and maintain. Perl is shipped with a lot of pattern-matching utilities and a number of useful libraries. For example, I used the Mail libraries and the Tk interface to generate the administration GUI.
AdminAgent is easy to understand, implement, and maintain. AdminAgent does not require additional password and password management. It's based on standard tools, and it's easy to extend (for example, to match higher security requirements). AdminAgent was developed on Sun Solaris 2.7, but has been tested on HP-UX 11.00, HP-UX 10.20, and SuSE Linux 6.0. The syntax of the mail files is slightly different on these platforms, so the parser has been generalized; now it works on all three platforms. The application is based on standard tools, so it should run on every *NIX system.
The basic idea is that an agent process watches for email messages that use a standard format to request an administrative action. If the agent receives a request, it consults a database that defines which users are allowed to make the request and what should be done when the request is made. The agent then launches the scripts required to perform the administrative action.
The application consists of:
1. The database plus a Perl library. The database defines which users can make what requests and what action will be taken. The library defines the database access methods. There are no passwords contained in the database, because the application trusts the email system.
2. The agent process, which continues to read the email of the Web administrator for new mail and launches the desired application if necessary.
3. A number of short scripts to configure the database.
These three components are independent from each other, so they can be implemented, debugged, and tested separately.
The Database
AdminAgent uses the DBM database. DBM can be found on every UNIX system and exists in several flavors, all of them supported by the Perl language. DBM doesn't support the concept of tables and rows such as a RDBM like Oracle or Informix. What I refer to as a table corresponds to a DBM file (i.e., a database). Each of these DBM files consist of Key, Value pairs. The Key is the Primary Key; the Value Field contains the other Fields joined together, with colons as field separators. AdminAgent has no knowledge of the inner architecture of the database; it accesses the database via a set of methods.
Actually four tables are used:
MessageId Table
Authorization Table
Program Registry Table
Request Table
Upon receiving email, the agent looks at the subject field to understand if the message regards an application registered for handling. To determine this, the agent looks it up in the Request Table. In the Request Table, the agent finds the request that the user can make upon this application together with one optional parameter. Once the agent knows that it must handle the request, it looks up whether the sender is authorized to make the request and subsequently whether the request has just been handled. Since every email has a unique Message Identifier, this identifier can be used to determine whether the request has been elaborated. This is necessary since the messages are not deleted automatically. At this point is clear that the message mst be handled, that the user is authorized to make the request, and the action that must be taken. The agent gets the command to be executed from the Program Registry Table using the script id found reading the Requests Table.
For example, on the intranet Web server, we produce dynamically a .gif file based upon data available in a particular format. The message has the subject BusinessGraph (the application). In the body, there must be the request upon this application, update, and the parameter that says what exactly has to be updated. This is the data for the MarketShare.
So, the message reads:
From: user1
Subject: BusinessGraph
Message:
Dear Administrator
could You please update the MarketShare.data graphic.
Thanx a lot
Best Regards
User 1
As you can see only the words update and MarketShare.data are required, the rest of the message is ignored.
This is the database configuration that does the job:
Request Table:
Application Request Parameter (optional) ScriptID
BusinessGraph Update MarketShare.data 101
BusinessGraph Update DailySales.data 107
Program Registry Table:
RequestID Program
101 /usr/local/business/applications/perl/gen_gif MarketShare.data
107 /usr/local/business/applications/perl/gen_gif DailySales.data
Authorization Table:
UserId RequestID
user1 107:101
user2 101
The Library
The library is written in Perl and is included in all scripts that have access to the database. The database access routines are cleanly separated from the application code, allowing changes to the repository without modifying the application scripts. The library contains the following methods:
Database management
open_database (Mode) Mode=Write, ReadOnly
close_database()
reset_database()
dump_database()
Data management (separate procedure for each table):
AddElement
DeleteElement
ModifyElement
IterateTable
GetElement
GetIndices
The procedures provide basic functions to insert, update, modify, or delete elements. Actually these functions are different for each table for historical reasons. Because different checking is required for each table and at first the project was thought only to be a test, I did not bother about a clean design. This may change with the next release. Again, this will change only the database scripts, not the application. Some of administrative actions require the execution of two or three of these basic functions, so convenience functions have been added.
The Agent Process
The heart of the whole program is the agent process. This process is launched from crontab every five minutes to look at the mail that has arrived. The daemon process runs under the user-id of the Web administrator. It scans the mail file of the Web administrator for subject fields it must act upon. If it finds a subject handled by the Agent, it looks first in the database to see whether this request has just been handled, if so the request is skipped. If the request has not been handled, the process looks up in the database what requests are allowed for this subject and subsequently controls whether the sending user is allowed to make this request. If the process doesn't understand the request, because it doesn't find the correct actions, it complains with email to the sender. If the user is not allowed to make the request, the Web administrator is also informed.
If everything went fine until now, the agent looks in the database to see what program corresponds to this combination of subject, request, and parameters and runs the corresponding program. After the program is run with success, the agent writes in the database the program run, the completed request, the userid of the sender and the current date. Finished his action upon this message, the agent sends now a mail to the Web administrator and reads the next message. The mail is kept in the mail file; the agent itself does not cancel mail.
The Administration Tool
The basis for the database administration is the database library. It defines all functions necessary to insert, update, and query the data. Here is an example written in Perl that inserts a new request in the request table:
1 #!/usr/bin/perl -w
2
3 use AdminAgent;
4
5 $Mode = "Write";
6 &open_database($Mode) || & print_error();
7
8 $Command = "Update" ;
9 $Param = "MarketShare";
10 $Subject = "BusinessGraphs";
11 &add_Action($Subject,$Command,$Param) || &print_error();
12
13 &close_database();
This example shows how easy it is to maintain the database. This updates the table that maintains information about the request that can be made. To have a useful entry, we must supply other information, such as the user who is allowed to make the request and, most importantly, the script to be launched upon receiving this request. It is very easy to write scripts that provide the necessary information to the database. An example implementation is on the script directory of the Web site cited above.
Extending the First Approach
Administration Tool
It is not difficult to use the basic scripts to add users, add scripts, change user privileges, and so on. Nevertheless, after a while I got tired of using such archaic tools, so I decided to write an administration tool. Since I had no time to rewrite my scripts, the main goal was to reuse existing code. In the end, I reused it all. I wrote a main script that uses the ready to run scripts.
The effort of writing a line-oriented tool and writing a tool with a GUI is more or less the same using Perl. I just saved time in reusing the existing code, and in consequence I felt free to use the time saved to write a nice-looking application using the TK Perl library. The graphical interface and the control functions are well separated, so it's not difficult to add further functionality to these scripts.
The command-line administration tool is included with the other files at the download site; the graphical user interface is still in beta and will be included as soon as possible.
To demonstrate the ease of use, I give the following example written in Perl/Tk that generates the error message part of the graphical admin tool.
1 #!/usr/bin/perl
2
3 use Tk;
4
5 function ErrorMsg {
6 my ( ErrorMsg ) = @_ ;
7 $top = MainWindow->new();
8
9 $top->Message(-width=>"3c",
10 -justify => "center",
11 -text=>$text)->pack(-side=>"left");
12
13 MainLoop;
14 return 1;
15 }
Web-Enabling the Application
In these times, no one buys an application that cannot be run on the Web. First of all, it's a very intuitive graphical user interface that is widely accepted by the majority of the company's Intranet users. But apart from the simple "nice-looking" aspect, launching scripts from an HTML page offers the following advantages:
1. The syntax of the request is correct. We don't need to handle scripts with syntax errors.
2. User authentication and authorization can be handled just in the request phase.
An HTML form is written in a few minutes; the corresponding CGI script doesn't take much more time and is written in the same language (Perl). The authorization is delegated to the Web server. The maintenance of user authorization is just handled by the database routines. The result is that with very little effort, you have a lot of advantages, and again we can extend the application by not changing absolutely anything from the existing code. An example of how to do this is included in the download files.
Security Aspects
Basically, AdminAgent is only as secure as the email on the system it is installed on. To increase security, there are two aspects to deal with: documentation and authentication.
Documentation
The solution discussed here leaves the mail file intact, leaving no trace of what requests have been made from whom. On a user's email, the requested action is executed, and the request remains in the mailbox of the administrator for eventual documentation purposes.
Authentication
The script is (obviously) convinced that the sender of the request is the person whose email address appears in the from field. If we want to be really sure that the person who wrote the email is the person it claims to be we can use an approach normally used in mailing lists: Upon receiving a request, the request is mailed back to the sender, asking him for confirmation. One could even go a step further: together with the confirmation request, a password could be sent back. This password has an expiration time. If the sender of the request confirms within the expiration time, the request is executed. If she discards the confirmation request, the password expires and nothing is done. The implementation is as easy as the extension of the admin tool. It's one Perl function to be added. This function uses a new table of UserId, RequestId, Password, and Action to be executed. The hook of the function is put in at the point where the script has decided to handle the request. It looks up in the new table whether it's a confirmation of a request. If it is not, the agent handles it as a new request. If the password and user-id are verified, everything is okay, and the request is handled.
More Sophisticated Solutions
In the existing solution, crontab spawns a new process every five minutes. This has the advantage that every time the process springs to life, fresh process environment will be created and allocated fresh memory. At the death of this process, system resources are released. I believe that this is a good choice, because it guarantees clean memory management. Performance should not be an issue until requests become so frequent that the process creation time begins to have effect on the system.
Nevertheless, tests has been made in a client/server approach: a server process starts up and puts itself into sleep. This, however, requires a more sophisticated approach on the client side, too. There must be a process to send a signal to the daemon process. This process could be generated by Sendmail's forwarding mechanism. Furthermore, the forward should only work if the argument matches certain criteria. One of the most elegant solutions would be to use the Majordomo software. This powerful software can not only forward mail on a pattern matching-based decision system, but can also run scripts or programs. It is worthwhile to take into account for the next release of AdminAgent.
Conclusion
AdminAgent is a robust tool that executes administration scripts and programs on user requests. It permits all configuration for all applications to be delegated in one place. The email system gives a very affordable basis for AdminAgent. These user requests may be scripts, programs, or commands executed by the systems administrator (or some other person who doesn't like to make the password available or does not like to deal with setuid scripts).
The power of the solution presented here is in its simplicity. Simplicity increases security. It is intended as a solution for a company Intranet, so general security requirements are not very high -- in particular the fields in the email are trusted. The described security extensions, however, show how to make AdminAgent more secure, with the cost of an additional email from the requesting person. The system is easily and quickly extensible -- a requirement in the rapidly changing arena of Web applications.
About the Author
Reinhard Voglmaier studied physics at the University of Munich in Germany and graduated from Max Planck Institute for Astrophysics and Extraterrestrial Physics in Munich. After working in the IT department at the German University of the Army in the field of computer architecture, he was employed as a Specialist for Automation in Honeywell and then as a UNIX Systems Specialist for performance questions in database/network installations in Siemens Nixdorf. Currently, he is the Internet and Intranet Manager at GlaxoWellcome, Italy. He can be reached at: rv33100@GlaxoWellcome.co.uk. |