% Generated by Sphinx.
\def\sphinxdocclass{report}
\documentclass[letterpaper,10pt,english]{sphinxmanual}
\usepackage[utf8]{inputenc}
\DeclareUnicodeCharacter{00A0}{\nobreakspace}
\usepackage{cmap}
\usepackage[T1]{fontenc}
\usepackage{babel}
\usepackage{times}
\usepackage[Bjarne]{fncychap}
\usepackage{longtable}
\usepackage{sphinx}
\usepackage{multirow}


\title{Kerberos Plugin Module Developer Guide}
\date{ }
\release{1.12.2}
\author{MIT}
\newcommand{\sphinxlogo}{}
\renewcommand{\releasename}{Release}
\makeindex

\makeatletter
\def\PYG@reset{\let\PYG@it=\relax \let\PYG@bf=\relax%
    \let\PYG@ul=\relax \let\PYG@tc=\relax%
    \let\PYG@bc=\relax \let\PYG@ff=\relax}
\def\PYG@tok#1{\csname PYG@tok@#1\endcsname}
\def\PYG@toks#1+{\ifx\relax#1\empty\else%
    \PYG@tok{#1}\expandafter\PYG@toks\fi}
\def\PYG@do#1{\PYG@bc{\PYG@tc{\PYG@ul{%
    \PYG@it{\PYG@bf{\PYG@ff{#1}}}}}}}
\def\PYG#1#2{\PYG@reset\PYG@toks#1+\relax+\PYG@do{#2}}

\expandafter\def\csname PYG@tok@gd\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}}
\expandafter\def\csname PYG@tok@gu\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}}
\expandafter\def\csname PYG@tok@gt\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}}
\expandafter\def\csname PYG@tok@gs\endcsname{\let\PYG@bf=\textbf}
\expandafter\def\csname PYG@tok@gr\endcsname{\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}}
\expandafter\def\csname PYG@tok@cm\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}}
\expandafter\def\csname PYG@tok@vg\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\expandafter\def\csname PYG@tok@m\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@mh\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@cs\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
\expandafter\def\csname PYG@tok@ge\endcsname{\let\PYG@it=\textit}
\expandafter\def\csname PYG@tok@vc\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\expandafter\def\csname PYG@tok@il\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@go\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.20,0.20,0.20}{##1}}}
\expandafter\def\csname PYG@tok@cp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@gi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}}
\expandafter\def\csname PYG@tok@gh\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
\expandafter\def\csname PYG@tok@ni\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.84,0.33,0.22}{##1}}}
\expandafter\def\csname PYG@tok@nl\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.13,0.44}{##1}}}
\expandafter\def\csname PYG@tok@nn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}}
\expandafter\def\csname PYG@tok@no\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.38,0.68,0.84}{##1}}}
\expandafter\def\csname PYG@tok@na\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@nb\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@nc\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}}
\expandafter\def\csname PYG@tok@nd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.33,0.33,0.33}{##1}}}
\expandafter\def\csname PYG@tok@ne\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@nf\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.02,0.16,0.49}{##1}}}
\expandafter\def\csname PYG@tok@si\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.44,0.63,0.82}{##1}}}
\expandafter\def\csname PYG@tok@s2\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@vi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\expandafter\def\csname PYG@tok@nt\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.02,0.16,0.45}{##1}}}
\expandafter\def\csname PYG@tok@nv\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\expandafter\def\csname PYG@tok@s1\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@gp\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}}
\expandafter\def\csname PYG@tok@sh\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@ow\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@sx\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}}
\expandafter\def\csname PYG@tok@bp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@c1\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}}
\expandafter\def\csname PYG@tok@kc\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@c\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}}
\expandafter\def\csname PYG@tok@mf\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@err\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{\strut ##1}}}
\expandafter\def\csname PYG@tok@kd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@ss\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.32,0.47,0.09}{##1}}}
\expandafter\def\csname PYG@tok@sr\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.14,0.33,0.53}{##1}}}
\expandafter\def\csname PYG@tok@mo\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@mi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@kn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@o\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PYG@tok@kr\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@s\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@kp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@w\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}}
\expandafter\def\csname PYG@tok@kt\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.56,0.13,0.00}{##1}}}
\expandafter\def\csname PYG@tok@sc\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@sb\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@k\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@se\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@sd\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}

\def\PYGZbs{\char`\\}
\def\PYGZus{\char`\_}
\def\PYGZob{\char`\{}
\def\PYGZcb{\char`\}}
\def\PYGZca{\char`\^}
\def\PYGZam{\char`\&}
\def\PYGZlt{\char`\<}
\def\PYGZgt{\char`\>}
\def\PYGZsh{\char`\#}
\def\PYGZpc{\char`\%}
\def\PYGZdl{\char`\$}
\def\PYGZhy{\char`\-}
\def\PYGZsq{\char`\'}
\def\PYGZdq{\char`\"}
\def\PYGZti{\char`\~}
% for compatibility with earlier versions
\def\PYGZat{@}
\def\PYGZlb{[}
\def\PYGZrb{]}
\makeatother

\begin{document}

\maketitle
\tableofcontents
\phantomsection\label{plugindev/index::doc}


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.

See \emph{plugin\_config} for information on how to register dynamic
plugin modules and how to enable and disable modules via
\emph{krb5.conf(5)}.


\chapter{Contents}
\label{plugindev/index:for-plugin-module-developers}\label{plugindev/index:contents}

\section{General plugin concepts}
\label{plugindev/general:general-plugin-concepts}\label{plugindev/general::doc}
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 \href{http://www.gnu.org/software/automake/}{automake} and \href{http://www.gnu.org/software/libtool/}{libtool}, or
tools with similar functionality.

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
\code{INTERFACE\_MODULE\_initvt}, where \emph{INTERFACE} is the name of the
pluggable interface and \emph{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 \code{kdcpreauth\_mymech\_initvt} and \code{clpreauth\_mymech\_initvt}.

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

initvt functions have the following prototype:

\begin{Verbatim}[commandchars=\\\{\}]
krb5\PYGZus{}error\PYGZus{}code interface\PYGZus{}modname\PYGZus{}initvt(krb5\PYGZus{}context context,
                                         int maj\PYGZus{}ver, int min\PYGZus{}ver,
                                         krb5\PYGZus{}plugin\PYGZus{}vtable vtable);
\end{Verbatim}

and should do the following:
\begin{enumerate}
\item {} 
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 {} 
Cast the supplied vtable pointer to the structure type
corresponding to the major version, as documented in the pluggable
interface header file.

\item {} 
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}

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.

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

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{Verbatim}[commandchars=\\\{\}]
krb5\PYGZus{}error\PYGZus{}code
fences\PYGZus{}wicker\PYGZus{}initvt(krb5\PYGZus{}context context, int maj\PYGZus{}ver,
                     int min\PYGZus{}ver, krb5\PYGZus{}plugin\PYGZus{}vtable vtable)
\PYGZob{}
    krb5\PYGZus{}ccselect\PYGZus{}vtable vt;

    if (maj\PYGZus{}ver == 1) \PYGZob{}
        krb5\PYGZus{}fences\PYGZus{}vtable vt = (krb5\PYGZus{}fences\PYGZus{}vtable)vtable;
        vt\PYGZhy{}\PYGZgt{}name = \PYGZdq{}wicker\PYGZdq{};
        vt\PYGZhy{}\PYGZgt{}slats = wicker\PYGZus{}slats;
        vt\PYGZhy{}\PYGZgt{}braces = wicker\PYGZus{}braces;
    \PYGZcb{} else if (maj\PYGZus{}ver == 2) \PYGZob{}
        krb5\PYGZus{}fences\PYGZus{}vtable\PYGZus{}v2 vt = (krb5\PYGZus{}fences\PYGZus{}vtable\PYGZus{}v2)vtable;
        vt\PYGZhy{}\PYGZgt{}name = \PYGZdq{}wicker\PYGZdq{};
        vt\PYGZhy{}\PYGZgt{}material = wicker\PYGZus{}material;
        vt\PYGZhy{}\PYGZgt{}construction = wicker\PYGZus{}construction;
        if (min\PYGZus{}ver \PYGZlt{} 2)
            return 0;
        vt\PYGZhy{}\PYGZgt{}footing = wicker\PYGZus{}footing;
        if (min\PYGZus{}ver \PYGZlt{} 3)
            return 0;
        vt\PYGZhy{}\PYGZgt{}appearance = wicker\PYGZus{}appearance;
    \PYGZcb{} else \PYGZob{}
        return KRB5\PYGZus{}PLUGIN\PYGZus{}VER\PYGZus{}NOTSUPP;
    \PYGZcb{}
    return 0;
\PYGZcb{}
\end{Verbatim}


\section{Client preauthentication interface (clpreauth)}
\label{plugindev/clpreauth:client-preauthentication-interface-clpreauth}\label{plugindev/clpreauth::doc}
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!RFC 4120}\href{http://tools.ietf.org/html/rfc4120.html}{\textbf{RFC 4120}} and \index{RFC!RFC 6113}\href{http://tools.ietf.org/html/rfc6113.html}{\textbf{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 \code{\textless{}krb5/clpreauth\_plugin.h\textgreater{}} (or
\code{\textless{}krb5/preauth\_plugin.h\textgreater{}} before release 1.12).

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

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

\item {} 
Examining the padata information included in the preauth\_required
error and producing padata values for the next AS request.  This is
done with the \textbf{process} method.

\item {} 
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 \textbf{process} method.

\item {} 
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 \textbf{tryagain}
method.

\item {} 
Receiving option information (supplied by \code{kinit -X} or by an
application), with the \textbf{gic\_opts} method.

\end{itemize}

A clpreauth module can create and destroy per-library-context and
per-request state objects by implementing the \textbf{init}, \textbf{fini},
\textbf{request\_init}, and \textbf{request\_fini} methods.  Per-context state
objects have the type krb5\_clpreauth\_moddata, and per-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.

The \textbf{process} and \textbf{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-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.


\section{KDC preauthentication interface (kdcpreauth)}
\label{plugindev/kdcpreauth:kdc-preauthentication-interface-kdcpreauth}\label{plugindev/kdcpreauth::doc}
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 \code{\textless{}krb5/kdcpreauth\_plugin.h\textgreater{}} (or
\code{\textless{}krb5/preauth\_plugin.h\textgreater{}} before release 1.12).

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

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

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

\item {} 
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 \textbf{verify} method.

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

\end{itemize}

A module can create and destroy per-KDC state objects by implementing
the \textbf{init} and \textbf{fini} methods.  Per-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.

A module can create a per-request state object by returning one in the
\textbf{verify} method, receiving it in the \textbf{return\_padata} method, and
destroying it in the \textbf{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-request state objects have the type
krb5\_kdcpreauth\_modreq, which is an abstract pointer type.

The \textbf{edata}, \textbf{verify}, and \textbf{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-term keys, the
DER-encoded request body, the FAST armor key, string attributes on the
client's database entry, and the client's database entry itself.

The \textbf{edata} and \textbf{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 \href{https://fedorahosted.org/libverto/}{libverto} API.


\section{Credential cache selection interface (ccselect)}
\label{plugindev/ccselect:credential-cache-selection-interface-ccselect}\label{plugindev/ccselect::doc}\label{plugindev/ccselect:ccselect-plugin}
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
\code{\textless{}krb5/ccselect\_plugin.h\textgreater{}}.

The primary ccselect method is \textbf{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.

A module can create and destroy per-library-context state objects by
implementing the \textbf{init} and \textbf{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.

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 \textbf{init} method.


\section{Password quality interface (pwqual)}
\label{plugindev/pwqual::doc}\label{plugindev/pwqual:password-quality-interface-pwqual}\label{plugindev/pwqual:pwqual-plugin}
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 \code{\textless{}krb5/pwqual\_plugin.h\textgreater{}}.

The primary pwqual method is \textbf{check}, which receives a password as
input and returns success (0) or a \code{KADM5\_PASS\_Q\_} failure code
depending on whether the password is allowed.  The \textbf{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.

A module can create and destroy per-process state objects by
implementing the \textbf{open} and \textbf{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 \textbf{open} method also receives the name of the realm's
dictionary file (as configured by the \textbf{dict\_file} variable in the
\emph{kdc\_realms} section of \emph{kdc.conf(5)}) if it wishes to use
it.


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

The kadm5\_hook interface has four primary methods: \textbf{chpass},
\textbf{create}, \textbf{modify}, and \textbf{remove}.  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-commit stage.

A module can create and destroy per-process state objects by
implementing the \textbf{init} and \textbf{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.

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.


\section{Host-to-realm interface (hostrealm)}
\label{plugindev/hostrealm:hostrealm-plugin}\label{plugindev/hostrealm::doc}\label{plugindev/hostrealm:host-to-realm-interface-hostrealm}
The host-to-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
\code{\textless{}krb5/hostrealm\_plugin.h\textgreater{}}.

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.

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

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

The optional \textbf{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.

The optional \textbf{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 succesful result.

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

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


\section{Local authorization interface (localauth)}
\label{plugindev/localauth:local-authorization-interface-localauth}\label{plugindev/localauth:localauth-plugin}\label{plugindev/localauth::doc}
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
\code{krb5\_kuserok()} or \code{krb5\_aname\_to\_localname()}, localauth
modules are consulted to determine the result.  For a detailed
description of the localauth interface, see the header file
\code{\textless{}krb5/localauth\_plugin.h\textgreater{}}.

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

The optional \textbf{userok} method allows a module to control the behavior
of \code{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.

The optional \textbf{an2ln} method can work in two different ways.  If the
module sets an array of uppercase type names in \textbf{an2ln\_types}, then
the module's \textbf{an2ln} method will only be invoked by
\code{krb5\_aname\_to\_localname()} if an \textbf{auth\_to\_local} value in
\emph{krb5.conf(5)} refers to one of the module's types.  In this
case, the \emph{type} and \emph{residual} arguments will give the type name and
residual string of the \textbf{auth\_to\_local} value.

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

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


\section{Server location interface (locate)}
\label{plugindev/locate:server-location-interface-locate}\label{plugindev/locate::doc}
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 \code{\textless{}krb5/locate\_plugin.h\textgreater{}}.

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

The primary locate method is \textbf{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 \textbf{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.

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


\section{Configuration interface (profile)}
\label{plugindev/profile:configuration-interface-profile}\label{plugindev/profile::doc}\label{plugindev/profile:profile-plugin}
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 \code{\textless{}profile.h\textgreater{}}.

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

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 \code{module} directive at the beginning of krb5.conf, as
described in \emph{profile\_plugin\_config}.

A profile module exports a function named \code{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-profile state object.  If the module uses state objects,
it should implement the \textbf{copy} and \textbf{cleanup} methods to manage
them.

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

Iterable profile modules must also define the \textbf{iterator\_create},
\textbf{iterator}, \textbf{iterator\_free}, and \textbf{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.

Writable profile modules must also define the \textbf{writable},
\textbf{modified}, \textbf{update\_relation}, \textbf{rename\_section},
\textbf{add\_relation}, and \textbf{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.

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

\begin{Verbatim}[commandchars=\\\{\}]
\PYGZsh{}include \PYGZlt{}stdlib.h\PYGZgt{}
\PYGZsh{}include \PYGZlt{}string.h\PYGZgt{}
\PYGZsh{}include \PYGZlt{}profile.h\PYGZgt{}

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

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

    for (v = values; *v; v++)
        free(*v);
    free(values);
\PYGZcb{}

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

long
profile\PYGZus{}module\PYGZus{}init(const char *residual, struct profile\PYGZus{}vtable *vtable,
                    void **cb\PYGZus{}ret)
\PYGZob{}
    *cb\PYGZus{}ret = NULL;
    vtable\PYGZhy{}\PYGZgt{}get\PYGZus{}values = get\PYGZus{}values;
    vtable\PYGZhy{}\PYGZgt{}free\PYGZus{}values = free\PYGZus{}values;
    return 0;
\PYGZcb{}
\end{Verbatim}


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

A mechanism module is a Unix shared object or Windows DLL, built
separately from the krb5 tree.  Modules are loaded according to the
\code{/etc/gss/mech} config file, as described in
\emph{gssapi\_plugin\_config}.

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.

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

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 \textbf{gss\_display\_status} is called.


\subsection{Interposer modules}
\label{plugindev/gssapi:interposer-modules}
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.

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

\begin{Verbatim}[commandchars=\\\{\}]
gss\PYGZus{}OID\PYGZus{}set gss\PYGZus{}mech\PYGZus{}interposer(gss\PYGZus{}OID mech\PYGZus{}type);
\end{Verbatim}

This function is invoked with the OID of the interposer mechanism as
specified in \code{/etc/gss/mech}, 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.

An interposer module must use the prefix \code{gssi\_} for the GSSAPI
functions it exports, instead of the prefix \code{gss\_}.

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.

Since \textbf{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 \emph{verifier\_cred\_handle} parameter.

Since \textbf{gss\_import\_name}, \textbf{gss\_import\_cred}, and
\textbf{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{Verbatim}[commandchars=\\\{\}]
OM\PYGZus{}uint32 gssi\PYGZus{}import\PYGZus{}sec\PYGZus{}context\PYGZus{}by\PYGZus{}mech(OM\PYGZus{}uint32 *minor\PYGZus{}status,
    gss\PYGZus{}OID desired\PYGZus{}mech, gss\PYGZus{}buffer\PYGZus{}t interprocess\PYGZus{}token,
    gss\PYGZus{}ctx\PYGZus{}id\PYGZus{}t *context\PYGZus{}handle);

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

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

To re-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.  The mechglue token
formats are:
\begin{itemize}
\item {} 
For \textbf{gss\_import\_sec\_context}, a four-byte OID length in big-endian
order, followed by the mechanism OID, followed by the mechanism
token.

\item {} 
For \textbf{gss\_import\_name}, the bytes 04 01, followed by a two-byte OID
length in big-endian order, followed by the mechanism OID, followed
by the bytes 06, followed by the OID length as a single byte,
followed by the mechanism OID, followed by the mechanism token.

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

\end{itemize}


\section{Internal pluggable interfaces}
\label{plugindev/internal::doc}\label{plugindev/internal:internal-pluggable-interfaces}
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{plugindev/internal:kerberos-database-interface-kdb}
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
\code{\textless{}kdb.h\textgreater{}}.

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


\subsection{Authorization data interface (authdata)}
\label{plugindev/internal:authorization-data-interface-authdata}
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 \code{\textless{}krb5/authdata\_plugin.h\textgreater{}}, which is not
installed by the build.



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