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}