diff options
Diffstat (limited to 'crypto/krb5/doc/kadm5')
-rw-r--r-- | crypto/krb5/doc/kadm5/adb-unit-test.tex | 135 | ||||
-rw-r--r-- | crypto/krb5/doc/kadm5/api-funcspec.tex | 2015 | ||||
-rw-r--r-- | crypto/krb5/doc/kadm5/api-server-design.tex | 1054 | ||||
-rw-r--r-- | crypto/krb5/doc/kadm5/fullpage.sty | 9 |
4 files changed, 0 insertions, 3213 deletions
diff --git a/crypto/krb5/doc/kadm5/adb-unit-test.tex b/crypto/krb5/doc/kadm5/adb-unit-test.tex deleted file mode 100644 index 0595c6729320..000000000000 --- a/crypto/krb5/doc/kadm5/adb-unit-test.tex +++ /dev/null @@ -1,135 +0,0 @@ -% This document is included for historical purposes only, and does not -% apply to krb5 today. - -\documentstyle[times,fullpage]{article} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Make _ actually generate an _, and allow line-breaking after it. -\let\underscore=\_ -\catcode`_=13 -\def_{\underscore\penalty75\relax} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newcommand{\test}[1]{\begin{description} -\setlength{\itemsep}{0pt} -#1 -\end{description} - -} - -\newcommand{\numtest}[2]{\begin{description} -\setlength{\itemsep}{0pt} -\Number{#1} -#2 -\end{description} - -} - -\newcommand{\Number}[1]{\item[Number:] #1} -\newcommand{\Reason}[1]{\item[Reason:] #1} -%\newcommand{\Call}[1]{\item[Call:] #1} -\newcommand{\Expected}[1]{\item[Expected:] #1} -\newcommand{\Conditions}[1]{\item[Conditions:] #1} -\newcommand{\Priority}[1]{\item[Priority:] #1} -\newcommand{\Status}[1]{\item[Status:] #1} -%\newcommand{\Number}[1]{} -%\newcommand{\Reason}[1]{} -\newcommand{\Call}[1]{} -%\newcommand{\Expected}[1]{} -%\newcommand{\Conditions}[1]{} -%\newcommand{\Priority}[1]{} - -\title{OpenV*Secure Admin Database API\\ -Unit Test Description} -\author{Jonathan I. Kamens} - -\begin{document} - -\maketitle - -%\tableofcontents - -\section{Introduction} - -The following is a description of a black-box unit test of the -OpenV*Secure Admin Database API (osa_adb). Each API function is -listed, followed by the tests that should be performed on it. - -The tests described here are based on the ``OV*Secure Admin Server -Implementation Design'' revision 1.14. - -\section{osa_adb_get_lock and osa_adb_release_lock} - -\numtest{1}{ -\Reason{A shared lock can be acquired.} -\Status{Implemented} -} - -\numtest{2}{ -\Reason{An exclusive lock can be acquired and released.} -\Status{Implemented} -} - -\numtest{3}{ -\Reason{A permanent lock can be acquired and released.} -\Status{Implemented} -} - -\numtest{4}{ -\Reason{Attempting to release a lock when none is held fails with -NOTLOCKED.} -\Status{Implemented} -} - -\numtest{5}{ -\Reason{Two processes can both acquire a shared lock.} -\Status{Implemented} -} - -\numtest{6}{ -\Reason{An attempt to acquire a shared lock while another process holds an -exclusive lock fails with CANTLOCK_DB.} -\Status{Implemented} -} - -\numtest{7}{ -\Reason{An attempt to acquire an exclusive lock while another process holds a -shared lock fails with CANTLOCK_DB.} -\Status{Implemented} -} - -\numtest{8}{ -\Reason{An attempt to open the database while a process holds a -permanent lock fails with NO_LOCKFILE.} -\Status{Implemented} -} - -\numtest{9}{ -\Reason{An attempt to acquire an exclusive lock while a process holds a -permanent lock fails with NO_LOCKFILE.} -\Status{Implemented} -} - -\numtest{10}{ -\Reason{Acquiring a permanent lock deletes the lockfile.} -\Status{Implemented} -} - -\numtest{11}{ -\Reason{Releasing a permanent lock re-creates the lockfile.} -\Status{Implemented} -} - -\numtest{12}{ -\Reason{A process can perform a get operation while another process holds a -shared lock.} -\Status{Implemented} -} - -\numtest{13}{ -\Reason{A process that is running and has opened the adb principal database -can retrieve a principal created after the open occurred.} -\Status{Implemented, but not working} -} - -\end{document} diff --git a/crypto/krb5/doc/kadm5/api-funcspec.tex b/crypto/krb5/doc/kadm5/api-funcspec.tex deleted file mode 100644 index b633cef1ef33..000000000000 --- a/crypto/krb5/doc/kadm5/api-funcspec.tex +++ /dev/null @@ -1,2015 +0,0 @@ -% This document is included for historical purposes only, and does not -% apply to krb5 today. - -\documentstyle[12pt,fullpage]{article} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Make _ actually generate an _, and allow line-breaking after it. -\let\underscore=\_ -\catcode`_=13 -\def_{\underscore\penalty75\relax} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\setlength{\parskip}{.7\baselineskip} -\setlength{\parindent}{0pt} - -\def\v#1{\verb+#1+} - -\title{Kerberos Administration System \\ - KADM5 API Functional Specifications} -\author{Barry Jaspan} - -\begin{document} - -\sloppy -\maketitle - -{\setlength{\parskip}{0pt}\tableofcontents} - -\section{Introduction} - -This document describes the Admin API that can be used to maintain -principals and policies. It describes the data structures used for -each function and the interpretation of each data type field, the -semantics of each API function, and the possible return codes. - -The Admin API is intended to be used by remote clients using an RPC -interface. It is implemented by the admin server running on the -Kerberos master server. It is also possible for a program running on -the Kerberos master server to use the Admin API directly, without -going through the admin server. - -\section{Versions of the API} - -The versions of this API and a brief description of the changes for -each are: - -\begin{description} -\item[KADM5_API_VERSION_1] The initial version of this API, written by -OpenVision Technologies and donated to MIT for including in the public -release. Originally called OVSEC_KADM_API_VERSION_1. Most everything -has been renamed in one way or another, including functions, header -files, and data structures. Where possible, the old OVSEC_KADM names -have been left behind for compatibility with version 1, and -KADM5_API_VERSION_1 is compatible with OVSEC_KADM_API_VERSION_1 at -compile-, link-, and run-time. - -The OVSEC_KADM name compatibility will not be extended to new -functionality in future versions because no existing OVSEC_KADM -clients will use that functionality; new clients should be written to -the KADM5 API. - -\item[KADM5_API_VERSION_2] This version contains the initial changes -necessary to make the OpenVision administration system work with the -mid-1996 MIT version of Kerberos 5. Changes include -\begin{enumerate} -\item The kadm5_init functions now take a structure of parameters -instead of just a realm name, allowing the calling program to specify -non-default values for various configuration options. See section -\ref{sec:configparams} for details. - -\item The KADM5 API has been extended to support new features of the -Kerberos database, including multiple encryption and salt types per -principal. See section \ref{sec:keys} for details. - -\item kadm5_get_principal now allows a principal's keys to be -retrieved {\it by local clients only}. This is necessary in order for -the kadm5 API to provide the primary Kerberos database interface. - -\item The KADM5 authorization system has been completely changed. - -\item The functions kadm5_flush, kadm5_get_principals, and -kadm5_get_policies have been added. - -\item The KADM5 API now obeys a caller-allocates rather than -callee-allocates system. kadm5_get_principal and kadm5_get_policy are -affected. -\end{enumerate} -\end{description} - -\section{Policies and Password Quality} - -The Admin API Password Quality mechanism provides the following -controls. Note that two strings are defined to be ``significantly -different'' if they differ by at least one character. The compare is not -case sensitive. - -\begin{itemize} -\item A minimum length can be required; a password with -fewer than the specified number of characters will not be accepted. - -\item A minimum number of character classes can be required; a -password that does not contain at least one character from at least -the specified number of character classes will not be accepted. The -character classes are defined by islower(), isupper(), isdigit(), -ispunct(), and other. - -\item Passwords can be required to be different from -previous passwords; a password that generates the same encryption key -as any of the principal's specified previous number of passwords will -not be accepted. This comparison is performed on the encryption keys -generated from the passwords, not on the passwords themselves. - -\item A single ``forbidden password'' dictionary can be specified for all -users; a password that is not significantly different from every word -in the dictionary will not be accepted. -\end{itemize} - -\section{Data Structures} - -This section describes the data structures used by the Admin API. -They are defined in $<$kadm5/admin.h$>$. - -\subsection{Principals, kadm5_principal_ent_t} -\label{sec:principal-structure} - -A Kerberos principal entry is represented by a kadm5_principal_ent_t. -It contains a subset of the information stored in the master Kerberos -database as well as the additional information maintained by the admin -system. In the current version, the only additional information is -the principal's policy and the aux_attributes flags. - -The principal may or may not have a policy enforced on it. If the -POLICY bit (see section \ref{sec:masks}) is set in aux_attributes, the -policy field names the principal's policy. If the POLICY bit is not -set in aux_attributes, no policy is enforced on the principal and the -value of the policy field is undefined. - -\begin{figure}[htbp] -\begin{verbatim} -typedef struct _kadm5_principal_ent_t { - krb5_principal principal; - - krb5_timestamp princ_expire_time; - krb5_timestamp last_pwd_change; - krb5_timestamp pw_expiration; - krb5_deltat max_life; - krb5_principal mod_name; - krb5_timestamp mod_date; - krb5_flags attributes; - krb5_kvno kvno; - krb5_kvno mkvno; - - char * policy; - u_int32 aux_attributes; - - krb5_deltat max_renewable_life; - krb5_timestamp last_success; - krb5_timestamp last_failed; - krb5_kvno fail_auth_count; - krb5_int16 n_key_data; - krb5_int16 n_tl_data; - krb5_tl_data *tl_data; - krb5_key_data *key_data; -} kadm5_principal_ent_rec, *kadm5_principal_ent_t; -\end{verbatim} -\caption{Definition of kadm5_principal_ent_t.} -\label{fig:princ-t} -\end{figure} - -The fields of an kadm5_principal_ent_t are interpreted as -follows. - -\begin{description} -\item[principal] The name of the principal; must conform to Kerberos -naming specifications. - -\item[princ_expire_time] The expire time of the principal as a Kerberos -timestamp. No Kerberos tickets will be issued for a principal after -its expire time. - -\item[last_pwd_change] The time this principal's password was last -changed, as a Kerberos timestamp. - -\item[pw_expiration] The expire time of the user's current password, as a -Kerberos timestamp. No application service tickets will be issued for the -principal once the password expire time has passed. Note that the user can -only obtain tickets for services that have the PW_CHANGE_SERVICE bit set in -the attributes field. - -\item[max_life] The maximum lifetime of any Kerberos ticket issued to -this principal. - -\item[attributes] A bitfield of attributes for use by the KDC. The -symbols and constant values are defined below; their interpretation -appears in the libkdb functional specification. - -\begin{tabular}{clr} -{\bf Name} & {\bf Value} \\ -KRB5_KDB_DISALLOW_POSTDATED & 0x00000001 \\ -KRB5_KDB_DISALLOW_FORWARDABLE & 0x00000002 \\ -KRB5_KDB_DISALLOW_TGT_BASED & 0x00000004 \\ -KRB5_KDB_DISALLOW_RENEWABLE & 0x00000008 \\ -KRB5_KDB_DISALLOW_PROXIABLE & 0x00000010 \\ -KRB5_KDB_DISALLOW_DUP_SKEY & 0x00000020 \\ -KRB5_KDB_DISALLOW_ALL_TIX & 0x00000040 \\ -KRB5_KDB_REQUIRES_PRE_AUTH & 0x00000080 \\ -KRB5_KDB_REQUIRES_HW_AUTH & 0x00000100 \\ -KRB5_KDB_REQUIRES_PWCHANGE & 0x00000200 \\ -KRB5_KDB_DISALLOW_SVR & 0x00001000 \\ -KRB5_KDB_PWCHANGE_SERVICE & 0x00002000 \\ -KRB5_KDB_SUPPORT_DESMD5 & 0x00004000 \\ -KRB5_KDB_NEW_PRINC & 0x00008000 -\end{tabular} - -\item[mod_name] The name of the Kerberos principal that most recently -modified this principal. - -\item[mod_date] The time this principal was last modified, as a Kerberos -timestamp. - -\item[kvno] The version of the principal's current key. - -\item[mkvno] The version of the Kerberos Master Key in effect when -this principal's key was last changed. In KADM5_API_VERSION_2, this -field is always zero. - -\item[policy] If the POLICY bit is set in aux_attributes, the name -of the policy controlling this principal. - -\item[aux_attributes] A bitfield of flags for use by the -administration system. Currently, the only valid flag is POLICY, and -it indicates whether or not the principal has a policy enforced on it. - -\item[max_renewable_life] The maximum renewable lifetime of any -Kerberos ticket issued to or for this principal. This field only -exists in KADM5_API_VERSION_2. - -\item[last_success] The KDC time of the last successful AS_REQ. This -is only updated if KRBCONF_KDC_MODIFIES_KDB is defined during -compilation of the KDC. This field only exists in -KADM5_API_VERSION_2. - -\item[last_failed] The KDC time of the last failed AS_REQ. This is -only updated if KRBCONF_KDC_MODIFIES_KDB is defined during compilation -of the KDC. This field only exists in KADM5_API_VERSION_2. - -\item[fail_auth_count] The number of consecutive failed AS_REQs. When -this number reaches KRB5_MAX_FAIL_COUNT, the KRB5_KDC_DISALLOW_ALL_TIX -is set on the principal. This is only updated if -KRBCONF_KDC_MODIFIES_KDB is defined during compilation. This field -only exists in KADM5_API_VERSION_2. - -\item[n_tl_data] The number of elements in the \v{tl_data} linked -list. This field only exists in KADM5_API_VERSION_2. - -\item[n_key_data] The number of elements in the \v{key_data} -array. This field only exists in KADM5_API_VERSION_2. - -\item[tl_data] A linked list of tagged data. This list is a mechanism -by which programs can store extended information in a principal entry, -without having to modify the database API. Each element is of type -krb5_tl_data: -\begin{verbatim} -typedef struct _krb5_tl_data { - struct _krb5_tl_data* tl_data_next; - krb5_int16 tl_data_type; - krb5_int16 tl_data_length; - krb5_octet * tl_data_contents; -} krb5_tl_data; -\end{verbatim} -% -The KADM5 API only allows elements whose tl_data_type is greater than -or equal to 256. Values less than 256 are reserved for internal use -by the KADM5 or kdb system. They are filtered out of the list -returned by kadm5_get_principal, and generate an error if given to -kadm5_modify_principal. - -The libkdb library defines the tagged data types -KRB5_TL_LAST_PWD_CHANGE, KRB5_TL_MOD_PRINC, and KRB5_TL_KADM_DATA, all -with values less than 256, which store the last password modification -time, time and modifier of last principal modification, and -administration system data. All of these entries are expected by the -administration system and parsed out into fields of the -kadm5_principal_ent_rec structure; as described above, they are not -included in the tl_data list. - -Tagged data elements with types greater than 256 are handled without -interpretation by KADM5. Note that an application that calls -kadm5_modify_principal with the KADM5_TL_DATA mask bit set is -responsible for providing the {\it complete} tl_data list, which it -necessarily must obtain from kadm5_get_principal. It is {\it never} -possible for an application to construct a complete tl_data list from -scratch. - -\item[key_data] An array of the principal's keys. The keys contained -in this array are encrypted in the Kerberos master key. See section -\ref{sec:keys} for a discussion of the krb5_key_data structure. -\end{description} - -\subsection{Policies, kadm5_policy_ent_t} -\label{sec:policy-fields} - -If the POLICY bit is set in aux_attributes, the \v{policy} name field -in the kadm5_principal_ent_t structure refers to a password policy -entry defined in a \v{kadm5_policy_ent_t}. - -\begin{verbatim} -typedef struct _kadm5_policy_ent_t { - char *policy; - - u_int32 pw_min_life; - u_int32 pw_max_life; - u_int32 pw_min_length; - u_int32 pw_min_classes; - u_int32 pw_history_num; - u_int32 policy_refcnt; -} kadm5_policy_ent_rec, *kadm5_policy_ent_t; -\end{verbatim} - -The fields of an kadm5_policy_ent_t are interpreted as follows. -Note that a policy's values only apply to a principal using that -policy. - -\begin{description} -\item[policy] The name of this policy, as a NULL-terminated string. -The ASCII characters between 32 (space) and 126 (tilde), inclusive, -are legal. - -\item[pw_min_life] The minimum password lifetime, in seconds. -A principal cannot change its password before pw_min_life seconds have -passed since last_pwd_change. - -\item[pw_max_life] The default duration, in seconds, used to compute -pw_expiration when a principal's password is changed. - -\item[pw_min_length] The minimum password length, in characters. A -principal cannot set its password to anything with fewer than this -number of characters. This value must be greater than zero. - -\item[pw_min_classes] The minimum number of character classes in the -password. This value can only be 1, 2, 3, 4, or 5. A principal cannot -set its password to anything with fewer than this number of character -classes in it. - -\item[pw_history_num] The number of past passwords that are -stored for the principal; the minimum value is 1 and the maximum value -is 10. A principal cannot set its password to any of its previous -pw_history_num passwords. The first ``previous'' password is the -current password; thus, a principal with a policy can never reset its -password to its current value. - -\item[policy_refcnt] The number of principals currently using this policy. -A policy cannot be deleted unless this number is zero. -\end{description} - -\subsection{Configuration parameters} -\label{sec:configparams} - -The KADM5 API acquires configuration information from the Kerberos -configuration file (\$KRB5_CONFIG or DEFAULT_PROFILE_PATH) and from -the KDC configuration file (\$KRB5_KDC_CONFIG or DEFAULT_KDC_PROFILE). -In KADM5_API_VERSION_2, some of the configuration parameters used by -the KADM5 API can be controlled by the caller by providing a -kadm5_config_params structure to kadm5_init: -% -\begin{verbatim} -typedef struct _kadm5_config_params { - u_int32 mask; - - /* Client and server fields */ - char *realm; - char *profile; - int kadmind_port; - - /* client fields */ - char *admin_server; - - /* server fields */ - char *dbname; - char *admin_dbname; - char *admin_lockfile; - char *acl_file; - char *dict_file; - char *admin_keytab; - - /* server library (database) fields */ - int mkey_from_kbd; - char *stash_file; - char *mkey_name; - krb5_enctype enctype; - krb5_deltat max_life; - krb5_deltat max_rlife; - krb5_timestamp expiration; - krb5_flags flags; - krb5_key_salt_tuple *keysalts; - krb5_int32 num_keysalts; -} kadm5_config_params; -\end{verbatim} -% -The following list describes each of the fields of the structure, -along with the profile relation it overrides, its mask value, its -default value, and whether it is valid on the client, server, or both, -or neither. -\begin{description} -\item[mask] No variable. No mask value. A bitfield specifying which -fields of the structure contain valid information. A caller sets this -mask before calling kadm5_init_*, indicating which parameters are -specified. The mask values are defined in $<$kadm5/admin.h$>$ and are -all prefixed with KADM5_CONFIG_; the prefix is not included in the -descriptions below. - -\item[realm] No variable. REALM. Client and server. The realm to -which these parameters apply, and the realm for which additional -parameters are to be acquired, if any. If this field is not specified -in the mask, the default local realm is used. - -\item[profile] Variable: profile (server only). PROFILE. Client and -server. The Kerberos profile to use. On the client, the default is -the value of the KRB5_CONFIG environment variable, or -DEFAULT_PROFILE_PATH if that is not set. On the server, the value of -the ``profile'' variable of the KDC configuration file will be used as -the first default if it exists; otherwise, the default is the value of -the KRB5_KDC_PROFILE environment variable or DEFAULT_KDC_PROFILE. - -\item[kadmind_port] Variable: kadmind_port. KADMIND_PORT. Client and -server. The port number the kadmind server listens on. The client -uses this field to determine where to connect, and the server to -determine where to listen. The default is 749, which has been -assigned by IANA. - -\item[admin_server] Variable: admin_server. ADMIN_SERVER. Client. -The host name of the admin server to which to connect. There is no -default. If the value of this field contains a colon (:), the text -following the colon is treated as an integer and assigned to the -kadmind_port field, overriding any value of the kadmind_port variable. - -\item[dbname] Variable: dbname. DBNAME. Server. The Kerberos -database name to use; the Kerberos database stores principal -information. The default is DEFAULT_KDB_FILE. - -\item[admin_dbname] Variable: admin_database_name. ADBNAME. -Neither. If the dbname field is set, this field is set to the value -of dbname followed by ``.kadm5''. - -\item[admin_lockfile] Variable: admin_database_lockfile. -ADB_LOCKFILE. Neither. If the admin_dbname field is set, this field -is set to the value of admin_dbname followed by ``.lock''. - -\item[acl_file] Variable: acl_file. ACL_FILE. Server. The admin -server's ACL file. The default is DEFAULT_KADM5_ACL_FILE. - -\item[dict_file] Variable: admin_dict_file. DICT_FILE. Server. The -admin server's dictionary file of passwords to disallow. No default. - -\item[admin_keytab] Variable: admin_keytab. ADMIN_KEYTAB. Server. -The keytab file containing the kadmin/admin and kadmin/changepw -entries for the server to use. The default is the value of the -KRB5_KTNAME environment variable, if defined, else -DEFAULT_KADM5_KEYTAB. - -\item[mkey_from_keyboard] No variable. MKEY_FROM_KEYBOARD. Server. -If non-zero, prompt for the master password via the tty instead of -using the stash file. If this mask bit is not set, or is set and the -value is zero, the stash file is used. - -\item[stash_file] Variable: key_stash_file. STASH_FILE. Server. The -file name containing the master key stash file. No default; libkdb -will work with a NULL value. - -\item[mkey_name] Variable: master_key_name. MKEY_NAME. Server. The -name of the master principal for the realm. No default; lbkdb will -work with a NULL value. - -\item[enctype] Variable: master_key_type. ENCTYPE. Server. The -encryption type of the master principal. The default is -DEFAULT_KDC_ENCTYPE. - -\item[max_life] Variable: max_life. MAX_LIFE. Maximum lifetime for -all tickets issued to the principal. The default is 28800, which is 8 -hours. - -\item[max_rlife, expiration, flags] Variables: max_renewable_life, -default_principal_expiration, default_principal_flags. MAX_LIFE, -MAX_RLIFE, EXPIRATION, FLAGS. Server. Default values for new -principals. All default to 0. - -\item[keysalts, num_keysalts] Variable: supported_enctypes. ENCTYPES. -Server. The list of supported encryption type/salt type tuples; both -fields must be assigned if ENCTYPES is set. The default is a list -containing one enctype, DES-CBC-CRC with normal salt. -\end{description} - -\subsection{Principal keys} -\label{sec:keys} - -In KADM5_API_VERSION_1, all principals had a single key. The -encryption method was always DES, and the salt type was determined -outside the API (by command-line options to the administration -server). - -In KADM5_API_VERSION_2, principals can have multiple keys, each with -its own encryption type and salt. Each time a principal's key is -changed with kadm5_create_principal, kadm5_chpass_principal or -kadm5_randkey_principal, existing key entries are removed and a key -entry for each encryption and salt type tuple specified in the -configuration parameters is added. There is no provision for -specifying encryption and salt type information on a per-principal -basis; in a future version, this will probably be part of the admin -policy. There is also presently no provision for keeping multiple key -versions for a single principal active in the database. - -A single key is represented by a krb5_key_data: -% -\begin{verbatim} -typedef struct _krb5_key_data { - krb5_int16 key_data_ver; /* Version */ - krb5_int16 key_data_kvno; /* Key Version */ - krb5_int16 key_data_type[2]; /* Array of types */ - krb5_int16 key_data_length[2]; /* Array of lengths */ - krb5_octet * key_data_contents[2]; /* Array of pointers */ -} krb5_key_data; -\end{verbatim} -% -\begin{description} -\item[key_data_ver] The version number of the structure. Versions 1 -and 2 are currently defined. If key_data_ver is 1 then the key is -either a random key (not requiring a salt) or the salt is the normal -v5 salt which is the same as the realm and therefore doesn't need to -be saved in the database. - -\item[key_data_kvno] The key version number of this key. - -\item[key_data_type] The first element is the enctype of this key. In -a version 2 structure, the second element is the salttype of this key. -The legal encryption types are defined in $<$krb5.h$>$. The legal -salt types are defined in $<$k5-int.h$>$. - -\item[key_data_length] The first element is length this key. In a -version 2 structure, the second element is length of the salt for this -key. - -\item[key_data_contents] The first element is the content of this key. -In a version 2 structure, the second element is the contents of the -salt for this key. -\end{description} - -\subsection{Field masks} -\label{sec:masks} - -The API functions for creating, retrieving, and modifying principals -and policies allow for a relevant subset of the fields of the -kadm5_principal_ent_t and kadm5_policy_ent_t to be specified or -changed. The chosen fields are determined by a bitmask that is passed -to the relevant function. Each API function has different rules for -which mask values can be specified, and can specify whether a given -mask value is mandatory, optional, or forbidden. Mandatory fields -must be present and forbidden fields must not be present or an error -is generated. When creating a principal or policy, optional fields -have a default value if they are not specified. When modifying a -principal or policy, optional fields are unchanged if they are not -specified. When retrieving a principal, optional fields are simply -not provided if they are not specified; not specifying undeeded fields -for retrieval may improve efficiency. The values for forbidden fields -are defined in the function semantics. - -The masks for principals are in table \ref{tab:princ-bits} and the -masks for policies are in table \ref{tab:policy-bits}. They are -defined in $<$kadm5/admin.h$>$. The KADM5_ prefix has been removed -from the Name fields. In the Create and Modify fields, M means -mandatory, F means forbidden, and O means optional. Create fields -that are optional specify the default value. The notation ``K/M -value'' means that the field inherits its value from the corresponding -field in the Kerberos master principal, for KADM5_API_VERSION_1, and -from the configuration parameters for KADM5_API_VERSION_2. - -All masks for principals are optional for retrevial, {\it except} that -the KEY_DATA mask is illegal when specified by a remote client; for -details, see the function semantics for kadm5_get_principal. - -Note that the POLICY and POLICY_CLR bits are special. When POLICY is -set, the policy is assigned to the principal. When POLICY_CLR is -specified, the policy is unassigned to the principal and as a result -no policy controls the principal. - -For convenience, the mask KADM5_PRINCIPAL_NORMAL_MASK contains all of -the principal masks {\it except} KADM5_KEY_DATA and KADM5_TL_DATA, and -the mask KADM5_POLICY_NORMAL_MASK contains all of the policy masks. - -\begin{table}[htbp] -\begin{tabular}{@{}lclll} -{\bf Name} & {\bf Value} & {\bf Fields Affected} & {\bf Create} & - {\bf Modify} \\ -PRINCIPAL & 0x000001 & principal & M & F \\ -PRINC_EXPIRE_TIME & 0x000002 & princ_expire_time & O, K/M value & O \\ -PW_EXPIRATION & 0x000004 & pw_expiration & O, now+pw_max_life & O \\ -LAST_PWD_CHANGE & 0x000008 & last_pwd_change & F & F \\ -ATTRIBUTES & 0x000010 & attributes & O, 0 & O \\ -MAX_LIFE & 0x000020 & max_life & O, K/M value & O \\ -MOD_TIME & 0x000040 & mod_date & F & F \\ -MOD_NAME & 0x000080 & mod_name & F & F \\ -KVNO & 0x000100 & kvno & O, 1 & O \\ -MKVNO & 0x000200 & mkvno & F & F \\ -AUX_ATTRIBUTES & 0x000400 & aux_attributes & F & F \\ -POLICY & 0x000800 & policy & O, none & O \\ -POLICY_CLR & 0x001000 & policy & F & O \\ -MAX_RLIFE & 0x002000 & max_renewable_life & O, K/M value & O \\ -LAST_SUCCESS & 0x004000 & last_success & F & F \\ -LAST_FAILED & 0x008000 & last_failed & F & F \\ -FAIL_AUTH_COUNT & 0x010000 & fail_auth_count & F & O \\ -KEY_DATA & 0x020000 & n_key_data, key_data & F & F \\ -TL_DATA & 0x040000 & n_tl_data, tl_data & O, 0, NULL & O -\end{tabular} -\caption{Mask bits for creating, retrieving, and modifying principals.} -\label{tab:princ-bits} -\end{table} - -\begin{table}[htbp] -\begin{tabular}{@{}lclll} -Name & Value & Field Affected & Create & Modify \\ -POLICY & same & policy & M & F \\ -PW_MAX_LIFE & 0x004000 & pw_max_life & O, 0 (infinite) & O \\ -PW_MIN_LIFE & 0x008000 & pw_min_life & O, 0 & O \\ -PW_MIN_LENGTH & 0x010000 & pw_min_length & O, 1 & O \\ -PW_MIN_CLASSES & 0x020000 & pw_min_classes & O, 1 & O \\ -PW_HISTORY_NUM & 0x040000 & pw_history_num & O, 0 & O \\ -REF_COUNT & 0x080000 & pw_refcnt & F & F -\end{tabular} -\caption{Mask bits for creating/modifying policies.} -\label{tab:policy-bits} -\end{table} - -\section{Constants, Header Files, Libraries} - -$<$kadm5/admin.h$>$ includes a number of required header files, -including RPC, Kerberos 5, com_err, and admin com_err -defines. It contains prototypes for all kadm5 routines mentioned -below, as well as all Admin API data structures, type definitions and -defines mentioned in this document. - -Before \v{\#include}ing $<$kadm5/admin.h$>$, the programmer can -specify the API version number that the program will use by -\v{\#define}ing USE_KADM5_API_VERSION; for example, define that symbol -to be 1 to use KADM5_API_VERSION_1. This will ensure that the correct -functional prototypes and data structures are defined. If no version -symbol is defined, the most recent version supported by the header -files will be used. - -Some of the defines and their values contained in $<$kadm5/admin.h$>$ -include the following, whose KADM5_ prefixes have been removed. -Symbols that do not exist in KADM5_API_VERSION_2 do not have a KADM5_ -prefix, but instead retain only with OVSEC_KADM_ prefix for -compatibility. -\begin{description} -\item[admin service principal] ADMIN_SERVICE (``kadmin/admin'') -\item[admin history key] HIST_PRINCIPAL (``kadmin/history'') -\item[change password principal] CHANGEPW_SERVICE (``kadmin/changepw'') -\item[server acl file path] ACLFILE (``/krb5/ovsec_adm.acl''). In -KADM5_API_VERSION 2, this is controlled by configuration parameters. -\item[dictionary] WORDFILE (``/krb5/kadmind.dict''). In -KADM5_API_VERSION 2, this is controlled by configuration parameters. -\end{description} - -KADM5 errors are described in $<$kadm5/kadm_err.h$>$, which -is included by $<$kadm5/admin.h$>$. - -The locations of the admin policy and principal databases, as well as -defines and type definitions for the databases, are defined in -$<$kadm5/adb.h$>$. Some of the defines in that file are: -\begin{description} -\item[admin policy database] POLICY_DB (``/krb5/kadm5_policy.db''). In -KADM5_API_VERSION 2, this is controlled by configuration parameters. -\item[admin principal database] PRINCIPAL_DB -(``/krb5/ovsec_principal.db''). In KADM5_API_VERSION 2, this is -controlled by configuration parameters. -\end{description} - -Client applications will link against libkadm5clnt.a and server -programs against libkadm5srv.a. Client applications must also link -against: libgssapi_krb5.a, libkrb5.a, libcrypto.a, libgssrpc.a, -libcom_err.a, and libdyn.a. Server applications must also link -against: libkdb5.a, libkrb5.a, libcrypto.a, libgssrpc.a, libcom_err.a, -and libdyn.a. - -\section{Error Codes} - -The error codes that can be returned by admin functions are listed -below. Error codes indicated with a ``*'' can be returned by every -admin function and always have the same meaning; these codes are -omitted from the list presented with each function. - -The admin system guarantees that a function that returns an error code -has no other side effect. - -The Admin system will use \v{com_err} for error codes. Note that this -means \v{com_err} codes may be returned from functions that the admin -routines call (e.g. the kerberos library). Callers should not expect -that only KADM5 errors will be returned. The Admin system error code -table name will be ``ovk'', and the offsets will be the same as the -order presented here. As mentioned above, the error table include file -will be $<$kadm5/kadm_err.h$>$. - -Note that these error codes are also used as protocol error code -constants and therefore must not change between product releases. -Additional codes should be added at the end of the list, not in the -middle. The integer value of KADM5_FAILURE is 43787520; the -remaining values are assigned in sequentially increasing order. - -\begin{description} -\item[* KADM5_FAILURE] Operation failed for unspecified reason -\item[* KADM5_AUTH_GET] Operation requires ``get'' privilege -\item[* KADM5_AUTH_ADD] Operation requires ``add'' privilege -\item[* KADM5_AUTH_MODIFY] Operation requires ``modify'' privilege -\item[* KADM5_AUTH_DELETE] Operation requires ``delete'' privilege -\item[* KADM5_AUTH_INSUFFICIENT] Insufficient authorization for -operation -\item[* KADM5_BAD_DB] Database inconsistency detected -\item[KADM5_DUP] Principal or policy already exists -\item[KADM5_RPC_ERROR] Communication failure with server -\item[KADM5_NO_SRV] No administration server found for realm -\item[KADM5_BAD_HIST_KEY] Password history principal key version -mismatch -\item[KADM5_NOT_INIT] Connection to server not initialized -\item[KADM5_UNK_PRINC] Principal does not exist -\item[KADM5_UNK_POLICY] Policy does not exist -\item[KADM5_BAD_MASK] Invalid field mask for operation -\item[KADM5_BAD_CLASS] Invalid number of character classes -\item[KADM5_BAD_LENGTH] Invalid password length -\item[KADM5_BAD_POLICY] Illegal policy name -\item[KADM5_BAD_PRINCIPAL] Illegal principal name. -\item[KADM5_BAD_AUX_ATTR] Invalid auxiliary attributes -\item[KADM5_BAD_HISTORY] Invalid password history count -\item[KADM5_BAD_MIN_PASS_LIFE] Password minimum life is greater -then password maximum life -\item[KADM5_PASS_Q_TOOSHORT] Password is too short -\item[KADM5_PASS_Q_CLASS] Password does not contain enough -character classes -\item[KADM5_PASS_Q_DICT] Password is in the password dictionary -\item[KADM5_PASS_REUSE] Cannot reuse password -\item[KADM5_PASS_TOOSOON] Current password's minimum life has not -expired -\item[KADM5_POLICY_REF] Policy is in use -\item[KADM5_INIT] Connection to server already initialized -\item[KADM5_BAD_PASSWORD] Incorrect password -\item[KADM5_PROTECT_PRINCIPAL] Cannot change protected principal -\item[* KADM5_BAD_SERVER_HANDLE] Programmer error! Bad Admin server handle -\item[* KADM5_BAD_STRUCT_VERSION] Programmer error! Bad API structure version -\item[* KADM5_OLD_STRUCT_VERSION] API structure version specified by application is no longer supported (to fix, recompile application against current Admin API header files and libraries) -\item[* KADM5_NEW_STRUCT_VERSION] API structure version specified by application is unknown to libraries (to fix, obtain current Admin API header files and libraries and recompile application) -\item[* KADM5_BAD_API_VERSION] Programmer error! Bad API version -\item[* KADM5_OLD_LIB_API_VERSION] API version specified by application is no longer supported by libraries (to fix, update application to adhere to current API version and recompile) -\item[* KADM5_OLD_SERVER_API_VERSION] API version specified by application is no longer supported by server (to fix, update application to adhere to current API version and recompile) -\item[* KADM5_NEW_LIB_API_VERSION] API version specified by application is unknown to libraries (to fix, obtain current Admin API header files and libraries and recompile application) -\item[* KADM5_NEW_SERVER_API_VERSION] API version specified by -application is unknown to server (to fix, obtain and install newest -Admin Server) -\item[KADM5_SECURE_PRINC_MISSING] Database error! Required principal missing -\item[KADM5_NO_RENAME_SALT] The salt type of the specified principal -does not support renaming -\item[KADM5_BAD_CLIENT_PARAMS] Illegal configuration parameter for -remote KADM5 client -\item[KADM5_BAD_SERVER_PARAMS] Illegal configuration parameter for -local KADM5 client. -\item[KADM5_AUTH_LIST] Operation requires ``list'' privilege -\item[KADM5_AUTH_CHANGEPW] Operation requires ``change-password'' privilege -\item[KADM5_BAD_TL_TYPE] Programmer error! Illegal tagged data list -element type -\item[KADM5_MISSING_CONF_PARAMS] Required parameters in kdc.conf missing -\item[KADM5_BAD_SERVER_NAME] Bad krb5 admin server hostname -\item[KADM5_AUTH_SETKEY] Operation requires ``set-key'' privilege -\item[KADM5_SETKEY_DUP_ENCTYPES] Multiple values for single or folded enctype -\end{description} - -\section{Authentication and Authorization} -\label{sec:auth} - -Two Kerberos principals exist for use in communicating with the Admin -system: kadmin/admin and kadmin/changepw. Both principals -have the KRB5_KDB_DISALLOW_TGT_BASED bit set in their attributes so -that service tickets for them can only be acquired via a -password-based (AS_REQ) request. Additionally, kadmin/changepw -has the KRB5_KDB_PWCHANGE_SERVICE bit set so that a principal with an -expired password can still obtain a service ticket for it. - -The Admin system accepts requests that are authenticated to either -service principal, but the sets of operations that can be performed by -a request authenticated to each service are different. In particular, -only the functions chpass_principal, randkey_principal, get_principal, -and get_policy can be performed by a request authenticated to the -kadmin/changepw service, and they can only be performed when the -target principal of the operation is the same as the authenticated -client principal; the function semantics descriptions below give the -precise details. This means that administrative operations can only -be performed when authenticated to the kadmin/admin service. The -reason for this distinction is that tickets for kadmin/changepw can be -acquired with an expired password, and the KADM system does not want -to allow an administrator with an expired password to perform -administrative operations on arbitrary principals. - -Each Admin API operation authenticated to the kadmin/admin service -requires a specific authorization to run. This version uses a simple -named privilege system with the following names and meanings: - -\begin{description} -\item[Get] Able to examine the attributes (NOT key data) of principals -and policies. -\item[Add] Able to add principals and policies. -\item[Modify] Able to modify attributes of existing principals and -policies; this does not include changing passwords. -\item[Delete] Able to remove principals and policies. -\item[List] Able to retrieve a list of principals and policies. -\item[Changepw] Able to change the password of principals. -\item[Setkey] Able to set principal keys directly. -\end{description} - -Privileges are specified via an external configuration file on the -Kerberos master server. - -Table \ref{tab:func-overview} summarizes the authorization -requirements of each function. Additionally, each API function -description identifies the privilege required to perform it. The -Authorization checks only happen if you are using the RPC mechanism. -If you are using the server-side API functions locally on the admin -server, the only authorization check is if you can access the -approporiate local files. - -\section{Functions} - -\subsection{Overview} - -The functions provided by the Admin API, and the authorization they -require, are listed in the table \ref{tab:func-overview}. The -``kadm5_'' prefix has been removed from each function name. - -The function semantics in the following sections omit details that are -the same for every function. - -\begin{itemize} -\item The effects of every function are atomic. - -\item Every function performs an authorization check and returns -the appropriate KADM5_AUTH_* error code if the caller does not -have the required privilege. No other information or error code is -ever returned to an unauthorized user. - -\item Every function checks its arguments for NULL pointers or other -obviously invalid values, and returns EINVAL if any are detected. - -\item Any function that performs a policy check uses the policy named -in the principal's policy field. If the POLICY bit is not set in the -principal's aux_attributes field, however, the principal has no -policy, so the policy check is not performed. - -\item Unless otherwise specified, all functions return KADM5_OK. -\end{itemize} - -\begin{table}[htbp] -\caption{Summary of functions and required authorization.} -\label{tab:func-overview} -\begin{tabular}{@{}llp{3.24in}} -\\ -{\bf Function Name} & {\bf Authorization} & {\bf Operation} \\ - -init & none & Open a connection with the kadm5 library. OBSOLETE -but still provided---use init_with_password instead. \\ -init_with_password & none & Open a connection with the kadm5 -library using a password to obtain initial credentials. \\ -init_with_skey & none & Open a connection with the kadm5 library -using the keytab entry to obtain initial credentials. \\ -destroy & none & Close the connection with the kadm5 library. \\ -flush & none & Flush all database changes to disk; no-op when called -remotely. \\ -create_principal & add & Create a new principal. \\ -delete_principal & delete & Delete a principal. \\ -modify_principal & modify & Modify the attributes of an existing - principal (not password). \\ -rename_principal & add and delete & Rename a principal. \\ -get_principal & get\footnotemark & Retrieve a principal. \\ -get_principals & list & Retrieve some or all principal names. \\ -chpass_principal & changepw\footnotemark[\thefootnote] & - Change a principal's password. \\ -chpass_principal_util & changepw\footnotemark[\thefootnote] & Utility wrapper around chpass_principal. \\ -randkey_principal & changepw\footnotemark[\thefootnote] & - Randomize a principal's key. \\ -setkey_principal & setkey & Explicitly set a principal's keys. \\ -decrypt_key & none & Decrypt a principal key. \\ -create_policy & add & Create a new policy. \\ -delete_policy & delete & Delete a policy. \\ -modify_policy & modify & Modify the attributes of a policy. \\ -get_policy & get & Retrieve a policy. \\ -get_policies & list & Retrieve some or all policy names. \\ -free_principal_ent & none & Free the memory associated with an - kadm5_principal_ent_t. \\ -free_policy_ent & none & Free the memory associated with an - kadm5_policy_ent_t. \\ -get_privs & none & Return the caller's admin server privileges. -\end{tabular} -\end{table} -\footnotetext[\thefootnote]{These functions also allow a principal to -perform the operation on itself; see the function's semantics for -details.} - -\subsection{kadm5_init_*} - -In KADM5_API_VERSION 1: - -\begin{verbatim} -kadm5_ret_t kadm5_init_with_password(char *client_name, char *pass, - char *service_name, char *realm, - unsigned long struct_version, - unsigned long api_version, - void **server_handle) - -kadm5_ret_t kadm5_init_with_skey(char *client_name, char *keytab, - char *service_name, char *realm, - unsigned long struct_version, - unsigned long api_version, - void **server_handle) - -kadm5_ret_t kadm5_init(char *client_name, char *pass, - char *service_name, char *realm, - unsigned long struct_version, - unsigned long api_version, - void **server_handle) -\end{verbatim} - -In KADM5_API_VERSION 2: - -\begin{verbatim} -kadm5_ret_t kadm5_init_with_password(char *client_name, char *pass, - char *service_name, - kadm5_config_params *realm_params, - unsigned long struct_version, - unsigned long api_version, - void **server_handle) - -kadm5_ret_t kadm5_init_with_skey(char *client_name, char *keytab, - char *service_name, - kadm5_config_params *realm_params, - unsigned long struct_version, - unsigned long api_version, - void **server_handle) - -kadm5_ret_t kadm5_init(char *client_name, char *pass, - char *service_name, - kadm5_config_params *realm_params, - unsigned long struct_version, - unsigned long api_version, - void **server_handle) - -kadm5_ret_t kadm5_init_with_creds(char *client_name, - krb5_ccache ccache, - char *service_name, - kadm5_config_params *params, - krb5_ui_4 struct_version, - krb5_ui_4 api_version, - void **server_handle) -\end{verbatim} - -AUTHORIZATION REQUIRED: none - -NOTE: kadm5_init is an obsolete function provided for backwards -compatibility. It is identical to kadm5_init_with_password. - -These three functions open a connection to the kadm5 library and -initialize any necessary state information. They behave differently -when called from local and remote clients. - -In KADM5_API_VERSION_2, these functions take a kadm5_config_params -structure instead of a realm name as an argument. The semantics are -similar: if a NULL pointer is passed for the realm_params argument, -the default realm and default parameters for that realm, as specified -in the krb5 configuration file (e.g. /etc/krb5.conf) are used. If a -realm_params structure is provided, the fields that are set override -the default values. If a parameter is specified to the local or -remote libraries that does not apply to that side, an error code -(KADM5_BAD_CLIENT_PARAMS or KADM5_BAD_SERVER_PARAMS) is returned. See -section \ref{sec:configparams} for a discussion of configuration -parameters. - -For remote clients, the semantics are: - -\begin{enumerate} -\item Initializes all the com_err error tables used by the Admin -system. - -\item Acquires configuration parameters. In KADM5_API_VERSION_1, all -the defaults specified in the configuration file are used, according -to the realm. In KADM5_API_VERSION_2, the values in params_in are -merged with the default values. If an illegal mask value is -specified, KADM5_BAD_CLIENT_PARAMS is returned. - -\item Acquires a Kerberos ticket for the specified service. - -\begin{enumerate} -\item The ticket's client is client_name, which can be any valid -Kerberos principal. If client_name does not include a realm, the -default realm of the local host is used -\item The ticket's service is service_name@realm. service_name must -be one of the constants KADM5_ADMIN_SERVICE or -KADM5_CHANGEPW_SERVICE. -\item If realm is NULL, client_name's realm is used. - -\item For init_with_password, an initial ticket is acquired and -decoded with the password pass, which must be client_name's password. -If pass is NULL or an empty string, the user is prompted (via the tty) -for a password. - -\item For init_with_skey, an initial ticket is acquired and decoded -with client_name's key obtained from the specified keytab. If keytab -is NULL or an empty string the default keytab is used. - -\item For init_with_creds, ccache must be an open credential cache -that already has a ticket for the specified client and server. -Alternatively, if a site chooses to disable the DISALLOW_TGT_BASED -flag on the admin and changepw principals, the ccache can contain a -ticket-granting ticket for client_name. -\end{enumerate} - -\item Creates a GSS-API authenticated connection to the Admin server, -using the just-acquired Kerberos ticket. - -\item Verifies that the struct_version and api_version specified by -the caller are valid and known to the library. - -\item Sends the specified api_version to the server. - -\item Upon successful completion, fills in server_handle with a handle -for this connection, to be used in all subsequent API calls. -\end{enumerate} - -The caller should always specify KADM5_STRUCT_VERSION for the -struct_version argument, a valid and supported API version constant -for the api_version argument (currently, KADM5_API_VERSION_1 or -KADM5_API_VERSION_2), and a valid pointer in which the server handle -will be stored. - -If any kadm5_init_* is invoked locally its semantics are: - -\begin{enumerate} -\item Initializes all the com_err error tables used by the Admin -system. - -\item Acquires configuration parameters. In KADM5_API_VERSION_1, all -the defaults specified in the configuration file are used, according -to the realm. In KADM5_API_VERSION_2, the values in params_in are -merged with the default values. If an illegal mask value is -specified, KADM5_BAD_SERVER_PARAMS is returned. - -\item Initializes direct access to the KDC database. In -KADM5_API_VERISON_1, if pass (or keytab) is NULL or an empty string, -reads the master password from the stash file; otherwise, the non-NULL -password is ignored and the user is prompted for it via the tty. In -KADM5_API_VERSION_2, if the MKEY_FROM_KEYBOARD parameter mask is set -and the value is non-zero, reads the master password from the user via -the tty; otherwise, the master key is read from the stash file. -Calling init_with_skey or init_with_creds with the MKEY_FROM_KEYBOARD -mask set with a non-zero field is illegal, and calling them without -the mask set is exactly like calling init_with_password. - -\item Initializes the dictionary (if present) for dictionary checks. - -\item Parses client_name as a Kerberos principal. client_name should -usually be specified as the name of the program. - -\item Verifies that the struct_version and api_version specified by -the caller are valid. - -\item Fills in server_handle with a handle containing all state -information (version numbers and client name) for this ``connection.'' -\end{enumerate} -The service_name argument is not used. - -RETURN CODES: - -\begin{description} -\item[KADM5_NO_SRV] No Admin server can be found for the -specified realm. - -\item[KADM5_RPC_ERROR] The RPC connection to the server cannot be -initiated. - -\item[KADM5_BAD_PASSWORD] Incorrect password. - -\item[KADM5_SECURE_PRINC_MISSING] The principal -KADM5_ADMIN_SERVICE or KADM5_CHANGEPW_SERVICE does not -exist. This is a special-case replacement return code for ``Server -not found in database'' for these required principals. - -\item[KADM5_BAD_CLIENT_PARAMS] A field in the parameters mask was -specified to the remote client library that is not legal for remote -clients. - -\item[KADM5_BAD_SERVER_PARAMS] A field in the parameters mask was -specified to the local client library that is not legal for local -clients. -\end{description} - -\subsection{kadm5_flush} - -\begin{verbatim} -kadm5_ret_t kadm5_flush(void *server_handle) -\end{verbatim} - -AUTHORIZATION REQUIRED: none - -Flush all changes to the Kerberos databases, leaving the connection to -the Admin API open. This function behaves differently when called by -local and remote clients. - -For local clients, the function closes and reopens the Kerberos -database with krb5_db_fini() and krb5_db_init(). -Although it is unlikely, either of these functions -could return errors; in that case, this function calls -kadm5_destroy and returns the error code. Therefore, if -kadm5_flush does not return KADM5_OK, the connection to the -Admin server has been terminated and, in principle, the databases -might be corrupt. - -For remote clients, the function is a no-op. - -\subsection{kadm5_destroy} - -\begin{verbatim} -kadm5_ret_t kadm5_destroy(void *server_handle) -\end{verbatim} - -AUTHORIZATION REQUIRED: none - -Close the connection to the Admin server and releases all related -resources. This function behaves differently when called by local and -remote clients. - -For remote clients, the semantics are: - -\begin{enumerate} -\item Destroy the temporary credential cache created by -kadm5_init. - -\item Tear down the GSS-API context negotiated with the server. - -\item Close the RPC connection. - -\item Free storage space associated with server_handle, after erasing -its magic number so it won't be mistaken for a valid handle by the -library later. -\end{enumerate} - -For local clients, this function just frees the storage space -associated with server_handle after erasing its magic number. - -RETURN CODES: - -\subsection{kadm5_create_principal} - -\begin{verbatim} -kadm5_ret_t -kadm5_create_principal(void *server_handle, - kadm5_principal_ent_t princ, u_int32 mask, - char *pw); -\end{verbatim} - -AUTHORIZATION REQUIRED: add - -\begin{enumerate} - -\item Return KADM5_BAD_MASK if the mask is invalid. -\item If the named principal exists, return KADM5_DUP. -\item If the POLICY bit is set and the named policy does not exist, -return KADM5_UNK_POLICY. -\item If KADM5_POLICY bit is set in aux_attributes check to see if -the password does not meets quality standards, return the appropriate -KADM5_PASS_Q_* error code if it fails. -\item Store the principal, set the key; see section \ref{sec:keys}. -\item If the POLICY bit is set, increment the named policy's reference -count by one. - -\item Set the pw_expiration field. -\begin{enumerate} -\item If the POLICY bit is set in mask, then if pw_max_life is non-zero, -set pw_expiration to now + pw_maxlife, otherwise set pw_max_life to -never. -\item If the PW_EXPIRATION bit is set in mask, set pw_expiration to -the requested value, overriding the value set above. -\end{enumerate} -NOTE: This is a change from the original semantics, in which policy -expiration was enforced even on administrators. The old semantics are -not preserved, even for version 1 callers, because this is a -server-specific policy decision; besides, the new semantics are less -restrictive, so all previous callers should continue to function -properly. - -\item Set mod_date to now and set mod_name to caller. -\item Set last_pwd_change to now. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_BAD_MASK] The field mask is invalid for a create -operation. -\item[KADM5_DUP] Principal already exists. -\item[KADM5_UNK_POLICY] Policy named in entry does not exist. -\item[KADM5_PASS_Q_*] Specified password does not meet policy -standards. -\end{description} - -\subsection{kadm5_delete_principal} - -\begin{verbatim} -kadm5_ret_t -kadm5_delete_principal(void *server_handle, krb5_principal princ); -\end{verbatim} - -AUTHORIZATION REQUIRED: delete - -\begin{enumerate} -\item Return KADM5_UNK_PRINC if the principal does not exist. -\item If the POLICY bit is set in aux_attributes, decrement the named -policy's reference count by one. -\item Delete principal. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_UNK_PRINC] Principal does not exist. -\end{description} - -\subsection{kadm5_modify_principal} - -\begin{verbatim} -kadm5_ret_t -kadm5_modify_principal(void *server_handle, - kadm5_principal_ent_t princ, u_int32 mask); -\end{verbatim} - -Modify the attributes of the principal named in -kadm5_principal_ent_t. This does not allow the principal to be -renamed or for its password to be changed. - -AUTHORIZATION REQUIRED: modify - -Although a principal's pw_expiration is usually computed based on its -policy and the time at which it changes its password, this function -also allows it to be specified explicitly. This allows an -administrator, for example, to create a principal and assign it to a -policy with a pw_max_life of one month, but to declare that the new -principal must change its password away from its initial value -sometime within the first week. - -\begin{enumerate} -\item Return KADM5_UNK_PRINC if the principal does not exist. -\item Return KADM5_BAD_MASK if the mask is invalid. -\item If POLICY bit is set but the new policy does not exist, return -KADM5_UNK_POLICY. -\item If either the POLICY or POLICY_CLR bits are set, update the -corresponding bits in aux_attributes. - -\item Update policy reference counts. -\begin{enumerate} -\item If the POLICY bit is set, then increment policy count on new -policy. -\item If the POLICY or POLICY_CLR bit is set, and the POLICY bit in -aux_attributes is set, decrement policy count on old policy. -\end{enumerate} - -\item Set pw_expiration appropriately. pw_expiration can change if: -the POLICY bit is set in mask, so the principal is changing to a -policy (either from another policy or no policy); the POLICY_CLR bit -is set in mask, so the principal is changing to no policy; or -PW_EXPIRATION is set. -\begin{enumerate} -\item If the POLICY bit is set in mask, set pw_expiration to -last_pwd_change + pw_max_life if pw_max_life is non-zero, otherwise -set pw_expiration to never. -\item If the POLICY_CLR biti s set in mask, set pw_expiration to -never. -\item If PW_EXPIRATION is set, set pw_expiration to the requested -value, overriding the value from the previous two cases. NOTE: This -is a change from the original semantics, in which policy expiration -was enforced even on administrators. The old semantics are not -preserved, even for version 1 callers, because this is a -server-specific policy decision; besides, the new semantics are less -restrictive, so all previous callers should continue to function -properly. -\end{enumerate} - -% Here is the previous, and confusing, text of pw_expiration semantics: -%\begin{enumerate} -%\item If the POLICY bit is not set in aux_attributes, then -%\begin{enumerate} -%\item if the PW_EXPIRATION bit is set, set pw_expiration to the given -%value, else -%\item set pw_expiration to never. -%\end{enumerate} -%\item Otherwise, if the PW_EXPIRATION bit is set, set pw_expiration to -%the sooner of the given value and last_pwd_change + pw_max_life. -%\item Otherwise, set pw_expiration to last_pwd_change + pw_max_life. -%\end{enumerate} - -\item Update the remaining fields specified in the mask. -\item Update mod_name field to caller and mod_date to now. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_UNK_PRINC] Entry does not exist. -\item[KADM5_BAD_MASK] The mask is not valid for a modify -operation. -\item[KADM5_UNK_POLICY] The POLICY bit is set but the new -policy does not exist. -\item[KADM5_BAD_TL_TYPE] The KADM5_TL_DATA bit is set in mask, and the -given tl_data list contains an element whose type is less than 256. -\end{description} - -\subsection{kadm5_rename_principal} - -\begin{verbatim} -kadm5_ret_t -kadm5_rename_principal(void *server_handle, krb5_principal source, - krb5_principal target); -\end{verbatim} - -AUTHORIZATION REQUIRED: add and delete - -\begin{enumerate} -\item Check to see if source principal exists, if not return -KADM5_UNK_PRINC error. -\item Check to see if target exists, if so return KADM5_DUP error. -\item Create the new principal named target, then delete the old -principal named source. All of target's fields will be the same as -source's fields, except that mod_name and mod_date will be updated to -reflect the current caller and time. -\end{enumerate} - -Note that since the principal name may have been used as the salt for -the principal's key, renaming the principal may render the principal's -current password useless; with the new salt, the key generated by -string-to-key on the password will suddenly be different. Therefore, -an application that renames a principal must also require the user to -specify a new password for the principal (and administrators should -notify the affected party). - -Note also that, by the same argument, renaming a principal will -invalidate that principal's password history information; since the -salt will be different, a user will be able to select a previous -password without error. - -RETURN CODES: - -\begin{description} -\item[KADM5_UNK_PRINC] Source principal does not exist. -\item[KADM5_DUP] Target principal already exist. -\end{description} - -\subsection{kadm5_chpass_principal} - -\begin{verbatim} -kadm5_ret_t -kadm5_chpass_principal(void *server_handle, krb5_principal princ, - char *pw); -\end{verbatim} - -AUTHORIZATION REQUIRED: changepw, or the calling principal being the -same as the princ argument. If the request is authenticated to the -kadmin/changepw service, the changepw privilege is disregarded. - -Change a principal's password. See section \ref{sec:keys} for a -description of how the keys are determined. - -This function enforces password policy and dictionary checks. If the new -password specified is in the password dictionary, and the policy bit is set -KADM5_PASS_DICT is returned. If the principal's POLICY bit is set in -aux_attributes, compliance with each of the named policy fields is verified -and an appropriate error code is returned if verification fails. - -Note that the policy checks are only be performed if the POLICY bit is -set in the principal's aux_attributes field. - -\begin{enumerate} -\item Make sure principal exists, if not return KADM5_UNK_PRINC error. -\item If caller does not have modify privilege, (now - last_pwd_change) $<$ -pw_min_life, and the KRB5_KDB_REQUIRES_PWCHANGE bit is not set in the -principal's attributes, return KADM5_PASS_TOOSOON. -\item If the principal your are trying to change is kadmin/history -return KADM5_PROTECT_PRINCIPAL. -\item If the password does not meet the quality -standards, return the appropriate KADM5_PASS_Q_* error code. -\item Convert password to key; see section \ref{sec:keys}. -\item If the new key is in the principal's password history, return -KADM5_PASS_REUSE. -\item Store old key in history. -\item Update principal to have new key. -\item Increment principal's key version number by one. -\item If the POLICY bit is set, set pw_expiration to now + -max_pw_life. If the POLICY bit is not set, set pw_expiration to -never. -\item If the KRB5_KDB_REQUIRES_PWCHANGE bit is set in the principal's -attributes, clear it. -\item Update last_pwd_change and mod_date to now, update mod_name to -caller. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_UNK_PRINC] Principal does not exist. -\item[KADM5_PASS_Q_*] Requested password does not meet quality -standards. -\item[KADM5_PASS_REUSE] Requested password is in user's -password history. -\item[KADM5_PASS_TOOSOON] Current password has not reached minimum life -\item[KADM5_PROTECT_PRINCIPAL] Cannot change the password of a special principal -\end{description} - - -\subsection{kadm5_chpass_principal_util} - -\begin{verbatim} -kadm5_ret_t -kadm5_chpass_principal_util(void *server_handle, krb5_principal princ, - char *new_pw, char **pw_ret, - char *msg_ret); -\end{verbatim} - -AUTHORIZATION REQUIRED: changepw, or the calling principal being the -same as the princ argument. If the request is authenticated to the -kadmin/changepw service, the changepw privilege is disregarded. - -This function is a wrapper around kadm5_chpass_principal. It can -read a new password from a user, change a principal's password, and -return detailed error messages. msg_ret should point to a char buffer -in the caller's space of sufficient length for the error messages -described below. 1024 bytes is recommended. It will also return the -new password to the caller if pw_ret is non-NULL. - -\begin{enumerate} -\item If new_pw is NULL, this routine will prompt the user for the new -password (using the strings specified by KADM5_PW_FIRST_PROMPT and -KADM5_PW_SECOND_PROMPT) and read (without echoing) the password input. -Since it is likely that this will simply call krb5_read_password only -terminal-based applications will make use of the password reading -functionality. If the passwords don't match the string ``New passwords do -not match - password not changed.'' will be copied into msg_ret, and the -error code KRB5_LIBOS_BADPWDMATCH will be returned. For other errors that -occur while reading the new password, copy the string ``<com_err message$>$ -occurred while trying to read new password.'' followed by a blank line and -the string specified by CHPASS_UTIL_PASSWORD_NOT_CHANGED into msg_ret and -return the error code returned by krb5_read_password. - -\item If pw_ret is non-NULL, and the password was prompted, set *pw_ret to -point to a static buffer containing the password. If pw_ret is non-NULL -and the password was supplied, set *pw_ret to the supplied password. - -\item Call kadm5_chpass_principal with princ, and new_pw. - -\item If successful copy the string specified by CHPASS_UTIL_PASSWORD_CHANGED -into msg_ret and return zero. - -\item For a policy related failure copy the appropriate message (from below) -followed by a newline and ``Password not changed.'' into msg_ret -filling in the parameters from the principal's policy information. If -the policy information cannot be obtained copy the generic message if -one is specified below. Return the error code from -kadm5_chpass_principal. - -Detailed messages: -\begin{description} - -\item[PASS_Q_TOO_SHORT] -New password is too short. Please choose a -password which is more than $<$pw-min-len$>$ characters. - -\item[PASS_Q_TOO_SHORT - generic] -New password is too short. Please choose a longer password. - -\item[PASS_REUSE] -New password was used previously. Please choose a -different password. - -\item[PASS_Q_CLASS] -New password does not have enough character classes. Classes include -lower class letters, upper case letters, digits, punctuation and all -other characters. Please choose a password with at least -$<$min-classes$>$ character classes. - -\item[PASS_Q_CLASS - generic] -New password does not have enough character classes. Classes include -lower class letters, upper case letters, digits, punctuation and all -other characters. - -\item[PASS_Q_DICT] -New password was found in a dictionary of possible passwords and -therefore may be easily guessed. Please choose another password. See -the kpasswd man page for help in choosing a good password. - -\item[PASS_TOOSOON] -Password cannot be changed because it was changed too recently. Please -wait until $<$last-pw-change+pw-min-life$>$ before you change it. If you -need to change your password before then, contact your system -security administrator. - -\item[PASS_TOOSOON - generic] -Password cannot be changed because it was changed too recently. If you -need to change your now please contact your system security -administrator. -\end{description} - -\item For other errors copy the string ``$<$com_err message$>$ -occurred while trying to change password.'' following by a blank line -and ``Password not changed.'' into msg_ret. Return the error code -returned by kadm5_chpass_principal. -\end{enumerate} - - -RETURN CODES: - -\begin{description} -\item[KRB5_LIBOS_BADPWDMATCH] Typed new passwords did not match. -\item[KADM5_UNK_PRINC] Principal does not exist. -\item[KADM5_PASS_Q_*] Requested password does not meet quality -standards. -\item[KADM5_PASS_REUSE] Requested password is in user's -password history. -\item[KADM5_PASS_TOOSOON] Current password has not reached minimum -life. -\end{description} - -\subsection{kadm5_randkey_principal} - -In KADM5_API_VERSION_1: - -\begin{verbatim} -kadm5_ret_t -kadm5_randkey_principal(void *server_handle, krb5_principal princ, - krb5_keyblock **new_key) -\end{verbatim} - -In KADM5_API_VERSION_2: - -\begin{verbatim} -kadm5_ret_t -kadm5_randkey_principal(void *server_handle, krb5_principal princ, - krb5_keyblock **new_keys, int *n_keys) -\end{verbatim} - -AUTHORIZATION REQUIRED: changepw, or the calling principal being the -same as the princ argument. If the request is authenticated to the -kadmin/changepw service, the changepw privilege is disregarded. - -Generate and assign a new random key to the named principal, and -return the generated key in allocated storage. In -KADM5_API_VERSION_2, multiple keys may be generated and returned as an -array, and n_new_keys is filled in with the number of keys generated. -See section \ref{sec:keys} for a description of how the keys are -chosen. In KADM5_API_VERSION_1, the caller must free the returned -krb5_keyblock * with krb5_free_keyblock. In KADM5_API_VERSION_2, the -caller must free each returned keyblock with krb5_free_keyblock. - -If the principal's POLICY bit is set in aux_attributes and the caller does -not have modify privilege , compliance with the password minimum life -specified by the policy is verified and an appropriate error code is returned -if verification fails. - -\begin{enumerate} -\item If the principal does not exist, return KADM5_UNK_PRINC. -\item If caller does not have modify privilege, (now - last_pwd_change) $<$ -pw_min_life, and the KRB5_KDB_REQUIRES_PWCHANGE bit is not set in the -principal's attributes, return KADM5_PASS_TOOSOON. -\item If the principal you are trying to change is kadmin/history return -KADM5_PROTECT_PRINCIPAL. -\item Store old key in history. -\item Update principal to have new key. -\item Increment principal's key version number by one. -\item If the POLICY bit in aux_attributes is set, set pw_expiration to -now + max_pw_life. -\item If the KRB5_KDC_REQUIRES_PWCHANGE bit is set in the principal's -attributes, clear it. -\item Update last_pwd_change and mod_date to now, update mod_name to -caller. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_UNK_PRINC] Principal does not exist. -\item[KADM5_PASS_TOOSOON] The minimum lifetime for the current -key has not expired. -\item[KADM5_PROTECT_PRINCIPAL] Cannot change the password of a special -principal -\end{description} - -This function can also be used as part of a sequence to create a new -principal with a random key. The steps to perform the operation -securely are - -\begin{enumerate} -\item Create the principal with kadm5_create_principal with a -random password string and with the KRB5_KDB_DISALLOW_ALL_TIX bit set -in the attributes field. - -\item Randomize the principal's key with kadm5_randkey_principal. - -\item Call kadm5_modify_principal to reset the -KRB5_KDB_DISALLOW_ALL_TIX bit in the attributes field. -\end{enumerate} - -The three steps are necessary to ensure secure creation. Since an -attacker might be able to guess the initial password assigned by the -client program, the principal must be disabled until the key can be -truly randomized. - -\subsection{kadm5_setkey_principal} - -\begin{verbatim} -kadm5_ret_t -kadm5_setkey_principal(void *server_handle, krb5_principal princ, - krb5_keyblock *new_keys, int n_keys) -\end{verbatim} - -AUTHORIZATION REQUIRED: setkey. This function does not allow the use -of regular changepw authorization because it bypasses the password -policy mechanism. - -This function only exists in KADM5_API_VERSION_2. - -Explicitly sets the specified principal's keys to the n_keys keys in -the new_keys array. The keys in new_keys should not be encrypted in -the Kerberos master key; this function will perform that operation -itself (the keys will be protected during transmission from the -calling client to the kadmind server by the AUTH_GSSAPI RPC layer). -This function completely bypasses the principal's password policy, if -set. - -\begin{enumerate} -\item If the principal does not exist, return KADM5_UNK_PRINC. -\item If the principal you are trying to change is kadmin/history return -KADM5_PROTECT_PRINCIPAL. -\item If new_keys contains more than one key of any ENCTYPE_DES_CBC_* -type that is folded, return KADM5_SETKEY_DUP_ENCTYPES. -\item Store old key in history. -\item Update principal to have new key. -\item Increment principal's key version number by one. -\item If the POLICY bit in aux_attributes is set, set pw_expiration to -now + max_pw_life. -\item If the KRB5_KDC_REQUIRES_PWCHANGE bit is set in the principal's -attributes, clear it. -\item Update last_pwd_change and mod_date to now, update mod_name to -caller. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_UNK_PRINC] Principal does not exist. -\item[KADM5_PROTECT_PRINCIPAL] Cannot change the password of a special -principal -\end{description} - -This function can also be used as part of a sequence to create a new -principal with an explicitly key. The steps to perform the operation -securely are - -\begin{enumerate} -\item Create the principal with kadm5_create_principal with a -random password string and with the KRB5_KDB_DISALLOW_ALL_TIX bit set -in the attributes field. - -\item Set the principal's key with kadm5_setkey_principal. - -\item Call kadm5_modify_principal to reset the -KRB5_KDB_DISALLOW_ALL_TIX bit in the attributes field. -\end{enumerate} - -The three steps are necessary to ensure secure creation. Since an -attacker might be able to guess the initial password assigned by the -client program, the principal must be disabled until the key can be -truly randomized. - -\subsection{kadm5_get_principal} - -In KADM5_API_VERSION_1: - -\begin{verbatim} -kadm5_ret_t -kadm5_get_principal(void *server_handle, krb5_principal princ, - kadm5_principal_ent_t *ent); -\end{verbatim} - -In KADM5_API_VERSION_2: - -\begin{verbatim} -kadm5_ret_t -kadm5_get_principal(void *server_handle, krb5_principal princ, - kadm5_principal_ent_t ent, u_int32 mask); -\end{verbatim} - -AUTHORIZATION REQUIRED: get, or the calling principal being the same -as the princ argument. If the request is authenticated to the -kadmin/changepw service, the get privilege is disregarded. - -In KADM5_API_VERSION_1, return all of the principal's attributes in -allocated memory; if an error is returned entry is set to NULL. In -KADM5_API_VERSION_2, fill in the fields of the principal structure -specified in the mask; memory for the structure is not allocated. -Typically, a caller will specify the mask KADM5_PRINCIPAL_NORMAL_MASK, -which includes all the fields {\it except} key_data and tl_data to -improve time and memory efficiency. A caller that wants key_data and -tl_data can bitwise-OR those masks onto NORMAL_MASK. Note that even -if KADM5_TL_DATA is specified, this function will not return internal -tl_data elements whose type is less than 256. - -The caller must free the returned entry with kadm5_free_principal_ent. - -The function behaves differently for local and remote clients. For -remote clients, the KEY_DATA mask is illegal and results in a -KADM5_BAD_MASK error. - -RETURN CODES: - -\begin{description} -\item[KADM5_UNK_PRINC] Principal does not exist. -\item[KADM5_BAD_MASK] The mask is not valid for a get operation. - -\end{description} - -\subsection{kadm5_decyrpt_key} - -\begin{verbatim} -kadm5_ret_t kadm5_decrypt_key(void *server_handle, - kadm5_principal_ent_t entry, krb5_int32 - ktype, krb5_int32 stype, krb5_int32 - kvno, krb5_keyblock *keyblock, - krb5_keysalt *keysalt, int *kvnop) -\end{verbatim} - -AUTHORIZATION REQUIRED: none, local function - -Searches a principal's key_data array to find a key with the specified -enctype, salt type, and kvno, and decrypts the key into keyblock and -keysalt if found. entry must have been returned by -kadm5_get_principal with at least the KADM5_KEY_DATA mask set. -Returns ENOENT if the key cannot be found, EINVAL if the key_data -array is empty (as it always is in an RPC client). - -If ktype or stype is -1, it is ignored for the search. If kvno is -1, -ktype and stype are ignored and the key with the max kvno is returned. -If kvno is 0, only the key with the max kvno is returned and only if -it matches the ktype and stype; otherwise, ENOENT is returned. - -\subsection{kadm5_get_principals} - -\begin{verbatim} -kadm5_ret_t -kadm5_get_principals(void *server_handle, char *exp, - char ***princs, int *count) -\end{verbatim} - -Retrieves the list of principal names. - -AUTHORIZATION REQUIRED: list - -If \v{exp} is NULL, all principal names are retrieved; otherwise, -principal names that match the expression exp are retrieved. -\v{princs} is filled in with a pointer to a NULL-terminated array of -strings, and \v{count} is filled in with the number of principal names -in the array. \v{princs} must be freed with a call to -\v{kadm5_free_name_list}. - -All characters in the expression match themselves except ``?'' which -matches any single character, ``*'' which matches any number of -consecutive characters, and ``[chars]'' which matches any single -character of ``chars''. Any character which follows a ``$\backslash$'' -matches itself exactly, and a ``$\backslash$'' cannot be the last -character in the string. - -\subsection{kadm5_create_policy} - -\begin{verbatim} -kadm5_ret_t -kadm5_create_policy(void *server_handle, - kadm5_policy_ent_t policy, u_int32 mask); -\end{verbatim} - -Create a new policy. - -AUTHORIZATION REQUIRED: add - -\begin{enumerate} -\item Check to see if mask is valid, if not return KADM5_BAD_MASK error. -\item Return KADM5_BAD_POLICY if the policy name contains illegal -characters. - -\item Check to see if the policy already exists, if so return -KADM5_DUP error. -\item If the PW_MIN_CLASSES bit is set and pw_min_classes is not 1, 2, -3, 4, or 5, return KADM5_BAD_CLASS. -\item Create a new policy setting the appropriate fields determined -by the mask. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_DUP] Policy already exists -\item[KADM5_BAD_MASK] The mask is not valid for a create -operation. -\item[KADM5_BAD_CLASS] The specified number of character classes -is invalid. -\item[KADM5_BAD_POLICY] The policy name contains illegal characters. -\end{description} - -\subsection{kadm5_delete_policy} - -\begin{verbatim} -kadm5_ret_t -kadm5_delete_policy(void *server_handle, char *policy); -\end{verbatim} - -Deletes a policy. - -AUTHORIZATION REQUIRED: delete - -\begin{enumerate} -\item Return KADM5_BAD_POLICY if the policy name contains illegal -characters. -\item Return KADM5_UNK_POLICY if the named policy does not exist. -\item Return KADM5_POLICY_REF if the named policy's refcnt is not 0. -\item Delete policy. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_BAD_POLICY] The policy name contains illegal characters. -\item[KADM5_UNK_POLICY] Policy does not exist. -\item[KADM5_POLICY_REF] Policy is being referenced. -\end{description} - -\subsection{kadm5_modify_policy} - -\begin{verbatim} -kadm5_ret_t -kadm5_modify_policy(void *server_handle, - kadm5_policy_ent_t policy, u_int32 mask); -\end{verbatim} - -Modify an existing policy. Note that modifying a policy has no affect -on a principal using the policy until the next time the principal's -password is changed. - -AUTHORIZATION REQUIRED: modify - -\begin{enumerate} -\item Return KADM5_BAD_POLICY if the policy name contains illegal -characters. -\item Check to see if mask is legal, if not return KADM5_BAD_MASK error. -\item Check to see if policy exists, if not return -KADM5_UNK_POLICY error. -\item If the PW_MIN_CLASSES bit is set and pw_min_classes is not 1, 2, -3, 4, or 5, return KADM5_BAD_CLASS. -\item Update the fields specified in the mask. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_BAD_POLICY] The policy name contains illegal characters. -\item[KADM5_UNK_POLICY] Policy not found. -\item[KADM5_BAD_MASK] The mask is not valid for a modify -operation. -\item[KADM5_BAD_CLASS] The specified number of character classes -is invalid. -\end{description} - -\subsection{kadm5_get_policy} - -In KADM5_API_VERSION_1: - -\begin{verbatim} -kadm5_ret_t -kadm5_get_policy(void *server_handle, char *policy, kadm5_policy_ent_t *ent); -\end{verbatim} - -In KADM5_API_VERSION_2: - -\begin{verbatim} -kadm5_ret_t -kadm5_get_policy(void *server_handle, char *policy, kadm5_policy_ent_t ent); -\end{verbatim} - -AUTHORIZATION REQUIRED: get, or the calling principal's policy being -the same as the policy argument. If the request is authenticated to -the kadmin/changepw service, the get privilege is disregarded. - -In KADM5_API_VERSION_1, return the policy's attributes in allocated -memory; if an error is returned entry is set to NULL. In -KADM5_API_VERSION_2, fill in fields of the policy structure allocated -by the caller. The caller must free the returned entry with -kadm5_free_policy_ent - -RETURN CODES: - -\begin{description} -\item[KADM5_BAD_POLICY] The policy name contains illegal characters. -\item[KADM5_UNK_POLICY] Policy not found. -\end{description} - -\subsection{kadm5_get_policies} - -\begin{verbatim} -kadm5_ret_t -kadm5_get_policies(void *server_handle, char *exp, - char ***pols, int *count) -\end{verbatim} - -Retrieves the list of principal names. - -AUTHORIZATION REQUIRED: list - -If \v{exp} is NULL, all principal names are retrieved; otherwise, -principal names that match the expression exp are retrieved. \v{pols} -is filled in with a pointer to a NULL-terminated array of strings, and -\v{count} is filled in with the number of principal names in the -array. \v{pols} must be freed with a call to -\v{kadm5_free_name_list}. - -All characters in the expression match themselves except ``?'' which -matches any single character, ``*'' which matches any number of -consecutive characters, and ``[chars]'' which matches any single -character of ``chars''. Any character which follows a ``$\backslash$'' -matches itself exactly, and a ``$\backslash$'' cannot be the last -character in the string. - -\subsection{kadm5_free_principal_ent, _policy_ent} - -\begin{verbatim} -void kadm5_free_principal_ent(void *server_handle, - kadm5_principal_ent_t princ); -\end{verbatim} - -In KADM5_API_VERSION_1, free the structure and contents allocated by a -call to kadm5_get_principal. In KADM5_API_VERSION_2, free the -contents allocated by a call to kadm5_get_principal. - -AUTHORIZATION REQUIRED: none (local operation) - -\begin{verbatim} -void kadm5_free_policy_ent(kadm5_policy_ent_t policy); -\end{verbatim} - -Free memory that was allocated by a call to kadm5_get_policy. If -the argument is NULL, the function returns successfully. - -AUTHORIZATION REQUIRED: none (local operation) - -\subsection{kadm5_free_name_list} - -\begin{verbatim} -void kadm5_free_name_list(void *server_handle, - char **names, int *count); -\end{verbatim} - -Free the memory that was allocated by kadm5_get_principals or -kadm5_get_policies. names and count must be a matched pair of -values returned from one of those two functions. - -\subsection{kadm5_free_key_data} - -\begin{verbatim} -void kadm5_free_key_data(void *server_handle, - krb5_int16 *n_key_data, krb5_key_data *key_data) -\end{verbatim} - -Free the memory that was allocated by kadm5_randkey_principal. -n_key_data and key_data must be a matched pair of values returned from -that function. - -\subsection{kadm5_get_privs} - -\begin{verbatim} -kadm5_ret_t -kadm5_get_privs(void *server_handle, u_int32 *privs); -\end{verbatim} - -Return the caller's admin server privileges in the integer pointed to -by the argument. The Admin API does not define any way for a -principal's privileges to be set. Note that this function will -probably be removed or drastically changed in future versions of this -system. - -The returned value is a bitmask indicating the caller's privileges: - -\begin{tabular}{llr} -{\bf Privilege} & {\bf Symbol} & {\bf Value} \\ -Get & KADM5_PRIV_GET & 0x01 \\ -Add & KADM5_PRIV_ADD & 0x02 \\ -Modify & KADM5_PRIV_MODIFY & 0x04 \\ -Delete & KADM5_PRIV_DELETE & 0x08 \\ -List & KADM5_PRIV_LIST & 0x10 \\ -Changepw & KADM5_PRIV_CPW & 0x20 -\end{tabular} - -There is no guarantee that a caller will have a privilege indicated by -this function for any length of time or for any particular target; -applications using this function must still be prepared to handle all -possible KADM5_AUTH_* error codes. - -In the initial MIT Kerberos version of the admin server, permissions -depend both on the caller and the target; this function returns a -bitmask representing all privileges the caller can possibly have for -any possible target. - -\end{document} diff --git a/crypto/krb5/doc/kadm5/api-server-design.tex b/crypto/krb5/doc/kadm5/api-server-design.tex deleted file mode 100644 index 2cf0fe84f363..000000000000 --- a/crypto/krb5/doc/kadm5/api-server-design.tex +++ /dev/null @@ -1,1054 +0,0 @@ -% This document is included for historical purposes only, and does not -% apply to krb5 today. - -\documentstyle[12pt,fullpage]{article} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Make _ actually generate an _, and allow line-breaking after it. -\let\underscore=\_ -\catcode`_=13 -\def_{\underscore\penalty75\relax} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\setlength{\parskip}{.7\baselineskip} -\setlength{\parindent}{0pt} - -\def\v#1{\verb+#1+} -\def\k#1{K$_#1$} - -\title{KADM5 Library and Server \\ Implementation Design} -\author{Barry Jaspan} - -\begin{document} - -\sloppy -\maketitle - -{\setlength{\parskip}{0pt}\tableofcontents} - -\section{Overview} - -The KADM5 administration system is designed around the KADM5 API. The -``server-side'' library libkadm5srv.a implements the KADM5 API by -operating directly on the underlying KDC and admin databases. The -``client-side'' library libkadm5clnt.a implements the KADM5 API via an -RPC mechanism. The administration server kadmind accepts RPC requests -from the client-side library and translates them into calls to the -server-side library, performing authentication, authorization, and -logging along the way. - -The two libraries, libkadm5clnt.a and libkadm5srv.a, export the -identical kadm5 interface; for example, both contain definitions for -kadm5_get_principal, and all other kadm5 functions. In most cases, -the client library function just marshalls arguments and results into -and out of an RPC call, whereas the server library function performs -the actual operation on the database file. kadm5_init_*, however, are -substantially different even though they export the same interface: on -the client, they establish the RPC connection and GSS-API context, -whereas on the server side the open the database files, read in the -password dictionary, and the like. Also, the kadm5_free functions -operate on local process memory in both libraries. - -The admin server is implemented as a nearly-stateless transaction -server, where each admin API function represents a single transaction. -No per-client or per-connection information is stored; only local -database handles are maintained between requests. The RPC mechanism -provides access to remote callers' authentication credentials for -authorization purposes. - -The admin API is exported via an RPC interface that hides all details -about network encoding, authentication, and encryption of data on the -wire. The RPC mechanism does, however, allow the server to access the -underlying authentication credentials for authorization purposes. - -The admin system maintains two databases: -% -\begin{itemize} -\item The master Kerberos (KDC) database is used to store all the -information that the Kerberos server understands, thus allowing the -greatest functionality with no modifications to a standard KDC. - -\item The KDC database also stores kadm5-specific per-principal -information in each principal's krb5_tl_data list. In a prior -version, this data was stored in a separate admin principal database; -thus, when this document refers to ``the admin principal database,'' -it now refers to the appropriate krb5_tl_data entries in the KDC -database. - -\item The policy database stores kadm5 policy information. -\end{itemize} - -The per-principal information stored in the admin principal database -consists of the principal's policy name and an array of the -principal's previous keys. The old keys are stored encrypted in the -key of the special principal ``kadmin/history'' that is created by the -server library when it is first needed. Since a change in -kadmin/history's key renders every principal's key history array -useless, it can only be changed using the ovsec_adm_edit utility; that -program will reencrypt every principal's key history in the new -key.\footnote{ovsec_adm_edit has not yet been implemented, and there -are currently no plans to implement it; thus, the history cannot -currently be changed.} The server library refuses all requests to -change kadmin/history's key. - -\section{API Handles} - -Each call to kadm5_init_* on the client or server creates a new API -handle. The handles encapsulate the API and structure versions -specified by kadm5_init_*'s caller and all other internal data needed -by the library. A process can have multiple open API handles -simultaneously by calling kadm5_init_* multiple times, and call can -specify a different version, client or service principal, and so -forth. - -Each kadm5 function verifies the handle it is given with the -CHECK_HANDLE or _KADM5_CHECK_HANDLE macros. The CHECK_HANDLE macro -differs for the client and server library because the handle types -used by those libraries differ, so it is defined in both -$<$client_internal.h$>$ and $<$server_internal.h$>$ in the library -source directory. In each header file, CHECK_HANDLE first calls -GENERIC_CHECK_HANDLE, defined in $<$admin_internal.h$>$, which -verifies the magic number, API version, and structure version that is -contained in both client and server handles. CHECK_HANDLE then calls -either CLIENT_CHECK_HANDLE or SERVER_CHECK_HANDLE respectively to -verify the client- or server-library specific handle fields. - -The CHECK_HANDLE macro is useful because it inlines the handle check -instead of requiring a separate function call. However, using -CHECK_HANDLE means that a source file cannot be compiled once and -included into both the client and server library, because CHECK_HANDLE -is always either specific to either the client or server library, not -both. There are a number of functions that can be implemented with -the same code in both the client and server libraries, however, -including all of the kadm5_free functions and -kadm5_chpass_principal_util. The _KADM5_CHECK_HANDLE macro solves -this problem; instead of inlining the handle check, it calls the -function _kadm5_check_handle which is defined separately in both the -client and server library, in client_init.c and server_init.c. -Since these two files are only compiled once and put in a single -library, they simply verify the handle they are passed with -CHECK_HANDLE and return the result. - -\section{API Versioning} - -The KADM5 system was designed by OpenVision to support multiple -versions of the KADM5 API. MIT has not adopted this level of support, -and considers the KADM5 C API to be unstable from release to release. -This section describes the original design intent; bear in mind that -only the most recent API is supported by current MIT krb5 releases, -and that the API version does not necessarily change with API changes -unless there is a need to do so for wire compatibility. - -Historically, three versions of the KADM5 API have existed: -KADM5_API_VERSION_1 through KADM5_API_VERSION_3. The first version -was equivalent to the initial OpenVision API, -OVSEC_KADM_API_VERSION_1; the second was created during the initial -integration of the OpenVision system into the MIT release; and the -third was created for MIT krb5 1.8 to add lockout fields to policy -entries. MIT dropped wire compatibility support for version 1 in MIT -krb5 1.8 (as version 1 was never used in shipped MIT code), but -retains wire compatibility support for version 2. - -Implementing a versioned API in C via with both local and RPC access -presents a number of design issues, some of them quite subtle. The -contexts in which versioning considerations must be made include: - -\begin{enumerate} -\item Typedefs, function declarations, and defined constants depend on -the API version a client is written to and must be correct at compile -time. - -\item Each function in the server library must behave according to the -API version specified by the caller at runtime to kadm5_init_*. - -\item The XDR functions used by the RPC layer to transmit function -arguments and results must encode data structures correctly depending -on the API version specified by the client at runtime. - -\item Each function in the client library must behave according to the -API version specified by the caller at runtime to kadm5_init_*. - -\item The RPC server (kadmind) must accept calls from a client using -any supported API version, and must then invoke the function in the -server library corresponding to the RPC with the API version indicated -by the client caller. - -\item When a first API function is invoked that needs to call a second -function in the API on its own behalf, and that second API function's -behavior depends on the API version specified, the first API function -must either be prepared to call the second API function at whatever -version its caller specifies or have a means of always calling the -second API function at a pre-determined version. -\end{enumerate} - -The following functions describe how each context is handled. - -\subsection{Designing for future compatibility} - -Any code whose behavior depends on the API version should be written -so as to be compatible with future, currently unknown API versions on -the grounds that any particular piece of API behavior will most -likely not change between versions. For example, in the current -system, the code is not written as ``if this is VERSION_1, do X, else -if this is VERSION_2, do Y''; instead, it is written as ``if this is -VERSION_1, do X; else, do Y.'' The former will require additional -work when VERSION_3 is defined, even if ``do Y'' is still the correct -action, whereas the latter will work without modification in that -case. - -\subsection{Header file declarations} - -Typedefs, defined constants and macros, and function declarations may -change between versions. A client is always written to a single, -specific API version, and thus expects the header files to define -everything according to that API. Failure of a header file to define -values correctly will result in either compiler warnings (e.g. if the -pointer type of a function argument changes) or fatal errors (e.g. if -the number of arguments to a function changes, or the fields of a -structure change). For example, in VERSION_1, kadm5_get_policy took a -pointer to a pointer to a structure, and in VERSION_2 it takes a -pointer to a structure; that would generate a warning if not correct. -In VERSION_1, kadm5_randkey_principal accepted three arguments but in -VERSION_2 accepts four; that would generate a fatal error. - -The header file defines everything correctly based on the value of the -USE_KADM5_API_VERSION constant. The constant can be assigned to an -integer corresponding to any supported API version, and defaults to -the newest version. The header files then simply use an \#ifdef to -include the right definitions: -% -\begin{verbatim} -#if USE_KADM5_API_VERSION == 1 -kadm5_ret_t kadm5_get_principal(void *server_handle, - krb5_principal principal, - kadm5_principal_ent_t *ent); -#else -kadm5_ret_t kadm5_get_principal(void *server_handle, - krb5_principal principal, - kadm5_principal_ent_t ent, - long mask); -#endif -\end{verbatim} - -\subsection{Server library functions} - -Server library functions must know how many and what type of arguments -to expect, and must operate on those arguments correctly, based on the -API version with which they are invoked. The API version is contained -in the handle that is always passed as their first argument, generated -by kadm5_init_* (to which the client specified the API version to use -at run-time). - -In general, it is probably unsafe for a compiled function in a library -to re-interpret the number and type of defined arguments at run-time -since the calling conventions may not allow it; for example, a -function whose first argument was a short in one version and a pointer -in the next might fail if it simply typed-casted the argument. In -that case, the function would have to written to take variable -arguments (i.e. use $<$stdarg.h$>$) and extract them from the stack -based on the API version. Alternatively, a separate function for each -API version could be defined, and $<$kadm5/admin.h$>$ could be written -to \v{\#define} the exported function name based on the value of -USE_KADM5_API_VERSION. - -In the current system, it turns out, that isn't necessary, and future -implementors should take try to ensure that no version has semantics -that will cause such problems in the future. All the functions in -KADM5 that have different arguments or results between VERSION_1 and -VERSION_2 do so simply by type-casting their arguments to the -appropriate version and then have separate code paths to handle each -one correctly. kadm5_get_principal, in svr_principal.c, is a good -example. In VERSION_1, it took the address of a pointer to a -kadm5_principal_ent_t to fill in with a pointer to allocated memory; -in VERSION_2, it takes a pointer to a structure to fill in, and a mask -of which fields in that structure should be filled in. Also, the -contents of the kadm5_principal_ent_t changed slightly between the two -versions. kadm5_get_principal handles versioning as follows -(following along in the source code will be helpful): - -\begin{enumerate} -\item If VERSION_1, it saves away its entry argument (address of a -pointer to a structure) and resets its value to contain the address of -a locally stack-allocated entry structure; this allows most of the -function to written once, in terms of VERSION_2 semantics. If -VERSION_1, it also resets its mask argument to be -KADM5_PRINCIPAL_NORMAL_MASK, because that is the equivalent to -VERSION_1 behavior, which was to return all the fields of the -structure. - -\item The bulk of the function is implemented as expected for -VERSION_2. - -\item The new fields in the VERSION_2 entry structure are assigned -inside a block that is only execute if the caller specified -VERSION_2. This saves a little time for a VERSION_1 caller. - -\item After the entry structure is filled, the function checks again -if it was called as VERSION_1. If so, it allocates a new -kadm5_principal_ent_t_v1 structure (which is conveniently defined in -the header file) with malloc, copies the appropriate values from the -entry structure into the VERSION_1 entry structure, and then writes -the address of the newly allocated memory into address specified by -the original entry argument which it had previously saved away. -\end{enumerate} - -There is another complication involved in a function re-interpreting -the number of arguments it receives at compile time---it cannot assign -any value to an argument for which the client did not pass a value. -For example, a VERSION_1 client only passes three arguments to -kadm5_get_principal. If the implementation of kadm5_get_principal -notices that the caller is VERSION_1 and therefore assigns its fourth -argument, mask, to a value that mimics the VERSION_1 behavior, it may -inadvertently overwrite data on its caller's stack. This problem can -be avoided simply by using a true local variable in such cases, -instead of treating an unpassed argument as a local variable. - -\subsection{XDR functions} - -The XDR functions used to encode function arguments and results must -know how to encode the data for any API version. This is important -both so that all the data gets correctly transmitted and so that -protocol compatibility between clients or servers using the new -library but an old API version is maintained; specific, new kadmind -servers should support old kadm5 clients. - -The signature of all XDR functions is strictly defined: they take the -address of an XDR function and the address of the data object to be -encoded or decoded. It is thus impossible to provide the API version -of the data object as an additional argument to an XDR function. -There are two other means to convey the information, storing the API -version to use as a field in the data object itself and creating -separate XDR functions to handle each different version of the data -object, and both of them are used in KADM5. - -In the client library, each kadm5 function collects its arguments into -a single structure to be passed by the RPC; similarly, it expects all -of the results to come back as a single structure from the RPC that it -will then decode back into its constituent pieces (these are the -standard ONC RPC semantics). In order to pass versioning information -to the XDR functions, each function argument and result datatype has a -filed to store the API version. For example, consider -kadm5_get_principal's structures: -% -\begin{verbatim} -struct gprinc_arg { - krb5_ui_4 api_version; - krb5_principal princ; - long mask; -}; -typedef struct gprinc_arg gprinc_arg; -bool_t xdr_gprinc_arg(); - -struct gprinc_ret { - krb5_ui_4 api_version; - kadm5_ret_t code; - kadm5_principal_ent_rec rec; -}; -typedef struct gprinc_ret gprinc_ret; -bool_t xdr_gprinc_ret(); -\end{verbatim} -% -kadm5_get_principal (in client_principal.c) assigns the api_version -field of the gprinc_arg to the version specified by its caller, -assigns the princ field based on its arguments, and assigns the mask -field from its argument if the caller specified VERSION_2. It then -calls the RPC function clnt_call, specifying the XDR functions -xdr_gprinc_arg and xdr_gprinc_ret to handle the arguments and results. - -xdr_gprinc_arg is invoked with a pointer to the gprinc_arg structure -just described. It first encodes the api_version field; this allows -the server to know what to expect. It then encodes the krb5_principal -structure and, if api_version is VERSION_2, the mask. If api_version -is not VERSION_2, it does not encode {\it anything} in place of the -mask, because an old VERSION_1 server will not expect any other data -to arrive on the wire there. - -The server performs the kadm5_get_principal call and returns its -results in an XDR encoded gprinc_ret structure. clnt_call, which has -been blocking until the results arrived, invokes xdr_gprinc_ret with a -pointer to the encoded data for it to decode. xdr_gprinc_ret first -decodes the api_version field, and then the code field since that is -present in all versions to date. The kadm5_principal_ent_rec presents -a problem, however. The structure does not itself contain an -api_version field, but the structure is different between the two -versions. Thus, a single XDR function cannot decode both versions of -the structure because it will have no way to decide which version to -expect. The solution is to have two functions, -kadm5_principal_ent_rec_v1 and kadm5_principal_ent_rec, which always -decode according to VERSION_1 or VERSION_2, respectively. gprinc_ret -knows which one to invoke because it has the api_version field -returned by the server (which is always the same as that specified by -the client in the gpring_arg). - -In hindsight, it probably would have been better to encode the API -version of all structures directly in a version field in the structure -itself; then multiple XDR functions for a single data type wouldn't be -necessary, and the data objects would stand complete on their own. -This can be added in a future API version if desired. - -\subsection{Client library functions} - -Just as with server library functions, client library functions must -be able to interpret their arguments and provide result according to -the API version specified by the caller. Again, kadm5_get_principal -(in client_principal.c) is a good example. The gprinc_ret structure -that it gets back from clnt_call contains a kadm5_principal_ent_rec or -a kadm5_principal_ent_rec_v1 (the logic is simplified somewhat because -the VERSION_2 structure only has new fields added on the end). If -kadm5_get_principal was invoked with VERSION_2, that structure should -be copied into the pointer provided as the entry argument; if it was -invoked with VERSION_1, however, the structure should be copied into -allocated memory whose address is then written into the pointer -provided by the entry argument. Client library functions make this -determination based on the API version specified in the provided -handle, just like server library functions do. - -\subsection{Admin server stubs} - -When an RPC call arrives at the server, the RPC layer authenticates -the call using the GSS-API, decodes the arguments into their -single-structure form (ie: a gprinc_arg) and dispatches the call to a -stub function in the server (in server_stubs.c). The stub function -first checks the caller's authorization to invoke the function and, if -authorized, calls the kadm5 function corresponding to the RPC function -with the arguments specified in the single-structure argument. - -Once again, kadm5_get_principal is a good example for the issues -involved. The contents of the gprinc_arg given to the stub -(get_principal_1) depends on the API version the caller on the client -side specified; that version is available to the server in the -api_version field of the gprinc_arg. When the server calls -kadm5_get_principal in the server library, it must give that function -an API handle that contains the API version requested by the client; -otherwise the function semantics might not be correct. One -possibility would be for the server to call kadm5_init for each client -request, specifying the client's API version number and thus generating -an API handle with the correct version, but that would be -prohibitively inefficient. Instead, the server dips down in the -server library's internal abstraction barrier, using the function -new_server_handle to cons up a server handle based on the server's own -global_server_handle but using the API version specified by the -client. The server then passes the newly generated handle to -kadm5_get_principal, ensuring the right behavior, and creates the -gprinc_ret structure in a manner similar to that described above. - -Although new_server_handle solves the problem of providing the server -with an API handle containing the right API version number, it does -not solve another problem: that a single source file, server_stubs.c, -needs to be able to invoke functions with arguments appropriate for -multiple API versions. If the client specifies VERSION_1, for -example, the server must invoke kadm5_get_principal with three -arguments, but if the client specifies VERSION_2 the server must -invoke kadm5_get_principal with four arguments. The compiler will not -allow this inconsistency. The server defines wrapper functions in a -separate source file that match the old version, and the separate -source file is compiled with USE_KADM5_API_VERSION set to the old -version; see kadm5_get_principal_v1 in server_glue_v1.c. The server -then calls the correct variant of kadm5_get_principal_* based on the -API version and puts the return values into the gprinc_ret in a manner -similar to that described above. - -Neither of these solutions are necessarily correct. new_server_handle -violates the server library's abstraction barrier and is at best a -kludge; the server library should probably export a function to -provide this behavior without violating the abstraction; -alternatively, the librar should be modified so that having the server -call kadm5_init for each client RPC request would not be too -inefficient. The glue functions in server_glue_v1.c really are not -necessary, because the server stubs could always just pass dummy -arguments for the extra arguments; after all, the glue functions pass -{\it nothing} for the extra arguments, so they just end up as stack -garbage anyway. - -Another alternative to the new_server_handle problem is to have the -server always invoke server library functions at a single API version, -and then have the stubs take care of converting the function arguments -and results back into the form expected by the caller. In general, -however, this might require the stubs to duplicate substantial logic -already present in the server library and further violate the server -library's abstraction barrier. - -\subsection{KADM5 self-reference} - -Some kadm5 functions call other kadm5 functions ``on their own -behalf'' to perform functionality that is necessary but that does not -directly affect what the client sees. For example, -kadm5_chpass_principal has to enforce password policies; thus, it -needs to call kadm5_get_principal and, if the principal has a policy, -kadm5_get_policy and kadm5_modify_principal in the process of changing -a principal's password. This leads to a complication: what API handle -should kadm5_chpass_principal pass to the other kadm5 functions it -calls? - -The ``obvious,'' but wrong, answer is that it should pass the handle -it was given by its caller. The caller may provide an API handle -specifying any valid API version. Although the semantics of -kadm5_chpass_principal did not change between VERSION_1 and VERSION_2, -the declarations of both kadm5_get_principal and kadm5_get_policy -did. Thus, to use the caller's API handle, kadm5_chpass_principal -will have to have a separate code path for each API version, even -though it itself did not change between versions, and duplicate a lot -of logic found elsewhere in the library. - -Instead, each API handle contains a ``local-use handle,'' or lhandle, -that kadm5 functions should use to call other kadm5 functions. For -example, the client-side library's handle structure is: -% -\begin{verbatim} -typedef struct _kadm5_server_handle_t { - krb5_ui_4 magic_number; - krb5_ui_4 struct_version; - krb5_ui_4 api_version; - char * cache_name; - int destroy_cache; - CLIENT * clnt; - krb5_context context; - kadm5_config_params params; - struct _kadm5_server_handle_t *lhandle; -} kadm5_server_handle_rec, *kadm5_server_handle_t; -\end{verbatim} -% -The lhandle field is allocated automatically when the handle is -created. All of the fields of the API handle that are accessed -outside kadm5_init are also duplicated in the lhandle; however, the -api_version field of the lhandle is always set to a {\it constant} -value, regardless of the API version specified by the caller to -kadm5_init. In the current implementation, the lhandle's api_version -is always VERSION_2. - -By passing the caller's handle's lhandle to recursively called kadm5 -functions, a kadm5 function is assured of invoking the second kadm5 -function with a known API version. Additionally, the lhandle's -lhandle field points back to the lhandle, in case kadm5 functions call -themselves more than one level deep; handle$->$lhandle always points -to the same lhandle, no matter how many times the indirection is -performed. - -This scheme might break down if a kadm5 function has to call another -kadm5 function to perform operations that they client will see and for -its own benefit, since the semantics of the recursively-called kadm5 -function may depend on the API version specified and the client may be -depending on a particular version's behavior. Future implementors -should avoid creating a situation in which this is possible. - -\section{Server Main} - -The admin server starts by trapping all fatal signals and directing -them to a cleanup-and-exit function. It then creates and exports the -RPC interface and enters its main loop. - -The main loop dispatches all incoming requests to the RPC mechanism. -In a previous version, after 15 seconds of inactivity, the server -closed all open databases; each database was be automatically reopened -by the API function implementations as necessary. That behavior -existed to protect against loss of written data before the process -exited. The current database libraries write all changes out to disk -immediately, however, so this behavior is no longer required or -performed. - -\section{Remote Procedure Calls} - -The RPC for the Admin system will be based on ONC RPC. ONC RPC is -used because it is a well-known, portable RPC mechanism. The -underlying external data representation (xdr) mechanisms for wire -encapsulation are well-known and extensible. Authentication to the -admin server and encryption of all RPC functional arguments and -results are be handled via the AUTH_GSSAPI authentication flavor of -ONC RPC. - -\section{Database Record Types} -\label{sec:db-types} - -\subsection{Admin Principal, osa_princ_ent_t} - -The admin principal database stores records of the type -osa_princ_ent_t (declared in $<$kadm5/adb.h$>$), which is the -subset of the kadm5_principal_ent_t structure that is not stored -in the Kerberos database plus the necessary bookkeeping information. -The records are keyed by the ASCII representation of the principal's -name, including the trailing NULL. - -\begin{verbatim} -typedef struct _osa_pw_hist_t { - int n_key_data; - krb5_key_data *key_data; -} osa_pw_hist_ent, *osa_pw_hist_t; - -typedef struct _osa_princ_ent_t { - char * policy; - u_int32 aux_attributes; - - unsigned int old_key_len; - unsigned int old_key_next; - krb5_kvno admin_history_kvno; - osa_pw_hist_ent *old_keys; - - - u_int32 num_old_keys; - u_int32 next_old_key; - krb5_kvno admin_history_kvno; - osa_pw_hist_ent *old_keys; -} osa_princ_ent_rec, *osa_princ_ent_t; -\end{verbatim} - -The fields that are different from kadm5_principal_ent_t are: - -\begin{description} -\item[num_old_keys] The number of previous keys in the old_keys array. -This value must be 0 $\le$ num_old_keys $<$ pw_history_num. - -\item[old_key_next] The index into old_keys where the next key should -be inserted. This value must be 0 $\le$ old_key_next $\le$ -num_old_keys. - -\item[admin_history_kvno] The key version number of the kadmin/history -principal's key used to encrypt the values in old_keys. If the server -library finds that kadmin/history's kvno is different from the value -in this field, it returns KADM5_BAD_HIST_KEY. - -\item[old_keys] The array of the principal's previous passwords, each -encrypted in the kadmin/history key. There are num_old_keys -elements. Each ``password'' in the array is itself an array of -n_key_data krb5_key_data structures, one for each keysalt type the -password was encoded in. -\end{description} - -\subsection{Policy, osa_policy_ent_t} - -The policy database stores records of the type osa_policy_ent_t -(declared in $<$kadm5/adb.h$>$) , which is all of -kadm5_policy_ent_t plus necessary bookkeeping information. The -records are keyed by the policy name. - -\begin{verbatim} -typedef struct _osa_policy_ent_t { - char *policy; - - u_int32 pw_min_life; - u_int32 pw_max_life; - u_int32 pw_min_length; - u_int32 pw_min_classes; - u_int32 pw_history_num; - - u_int32 refcnt; -} osa_policy_ent_rec, *osa_policy_ent_t; -\end{verbatim} - -\subsection{Kerberos, krb5_db_entry} - -The Kerberos database stores records of type krb5_db_entry, which is -defined in the $<$k5-int.h$>$ header file. The semantics of each -field are defined in the libkdb functional specification. - -\section{Database Access Methods} - -\subsection{Principal and Policy Databases} - -This section describes the database abstraction used for the admin -policy database; the admin principal database used to be treated in -the same manner but is now handled more directly as krb5_tl_data; -thus, nothing in this section applies to it any more. Since both -databases export equivalent functionality, the API is only described -once. The character T is used to represent both ``princ'' and -``policy''. The location of the principal database is defined by the -configuration parameters given to any of the kadm5_init functions in -the server library. - -Note that this is {\it only} a database abstraction. All functional -intelligence, such as maintaining policy reference counts or sanity -checking, must be implemented above this layer. - -Prototypes for the osa functions are supplied in -$<$kadm5/adb.h$>$. The routines are defined in libkadm5srv.a. They -require linking with the Berkely DB library. - -\subsubsection{Error codes} - -The database routines use com_err for error codes. The error code -table name is ``adb'' and the offsets are the same as the order -presented here. The error table header file is -$<$kadm5/adb_err.h$>$. Callers of the OSA routines should first call -init_adb_err_tbl() to initialize the database table. - -\begin{description} -\item[OSA_ADB_OK] Operation successful. -\item[OSA_ADB_FAILURE] General failure. -\item[OSA_ADB_DUP] Operation would create a duplicate database entry. -\item[OSA_ADB_NOENT] Named entry not in database. -\item[OSA_ADB_BAD_PRINC] The krb5_principal structure is invalid. -\item[OSA_ADB_BAD_POLICY] The specified policy name is invalid. -\item[OSA_ADB_XDR_FAILURE] The principal or policy structure cannot be -encoded for storage. -\item[OSA_ADB_BADLOCKMODE] Bad lock mode specified. -\item[OSA_ADB_CANTLOCK_DB] Cannot lock database, presumably because it -is already locked. -\item[OSA_ADB_NOTLOCKED] Internal error, database not locked when -unlock is called. -\item[OSA_ADB_NOLOCKFILE] KADM5 administration database lock file missing. -\end{description} - -Database functions can also return system errors. Unless otherwise -specified, database functions return OSA_ADB_OK. - -\subsubsection{Locking} - -All of the osa_adb functions except open and close lock and unlock the -database to prevent concurrency collisions. The overall locking -algorithm is as follows: - -\begin{enumerate} -\item osa_adb_open_T calls osa_adb_init_db to allocate the osa_adb_T_t -structure and open the locking file for further use. - -\item Each osa_adb functions locks the locking file and opens the -appropriate database with osa_adb_open_and_lock, performs its action, -and then closes the database and unlocks the locking file with -osa_adb_close_and_unlock. - -\item osa_adb_close_T calls osa_adb_fini_db to close the locking file -and deallocate the db structure. -\end{enumerate} - -Functions which modify the database acquire an exclusive lock, others -acquire a shared lock. osa_adb_iter_T acquires an exclusive lock for -safety but as stated below consequences of modifying the database in -the iteration function are undefined. - -\subsubsection{Function descriptions} - -\begin{verbatim} -osa_adb_ret_t osa_adb_create_T_db(kadm5_config_params *params) -\end{verbatim} -% -Create the database and lockfile specified in params. The database -must not already exist, or EEXIST is returned. The lock file is only -created after the database file has been created successfully. - -\begin{verbatim} -osa_adb_ret_t osa_adb_rename_T_db(kadm5_config_params *fromparams, - kadm5_config_params *toparams) -\end{verbatim} -% -Rename the database named by fromparams to that named by toparams. -The fromparams database must already exist; the toparams database may -exist or not. When the function returns, the database named by -fromparams no longer exists, and toparams has been overwritten with -fromparams. This function acquires a permanent lock on both databases -for the duration of its operation, so a failure is likely to leave the -databases unusable. - -\begin{verbatim} -osa_adb_ret_t osa_adb_destroy_policy_db(kadm5_config_params *params) -\end{verbatim} -% -Destroy the database named by params. The database file and lock file -are deleted. - -\begin{verbatim} -osa_adb_ret_t -osa_adb_open_T(osa_adb_T_t *db, char *filename); -\end{verbatim} -% -Open the database named filename. Returns OSA_ADB_NOLOCKFILE if the -database does not exist or if the lock file is missing. The database -is not actually opened in the operating-system file sense until a lock -is acquire. - -\begin{verbatim} -osa_adb_ret_t -osa_adb_close_T(osa_adb_T_t db); -\end{verbatim} -% -Release all shared or exclusive locks (on BOTH databases, since they -use the same lock file) and close the database. - -It is an error to exit while a permanent lock is held; -OSA_ADB_NOLOCKFILE is returned in this case. - -\begin{verbatim} -osa_adb_ret_t osa_adb_get_lock(osa_adb_T_t db, int mode) -\end{verbatim} - -Acquire a lock on the administration databases; note that both -databases are locked simultaneously by a single call. The mode -argument can be OSA_ADB_SHARED, OSA_ADB_EXCLUSIVE, or -OSA_ADB_PERMANENT. The first two and the third are really disjoint -locking semantics and should not be interleaved. - -Shared and exclusive locks have the usual semantics, and a program can -upgrade a shared lock to an exclusive lock by calling the function -again. A reference count of open locks is maintained by this function -and osa_adb_release_lock so the functions can be called multiple -times; the actual lock is not released until the final -osa_adb_release_lock. Note, however, that once a lock is upgraded -from shared to exclusive, or from exclusive to permanent, it is not -downgraded again until released completely. In other words, -get_lock(SHARED), get_lock(EXCLUSIVE), release_lock() leaves the -process with an exclusive lock with a reference count of one. An -attempt to get a shared or exclusive lock that conflicts with another -process results in the OSA_ADB_CANLOCK_DB error code. - -This function and osa_adb_release_lock are called automatically as -needed by all other osa_adb functions to acquire shared and exclusive -locks and so are not normally needed. They can be used explicitly by -a program that wants to perform multiple osa_adb functions within the -context of a single lock. - -Acquiring an OSA_ADB_PERMANENT lock is different. A permanent lock -consists of first acquiring an exclusive lock and then {\it deleting -the lock file}. Any subsequent attempt to acquire a lock by a -different process will fail with OSA_ADB_NOLOCKFILE instead of -OSA_ADB_CANTLOCK_DB (attempts in the same process will ``succeed'' -because only the reference count gets incremented). The lock file is -recreated by osa_adb_release_lock when the last pending lock is released. - -The purpose of a permanent lock is to absolutely ensure that the -database remain locked during non-atomic operations. If the locking -process dies while holding a permanent lock, all subsequent osa_adb -operations will fail, even through a system reboot. This is useful, -for example, for ovsec_adm_import which creates both new database -files in a temporary location and renames them into place. If both -renames do not fully complete the database will probably be -inconsistent and everything should stop working until an administrator -can clean it up. - -\begin{verbatim} -osa_adb_ret_t osa_adb_release_lock(osa_adb_T_t db) -\end{verbatim} - -Releases a shared, exclusive, or permanent lock acquired with -osa_adb_get_lock, or just decrements the reference count if multiple -locks are held. When a permanent lock is released, the lock file is -re-created. - -All of a process' shared or exclusive database locks are released when -the process terminates. A permanent lock is {\it not} released when -the process exits (although the exclusive lock it begins with -obviously is). - -\begin{verbatim} -osa_adb_ret_t -osa_adb_create_T(osa_adb_T_t db, osa_T_ent_t entry); -\end{verbatim} -% -Adds the entry to the database. All fields are defined. Returns -OSA_ADB_DUP if it already exists. - -\begin{verbatim} -osa_adb_ret_t -osa_adb_destroy_T(osa_adb_T_t db, osa_T_t name); -\end{verbatim} - -Removes the named entry from the database. Returns OSA_ADB_NOENT if -it does not exist. - -\begin{verbatim} -osa_adb_ret_t -osa_adb_get_T(osa_adb_T_t db, osa_T_t name, - osa_princ_ent_t *entry); -\end{verbatim} - -Looks up the named entry in the db, and returns it in *entry in -allocated storage that must be freed with osa_adb_free_T. Returns -OSA_ADB_NOENT if name does not exist, OSA_ADB_MEM if memory cannot be -allocated. - -\begin{verbatim} -osa_adb_ret_t -osadb_adb_put_T(osa_adb_T_t db, osa_T_ent_t entry); -\end{verbatim} - -Modifies the existing entry named in entry. All fields must be filled -in. Returns OSA_DB_NOENT if the named entry does not exist. Note -that this cannot be used to rename an entry; rename is implemented by -deleting the old name and creating the new one (NOT ATOMIC!). - -\begin{verbatim} -void osa_adb_free_T(osa_T_ent_t); -\end{verbatim} - -Frees the memory associated with an osa_T_ent_t allocated by -osa_adb_get_T. - -\begin{verbatim} -typedef osa_adb_ret_t (*osa_adb_iter_T_func)(void *data, - osa_T_ent_t entry); - -osa_adb_ret_t osa_adb_iter_T(osa_adb_T_t db, osa_adb_iter_T_func func, - void *data); -\end{verbatim} - -Iterates over every entry in the database. For each entry ent in the -database db, the function (*func)(data, ent) is called. If func -returns an error code, osa_adb_iter_T returns an error code. If all -invocations of func return OSA_ADB_OK, osa_adb_iter_T returns -OSA_ADB_OK. The function func is permitted to access the database, -but the consequences of modifying the database during the iteration -are undefined. - -\subsection{Kerberos Database} - -Kerberos uses the libkdb interface to store krb5_db_entry records. It -can be accessed and modified in parallel with the Kerberos server, -using functions that are defined inside the KDC and the libkdb.a. The -libkdb interface is defined in the libkdb functional specifications. - -\subsubsection{Initialization and Key Access} - -Keys stored in the Kerberos database are encrypted in the Kerberos -master key. The admin server will therefore have to acquire the key -before it can perform any key-changing operations, and will have to -decrypt and encrypt the keys retrieved from and placed into the -database via krb5_db_get_principal and _put_principal. This section -describes the internal admin server API that will be used to perform -these functions. - -\begin{verbatim} -krb5_principal master_princ; -krb5_encrypt_block master_encblock; -krb5_keyblock master_keyblock; - -void kdc_init_master() -\end{verbatim} - -kdc_init_master opens the database and acquires the master key. It -also sets the global variables master_princ, master_encblock, and -master_keyblock: - -\begin{itemize} -\item master_princ is set to the name of the Kerberos master principal -(\v{K/M@REALM}). - -\item master_encblock is something I have no idea about. - -\item master_keyblock is the Kerberos master key -\end{itemize} - -\begin{verbatim} -krb5_error_code kdb_get_entry_and_key(krb5_principal principal, - krb5_db_entry *entry, - krb5_keyblock *key) -\end{verbatim} - -kdb_get_entry_and_key retrieves the named principal's entry from the -database in entry, and decrypts its key into key. The caller must -free entry with krb5_dbm_db_free_principal and free key-$>$contents with -free.\footnote{The caller should also \v{memset(key-$>$contents, 0, -key-$>$length)}. There should be a function krb5_free_keyblock_contents -for this, but there is not.} - -\begin{verbatim} -krb5_error_code kdb_put_entry_pw(krb5_db_entry *entry, char *pw) -\end{verbatim} - -kdb_put_entry_pw stores entry in the database. All the entry values -must already be set; this function does not change any of them except -the key. pw, the NULL-terminated password string, is converted to a -key using string-to-key with the salt type specified in -entry-$>$salt_type.\footnote{The salt_type should be set based on the -command line arguments to the kadmin server (see the ``Command Line'' -section of the functional specification).} - -\section{Admin Principal and Policy Database Implementation} - -The admin principal and policy databases will each be stored in a -single hash table, implemented by the Berkeley 4.4BSD db library. -Each record will consist of an entire osa_T_ent_t. The key into the -hash table is the entry name (for principals, the ASCII representation -of the name). The value is the T entry structure. Since the key and -data must be self-contained, with no pointers, the Sun xdr mechanisms -will be used to marshal and unmarshal data in the database. - -The server in the first release will be single-threaded in that a -request will run to completion (or error) before the next will run, -but multiple connections will be allowed simultaneously. - -\section{ACLs, acl_check} - -The ACL mechanism described in the ``Authorization ACLs'' section of -the functional specifications will be implemented by the acl_check -function. - -\begin{verbatim} -enum access_t { - ACCESS_DENIED = 0, - ACCESS_OK = 1, -}; - -enum access_t acl_check(krb5_principal princ, char *priv); -\end{verbatim} - -The priv argument must be one of ``get'', ``add'', ``delete'', or -``modify''. acl_check returns 1 if the principal princ has the named -privilege, 0 if it does not. - -\section{Function Details} - -This section discusses specific design issues for Admin API functions -that are not addressed by the functional specifications. - -\subsection{kadm5_create_principal} - -If the named principal exists in either the Kerberos or admin -principal database, but not both, return KADM5_BAD_DB. - -The principal's initial key is not stored in the key history array at -creation time. - -\subsection{kadm5_delete_principal} - -If the named principal exists in either the Kerberos or admin -principal database, but not both, return KADM5_BAD_DB. - -\subsection{kadm5_modify_principal} - -If the named principal exists in either the Kerberos or admin -principal database, but not both, return KADM5_BAD_DB. - -If pw_history_num changes and the new value $n$ is smaller than the -current value of num_old_keys, old_keys should end up with the $n$ -most recent keys; these are found by counting backwards $n$ elements -in old_keys from old_key_next. old_key_nexts should then be reset to -0, the oldest of the saved keys, and num_old_keys set to $n$, the -new actual number of old keys in the array. - -\subsection{kadm5_chpass_principal, randkey_principal} - -The algorithm for determining whether a password is in the principal's -key history is complicated by the use of the kadmin/history \k{h} -encrypting key. - -\begin{enumerate} -\item For kadm5_chpass_principal, convert the password to a key -using string-to-key and the salt method specified by the command line -arguments. - -\item If the POLICY bit is set and pw_history_num is not zero, check -if the new key is in the history. -\begin{enumerate} -\item Retrieve the principal's current key and decrypt it with \k{M}. -If it is the same as the new key, return KADM5_PASS_REUSE. -\item Retrieve the kadmin/history key \k{h} and decrypt it with \k{M}. -\item Encrypt the principal's new key in \k{h}. -\item If the principal's new key encrypted in \k{h} is in old_keys, -return KADM5_PASS_REUSE. -\item Encrypt the principal's current key in \k{h} and store it in -old_keys. -\item Erase the memory containing \k{h}. -\end{enumerate} - -\item Encrypt the principal's new key in \k{M} and store it in the -database. -\item Erase the memory containing \k{M}. -\end{enumerate} - -To store the an encrypted key in old_keys, insert it as the -old_key_next element of old_keys, and increment old_key_next by one -modulo pw_history_num. - -\subsection{kadm5_get_principal} - -If the named principal exists in either the Kerberos or admin -principal database, but not both, return KADM5_BAD_DB. - -\end{document} diff --git a/crypto/krb5/doc/kadm5/fullpage.sty b/crypto/krb5/doc/kadm5/fullpage.sty deleted file mode 100644 index d5a2bf5b0371..000000000000 --- a/crypto/krb5/doc/kadm5/fullpage.sty +++ /dev/null @@ -1,9 +0,0 @@ -\marginparwidth 0pt -\oddsidemargin 0pt -\evensidemargin 0pt -\marginparsep 0pt - -\topmargin 0pt - -\textwidth 6.5in -\textheight 8.5 in |