+++ /dev/null
-\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}
+++ /dev/null
-\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}
+++ /dev/null
-\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}