Next: , Previous: Examples, Up: Programming Manual


5.19 Kerberos Database Functions

Shisa is a separate and standalone library from Shishi (see Introduction to Shisa). If you only wish to manipulate the information stored in the Kerberos user database used by Shishi, you do not need to link or use the Shishi library at all. However, you may find it useful to combine the two libraries.

For two real world examples on using the Shisa library, refer to src/shisa.c (Shisa command line tool) and src/kdc.c (part of Shishid server).

Shisa uses two ‘struct’s to carry information. The first, Shisa_principal, is used to hold information about principals. The struct does not contain pointers to strings etc, so the library assumes the caller is responsible for allocating and deallocating the struct itself. Each such struct is (uniquely) identified by the combination of principal name and realm name.

     struct Shisa_principal
     {
       int isdisabled;
       uint32_t kvno;
       time_t notusedbefore;
       time_t lastinitialtgt;      /* time of last initial request for a TGT */
       time_t lastinitialrequest;  /* time of last initial request */
       time_t lasttgt;             /* time of issue for the newest TGT used */
       time_t lastrenewal;         /* time of the last renewal */
       time_t passwordexpire;      /* time when the password will expire */
       time_t accountexpire;       /* time when the account will expire. */
     };
     typedef struct Shisa_principal Shisa_principal;

The second structure is called Shisa_key and hold information about cryptographic keys. Because the struct contain pointers, and the caller cannot know how many keys a principal have, the Shisa library manages memory for the struct. The library allocate the structs, and the pointers within them. The caller may deallocate them, but it is recommended to use shisa_key_free or shisa_keys_free instead. Note that each principal may have multiple keys.

     struct Shisa_key
     {
       uint32_t kvno;
       int32_t etype;
       int priority;
       char *key;
       size_t keylen;
       char *salt;
       size_t saltlen;
       char *str2keyparam;
       size_t str2keyparamlen;
       char *password;
     };
     typedef struct Shisa_key Shisa_key;

Shisa is typically initialized by calling shisa_init, and deinitialized (when the application no longer need to use Shisa, typically when it shuts down) by calling shisa_done, but here are the complete (de)initialization interface functions.

shisa

— Function: Shisa * shisa ( void)

Initializes the Shisa library. If this function fails, it may print diagnostic errors to stderr.

Return value: Returns Shisa library handle, or NULL on error.

shisa_done

— Function: void shisa_done (Shisa * dbh)

Deallocates the shisa library handle. The handle must not be used in any calls to shisa functions after this.

shisa_init

— Function: int shisa_init (Shisa ** dbh)

dbh: pointer to library handle to be created.

Create a Shisa library handle, using shisa(), and read the system configuration file from their default locations. The paths to the default system configuration file is decided at compile time ($sysconfdir/shisa.conf).

The handle is allocated regardless of return values, except for SHISA_INIT_ERROR which indicates a problem allocating the handle. (The other error conditions comes from reading the files.)

Return value: Returns SHISA_OK iff successful.

shisa_init_with_paths

— Function: int shisa_init_with_paths (Shisa ** dbh, const char * file)

dbh: pointer to library handle to be created.

file: Filename of system configuration, or NULL.

Create a Shisa library handle, using shisa(), and read the system configuration file indicated location (or the default location, if NULL). The paths to the default system configuration file is decided at compile time ($sysconfdir/shisa.conf).

The handle is allocated regardless of return values, except for SHISA_INIT_ERROR which indicates a problem allocating the handle. (The other error conditions comes from reading the files.)

Return value: Returns SHISA_OK iff successful.

The default configuration file is typically read automatically by calling shisa_init, but if you wish to manually access the Shisa configuration file functions, here is the complete interface.

shisa_cfg_db

— Function: int shisa_cfg_db (Shisa * dbh, const char * value)

dbh: Shisa library handle created by shisa().

value: string with database definition.

Setup and open a new database. The syntax of the value parameter is "TYPE[ LOCATION[ PARAMETER]]", where TYPE is one of the supported database types (e.g., "file") and LOCATION and PARAMETER are optional strings passed to the database during initialization. Neither TYPE nor LOCATION can contain " " (SPC), but PARAMETER may.

Return Value: Returns SHISA_OK if database was parsed and open successfully.

shisa_cfg

— Function: int shisa_cfg (Shisa * dbh, const char * option)

dbh: Shisa library handle created by shisa().

option: string with shisa library option.

Configure shisa library with given option.

Return Value: Returns SHISA_OK if option was valid.

shisa_cfg_from_file

— Function: int shisa_cfg_from_file (Shisa * dbh, const char * cfg)

dbh: Shisa library handle created by shisa().

cfg: filename to read configuration from.

Configure shisa library using configuration file.

Return Value: Returns SHISA_OK iff successful.

shisa_cfg_default_systemfile

— Function: const char * shisa_cfg_default_systemfile (Shisa * dbh)

dbh: Shisa library handle created by shisa().

Return value: Return system configuration filename.

The core part of the Shisa interface follows. The typical procedure is to use shisa_principal_find to verify that a specific principal exists, and to extract some information about it, and then use shisa_keys_find to get the cryptographic keys for the principal, usually suppliying some hints as to which of all keys you are interested in (e.g., key version number and encryption algorithm number).

shisa_enumerate_realms

— Function: int shisa_enumerate_realms (Shisa * dbh, char *** realms, size_t * nrealms)

dbh: Shisa library handle created by shisa().

realms: Pointer to newly allocated array of newly allocated zero-terminated UTF-8 strings indicating name of realm.

nrealms: Pointer to number indicating number of allocated realm strings.

Extract a list of all realm names in backend, as zero-terminated UTF-8 strings. The caller must deallocate the strings.

Return value: Returns SHISA_OK on success, or error code.

shisa_enumerate_principals

— Function: int shisa_enumerate_principals (Shisa * dbh, const char * realm, char *** principals, size_t * nprincipals)

dbh: Shisa library handle created by shisa().

realm: Name of realm, as zero-terminated UTF-8 string.

nprincipals: Pointer to number indicating number of allocated realm strings.

Extract a list of all principal names in realm in backend, as zero-terminated UTF-8 strings. The caller must deallocate the strings.

Return value: Returns SHISA_OK on success, SHISA_NO_REALM if the specified realm does not exist, or error code.

shisa_principal_find

— Function: int shisa_principal_find (Shisa * dbh, const char * realm, const char * principal, Shisa_principal * ph)

dbh: Shisa library handle created by shisa().

realm: Name of realm the principal belongs in.

principal: Name of principal to get information on.

ph: Pointer to previously allocated principal structure to fill out with information about principal.

Extract information about given PRINCIPALREALM.

Return value: Returns SHISA_OK iff successful, SHISA_NO_REALM if the indicated realm does not exist, SHISA_NO_PRINCIPAL if the indicated principal does not exist, or an error code.

shisa_principal_update

— Function: int shisa_principal_update (Shisa * dbh, const char * realm, const char * principal, const Shisa_principal * ph)

dbh: Shisa library handle created by shisa().

realm: Name of realm the principal belongs in.

principal: Name of principal to get information on.

ph: Pointer to principal structure with information to store in database.

Modify information stored for given PRINCIPALREALM. Note that it is usually a good idea to only set the fields in ph that you actually want to update. Specifically, first calling shisa_principal_find() to get the current information, then modifying one field, and calling shisa_principal_update() is not recommended in general, as this will 1) overwrite any modifications made to other fields between the two calls (by other processes) and 2) will cause all values to be written again, which may generate more overhead.

Return value: Returns SHISA_OK if successful, SHISA_NO_REALM if the indicated realm does not exist, SHISA_NO_PRINCIPAL if the indicated principal does not exist, or an error code.

shisa_principal_add

— Function: int shisa_principal_add (Shisa * dbh, const char * realm, const char * principal, const Shisa_principal * ph, const Shisa_key * key)

dbh: Shisa library handle created by shisa().

realm: Name of realm the principal belongs in.

principal: Name of principal to add, may be NULL to indicate that the realm should be created, in which case ph and key are not used.

ph: Pointer to principal structure with information to store in database.

key: Pointer to key structure with information to store in database.

Add given information to database as PRINCIPALREALM.

Return value: Returns SHISA_OK iff successfully added, or an error code.

shisa_principal_remove

— Function: int shisa_principal_remove (Shisa * dbh, const char * realm, const char * principal)

dbh: Shisa library handle created by shisa().

realm: Name of realm the principal belongs in.

principal: Name of principal to remove, may be NULL to indicate that the realm itself should be removed (requires that the realm to be empty).

Remove all information stored in the database for given PRINCIPALREALM.

Return value: Returns SHISA_OK if successful, or an error code.

shisa_keys_find

— Function: int shisa_keys_find (Shisa * dbh, const char * realm, const char * principal, const Shisa_key * hint, Shisa_key *** keys, size_t * nkeys)

dbh: Shisa library handle created by shisa().

realm: Name of realm the principal belongs in.

principal: Name of principal to add key for.

hint: Pointer to Shisa key structure with hints on matching the key to modify, may be NULL to match all keys.

keys: pointer to newly allocated array with Shisa key structures.

nkeys: pointer to number of newly allocated Shisa key structures in keys.

Iterate through keys for given PRINCIPALREALM and extract any keys that match hint. Not all elements of hint need to be filled out, only use the fields you are interested in. For example, if you want to extract all keys with an etype of 3 (DES-CBC-MD5), set the key->etype field to 3, and set all other fields to 0.

Return value: Returns SHISA_OK iff successful, or an error code.

shisa_key_add

— Function: int shisa_key_add (Shisa * dbh, const char * realm, const char * principal, const Shisa_key * key)

dbh: Shisa library handle created by shisa().

realm: Name of realm the principal belongs in.

principal: Name of principal to add key for.

key: Pointer to Shisa key structure with key to add.

Add key to database for given PRINCIPALREALM.

Return value: Returns SHISA_OK iff successful, or an error code.

shisa_key_update

— Function: int shisa_key_update (Shisa * dbh, const char * realm, const char * principal, const Shisa_key * oldkey, const Shisa_key * newkey)

dbh: Shisa library handle created by shisa().

realm: Name of realm the principal belongs in.

principal: Name of principal to remove key for.

oldkey: Pointer to Shisa key structure with hints on matching the key to modify.

newkey: Pointer to Shisa key structure with new values for the key, note that all fields are used (and not just the ones specified by oldkey).

Modify data about a key in the database, for the given PRINCIPALREALM. First the oldkey is used to locate the key to update (similar to shisa_keys_find()), then that key is modified to contain whatever information is stored in newkey. Not all elements of oldkey need to be filled out, only enough as to identify the key uniquely. For example, if you want to modify the information stored for the only key with an etype of 3 (DES-CBC-MD5), set the key->etype field to 3, and set all other fields to 0.

Return value: Returns SHISA_OK on success, SHISA_NO_KEY if no key could be identified, and SHISA_MULTIPLE_KEY_MATCH if more than one key matched the given criteria, or an error code.

shisa_key_remove

— Function: int shisa_key_remove (Shisa * dbh, const char * realm, const char * principal, const Shisa_key * key)

dbh: Shisa library handle created by shisa().

realm: Name of realm the principal belongs in.

principal: Name of principal to remove key for.

key: Pointer to Shisa key structure with hints on matching the key to remove.

Remove a key, matching the hints in key, from the Shisa database for the user PRINCIPALREALM. Not all elements of key need to be filled out, only those you are interested in. For example, if you want to remove the only key with an etype of 3 (DES-CBC-MD5), set the key->etype field to 3, and set all other fields to 0.

Return value: Returns SHISA_OK on success, SHISA_NO_KEY if no key could be identified, and SHISA_MULTIPLE_KEY_MATCH if more than one key matched the given criteria, or an error code.

shisa_key_free

— Function: void shisa_key_free (Shisa * dbh, Shisa_key * key)

dbh: Shisa library handle created by shisa().

key: Pointer to Shisa key structure to deallocate.

Deallocate the fields of a Shisa key structure, and the structure itself.

shisa_keys_free

— Function: void shisa_keys_free (Shisa * dbh, Shisa_key ** keys, size_t nkeys)

dbh: Shisa library handle created by shisa().

keys: Pointer to array with nkeys elements of keys.

nkeys: Number of key elements in keys array.

Deallocate each element of an array with Shisa database keys, using shisa_key_free().

Error handling is similar to that for Shishi in general (see Error Handling), i.e., you invoke shisa_strerror on the integer return value received by some function, if the return value is non-zero. Below is the complete interface.

shisa_strerror

— Function: const char * shisa_strerror (int err)

err: shisa error code

Return value: Returns a pointer to a statically allocated string containing a description of the error with the error value err. This string can be used to output a diagnostic message to the user.

shisa_info

— Function: void shisa_info (Shisa * dbh, const char * format, ...)

dbh: Shisa library handle created by shisa().

format: printf style format string. ...: print style arguments.

Print informational message to standard error.