/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
- * Copyright 1990,1991 by the Massachusetts Institute of Technology.
+ * Copyright 1990, 1991, 2016 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
/* This version will be incremented when incompatible changes are made to the
* KDB API, and will be kept in sync with the libkdb major version. */
-#define KRB5_KDB_API_VERSION 6
+#define KRB5_KDB_API_VERSION 8
/* Salt types */
#define KRB5_KDB_SALTTYPE_NORMAL 0
#define KRB5_KDB_OK_AS_DELEGATE 0x00100000
#define KRB5_KDB_OK_TO_AUTH_AS_DELEGATE 0x00200000 /* S4U2Self OK */
#define KRB5_KDB_NO_AUTH_DATA_REQUIRED 0x00400000
+#define KRB5_KDB_LOCKDOWN_KEYS 0x00800000
/* Creation flags */
#define KRB5_KDB_CREATE_BTREE 0x00000001
#define KRB5_KDB_FLAGS_S4U ( KRB5_KDB_FLAG_PROTOCOL_TRANSITION | \
KRB5_KDB_FLAG_CONSTRAINED_DELEGATION )
+/* KDB iteration flags */
+#define KRB5_DB_ITER_WRITE 0x00000001
+#define KRB5_DB_ITER_REV 0x00000002
+#define KRB5_DB_ITER_RECURSE 0x00000004
+
+/* String attribute names recognized by krb5 */
+#define KRB5_KDB_SK_SESSION_ENCTYPES "session_enctypes"
+#define KRB5_KDB_SK_REQUIRE_AUTH "require_auth"
+
#if !defined(_WIN32)
/*
*/
typedef struct _krb5_key_data {
krb5_int16 key_data_ver; /* Version */
- krb5_int16 key_data_kvno; /* Key Version */
+ krb5_ui_2 key_data_kvno; /* Key Version */
krb5_int16 key_data_type[2]; /* Array of types */
krb5_ui_2 key_data_length[2]; /* Array of lengths */
krb5_octet * key_data_contents[2]; /* Array of pointers */
krb5_principal princ; /* Length, data */
krb5_tl_data * tl_data; /* Linked list */
+
+ /* key_data must be sorted by kvno in descending order. */
krb5_key_data * key_data; /* Array */
} krb5_db_entry;
krb5_ui_4 pw_min_length;
krb5_ui_4 pw_min_classes;
krb5_ui_4 pw_history_num;
- krb5_ui_4 policy_refcnt;
+ krb5_ui_4 policy_refcnt; /* no longer used */
/* Only valid if version > 1 */
krb5_ui_4 pw_max_fail; /* pwdMaxFailure */
krb5_ui_4 pw_failcnt_interval; /* pwdFailureCountInterval */
krb5_ui_4 pw_lockout_duration; /* pwdLockoutDuration */
+ /* Only valid if version > 2 */
+ krb5_ui_4 attributes;
+ krb5_ui_4 max_life;
+ krb5_ui_4 max_renewable_life;
+ char * allowed_keysalts;
+ krb5_int16 n_tl_data;
+ krb5_tl_data * tl_data;
} osa_policy_ent_rec, *osa_policy_ent_t;
typedef void (*osa_adb_iter_policy_func) (void *, osa_policy_ent_t);
#define KRB5_KDB_MAGIC_NUMBER 0xdbdbdbdb
#define KRB5_KDB_V1_BASE_LENGTH 38
+#define KRB5_KDB_MAX_ALLOWED_KS_LEN 512
+
#define KRB5_TL_LAST_PWD_CHANGE 0x0001
#define KRB5_TL_MOD_PRINC 0x0002
#define KRB5_TL_KADM_DATA 0x0003
#define KRB5_KDB_SRV_TYPE_ADMIN 0x0200
#endif
-#ifndef KRB5_KDB_SRV_TYPE_PASSWD
-#define KRB5_KDB_SRV_TYPE_PASSWD 0x0300
-#endif
+/* 0x0300 was KRB5_KDB_SRV_TYPE_PASSWD but it is no longer used. */
#ifndef KRB5_KDB_SRV_TYPE_OTHER
#define KRB5_KDB_SRV_TYPE_OTHER 0x0400
#define KRB5_DB_LOCKMODE_SHARED 0x0001
#define KRB5_DB_LOCKMODE_EXCLUSIVE 0x0002
-#define KRB5_DB_LOCKMODE_DONTBLOCK 0x0004
#define KRB5_DB_LOCKMODE_PERMANENT 0x0008
/* libkdb.spec */
krb5_db_entry *entry );
krb5_error_code krb5_db_delete_principal ( krb5_context kcontext,
krb5_principal search_for );
+krb5_error_code krb5_db_rename_principal ( krb5_context kcontext,
+ krb5_principal source,
+ krb5_principal target );
+
+/*
+ * Iterate over principals in the KDB. If the callback may write to the DB,
+ * the caller must get an exclusive lock with krb5_db_lock before iterating,
+ * and release it with krb5_db_unlock after iterating.
+ */
krb5_error_code krb5_db_iterate ( krb5_context kcontext,
char *match_entry,
int (*func) (krb5_pointer, krb5_db_entry *),
- krb5_pointer func_arg );
+ krb5_pointer func_arg, krb5_flags iterflags );
krb5_error_code krb5_db_store_master_key ( krb5_context kcontext,
krb5_error_code krb5_db_store_master_key_list ( krb5_context kcontext,
char *keyfile,
krb5_principal mname,
- krb5_keylist_node *keylist,
char *master_pwd);
krb5_error_code krb5_db_fetch_mkey ( krb5_context context,
krb5_principal mname,
krb5_error_code
krb5_db_fetch_mkey_list( krb5_context context,
krb5_principal mname,
- const krb5_keyblock * mkey,
- krb5_kvno mkvno,
- krb5_keylist_node **mkeys_list );
-/**
- * Free a master keylist.
- */
-void
-krb5_db_free_mkey_list( krb5_context context,
- krb5_keylist_node *mkey_list );
+ const krb5_keyblock * mkey );
krb5_error_code
krb5_dbe_find_enctype( krb5_context kcontext,
krb5_error_code
krb5_dbe_find_act_mkey( krb5_context context,
- krb5_keylist_node * mkey_list,
krb5_actkvno_node * act_mkey_list,
krb5_kvno * act_kvno,
krb5_keyblock ** act_mkey);
krb5_error_code
krb5_dbe_find_mkey( krb5_context context,
- krb5_keylist_node * mkey_list,
krb5_db_entry * entry,
krb5_keyblock ** mkey);
krb5_db_entry * entry,
krb5_kvno * mkvno);
+krb5_keylist_node *
+krb5_db_mkey_list_alias( krb5_context kcontext );
+
/* Set *mkvno to mkvno in entry tl_data, or minimum value from mkey_list. */
krb5_error_code
krb5_dbe_get_mkvno( krb5_context context,
krb5_db_entry * entry,
- krb5_keylist_node * mkey_list,
krb5_kvno * mkvno);
krb5_error_code
krb5_timestamp mod_date,
krb5_const_principal mod_princ);
+/*
+ * These are wrappers around realloc() and free(). Applications and KDB
+ * modules can use them when manipulating principal and policy entries to
+ * ensure that they allocate and free memory in a manner compatible with the
+ * library. Using libkrb5 or libkbd5 functions to construct values (such as
+ * krb5_copy_principal() to construct the princ field of a krb5_db_entry) is
+ * also safe. On Unix platforms, just using malloc() and free() is safe as
+ * long as the application or module does not use a malloc replacement.
+ */
void *krb5_db_alloc( krb5_context kcontext,
void *ptr,
size_t size );
-
void krb5_db_free( krb5_context kcontext,
void *ptr);
krb5_int16 tl_data_type);
krb5_error_code
+krb5_db_update_tl_data(krb5_context context,
+ krb5_int16 * n_tl_datap,
+ krb5_tl_data **tl_datap,
+ krb5_tl_data * new_tl_data);
+
+krb5_error_code
krb5_dbe_update_tl_data( krb5_context context,
krb5_db_entry * entry,
krb5_tl_data * new_tl_data);
+/* Compute the salt for a key data entry given the corresponding principal. */
+krb5_error_code
+krb5_dbe_compute_salt(krb5_context context, const krb5_key_data *key,
+ krb5_const_principal princ, krb5_int16 *salttype_out,
+ krb5_data **salt_out);
+
+/*
+ * Modify the key data of entry to explicitly store salt values using the
+ * KRB5_KDB_SALTTYPE_SPECIAL salt type.
+ */
+krb5_error_code
+krb5_dbe_specialize_salt(krb5_context context, krb5_db_entry *entry);
+
krb5_error_code
krb5_dbe_cpw( krb5_context kcontext,
krb5_keyblock * master_key,
const krb5_db_entry *server,
krb5_const_principal proxy);
+/**
+ * Sort an array of @a krb5_key_data keys in descending order by their kvno.
+ * Key data order within a kvno is preserved.
+ *
+ * @param key_data
+ * The @a krb5_key_data array to sort. This is sorted in place so the
+ * array will be modified.
+ * @param key_data_length
+ * The length of @a key_data.
+ */
+void
+krb5_dbe_sort_key_data(krb5_key_data *key_data, size_t key_data_length);
+
/* default functions. Should not be directly called */
/*
* Default functions prototype
krb5_def_fetch_mkey_list( krb5_context context,
krb5_principal mprinc,
const krb5_keyblock *mkey,
- krb5_kvno mkvno,
krb5_keylist_node **mkeys_list);
krb5_error_code
krb5_key_data * key_data);
krb5_error_code
+krb5_db_def_rename_principal( krb5_context kcontext,
+ krb5_const_principal source,
+ krb5_const_principal target);
+
+krb5_error_code
krb5_db_create_policy( krb5_context kcontext,
osa_policy_ent_t policy);
void
krb5_dbe_free_string(krb5_context, char *);
+/*
+ * Register the KDB keytab type, allowing "KDB:" to be used as a keytab name.
+ * For this type to work, the context used for keytab operations must have an
+ * associated database handle (via krb5_db_open()).
+ */
+krb5_error_code krb5_db_register_keytab(krb5_context context);
+
#define KRB5_KDB_DEF_FLAGS 0
#define KDB_MAX_DB_NAME 128
* This number indicates the date of the last incompatible change to the DAL.
* The maj_ver field of the module's vtable structure must match this version.
*/
-#define KRB5_KDB_DAL_MAJOR_VERSION 3
+#define KRB5_KDB_DAL_MAJOR_VERSION 6
/*
* A krb5_context can hold one database object. Modules should use
* 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.
+ *
+ * Modules must allocate memory for principal entries, policy entries, and
+ * other structures using an allocator compatible with malloc() as seen by
+ * libkdb5 and libkrb5. Modules may link against libkdb5 and call
+ * krb5_db_alloc() to be certain that the same malloc implementation is used.
*/
typedef struct _kdb_vftabl {
* 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
krb5_db_entry **entry);
/*
- * Mandatory: Free a database entry. The entry 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.
- */
- void (*free_principal)(krb5_context kcontext, krb5_db_entry *entry);
-
- /*
* Optional: Create or modify a principal entry. db_args communicates
* command-line arguments for module-specific flags.
*
krb5_const_principal search_for);
/*
+ * Optional with default: Rename a principal. If the source principal does
+ * not exist, return KRB5_KDB_NOENTRY. If the target exists, return an
+ * error.
+ *
+ * NOTE: If the module chooses to implement a custom function for renaming
+ * a principal instead of using the default, then rename operations will
+ * fail if iprop logging is enabled.
+ */
+ krb5_error_code (*rename_principal)(krb5_context kcontext,
+ krb5_const_principal source,
+ krb5_const_principal target);
+
+ /*
* 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
krb5_error_code (*iterate)(krb5_context kcontext,
char *match_entry,
int (*func)(krb5_pointer, krb5_db_entry *),
- krb5_pointer func_arg);
+ krb5_pointer func_arg, krb5_flags iterflags);
/*
* Optional: Create a password policy entry. Return an error if the policy
*/
krb5_error_code (*delete_policy)(krb5_context kcontext, char *policy);
- /* Optional: Free a policy entry returned by db_get_policy. */
- void (*free_policy)(krb5_context kcontext, osa_policy_ent_t val);
-
- /*
- * 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 *(*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 (*free)(krb5_context kcontext, void *ptr);
-
/*
* 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
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);
/*
*
* server: The DB entry of the service principal.
*
- * krbtgt: For TGS requests, the DB entry of the (possibly foreign)
- * ticket granting service of the TGT. For AS requests, the DB entry
- * of the service principal.
+ * krbtgt: For TGS requests, the DB entry of the server of the ticket in
+ * the PA-TGS-REQ padata; this is usually a local or cross-realm krbtgt
+ * principal, but not always. For AS requests, the DB entry of the
+ * service principal; this is usually a local krbtgt principal, but not
+ * always.
*
* client_key: The reply key for the KDC request, before any FAST armor
* is applied. For AS requests, this may be the client's long-term key
*
* server_key: The server key used to encrypt the returned ticket.
*
- * krbtgt_key: For TGS requests, the key of the (possibly foreign) ticket
- * granting service of the TGT. for AS requests, the service
- * principal's key.
+ * krbtgt_key: For TGS requests, the key used to decrypt the ticket in
+ * the PA-TGS-REQ padata. For AS requests, the server key used to
+ * encrypt the returned ticket.
*
* session_key: The session key of the ticket being granted to the
* requestor.
/*
* Optional: Perform a policy check on a cross-realm ticket's transited
- * field and return an error (other than KRB5_PLUGIN_OP_NOTSUPP) if the
- * check fails.
+ * field. Return 0 if the check authoritatively succeeds,
+ * KRB5_PLUGIN_NO_HANDLE to use the core transited-checking mechanisms, or
+ * another error (other than KRB5_PLUGIN_OP_NOTSUPP) if the check fails.
*/
krb5_error_code (*check_transited_realms)(krb5_context kcontext,
const krb5_data *tr_contents,
* - Place a short string literal into *status.
* - If desired, place data into e_data. Any data placed here will be
* freed by the caller using the standard free function.
- * - Return an appropriate error (such as KDC_ERR_POLICY).
+ * - Return an appropriate error (such as KRB5KDC_ERR_POLICY).
*/
krb5_error_code (*check_policy_as)(krb5_context kcontext,
krb5_kdc_req *request,
* - Place a short string literal into *status.
* - If desired, place data into e_data. Any data placed here will be
* freed by the caller using the standard free function.
- * - Return an appropriate error (such as KDC_ERR_POLICY).
+ * - Return an appropriate error (such as KRB5KDC_ERR_POLICY).
* The input parameter ticket contains the TGT used in the TGS request.
*/
krb5_error_code (*check_policy_tgs)(krb5_context kcontext,
krb5_const_principal client,
const krb5_db_entry *server,
krb5_const_principal proxy);
+
+ /* End of minor version 0. */
+
+ /*
+ * Optional: Free the e_data pointer of a database entry. If this method
+ * is not implemented, the e_data pointer in principal entries will be
+ * freed with free() as seen by libkdb5.
+ */
+ void (*free_principal_e_data)(krb5_context kcontext, krb5_octet *e_data);
+
+ /* End of minor version 1 for major version 6. */
} kdb_vftabl;
#endif /* !defined(_WIN32) */