06/29/99

KIWI - Kerberos Interaction With Immediacy

  1. What it is
  2. Access and Security
  3. The Transaction Engine
  4. The Command Set
  5. Kiwi, the Client Utility
  6. The KIWI API
  7. Kiwid, the Server Process
  8. The Phase-In Process

What it is

Kiwi is a simple transaction server that accepts requests from authorized entities to create Kerberos principals and to change their passwords. The goal is to have multiple master KDCs that are all updated in real time so we can do load balancing between them. Standard secondary KDCs are updated by an offline process that could be hourly or worse.

The underlying mechanism is a general purpose, fault tolerant transaction engine. This is the same basic engine that is used to support our passwd file synchronization and email server aliasing.

Kiwi maintains a simple database of key-value pairs indicating the last password received for each principal. This database can be used to rebuild the Kerberos database if necessary. The database is backed up by the transaction logs that the transaction engine maintains. The transaction logs can be replayed at any time to rebuild the database.

Implementation of Kiwi will be phased in over several weeks. This phase-in process is described elsewhere

The name Kiwi is a logical follow-on to Tracy Stenvik's Mango server. Tracy was trying to come up with a clever name when he noticed his can of Koala Springs® Mango-Orange flavored soda on his desk. Their Kiwi-Lime flavor is my favorite.

Access and Security

Kiwi uses Jim Fox's Lightweight Secure Connection Library to control access to the database. Each client connecting to the Kiwi dæmon must specify a valid LSC key. LSC keys have a public portion and a private portion. The key names are in the form:

kiwiX_group_member

which encodes the following information:
X: Security level
The security level is a hexidecimal digit from 0 to F. Each bit in the security level allows certain functions:

0: Level zero is unprivileged and can only create new principals.
1: Bit 0x01 is required to fetch principal info.
2: Bit 0x02 is required to delete principals.
4: Bit 0x04 is required for admin functions including setting passwords.
8: Bit 0x08 is required to act as a kiwi server, receiving all the updates.
9: The slave servers all run at level 9.
F: The master servers all run at level 15.

The mango servers connect at level 7. They are permitted to change anyone's password. The actual policy of who can change what password is implemented in the mango servers.

group
The group is an arbitrary character string (eg: UCS, NDC, etc).

member
The member is an arbitrary character string, but for practical purposes should be the host name of the computer owning the key.
The public keys for the servers need to be distributed to each of the servers. There's a script, newkey.sh in the installation materials that will create a new private and public key and update the global file that gets installed everywhere. This script can be used when adding a new host to the list of server hosts.

The Transaction Engine

The Kiwi servers use the same transaction engine as the pwsync and deskmail servers. The Kiwi server on each of the KDC hosts act as peers. Any one of them could be the master and the rest act as chiefs. If the master server goes down for whatever reason one of the chiefs will take over as master. Other servers act as slaves, just receiving password updates to apply to their own database (eg: an NT domain controller).

The Command Set

The set of commands supported by the server are:
Create name value
The Create command checks for the specified principal name in the Kiwi database. If it does not exist, the command processing proceeds as in the Set command below. If the principal is already in the database, an "Already exists" error is returned.

Delete name
The Delete command deletes a name-value pair from the Kiwi database and the local Kerberos KDC. Deleting a nonexistant name is not an error and simply does nothing.

Get name
The Get command retrieves a value from the Kiwi database for the given name. If the name is not in the database an error is returned. If requested with level 7 or higher authority, the value returned will include the encrypted password associated with the principal. This encrypted password can be used to set the same password on another principal or, if the encrypting pass phrase is known, be decrypted to a plain text password for installing in another database (eg: an NT domain controller).

Newkey file value
The Newkey command adds the public key for a new client to the list of clients that the servers know about. The file parameter has to be the string "pub_keys" for now. The value field is simply the text from the pub_keys file as created by the lsc_keygen utility.

Set name value
Stores the specified value in the Kiwi database and sets the Kerberos password if required. The value field consists of several colon-delimited single character keywords and values. The keywords are:

D: The date of the transaction. The date is a simple %d encoding of the time_t data type.
P: The plain text password in a simple 3-bytes-in-4-characters encoding. This encoding is similar to BASE64, but unique to the Kiwi protocol.
E: The password encrypted with a reversable private key and then encoded with the 3-in-4 encoding as above.
W: The source of the updating entity (the lsc key name for the Kiwi client process).

If the password is changing, the master Kiwi server first updates the local Kerberos KDC. If that update succeeds then the transaction is assigned a sequence number and is passed on to the subordinant servers. Updating the KDC is the only way to determine whether the given password update is legitimate (eg: it might fail due to being too short for the principal's policy settings. The Kiwi database only reflects the successful updates.

KIWI command [parameters]
The above commands are all database specific. The generic commands prefixed by the KIWI keyword are passed to the transaction engine for processing. These commands are described elsewhere.

Kiwi, the Client Utility

A simple utility exists to pass commands to the Kiwi servers. The general usage is:

kiwi -c 'command'

The specified command is sent to the master server. If no -c option is specified or a single dash is specified for the command, all lines on stdin are processed as separate commands until there is an error, end of file or an end/exit/quit command is encountered.

The kiwi utility is used to enter new keys (with the Newkey command), other maintenance activities such as checkpoints and checksums and general debugging. It is not intended to be used for resetting passwords as all passwords are encoded in a pretty unreadable format.

The Kiwi API

Communication with the Kiwi servers is accomplished through the Kiwi Application Programming Interface. This library is based on the standard transaction engine API. The Kiwi specific routines are:
extern char *kiwi_errmsg;
extern int  kiwi_errno;

int  kiwi_init(char *dir);

int  kiwi_setpw(char *name, char *password);
int  kiwi_addpw(char *name, char *password);

General Basics

The normal sequence is to call kiwi_init with a null parameter to things set up. This initializes the various global variables and reads the configuration file, /usr/local/lib/kiwi/conf, which defines the host and tcp/udp port and ordinal for the KIWI servers.

Once initialized, the kiwi_setpw and kiwi_addpw routines can be called to create new principals and set their passwords. The reply from these routines will indicate success or failure:

KIWI_RETRY-2Didn't work, but may later
KIWI_ERROR-1Unsuccessful return value
KIWI_OKAY0Successful return value
KIWI_MORE1More data available

In addition, the kiwi_errno variable will contain an extended error status as defined by the KIWI_E_xxx constants in the kiwi.h include file and kiwi_errmsg will point to a suitable message to be displayed as part of an error message as well as any response from the server. Note that these two global variables (and others) indicate that the KIWI API is not officially "thread safe". Only one thread, normally the main thread, should be making calls to the KIWI library.

Kiwid, the Server Process

The kiwid dæmon process runs on each of the master, chief and slave server systems. Kiwid updates its own database and passes any update commands to a child process that updates the local database, whatever that may be. Normally the master and chief kiwid process are expected to run on the Kerberos servers. Slave servers will run on the auxiliary systems that also need the plain text passwords such as the pwsync updater, an NT domain controller, etc. The kiwid process will invoke an appropriate child process depending on the database that needs to be maintained. The default child process is kiwi_k5 that updates a Kerberos KDC. The build for this child process is found in the /tulsa/src/kiwid/KRB5 directory. The child that updates the pwsync database is found in /tulsa/src/kiwid/PWSYNC. Each of these uses the same main module /tulsa/src/kiwid/kiwi_child.c with a custom version of the uwk.c module. The -t flag on the kiwid command line specifies which child module should be used.

To install a new slave server, one would perform the following steps:

  1. Update the /tulsa/src/kiwid/kiwid.ini file to set the appropriate TFLAG value for your server host (and do a make pending).

  2. Create a child subdirectory of /tulsa/src/kiwid containing its own version of the uwk.c module if necessary. A make pending should be run for the appropriate architecture for the kiwi, kiwid and kiwid/CHILD products.

  3. The kiwi, kiwid and kiwid-child products should be installed on the target server.

  4. Create a new server key for the client host that will be running this child. This can probably be done on melville with:

    /tulsa/src/kiwi/newkey.sh -l 9 [-g group] host

    If the server is going to be a new chief server, the -S option should be included on that command and the level should be elevated to hexidecimal F. A tulsa_prodinst or tulsa_weekly will have to be run on all clients and servers and all clients and servers will have to be restarted before the new chief can become master, so don't do this on a whim.

  5. Run the rebuild script to build the database on the new client. This can probably be done on melville with:

    /tulsa/src/kiwid/rebuild.sh host

    The rebuild script will copy all the squirrelled passwords and the key to decrypt them to the remote system so make sure the system you run this on is secure. After the reload, the squirrelled passwords will be deleted unless it's a chief server that's being rebuilt.

Ken Lowe
Email --
ken@u.washington.edu
Web -- http://staff.washington.edu/krl/