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