diff options
Diffstat (limited to 'doc/pdf/plugindev.tex')
| -rw-r--r-- | doc/pdf/plugindev.tex | 801 | 
1 files changed, 801 insertions, 0 deletions
diff --git a/doc/pdf/plugindev.tex b/doc/pdf/plugindev.tex new file mode 100644 index 0000000000000..4e3b805923ac8 --- /dev/null +++ b/doc/pdf/plugindev.tex @@ -0,0 +1,801 @@ +% 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.15.1} +\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 a PREAUTH\_REQUIRED or +MORE\_PREAUTH\_DATA\_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{verify} method can assert one or more authentication indicators to +be included in the issued ticket using the \code{add\_auth\_indicator} +callback (new in release 1.14). + +A module can generate state information to be included with the next +client request using the \code{set\_cookie} callback (new in release +1.14).  On the next request, the module can read this state +information using the \code{get\_cookie} callback.  Cookie information is +encrypted, timestamped, and transmitted to the client in a +\code{PA-FX-COOKIE} pa-data item.  Older clients may not support cookies +and therefore may not transmit the cookie in the next request; in this +case, \code{get\_cookie} will not yield the saved information. + +If a module implements a mechanism which requires multiple round +trips, its \textbf{verify} method can respond with the code +\code{KRB5KDC\_ERR\_MORE\_PREAUTH\_DATA\_REQUIRED} and a list of pa-data in +the \emph{e\_data} parameter to be processed by the client. + +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 five primary methods: \textbf{chpass}, +\textbf{create}, \textbf{modify}, \textbf{remove}, and \textbf{rename}.  (The \textbf{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-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 successful 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} or \code{/etc/gss/mech.d/*.conf} config files, 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} or in a \code{/etc/gss/mech.d/*.conf} +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. + +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}  | 
