%% Generated by Sphinx.
\def\sphinxdocclass{report}
\documentclass[letterpaper,10pt,english]{sphinxmanual}
\ifdefined\pdfpxdimen
   \let\sphinxpxdimen\pdfpxdimen\else\newdimen\sphinxpxdimen
\fi \sphinxpxdimen=.75bp\relax
\ifdefined\pdfimageresolution
    \pdfimageresolution= \numexpr \dimexpr1in\relax/\sphinxpxdimen\relax
\fi
%% let collapsible pdf bookmarks panel have high depth per default
\PassOptionsToPackage{bookmarksdepth=5}{hyperref}

\PassOptionsToPackage{booktabs}{sphinx}
\PassOptionsToPackage{colorrows}{sphinx}

\PassOptionsToPackage{warn}{textcomp}
\usepackage[utf8]{inputenc}
\ifdefined\DeclareUnicodeCharacter
% support both utf8 and utf8x syntaxes
  \ifdefined\DeclareUnicodeCharacterAsOptional
    \def\sphinxDUC#1{\DeclareUnicodeCharacter{"#1}}
  \else
    \let\sphinxDUC\DeclareUnicodeCharacter
  \fi
  \sphinxDUC{00A0}{\nobreakspace}
  \sphinxDUC{2500}{\sphinxunichar{2500}}
  \sphinxDUC{2502}{\sphinxunichar{2502}}
  \sphinxDUC{2514}{\sphinxunichar{2514}}
  \sphinxDUC{251C}{\sphinxunichar{251C}}
  \sphinxDUC{2572}{\textbackslash}
\fi
\usepackage{cmap}
\usepackage[T1]{fontenc}
\usepackage{amsmath,amssymb,amstext}
\usepackage{babel}



\usepackage{tgtermes}
\usepackage{tgheros}
\renewcommand{\ttdefault}{txtt}



\usepackage[Bjarne]{fncychap}
\usepackage{sphinx}

\fvset{fontsize=auto}
\usepackage{geometry}


% Include hyperref last.
\usepackage{hyperref}
% Fix anchor placement for figures with captions.
\usepackage{hypcap}% it must be loaded after hyperref.
% Set up styles of URL: it should be placed after hyperref.
\urlstyle{same}


\usepackage{sphinxmessages}
\setcounter{tocdepth}{1}



\title{Kerberos Plugin Module Developer Guide}
\date{ }
\release{1.22.2}
\author{MIT}
\newcommand{\sphinxlogo}{\vbox{}}
\renewcommand{\releasename}{Release}
\makeindex
\begin{document}

\ifdefined\shorthandoff
  \ifnum\catcode`\=\string=\active\shorthandoff{=}\fi
  \ifnum\catcode`\"=\active\shorthandoff{"}\fi
\fi

\pagestyle{empty}
\sphinxmaketitle
\pagestyle{plain}
\sphinxtableofcontents
\pagestyle{normal}
\phantomsection\label{\detokenize{plugindev/index::doc}}


\sphinxAtStartPar
Kerberos plugin modules allow increased control over MIT krb5 library
and server behavior.  This guide describes how to create dynamic
plugin modules and the currently available pluggable interfaces.

\sphinxAtStartPar
See \DUrole{xref,std,std-ref}{plugin\_config} for information on how to register dynamic
plugin modules and how to enable and disable modules via
\DUrole{xref,std,std-ref}{krb5.conf(5)}.


\chapter{Contents}
\label{\detokenize{plugindev/index:contents}}
\sphinxstepscope


\section{General plugin concepts}
\label{\detokenize{plugindev/general:general-plugin-concepts}}\label{\detokenize{plugindev/general::doc}}
\sphinxAtStartPar
A krb5 dynamic plugin module is a Unix shared object or Windows DLL.
Typically, the source code for a dynamic plugin module should live in
its own project with a build system using \sphinxhref{https://www.gnu.org/software/automake/}{automake} and \sphinxhref{https://www.gnu.org/software/libtool/}{libtool}, or
tools with similar functionality.

\sphinxAtStartPar
A plugin module must define a specific symbol name, which depends on
the pluggable interface and module name.  For most pluggable
interfaces, the exported symbol is a function named
\sphinxcode{\sphinxupquote{INTERFACE\_MODULE\_initvt}}, where \sphinxstyleemphasis{INTERFACE} is the name of the
pluggable interface and \sphinxstyleemphasis{MODULE} is the name of the module.  For these
interfaces, it is possible for one shared object or DLL to implement
multiple plugin modules, either for the same pluggable interface or
for different ones.  For example, a shared object could implement both
KDC and client preauthentication mechanisms, by exporting functions
named \sphinxcode{\sphinxupquote{kdcpreauth\_mymech\_initvt}} and \sphinxcode{\sphinxupquote{clpreauth\_mymech\_initvt}}.

\sphinxAtStartPar
A plugin module implementation should include the header file
\sphinxcode{\sphinxupquote{\textless{}krb5/INTERFACE\_plugin.h\textgreater{}}}, where \sphinxstyleemphasis{INTERFACE} is the name of the
pluggable interface.  For instance, a ccselect plugin module
implementation should use \sphinxcode{\sphinxupquote{\#include \textless{}krb5/ccselect\_plugin.h\textgreater{}}}.

\sphinxAtStartPar
initvt functions have the following prototype:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{krb5\PYGZus{}error\PYGZus{}code} \PYG{n}{interface\PYGZus{}modname\PYGZus{}initvt}\PYG{p}{(}\PYG{n}{krb5\PYGZus{}context} \PYG{n}{context}\PYG{p}{,}
                                         \PYG{n+nb}{int} \PYG{n}{maj\PYGZus{}ver}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{min\PYGZus{}ver}\PYG{p}{,}
                                         \PYG{n}{krb5\PYGZus{}plugin\PYGZus{}vtable} \PYG{n}{vtable}\PYG{p}{)}\PYG{p}{;}
\end{sphinxVerbatim}

\sphinxAtStartPar
and should do the following:
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {} 
\sphinxAtStartPar
Check that the supplied maj\_ver argument is supported by the
module.  If it is not supported, the function should return
KRB5\_PLUGIN\_VER\_NOTSUPP.

\item {} 
\sphinxAtStartPar
Cast the supplied vtable pointer to the structure type
corresponding to the major version, as documented in the pluggable
interface header file.

\item {} 
\sphinxAtStartPar
Fill in the structure fields with pointers to method functions and
static data, stopping at the field indicated by the supplied minor
version.  Fields for unimplemented optional methods can be left
alone; it is not necessary to initialize them to NULL.

\end{enumerate}

\sphinxAtStartPar
In most cases, the context argument will not be used.  The initvt
function should not allocate memory; think of it as a glorified
structure initializer.  Each pluggable interface defines methods for
allocating and freeing module state if doing so is necessary for the
interface.

\sphinxAtStartPar
Pluggable interfaces typically include a \sphinxstylestrong{name} field in the vtable
structure, which should be filled in with a pointer to a string
literal containing the module name.

\sphinxAtStartPar
Here is an example of what an initvt function might look like for a
fictional pluggable interface named fences, for a module named
“wicker”:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{krb5\PYGZus{}error\PYGZus{}code}
\PYG{n}{fences\PYGZus{}wicker\PYGZus{}initvt}\PYG{p}{(}\PYG{n}{krb5\PYGZus{}context} \PYG{n}{context}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{maj\PYGZus{}ver}\PYG{p}{,}
                     \PYG{n+nb}{int} \PYG{n}{min\PYGZus{}ver}\PYG{p}{,} \PYG{n}{krb5\PYGZus{}plugin\PYGZus{}vtable} \PYG{n}{vtable}\PYG{p}{)}
\PYG{p}{\PYGZob{}}
    \PYG{n}{krb5\PYGZus{}ccselect\PYGZus{}vtable} \PYG{n}{vt}\PYG{p}{;}

    \PYG{k}{if} \PYG{p}{(}\PYG{n}{maj\PYGZus{}ver} \PYG{o}{==} \PYG{l+m+mi}{1}\PYG{p}{)} \PYG{p}{\PYGZob{}}
        \PYG{n}{krb5\PYGZus{}fences\PYGZus{}vtable} \PYG{n}{vt} \PYG{o}{=} \PYG{p}{(}\PYG{n}{krb5\PYGZus{}fences\PYGZus{}vtable}\PYG{p}{)}\PYG{n}{vtable}\PYG{p}{;}
        \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{name} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{wicker}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{;}
        \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{slats} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}slats}\PYG{p}{;}
        \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{braces} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}braces}\PYG{p}{;}
    \PYG{p}{\PYGZcb{}} \PYG{k}{else} \PYG{k}{if} \PYG{p}{(}\PYG{n}{maj\PYGZus{}ver} \PYG{o}{==} \PYG{l+m+mi}{2}\PYG{p}{)} \PYG{p}{\PYGZob{}}
        \PYG{n}{krb5\PYGZus{}fences\PYGZus{}vtable\PYGZus{}v2} \PYG{n}{vt} \PYG{o}{=} \PYG{p}{(}\PYG{n}{krb5\PYGZus{}fences\PYGZus{}vtable\PYGZus{}v2}\PYG{p}{)}\PYG{n}{vtable}\PYG{p}{;}
        \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{name} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{wicker}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{;}
        \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{material} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}material}\PYG{p}{;}
        \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{construction} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}construction}\PYG{p}{;}
        \PYG{k}{if} \PYG{p}{(}\PYG{n}{min\PYGZus{}ver} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{2}\PYG{p}{)}
            \PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;}
        \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{footing} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}footing}\PYG{p}{;}
        \PYG{k}{if} \PYG{p}{(}\PYG{n}{min\PYGZus{}ver} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{3}\PYG{p}{)}
            \PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;}
        \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{appearance} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}appearance}\PYG{p}{;}
    \PYG{p}{\PYGZcb{}} \PYG{k}{else} \PYG{p}{\PYGZob{}}
        \PYG{k}{return} \PYG{n}{KRB5\PYGZus{}PLUGIN\PYGZus{}VER\PYGZus{}NOTSUPP}\PYG{p}{;}
    \PYG{p}{\PYGZcb{}}
    \PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}


\subsection{Logging from KDC and kadmind plugin modules}
\label{\detokenize{plugindev/general:logging-from-kdc-and-kadmind-plugin-modules}}
\sphinxAtStartPar
Plugin modules for the KDC or kadmind daemons can write to the
configured logging outputs (see \DUrole{xref,std,std-ref}{logging}) by calling the
\sphinxstylestrong{com\_err} function.  The first argument (\sphinxstyleemphasis{whoami}) is ignored.  If
the second argument (\sphinxstyleemphasis{code}) is zero, the formatted message is logged
at informational severity; otherwise, the formatted message is logged
at error severity and includes the error message for the supplied
code.  Here are examples:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{com\PYGZus{}err}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Client message contains }\PYG{l+s+si}{\PYGZpc{}d}\PYG{l+s+s2}{ items}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{nitems}\PYG{p}{)}\PYG{p}{;}
\PYG{n}{com\PYGZus{}err}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{retval}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{while decoding client message}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{;}
\end{sphinxVerbatim}

\sphinxAtStartPar
(The behavior described above is new in release 1.17.  In prior
releases, the \sphinxstyleemphasis{whoami} argument is included for some logging output
types, the logged message does not include the usual header for some
output types, and the severity for syslog outputs is configured as
part of the logging specification, defaulting to error severity.)

\sphinxstepscope


\section{Client preauthentication interface (clpreauth)}
\label{\detokenize{plugindev/clpreauth:client-preauthentication-interface-clpreauth}}\label{\detokenize{plugindev/clpreauth::doc}}
\sphinxAtStartPar
During an initial ticket request, a KDC may ask a client to prove its
knowledge of the password before issuing an encrypted ticket, or to
use credentials other than a password.  This process is called
preauthentication, and is described in \index{RFC@\spxentry{RFC}!RFC 4120@\spxentry{RFC 4120}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc4120.html}{\sphinxstylestrong{RFC 4120}} and \index{RFC@\spxentry{RFC}!RFC 6113@\spxentry{RFC 6113}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc6113.html}{\sphinxstylestrong{RFC 6113}}.
The clpreauth interface allows the addition of client support for
preauthentication mechanisms beyond those included in the core MIT
krb5 code base.  For a detailed description of the clpreauth
interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/clpreauth\_plugin.h\textgreater{}}} (or
\sphinxcode{\sphinxupquote{\textless{}krb5/preauth\_plugin.h\textgreater{}}} before release 1.12).

\sphinxAtStartPar
A clpreauth module is generally responsible for:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Supplying a list of preauth type numbers used by the module in the
\sphinxstylestrong{pa\_type\_list} field of the vtable structure.

\item {} 
\sphinxAtStartPar
Indicating what kind of preauthentication mechanism it implements,
with the \sphinxstylestrong{flags} method.  In the most common case, this method
just returns \sphinxcode{\sphinxupquote{PA\_REAL}}, indicating that it implements a normal
preauthentication type.

\item {} 
\sphinxAtStartPar
Examining the padata information included in a PREAUTH\_REQUIRED or
MORE\_PREAUTH\_DATA\_REQUIRED error and producing padata values for the
next AS request.  This is done with the \sphinxstylestrong{process} method.

\item {} 
\sphinxAtStartPar
Examining the padata information included in a successful ticket
reply, possibly verifying the KDC identity and computing a reply
key.  This is also done with the \sphinxstylestrong{process} method.

\item {} 
\sphinxAtStartPar
For preauthentication types which support it, recovering from errors
by examining the error data from the KDC and producing a padata
value for another AS request.  This is done with the \sphinxstylestrong{tryagain}
method.

\item {} 
\sphinxAtStartPar
Receiving option information (supplied by \sphinxcode{\sphinxupquote{kinit \sphinxhyphen{}X}} or by an
application), with the \sphinxstylestrong{gic\_opts} method.

\end{itemize}

\sphinxAtStartPar
A clpreauth module can create and destroy per\sphinxhyphen{}library\sphinxhyphen{}context and
per\sphinxhyphen{}request state objects by implementing the \sphinxstylestrong{init}, \sphinxstylestrong{fini},
\sphinxstylestrong{request\_init}, and \sphinxstylestrong{request\_fini} methods.  Per\sphinxhyphen{}context state
objects have the type krb5\_clpreauth\_moddata, and per\sphinxhyphen{}request state
objects have the type krb5\_clpreauth\_modreq.  These are abstract
pointer types; a module should typically cast these to internal
types for the state objects.

\sphinxAtStartPar
The \sphinxstylestrong{process} and \sphinxstylestrong{tryagain} methods have access to a callback
function and handle (called a “rock”) which can be used to get
additional information about the current request, including the
expected enctype of the AS reply, the FAST armor key, and the client
long\sphinxhyphen{}term key (prompting for the user password if necessary).  A
callback can also be used to replace the AS reply key if the
preauthentication mechanism computes one.

\sphinxstepscope


\section{KDC preauthentication interface (kdcpreauth)}
\label{\detokenize{plugindev/kdcpreauth:kdc-preauthentication-interface-kdcpreauth}}\label{\detokenize{plugindev/kdcpreauth::doc}}
\sphinxAtStartPar
The kdcpreauth interface allows the addition of KDC support for
preauthentication mechanisms beyond those included in the core MIT
krb5 code base.  For a detailed description of the kdcpreauth
interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/kdcpreauth\_plugin.h\textgreater{}}} (or
\sphinxcode{\sphinxupquote{\textless{}krb5/preauth\_plugin.h\textgreater{}}} before release 1.12).

\sphinxAtStartPar
A kdcpreauth module is generally responsible for:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Supplying a list of preauth type numbers used by the module in the
\sphinxstylestrong{pa\_type\_list} field of the vtable structure.

\item {} 
\sphinxAtStartPar
Indicating what kind of preauthentication mechanism it implements,
with the \sphinxstylestrong{flags} method.  If the mechanism computes a new reply
key, it must specify the \sphinxcode{\sphinxupquote{PA\_REPLACES\_KEY}} flag.  If the mechanism
is generally only used with hardware tokens, the \sphinxcode{\sphinxupquote{PA\_HARDWARE}}
flag allows the mechanism to work with principals which have the
\sphinxstylestrong{requires\_hwauth} flag set.

\item {} 
\sphinxAtStartPar
Producing a padata value to be sent with a preauth\_required error,
with the \sphinxstylestrong{edata} method.

\item {} 
\sphinxAtStartPar
Examining a padata value sent by a client and verifying that it
proves knowledge of the appropriate client credential information.
This is done with the \sphinxstylestrong{verify} method.

\item {} 
\sphinxAtStartPar
Producing a padata response value for the client, and possibly
computing a reply key.  This is done with the \sphinxstylestrong{return\_padata}
method.

\end{itemize}

\sphinxAtStartPar
A module can create and destroy per\sphinxhyphen{}KDC state objects by implementing
the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  Per\sphinxhyphen{}KDC state objects have the
type krb5\_kdcpreauth\_moddata, which is an abstract pointer types.  A
module should typically cast this to an internal type for the state
object.

\sphinxAtStartPar
A module can create a per\sphinxhyphen{}request state object by returning one in the
\sphinxstylestrong{verify} method, receiving it in the \sphinxstylestrong{return\_padata} method, and
destroying it in the \sphinxstylestrong{free\_modreq} method.  Note that these state
objects only apply to the processing of a single AS request packet,
not to an entire authentication exchange (since an authentication
exchange may remain unfinished by the client or may involve multiple
different KDC hosts).  Per\sphinxhyphen{}request state objects have the type
krb5\_kdcpreauth\_modreq, which is an abstract pointer type.

\sphinxAtStartPar
The \sphinxstylestrong{edata}, \sphinxstylestrong{verify}, and \sphinxstylestrong{return\_padata} methods have access
to a callback function and handle (called a “rock”) which can be used
to get additional information about the current request, including the
maximum allowable clock skew, the client’s long\sphinxhyphen{}term keys, the
DER\sphinxhyphen{}encoded request body, the FAST armor key, string attributes on the
client’s database entry, and the client’s database entry itself.  The
\sphinxstylestrong{verify} method can assert one or more authentication indicators to
be included in the issued ticket using the \sphinxcode{\sphinxupquote{add\_auth\_indicator}}
callback (new in release 1.14).

\sphinxAtStartPar
A module can generate state information to be included with the next
client request using the \sphinxcode{\sphinxupquote{set\_cookie}} callback (new in release
1.14).  On the next request, the module can read this state
information using the \sphinxcode{\sphinxupquote{get\_cookie}} callback.  Cookie information is
encrypted, timestamped, and transmitted to the client in a
\sphinxcode{\sphinxupquote{PA\sphinxhyphen{}FX\sphinxhyphen{}COOKIE}} pa\sphinxhyphen{}data item.  Older clients may not support cookies
and therefore may not transmit the cookie in the next request; in this
case, \sphinxcode{\sphinxupquote{get\_cookie}} will not yield the saved information.

\sphinxAtStartPar
If a module implements a mechanism which requires multiple round
trips, its \sphinxstylestrong{verify} method can respond with the code
\sphinxcode{\sphinxupquote{KRB5KDC\_ERR\_MORE\_PREAUTH\_DATA\_REQUIRED}} and a list of pa\sphinxhyphen{}data in
the \sphinxstyleemphasis{e\_data} parameter to be processed by the client.

\sphinxAtStartPar
The \sphinxstylestrong{edata} and \sphinxstylestrong{verify} methods can be implemented
asynchronously.  Because of this, they do not return values directly
to the caller, but must instead invoke responder functions with their
results.  A synchronous implementation can invoke the responder
function immediately.  An asynchronous implementation can use the
callback to get an event context for use with the \sphinxhref{https://fedorahosted.org/libverto/}{libverto} API.

\sphinxstepscope


\section{Credential cache selection interface (ccselect)}
\label{\detokenize{plugindev/ccselect:credential-cache-selection-interface-ccselect}}\label{\detokenize{plugindev/ccselect:ccselect-plugin}}\label{\detokenize{plugindev/ccselect::doc}}
\sphinxAtStartPar
The ccselect interface allows modules to control how credential caches
are chosen when a GSSAPI client contacts a service.  For a detailed
description of the ccselect interface, see the header file
\sphinxcode{\sphinxupquote{\textless{}krb5/ccselect\_plugin.h\textgreater{}}}.

\sphinxAtStartPar
The primary ccselect method is \sphinxstylestrong{choose}, which accepts a server
principal as input and returns a ccache and/or principal name as
output.  A module can use the krb5\_cccol APIs to iterate over the
cache collection in order to find an appropriate ccache to use.

\sphinxAtStartPar
A module can create and destroy per\sphinxhyphen{}library\sphinxhyphen{}context state objects by
implementing the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  State objects have
the type krb5\_ccselect\_moddata, which is an abstract pointer type.  A
module should typically cast this to an internal type for the state
object.

\sphinxAtStartPar
A module can have one of two priorities, “authoritative” or
“heuristic”.  Results from authoritative modules, if any are
available, will take priority over results from heuristic modules.  A
module communicates its priority as a result of the \sphinxstylestrong{init} method.

\sphinxstepscope


\section{Password quality interface (pwqual)}
\label{\detokenize{plugindev/pwqual:password-quality-interface-pwqual}}\label{\detokenize{plugindev/pwqual:pwqual-plugin}}\label{\detokenize{plugindev/pwqual::doc}}
\sphinxAtStartPar
The pwqual interface allows modules to control what passwords are
allowed when a user changes passwords.  For a detailed description of
the pwqual interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/pwqual\_plugin.h\textgreater{}}}.

\sphinxAtStartPar
The primary pwqual method is \sphinxstylestrong{check}, which receives a password as
input and returns success (0) or a \sphinxcode{\sphinxupquote{KADM5\_PASS\_Q\_}} failure code
depending on whether the password is allowed.  The \sphinxstylestrong{check} method
also receives the principal name and the name of the principal’s
password policy as input; although there is no stable interface for
the module to obtain the fields of the password policy, it can define
its own configuration or data store based on the policy name.

\sphinxAtStartPar
A module can create and destroy per\sphinxhyphen{}process state objects by
implementing the \sphinxstylestrong{open} and \sphinxstylestrong{close} methods.  State objects have
the type krb5\_pwqual\_moddata, which is an abstract pointer type.  A
module should typically cast this to an internal type for the state
object.  The \sphinxstylestrong{open} method also receives the name of the realm’s
dictionary file (as configured by the \sphinxstylestrong{dict\_file} variable in the
\DUrole{xref,std,std-ref}{kdc\_realms} section of \DUrole{xref,std,std-ref}{kdc.conf(5)}) if it wishes to use
it.

\sphinxstepscope


\section{KADM5 hook interface (kadm5\_hook)}
\label{\detokenize{plugindev/kadm5_hook:kadm5-hook-interface-kadm5-hook}}\label{\detokenize{plugindev/kadm5_hook:kadm5-hook-plugin}}\label{\detokenize{plugindev/kadm5_hook::doc}}
\sphinxAtStartPar
The kadm5\_hook interface allows modules to perform actions when
changes are made to the Kerberos database through \DUrole{xref,std,std-ref}{kadmin(1)}.
For a detailed description of the kadm5\_hook interface, see the header
file \sphinxcode{\sphinxupquote{\textless{}krb5/kadm5\_hook\_plugin.h\textgreater{}}}.

\sphinxAtStartPar
The kadm5\_hook interface has five primary methods: \sphinxstylestrong{chpass},
\sphinxstylestrong{create}, \sphinxstylestrong{modify}, \sphinxstylestrong{remove}, and \sphinxstylestrong{rename}.  (The \sphinxstylestrong{rename}
method was introduced in release 1.14.)  Each of these methods is
called twice when the corresponding administrative action takes place,
once before the action is committed and once afterwards.  A module can
prevent the action from taking place by returning an error code during
the pre\sphinxhyphen{}commit stage.

\sphinxAtStartPar
A module can create and destroy per\sphinxhyphen{}process state objects by
implementing the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  State objects have
the type kadm5\_hook\_modinfo, which is an abstract pointer type.  A
module should typically cast this to an internal type for the state
object.

\sphinxAtStartPar
Because the kadm5\_hook interface is tied closely to the kadmin
interface (which is explicitly unstable), it may not remain as stable
across versions as other public pluggable interfaces.

\sphinxstepscope


\section{kadmin authorization interface (kadm5\_auth)}
\label{\detokenize{plugindev/kadm5_auth:kadmin-authorization-interface-kadm5-auth}}\label{\detokenize{plugindev/kadm5_auth:kadm5-auth-plugin}}\label{\detokenize{plugindev/kadm5_auth::doc}}
\sphinxAtStartPar
The kadm5\_auth interface (new in release 1.16) allows modules to
determine whether a client principal is authorized to perform an
operation in the kadmin protocol, and to apply restrictions to
principal operations.  For a detailed description of the kadm5\_auth
interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/kadm5\_auth\_plugin.h\textgreater{}}}.

\sphinxAtStartPar
A module can create and destroy per\sphinxhyphen{}process state objects by
implementing the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  State objects have
the type kadm5\_auth\_modinfo, which is an abstract pointer type.  A
module should typically cast this to an internal type for the state
object.

\sphinxAtStartPar
The kadm5\_auth interface has one method for each kadmin operation,
with parameters specific to the operation.  Each method can return
either 0 to authorize access, KRB5\_PLUGIN\_NO\_HANDLE to defer the
decision to other modules, or another error (canonically EPERM) to
authoritatively deny access.  Access is granted if at least one module
grants access and no module authoritatively denies access.

\sphinxAtStartPar
The \sphinxstylestrong{addprinc} and \sphinxstylestrong{modprinc} methods can also impose restrictions
on the principal operation by returning a \sphinxcode{\sphinxupquote{struct
kadm5\_auth\_restrictions}} object.  The module should also implement
the \sphinxstylestrong{free\_restrictions} method if it dynamically allocates
restrictions objects for principal operations.

\sphinxAtStartPar
kadm5\_auth modules can optionally inspect principal or policy objects.
To do this, the module must also include \sphinxcode{\sphinxupquote{\textless{}kadm5/admin.h\textgreater{}}} to gain
access to the structure definitions for those objects.  As the kadmin
interface is explicitly not as stable as other public interfaces,
modules which do this may not retain compatibility across releases.

\sphinxstepscope


\section{Host\sphinxhyphen{}to\sphinxhyphen{}realm interface (hostrealm)}
\label{\detokenize{plugindev/hostrealm:host-to-realm-interface-hostrealm}}\label{\detokenize{plugindev/hostrealm:hostrealm-plugin}}\label{\detokenize{plugindev/hostrealm::doc}}
\sphinxAtStartPar
The host\sphinxhyphen{}to\sphinxhyphen{}realm interface was first introduced in release 1.12.  It
allows modules to control the local mapping of hostnames to realm
names as well as the default realm.  For a detailed description of the
hostrealm interface, see the header file
\sphinxcode{\sphinxupquote{\textless{}krb5/hostrealm\_plugin.h\textgreater{}}}.

\sphinxAtStartPar
Although the mapping methods in the hostrealm interface return a list
of one or more realms, only the first realm in the list is currently
used by callers.  Callers may begin using later responses in the
future.

\sphinxAtStartPar
Any mapping method may return KRB5\_PLUGIN\_NO\_HANDLE to defer
processing to a later module.

\sphinxAtStartPar
A module can create and destroy per\sphinxhyphen{}library\sphinxhyphen{}context state objects
using the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  If the module does not need
any state, it does not need to implement these methods.

\sphinxAtStartPar
The optional \sphinxstylestrong{host\_realm} method allows a module to determine
authoritative realm mappings for a hostname.  The first authoritative
mapping is used in preference to KDC referrals when getting service
credentials.

\sphinxAtStartPar
The optional \sphinxstylestrong{fallback\_realm} method allows a module to determine
fallback mappings for a hostname.  The first fallback mapping is tried
if there is no authoritative mapping for a realm, and KDC referrals
failed to produce a successful result.

\sphinxAtStartPar
The optional \sphinxstylestrong{default\_realm} method allows a module to determine the
local default realm.

\sphinxAtStartPar
If a module implements any of the above methods, it must also
implement \sphinxstylestrong{free\_list} to ensure that memory is allocated and
deallocated consistently.

\sphinxstepscope


\section{Local authorization interface (localauth)}
\label{\detokenize{plugindev/localauth:local-authorization-interface-localauth}}\label{\detokenize{plugindev/localauth:localauth-plugin}}\label{\detokenize{plugindev/localauth::doc}}
\sphinxAtStartPar
The localauth interface was first introduced in release 1.12.  It
allows modules to control the relationship between Kerberos principals
and local system accounts.  When an application calls
\sphinxcode{\sphinxupquote{krb5\_kuserok()}} or \sphinxcode{\sphinxupquote{krb5\_aname\_to\_localname()}}, localauth
modules are consulted to determine the result.  For a detailed
description of the localauth interface, see the header file
\sphinxcode{\sphinxupquote{\textless{}krb5/localauth\_plugin.h\textgreater{}}}.

\sphinxAtStartPar
A module can create and destroy per\sphinxhyphen{}library\sphinxhyphen{}context state objects
using the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  If the module does not need
any state, it does not need to implement these methods.

\sphinxAtStartPar
The optional \sphinxstylestrong{userok} method allows a module to control the behavior
of \sphinxcode{\sphinxupquote{krb5\_kuserok()}}.  The module receives the authenticated name
and the local account name as inputs, and can return either 0 to
authorize access, KRB5\_PLUGIN\_NO\_HANDLE to defer the decision to other
modules, or another error (canonically EPERM) to authoritatively deny
access.  Access is granted if at least one module grants access and no
module authoritatively denies access.

\sphinxAtStartPar
The optional \sphinxstylestrong{an2ln} method can work in two different ways.  If the
module sets an array of uppercase type names in \sphinxstylestrong{an2ln\_types}, then
the module’s \sphinxstylestrong{an2ln} method will only be invoked by
\sphinxcode{\sphinxupquote{krb5\_aname\_to\_localname()}} if an \sphinxstylestrong{auth\_to\_local} value in
\DUrole{xref,std,std-ref}{krb5.conf(5)} refers to one of the module’s types.  In this
case, the \sphinxstyleemphasis{type} and \sphinxstyleemphasis{residual} arguments will give the type name and
residual string of the \sphinxstylestrong{auth\_to\_local} value.

\sphinxAtStartPar
If the module does not set \sphinxstylestrong{an2ln\_types} but does implement
\sphinxstylestrong{an2ln}, the module’s \sphinxstylestrong{an2ln} method will be invoked for all
\sphinxcode{\sphinxupquote{krb5\_aname\_to\_localname()}} operations unless an earlier module
determines a mapping, with \sphinxstyleemphasis{type} and \sphinxstyleemphasis{residual} set to NULL.  The
module can return KRB5\_LNAME\_NO\_TRANS to defer mapping to later
modules.

\sphinxAtStartPar
If a module implements \sphinxstylestrong{an2ln}, it must also implement
\sphinxstylestrong{free\_string} to ensure that memory is allocated and deallocated
consistently.

\sphinxstepscope


\section{Server location interface (locate)}
\label{\detokenize{plugindev/locate:server-location-interface-locate}}\label{\detokenize{plugindev/locate::doc}}
\sphinxAtStartPar
The locate interface allows modules to control how KDCs and similar
services are located by clients.  For a detailed description of the
ccselect interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/locate\_plugin.h\textgreater{}}}.

\sphinxAtStartPar
A locate module exports a structure object of type
krb5plugin\_service\_locate\_ftable, with the name \sphinxcode{\sphinxupquote{service\_locator}}.
The structure contains a minor version and pointers to the module’s
methods.

\sphinxAtStartPar
The primary locate method is \sphinxstylestrong{lookup}, which accepts a service type,
realm name, desired socket type, and desired address family (which
will be AF\_UNSPEC if no specific address family is desired).  The
method should invoke the callback function once for each server
address it wants to return, passing a socket type (SOCK\_STREAM for TCP
or SOCK\_DGRAM for UDP) and socket address.  The \sphinxstylestrong{lookup} method
should return 0 if it has authoritatively determined the server
addresses for the realm, KRB5\_PLUGIN\_NO\_HANDLE if it wants to let
other location mechanisms determine the server addresses, or another
code if it experienced a failure which should abort the location
process.

\sphinxAtStartPar
A module can create and destroy per\sphinxhyphen{}library\sphinxhyphen{}context state objects by
implementing the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  State objects have
the type void *, and should be cast to an internal type for the state
object.

\sphinxstepscope


\section{Configuration interface (profile)}
\label{\detokenize{plugindev/profile:configuration-interface-profile}}\label{\detokenize{plugindev/profile:profile-plugin}}\label{\detokenize{plugindev/profile::doc}}
\sphinxAtStartPar
The profile interface allows a module to control how krb5
configuration information is obtained by the Kerberos library and
applications.  For a detailed description of the profile interface,
see the header file \sphinxcode{\sphinxupquote{\textless{}profile.h\textgreater{}}}.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
The profile interface does not follow the normal conventions
for MIT krb5 pluggable interfaces, because it is part of a
lower\sphinxhyphen{}level component of the krb5 library.
\end{sphinxadmonition}

\sphinxAtStartPar
As with other types of plugin modules, a profile module is a Unix
shared object or Windows DLL, built separately from the krb5 tree.
The krb5 library will dynamically load and use a profile plugin module
if it reads a \sphinxcode{\sphinxupquote{module}} directive at the beginning of krb5.conf, as
described in \DUrole{xref,std,std-ref}{profile\_plugin\_config}.

\sphinxAtStartPar
A profile module exports a function named \sphinxcode{\sphinxupquote{profile\_module\_init}}
matching the signature of the profile\_module\_init\_fn type.  This
function accepts a residual string, which may be used to help locate
the configuration source.  The function fills in a vtable and may also
create a per\sphinxhyphen{}profile state object.  If the module uses state objects,
it should implement the \sphinxstylestrong{copy} and \sphinxstylestrong{cleanup} methods to manage
them.

\sphinxAtStartPar
A basic read\sphinxhyphen{}only profile module need only implement the
\sphinxstylestrong{get\_values} and \sphinxstylestrong{free\_values} methods.  The \sphinxstylestrong{get\_values} method
accepts a null\sphinxhyphen{}terminated list of C string names (e.g., an array
containing “libdefaults”, “clockskew”, and NULL for the \sphinxstylestrong{clockskew}
variable in the \DUrole{xref,std,std-ref}{libdefaults} section) and returns a
null\sphinxhyphen{}terminated list of values, which will be cleaned up with the
\sphinxstylestrong{free\_values} method when the caller is done with them.

\sphinxAtStartPar
Iterable profile modules must also define the \sphinxstylestrong{iterator\_create},
\sphinxstylestrong{iterator}, \sphinxstylestrong{iterator\_free}, and \sphinxstylestrong{free\_string} methods.  The
core krb5 code does not require profiles to be iterable, but some
applications may iterate over the krb5 profile object in order to
present configuration interfaces.

\sphinxAtStartPar
Writable profile modules must also define the \sphinxstylestrong{writable},
\sphinxstylestrong{modified}, \sphinxstylestrong{update\_relation}, \sphinxstylestrong{rename\_section},
\sphinxstylestrong{add\_relation}, and \sphinxstylestrong{flush} methods.  The core krb5 code does not
require profiles to be writable, but some applications may write to
the krb5 profile in order to present configuration interfaces.

\sphinxAtStartPar
The following is an example of a very basic read\sphinxhyphen{}only profile module
which returns a hardcoded value for the \sphinxstylestrong{default\_realm} variable in
\DUrole{xref,std,std-ref}{libdefaults}, and provides no other configuration information.
(For conciseness, the example omits code for checking the return
values of malloc and strdup.)

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{c+c1}{\PYGZsh{}include \PYGZlt{}stdlib.h\PYGZgt{}}
\PYG{c+c1}{\PYGZsh{}include \PYGZlt{}string.h\PYGZgt{}}
\PYG{c+c1}{\PYGZsh{}include \PYGZlt{}profile.h\PYGZgt{}}

\PYG{n}{static} \PYG{n}{long}
\PYG{n}{get\PYGZus{}values}\PYG{p}{(}\PYG{n}{void} \PYG{o}{*}\PYG{n}{cbdata}\PYG{p}{,} \PYG{n}{const} \PYG{n}{char} \PYG{o}{*}\PYG{n}{const} \PYG{o}{*}\PYG{n}{names}\PYG{p}{,} \PYG{n}{char} \PYG{o}{*}\PYG{o}{*}\PYG{o}{*}\PYG{n}{values}\PYG{p}{)}
\PYG{p}{\PYGZob{}}
    \PYG{k}{if} \PYG{p}{(}\PYG{n}{names}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]} \PYG{o}{!=} \PYG{n}{NULL} \PYG{o}{\PYGZam{}}\PYG{o}{\PYGZam{}} \PYG{n}{strcmp}\PYG{p}{(}\PYG{n}{names}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{libdefaults}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)} \PYG{o}{==} \PYG{l+m+mi}{0} \PYG{o}{\PYGZam{}}\PYG{o}{\PYGZam{}}
        \PYG{n}{names}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]} \PYG{o}{!=} \PYG{n}{NULL} \PYG{o}{\PYGZam{}}\PYG{o}{\PYGZam{}} \PYG{n}{strcmp}\PYG{p}{(}\PYG{n}{names}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{default\PYGZus{}realm}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)} \PYG{o}{==} \PYG{l+m+mi}{0}\PYG{p}{)} \PYG{p}{\PYGZob{}}
        \PYG{o}{*}\PYG{n}{values} \PYG{o}{=} \PYG{n}{malloc}\PYG{p}{(}\PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{sizeof}\PYG{p}{(}\PYG{n}{char} \PYG{o}{*}\PYG{p}{)}\PYG{p}{)}\PYG{p}{;}
        \PYG{p}{(}\PYG{o}{*}\PYG{n}{values}\PYG{p}{)}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]} \PYG{o}{=} \PYG{n}{strdup}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{ATHENA.MIT.EDU}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{;}
        \PYG{p}{(}\PYG{o}{*}\PYG{n}{values}\PYG{p}{)}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]} \PYG{o}{=} \PYG{n}{NULL}\PYG{p}{;}
        \PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;}
    \PYG{p}{\PYGZcb{}}
    \PYG{k}{return} \PYG{n}{PROF\PYGZus{}NO\PYGZus{}RELATION}\PYG{p}{;}
\PYG{p}{\PYGZcb{}}

\PYG{n}{static} \PYG{n}{void}
\PYG{n}{free\PYGZus{}values}\PYG{p}{(}\PYG{n}{void} \PYG{o}{*}\PYG{n}{cbdata}\PYG{p}{,} \PYG{n}{char} \PYG{o}{*}\PYG{o}{*}\PYG{n}{values}\PYG{p}{)}
\PYG{p}{\PYGZob{}}
    \PYG{n}{char} \PYG{o}{*}\PYG{o}{*}\PYG{n}{v}\PYG{p}{;}

    \PYG{k}{for} \PYG{p}{(}\PYG{n}{v} \PYG{o}{=} \PYG{n}{values}\PYG{p}{;} \PYG{o}{*}\PYG{n}{v}\PYG{p}{;} \PYG{n}{v}\PYG{o}{+}\PYG{o}{+}\PYG{p}{)}
        \PYG{n}{free}\PYG{p}{(}\PYG{o}{*}\PYG{n}{v}\PYG{p}{)}\PYG{p}{;}
    \PYG{n}{free}\PYG{p}{(}\PYG{n}{values}\PYG{p}{)}\PYG{p}{;}
\PYG{p}{\PYGZcb{}}

\PYG{n}{long}
\PYG{n}{profile\PYGZus{}module\PYGZus{}init}\PYG{p}{(}\PYG{n}{const} \PYG{n}{char} \PYG{o}{*}\PYG{n}{residual}\PYG{p}{,} \PYG{n}{struct} \PYG{n}{profile\PYGZus{}vtable} \PYG{o}{*}\PYG{n}{vtable}\PYG{p}{,}
                    \PYG{n}{void} \PYG{o}{*}\PYG{o}{*}\PYG{n}{cb\PYGZus{}ret}\PYG{p}{)}\PYG{p}{;}

\PYG{n}{long}
\PYG{n}{profile\PYGZus{}module\PYGZus{}init}\PYG{p}{(}\PYG{n}{const} \PYG{n}{char} \PYG{o}{*}\PYG{n}{residual}\PYG{p}{,} \PYG{n}{struct} \PYG{n}{profile\PYGZus{}vtable} \PYG{o}{*}\PYG{n}{vtable}\PYG{p}{,}
                    \PYG{n}{void} \PYG{o}{*}\PYG{o}{*}\PYG{n}{cb\PYGZus{}ret}\PYG{p}{)}
\PYG{p}{\PYGZob{}}
    \PYG{o}{*}\PYG{n}{cb\PYGZus{}ret} \PYG{o}{=} \PYG{n}{NULL}\PYG{p}{;}
    \PYG{n}{vtable}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{get\PYGZus{}values} \PYG{o}{=} \PYG{n}{get\PYGZus{}values}\PYG{p}{;}
    \PYG{n}{vtable}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{free\PYGZus{}values} \PYG{o}{=} \PYG{n}{free\PYGZus{}values}\PYG{p}{;}
    \PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}

\sphinxstepscope


\section{GSSAPI mechanism interface}
\label{\detokenize{plugindev/gssapi:gssapi-mechanism-interface}}\label{\detokenize{plugindev/gssapi::doc}}
\sphinxAtStartPar
The GSSAPI library in MIT krb5 can load mechanism modules to augment
the set of built\sphinxhyphen{}in mechanisms.

\sphinxAtStartPar
A mechanism module is a Unix shared object or Windows DLL, built
separately from the krb5 tree.  Modules are loaded according to the
GSS mechanism config files described in \DUrole{xref,std,std-ref}{gssapi\_plugin\_config}.

\sphinxAtStartPar
For the most part, a GSSAPI mechanism module exports the same
functions as would a GSSAPI implementation itself, with the same
function signatures.  The mechanism selection layer within the GSSAPI
library (called the “mechglue”) will dispatch calls from the
application to the module if the module’s mechanism is requested.  If
a module does not wish to implement a GSSAPI extension, it can simply
refrain from exporting it, and the mechglue will fail gracefully if
the application calls that function.

\sphinxAtStartPar
The mechglue does not invoke a module’s \sphinxstylestrong{gss\_add\_cred},
\sphinxstylestrong{gss\_add\_cred\_from}, \sphinxstylestrong{gss\_add\_cred\_impersonate\_name}, or
\sphinxstylestrong{gss\_add\_cred\_with\_password} function.  A mechanism only needs to
implement the “acquire” variants of those functions.

\sphinxAtStartPar
A module does not need to coordinate its minor status codes with those
of other mechanisms.  If the mechglue detects conflicts, it will map
the mechanism’s status codes onto unique values, and then map them
back again when \sphinxstylestrong{gss\_display\_status} is called.


\subsection{NegoEx modules}
\label{\detokenize{plugindev/gssapi:negoex-modules}}
\sphinxAtStartPar
Some Windows GSSAPI mechanisms can only be negotiated via a Microsoft
extension to SPNEGO called NegoEx.  Beginning with release 1.18,
mechanism modules can support NegoEx as follows:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Implement the gssspi\_query\_meta\_data(), gssspi\_exchange\_meta\_data(),
and gssspi\_query\_mechanism\_info() SPIs declared in
\sphinxcode{\sphinxupquote{\textless{}gssapi/gssapi\_ext.h\textgreater{}}}.

\item {} 
\sphinxAtStartPar
Implement gss\_inquire\_sec\_context\_by\_oid() and answer the
\sphinxstylestrong{GSS\_C\_INQ\_NEGOEX\_KEY} and \sphinxstylestrong{GSS\_C\_INQ\_NEGOEX\_VERIFY\_KEY} OIDs
to provide the checksum keys for outgoing and incoming checksums,
respectively.  The answer must be in two buffers: the first buffer
contains the key contents, and the second buffer contains the key
encryption type as a four\sphinxhyphen{}byte little\sphinxhyphen{}endian integer.

\end{itemize}

\sphinxAtStartPar
By default, NegoEx mechanisms will not be directly negotiated via
SPNEGO.  If direct SPNEGO negotiation is required for
interoperability, implement gss\_inquire\_attrs\_for\_mech() and assert
the GSS\_C\_MA\_NEGOEX\_AND\_SPNEGO attribute (along with any applicable
RFC 5587 attributes).


\subsection{Interposer modules}
\label{\detokenize{plugindev/gssapi:interposer-modules}}
\sphinxAtStartPar
The mechglue also supports a kind of loadable module, called an
interposer module, which intercepts calls to existing mechanisms
rather than implementing a new mechanism.

\sphinxAtStartPar
An interposer module must export the symbol \sphinxstylestrong{gss\_mech\_interposer}
with the following signature:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{gss\PYGZus{}OID\PYGZus{}set} \PYG{n}{gss\PYGZus{}mech\PYGZus{}interposer}\PYG{p}{(}\PYG{n}{gss\PYGZus{}OID} \PYG{n}{mech\PYGZus{}type}\PYG{p}{)}\PYG{p}{;}
\end{sphinxVerbatim}

\sphinxAtStartPar
This function is invoked with the OID of the interposer mechanism as
specified in the mechanism config file, and returns a set of mechanism
OIDs to be interposed.  The returned OID set must have been created
using the mechglue’s gss\_create\_empty\_oid\_set and
gss\_add\_oid\_set\_member functions.

\sphinxAtStartPar
An interposer module must use the prefix \sphinxcode{\sphinxupquote{gssi\_}} for the GSSAPI
functions it exports, instead of the prefix \sphinxcode{\sphinxupquote{gss\_}}.  In most cases,
unexported \sphinxcode{\sphinxupquote{gssi\_}} functions will result in failure from their
corresponding \sphinxcode{\sphinxupquote{gss\_}} calls.

\sphinxAtStartPar
An interposer module can link against the GSSAPI library in order to
make calls to the original mechanism.  To do so, it must specify a
special mechanism OID which is the concatention of the interposer’s
own OID byte string and the original mechanism’s OID byte string.

\sphinxAtStartPar
Functions that do not accept a mechanism argument directly require no
special handling, with the following exceptions:

\sphinxAtStartPar
Since \sphinxstylestrong{gss\_accept\_sec\_context} does not accept a mechanism argument,
an interposer mechanism must, in order to invoke the original
mechanism’s function, acquire a credential for the concatenated OID
and pass that as the \sphinxstyleemphasis{verifier\_cred\_handle} parameter.

\sphinxAtStartPar
Since \sphinxstylestrong{gss\_import\_name}, \sphinxstylestrong{gss\_import\_cred}, and
\sphinxstylestrong{gss\_import\_sec\_context} do not accept mechanism parameters, the SPI
has been extended to include variants which do.  This allows the
interposer module to know which mechanism should be used to interpret
the token.  These functions have the following signatures:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gssi\PYGZus{}import\PYGZus{}sec\PYGZus{}context\PYGZus{}by\PYGZus{}mech}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,}
    \PYG{n}{gss\PYGZus{}OID} \PYG{n}{desired\PYGZus{}mech}\PYG{p}{,} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}t} \PYG{n}{interprocess\PYGZus{}token}\PYG{p}{,}
    \PYG{n}{gss\PYGZus{}ctx\PYGZus{}id\PYGZus{}t} \PYG{o}{*}\PYG{n}{context\PYGZus{}handle}\PYG{p}{)}\PYG{p}{;}

\PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gssi\PYGZus{}import\PYGZus{}name\PYGZus{}by\PYGZus{}mech}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,}
    \PYG{n}{gss\PYGZus{}OID} \PYG{n}{mech\PYGZus{}type}\PYG{p}{,} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}t} \PYG{n}{input\PYGZus{}name\PYGZus{}buffer}\PYG{p}{,}
    \PYG{n}{gss\PYGZus{}OID} \PYG{n}{input\PYGZus{}name\PYGZus{}type}\PYG{p}{,} \PYG{n}{gss\PYGZus{}name\PYGZus{}t} \PYG{n}{output\PYGZus{}name}\PYG{p}{)}\PYG{p}{;}

\PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gssi\PYGZus{}import\PYGZus{}cred\PYGZus{}by\PYGZus{}mech}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,}
    \PYG{n}{gss\PYGZus{}OID} \PYG{n}{mech\PYGZus{}type}\PYG{p}{,} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}t} \PYG{n}{token}\PYG{p}{,}
    \PYG{n}{gss\PYGZus{}cred\PYGZus{}id\PYGZus{}t} \PYG{o}{*}\PYG{n}{cred\PYGZus{}handle}\PYG{p}{)}\PYG{p}{;}
\end{sphinxVerbatim}

\sphinxAtStartPar
To re\sphinxhyphen{}enter the original mechanism when importing tokens for the above
functions, the interposer module must wrap the mechanism token in the
mechglue’s format, using the concatenated OID (except in
\sphinxstylestrong{gss\_import\_name}).  The mechglue token formats are:
\begin{itemize}
\item {} 
\sphinxAtStartPar
For \sphinxstylestrong{gss\_import\_sec\_context}, a four\sphinxhyphen{}byte OID length in big\sphinxhyphen{}endian
order, followed by the concatenated OID, followed by the mechanism
token.

\item {} 
\sphinxAtStartPar
For \sphinxstylestrong{gss\_import\_name}, the bytes 04 01, followed by a two\sphinxhyphen{}byte OID
length in big\sphinxhyphen{}endian order, followed by the mechanism OID, followed
by a four\sphinxhyphen{}byte token length in big\sphinxhyphen{}endian order, followed by the
mechanism token.  Unlike most uses of OIDs in the API, the mechanism
OID encoding must include the DER tag and length for an object
identifier (06 followed by the DER length of the OID byte string),
and this prefix must be included in the two\sphinxhyphen{}byte OID length.
input\_name\_type must also be set to GSS\_C\_NT\_EXPORT\_NAME.

\item {} 
\sphinxAtStartPar
For \sphinxstylestrong{gss\_import\_cred}, a four\sphinxhyphen{}byte OID length in big\sphinxhyphen{}endian order,
followed by the concatenated OID, followed by a four\sphinxhyphen{}byte token
length in big\sphinxhyphen{}endian order, followed by the mechanism token.  This
sequence may be repeated multiple times.

\end{itemize}

\sphinxstepscope


\section{Internal pluggable interfaces}
\label{\detokenize{plugindev/internal:internal-pluggable-interfaces}}\label{\detokenize{plugindev/internal::doc}}
\sphinxAtStartPar
Following are brief discussions of pluggable interfaces which have not
yet been made public.  These interfaces are functional, but the
interfaces are likely to change in incompatible ways from release to
release.  In some cases, it may be necessary to copy header files from
the krb5 source tree to use an internal interface.  Use these with
care, and expect to need to update your modules for each new release
of MIT krb5.


\subsection{Kerberos database interface (KDB)}
\label{\detokenize{plugindev/internal:kerberos-database-interface-kdb}}
\sphinxAtStartPar
A KDB module implements a database back end for KDC principal and
policy information, and can also control many aspects of KDC behavior.
For a full description of the interface, see the header file
\sphinxcode{\sphinxupquote{\textless{}kdb.h\textgreater{}}}.

\sphinxAtStartPar
The KDB pluggable interface is often referred to as the DAL (Database
Access Layer).


\subsection{Authorization data interface (authdata)}
\label{\detokenize{plugindev/internal:authorization-data-interface-authdata}}
\sphinxAtStartPar
The authdata interface allows a module to provide (from the KDC) or
consume (in application servers) authorization data of types beyond
those handled by the core MIT krb5 code base.  The interface is
defined in the header file \sphinxcode{\sphinxupquote{\textless{}krb5/authdata\_plugin.h\textgreater{}}}, which is not
installed by the build.

\sphinxstepscope


\section{PKINIT certificate authorization interface (certauth)}
\label{\detokenize{plugindev/certauth:pkinit-certificate-authorization-interface-certauth}}\label{\detokenize{plugindev/certauth:certauth-plugin}}\label{\detokenize{plugindev/certauth::doc}}
\sphinxAtStartPar
The certauth interface was first introduced in release 1.16.  It
allows customization of the X.509 certificate attribute requirements
placed on certificates used by PKINIT enabled clients.  For a detailed
description of the certauth interface, see the header file
\sphinxcode{\sphinxupquote{\textless{}krb5/certauth\_plugin.h\textgreater{}}}

\sphinxAtStartPar
A certauth module implements the \sphinxstylestrong{authorize} method to determine
whether a client’s certificate is authorized to authenticate a client
principal.  \sphinxstylestrong{authorize} receives the DER\sphinxhyphen{}encoded certificate, the
requested client principal, and a pointer to the client’s
krb5\_db\_entry (for modules that link against libkdb5).  The method
must decode the certificate and inspect its attributes to determine if
it should authorize PKINIT authentication.  It returns the
authorization status and optionally outputs a list of authentication
indicator strings to be added to the ticket.

\sphinxAtStartPar
Beginning in release 1.19, the authorize method can request that the
hardware authentication bit be set in the ticket by returning
\sphinxstylestrong{KRB5\_CERTAUTH\_HWAUTH}.  Beginning in release 1.20, the authorize
method can return \sphinxstylestrong{KRB5\_CERTAUTH\_HWAUTH\_PASS} to request that the
hardware authentication bit be set in the ticket but otherwise defer
authorization to another certauth module.  A module must use its own
internal or library\sphinxhyphen{}provided ASN.1 certificate decoder.

\sphinxAtStartPar
A module can optionally create and destroy module data with the
\sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  Module data objects last for the
lifetime of the KDC process.

\sphinxAtStartPar
If a module allocates and returns a list of authentication indicators
from \sphinxstylestrong{authorize}, it must also implement the \sphinxstylestrong{free\_ind} method
to free the list.

\sphinxstepscope


\section{KDC policy interface (kdcpolicy)}
\label{\detokenize{plugindev/kdcpolicy:kdc-policy-interface-kdcpolicy}}\label{\detokenize{plugindev/kdcpolicy:kdcpolicy-plugin}}\label{\detokenize{plugindev/kdcpolicy::doc}}
\sphinxAtStartPar
The kdcpolicy interface was first introduced in release 1.16.  It
allows modules to veto otherwise valid AS and TGS requests or restrict
the lifetime and renew time of the resulting ticket.  For a detailed
description of the kdcpolicy interface, see the header file
\sphinxcode{\sphinxupquote{\textless{}krb5/kdcpolicy\_plugin.h\textgreater{}}}.

\sphinxAtStartPar
The optional \sphinxstylestrong{check\_as} and \sphinxstylestrong{check\_tgs} functions allow the module
to perform access control.  Additionally, a module can create and
destroy module data with the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  Module
data objects last for the lifetime of the KDC process, and are
provided to all other methods.  The data has the type
krb5\_kdcpolicy\_moddata, which should be cast to the appropriate
internal type.

\sphinxAtStartPar
kdcpolicy modules can optionally inspect principal entries.  To do
this, the module must also include \sphinxcode{\sphinxupquote{\textless{}kdb.h\textgreater{}}} to gain access to the
principal entry structure definition.  As the KDB interface is
explicitly not as stable as other public interfaces, modules which do
this may not retain compatibility across releases.



\renewcommand{\indexname}{Index}
\printindex
\end{document}