diff options
author | no author <devnull@mit.edu> | 1994-06-28 03:14:16 +0000 |
---|---|---|
committer | no author <devnull@mit.edu> | 1994-06-28 03:14:16 +0000 |
commit | c3f016dc699c86b7c0f09fd361d7a6efd33cc93f (patch) | |
tree | 575f11229410a2d15df1cc3e280d7ee8ddcab446 | |
parent | 8c0cc69474eabd54e5191473ba55d9500022b1c7 (diff) | |
download | krb5-krb5-1.0-beta4.1.zip krb5-krb5-1.0-beta4.1.tar.gz krb5-krb5-1.0-beta4.1.tar.bz2 |
This commit was manufactured by cvs2svn to create tag 'BETA_4_1'krb5-1.0-beta4.1
git-svn-id: svn://anonsvn.mit.edu/krb5/tags/BETA_4_1@3922 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r-- | doc/kadm5/api-funcspec.tex | 1527 | ||||
-rw-r--r-- | doc/kadm5/api-server-design.tex | 584 | ||||
-rw-r--r-- | doc/kadm5/api-unit-test.tex | 2077 |
3 files changed, 0 insertions, 4188 deletions
diff --git a/doc/kadm5/api-funcspec.tex b/doc/kadm5/api-funcspec.tex deleted file mode 100644 index 3f6b32b..0000000 --- a/doc/kadm5/api-funcspec.tex +++ /dev/null @@ -1,1527 +0,0 @@ -\documentstyle[12pt,fullpage,changebar]{article} - -% $Id$ - -\setlength{\parskip}{.7\baselineskip} -\setlength{\parindent}{0pt} - -\def\secure{OV*Secure} -\def\v#1{\verb+#1+} - -\title{OV*Secure Admin \\ Functional Specifications} -\author{Barry Jaspan} -\date{DRAFT --- \today} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Make _ actually generate an _, and allow line-breaking after it. -\let\underscore=\_ -\catcode`_=13 -\def_{\underscore\penalty75\relax} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\begin{document} - -\maketitle - -{\setlength{\parskip}{0pt}\tableofcontents} - -\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. - -\item A password that is not significantly different from each -component and the realm of the principal's name will not be accepted. -\end{itemize} - -\section{Interrealm Operation} - -For version 1.0, the behavior of any function when called with a -principal name that is not in the host's local realm is undefined. - -\section{Admin API} - -This section 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 may also be possible for a program running -on the Kerberos master server to use the Admin API directly, without -going through the admin server. - -\subsection{Data Structures} - -This section describes the data structures used by the Admin API that -are unique to \secure{}. They are defined in $<$ovsec_admin/admin.h$>$. - -\subsubsection{Principals, ovsec_kadm_principal_ent_t} -\label{sec:principal-structure} - -A Kerberos principal entry is represented by a -ovsec_kadm_principal_ent_t. It contains a subset of the information -stored in the master Kerberos database as well as the additional -information maintained by \secure{}. 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 _ovsec_kadm_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; -} ovsec_kadm_principal_ent_rec, *ovsec_kadm_principal_ent_t; -\end{verbatim} -\caption{Definition of ovsec_kadm_principal_ent_t.} -\label{fig:princ-t} -\end{figure} - -The fields of an ovsec_kadm_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. -Note that only some are explicitly supported by \secure{}. - -\begin{tabular}{clr} -{\bf Supported} & {\bf Name} & {\bf Value} \\ - & KRB5_KDB_DISALLOW_POSTDATED & 0x00000001 \\ - & KRB5_KDB_DISALLOW_FORWARDABLE & 0x00000002 \\ -X & KRB5_KDB_DISALLOW_TGT_BASED & 0x00000004 \\ - & KRB5_KDB_DISALLOW_RENEWABLE & 0x00000008 \\ - & KRB5_KDB_DISALLOW_PROXIABLE & 0x00000010 \\ - & KRB5_KDB_DISALLOW_DUP_SKEY & 0x00000020 \\ -X & KRB5_KDB_DISALLOW_ALL_TIX & 0x00000040 \\ - & KRB5_KDB_REQUIRES_PRE_AUTH & 0x00000080 \\ - & KRB5_KDB_REQUIRES_HW_AUTH & 0x00000100 \\ -X & KRB5_KDB_REQUIRES_PWCHANGE & 0x00000200 \\ - & KRB5_KDB_DISALLOW_SVR & 0x00001000 \\ -X & KRB5_KDB_PWCHANGE_SERVICE & 0x00002000 -\end{tabular} - -The interpretation of each bit is as follows. For each of the bits -that disables a corresponding KDC_OPT option, the option is disabled -on an AS_REQ if the bit is set on either the client or the server, and -the option is disabled on TGS_REQ if the bit is set on the server (the -setting of the bit on the client is irrelevant for a TGS_REQ). - -\begin{description} -\item[KRB5_KDB_DISALLOW_POSTDATED] Disables the ALLOW_POSTDATE -and POSTDATED KDC options on AS_REQ and TGS_REQ. - -\item[KRB5_KDB_DISALLOW_FORWARDABLE] Disables the FORWARDABLE KDC -option for AS_REQ and TGS_REQ. - -\item[KRB5_KDB_DISALLOW_TGT_BASED] All TGS_REQ requests will fail for -a principal with this bit set. - -\item[KRB5_KDB_DISALLOW_RENEWABLE] Disables the RENEWABLE KDC option for -AS_REQ and TGS_REQ. - -\item[KRB5_KDB_DISALLOW_PROXIABLE] Disables the PROXIABLE KDC option on -AS_REQ and TGS_REQ. - -\item[KRB5_KDB_DISALLOW_DUP_SKEY] Disables the ENC_TKT_IN_SKEY option on -TGS_REQ. - -\item[KRB5_KDB_DISALLOW_ALL_TIX] All AS_REQ requests fail if this bit -is set for the client or the server, and all TGS_REQ requests fail if -this bit is set for the server. Note that this bit can be set -automatically if the symbol KRBCONF_KDC_MODIFIES_KDC is defined and a -specified number of pre-authentication attempts fail. - -\item[KRB5_KDB_REQUIRES_PRE_AUTH] Any AS_REQ will fail if this bit is -set and the padata field of the request is empty. Any TGS_REQ will -fail if this bit is set and the TKT_FLAG_PRE_AUTH bit is not set in -the tgt. Thus, it is possible to have the bit not set on the TGT but -to have a specific service require pre-authentication. - -\item[KRB5_KDB_REQUIRES_HW_AUTH] Unclear. - -\item[KRB5_KDB_REQUIRES_PWCHANGE] An AS_REQ will fail if this bit is -set on the client and the KRB5_KDC_PWCHANGE_SERVICE bit is not set on -the server. - -\item[KRB5_KDB_DISALLOW_SVR] All AS_REQ and TGS_REQ request will fail -if the server has this bit set. - -\item[KRB5_KDB_PWCHANGE_SERVICE] An request from a client whose -password has expired will succeed if this bit is set on the server. -Also see KRB5_KDC_REQUIRES_PWCHANGE. -\end{description} - -\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. - -\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. -\end{description} - -\subsubsection{Policies, ovsec_kadm_policy_ent_t} -\label{sec:policy-fields} - -If the POLICY bit is set in aux_attributes, the \v{policy} name field -in the ovsec_kadm_principal_ent_t structure refers to a password -policy entry defined in a \v{ovsec_kadm_policy_ent_t}. - -\begin{verbatim} -typedef struct _ovsec_kadm_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; -} ovsec_kadm_policy_ent_rec, *ovsec_kadm_policy_ent_t; -\end{verbatim} - -The fields of an ovsec_kadm_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} - -\subsubsection{Create/Modify Masks} -\label{sec:masks} - -The API functions for creating and modifying principals and policies -allow for a relevant subset of the fields of the -ovsec_kadm_principal_ent_t and ovsec_kadm_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. 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 $<$ovsec_admin/admin.h$>$. The -OVSEC_KADM_ 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. - -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. - -If the principal has a policy assigned, the POLICY bit is set in -aux_attributes. - -\begin{table}[htbp] -\begin{tabular}{@{}lclll} -{\bf Name} & {\bf Value} & {\bf Field 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 -\end{tabular} -\caption{Mask bits for creating/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} - -\subsection{Constants, Header Files, Libraries} - -For release 1.0 both all of the files decribed in this section are -rooted off of the ``stage'' directory in the build tree. If we export -this interface in future releases they will move to the ``install'' -tree. Include files are found under ``stage/include'', libraries under -``stage/lib''. - -$<$ovsec_admin/admin.h$>$ contains ovsec_kadm routine prototypes, data -structures, mask bitfields defines, and the following name and -location definitions: - -\begin{description} -\item[admin service principal] ADM_PRINCIPAL (``ovsec_kadm/admin'') -\item[admin history key] HIST_PRINCIPAL (``ovsec_kadm/history'') -\item[change password principal] CHANGEPW_PRINCIPAL (``ovsec_kadm/changepw'') -\item[server acl file path] ACLFILE (``/krb5/ovsec_admin.acl'') -\item[dictionary] WORDFILE (``/krb5/ovsec_adm_dict'') -\end{description} - -OVSEC_KADM errors are described in $<$ovsec_admin/kadm_err.h$>$. - -The location of the admin policy and principal databases are defined -in $<$ovsec_admin/adb.h$>$: - -\begin{description} -\item[admin policy database] POLICY_DB (``/krb5/ovsec_policy.db'') -\item[admin principal database] PRINCIPAL_DB (``/krb5/ovsec_principal.db'') -\end{description} - -Client applications will link against libclient.a and server programs -against libsrv.a. Right now both clients and servers also need to link -against libcommon.a but we should put that in both libclient.a and -libsrv.a to simplify the linking process. - -\subsection{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 returned from functions that the admin -routines call (e.g. the kerberos library). Callers should not expect -that only OVSEC 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. The error table include file will be -$<$ovsec_admin/kadm_err.h$>$. - -\begin{description} -\item[* OVSEC_KADM_FAILURE] Operation failed for unspecified reason. -\item[* OVSEC_KADM_AUTH_GET] Operation requires ``get'' privilege. -\item[* OVSEC_KADM_AUTH_ADD] Operation requires ``add'' privilege. -\item[* OVSEC_KADM_AUTH_MODIFY] Operation requires ``modify'' privilege. -\item[* OVSEC_KADM_AUTH_DELETE] Operation requires ``delete'' privilege. -\item[* OVSEC_KADM_AUTH_INSUFFICIENT] Insufficient authorization for -operation. -\item[* OVSEC_KADM_BAD_DB] Database inconsistency detected. -\item[OVSEC_KADM_DUP] Principal or policy already exists. -\item[OVSEC_KADM_RPC_ERROR] Communication failure with server. -\item[OVSEC_KADM_NO_SRV] No administration server found for realm. -\item[OVSEC_KADM_BAD_HIST_KEY] Password history principal key version -mismatch. -\item[OVSEC_KADM_NOT_INIT] Connection to server not initialized. -\item[OVSEC_KADM_UNK_PRINC] Principal does not exist. -\item[OVSEC_KADM_UNK_POLICY] Policy does not exist. -\item[OVSEC_KADM_BAD_MASK] Invalid field mask for operation. -\item[OVSEC_KADM_BAD_CLASS] Invalid number of character classes. -\item[OVSEC_KADM_BAD_LENGTH] Invalid password length. -\item[OVSEC_KADM_BAD_POLICY] Illegal policy name. -\item[OVSEC_KADM_BAD_PRINCIPAL] Illegal principal name. XXX use krb5 -error code? -\item[OVSEC_KADM_BAD_AUX_ATTR] Invalid auxillary attributes. -\item[OVSEC_KADM_BAD_HISTORY] Invalid password history count. -\item[OVSEC_KADM_BAD_MIN_PASS_LIFE] Password minimum life is greater -then password maximum life. -\item[OVSEC_KADM_PASS_Q_TOOSHORT] Password is too short. -\item[OVSEC_KADM_PASS_Q_CLASS] Password does not contain enough -character classes. -\item[OVSEC_KADM_PASS_Q_DICT] Password is in the password dictionary. -\item[OVSEC_KADM_PASS_REUSE] Cannot resuse password. -\item[OVSEC_KADM_PASS_TOOSOON] Current password's minimum life has not -expired. -\item[OVSEC_KADM_POLICY_REF] Policy reference count is not zero. -\item[OVSEC_KADM_INIT] Connection to server already initialized. -\item[OVSEC_KADM_BAD_PASSWORD] Incorrect password. -\item[OVSEC_KADM_PROTECT_PRINCIPAL] Cannot change protected principal." -\end{description} - -\subsection{Authentication and Authorization} -\label{sec:auth} - -Two Kerberos principals exist for use in communicating with the Admin -system: ovsec_kadm/admin and ovsec_kadm/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, ovsec_kadm/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 set 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 -ovsec_kadm/changepw service. The function semantics describe the precise -details. - -Each Admin API operation authenticated to the ovsec_kadm/admin service -requires a specific authorization to run. This version uses a simple -named privilege system with the following names and meanings: - -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. - -\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. -\item[Delete] Able to remove principals and policies. -\end{description} - -Privileges are specified via an external configuration file on the -Kerberos master server (see section \ref{sec:acls}). - -Table \ref{tab:func-overview} summarizes the authorization -requirements of each function. Additionally, each API function -description identifies the privilege required to perform it. - -\subsection{Function Overview} - -The functions provided by the Admin API, and the authorization they -require, are listed in the table \ref{tab:func-overview}. The -``ovsec_kadm_'' 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 OVSEC_KADM_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 OVSEC_KADM_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 ovsec_kadm library. \\ -destroy & none & Close the connection with the ovsec_kadm library. \\ -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. \\ -chpass_principal & modify\footnotemark[\thefootnote] & - Change a principal's password. \\ -chpass_principal_util & modify\footnotemark[\thefootnote] & Utility wrapper around chpass_principal. \\ -randkey_principal & modify\footnotemark[\thefootnote] & - Randomize a principal's 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. \\ -free_principal_ent & none & Free the memory associated with an - ovsec_kadm_principal_ent_t. \\ -free_policy_ent & none & Free the memory associated with an - ovsec_kadm_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{ovsec_kadm_init} - -\begin{verbatim} -ovsec_kadm_ret_t ovsec_kadm_init(char *client_name, char *pass, - char *service_name, char *realm) -\end{verbatim} - -AUTHORIZATION REQUIRED: none - -Open a connection to the ovsec_kadm library and initialize any -neccessary state information. This function behaves differently when -called from local and remote clients. - -For remote clients, the semantics are: - -\begin{enumerate} -\item Initializes all the com_err error tables used by the Admin -system. - -\item Acquire 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 OVSEC_KADM_ADMIN_SERVICE or -OVSEC_KADM_CHANGEPW_SERVICE. -\item If realm is NULL, client_name's realm is used. -\item The ticket is decoded with the password pass, which must be -client_name's password. If pass is NULL, the user is prompted (via -the tty) for a password. -\end{enumerate} - -\item Create a GSS-API authenticated connection to the Admin server, -using the just-acquired Kerberos ticket. -\end{enumerate} - -Local clients, running on the KDC, may be useful. For now this is will -most likely be used for testing, but could in the future be the basis -for a command-line system that works both remotely and on the KDC -machine. If ovsec_kadm_init is invoked locally its semantics are: - -\begin{enumerate} -\item Initializes all the com_err error tables used by the Admin -system. - -\item Initializes direct access to the KDC database. If pass is NULL, -reads the master password from /.k5.REALM-NAME (created by kstash). -Otherwise, the non-NULL password is ignored and the user is prompted -for it via the tty. - -\item Initializes the dictionary (if present) for dictionary checks. - -\item Parses client_name as a Kerberos principal and initializes the -global current_caller principal to it. client_name should usually be -specified as the name of the program. - -\item The service_name argument is not used. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[OVSEC_KADM_NO_SRV] No Admin server can be found for the -specified realm. - -\item[OVSEC_KADM_RPC_ERROR] The RPC connection to the server cannot be -initiated. - -\item[OVSEC_KADM_BAD_PASSWORD] Incorrect password. -\end{description} - -\subsection{ovsec_kadm_destroy} - -\begin{verbatim} -ovsec_kadm_ret_t ovsec_kadm_destroy() -\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 -ovsec_kadm_init. - -\item Tear down the GSS-API context negotiated with the server. - -\item Close the RPC connection. -\end{enumerate} - -For local clients, this function does nothing. - -RETURN CODES: - -\subsection{ovsec_kadm_create_principal} - -\begin{verbatim} -ovsec_kadm_ret_t -ovsec_kadm_create_principal(ovsec_kadm_principal_ent_t princ, u_int32 mask, - char *pw); -\end{verbatim} - -AUTHORIZATION REQUIRED: add - -\begin{enumerate} - -\item Return OVSEC_KADM_BAD_MASK if the mask is invalid. -\item If the named principal exists, return OVSEC_KADM_DUP. -\item If the POLICY bit is set and the named policy does not exist, -return OVSEC_KADM_UNK_POLICY. -\item If OVSEC_KADM_POLICY bit is set in aux_attributes check to see if -the password does not meets quality standards, return the appropriate -OVSEC_KADM_PASS_Q_* error code if it fails. -\item Store the principal, set the key. The key is generated with -Kerberos' string-to-key function, using the salt method specified on -the admin server's command line; see section \ref{sec:commandline}. -\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 not set, 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 now + pw_max_life. -\item Otherwise, set pw_expiration to now + pw_max_life. -\end{enumerate} - -\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[OVSEC_KADM_BAD_MASK] The field mask is invalid for a create -operation. -\item[OVSEC_KADM_DUP] Principal already exists. -\item[OVSEC_KADM_UNK_POLICY] Policy named in entry does not exist. -\item[OVSEC_KADM_PASS_Q_*] Specified password does not meet policy -standards. -\end{description} - -\subsection{ovsec_kadm_delete_principal} - -\begin{verbatim} -ovsec_kadm_ret_t -ovsec_kadm_delete_principal(krb5_principal princ); -\end{verbatim} - -AUTHORIZATION REQUIRED: delete - -\begin{enumerate} -\item Return OVSEC_KADM_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[OVSEC_KADM_UNK_PRINC] Principal does not exist. -\end{description} - -\subsection{ovsec_kadm_modify_principal} - -\begin{verbatim} -ovsec_kadm_ret_t -ovsec_kadm_modify_principal(ovsec_kadm_principal_ent_t princ, u_int32 mask); -\end{verbatim} - -Modify the attributes of the principal named in -ovsec_kadm_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 OVSEC_KADM_UNK_PRINC if the principal does not exist. -\item Return OVSEC_KADM_BAD_MASK if the mask is invalid. -\item If POLICY bit is set but the new policy does not exist, return -OVSEC_KADM_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 according to the new policy. -\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 fields specified in the mask. -\item Update mod_name field to caller and mod_date to now. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[OVSEC_KADM_UNK_PRINC] Entry does not exist. -\item[OVSEC_KADM_BAD_MASK] The mask is not valid for a modify -operation. -\item[OVSEC_KADM_UNK_POLICY] The POLICY bit is set but the new -policy does not exist. -\end{description} - -\subsection{ovsec_kadm_rename_principal} - -\begin{verbatim} -ovsec_kadm_ret_t -ovsec_kadm_rename_principal(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 -OVSEC_KADM_UNK_PRINC error. -\item Check to see if target exists, if so return OVSEC_KADM_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[OVSEC_KADM_UNK_PRINC] Source principal does not exist. -\item[OVSEC_KADM_DUP] Target principal already exist. -\end{description} - -\subsection{ovsec_kadm_chpass_principal} - -\begin{verbatim} -ovsec_kadm_ret_t -ovsec_kadm_chpass_principal(krb5_principal princ, char *pw); -\end{verbatim} - -AUTHORIZATION REQUIRED: modify, or the calling principal being the -same as the princ argument. If the request is authenticated to the -ovsec_kadm/changepw service, the modify privilege is disregarded. - -Change a principal's password. - -This function enforces password policy and dictionary checks. If the new -password specified is in the password dictionary, and the policy bit is set -OVSEC_KADM_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 OVSEC_KADM_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 OVSEC_KADM_PASS_TOOSOON. -\item If the principal your are trying to change is ovsec_adm/history -return OVSEC_KADM_PROTECT_PRINCIPAL. -\item If the password does not meet the quality -standards, return the appropriate OVSEC_KADM_PASS_Q_* error code. -\item Convert password to key. The key is generated with -Kerberos' string-to-key function, using the salt method specified on -the admin server's command line; see section \ref{sec:commandline}. -\item If the new key is in the principal's password history, return -OVSEC_KADM_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[OVSEC_KADM_UNK_PRINC] Principal does not exist. -\item[OVSEC_KADM_PASS_Q_*] Requested password does not meet quality -standards. -\item[OVSEC_KADM_PASS_REUSE] Requested password is in user's -password history. -\item[OVSEC_KADM_PASS_TOOSOON] Current password has not reached minimum life -\item[OVSEC_KADM_PROTECT_PRINCIPAL] Cannot change the password of a special principal -\end{description} - - -\subsection{ovsec_kadm_chpass_principal_util} - -\begin{verbatim} -ovsec_kadm_ret_t -ovsec_kadm_chpass_principal_util(krb5_principal princ, char *new_pw, - char **pw_ret, char *msg_ret); -\end{verbatim} - -AUTHORIZATION REQUIRED: modify, or the calling principal being the -same as the princ argument. If the request is authenticated to the -ovsec_kadm/changepw service, the modify privilege is disregarded. - -This function is a wrapper around ovsec_kadm_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 OVSEC_KADM_PW_FIRST_PROMPT and -OVSEC_KADM_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 -ocurr 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 ovsec_kadm_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 -ovsec_kadm_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 ovsec_kadm_chpass_principal. -\end{enumerate} - - -RETURN CODES: - -\begin{description} -\item[KRB5_LIBOS_BADPWDMATCH] Typed new passwords did not match. -\item[OVSEC_KADM_UNK_PRINC] Principal does not exist. -\item[OVSEC_KADM_PASS_Q_*] Requested password does not meet quality -standards. -\item[OVSEC_KADM_PASS_REUSE] Requested password is in user's -password history. -\item[OVSEC_KADM_PASS_TOOSOON] Current password has not reached minimum -life. -\end{description} - - -\subsection{ovsec_kadm_randkey_principal} - -\begin{verbatim} -ovsec_kadm_ret_t -ovsec_kadm_randkey_principal(krb5_principal princ, krb5_keyblock **new_key) -\end{verbatim} - -AUTHORIZATION REQUIRED: modify, or the calling principal being the -same as the princ argument. If the request is authenticated to the -ovsec_kadm/changepw service, the modify privilege is disregarded. - -Generate and assign a new random key to the named principal, and -return the generated key in allocated storage. The caller must free -the returned krb5_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 OVSEC_KADM_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 OVSEC_KADM_PASS_TOOSOON. -\item If the principal you are trying to change is ovsec_adm/history return -OVSEC_KADM_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[OVSEC_KADM_UNK_PRINC] Principal does not exist. -\item[OVSEC_KADM_PASS_TOOSOON] The minimum lifetime for the current -key has not expired. -\item[OVSEC_KADM_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 ovsec_kadm_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 ovsec_kadm_randkey_principal. - -\item Call ovsec_kadm_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{ovsec_kadm_get_principal} - -\begin{verbatim} -ovsec_kadm_ret_t -ovsec_kadm_get_principal(krb5_principal princ, - ovsec_kadm_principal_ent_t *ent); -\end{verbatim} - -Return the principal's attributes in allocated memory. The caller -must free the returned entry with ovsec_kadm_free_principal_ent. -If an error is returned entry is set to NULL. - -AUTHORIZATION REQUIRED: get, or the calling principal being the same -as the princ argument. If the request is authenticated to the -ovsec_kadm/changepw service, the get privilege is disregarded. - - -RETURN CODES: - -\begin{description} -\item[OVSEC_KADM_UNK_PRINC] Principal does not exist. -\end{description} - -\subsection{ovsec_kadm_create_policy} - -\begin{verbatim} -ovsec_kadm_ret_t -ovsec_kadm_create_policy(ovsec_kadm_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 OVSEC_KADM_BAD_MASK error. -\item Return OVSEC_KADM_BAD_POLICY if the policy name contains illegal -characters. - -\item Check to see if the policy already exists, if so return -OVSEC_KADM_DUP error. -\item If the PW_MIN_CLASSES bit is set and pw_min_classes is not 1, 2, -3, 4, or 5, return OVSEC_KADM_BAD_CLASS. -\item Create a new policy setting the appropriate fields determined -by the mask. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[OVSEC_KADM_DUP] Policy already exists -\item[OVSEC_KADM_BAD_MASK] The mask is not valid for a create -operation. -\item[OVSEC_KADM_BAD_CLASS] The specified number of character classes -is invalid. -\item[OVSEC_KADM_BAD_POLICY] The policy name contains illegal characters. -\end{description} - -\subsection{ovsec_kadm_delete_policy} - -\begin{verbatim} -ovsec_kadm_ret_t -ovsec_kadm_delete_policy(char *policy); -\end{verbatim} - -Deletes a policy. - -AUTHORIZATION REQUIRED: delete - -\begin{enumerate} -\item Return OVSEC_KADM_BAD_POLICY if the policy name contains illegal -characters. -\item Return OVSEC_KADM_UNK_POLICY if the named policy does not exist. -\item Return OVSEC_KADM_POLICY_REF if the named policy's refcnt is not 0. -\item Delete policy. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[OVSEC_KADM_BAD_POLICY] The policy name contains illegal characters. -\item[OVSEC_KADM_UNK_POLICY] Policy does not exist. -\item[OVSEC_KADM_POLICY_REF] Policy is being referenced. -\end{description} - -\subsection{ovsec_kadm_modify_policy} - -\begin{verbatim} -ovsec_kadm_ret_t -ovsec_kadm_modify_policy(ovsec_kadm_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 OVSEC_KADM_BAD_POLICY if the policy name contains illegal -characters. -\item Check to see if mask is legal, if not return OVSEC_KADM_BAD_MASK error. -\item Check to see if policy exists, if not return -OVSEC_KADM_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 OVSEC_KADM_BAD_CLASS. -\item Update the fields specified in the mask. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[OVSEC_KADM_BAD_POLICY] The policy name contains illegal characters. -\item[OVSEC_KADM_UNK_POLICY] Policy not found. -\item[OVSEC_KADM_BAD_MASK] The mask is not valid for a modify -operation. -\item[OVSEC_KADM_BAD_CLASS] The specified number of character classes -is invalid. -\end{description} - -\subsection{ovsec_kadm_get_policy} - -\begin{verbatim} -ovsec_kadm_ret_t -ovsec_kadm_get_policy(char *policy, ovsec_kadm_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 ovsec_kadm/changepw service, the get privilege is disregarded. -If an error is returned entry is set to NULL. - -Return the policy's attributes in allocated memory. The caller must -free the returned entry with ovsec_kadm_free_policy_ent. - -RETURN CODES: - -\begin{description} -\item[OVSEC_KADM_BAD_POLICY] The policy name contains illegal characters. -\item[OVSEC_KADM_UNK_POLICY] Policy not found. -\end{description} - -\subsection{ovsec_kadm_free_principal_ent, _policy_ent} - -\begin{verbatim} -void ovsec_kadm_free_principal_ent(ovsec_kadm_principal_ent_t princ); -\end{verbatim} - -Free the memory that was allocated by a call to -ovsec_kadm_get_principal. If the argument is NULL, the function -returns succesfully. - -AUTHORIZATION REQUIRED: none (local operation) - -\begin{verbatim} -void ovsec_kadm_free_policy_ent(ovsec_kadm_policy_ent_t policy); -\end{verbatim} - -Free memory that was allocated by a call to ovsec_kadm_get_policy. If -the argument is NULL, the function returns succesfully. - -AUTHORIZATION REQUIRED: none (local operation) - -\subsection{ovsec_kadm_get_privs} - -\begin{verbatim} -ovsec_kadm_ret_t -ovsec_kadm_get_privs(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 & OVSEC_KADM_PRIV_GET & 0x01 \\ -Add & OVSEC_KADM_PRIV_ADD & 0x02 \\ -Modify & OVSEC_KADM_PRIV_MODIFY & 0x04 \\ -Delete & OVSEC_KADM_PRIV_DELETE & 0x08 -\end{tabular} - -There is no guarantee that a caller will have a privilege indicated by -this function for any length of time; applications using this function -must still be prepared to handle all possible OVSEC_KADM_AUTH_* error -codes. - -\section{Server} - -The Admin API will be implemented by a server process running on the -same machine as the Kerberos server, and a client library to -communicate with the server. - -\subsection{Command Line} -\label{sec:commandline} - -The command line syntax of the admin server is - -\begin{verbatim} -ovsec_adm_server [-m] [-r realm] [-createsalt normal|none] - [-modifysalt normal|none|keep] -\end{verbatim} - -The -m argument specifies that the Kerberos master key should be read -from the keyboard instead of from the stash file. If the stash file -does not exist and this argument is not specified, the server will -not start. - -The -r argument specifies the Kerberos realm. If this argument is not -specified, the host's default realm is used. - -The -createsalt and -modifysalt arguments control the type of salt -used when creating and modifying keys in the Kerberos database, -respectively. ``normal'' means the standard V5 salt which uses the -principal and realm name. ``none'' means no salt, which is compatible -with Kerberos V4. ``keep'' means maintain the previous salt when a -key is changed. - -If the either admin principal or policy databases are reloaded using -the tools described in section \ref{sec:tools}, the admin server must -be shut down during the process. If the admin server is left running -during the import process, at best the server may use old information -and at worst the database may become inconsistent. - -\subsection{Protocol and Port Number} - -The admin server accepts TCP Sun RPC connections. The port number -(which the server listens on, and which clients should use to contact -it) is determined by a three step process: - -\begin{enumerate} -\item If ovsec_kadm/tcp exists in /etc/services, the specified port -number is used. - -\item Otherwise, if kerberos_adm/tcp exists in /etc/services, the -specified port number is used. - -\item Otherwise, port number 752 is used. -\end{enumerate} - -\subsection{Key Table, Authorization ACLs} -\label{sec:acls} - -The admin server's keytable is stored in /krb5/ovsec_admin.srvtab. It -contains entries for the principals ovsec_kadm/admin and -ovsec_kadm/changepw. - -The admin server will use a simple ACL mechanism to grant privileges -to principals. The file {\tt /krb5/ovsec_admin_acl} will contain a -list of principals and their privileges. It is read at start-up, and -can only be reread by restarting the admin server. - -The format of this file is: - -\begin{itemize} -\item Blank lines or lines beginning with ``\#'' are ignored. - -\item ACL entry lines contain two fields separated by any number of -spaces, tabs, or newlines, and are terminated with a semi-colon. The -first field is a Kerberos name and the second field is the privilege -list. - -\item The privilege list can contain a comma separated list of the -words ``get'', ``add'', ``modify'', and ``delete''. -\end{itemize} - -The principal named in the first field of each ACL entry has the -privileges listed in the second field the ACL entry. - -\subsection{Logging} - -The Admin server will log various events via the syslog mechanism (see -the syslog(3) manual page). The level depends on the notice, the -facility is LOG_LOCAL6, and notices are identified with the name -``ovsec_adm_server''. Each syslog message described below begins with -a prefix including the time the message was logged, the host name of -the logging machine, and the pid of the logging process: - -\begin{verbatim} -Nov 11 12:37:26 suan-la-chow-show ovsec_adm_server[9229]: <message> -\end{verbatim} - -\subsubsection{Miscellaneous Messages} - -When the server starts successfully and is ready to handle requests, -is logs the message ``starting'' at the LOG_INFO level. When it exits -(due to a signal, for example) it logs the message ``finished, -exiting'' at the LOG_INFO level. - -If the dictionary file does not exist, the server logs the message -``WARNING: Cannot find the dictionary file $<$name$>$, continuing -without one.'' at the LOG_ERR level and continues with dictionary -checking disabled. - -If the server cannot register itself as an RPC server via the portmap -daemon, it logs the message ``Cannot register RPC service, failing.'' -at the LOG_ERR level and exits with non-zero status. This error can -happen if the portmapper is not running. - -If the GSS-API authentication system cannot be initialized, the server -logs the message ``Cannot initialize GSS-API authentication, -failing.'' at the LOG_ERR level and exits with non-zero status. This -error can happen if, for example, the file ovsec_adm.srvtab does not -exist or is incorrect. - -\subsubsection{Request Messages} - -In the event descriptions below, IP address refers to the originating -remote IP address, procedure name refers to the name of the API -function, client name refers to the authenticated name of the caller, -service name refers to the service the client authenticated to (see -section \ref{sec:auth}), primary argument refers to the name of the -principal or policy affected by the call,\footnote{The first release -only logs the primary argument, rather than logging the old and new -values of all fields.} and status refers to the com_err string -corresponding to the error code generated. All of these messages are -logged at the LOG_NOTICE level. - -\begin{itemize} -\item Unsuccessful authentication attempts (e.g.: failures during -GSS-API context establishment). This error occurs inside the RPC; the -admin server is notified via a callback. - -\begin{verbatim} -Authentication attempt failed: <IP address>, <GSS-API error strings> -\end{verbatim} - -Example: A buggy client attempts to authenticate to the admin server -as the existing but invalid service name ``mailserver@REALM.COM'': - -\begin{verbatim} -Authentication attempt failed: 192.231.148.11, Miscellaneous error, Wrong -principal in request -\end{verbatim} - -\item Authentication failure. This error can occur both within the -RPC, while parsing the RPC call header, and while arguments are -decoded by the admin server. It can be the result of a a garbled -{\it or retransmitted} packet, a replay attack, a packet-modification -attack, or a header/argument splicing attack. - -\begin{verbatim} -WARNING! Forged/garbled request: <procedure name>, claimed client = <client -name>, service = <service name>, addr = <IP address> -\end{verbatim} - -Example: An attacker attempts to replay a previously valid ``create -principal'' message from jon/admin@REALM.COM: - -\begin{verbatim} -WARNING! Forged/garbled request: ovsec_kadm_create_principal, claimed client = -jon/admin@REALM.COM, service = admin@REALM.COM, addr = 192.231.148.12 -\end{verbatim} - -\item Unauthorized request. This error occurs when a properly -authenticated caller attempts to perform an operation for which it is -not authorized. - -\begin{verbatim} -Unauthorized request: <procedure name>, <primary argument>, client = -<client name>, service = <service name>, addr = <IP address> -\end{verbatim} - -Example: An attacker cracker@REALM.COM attempts to modify the Kerberos -master principal: - -\begin{verbatim} -Unauthorized request: ovsec_kadm_modify_principal, K/M@REALM.COM, -client = cracker@REALM.COM, service = admin@REALM.COM, addr = -192.231.148.12 -\end{verbatim} - -\item Authorized requests and miscellaneous errors. A message is -logged when an authorized request succeeds or fails for any reason -other than those listed above. In the case of success, the status is -``success''; otherwise, the status can be anything from ``no space -left on device'' (ENOSPC) to an OVSEC_KADM error such as ``principal -does not exist'' (OVSEC_KADM_UNK_PRINC). - -\begin{verbatim} -Request: <procedure name>, <primary argument>, <status>, client = -<client name>, service = <service name>, addr = <IP address> -\end{verbatim} - -Example: jon/admin@REALM.COM creates a new principal new@REALM.COM: - -\begin{verbatim} -Request: ovsec_kadm_create_principal, new@REALM.COM, success, -client = jon/admin@REALM.COM, service = admin@REALM.COM, addr = -192.231.148.12 -\end{verbatim} - -Example: A buggy client program attempts to create a principal with a -NULL name: - -\begin{verbatim} -Request: ovsec_kadm_create_principal, (null), Invalid argument, client -= jon/admin@REALM.COM, service = admin@REALM.COM, addr = -192.231.148.12 -\end{verbatim} - -Example: joe/user@REALM.COM changes its own password: - -\begin{verbatim} -Request: ovsec_kadm_chpass_principal, joe/user@REALM.COM, success, -client = joe/user@REALM.COM, server = ovsec_kadm/changepw@REALM.COM, -addr = 192.231.148.12 -\end{verbatim} - -Example: jon/admin@REALM.COM attempts to get a principal that does not -exist: - -\begin{verbatim} -Request: ovsec_kadm_get_principal, does/not/exist@REALM.COM, principal -does not exist, client = jon/admin@REALM.COM, server = -admin@REALM.COM, addr = 192.231.148.12 -\end{verbatim} - -\end{itemize} - -\subsection{Password Dictionary} - -The Admin server's password dictionary is stored in -/krb5/ovsec_adm_dict. It is read once when the server starts. It -contains a list of entries, separated by newlines. An entry may -include any character except a newline and NULL, including spaces. -The dictionary does not need to be sorted. - -\section{Tools} -\label{sec:tools} - -Three tools will be provided to create and manage the admin databases. -This need only run on the admin server machine and do not need to -operate remotely. The tools are: - -\begin{description} -\item[ovsec_adm_create] create the admin service principal, the admin -history principal, the admin password-changing principal, and empty -admin policy database, and an admin principal database with an empty -entry for every exist principal. -\item[ovsec_adm_db_export/import] dump or load the admin policy and -principal databases -\item[ovsec_adm_check] check the KDC and admin databases for -inconsistencies and repair them. -\end{description} - -The details of these tools are described in their own documents. - -\end{document} diff --git a/doc/kadm5/api-server-design.tex b/doc/kadm5/api-server-design.tex deleted file mode 100644 index b330e9c..0000000 --- a/doc/kadm5/api-server-design.tex +++ /dev/null @@ -1,584 +0,0 @@ -\documentstyle[12pt,fullpage,changebar]{article} - -% $Id$ - -\setlength{\parskip}{.7\baselineskip} -\setlength{\parindent}{0pt} - -\def\secure{OV*Secure} -\def\v#1{\verb+#1+} -\def\k#1{K$_#1$} - -\title{OV*Secure Admin Server \\ Implementation Design} -\author{Barry Jaspan} -\date{DRAFT --- \today} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Make _ actually generate an _, and allow line-breaking after it. -\let\underscore=\_ -\catcode`_=13 -\def_{\underscore\penalty75\relax} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\begin{document} - -\maketitle - -{\setlength{\parskip}{0pt}\tableofcontents} - -\section{Overview} - -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 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 server accesses a total of three databases. - -\begin{itemize} -\item The master Kerberos 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 admin principal database stores \secure{}-specific per-principal -information. - -\item The policy database stores \secure{} 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 -ovsec_kadm_create. Since a change in kadmin/history's key renders -every principal's key history array useless, it can only be changed -using the ovsec_kadm_edit utility; that program will reencrypt every -principal's key history in the new key. The admin server refuses all -requests to change kdamin/history's key. - -\section{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. -After 15 seconds of inactivity, the server closes all open databases; -each database will be automatically reopened by the API function -implementations as necessary. - -\section{Remote Procedure Calls} - -The RPC for the Admin system will be based on SUNRPC. SUNRPC 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 will be handled by adding a GSS-API -authentication type within the existing SUNRPC structure. This will -require code modifications to SUNRPC, but the API and wire protocol do -not need to change. This may affect whether the RPC will use UDP or -TCP; although all the admin functions are stateless, the GSS-API -authentication binding will not be and it might be easier to use TCP -for this reason. - -\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 $<$ovsec_admin/adb.h$>$), which is the -subset of the ovsec_kadm_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_princ_ent_t { - krb5_principal name; - - char * policy; - u_int32 aux_attributes; - - u_int32 num_old_keys; - u_int32 next_old_key; - krb5_kvno admin_history_kvno; - krb5_encrypted_keyblock *old_keys; -} osa_princ_ent_rec, *osa_princ_ent_t; -\end{verbatim} - -The fields that are different from ovsec_kadm_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[next_old_key] The index into old_keys where the next key should -be inserted. This value must be 0 $\le$ next_old_key $\le$ -num_old_keys. - -\item[admin_history_kvno] The key version number of the admin/history -principal's key used to encrypt the values in old_keys. If the admin -server finds that admin/history's kvno is different from the value in -this field, an error message is logged. (XXX where?) - -\item[old_keys] The array of the principal's previous keys, each -encrypted in the admin/history key. There are num_old_keys elements. -\end{description} - -\subsection{Policy, osa_policy_ent_t} - -The policy database stores records of the type osa_policy_ent_t -(declared in $<$ovsec_admin/adb.h$>$) , which is all of -ovsec_kadm_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 $<$krb5/kdb.h$>$ header file. - -\begin{verbatim} -typedef struct _krb5_encrypted_keyblock { - krb5_keytype keytype; - int length; - krb5_octet *contents; -} krb5_encrypted_keyblock; - -typedef struct _krb5_db_entry { - krb5_principal principal; - krb5_encrypted_keyblock key; - krb5_kvno kvno; - krb5_deltat max_life; - krb5_deltat max_renewable_life; - krb5_kvno mkvno; - - krb5_timestamp expiration; - krb5_timestamp pw_expiration; - krb5_timestamp last_pwd_change; - krb5_timestamp last_success; - - krb5_timestamp last_failed; - krb5_kvno fail_auth_count; - - krb5_principal mod_name; - krb5_timestamp mod_date; - krb5_flags attributes; - krb5_int32 salt_type:8, - salt_length:24; - krb5_octet *salt; - krb5_encrypted_keyblock alt_key; - krb5_int32 alt_salt_type:8, - alt_salt_length:24; - krb5_octet *alt_salt; - - krb5_int32 expansion[8]; -} krb5_db_entry; -\end{verbatim} - -The interpretation of most of these fields is the same as given in the -``Principals, ovsec_kadm_principal_ent_t'' section of the functional -specification. The fields that are not defined there are not used by -\secure{}; however, the admin server preserves the value of any fields -it does not understand. - -\section{Database Access Methods} - -\subsection{Principal and Policy Databases} - -This section describes the database abstraction used for the admin -principal and policy databases. 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 \#define -PRINCIPAL_DB (``/krb5/ovsec_principal.db'') in $<$ovsec_admin/adb.h$>$. The -location of the policy database is defined by the \#define POLICY_DB -(``/krb5/ovsec_policy.db'') in $<$ovsec_admin/adb.h$>$. - -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 -$<$ovsec_admin/adb.h$>$. The routines can be found (in the first -relase) in ``stage/lib/libadb.a''. They require linking with the -Berkely DB library (``stage/lib/libdb.a''). [Note: We needed to remove -the dbm compatibility routines from libdb.a because we want to leave -KDB library alone in case somebody wants to run a stock MIT KDC with -our admin server.] - -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 -$<$ovsec_admin/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. -\end{description} - -Database functions can also return system errors. Unless otherwise -specified, database functions return OSA_ADB_OK. - -\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_FAILURE if it -cannot open the database. - -\begin{verbatim} -osa_adb_ret_t -osa_adb_close_T(osa_adb_T_t db); -\end{verbatim} -% -Close an open database. - -\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 -invokations 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 dbm 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. - -\subsubsection{Database Manipulation Functions} - -The following functions are declared in \v{lib/kdb/kdb_dbm.c} in the -Kerberos sources and are available in libkdb.a. They can return the -following error codes; error codes that can be returned by any -function are indicated with a ``*'' and are not listed specifically -for each function. - -\begin{description} -\item[* KRB5_KDB_NOTINITED] The database is not open; call -krb5_dbm_db_init. -\item[* KRB5_KDB_CANTLOCK_DB] The necessary lock cannot be acquired. Try -again later. -\item[* system errors] An error occurred accessing the database files. -\item[KRB5_KDB_DB_INUSE] The database was modified without the use -of proper locking.\footnote{This error occurs when the entire database -is swapped out from the under the process, say by a kdb5_edit restore. -It can only be returned by krb5_db_get_principal. It is not yet clear -what a program should do when it gets this error.} -\item[KRB5_KDB_NOENTRY] The principal to be deleted is not -in the database. -\end{description} - -\begin{verbatim} -krb5_dbm_db_init(void) -\end{verbatim} - -Opens the Kerberos database file (but does not actually call -dbm_open). This can be called even if the database is already open, -in which case it just returns success. - -\begin{verbatim} -krb5_dbm_db_fini(void) -\end{verbatim} - -Closes the database file; this MUST be called before the process -exits. Returns KRB5_KDB_DBNOTINITED if the database isn't open, but -that isn't really a fatal error. - -\begin{verbatim} -krb5_dbm_get_principal(krb5_principal searchfor, - krb5_db_entry *entries, int *nentries, krb5_boolean *more) -\end{verbatim} - -Search the database for the principal searchfor and write the results -into *entries. The interface is set up to handle wildcard gets, but -the code doesn't handle it: *nentries is assumed to be 1, and *more is -always returned as 0. - -This function does not retry if the database cannot be locked; that is -up to the caller. - -Returns KRB5_KDB_DB_INUSE. - -\begin{verbatim} -krb5_dbm_put_principal(krb5_db_entry *entries, int *nentries) -\end{verbatim} - -Stores *nentries elements from the entries array into the database. -On return *nentries is set to the number of entries actually written; -the first *nentries entries will have been written, even if an error -pis returned. - -This function does not retry if the database cannot be locked; that is -up to the caller. - -\begin{verbatim} -krb5_dbm_db_delete_principal(krb5_principal searchfor, int *nentries) -\end{verbatim} - -Removes the principal searchfor from the database. nentries will be -set to 0 or 1 on output, indicating the number of entries deleted (the -code does not currently support wildcards). - -Returns KRB5_KDB_NOENTRY. - -\begin{verbatim} -typedef krb5_error_code (*iter_func)(krb5_pointer, krb5_db_entry *); - -krb5_dbm_db_iterate(iter_func func, krb5_point func_arg) -\end{verbatim} - -Calls (*func)(func_arg, entry) for every entry in the database. If -func returns an error code, the iteration stops and that error code is -returned. - -Returns func error codes. - -\begin{verbatim} -void krb5_dbm_db_free_principal(krb5_db_entry *entries, int nentries) -\end{verbatim} - -Frees entries returned by krb5_dbm_db_get_principal. nentries entries -in the array entries will be freed. - -\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 addresed by the functional specifications. - -\subsection{ovsec_kadm_create_principal} - -If the named principal exists in either the Kerberos or admin -principal database, but not both, return OVSEC_KADM_BAD_DB. - -The principal's initial key is not stored in the key history array at -creation time. - -\subsection{ovsec_kadm_delete_principal} - -If the named principal exists in either the Kerberos or admin -principal database, but not both, return OVSEC_KADM_BAD_DB. - -\subsection{ovsec_kadm_modify_principal} - -If the named principal exists in either the Kerberos or admin -principal database, but not both, return OVSEC_KADM_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 next_old_key. next_old_keys 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{ovsec_kadm_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 ovsec_kadm_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 OVSEC_KADM_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 OVSEC_KADM_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 -next_old_key element of old_keys, and increment next_old_key by one -modulo pw_history_num. - -\subsection{ovsec_kadm_get_principal} - -If the named principal exists in either the Kerberos or admin -principal database, but not both, return OVSEC_KADM_BAD_DB. - -\end{document} diff --git a/doc/kadm5/api-unit-test.tex b/doc/kadm5/api-unit-test.tex deleted file mode 100644 index 7bd470a..0000000 --- a/doc/kadm5/api-unit-test.tex +++ /dev/null @@ -1,2077 +0,0 @@ -\documentstyle[times,fullpage,rcsid]{article} - -\rcs$Header$ - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% 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 1.0 Admin API\\ -Unit Test Description\footnote{\rcsHeader}} -\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 API. Each API function is listed, followed by the -tests that shoud be performed on it. - -The tests described here are based on the ``OV*Secure Admin Functional -Specifications'' revision 1.27, dated November 17, 1993. - -Since inter-realm functionality is not a requirement for OpenV*Secure -1.0, it is not tested. - -All tests which test for success should verify, using some means other -than the return value of the function being tested, that the requested -operation was successfully performed. For example: for init, test -that other operations can be performed after init; for destroy, test -that other operations can't be performed after destroy; for modify -functions, verify that all modifications to the database which should -have taken place did, and that the new, modified data is in effect; -for get operations, verify that the data retrieved is the data that -should actually be in the database. - -As of now the tests are being re-worked to use database comparision routines -simular to the GUI tests. This routines are not completly in place yet. The -purpose for using these routines is for better detection of incorrect -database modification. - -Similarly, all tests which test for failure should verify that the -no component of the requested operation took place. For example: if -init fails, other operations should not work. If a modify fails, all -data in the database should be the same as it was before the attempt -to modify, and the old data should still be what is enforced. -Furthermore, tests which test for failure should verify that the -failure code returned is correct for the specific failure condition -tested. - -Most of the tests listed below should be run twice -- once locally on -the server after linking against the server API library, and once -talking to the server via authenticated Sun RPC after linking against -the client API library. Tests which should only be run locally or via -RPC are labelled with a ``local'' or ``RPC''. - -Furthermore, in addition to the tests labelled below, a test should be -implemented to verify that a client can't perform operations on the -server through the client API library when it's linked against -standard Sun RPC instead of OpenV*Secure's authenticated Sun RPC. -This will require a client with a modified version of ovsec_kadm_init -which doesn't call auth_gssapi_create. This client should call this -modified ovsec_kadm_init and then call some other admin API function, -specifying arguments to both functions that would work if the -authenciated Sun RPC had been used, but shouldn't if authentication -wasn't used. The test should verify that the API function call after -the init doesn't succeed. - -\section{ovsec_kadm_init} - -\numtest{1}{ -\Reason{An empty string realm is rejected.} -\Status{Implemented} -} - -\numtest{2}{ -\Reason{A realm containing invalid characters is rejected.} -\Status{Implemented} -} - -\numtest{2.5}{ -\Reason{A non-existent realm is rejected.} -\Status{Implemented} -} - -\numtest{3}{ -\Reason{A bad service name representing an existing principal - (different from the client principal) is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{4}{ -\Reason{A bad service name representing a non-existent - principal is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{5}{ -\Reason{A bad service name identical to the (existing) client - name is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{6}{ -\Reason{A null password causes password prompting.} -\Status{Implemented} -} - -\numtest{7}{ -\Reason{An empty-string causes password prompting} -\Status{Implemented} -} - -\numtest{8}{ -\Reason{An incorrect password which is the password of another - user is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{9}{ -\Reason{An incorrect password which isn't the password of any - user is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{10}{ -\Reason{A null client_name is rejected.} -\Status{Implemented} -} - -% Empty string client name is legal. -%\numtest{11}{ -%\Reason{An empty-string client_name is rejected.} -%} - -\numtest{12}{ -\Reason{A client_name referring to a non-existent principal in - the default realm is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{13}{ -\Reason{A client_name referring to a non-existent principal - with the local realm specified explicitly is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{14}{ -\Reason{A client_name referring to a non-existent principal in - a nonexistent realm is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{15}{ -\Reason{A client_name referring to an existing principal in a - nonexistent realm is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{16}{ -\Reason{Valid invocation.} -\Status{Implemented} -} - -\numtest{17}{ -\Reason{Valid invocation (explicit client realm).} -\Status{Implemented} -} - -\numtest{18}{ -\Reason{Valid invocation (CHANGEPW_SERVICE).} -\Status{Implemented} -} - -\numtest{19}{ -\Reason{Valid invocation (explicit service realm).} -\Status{Implemented} -} - -\numtest{20}{ -\Reason{Valid invocation (database access allowed after init).} -\Status{Implemented} -} - -\numtest{21}{ -\Reason{Init fails when called twice in a row.} -\Status{Implemented} -} - -\numtest{22}{ -\Reason{A null password causes master-key prompting.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{22.5}{ -\Reason{A empty string password causes master-key prompting.} -\Conditions{local} -\Status{Implemented} -} - -%\numtest{23}{ -%\Reason{A non-null password causes reading from the kstash.} -%\Conditions{local} -%\Status{Implemented} - -} - -\numtest{24}{ -\Reason{Null service name is ignored in local invocation.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{25}{ -\Reason{Non-null service name is ignored in local invocation.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{26}{ -\Reason{Can't do ``get'' operation before calling init.} -\Status{Implemented} -} - -\numtest{27}{ -\Reason{Can't do ``add'' operation before calling init.} -\Status{Implemented} -} - -\numtest{28}{ -\Reason{Can't do ``modify'' operation before calling init.} -\Status{Implemented} -} - -\numtest{29}{ -\Reason{Can't do ``delete'' operation before calling init.} -\Status{Implemented} -} - -\numtest{30}{ -\Reason{Can init after failed init attempt.} -\Conditions{local} -\Status{Implemented} -} - -\section{ovsec_kadm_destroy} - -\numtest{1}{ -\Reason{Valid invocation.} -\Status{Implemented} -} - -\numtest{2}{ -\Reason{Valid invocation (``get'' not allowed after destroy).} -\Status{Implemented} -} - -\numtest{3}{ -\Reason{Valid invocation (``add'' not allowed after destroy).} -\Status{Implemented} -} - -\numtest{4}{ -\Reason{Valid invocation (``modify'' not allowed after destroy).} -\Status{Implemented} -} - -\numtest{5}{ -\Reason{Valid invocation (``delete'' not allowed after destroy).} -\Status{Implemented} -} - -\numtest{6}{ -\Reason{Fails if database not initialized.} -\Status{Implemented} -} - -\numtest{7}{ -\Reason{Fails if invoked twice in a row.} -\Status{Implemented} -} - -\numtest{8}{ -\Reason{Database can be reinitialized after destroy.} -\Status{Implemented} -} - -\section{ovsec_kadm_create_principal} - -%In the tests below, ``getu'' refers to a user who has only ``get'' access, -%''addu'' refers to a user who has only ``add'' access, ``modifyu'' refers to -%a user who has only ``modify'' access, and ``deleteu'' refers to a user -%who has only ``delete'' access. ``amu'' refers to a user with ``add'' and -%''modify'' access. ``new_princ'' refers to a principal entry structure -%filled in as follows: -% -% krb5_parse_name("newuser", \&new_princ.principal); -% krb5_timeofday(\&new_princ.princ_expire_time); -% new_princ.princ_expire_time += 130; -% krb5_timeofday(\&new_princ.last_pwd_change); -% new_princ.last_pwd_change += 140; -% krb5_timeofday(\&new_princ.pw_expiration); -% new_princ.pw_expiration += 150; -% new_princ.max_life = 160; -% krb5_parse_name("usera", \&new_princ.mod_name); -% krb5_timeofday(\&new_princ.mod_date); -% new_princ.mod_date += 170; -% new_princ.attributes = 0xabcdabcd; -% new_princ.kvno = 180; -% new_princ.mkvno = 190; -% new_princ.policy = null; -% new_princ.aux_attributes = 0xdeadbeef; -% -%The offsets of 130 through 190 above are used to ensure that the -%fields are all known to be different from each other, so that -%accidentally switched fields can be detected. Some of the fields in -%this structure may be changed by the tests, but they should clean up -%after themselves. - -\numtest{1}{ -\Reason{Fails if database not initialized.} -\Status{Implemented} -} - -\numtest{2}{ -\Reason{Fails on null princ argument.} -\Status{Implemented} -} - -\numtest{3}{ -\Reason{Fails on null password argument.} -\Status{Implemented} -} - -\numtest{4}{ -\Reason{Fails on empty-string password argument.} -\Status{Implemented} -} - -\numtest{5}{ -\Reason{Fails when mask contains undefined bit.} -\Status{Implemented} -} - -\numtest{6}{ -\Reason{Fails when mask contains LAST_PWD_CHANGE bit.} -\Status{Implemented} -} - -\numtest{7}{ -\Reason{Fails when mask contains MOD_TIME bit.} -\Status{Implemented} -} - -\numtest{8}{ -\Reason{Fails when mask contains MOD_NAME bit.} -\Status{Implemented} -} - -\numtest{9}{ -\Reason{Fails when mask contains MKVNO bit.} -\Status{Implemented} -} - -\numtest{10}{ -\Reason{Fails when mask contains AUX_ATTRIBUTES bit.} -\Status{Implemented} -} - -\numtest{11}{ -\Reason{Fails when mask contains POLICY_CLR bit.} -\Status{Implemented} -} - -\numtest{12}{ -\Reason{Fails for caller with no access bits.} -\Status{Implemented} -} - -\numtest{13}{ -\Reason{Fails when caller has ``get'' access and not ``add''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{14}{ -\Reason{Fails when caller has ``modify'' access and not ``add''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{15}{ -\Reason{Fails when caller has ``delete'' access and not ``add''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{16}{ -\Reason{Fails when caller connected with CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{17}{ -\Reason{Fails on attempt to create existing principal.} -\Status{Implemented} -} - -\numtest{18}{ -\Reason{Fails when password is too short.} -\Status{Implemented} -} - -\numtest{19}{ -\Reason{Fails when password has too few classes.} -\Status{Implemented} -} - -\numtest{20}{ -\Reason{Fails when password is in dictionary.} -\Status{Implemented} -} - -\numtest{21}{ -\Reason{Nonexistent policy is rejected.} -\Status{Implemented} -} - -\numtest{22}{ -\Reason{Fails on invalid principal name.} -\Status{Implemented} -} - -\numtest{23}{ -\Reason{Valid invocation.} -\Status{Implemented} -} - -\numtest{24}{ -\Reason{Succeeds when caller has ``add'' access and another one.} -\Status{Implemented} -} - -%\numtest{25}{ -%\Reason{Fails when password is too short, when override_qual is true.} -%} - -%\numtest{26}{ -%\Reason{Fails when password has too few classes, when -% override_qual is true.} -%} - -%\numtest{27}{ -%\Reason{Fails when password is in dictionary, when override_qual is -% true.} -%} - -\numtest{28}{ -\Reason{Succeeds when assigning policy.} -\Status{Implemented} -} - -\numtest{29}{ -\Priority{High} -\Reason{Allows 0 (never) for princ_expire_time.} -\Status{Implemented} -} - -\numtest{30}{ -\Reason{Allows 0 (never) for pw_expiration when there's no policy.} -\Status{Implemented} -} - -\numtest{31}{ -\Reason{Allows 0 (never) for pw_expiration when there's a policy with - 0 for pw_max_life.} -\Status{Implemented} -} - -\numtest{32}{ -\Reason{Accepts 0 (never) for pw_expiration when there's a policy with - non-zero pw_max_life, but actually sets pw_expiration to now + - pw_max_life.} -\Status{Implemented} -} - -\numtest{33}{ -\Reason{Accepts and sets non-zero pw_expiration when no policy.} -\Status{Implemented} -} - -\numtest{34}{ -\Reason{Accepts and sets non-zero pw_expiration when there's a policy - with zero pw_max_life.} -\Status{Implemented} -} - -\numtest{35}{ -\Reason{Accepts and sets non-zero pw_expiration when there's a policy - with pw_max_life later than the specified pw_expiration.} -\Status{Implemented} -} - -\numtest{36}{ -\Reason{Accepts non-zero pw_expiration and limits it to now + - pw_max_life when it's later than now + non-zero pw_max_life in - policy.} -\Status{Implemented} -} - -\numtest{37}{ -\Priority{High} -\Reason{Sets pw_expiration to 0 (never) if there's no policy and no - specified pw_expiration.} -\Status{Implemented} -} - -\numtest{38}{ -\Priority{High} -\Reason{Sets pw_expiration to 0 (never) if it isn't specified and the - policy has a 0 (never) pw_max_life.} -\Status{Implemented} -} - -\numtest{39}{ -\Priority{High} -\Reason{Sets pw_expiration to now + pw_max_life if it isn't specified - and the policy has a non-zero pw_max_life.} -\Status{Implemented} -} - -\numtest{40}{ -\Priority{High} -\Reason{Allows 0 (forever) for max_life.} -\Status{Implemented} -} - -\numtest{41}{ -\Priority{High} -\Reason{Doesn't modify or free mod_name on success.} -} - -\numtest{42}{ -\Priority{High} -\Reason{Doesn't modify or free mod_name on failure.} -} - -\section{ovsec_kadm_delete_principal} - -\numtest{1}{ -\Reason{Fails if database not initialized.} -\Status{Implemented} -} - -\numtest{2}{ -\Reason{Fails on null principal.} -\Status{Implemented} -} - -% Empty string principal is legal. -%\numtest{3}{ -%\Reason{Fails on empty-string principal.} -%} - -% There is not invalid principal names -%\numtest{4}{ -%\Reason{Fails on invalid principal name.} -%} - -\numtest{5}{ -\Priority{High} -\Reason{Fails on nonexistent principal.} -\Status{Implemented} -} - -\numtest{6}{ -\Priority{High} -\Reason{Fails when caller connected with CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{7}{ -\Priority{High} -\Reason{Fails if caller has ``add'' access and not ``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{8}{ -\Priority{High} -\Reason{Fails if caller has ``modify'' access and not ``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{9}{ -\Priority{High} -\Reason{Fails if caller has ``get'' access and not ``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{10}{ -\Priority{High} -\Reason{Fails if caller has no access bits.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{11}{ -\Priority{High} -\Reason{Valid invocation.} -\Status{Implemented} -} - -\numtest{12}{ -\Priority{High} -\Reason{Valid invocation (on principal with policy).} -\Status{Implemented} -} - - - -\section{ovsec_kadm_modify_principal} - -\numtest{1}{ -\Reason{Fails if database not initialized.} -\Status{Implemented} -} - -\numtest{2}{ -\Priority{High} -\Reason{Fails if user connected with CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{3}{ -\Reason{Fails on mask with undefined bit set.} -\Status{Implemented} -} - -\numtest{4}{ -\Reason{Fails on mask with PRINCIPAL set.} -\Status{Implemented} -} - -\numtest{5}{ -\Priority{High} -\Reason{Fails on mask with LAST_PWD_CHANGE set.} -\Status{Implemented} -} - -\numtest{6}{ -\Reason{Fails on mask with MOD_TIME set.} -\Status{Implemented} -} - -\numtest{7}{ -\Reason{Fails on mask with MOD_NAME set.} -\Status{Implemented} -} - -\numtest{8}{ -\Reason{Fails on mask with MKVNO set.} -\Status{Implemented} -} - -\numtest{9}{ -\Priority{High} -\Reason{Fails on mask with AUX_ATTRIBUTES set.} -\Status{Implemented} -} - -\numtest{10}{ -\Reason{Fails on nonexistent principal.} -\Status{Implemented} -} - -\numtest{11}{ -\Priority{High} -\Reason{Fails for user with no access bits.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{12}{ -\Priority{High} -\Reason{Fails for user with ``get'' access.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{13}{ -\Priority{High} -\Reason{Fails for user with ``add'' access.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{14}{ -\Priority{High} -\Reason{Fails for user with ``delete'' access.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{15}{ -\Priority{High} -\Reason{Succeeds for user with ``modify'' access.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{16}{ -\Reason{Succeeds for user with ``modify'' and another access.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{17}{ -\Priority{High} -\Reason{Fails when nonexistent policy is specified.} -\Status{Implemented} -} - -\numtest{18}{ -\Priority{High} -\Reason{Succeeds when existent policy is specified.} -\Status{Implemented} -} - -\numtest{19}{ -\Reason{Updates policy count when setting policy from none.} -\Status{Implemented} -} - -\numtest{20}{ -\Reason{Updates policy count when clearing policy from set.} -\Status{Implemented} -} - -\numtest{21}{ -\Reason{Updates policy count when setting policy from other policy.} -\Status{Implemented} -} - -\numtest{21.5} -\Reason{Policy reference count remains unchanged when policy is - changed to itself.} -\status{Implemented.} -} - -\numtest{22}{ -\Reason{Allows 0 (never) for pw_expiration when there's no policy.} -\Status{Implemented} -} - -\numtest{23}{ -\Reason{Allows 0 (never) for pw_expiration when there's a policy with - 0 for pw_max_life.} -\Status{Implemented} -} - -\numtest{24}{ -\Reason{Accepts 0 (never) for pw_expiration when there's a policy with - non-zero pw_max_life, but actually sets pw_expiration to - last_pwd_change + pw_max_life.} -\Status{Implemented} -} - -\numtest{25}{ -\Reason{Accepts and sets non-zero pw_expiration when no policy.} -\Status{Implemented} -} - -\numtest{26}{ -\Reason{Accepts and sets non-zero pw_expiration when there's a policy - with zero pw_max_life.} -\Status{Implemented} -} - -\numtest{27}{ -\Reason{Accepts and sets non-zero pw_expiration when there's a policy - with pw_max_life later than the specified pw_expiration.} -\Status{Implemented} -} - -\numtest{28}{ -\Reason{Accepts non-zero pw_expiration and limits it to last_pwd_change + - pw_max_life when it's later than last_pwd_change + non-zero - pw_max_life in policy.} -\Status{Implemented} -} - -\numtest{29}{ -\Priority{High} -\Reason{Sets pw_expiration to 0 (never) if there's no policy and no - specified pw_expiration.} -\Status{Implemented} -} - -\numtest{30}{ -\Priority{High} -\Reason{Sets pw_expiration to 0 (never) if it isn't specified and the - policy has a 0 (never) pw_max_life.} -\Status{Implemented} -} - -\numtest{31}{ -\Priority{High} -\Reason{Sets pw_expiration to now + pw_max_life if it isn't specified - and the policy has a non-zero pw_max_life.} -\Status{Implemented} -} - -\numtest{32}{ -\Priority{High} -\Reason{Accepts princ_expire_time change.} -\Status{Implemented} -} - - - -\numtest{33}{ -\Priority{High} -\Reason{Accepts attributes change.} -\Status{Implemented} -} - -\numtest{33.25}{ -\Priority{High} -\Reason{Accepts attributes change (KRB5_KDB_REQUIRES_PW_CHANGE).} -\Status{Implemented} -} - -\numtest{33.5}{ -\Priority{High} -\Reason{Accepts attributes change (KRB5_DISALLOW_TGT_BASE).} -\Status{Implemented} -} - -\numtest{33.75}{ -\Priority{High} -\Reason{Accepts attributes change (KRB5_PW_CHANGE_SERVICE).} -\Status{Implemented} -} - -\numtest{34}{ -\Priority{High} -\Reason{Accepts max_life change.} -\Status{Implemented} -} - -\numtest{35}{ -\Priority{High} -\Reason{Accepts kvno change.} -\Status{Implemented} -} - -\numtest{36}{ -\Reason{Behaves correctly when policy is set to the same as it was - before.} -\Status{Implemented} -} - -\numtest{37}{ -\Reason{Behaves properly when POLICY_CLR is specified and there was no - policy before.} -\Status{Implemented} -} - -\numtest{38}{ -\Priority{High} -\Reason{Accepts 0 (never) for princ_expire_time.} -\Status{Implemented} -} - -\numtest{39}{ -\Priority{High} -\Reason{Accepts 0 for max_life.} -\Status{Implemented} -} - -\numtest{40}{ -\Reason{Rejects null principal argument.} -\Status{Implemented} -} - -\numtest{41}{ -\Priority{High} -\Reason{Doesn't modify or free mod_name on success.} -} - -\numtest{42}{ -\Priority{High} -\Reason{Doesn't modify or free mod_name on failure.} -} - - -\section{ovsec_kadm_rename_principal} - -\numtest{1}{ -\Reason{Fails if database not initialized.} -\Status{Implemented} -} - -\numtest{2}{ -\Priority{High} -\Reason{Fails if user connected with CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{3}{ -\Priority{High} -\Reason{Fails for user with no access bits.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{4}{ -\Reason{Fails for user with ``modify'' access and not ``add'' or -``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{5}{ -\Reason{Fails for user with ``get'' access and not ``add'' or -``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{6}{ -\Reason{Fails for user with ``modify'' and ``add'' but not ``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{7}{ -\Reason{Fails for user with ``modify'' and ``delete'' but not ``add''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{8}{ -\Reason{Fails for user with ``get'' and ``add'' but not ``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{9}{ -\Reason{Fails for user with ``get'' and ``delete'' but not ``add.''} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{10}{ -\Reason{Fails for user with ``modify'', ``get'' and ``add'', but not - ``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{11}{ -\Reason{Fails for user with ``modify'', ``get'' and ``delete'', but - not ``add''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{12}{ -\Priority{High} -\Reason{Fails for user with ``add'' but not ``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{13}{ -\Priority{High} -\Reason{Fails for user with ``delete'' but not ``add''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{14}{ -\Priority{High} -\Reason{Succeeds for user with ``add'' and ``delete''.} -\Status{Implemented} -} - -\numtest{15}{ -\Priority{High} -\Reason{Fails if target principal name exists.} -\Status{Implemented} -} - - - -\section{ovsec_kadm_chpass_principal} -\label{ovseckadmchpassprincipal} - -\subsection{Quality/history enforcement tests} - -This section lists a series of tests which will be run a number of -times, with various parameter settings (e.g., which access bits user -has, whether user connected with ADMIN_SERVICE or CHANGEPW_SERVICE, -etc.). The table following the -list of tests gives the various parameter settings under which the -tests should be run, as well which should succeed and which should -fail for each choice of parameter settings. - -\subsubsection{List of tests} - -The test number of each of these tests is an offset from the base -given in the table below. - -\numtest{1}{ -\Priority{High} -\Reason{With history setting of 1, change password to itself.} -} - -\numtest{2}{ -\Reason{With history setting of 2 but no password changes since - principal creation, change password to itself.} -} - -\numtest{3}{ -\Reason{With history setting of 2 and one password change since - principal creation, change password to itself - and directly previous password.} -} - -\numtest{4}{ -\Priority{High} -\Reason{With a history setting of 3 and no password changes, - change password to itself.} -} - -\numtest{5}{ -\Priority{High} -\Reason{With a history setting of 3 and 1 password change, - change password to itself or previous password.} -} - -\numtest{6}{ -\Priority{High} -\Reason{With a history setting of 3 and 2 password changes, - change password to itself and the two previous passwords.} -} - -\numtest{7}{ -\Priority{High} -\Reason{Change to previously unused password when now - - last_pwd_change $<$ pw_min_life.} -} - -\numtest{8}{ -\Priority{High} -\Reason{Change to previously unused password that doesn't contain enough - character classes.} -} - -\numtest{9}{ -\Priority{High} -\Reason{Change to previously unused password that's too short.} -} - -\numtest{10}{ -\Priority{High} -\Reason{Change to previously unused password that's in the dictionary.} -} - -\subsubsection{List of parameter settings} - -In the table below, ``7 passes'' means that test 7 above passes and -the rest of the tests fail. - -\begin{tabular}{llllll} -Base & Modify access? & Own password? & Service & Pass/Fail \\ \hline -0 & No & Yes & ADMIN & all fail \\ -20 & No & Yes & CHANGEPW & all fail \\ -40 & No & No & ADMIN & all fail \\ -60 & No & No & CHANGEPW & all fail \\ -80 & Yes & Yes & ADMIN & all fail \\ -100 & Yes & Yes & CHANGEPW & all fail \\ -120 & Yes & No & ADMIN & all fail \\ -140 & Yes & No & CHANGEPW & all fail \\ -\end{tabular} - -\subsection{Other quality/history tests} - -\numtest{161}{ -\Priority{High} -\Reason{With history of 1, can change password to anything other than - itself that doesn't conflict with other quality - rules.} -} - -\numtest{162}{ -\Reason{With history of 2 and 2 password changes, can change password - to original password.} -} - -\numtest{163}{ -\Priority{High} -\Reason{With history of 3 and 3 password changes, can change password - to original password.} -} - -\numtest{164}{ -\Priority{High} -\Reason{Can change password when now - last_pwd_change $>$ pw_min_life.} -} - -\numtest{165}{ -\Priority{High} -\Reason{Can change password when it contains exactly the number of - classes required by the policy.} -} - -\numtest{166}{ -\Priority{High} -\Reason{Can change password when it is exactly the length required by - the policy.} -} - -\numtest{167}{ -\Priority{High} -\Reason{Can change password to a word that isn't in the dictionary.} -} - - -\subsection{Other tests} - -\numtest{168}{ -\Reason{Fails if database not initialized.} -} - -\numtest{169}{ -\Reason{Fails for non-existent principal.} -} - -\numtest{170}{ -\Reason{Fails for null password.} -} - -\numtest{171}{ -\Priority{High} -\Reason{Fails for empty-string password.} -} - -\numtest{172}{ -\Priority{High} -\Reason{Pw_expiration is set to now + max_pw_life if policy exists and - has non-zero max_pw_life.} -} - -\numtest{173}{ -\Priority{High} -\Reason{Pw_expiration is set to 0 if policy exists and has zero - max_pw_life.} -} - -\numtest{174}{ -\Priority{High} -\Reason{Pw_expiration is set to 0 if no policy.} -} - -\numtest{175}{ -\Priority{High} -\Reason{KRB5_KDC_REQUIRES_PWCHANGE bit is cleared when password is - successfully changed.} -} - -\numtest{176}{ -\Priority{High} -\Reason{Fails for user with no access bits, on other's password.} -} - -\numtest{177}{ -\Priority{High} -\Reason{Fails for user with ``get'' but not ``modify'' access, on - other's password.} -} - -\numtest{178}{ -\Reason{Fails for user with ``delete'' but not ``modify'' access, on - other's password.} -} - -\numtest{179}{ -\Reason{Fails for user with ``add'' but not ``modify'' access, on - other's password.} -} - -\numtest{180}{ -\Reason{Succeeds for user with ``get'' and ``modify'' access, on - other's password.} -} - -\numtest{180.5}{ -\Priority{High} -\Reason{Succeeds for user with ``modify'' but not ``get'' access, on - other's password.} -} - -%\numtest{181}{ -%\Reason{Password that would succeed if override_qual were false fails -% if override_qual is true.} -%\Expected{Returns CANNOT_OVERRIDE.} -%} - - -\section{ovsec_kadm_chpass_principal_util} - -Rerun all the tests listed for ovsec_kadm_chpass_principal above in -Section \ref{ovseckadmchpassprincipal}. Verify that they succeed -and fail in the same circumstances. Also verify that in each failure -case, the error message returned in msg_ret is as specified in the -functional specification. - -Also, run the following additional tests. - -\numtest{1}{ -\Reason{Null msg_ret is rejected.} -} - -\numtest{2}{ -\Priority{High} -\Reason{New password is put into pw_ret, when it's prompted for.} -} - -\numtest{3}{ -\Priority{High} -Reason{New password is put into pw_ret, when it's supplied by the - caller.} -} - -\numtest{4}{ -\Priority{High} -\Reason{Successful invocation when pw_ret is null.} -} - - - -\section{ovsec_kadm_randkey_principal} - -\subsection{TOOSOON enforcement tests} - -This test should be run a number of times, as indicated in the table -following it. The table also indicates the expected result of each -run of the test. - -\test{ -\Reason{Change key when now - last_pwd_change $<$ pw_min_life.} -} - -\subsubsection{List of parameter settings} - -\begin{tabular}{llllll} -Number & Modify Access? & Own Key? & Service & Pass/Fail \\ \hline -1 & No & Yes & ADMIN & fail \\ -3 & No & Yes & CHANGEPW & fail \\ -5 & No & No & ADMIN & fail \\ -7 & No & No & CHANGEPW & fail \\ -9 & Yes & Yes & ADMIN & fail \\ -11 & Yes & Yes & CHANGEPW & fail \\ -13 & Yes & No & ADMIN & fail \\ -15 & Yes & No & CHANGEPW & fail \\ -\end{tabular} - -\subsection{Other tests} - -\numtest{17}{ -\Reason{Fails if database not initialized.} -} - -\numtest{18}{ -\Reason{Fails for non-existent principal.} -} - -\numtest{19}{ -\Reason{Fails for null keyblock pointer.} -} - -\numtest{20}{ -\Priority{High} -\Reason{Pw_expiration is set to now + max_pw_life if policy exists and - has non-zero max_pw_life.} -} - -\numtest{21}{ -\Priority{High} -\Reason{Pw_expiration is set to 0 if policy exists and has zero - max_pw_life.} -} - -\numtest{22}{ -\Priority{High} -\Reason{Pw_expiration is set to 0 if no policy.} -} - -\numtest{23}{ -\Priority{High} -\Reason{KRB5_KDC_REQUIRES_PWCHANGE bit is cleared when key is - successfully changed.} -} - -\numtest{24}{ -\Priority{High} -\Reason{Fails for user with no access bits, on other's password.} -} - -\numtest{25}{ -\Priority{High} -\Reason{Fails for user with ``get'' but not ``modify'' access, on - other's password.} -} - -\numtest{26}{ -\Reason{Fails for user with ``delete'' but not ``modify'' access, on - other's password.} -} - -\numtest{27}{ -\Reason{Fails for user with ``add'' but not ``modify'' access, on - other's password.} -} - -\numtest{28}{ -\Reason{Succeeds for user with ``get'' and ``modify'' access, on - other's password.} -} - -\numtest{28.5}{ -\Priority{High} -\Reason{Succeeds for user with ``modify'' but not ``get'' access, on - other's password.} -} - -\numtest{29}{ -\Reason{The new key that's assigned is truly random. XXX not sure how - to test this.} -} - - - -\section{ovsec_kadm_get_principal} - -\numtest{1}{ -\Reason{Fails for null ent.} -\Status{Implemented} -} - -\numtest{2}{ -\Reason{Fails for non-existent principal.} -\Status{Implemented} -} - -\numtest{3}{ -\Priority{High} -\Reason{Fails for user with no access bits, retrieving other principal.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{4}{ -\Priority{High} -\Reason{Fails for user with ``add'' but not ``get'', getting principal - other than his own, using ADMIN_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{5}{ -\Reason{Fails for user with ``modify'' but not ``get'', getting - principal other than his own, using ADMIN_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{6}{ -\Reason{Fails for user with ``delete'' but not ``get'', getting - principal other than his own, using ADMIN_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{7}{ -\Reason{Fails for user with ``delete'' but not ``get'', getting - principal other than his own, using CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{8}{ -\Priority{High} -\Reason{Fails for user with ``get'', getting principal other than his - own, using CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{9}{ -\Priority{High} -\Reason{Succeeds for user without ``get'', retrieving self, using - ADMIN_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{10}{ -\Reason{Succeeds for user without ``get'', retrieving self, using - CHANGEPW_SERVICE.} -\Status{Implemented} -} - -\numtest{11}{ -\Reason{Succeeds for user with ``get'', retrieving self, using - ADMIN_SERVICE.} -\Status{Implemented} -} - -\numtest{12}{ -\Reason{Succeeds for user with ``get'', retrieving self, using - CHANGEPW_SERVICE.} -\Status{Implemented} -} - -\numtest{13}{ -\Priority{High} -\Reason{Succeeds for user with ``get'', retrieving other user, using - ADMIN_SERVICE.} -\Status{Implemented} -} - -\numtest{14}{ -\Reason{Succeeds for user with ``get'' and ``modify'', retrieving - other principal, using ADMIN_SERVICE.} -\Status{Implemented} -} - - - -\section{ovsec_kadm_create_policy} - -\numtest{1}{ -\Reason{Fails for mask with undefined bit set.} -\Status{Implemented - untested} -} - -\numtest{2}{ -\Priority{High} -\Reason{Fails if caller connected with CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{3}{ -\Reason{Fails for mask without POLICY bit set.} -\Status{Implemented - untested} -} - -\numtest{4}{ -\Reason{Fails for mask with REF_COUNT bit set.} -\Status{Implemented} -} - -\numtest{5}{ -\Reason{Fails for invalid policy name.} -\Status{Implemented - untested} -} - -\numtest{6}{ -\Priority{High} -\Reason{Fails for existing policy name.} -\Status{Implemented} -} - -\numtest{7}{ -\Reason{Fails for null policy name.} -\Status{Implemented - untested} -} - -\numtest{8}{ -\Priority{High} -\Reason{Fails for empty-string policy name.} -\Status{Implemented} -} - -\numtest{9}{ -\Priority{High} -\Reason{Accepts 0 for pw_min_life.} -\Status{Implemented} -} - -\numtest{10}{ -\Priority{High} -\Reason{Accepts non-zero for pw_min_life.} -\Status{Implemented} -} - -\numtest{11}{ -\Priority{High} -\Reason{Accepts 0 for pw_max_life.} -\Status{Implemented} -} - -\numtest{12}{ -\Priority{High} -\Reason{Accepts non-zero for pw_max_life.} -\Status{Implemented} -} - -\numtest{13}{ -\Priority{High} -\Reason{Rejects 0 for pw_min_length.} -\Status{Implemented} -} - -\numtest{14}{ -\Priority{High} -\Reason{Accepts non-zero for pw_min_length.} -\Status{Implemented} -} - -\numtest{15}{ -\Priority{High} -\Reason{Rejects 0 for pw_min_classes.} -\Status{Implemented} -} - -\numtest{16}{ -\Priority{High} -\Reason{Accepts 1 for pw_min_classes.} -\Status{Implemented} -} - -\numtest{17}{ -\Priority{High} -\Reason{Accepts 4 for pw_min_classes.} -\Status{Implemented} -} - -\numtest{18}{ -\Priority{High} -\Reason{Rejects 5 for pw_min_classes.} -\Status{Implemented} -} - -\numtest{19}{ -\Priority{High} -\Reason{Rejects 0 for pw_history_num.} -\Status{Implemented} -} - -\numtest{20}{ -\Priority{High} -\Reason{Accepts 1 for pw_history_num.} -\Status{Implemented} -} - -\numtest{21}{ -\Priority{High} -\Reason{Accepts 10 for pw_history_num.} -\Status{Implemented} -} - -\numtest{21.5}{ -\Reason{Rejects 11 for pw_history_num.} -\Status{Implemented - untested} -} - -\numtest{22}{ -\Priority{High} -\Reason{Fails for user with no access bits.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{23}{ -\Priority{High} -\Reason{Fails for user with ``get'' but not ``add''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{24}{ -\Reason{Fails for user with ``modify'' but not ``add.''} -\Conditions{RPC} -\Status{Implemented - untested} -} - -\numtest{25}{ -\Reason{Fails for user with ``delete'' but not ``add.''} -\Conditions{RPC} -\Status{Implemented - untested} -} - -\numtest{26}{ -\Priority{High} -\Reason{Succeeds for user with ``add.''} -\Status{Implemented} -} - -\numtest{27}{ -\Reason{Succeeds for user with ``get'' and ``add.''} -\Status{Implemented - untested} -} - -\numtest{28}{ -\Reason{Rejects null policy argument.} -\Status{Implemented - untested} -} - -\numtest{29}{ -\Reason{Rejects pw_min_life greater than pw_max_life.} -} - - -\section{ovsec_kadm_delete_policy} - -\numtest{1}{ -\Reason{Fails for null policy name.} -} - -\numtest{2}{ -\Priority{High} -\Reason{Fails for empty-string policy name.} -\Status{Implemented} -} - -\numtest{3}{ -\Reason{Fails for non-existent policy name.} -} - -\numtest{4}{ -\Reason{Fails for bad policy name.} -} - -\numtest{5}{ -\Priority{High} -\Reason{Fails if caller connected with CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{6}{ -\Priority{High} -\Reason{Fails for user with no access bits.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{7}{ -\Priority{High} -\Reason{Fails for user with ``add'' but not ``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{8}{ -\Reason{Fails for user with ``modify'' but not ``delete''.} -\Conditions{RPC} -} - -\numtest{9}{ -\Reason{Fails for user with ``get'' but not ``delete.''} -\Conditions{RPC} -} - -\numtest{10}{ -\Priority{High} -\Reason{Succeeds for user with only ``delete''.} -\Status{Implemented} -} - -\numtest{11}{ -\Reason{Succeeds for user with ``delete'' and ``add''.} -} - -\numtest{12}{ -\Priority{High} -\Reason{Fails for policy with non-zero reference count.} -\Status{Implemented} -} - - - -\section{ovsec_kadm_modify_policy} - -\numtest{1}{ -\Reason{Fails for mask with undefined bit set.} -\Conditions{RPC} -} - -\numtest{2}{ -\Priority{High} -\Reason{Fails if caller connected with CHANGEPW_SERVICE.} -\Status{Implemented} -} - -\numtest{3}{ -\Reason{Fails for mask with POLICY bit set.} -} - -\numtest{4}{ -\Reason{Fails for mask with REF_COUNT bit set.} -\status{Implemented} -} - -\numtest{5}{ -\Reason{Fails for invalid policy name.} -} - -\numtest{6}{ -\Reason{Fails for non-existent policy name.} -} - -\numtest{7}{ -\Reason{Fails for null policy name.} -} - -\numtest{8}{ -\Priority{High} -\Reason{Fails for empty-string policy name.} -\Status{Implemented} -} - -\numtest{9}{ -\Priority{High} -\Reason{Accepts 0 for pw_min_life.} -\Status{Implemented} -} - -\numtest{10}{ -\Priority{High} -\Reason{Accepts non-zero for pw_min_life.} -\Status{Implemented} -} - -\numtest{11}{ -\Priority{High} -\Reason{Accepts 0 for pw_max_life.} -\Status{Implemented} -} - -\numtest{12}{ -\Priority{High} -\Reason{Accepts non-zero for pw_max_life.} -\Status{Implemented} -} - -\numtest{13}{ -\Priority{High} -\Reason{Accepts 0 for pw_min_length.} -\Status{Implemented} -} - -\numtest{14}{ -\Priority{High} -\Reason{Accepts non-zero for pw_min_length.} -\Status{Implemented} -} - -\numtest{15}{ -\Priority{High} -\Reason{Rejects 0 for pw_min_classes.} -\Status{Implemented} -} - -\numtest{16}{ -\Priority{High} -\Reason{Accepts 1 for pw_min_classes.} -\Status{Implemented} -} - -\numtest{17}{ -\Priority{High} -\Reason{Accepts 4 for pw_min_classes.} -\Status{Implemented} -} - -\numtest{18}{ -\Priority{High} -\Reason{Rejects 5 for pw_min_classes.} -\Status{Implemented} -} - -\numtest{19}{ -\Priority{High} -\Reason{Rejects 0 for pw_history_num.} -\Status{Implemented} -} - -\numtest{20}{ -\Priority{High} -\Reason{Accepts 1 for pw_history_num.} -\Status{Implemented} -} - -\numtest{21}{ -\Priority{High} -\Reason{Accepts 10 for pw_history_num.} -\Status{Implemented} -} - -\numtest{22}{ -\Priority{High} -\Reason{Fails for user with no access bits.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{23}{ -\Priority{High} -\Reason{Fails for user with ``get'' but not ``modify''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{24}{ -\Reason{Fails for user with ``add'' but not ``modify.''} -\Conditions{RPC} -} - -\numtest{25}{ -\Reason{Fails for user with ``delete'' but not ``modify.''} -\Conditions{RPC} -} - -\numtest{26}{ -\Priority{High} -\Reason{Succeeds for user with ``modify.''} -\Status{Implemented} -} - -\numtest{27}{ -\Reason{Succeeds for user with ``get'' and ``modify.''} -} - -\numtest{28}{ -\Reason{Rejects null policy argument.} -} - -\numtest{29}{ -\Reason{Rejects change which makes pw_min_life greater than - pw_max_life.} -} - -\section{ovsec_kadm_get_policy} - -\numtest{1}{ -\Reason{Fails for null policy.} -} - -\numtest{2}{ -\Reason{Fails for invalid policy name.} -} - -\numtest{3}{ -\Priority{High} -\Reason{Fails for empty-string policy name.} -\Status{Implemented} -} - -\numtest{4}{ -\Reason{Fails for non-existent policy name.} -} - -\numtest{5}{ -\Reason{Fails for null ent.} -} - -\numtest{6}{ -\Priority{High} -\Reason{Fails for user with no access bits trying to get other's - policy, using ADMIN_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{7}{ -\Priority{High} -\Reason{Fails for user with ``add'' but not ``get'' trying to get - other's policy, using ADMIN_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{8}{ -\Reason{Fails for user with ``modify'' but not ``get'' trying to get - other's policy, using ADMIN_SERVICE.} -\Conditions{RPC} -} - -\numtest{9}{ -\Reason{Fails for user with ``delete'' but not ``get'' trying to get - other's policy, using ADMIN_SERVICE.} -\Conditions{RPC} -} - -\numtest{10}{ -\Reason{Fails for user with ``delete'' but not ``get'' trying to get - other's policy, using CHANGEPW_SERVICE.} -\Conditions{RPC} -} - -\numtest{11}{ -\Priority{High} -\Reason{Succeeds for user with only ``get'', trying to get own policy, - using ADMIN_SERVICE.} -\Status{Implemented} -} - -\numtest{12}{ -\Priority{High} -\Reason{Succeeds for user with only ``get'', trying to get own policy, - using CHANGEPW_SERVICE.} -\Status{Implemented} -} - -\numtest{13}{ -\Reason{Succeeds for user with ``add'' and ``get'', trying to get own - policy, using ADMIN_SERVICE.} -} - -\numtest{14}{ -\Reason{Succeeds for user with ``add'' and ``get'', trying to get own - policy, using CHANGEPW_SERVICE.} -} - -\numtest{15}{ -\Reason{Succeeds for user without ``get'', trying to get own policy, - using ADMIN_SERVICE.} -} - -\numtest{16}{ -\Priority{High} -\Reason{Succeeds for user without ``get'', trying to get own policy, - using CHANGEPW_SERVICE.} -\Status{Implemented} -} - -\numtest{17}{ -\Priority{High} -\Reason{Succeeds for user with ``get'', trying to get other's policy, - using ADMIN_SERVICE.} -\Status{Implemented} -} - -\numtest{18}{ -\Priority{High} -\Reason{Fails for user with ``get'', trying to get other's policy, - using CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{19}{ -\Reason{Succeeds for user with ``modify'' and ``get'', trying to get - other's policy, using ADMIN_SERVICE.} -} - -\numtest{20}{ -\Reason{Fails for user with ``modify'' and ``get'', trying to get - other's policy, using CHANGEPW_SERVICE.} -} - - - -\section{ovsec_kadm_free_principal_ent} - -In addition to the tests listed here, a memory-leak detector such as -TestCenter, Purify or dbmalloc should be used to verify that the -memory freed by this function is really freed. - -\numtest{1}{ -\Reason{Null princ succeeds.} -} - -\numtest{2}{ -\Reason{Non-null princ succeeds.} -} - - -\section{ovsec_kadm_free_policy_ent} - -In addition to the tests listed here, a memory-leak detector such as -TestCenter, Purify or dbmalloc should be used to verify that the -memory freed by this function is really freed. - -\numtest{1}{ -\Reason{Null policy succeeds.} -} - -\numtest{2}{ -\Reason{Non-null policy succeeds.} -} - - - -\section{ovsec_kadm_get_privs} - -\numtest{1}{ -\Reason{Fails for null pointer argument.} -} - -This test should be run with the 16 possible combinations of access -bits (since there are 4 access bits, there are $2^4 = 16$ possible -combinations of them): - -\numtest{2}{ -\Priority{High} -\Reason{Returns correct bit mask for access bits of user.} -\Conditions{RPC} -} - -This test should be run locally: - -\numtest{3}{ -\Priority{High} -\Reason{Returns 0x0f.} -\Conditions{local} -} - -\end{document} |