xref: /freebsd/crypto/krb5/doc/pdf/plugindev.tex (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1%% Generated by Sphinx.
2\def\sphinxdocclass{report}
3\documentclass[letterpaper,10pt,english]{sphinxmanual}
4\ifdefined\pdfpxdimen
5   \let\sphinxpxdimen\pdfpxdimen\else\newdimen\sphinxpxdimen
6\fi \sphinxpxdimen=.75bp\relax
7\ifdefined\pdfimageresolution
8    \pdfimageresolution= \numexpr \dimexpr1in\relax/\sphinxpxdimen\relax
9\fi
10%% let collapsible pdf bookmarks panel have high depth per default
11\PassOptionsToPackage{bookmarksdepth=5}{hyperref}
12
13\PassOptionsToPackage{warn}{textcomp}
14\usepackage[utf8]{inputenc}
15\ifdefined\DeclareUnicodeCharacter
16% support both utf8 and utf8x syntaxes
17  \ifdefined\DeclareUnicodeCharacterAsOptional
18    \def\sphinxDUC#1{\DeclareUnicodeCharacter{"#1}}
19  \else
20    \let\sphinxDUC\DeclareUnicodeCharacter
21  \fi
22  \sphinxDUC{00A0}{\nobreakspace}
23  \sphinxDUC{2500}{\sphinxunichar{2500}}
24  \sphinxDUC{2502}{\sphinxunichar{2502}}
25  \sphinxDUC{2514}{\sphinxunichar{2514}}
26  \sphinxDUC{251C}{\sphinxunichar{251C}}
27  \sphinxDUC{2572}{\textbackslash}
28\fi
29\usepackage{cmap}
30\usepackage[T1]{fontenc}
31\usepackage{amsmath,amssymb,amstext}
32\usepackage{babel}
33
34
35
36\usepackage{tgtermes}
37\usepackage{tgheros}
38\renewcommand{\ttdefault}{txtt}
39
40
41
42\usepackage[Bjarne]{fncychap}
43\usepackage{sphinx}
44
45\fvset{fontsize=auto}
46\usepackage{geometry}
47
48
49% Include hyperref last.
50\usepackage{hyperref}
51% Fix anchor placement for figures with captions.
52\usepackage{hypcap}% it must be loaded after hyperref.
53% Set up styles of URL: it should be placed after hyperref.
54\urlstyle{same}
55
56
57\usepackage{sphinxmessages}
58\setcounter{tocdepth}{1}
59
60
61
62\title{Kerberos Plugin Module Developer Guide}
63\date{ }
64\release{1.21.3}
65\author{MIT}
66\newcommand{\sphinxlogo}{\vbox{}}
67\renewcommand{\releasename}{Release}
68\makeindex
69\begin{document}
70
71\pagestyle{empty}
72\sphinxmaketitle
73\pagestyle{plain}
74\sphinxtableofcontents
75\pagestyle{normal}
76\phantomsection\label{\detokenize{plugindev/index::doc}}
77
78
79\sphinxAtStartPar
80Kerberos plugin modules allow increased control over MIT krb5 library
81and server behavior.  This guide describes how to create dynamic
82plugin modules and the currently available pluggable interfaces.
83
84\sphinxAtStartPar
85See \DUrole{xref,std,std-ref}{plugin\_config} for information on how to register dynamic
86plugin modules and how to enable and disable modules via
87\DUrole{xref,std,std-ref}{krb5.conf(5)}.
88
89
90\chapter{Contents}
91\label{\detokenize{plugindev/index:contents}}
92
93\section{General plugin concepts}
94\label{\detokenize{plugindev/general:general-plugin-concepts}}\label{\detokenize{plugindev/general::doc}}
95\sphinxAtStartPar
96A krb5 dynamic plugin module is a Unix shared object or Windows DLL.
97Typically, the source code for a dynamic plugin module should live in
98its 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
99tools with similar functionality.
100
101\sphinxAtStartPar
102A plugin module must define a specific symbol name, which depends on
103the pluggable interface and module name.  For most pluggable
104interfaces, the exported symbol is a function named
105\sphinxcode{\sphinxupquote{INTERFACE\_MODULE\_initvt}}, where \sphinxstyleemphasis{INTERFACE} is the name of the
106pluggable interface and \sphinxstyleemphasis{MODULE} is the name of the module.  For these
107interfaces, it is possible for one shared object or DLL to implement
108multiple plugin modules, either for the same pluggable interface or
109for different ones.  For example, a shared object could implement both
110KDC and client preauthentication mechanisms, by exporting functions
111named \sphinxcode{\sphinxupquote{kdcpreauth\_mymech\_initvt}} and \sphinxcode{\sphinxupquote{clpreauth\_mymech\_initvt}}.
112
113\sphinxAtStartPar
114A plugin module implementation should include the header file
115\sphinxcode{\sphinxupquote{\textless{}krb5/INTERFACE\_plugin.h\textgreater{}}}, where \sphinxstyleemphasis{INTERFACE} is the name of the
116pluggable interface.  For instance, a ccselect plugin module
117implementation should use \sphinxcode{\sphinxupquote{\#include \textless{}krb5/ccselect\_plugin.h\textgreater{}}}.
118
119\sphinxAtStartPar
120initvt functions have the following prototype:
121
122\begin{sphinxVerbatim}[commandchars=\\\{\}]
123\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}{,}
124                                         \PYG{n+nb}{int} \PYG{n}{maj\PYGZus{}ver}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{min\PYGZus{}ver}\PYG{p}{,}
125                                         \PYG{n}{krb5\PYGZus{}plugin\PYGZus{}vtable} \PYG{n}{vtable}\PYG{p}{)}\PYG{p}{;}
126\end{sphinxVerbatim}
127
128\sphinxAtStartPar
129and should do the following:
130\begin{enumerate}
131\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
132\item {}
133\sphinxAtStartPar
134Check that the supplied maj\_ver argument is supported by the
135module.  If it is not supported, the function should return
136KRB5\_PLUGIN\_VER\_NOTSUPP.
137
138\item {}
139\sphinxAtStartPar
140Cast the supplied vtable pointer to the structure type
141corresponding to the major version, as documented in the pluggable
142interface header file.
143
144\item {}
145\sphinxAtStartPar
146Fill in the structure fields with pointers to method functions and
147static data, stopping at the field indicated by the supplied minor
148version.  Fields for unimplemented optional methods can be left
149alone; it is not necessary to initialize them to NULL.
150
151\end{enumerate}
152
153\sphinxAtStartPar
154In most cases, the context argument will not be used.  The initvt
155function should not allocate memory; think of it as a glorified
156structure initializer.  Each pluggable interface defines methods for
157allocating and freeing module state if doing so is necessary for the
158interface.
159
160\sphinxAtStartPar
161Pluggable interfaces typically include a \sphinxstylestrong{name} field in the vtable
162structure, which should be filled in with a pointer to a string
163literal containing the module name.
164
165\sphinxAtStartPar
166Here is an example of what an initvt function might look like for a
167fictional pluggable interface named fences, for a module named
168“wicker”:
169
170\begin{sphinxVerbatim}[commandchars=\\\{\}]
171\PYG{n}{krb5\PYGZus{}error\PYGZus{}code}
172\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}{,}
173                     \PYG{n+nb}{int} \PYG{n}{min\PYGZus{}ver}\PYG{p}{,} \PYG{n}{krb5\PYGZus{}plugin\PYGZus{}vtable} \PYG{n}{vtable}\PYG{p}{)}
174\PYG{p}{\PYGZob{}}
175    \PYG{n}{krb5\PYGZus{}ccselect\PYGZus{}vtable} \PYG{n}{vt}\PYG{p}{;}
176
177    \PYG{k}{if} \PYG{p}{(}\PYG{n}{maj\PYGZus{}ver} \PYG{o}{==} \PYG{l+m+mi}{1}\PYG{p}{)} \PYG{p}{\PYGZob{}}
178        \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}{;}
179        \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}{;}
180        \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{slats} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}slats}\PYG{p}{;}
181        \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{braces} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}braces}\PYG{p}{;}
182    \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{}}
183        \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}{;}
184        \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}{;}
185        \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{material} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}material}\PYG{p}{;}
186        \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{construction} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}construction}\PYG{p}{;}
187        \PYG{k}{if} \PYG{p}{(}\PYG{n}{min\PYGZus{}ver} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{2}\PYG{p}{)}
188            \PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;}
189        \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{footing} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}footing}\PYG{p}{;}
190        \PYG{k}{if} \PYG{p}{(}\PYG{n}{min\PYGZus{}ver} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{3}\PYG{p}{)}
191            \PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;}
192        \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{appearance} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}appearance}\PYG{p}{;}
193    \PYG{p}{\PYGZcb{}} \PYG{k}{else} \PYG{p}{\PYGZob{}}
194        \PYG{k}{return} \PYG{n}{KRB5\PYGZus{}PLUGIN\PYGZus{}VER\PYGZus{}NOTSUPP}\PYG{p}{;}
195    \PYG{p}{\PYGZcb{}}
196    \PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;}
197\PYG{p}{\PYGZcb{}}
198\end{sphinxVerbatim}
199
200
201\subsection{Logging from KDC and kadmind plugin modules}
202\label{\detokenize{plugindev/general:logging-from-kdc-and-kadmind-plugin-modules}}
203\sphinxAtStartPar
204Plugin modules for the KDC or kadmind daemons can write to the
205configured logging outputs (see \DUrole{xref,std,std-ref}{logging}) by calling the
206\sphinxstylestrong{com\_err} function.  The first argument (\sphinxstyleemphasis{whoami}) is ignored.  If
207the second argument (\sphinxstyleemphasis{code}) is zero, the formatted message is logged
208at informational severity; otherwise, the formatted message is logged
209at error severity and includes the error message for the supplied
210code.  Here are examples:
211
212\begin{sphinxVerbatim}[commandchars=\\\{\}]
213\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}{;}
214\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}{;}
215\end{sphinxVerbatim}
216
217\sphinxAtStartPar
218(The behavior described above is new in release 1.17.  In prior
219releases, the \sphinxstyleemphasis{whoami} argument is included for some logging output
220types, the logged message does not include the usual header for some
221output types, and the severity for syslog outputs is configured as
222part of the logging specification, defaulting to error severity.)
223
224
225\section{Client preauthentication interface (clpreauth)}
226\label{\detokenize{plugindev/clpreauth:client-preauthentication-interface-clpreauth}}\label{\detokenize{plugindev/clpreauth::doc}}
227\sphinxAtStartPar
228During an initial ticket request, a KDC may ask a client to prove its
229knowledge of the password before issuing an encrypted ticket, or to
230use credentials other than a password.  This process is called
231preauthentication, and is described in \index{RFC@\spxentry{RFC}!RFC 4120@\spxentry{RFC 4120}}\sphinxhref{https://tools.ietf.org/html/rfc4120.html}{\sphinxstylestrong{RFC 4120}} and \index{RFC@\spxentry{RFC}!RFC 6113@\spxentry{RFC 6113}}\sphinxhref{https://tools.ietf.org/html/rfc6113.html}{\sphinxstylestrong{RFC 6113}}.
232The clpreauth interface allows the addition of client support for
233preauthentication mechanisms beyond those included in the core MIT
234krb5 code base.  For a detailed description of the clpreauth
235interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/clpreauth\_plugin.h\textgreater{}}} (or
236\sphinxcode{\sphinxupquote{\textless{}krb5/preauth\_plugin.h\textgreater{}}} before release 1.12).
237
238\sphinxAtStartPar
239A clpreauth module is generally responsible for:
240\begin{itemize}
241\item {}
242\sphinxAtStartPar
243Supplying a list of preauth type numbers used by the module in the
244\sphinxstylestrong{pa\_type\_list} field of the vtable structure.
245
246\item {}
247\sphinxAtStartPar
248Indicating what kind of preauthentication mechanism it implements,
249with the \sphinxstylestrong{flags} method.  In the most common case, this method
250just returns \sphinxcode{\sphinxupquote{PA\_REAL}}, indicating that it implements a normal
251preauthentication type.
252
253\item {}
254\sphinxAtStartPar
255Examining the padata information included in a PREAUTH\_REQUIRED or
256MORE\_PREAUTH\_DATA\_REQUIRED error and producing padata values for the
257next AS request.  This is done with the \sphinxstylestrong{process} method.
258
259\item {}
260\sphinxAtStartPar
261Examining the padata information included in a successful ticket
262reply, possibly verifying the KDC identity and computing a reply
263key.  This is also done with the \sphinxstylestrong{process} method.
264
265\item {}
266\sphinxAtStartPar
267For preauthentication types which support it, recovering from errors
268by examining the error data from the KDC and producing a padata
269value for another AS request.  This is done with the \sphinxstylestrong{tryagain}
270method.
271
272\item {}
273\sphinxAtStartPar
274Receiving option information (supplied by \sphinxcode{\sphinxupquote{kinit \sphinxhyphen{}X}} or by an
275application), with the \sphinxstylestrong{gic\_opts} method.
276
277\end{itemize}
278
279\sphinxAtStartPar
280A clpreauth module can create and destroy per\sphinxhyphen{}library\sphinxhyphen{}context and
281per\sphinxhyphen{}request state objects by implementing the \sphinxstylestrong{init}, \sphinxstylestrong{fini},
282\sphinxstylestrong{request\_init}, and \sphinxstylestrong{request\_fini} methods.  Per\sphinxhyphen{}context state
283objects have the type krb5\_clpreauth\_moddata, and per\sphinxhyphen{}request state
284objects have the type krb5\_clpreauth\_modreq.  These are abstract
285pointer types; a module should typically cast these to internal
286types for the state objects.
287
288\sphinxAtStartPar
289The \sphinxstylestrong{process} and \sphinxstylestrong{tryagain} methods have access to a callback
290function and handle (called a “rock”) which can be used to get
291additional information about the current request, including the
292expected enctype of the AS reply, the FAST armor key, and the client
293long\sphinxhyphen{}term key (prompting for the user password if necessary).  A
294callback can also be used to replace the AS reply key if the
295preauthentication mechanism computes one.
296
297
298\section{KDC preauthentication interface (kdcpreauth)}
299\label{\detokenize{plugindev/kdcpreauth:kdc-preauthentication-interface-kdcpreauth}}\label{\detokenize{plugindev/kdcpreauth::doc}}
300\sphinxAtStartPar
301The kdcpreauth interface allows the addition of KDC support for
302preauthentication mechanisms beyond those included in the core MIT
303krb5 code base.  For a detailed description of the kdcpreauth
304interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/kdcpreauth\_plugin.h\textgreater{}}} (or
305\sphinxcode{\sphinxupquote{\textless{}krb5/preauth\_plugin.h\textgreater{}}} before release 1.12).
306
307\sphinxAtStartPar
308A kdcpreauth module is generally responsible for:
309\begin{itemize}
310\item {}
311\sphinxAtStartPar
312Supplying a list of preauth type numbers used by the module in the
313\sphinxstylestrong{pa\_type\_list} field of the vtable structure.
314
315\item {}
316\sphinxAtStartPar
317Indicating what kind of preauthentication mechanism it implements,
318with the \sphinxstylestrong{flags} method.  If the mechanism computes a new reply
319key, it must specify the \sphinxcode{\sphinxupquote{PA\_REPLACES\_KEY}} flag.  If the mechanism
320is generally only used with hardware tokens, the \sphinxcode{\sphinxupquote{PA\_HARDWARE}}
321flag allows the mechanism to work with principals which have the
322\sphinxstylestrong{requires\_hwauth} flag set.
323
324\item {}
325\sphinxAtStartPar
326Producing a padata value to be sent with a preauth\_required error,
327with the \sphinxstylestrong{edata} method.
328
329\item {}
330\sphinxAtStartPar
331Examining a padata value sent by a client and verifying that it
332proves knowledge of the appropriate client credential information.
333This is done with the \sphinxstylestrong{verify} method.
334
335\item {}
336\sphinxAtStartPar
337Producing a padata response value for the client, and possibly
338computing a reply key.  This is done with the \sphinxstylestrong{return\_padata}
339method.
340
341\end{itemize}
342
343\sphinxAtStartPar
344A module can create and destroy per\sphinxhyphen{}KDC state objects by implementing
345the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  Per\sphinxhyphen{}KDC state objects have the
346type krb5\_kdcpreauth\_moddata, which is an abstract pointer types.  A
347module should typically cast this to an internal type for the state
348object.
349
350\sphinxAtStartPar
351A module can create a per\sphinxhyphen{}request state object by returning one in the
352\sphinxstylestrong{verify} method, receiving it in the \sphinxstylestrong{return\_padata} method, and
353destroying it in the \sphinxstylestrong{free\_modreq} method.  Note that these state
354objects only apply to the processing of a single AS request packet,
355not to an entire authentication exchange (since an authentication
356exchange may remain unfinished by the client or may involve multiple
357different KDC hosts).  Per\sphinxhyphen{}request state objects have the type
358krb5\_kdcpreauth\_modreq, which is an abstract pointer type.
359
360\sphinxAtStartPar
361The \sphinxstylestrong{edata}, \sphinxstylestrong{verify}, and \sphinxstylestrong{return\_padata} methods have access
362to a callback function and handle (called a “rock”) which can be used
363to get additional information about the current request, including the
364maximum allowable clock skew, the client’s long\sphinxhyphen{}term keys, the
365DER\sphinxhyphen{}encoded request body, the FAST armor key, string attributes on the
366client’s database entry, and the client’s database entry itself.  The
367\sphinxstylestrong{verify} method can assert one or more authentication indicators to
368be included in the issued ticket using the \sphinxcode{\sphinxupquote{add\_auth\_indicator}}
369callback (new in release 1.14).
370
371\sphinxAtStartPar
372A module can generate state information to be included with the next
373client request using the \sphinxcode{\sphinxupquote{set\_cookie}} callback (new in release
3741.14).  On the next request, the module can read this state
375information using the \sphinxcode{\sphinxupquote{get\_cookie}} callback.  Cookie information is
376encrypted, timestamped, and transmitted to the client in a
377\sphinxcode{\sphinxupquote{PA\sphinxhyphen{}FX\sphinxhyphen{}COOKIE}} pa\sphinxhyphen{}data item.  Older clients may not support cookies
378and therefore may not transmit the cookie in the next request; in this
379case, \sphinxcode{\sphinxupquote{get\_cookie}} will not yield the saved information.
380
381\sphinxAtStartPar
382If a module implements a mechanism which requires multiple round
383trips, its \sphinxstylestrong{verify} method can respond with the code
384\sphinxcode{\sphinxupquote{KRB5KDC\_ERR\_MORE\_PREAUTH\_DATA\_REQUIRED}} and a list of pa\sphinxhyphen{}data in
385the \sphinxstyleemphasis{e\_data} parameter to be processed by the client.
386
387\sphinxAtStartPar
388The \sphinxstylestrong{edata} and \sphinxstylestrong{verify} methods can be implemented
389asynchronously.  Because of this, they do not return values directly
390to the caller, but must instead invoke responder functions with their
391results.  A synchronous implementation can invoke the responder
392function immediately.  An asynchronous implementation can use the
393callback to get an event context for use with the \sphinxhref{https://fedorahosted.org/libverto/}{libverto} API.
394
395
396\section{Credential cache selection interface (ccselect)}
397\label{\detokenize{plugindev/ccselect:credential-cache-selection-interface-ccselect}}\label{\detokenize{plugindev/ccselect:ccselect-plugin}}\label{\detokenize{plugindev/ccselect::doc}}
398\sphinxAtStartPar
399The ccselect interface allows modules to control how credential caches
400are chosen when a GSSAPI client contacts a service.  For a detailed
401description of the ccselect interface, see the header file
402\sphinxcode{\sphinxupquote{\textless{}krb5/ccselect\_plugin.h\textgreater{}}}.
403
404\sphinxAtStartPar
405The primary ccselect method is \sphinxstylestrong{choose}, which accepts a server
406principal as input and returns a ccache and/or principal name as
407output.  A module can use the krb5\_cccol APIs to iterate over the
408cache collection in order to find an appropriate ccache to use.
409
410\sphinxAtStartPar
411A module can create and destroy per\sphinxhyphen{}library\sphinxhyphen{}context state objects by
412implementing the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  State objects have
413the type krb5\_ccselect\_moddata, which is an abstract pointer type.  A
414module should typically cast this to an internal type for the state
415object.
416
417\sphinxAtStartPar
418A module can have one of two priorities, “authoritative” or
419“heuristic”.  Results from authoritative modules, if any are
420available, will take priority over results from heuristic modules.  A
421module communicates its priority as a result of the \sphinxstylestrong{init} method.
422
423
424\section{Password quality interface (pwqual)}
425\label{\detokenize{plugindev/pwqual:password-quality-interface-pwqual}}\label{\detokenize{plugindev/pwqual:pwqual-plugin}}\label{\detokenize{plugindev/pwqual::doc}}
426\sphinxAtStartPar
427The pwqual interface allows modules to control what passwords are
428allowed when a user changes passwords.  For a detailed description of
429the pwqual interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/pwqual\_plugin.h\textgreater{}}}.
430
431\sphinxAtStartPar
432The primary pwqual method is \sphinxstylestrong{check}, which receives a password as
433input and returns success (0) or a \sphinxcode{\sphinxupquote{KADM5\_PASS\_Q\_}} failure code
434depending on whether the password is allowed.  The \sphinxstylestrong{check} method
435also receives the principal name and the name of the principal’s
436password policy as input; although there is no stable interface for
437the module to obtain the fields of the password policy, it can define
438its own configuration or data store based on the policy name.
439
440\sphinxAtStartPar
441A module can create and destroy per\sphinxhyphen{}process state objects by
442implementing the \sphinxstylestrong{open} and \sphinxstylestrong{close} methods.  State objects have
443the type krb5\_pwqual\_moddata, which is an abstract pointer type.  A
444module should typically cast this to an internal type for the state
445object.  The \sphinxstylestrong{open} method also receives the name of the realm’s
446dictionary file (as configured by the \sphinxstylestrong{dict\_file} variable in the
447\DUrole{xref,std,std-ref}{kdc\_realms} section of \DUrole{xref,std,std-ref}{kdc.conf(5)}) if it wishes to use
448it.
449
450
451\section{KADM5 hook interface (kadm5\_hook)}
452\label{\detokenize{plugindev/kadm5_hook:kadm5-hook-interface-kadm5-hook}}\label{\detokenize{plugindev/kadm5_hook:kadm5-hook-plugin}}\label{\detokenize{plugindev/kadm5_hook::doc}}
453\sphinxAtStartPar
454The kadm5\_hook interface allows modules to perform actions when
455changes are made to the Kerberos database through \DUrole{xref,std,std-ref}{kadmin(1)}.
456For a detailed description of the kadm5\_hook interface, see the header
457file \sphinxcode{\sphinxupquote{\textless{}krb5/kadm5\_hook\_plugin.h\textgreater{}}}.
458
459\sphinxAtStartPar
460The kadm5\_hook interface has five primary methods: \sphinxstylestrong{chpass},
461\sphinxstylestrong{create}, \sphinxstylestrong{modify}, \sphinxstylestrong{remove}, and \sphinxstylestrong{rename}.  (The \sphinxstylestrong{rename}
462method was introduced in release 1.14.)  Each of these methods is
463called twice when the corresponding administrative action takes place,
464once before the action is committed and once afterwards.  A module can
465prevent the action from taking place by returning an error code during
466the pre\sphinxhyphen{}commit stage.
467
468\sphinxAtStartPar
469A module can create and destroy per\sphinxhyphen{}process state objects by
470implementing the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  State objects have
471the type kadm5\_hook\_modinfo, which is an abstract pointer type.  A
472module should typically cast this to an internal type for the state
473object.
474
475\sphinxAtStartPar
476Because the kadm5\_hook interface is tied closely to the kadmin
477interface (which is explicitly unstable), it may not remain as stable
478across versions as other public pluggable interfaces.
479
480
481\section{kadmin authorization interface (kadm5\_auth)}
482\label{\detokenize{plugindev/kadm5_auth:kadmin-authorization-interface-kadm5-auth}}\label{\detokenize{plugindev/kadm5_auth:kadm5-auth-plugin}}\label{\detokenize{plugindev/kadm5_auth::doc}}
483\sphinxAtStartPar
484The kadm5\_auth interface (new in release 1.16) allows modules to
485determine whether a client principal is authorized to perform an
486operation in the kadmin protocol, and to apply restrictions to
487principal operations.  For a detailed description of the kadm5\_auth
488interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/kadm5\_auth\_plugin.h\textgreater{}}}.
489
490\sphinxAtStartPar
491A module can create and destroy per\sphinxhyphen{}process state objects by
492implementing the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  State objects have
493the type kadm5\_auth\_modinfo, which is an abstract pointer type.  A
494module should typically cast this to an internal type for the state
495object.
496
497\sphinxAtStartPar
498The kadm5\_auth interface has one method for each kadmin operation,
499with parameters specific to the operation.  Each method can return
500either 0 to authorize access, KRB5\_PLUGIN\_NO\_HANDLE to defer the
501decision to other modules, or another error (canonically EPERM) to
502authoritatively deny access.  Access is granted if at least one module
503grants access and no module authoritatively denies access.
504
505\sphinxAtStartPar
506The \sphinxstylestrong{addprinc} and \sphinxstylestrong{modprinc} methods can also impose restrictions
507on the principal operation by returning a \sphinxcode{\sphinxupquote{struct
508kadm5\_auth\_restrictions}} object.  The module should also implement
509the \sphinxstylestrong{free\_restrictions} method if it dynamically allocates
510restrictions objects for principal operations.
511
512\sphinxAtStartPar
513kadm5\_auth modules can optionally inspect principal or policy objects.
514To do this, the module must also include \sphinxcode{\sphinxupquote{\textless{}kadm5/admin.h\textgreater{}}} to gain
515access to the structure definitions for those objects.  As the kadmin
516interface is explicitly not as stable as other public interfaces,
517modules which do this may not retain compatibility across releases.
518
519
520\section{Host\sphinxhyphen{}to\sphinxhyphen{}realm interface (hostrealm)}
521\label{\detokenize{plugindev/hostrealm:host-to-realm-interface-hostrealm}}\label{\detokenize{plugindev/hostrealm:hostrealm-plugin}}\label{\detokenize{plugindev/hostrealm::doc}}
522\sphinxAtStartPar
523The host\sphinxhyphen{}to\sphinxhyphen{}realm interface was first introduced in release 1.12.  It
524allows modules to control the local mapping of hostnames to realm
525names as well as the default realm.  For a detailed description of the
526hostrealm interface, see the header file
527\sphinxcode{\sphinxupquote{\textless{}krb5/hostrealm\_plugin.h\textgreater{}}}.
528
529\sphinxAtStartPar
530Although the mapping methods in the hostrealm interface return a list
531of one or more realms, only the first realm in the list is currently
532used by callers.  Callers may begin using later responses in the
533future.
534
535\sphinxAtStartPar
536Any mapping method may return KRB5\_PLUGIN\_NO\_HANDLE to defer
537processing to a later module.
538
539\sphinxAtStartPar
540A module can create and destroy per\sphinxhyphen{}library\sphinxhyphen{}context state objects
541using the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  If the module does not need
542any state, it does not need to implement these methods.
543
544\sphinxAtStartPar
545The optional \sphinxstylestrong{host\_realm} method allows a module to determine
546authoritative realm mappings for a hostname.  The first authoritative
547mapping is used in preference to KDC referrals when getting service
548credentials.
549
550\sphinxAtStartPar
551The optional \sphinxstylestrong{fallback\_realm} method allows a module to determine
552fallback mappings for a hostname.  The first fallback mapping is tried
553if there is no authoritative mapping for a realm, and KDC referrals
554failed to produce a successful result.
555
556\sphinxAtStartPar
557The optional \sphinxstylestrong{default\_realm} method allows a module to determine the
558local default realm.
559
560\sphinxAtStartPar
561If a module implements any of the above methods, it must also
562implement \sphinxstylestrong{free\_list} to ensure that memory is allocated and
563deallocated consistently.
564
565
566\section{Local authorization interface (localauth)}
567\label{\detokenize{plugindev/localauth:local-authorization-interface-localauth}}\label{\detokenize{plugindev/localauth:localauth-plugin}}\label{\detokenize{plugindev/localauth::doc}}
568\sphinxAtStartPar
569The localauth interface was first introduced in release 1.12.  It
570allows modules to control the relationship between Kerberos principals
571and local system accounts.  When an application calls
572\sphinxcode{\sphinxupquote{krb5\_kuserok()}} or \sphinxcode{\sphinxupquote{krb5\_aname\_to\_localname()}}, localauth
573modules are consulted to determine the result.  For a detailed
574description of the localauth interface, see the header file
575\sphinxcode{\sphinxupquote{\textless{}krb5/localauth\_plugin.h\textgreater{}}}.
576
577\sphinxAtStartPar
578A module can create and destroy per\sphinxhyphen{}library\sphinxhyphen{}context state objects
579using the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  If the module does not need
580any state, it does not need to implement these methods.
581
582\sphinxAtStartPar
583The optional \sphinxstylestrong{userok} method allows a module to control the behavior
584of \sphinxcode{\sphinxupquote{krb5\_kuserok()}}.  The module receives the authenticated name
585and the local account name as inputs, and can return either 0 to
586authorize access, KRB5\_PLUGIN\_NO\_HANDLE to defer the decision to other
587modules, or another error (canonically EPERM) to authoritatively deny
588access.  Access is granted if at least one module grants access and no
589module authoritatively denies access.
590
591\sphinxAtStartPar
592The optional \sphinxstylestrong{an2ln} method can work in two different ways.  If the
593module sets an array of uppercase type names in \sphinxstylestrong{an2ln\_types}, then
594the module’s \sphinxstylestrong{an2ln} method will only be invoked by
595\sphinxcode{\sphinxupquote{krb5\_aname\_to\_localname()}} if an \sphinxstylestrong{auth\_to\_local} value in
596\DUrole{xref,std,std-ref}{krb5.conf(5)} refers to one of the module’s types.  In this
597case, the \sphinxstyleemphasis{type} and \sphinxstyleemphasis{residual} arguments will give the type name and
598residual string of the \sphinxstylestrong{auth\_to\_local} value.
599
600\sphinxAtStartPar
601If the module does not set \sphinxstylestrong{an2ln\_types} but does implement
602\sphinxstylestrong{an2ln}, the module’s \sphinxstylestrong{an2ln} method will be invoked for all
603\sphinxcode{\sphinxupquote{krb5\_aname\_to\_localname()}} operations unless an earlier module
604determines a mapping, with \sphinxstyleemphasis{type} and \sphinxstyleemphasis{residual} set to NULL.  The
605module can return KRB5\_LNAME\_NO\_TRANS to defer mapping to later
606modules.
607
608\sphinxAtStartPar
609If a module implements \sphinxstylestrong{an2ln}, it must also implement
610\sphinxstylestrong{free\_string} to ensure that memory is allocated and deallocated
611consistently.
612
613
614\section{Server location interface (locate)}
615\label{\detokenize{plugindev/locate:server-location-interface-locate}}\label{\detokenize{plugindev/locate::doc}}
616\sphinxAtStartPar
617The locate interface allows modules to control how KDCs and similar
618services are located by clients.  For a detailed description of the
619ccselect interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/locate\_plugin.h\textgreater{}}}.
620
621\sphinxAtStartPar
622A locate module exports a structure object of type
623krb5plugin\_service\_locate\_ftable, with the name \sphinxcode{\sphinxupquote{service\_locator}}.
624The structure contains a minor version and pointers to the module’s
625methods.
626
627\sphinxAtStartPar
628The primary locate method is \sphinxstylestrong{lookup}, which accepts a service type,
629realm name, desired socket type, and desired address family (which
630will be AF\_UNSPEC if no specific address family is desired).  The
631method should invoke the callback function once for each server
632address it wants to return, passing a socket type (SOCK\_STREAM for TCP
633or SOCK\_DGRAM for UDP) and socket address.  The \sphinxstylestrong{lookup} method
634should return 0 if it has authoritatively determined the server
635addresses for the realm, KRB5\_PLUGIN\_NO\_HANDLE if it wants to let
636other location mechanisms determine the server addresses, or another
637code if it experienced a failure which should abort the location
638process.
639
640\sphinxAtStartPar
641A module can create and destroy per\sphinxhyphen{}library\sphinxhyphen{}context state objects by
642implementing the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  State objects have
643the type void *, and should be cast to an internal type for the state
644object.
645
646
647\section{Configuration interface (profile)}
648\label{\detokenize{plugindev/profile:configuration-interface-profile}}\label{\detokenize{plugindev/profile:profile-plugin}}\label{\detokenize{plugindev/profile::doc}}
649\sphinxAtStartPar
650The profile interface allows a module to control how krb5
651configuration information is obtained by the Kerberos library and
652applications.  For a detailed description of the profile interface,
653see the header file \sphinxcode{\sphinxupquote{\textless{}profile.h\textgreater{}}}.
654
655\begin{sphinxadmonition}{note}{Note:}
656\sphinxAtStartPar
657The profile interface does not follow the normal conventions
658for MIT krb5 pluggable interfaces, because it is part of a
659lower\sphinxhyphen{}level component of the krb5 library.
660\end{sphinxadmonition}
661
662\sphinxAtStartPar
663As with other types of plugin modules, a profile module is a Unix
664shared object or Windows DLL, built separately from the krb5 tree.
665The krb5 library will dynamically load and use a profile plugin module
666if it reads a \sphinxcode{\sphinxupquote{module}} directive at the beginning of krb5.conf, as
667described in \DUrole{xref,std,std-ref}{profile\_plugin\_config}.
668
669\sphinxAtStartPar
670A profile module exports a function named \sphinxcode{\sphinxupquote{profile\_module\_init}}
671matching the signature of the profile\_module\_init\_fn type.  This
672function accepts a residual string, which may be used to help locate
673the configuration source.  The function fills in a vtable and may also
674create a per\sphinxhyphen{}profile state object.  If the module uses state objects,
675it should implement the \sphinxstylestrong{copy} and \sphinxstylestrong{cleanup} methods to manage
676them.
677
678\sphinxAtStartPar
679A basic read\sphinxhyphen{}only profile module need only implement the
680\sphinxstylestrong{get\_values} and \sphinxstylestrong{free\_values} methods.  The \sphinxstylestrong{get\_values} method
681accepts a null\sphinxhyphen{}terminated list of C string names (e.g., an array
682containing “libdefaults”, “clockskew”, and NULL for the \sphinxstylestrong{clockskew}
683variable in the \DUrole{xref,std,std-ref}{libdefaults} section) and returns a
684null\sphinxhyphen{}terminated list of values, which will be cleaned up with the
685\sphinxstylestrong{free\_values} method when the caller is done with them.
686
687\sphinxAtStartPar
688Iterable profile modules must also define the \sphinxstylestrong{iterator\_create},
689\sphinxstylestrong{iterator}, \sphinxstylestrong{iterator\_free}, and \sphinxstylestrong{free\_string} methods.  The
690core krb5 code does not require profiles to be iterable, but some
691applications may iterate over the krb5 profile object in order to
692present configuration interfaces.
693
694\sphinxAtStartPar
695Writable profile modules must also define the \sphinxstylestrong{writable},
696\sphinxstylestrong{modified}, \sphinxstylestrong{update\_relation}, \sphinxstylestrong{rename\_section},
697\sphinxstylestrong{add\_relation}, and \sphinxstylestrong{flush} methods.  The core krb5 code does not
698require profiles to be writable, but some applications may write to
699the krb5 profile in order to present configuration interfaces.
700
701\sphinxAtStartPar
702The following is an example of a very basic read\sphinxhyphen{}only profile module
703which returns a hardcoded value for the \sphinxstylestrong{default\_realm} variable in
704\DUrole{xref,std,std-ref}{libdefaults}, and provides no other configuration information.
705(For conciseness, the example omits code for checking the return
706values of malloc and strdup.)
707
708\begin{sphinxVerbatim}[commandchars=\\\{\}]
709\PYG{c+c1}{\PYGZsh{}include \PYGZlt{}stdlib.h\PYGZgt{}}
710\PYG{c+c1}{\PYGZsh{}include \PYGZlt{}string.h\PYGZgt{}}
711\PYG{c+c1}{\PYGZsh{}include \PYGZlt{}profile.h\PYGZgt{}}
712
713\PYG{n}{static} \PYG{n}{long}
714\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}{)}
715\PYG{p}{\PYGZob{}}
716    \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{}}
717        \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{}}
718        \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}{;}
719        \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}{;}
720        \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}{;}
721        \PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;}
722    \PYG{p}{\PYGZcb{}}
723    \PYG{k}{return} \PYG{n}{PROF\PYGZus{}NO\PYGZus{}RELATION}\PYG{p}{;}
724\PYG{p}{\PYGZcb{}}
725
726\PYG{n}{static} \PYG{n}{void}
727\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}{)}
728\PYG{p}{\PYGZob{}}
729    \PYG{n}{char} \PYG{o}{*}\PYG{o}{*}\PYG{n}{v}\PYG{p}{;}
730
731    \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}{)}
732        \PYG{n}{free}\PYG{p}{(}\PYG{o}{*}\PYG{n}{v}\PYG{p}{)}\PYG{p}{;}
733    \PYG{n}{free}\PYG{p}{(}\PYG{n}{values}\PYG{p}{)}\PYG{p}{;}
734\PYG{p}{\PYGZcb{}}
735
736\PYG{n}{long}
737\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}{,}
738                    \PYG{n}{void} \PYG{o}{*}\PYG{o}{*}\PYG{n}{cb\PYGZus{}ret}\PYG{p}{)}\PYG{p}{;}
739
740\PYG{n}{long}
741\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}{,}
742                    \PYG{n}{void} \PYG{o}{*}\PYG{o}{*}\PYG{n}{cb\PYGZus{}ret}\PYG{p}{)}
743\PYG{p}{\PYGZob{}}
744    \PYG{o}{*}\PYG{n}{cb\PYGZus{}ret} \PYG{o}{=} \PYG{n}{NULL}\PYG{p}{;}
745    \PYG{n}{vtable}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{get\PYGZus{}values} \PYG{o}{=} \PYG{n}{get\PYGZus{}values}\PYG{p}{;}
746    \PYG{n}{vtable}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{free\PYGZus{}values} \PYG{o}{=} \PYG{n}{free\PYGZus{}values}\PYG{p}{;}
747    \PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;}
748\PYG{p}{\PYGZcb{}}
749\end{sphinxVerbatim}
750
751
752\section{GSSAPI mechanism interface}
753\label{\detokenize{plugindev/gssapi:gssapi-mechanism-interface}}\label{\detokenize{plugindev/gssapi::doc}}
754\sphinxAtStartPar
755The GSSAPI library in MIT krb5 can load mechanism modules to augment
756the set of built\sphinxhyphen{}in mechanisms.
757
758\sphinxAtStartPar
759A mechanism module is a Unix shared object or Windows DLL, built
760separately from the krb5 tree.  Modules are loaded according to the
761GSS mechanism config files described in \DUrole{xref,std,std-ref}{gssapi\_plugin\_config}.
762
763\sphinxAtStartPar
764For the most part, a GSSAPI mechanism module exports the same
765functions as would a GSSAPI implementation itself, with the same
766function signatures.  The mechanism selection layer within the GSSAPI
767library (called the “mechglue”) will dispatch calls from the
768application to the module if the module’s mechanism is requested.  If
769a module does not wish to implement a GSSAPI extension, it can simply
770refrain from exporting it, and the mechglue will fail gracefully if
771the application calls that function.
772
773\sphinxAtStartPar
774The mechglue does not invoke a module’s \sphinxstylestrong{gss\_add\_cred},
775\sphinxstylestrong{gss\_add\_cred\_from}, \sphinxstylestrong{gss\_add\_cred\_impersonate\_name}, or
776\sphinxstylestrong{gss\_add\_cred\_with\_password} function.  A mechanism only needs to
777implement the “acquire” variants of those functions.
778
779\sphinxAtStartPar
780A module does not need to coordinate its minor status codes with those
781of other mechanisms.  If the mechglue detects conflicts, it will map
782the mechanism’s status codes onto unique values, and then map them
783back again when \sphinxstylestrong{gss\_display\_status} is called.
784
785
786\subsection{NegoEx modules}
787\label{\detokenize{plugindev/gssapi:negoex-modules}}
788\sphinxAtStartPar
789Some Windows GSSAPI mechanisms can only be negotiated via a Microsoft
790extension to SPNEGO called NegoEx.  Beginning with release 1.18,
791mechanism modules can support NegoEx as follows:
792\begin{itemize}
793\item {}
794\sphinxAtStartPar
795Implement the gssspi\_query\_meta\_data(), gssspi\_exchange\_meta\_data(),
796and gssspi\_query\_mechanism\_info() SPIs declared in
797\sphinxcode{\sphinxupquote{\textless{}gssapi/gssapi\_ext.h\textgreater{}}}.
798
799\item {}
800\sphinxAtStartPar
801Implement gss\_inquire\_sec\_context\_by\_oid() and answer the
802\sphinxstylestrong{GSS\_C\_INQ\_NEGOEX\_KEY} and \sphinxstylestrong{GSS\_C\_INQ\_NEGOEX\_VERIFY\_KEY} OIDs
803to provide the checksum keys for outgoing and incoming checksums,
804respectively.  The answer must be in two buffers: the first buffer
805contains the key contents, and the second buffer contains the key
806encryption type as a four\sphinxhyphen{}byte little\sphinxhyphen{}endian integer.
807
808\end{itemize}
809
810\sphinxAtStartPar
811By default, NegoEx mechanisms will not be directly negotiated via
812SPNEGO.  If direct SPNEGO negotiation is required for
813interoperability, implement gss\_inquire\_attrs\_for\_mech() and assert
814the GSS\_C\_MA\_NEGOEX\_AND\_SPNEGO attribute (along with any applicable
815RFC 5587 attributes).
816
817
818\subsection{Interposer modules}
819\label{\detokenize{plugindev/gssapi:interposer-modules}}
820\sphinxAtStartPar
821The mechglue also supports a kind of loadable module, called an
822interposer module, which intercepts calls to existing mechanisms
823rather than implementing a new mechanism.
824
825\sphinxAtStartPar
826An interposer module must export the symbol \sphinxstylestrong{gss\_mech\_interposer}
827with the following signature:
828
829\begin{sphinxVerbatim}[commandchars=\\\{\}]
830\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}{;}
831\end{sphinxVerbatim}
832
833\sphinxAtStartPar
834This function is invoked with the OID of the interposer mechanism as
835specified in the mechanism config file, and returns a set of mechanism
836OIDs to be interposed.  The returned OID set must have been created
837using the mechglue’s gss\_create\_empty\_oid\_set and
838gss\_add\_oid\_set\_member functions.
839
840\sphinxAtStartPar
841An interposer module must use the prefix \sphinxcode{\sphinxupquote{gssi\_}} for the GSSAPI
842functions it exports, instead of the prefix \sphinxcode{\sphinxupquote{gss\_}}.  In most cases,
843unexported \sphinxcode{\sphinxupquote{gssi\_}} functions will result in failure from their
844corresponding \sphinxcode{\sphinxupquote{gss\_}} calls.
845
846\sphinxAtStartPar
847An interposer module can link against the GSSAPI library in order to
848make calls to the original mechanism.  To do so, it must specify a
849special mechanism OID which is the concatention of the interposer’s
850own OID byte string and the original mechanism’s OID byte string.
851
852\sphinxAtStartPar
853Functions that do not accept a mechanism argument directly require no
854special handling, with the following exceptions:
855
856\sphinxAtStartPar
857Since \sphinxstylestrong{gss\_accept\_sec\_context} does not accept a mechanism argument,
858an interposer mechanism must, in order to invoke the original
859mechanism’s function, acquire a credential for the concatenated OID
860and pass that as the \sphinxstyleemphasis{verifier\_cred\_handle} parameter.
861
862\sphinxAtStartPar
863Since \sphinxstylestrong{gss\_import\_name}, \sphinxstylestrong{gss\_import\_cred}, and
864\sphinxstylestrong{gss\_import\_sec\_context} do not accept mechanism parameters, the SPI
865has been extended to include variants which do.  This allows the
866interposer module to know which mechanism should be used to interpret
867the token.  These functions have the following signatures:
868
869\begin{sphinxVerbatim}[commandchars=\\\{\}]
870\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}{,}
871    \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}{,}
872    \PYG{n}{gss\PYGZus{}ctx\PYGZus{}id\PYGZus{}t} \PYG{o}{*}\PYG{n}{context\PYGZus{}handle}\PYG{p}{)}\PYG{p}{;}
873
874\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}{,}
875    \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}{,}
876    \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}{;}
877
878\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}{,}
879    \PYG{n}{gss\PYGZus{}OID} \PYG{n}{mech\PYGZus{}type}\PYG{p}{,} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}t} \PYG{n}{token}\PYG{p}{,}
880    \PYG{n}{gss\PYGZus{}cred\PYGZus{}id\PYGZus{}t} \PYG{o}{*}\PYG{n}{cred\PYGZus{}handle}\PYG{p}{)}\PYG{p}{;}
881\end{sphinxVerbatim}
882
883\sphinxAtStartPar
884To re\sphinxhyphen{}enter the original mechanism when importing tokens for the above
885functions, the interposer module must wrap the mechanism token in the
886mechglue’s format, using the concatenated OID (except in
887\sphinxstylestrong{gss\_import\_name}).  The mechglue token formats are:
888\begin{itemize}
889\item {}
890\sphinxAtStartPar
891For \sphinxstylestrong{gss\_import\_sec\_context}, a four\sphinxhyphen{}byte OID length in big\sphinxhyphen{}endian
892order, followed by the concatenated OID, followed by the mechanism
893token.
894
895\item {}
896\sphinxAtStartPar
897For \sphinxstylestrong{gss\_import\_name}, the bytes 04 01, followed by a two\sphinxhyphen{}byte OID
898length in big\sphinxhyphen{}endian order, followed by the mechanism OID, followed
899by a four\sphinxhyphen{}byte token length in big\sphinxhyphen{}endian order, followed by the
900mechanism token.  Unlike most uses of OIDs in the API, the mechanism
901OID encoding must include the DER tag and length for an object
902identifier (06 followed by the DER length of the OID byte string),
903and this prefix must be included in the two\sphinxhyphen{}byte OID length.
904input\_name\_type must also be set to GSS\_C\_NT\_EXPORT\_NAME.
905
906\item {}
907\sphinxAtStartPar
908For \sphinxstylestrong{gss\_import\_cred}, a four\sphinxhyphen{}byte OID length in big\sphinxhyphen{}endian order,
909followed by the concatenated OID, followed by a four\sphinxhyphen{}byte token
910length in big\sphinxhyphen{}endian order, followed by the mechanism token.  This
911sequence may be repeated multiple times.
912
913\end{itemize}
914
915
916\section{Internal pluggable interfaces}
917\label{\detokenize{plugindev/internal:internal-pluggable-interfaces}}\label{\detokenize{plugindev/internal::doc}}
918\sphinxAtStartPar
919Following are brief discussions of pluggable interfaces which have not
920yet been made public.  These interfaces are functional, but the
921interfaces are likely to change in incompatible ways from release to
922release.  In some cases, it may be necessary to copy header files from
923the krb5 source tree to use an internal interface.  Use these with
924care, and expect to need to update your modules for each new release
925of MIT krb5.
926
927
928\subsection{Kerberos database interface (KDB)}
929\label{\detokenize{plugindev/internal:kerberos-database-interface-kdb}}
930\sphinxAtStartPar
931A KDB module implements a database back end for KDC principal and
932policy information, and can also control many aspects of KDC behavior.
933For a full description of the interface, see the header file
934\sphinxcode{\sphinxupquote{\textless{}kdb.h\textgreater{}}}.
935
936\sphinxAtStartPar
937The KDB pluggable interface is often referred to as the DAL (Database
938Access Layer).
939
940
941\subsection{Authorization data interface (authdata)}
942\label{\detokenize{plugindev/internal:authorization-data-interface-authdata}}
943\sphinxAtStartPar
944The authdata interface allows a module to provide (from the KDC) or
945consume (in application servers) authorization data of types beyond
946those handled by the core MIT krb5 code base.  The interface is
947defined in the header file \sphinxcode{\sphinxupquote{\textless{}krb5/authdata\_plugin.h\textgreater{}}}, which is not
948installed by the build.
949
950
951\section{PKINIT certificate authorization interface (certauth)}
952\label{\detokenize{plugindev/certauth:pkinit-certificate-authorization-interface-certauth}}\label{\detokenize{plugindev/certauth:certauth-plugin}}\label{\detokenize{plugindev/certauth::doc}}
953\sphinxAtStartPar
954The certauth interface was first introduced in release 1.16.  It
955allows customization of the X.509 certificate attribute requirements
956placed on certificates used by PKINIT enabled clients.  For a detailed
957description of the certauth interface, see the header file
958\sphinxcode{\sphinxupquote{\textless{}krb5/certauth\_plugin.h\textgreater{}}}
959
960\sphinxAtStartPar
961A certauth module implements the \sphinxstylestrong{authorize} method to determine
962whether a client’s certificate is authorized to authenticate a client
963principal.  \sphinxstylestrong{authorize} receives the DER\sphinxhyphen{}encoded certificate, the
964requested client principal, and a pointer to the client’s
965krb5\_db\_entry (for modules that link against libkdb5).  The method
966must decode the certificate and inspect its attributes to determine if
967it should authorize PKINIT authentication.  It returns the
968authorization status and optionally outputs a list of authentication
969indicator strings to be added to the ticket.
970
971\sphinxAtStartPar
972Beginning in release 1.19, the authorize method can request that the
973hardware authentication bit be set in the ticket by returning
974\sphinxstylestrong{KRB5\_CERTAUTH\_HWAUTH}.  Beginning in release 1.20, the authorize
975method can return \sphinxstylestrong{KRB5\_CERTAUTH\_HWAUTH\_PASS} to request that the
976hardware authentication bit be set in the ticket but otherwise defer
977authorization to another certauth module.  A module must use its own
978internal or library\sphinxhyphen{}provided ASN.1 certificate decoder.
979
980\sphinxAtStartPar
981A module can optionally create and destroy module data with the
982\sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  Module data objects last for the
983lifetime of the KDC process.
984
985\sphinxAtStartPar
986If a module allocates and returns a list of authentication indicators
987from \sphinxstylestrong{authorize}, it must also implement the \sphinxstylestrong{free\_ind} method
988to free the list.
989
990
991\section{KDC policy interface (kdcpolicy)}
992\label{\detokenize{plugindev/kdcpolicy:kdc-policy-interface-kdcpolicy}}\label{\detokenize{plugindev/kdcpolicy:kdcpolicy-plugin}}\label{\detokenize{plugindev/kdcpolicy::doc}}
993\sphinxAtStartPar
994The kdcpolicy interface was first introduced in release 1.16.  It
995allows modules to veto otherwise valid AS and TGS requests or restrict
996the lifetime and renew time of the resulting ticket.  For a detailed
997description of the kdcpolicy interface, see the header file
998\sphinxcode{\sphinxupquote{\textless{}krb5/kdcpolicy\_plugin.h\textgreater{}}}.
999
1000\sphinxAtStartPar
1001The optional \sphinxstylestrong{check\_as} and \sphinxstylestrong{check\_tgs} functions allow the module
1002to perform access control.  Additionally, a module can create and
1003destroy module data with the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods.  Module
1004data objects last for the lifetime of the KDC process, and are
1005provided to all other methods.  The data has the type
1006krb5\_kdcpolicy\_moddata, which should be cast to the appropriate
1007internal type.
1008
1009\sphinxAtStartPar
1010kdcpolicy modules can optionally inspect principal entries.  To do
1011this, the module must also include \sphinxcode{\sphinxupquote{\textless{}kdb.h\textgreater{}}} to gain access to the
1012principal entry structure definition.  As the KDB interface is
1013explicitly not as stable as other public interfaces, modules which do
1014this may not retain compatibility across releases.
1015
1016
1017
1018\renewcommand{\indexname}{Index}
1019\printindex
1020\end{document}