From: Greg Hudson Date: Mon, 25 Jan 2010 04:12:21 +0000 (+0000) Subject: Document the DAL interface in comments, as an aid to module X-Git-Tag: krb5-1.9-beta1~375 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=1a9745b4696f800266a575f0b6676e3ec6953755;p=krb5.git Document the DAL interface in comments, as an aid to module implementors. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@23666 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/include/kdb.h b/src/include/kdb.h index 8c6f53265..9d8860698 100644 --- a/src/include/kdb.h +++ b/src/include/kdb.h @@ -719,197 +719,559 @@ krb5_dbe_free_tl_data(krb5_context, krb5_tl_data *); #define KRB5_KDB_OPT_SET_DB_NAME 0 #define KRB5_KDB_OPT_SET_LOCK_MODE 1 +/* + * A krb5_context can hold one database object. Modules should use + * context->dal_handle->db_context to store state associated with the database + * object. + * + * Some module functions are mandatory for KDC operation; others are optional + * or apply only to administrative operations. If a function is optional, a + * module can leave the function pointer as NULL. Alternatively, modules can + * return KRB5_KDB_DBTYPE_NOSUP when asked to perform an inapplicable action. + * + * Some module functions have default implementations which will call back into + * the vtable interface. Leave these functions as NULL to use the default + * implementations. + * + * The documentation in these comments describes the DAL as it is currently + * implemented and used, not as it should be. So if anything seems off, that + * probably means the current state of things is off. + */ + typedef struct _kdb_vftabl { short int maj_ver; short int min_ver; - krb5_error_code (*init_library)(); - krb5_error_code (*fini_library)(); - krb5_error_code (*init_module) ( krb5_context kcontext, - char * conf_section, - char ** db_args, - int mode ); - - krb5_error_code (*fini_module) ( krb5_context kcontext ); - - krb5_error_code (*db_create) ( krb5_context kcontext, - char * conf_section, - char ** db_args ); - - krb5_error_code (*db_destroy) ( krb5_context kcontext, - char *conf_section, - char ** db_args ); - - krb5_error_code (*db_get_age) ( krb5_context kcontext, - char *db_name, - time_t *age ); - - krb5_error_code (*db_set_option) ( krb5_context kcontext, - int option, - void *value ); - - krb5_error_code (*db_lock) ( krb5_context kcontext, - int mode ); - - krb5_error_code (*db_unlock) ( krb5_context kcontext); - - krb5_error_code (*db_get_principal) ( krb5_context kcontext, - krb5_const_principal search_for, - unsigned int flags, - krb5_db_entry *entries, - int *nentries, - krb5_boolean *more ); - - krb5_error_code (*db_free_principal) ( krb5_context kcontext, - krb5_db_entry *entry, - int count ); - - krb5_error_code (*db_put_principal) ( krb5_context kcontext, - krb5_db_entry *entries, - int *nentries, - char **db_args); - - krb5_error_code (*db_delete_principal) ( krb5_context kcontext, - krb5_const_principal search_for, - int *nentries ); - - krb5_error_code (*db_iterate) ( krb5_context kcontext, - char *match_entry, - int (*func) (krb5_pointer, krb5_db_entry *), - krb5_pointer func_arg ); - - krb5_error_code (*db_create_policy) ( krb5_context kcontext, - osa_policy_ent_t policy ); - - krb5_error_code (*db_get_policy) ( krb5_context kcontext, - char *name, - osa_policy_ent_t *policy, - int *cnt); - - krb5_error_code (*db_put_policy) ( krb5_context kcontext, - osa_policy_ent_t policy ); - - krb5_error_code (*db_iter_policy) ( krb5_context kcontext, - char *match_entry, - osa_adb_iter_policy_func func, - void *data ); - - - krb5_error_code (*db_delete_policy) ( krb5_context kcontext, - char *policy ); + /* + * Mandatory: Invoked after the module library is loaded, when the first DB + * using the module is opened, across all contexts. + */ + krb5_error_code (*init_library)(void); + + /* + * Mandatory: Invoked before the module library is unloaded, after the last + * DB using the module is closed, across all contexts. + */ + krb5_error_code (*fini_library)(void); + + /* + * Mandatory: Initialize a database object. Profile settings should be + * read from conf_section inside KDB_MODULE_SECTION. db_args communicates + * command-line arguments for module-specific flags. mode will be one of + * KRB5_KDB_OPEN_{RW,RO} or'd with one of + * KRB5_KDB_SRV_TYPE_{KDC,ADMIN,PASSWD,OTHER}. + * + * A db_args value of "temporary" is generated programattically by + * kdb5_util load. If this db_args value is present, the module should + * open a side copy of the database suitable for loading in a propagation + * from master to slave. This side copy will later be promoted with + * promote_db, allowing complete updates of the DB with no loss in read + * availability. If the module cannot comply with this architecture, it + * should return an error. + */ + krb5_error_code (*init_module)(krb5_context kcontext, char *conf_section, + char **db_args, int mode); + + /* + * Mandatory: Finalize the database object contained in a context. Free + * any state contained in the db_context pointer and null it out. + */ + krb5_error_code (*fini_module)(krb5_context kcontext); + + /* + * Optional: Create, but do not open, a database. conf_section and db_args + * have the same meaning as in init_module. This function may return an + * error if the database already exists. Used by kdb5_util create. + */ + krb5_error_code (*db_create)(krb5_context kcontext, char *conf_section, + char **db_args); + + /* + * Optional: Destroy a database. conf_section and db_args have the same + * meaning as in init_module. Used by kdb5_util destroy. In current + * usage, the database is destroyed while open, so the module should handle + * that. + */ + krb5_error_code (*db_destroy)(krb5_context kcontext, char *conf_section, + char **db_args); + + /* + * Optional: Set *age to the last modification time of the database. Used + * by the KDC lookaside cache to ensure that lookaside entries are not used + * if the database has changed since the entry was recorded. + * + * If this function is unimplemented, lookaside cache entries will + * effectively expire immediately. Another option is to supply the current + * time, which will cause lookaside cache entries to last for one second. + */ + krb5_error_code (*db_get_age)(krb5_context kcontext, char *db_name, + time_t *age); + + /* + * Optional: Set a database option. This function is not currently used by + * any callers. Behavior depends on the value of option: + * + * KRB5_KDB_OPT_SET_DB_NAME: Interpret value as a C string. Set the + * database name (e.g. a filename for an embedded database). + * + * KRB5_KDB_OPT_SET_LOCK_MODE: Interpret value as a pointer to + * krb5_boolean. If *value points to TRUE, set the database to + * non-blocking lock mode, causing operations to return OSA_ADB_CANTLOCK_DB + * when it would otherwise wait to obtain a lock. Set *value to the old + * value of the non-blocking flag. + */ + krb5_error_code (*db_set_option)(krb5_context kcontext, int option, + void *value); + + /* + * Optional: Lock the database, with semantics depending on the mode + * argument: + * + * KRB5_DB_LOCKMODE_SHARED: Lock may coexist with other shared locks. + * KRB5_DB_LOCKMODE_EXCLUSIVE: Lock may not coexist with other locks. + * KRB5_DB_LOCKMODE_PERMANENT: Exclusive lock surviving process exit. + * (KRB5_DB_LOCKMODE_DONTBLOCK is unused and unimplemented.) + * + * Used by the "kadmin lock" command, incremental propagation, and + * kdb5_util dump. Incremental propagation support requires shared locks + * to operate. kdb5_util dump will work if the module returns + * KRB5_PLUGIN_OP_NOTSUPP; note that this is *not* the usual "operation + * not supported" error code. + */ + krb5_error_code (*db_lock)(krb5_context kcontext, int mode); + + /* Optional: Release a lock created with db_lock. */ + krb5_error_code (*db_unlock)(krb5_context kcontext); + + /* + * Mandatory: Fill in *entries with the entry for the principal search_for. + * The module must allocate each entry field separately, as callers may + * free individual fields using db_free. If the principal is not found, + * set *nentries to 0 and return success. The meaning of flags are as + * follows: + * + * KRB5_KDB_FLAG_CANONICALIZE: Indicates that a KDC client requested name + * canonicalization. The module may return an out-of-realm referral by + * filling in an out-of-realm principal name in entries->princ and null + * values elsewhere. The module may return an in-realm alias by + * filling in an in-realm principal name in entries->princ other than + * the one requested. + * + * KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY: Set by the KDC when looking up the + * client entry in an AS request. Indicates that the module should + * return out-of-realm referral information in lieu of cross-realm TGT + * information. + * + * KRB5_KDB_FLAG_MAP_PRINCIPALS: Set by the KDC when looking up the client + * entry during TGS requests, except for S4U TGS requests and requests + * where the server entry has the KRB5_KDB_NO_AUTH_DATA_REQUIRED + * attribute. Indicates that the module should map cross-realm + * principals if it is capable of doing so. + * + * KRB5_KDB_FLAG_PROTOCOL_TRANSITION: Set by the KDC when looking up the + * client entry during an S4U2Self TGS request. No special behavior is + * needed. + * + * KRB5_KDB_FLAG_CONSTRAINED_DELEGATION: Set by the KDC when looking up the + * client entry during an S4U2Proxy TGS request. No special behavior + * is needed. + * + * KRB5_KDB_FLAG_CROSS_REALM: Set by the KDC when looking up a client entry + * during a TGS request, if the client principal is not part of the + * realm being served. + * + * The nentries and more arguments appear to be intended to account for + * multiple entries for a principal, but this functionality is neither + * implemented nor used. *nentries is set to 1 by all callers and should + * be set to 0 or 1 on return; the module should always set *more to FALSE. + * Callers will typically error out if modules behave otherwise. + */ + krb5_error_code (*db_get_principal)(krb5_context kcontext, + krb5_const_principal search_for, + unsigned int flags, + krb5_db_entry *entries, int *nentries, + krb5_boolean *more); + + /* + * Mandatory: Free the memory associated with principal entries. Do not + * free entry itself. All callers ignore the return value. Entries may + * have been constructed by the caller (using the db_alloc function to + * allocate associated memory); thus, a plugin must allocate each field + * of a principal entry separately. + */ + krb5_error_code (*db_free_principal)(krb5_context kcontext, + krb5_db_entry *entry, int count); + + /* + * Optional: Create or modify one or more principal entries. All callers + * operate on a single entry. db_args communicates command-line arguments + * for module-specific flags. + * + * The mask field of an entry indicates the changed fields. Mask values + * are defined in kadmin's admin.h header. If KADM5_PRINCIPAL is set in + * the mask, the entry is new; otherwise it already exists. All fields of + * an entry are expected to contain correct values, regardless of whether + * they are specified in the mask, so it is acceptable for a module to + * ignore the mask and update the entire entry. + */ + krb5_error_code (*db_put_principal)(krb5_context kcontext, + krb5_db_entry *entries, int *nentries, + char **db_args); + + /* + * Optional: Delete the entry for the principal search_for. If the + * principal does not exist, set *nentries to 0 and return success; if it + * did exist, set *nentries to 1. + */ + krb5_error_code (*db_delete_principal)(krb5_context kcontext, + krb5_const_principal search_for, + int *nentries); + + /* + * Optional: For each principal entry in the database, invoke func with the + * argments func_arg and the entry data. If match_entry is specified, the + * module may narrow the iteration to principal names matching that regular + * expression; a module may alternatively ignore match_entry. + */ + krb5_error_code (*db_iterate)(krb5_context kcontext, + char *match_entry, + int (*func)(krb5_pointer, krb5_db_entry *), + krb5_pointer func_arg); + + /* + * Optional: Create a password policy entry. Return an error if the policy + * already exists. + */ + krb5_error_code (*db_create_policy)(krb5_context kcontext, + osa_policy_ent_t policy); + + /* + * Optional: If a password policy entry exists with the name name, allocate + * a policy entry in *policy, fill it in with the policy information, and + * set *cnt to 1. If the entry does not exist, set *cnt to 0 and return + * success, or return an error (existing module implementations are not + * consistent). + */ + krb5_error_code (*db_get_policy)(krb5_context kcontext, char *name, + osa_policy_ent_t *policy, int *cnt); + + /* + * Optional: Modify an existing password policy entry to match the values + * in policy. Return an error if the policy does not already exist. + */ + krb5_error_code (*db_put_policy)(krb5_context kcontext, + osa_policy_ent_t policy); + + /* + * Optional: For each password policy entry in the database, invoke func + * with the argments data and the entry data. If match_entry is specified, + * the module may narrow the iteration to policy names matching that + * regular expression; a module may alternatively ignore match_entry. + */ + krb5_error_code (*db_iter_policy)(krb5_context kcontext, char *match_entry, + osa_adb_iter_policy_func func, + void *data); + + /* + * Optional: Delete the password policy entry with the name policy. Return + * an error if the entry does not exist. + */ + krb5_error_code (*db_delete_policy)(krb5_context kcontext, char *policy); + + /* Optional: Free a policy entry returned by db_get_policy. */ + void (*db_free_policy)(krb5_context kcontext, osa_policy_ent_t val); + + /* + * Optional: Fill in *realms with an array of realm names. This function + * is not used or implemented. + */ + krb5_error_code (*db_supported_realms)(krb5_context kcontext, + char **realms); + + /* Optional: Free a realm list returned by db_supported_realms. */ + krb5_error_code (*db_free_supported_realms)(krb5_context kcontext, + char **realms); + + /* + * Optional: Convert an error code returned by a module function (casted + * from krb5_error_code to long) into a string. If this function is + * implemented, libkdb5 will invoke it and call krb5_set_error_message with + * the result. This function may never return NULL. + * + * This function is not productively implemented in current modules, and it + * is better for a module to simply call krb5_set_error_message inside + * modules when appropriate. + */ + const char *(*errcode_2_string)(krb5_context kcontext, long err_code); + + /* Optional: Free an error string returned by errcode_2_string. */ + void (*release_errcode_string)(krb5_context kcontext, const char *msg); + + /* + * Mandatory: Has the semantics of realloc(ptr, size). Callers use this to + * allocate memory for new or changed principal entries, so the module + * should expect to potentially see this memory in db_free_principal. + */ + void *(*db_alloc)(krb5_context kcontext, void *ptr, size_t size); + + /* + * Mandatory: Has the semantics of free(ptr). Callers use this to free + * fields from a principal entry (such as key data) before changing it in + * place, and in some cases to free data they allocated with db_alloc. + */ + void (*db_free)(krb5_context kcontext, void *ptr); + + /* + * Optional with default: Inform the module of the master key. The module + * may remember an alias to the provided memory. This function is called + * at startup by the KDC and kadmind; both supply a NULL pwd argument. The + * module should not need to use a remembered master key value, so current + * modules do nothing with it besides return it from get_master_key, which + * is never used. The default implementation does nothing. + */ + krb5_error_code (*set_master_key)(krb5_context kcontext, char *pwd, + krb5_keyblock *key); - void (*db_free_policy) ( krb5_context kcontext, - osa_policy_ent_t val ); + /* + * Optional with default: Retrieve an alias to the master keyblock as + * previously set by set_master_key. This function is not used. The + * default implementation returns success without modifying *key, which + * would be an invalid implementation if it were ever used. + */ + krb5_error_code (*get_master_key)(krb5_context kcontext, + krb5_keyblock **key); + + /* + * Optional with default: Inform the module of the master key. The module + * may remember an alias to the provided memory. This function is called + * at startup by the KDC and kadmind with the value returned by + * fetch_master_key_list. The default implementation does nothing. + */ + krb5_error_code (*set_master_key_list)(krb5_context kcontext, + krb5_keylist_node *keylist); + + /* + * Optional with default: Retrieve an alias to the master key list as + * previously set by set_master_key_list. This function is used by the KDB + * keytab implementation in libkdb5, which is used by kadmind. The default + * implementation returns success without modifying *keylist, which is an + * invalid implementation. + */ + krb5_error_code (*get_master_key_list)(krb5_context kcontext, + krb5_keylist_node **keylist); + + /* This function has no entry point in libkdb5; leave it as NULL. */ + krb5_error_code (*setup_master_key_name)(krb5_context kcontext, + char *keyname, char *realm, + char **fullname, + krb5_principal *principal); + + /* + * Optional with default: Save a master keyblock into the stash file + * db_arg. master_pwd indicates the password used to derive the keyblock, + * if it is known. mname is the name of the master principal for the + * realm. + * + * The default implementation ignores master_pwd and saves the master key + * in a keytab-format file. + */ + krb5_error_code (*store_master_key)(krb5_context kcontext, char *db_arg, + krb5_principal mname, krb5_kvno kvno, + krb5_keyblock *key, char *master_pwd); + + /* + * Optional with default: Retrieve a master keyblock from the stash file + * db_args, filling in *key and *kvno. mname is the name of the master + * principal for the realm. + * + * The default implementation reads the master keyblock from a keytab or + * old-format stash file. + */ + krb5_error_code (*fetch_master_key)(krb5_context kcontext, + krb5_principal mname, + krb5_keyblock *key, krb5_kvno *kvno, + char *db_args); + + /* + * Optional with default: Verify that the keyblock mkey is a valid master + * key for the realm. This function used to be used by the KDC and + * kadmind, but is now used only by kdb5_util dump -mkey_convert. + * + * The default implementation retrieves the master key principal and + * attempts to decrypt its key with mkey. This only works for the current + * master keyblock. + */ + krb5_error_code (*verify_master_key)(krb5_context kcontext, + krb5_principal mprinc, krb5_kvno kvno, + krb5_keyblock *mkey); + + /* + * Optional with default: Given a keyblock for some version of the + * database's master key, fetch the decrypted master key values from the + * database and store the list into *mkeys_list. The caller will free + * *mkeys_list using a libkdb5 function which uses the standard free() + * function, so the module must not use a custom allocator. + * + * The default implementation tries the key against the current master key + * data and all KRB5_TL_MKEY_AUX values, which contain copies of the master + * keys encrypted with old master keys. + */ + krb5_error_code (*fetch_master_key_list)(krb5_context kcontext, + krb5_principal mname, + const krb5_keyblock *key, + krb5_kvno kvno, + krb5_keylist_node **mkeys_list); + + /* + * Optional with default: Save a list of master keyblocks, obtained from + * fetch_master_key_list, into the stash file db_arg. The caller will set + * master_pwd to NULL, so the module should just ignore it. mname is the + * name of the master principal for the realm. + * + * The default implementation saves the list of master keys in a + * keytab-format file. + */ + krb5_error_code (*store_master_key_list)(krb5_context kcontext, + char *db_arg, + krb5_principal mname, + krb5_keylist_node *keylist, + char *master_pwd); + + /* + * Optional with default: Starting at position *start, scan the key data of + * a database entry for a key matching the enctype ktype, the salt type + * stype, and the version kvno. Store the resulting key into *kdatap and + * set *start to the position after the key found. If ktype is negative, + * match any enctype. If stype is negative, match any salt type. If kvno + * is zero or negative, find the most recent key version satisfying the + * other constraints. + */ + krb5_error_code (*dbe_search_enctype)(krb5_context kcontext, + krb5_db_entry *dbentp, + krb5_int32 *start, krb5_int32 ktype, + krb5_int32 stype, krb5_int32 kvno, + krb5_key_data **kdatap); - krb5_error_code (*db_supported_realms) ( krb5_context kcontext, - char **realms ); - krb5_error_code (*db_free_supported_realms) ( krb5_context kcontext, - char **realms ); - - - const char * (*errcode_2_string) ( krb5_context kcontext, - long err_code ); - - void (*release_errcode_string) (krb5_context kcontext, const char *msg); - - void * (*db_alloc) (krb5_context kcontext, void *ptr, size_t size); - void (*db_free) (krb5_context kcontext, void *ptr); - - - - /* optional functions */ - krb5_error_code (*set_master_key) ( krb5_context kcontext, - char *pwd, - krb5_keyblock *key); - - krb5_error_code (*get_master_key) ( krb5_context kcontext, - krb5_keyblock **key); - - krb5_error_code (*set_master_key_list) ( krb5_context kcontext, - krb5_keylist_node *keylist); - - krb5_error_code (*get_master_key_list) ( krb5_context kcontext, - krb5_keylist_node **keylist); - - krb5_error_code (*setup_master_key_name) ( krb5_context kcontext, - char *keyname, - char *realm, - char **fullname, - krb5_principal *principal); - - krb5_error_code (*store_master_key) ( krb5_context kcontext, - char *db_arg, - krb5_principal mname, - krb5_kvno kvno, - krb5_keyblock *key, - char *master_pwd); - - krb5_error_code (*fetch_master_key) ( krb5_context kcontext, - krb5_principal mname, - krb5_keyblock *key, - krb5_kvno *kvno, - char *db_args); - - krb5_error_code (*verify_master_key) ( krb5_context kcontext, - krb5_principal mprinc, - krb5_kvno kvno, - krb5_keyblock *mkey ); - - krb5_error_code (*fetch_master_key_list) (krb5_context kcontext, - krb5_principal mname, - const krb5_keyblock *key, - krb5_kvno kvno, - krb5_keylist_node **mkeys_list); - - krb5_error_code (*store_master_key_list) ( krb5_context kcontext, - char *db_arg, - krb5_principal mname, - krb5_keylist_node *keylist, - char *master_pwd); - - krb5_error_code (*dbe_search_enctype) ( krb5_context kcontext, - krb5_db_entry *dbentp, - krb5_int32 *start, - krb5_int32 ktype, - krb5_int32 stype, - krb5_int32 kvno, - krb5_key_data **kdatap); - - - krb5_error_code - (*db_change_pwd) ( krb5_context context, - krb5_keyblock * master_key, - krb5_key_salt_tuple * ks_tuple, - int ks_tuple_count, - char * passwd, - int new_kvno, - krb5_boolean keepold, - krb5_db_entry * db_entry); - - /* Promote a temporary database to be the live one. */ - krb5_error_code (*promote_db) (krb5_context context, - char *conf_section, - char **db_args); - - krb5_error_code (*dbekd_decrypt_key_data) ( krb5_context kcontext, - const krb5_keyblock *mkey, - const krb5_key_data *key_data, - krb5_keyblock *dbkey, - krb5_keysalt *keysalt ); - - krb5_error_code (*dbekd_encrypt_key_data) ( krb5_context kcontext, - const krb5_keyblock *mkey, - const krb5_keyblock *dbkey, - const krb5_keysalt *keyselt, - int keyver, - krb5_key_data *key_data ); - - krb5_error_code - (*db_invoke) ( krb5_context context, - unsigned int method, - const krb5_data *req, - krb5_data *rep ); + /* + * Optional with default: Change the key data for db_entry to include keys + * derived from the password passwd in each of the specified key-salt + * types, at version new_kvno. Discard the old key data if keepold is not + * set. + * + * The default implementation uses the keyblock master_key to encrypt each + * new key, via the function dbekd_encrypt_key_data. + */ + krb5_error_code (*db_change_pwd)(krb5_context context, + krb5_keyblock *master_key, + krb5_key_salt_tuple *ks_tuple, + int ks_tuple_count, char *passwd, + int new_kvno, krb5_boolean keepold, + krb5_db_entry *db_entry); + + /* + * Optional with default: Promote a temporary database to be the live one. + * kdb5_util load opens the database with the "temporary" db_arg and then + * invokes this function when the load is complete, thus replacing the live + * database with no loss of read availability. + * + * The default implementation returns KRB5_PLUGIN_OP_NOTSUPP (which is + * *not* the usual "operation not supported" error code); kdb5_util dump + * recognizes and ignores this error code. + */ + krb5_error_code (*promote_db)(krb5_context context, char *conf_section, + char **db_args); + + /* + * Optional with default: Decrypt the key in key_data with master keyblock + * mkey, placing the result into dbkey. Copy the salt from key_data, if + * any, into keysalt. Either dbkey or keysalt may be left unmodified on + * successful return if key_data does not contain key or salt information. + * + * The default implementation expects the encrypted key (in krb5_c_encrypt + * format) to be stored in key_data_contents[0], with length given by + * key_data_length[0]. If key_data_ver is 2, it expects the salt to be + * stored, unencrypted, in key_data_contents[1], with length given by + * key_data_length[1]. + */ + krb5_error_code (*dbekd_decrypt_key_data)(krb5_context kcontext, + const krb5_keyblock *mkey, + const krb5_key_data *key_data, + krb5_keyblock *dbkey, + krb5_keysalt *keysalt); + + /* + * Optional with default: Encrypt dbkey with master keyblock mkey, placing + * the result into key_data along with keysalt. + * + * The default implementation stores the encrypted key (in krb5_c_encrypt + * format) in key_data_contents[0] and the length in key_data_length[0]. + * If keysalt is specified, it sets key_data_ver to 2, and stores the salt + * in key_data_contents[1] and its length in key_data_length[1]. If + * keysalt is not specified, key_data_ver is set to 1. + */ + krb5_error_code (*dbekd_encrypt_key_data)(krb5_context kcontext, + const krb5_keyblock *mkey, + const krb5_keyblock *dbkey, + const krb5_keysalt *keysalt, + int keyver, + krb5_key_data *key_data); + + /* + * Optional: Perform an operation on input data req with output stored in + * rep. Return KRB5_KDB_DBTYPE_NOSUP if the module does not implement the + * method. Defined methods are: + * + * KRB5_KDB_METHOD_SIGN_AUTH_DATA: req contains a krb5_sign_auth_data_req + * structure. Generate signed authorization data, such as a Windows + * PAC, for the ticket to be returned to the client. Place the signed + * authorization data in rep using a krb5_sign_auth_data_rep structure. + * This function will be invoked for an AS request if the client + * included padata requesting a PAC. This function will be invoked for + * a TGS request if there is authorization data in the TGT, if the + * client is from another realm, or if the TGS request is an S4U2Self + * or S4U2Proxy request. + * + * KRB5_KDB_METHOD_CHECK_TRANSITED_REALMS: req contains a + * kdb_check_transited_realms_req structure. Perform a policy check on + * a cross-realm ticket's transited field and return an error (other + * than KRB5_KDB_DBTYPE_NOSUP) if the check fails. Leave rep alone. + * + * KRB5_KDB_METHOD_CHECK_POLICY_AS: req contains a kdb_check_policy_as_req + * structure. Perform a policy check on an AS request, in addition to + * the standard policy checks. Return 0 if the AS request is allowed + * or an appropriate error (such as KDC_ERR_POLICY) if it is + * disallowed. Place in rep a kdb_check_policy_as_rep structure + * containing a status string and e_data value to return to the client + * if the policy check fails. The status string may be NULL, but must + * not contain allocated data as it will not be freed. The e_data + * structure may be empty; if not, it will be freed by the caller using + * the standard free function. + * + * KRB5_KDB_METHOD_CHECK_POLICY_TGS: Same as above, except the structures + * are kdb_check_policy_tgs_req and kdb_check_policy_tgs_rep. + * + * KRB5_KDB_METHOD_AUDIT_AS: req contains a kdb_audit_as_req structure. + * Informs the module of a successful or unsuccessful AS request. Do + * not place any data in rep. + * + * KRB5_KDB_METHOD_AUDIT_TGS: Same as above, except req contains a + * kdb_audit_tgs_req structure. + * + * KRB5_KDB_METHOD_REFRESH_POLICY: req and rep are NULL. Informs the + * module that the KDC received a request to reload configuration + * (that is, a SIGHUP). + * + * KRB5_KDB_METHOD_CHECK_ALLOWED_TO_DELEGATE: req contains a + * kdb_check_allowed_to_delegate_req structure. Perform a policy check + * on proxy being allowed to act on behalf of client to server. Return + * 0 if policy allows it, or an appropriate error (such as + * KRB5KDC_ERR_POLICY) if not. If this method is not implemented, all + * S4U2Proxy delegation requests will be rejected. Do not place any + * data in rep. + */ + krb5_error_code (*db_invoke)(krb5_context context, unsigned int method, + const krb5_data *req, krb5_data *rep); } kdb_vftabl; #endif /* !defined(_WIN32) */