File: plugindev.tex

package info (click to toggle)
krb5 1.22.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,652 kB
  • sloc: ansic: 293,109; python: 10,357; cpp: 9,477; makefile: 7,035; sh: 6,189; perl: 1,650; asm: 1,212; yacc: 933; javascript: 789; awk: 344; csh: 147; xml: 135; lisp: 104
file content (1058 lines) | stat: -rw-r--r-- 54,219 bytes parent folder | download
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}