aboutsummaryrefslogtreecommitdiff
path: root/doc/pdf/plugindev.tex
blob: 474b00c80cbf5ab0b54f6df6131be310060ba6fa (plain) (blame)
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
% Generated by Sphinx.
\def\sphinxdocclass{report}
\documentclass[letterpaper,10pt,english]{sphinxmanual}
\usepackage[utf8]{inputenc}
\DeclareUnicodeCharacter{00A0}{\nobreakspace}
\usepackage{cmap}
\usepackage[T1]{fontenc}
\usepackage{babel}
\usepackage{times}
\usepackage[Bjarne]{fncychap}
\usepackage{longtable}
\usepackage{sphinx}
\usepackage{multirow}


\title{Kerberos Plugin Module Developer Guide}
\date{ }
\release{1.16}
\author{MIT}
\newcommand{\sphinxlogo}{}
\renewcommand{\releasename}{Release}
\makeindex

\makeatletter
\def\PYG@reset{\let\PYG@it=\relax \let\PYG@bf=\relax%
    \let\PYG@ul=\relax \let\PYG@tc=\relax%
    \let\PYG@bc=\relax \let\PYG@ff=\relax}
\def\PYG@tok#1{\csname PYG@tok@#1\endcsname}
\def\PYG@toks#1+{\ifx\relax#1\empty\else%
    \PYG@tok{#1}\expandafter\PYG@toks\fi}
\def\PYG@do#1{\PYG@bc{\PYG@tc{\PYG@ul{%
    \PYG@it{\PYG@bf{\PYG@ff{#1}}}}}}}
\def\PYG#1#2{\PYG@reset\PYG@toks#1+\relax+\PYG@do{#2}}

\expandafter\def\csname PYG@tok@gd\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}}
\expandafter\def\csname PYG@tok@gu\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}}
\expandafter\def\csname PYG@tok@gt\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}}
\expandafter\def\csname PYG@tok@gs\endcsname{\let\PYG@bf=\textbf}
\expandafter\def\csname PYG@tok@gr\endcsname{\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}}
\expandafter\def\csname PYG@tok@cm\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}}
\expandafter\def\csname PYG@tok@vg\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\expandafter\def\csname PYG@tok@m\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@mh\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@cs\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
\expandafter\def\csname PYG@tok@ge\endcsname{\let\PYG@it=\textit}
\expandafter\def\csname PYG@tok@vc\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\expandafter\def\csname PYG@tok@il\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@go\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.20,0.20,0.20}{##1}}}
\expandafter\def\csname PYG@tok@cp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@gi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}}
\expandafter\def\csname PYG@tok@gh\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
\expandafter\def\csname PYG@tok@ni\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.84,0.33,0.22}{##1}}}
\expandafter\def\csname PYG@tok@nl\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.13,0.44}{##1}}}
\expandafter\def\csname PYG@tok@nn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}}
\expandafter\def\csname PYG@tok@no\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.38,0.68,0.84}{##1}}}
\expandafter\def\csname PYG@tok@na\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@nb\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@nc\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}}
\expandafter\def\csname PYG@tok@nd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.33,0.33,0.33}{##1}}}
\expandafter\def\csname PYG@tok@ne\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@nf\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.02,0.16,0.49}{##1}}}
\expandafter\def\csname PYG@tok@si\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.44,0.63,0.82}{##1}}}
\expandafter\def\csname PYG@tok@s2\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@vi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\expandafter\def\csname PYG@tok@nt\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.02,0.16,0.45}{##1}}}
\expandafter\def\csname PYG@tok@nv\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\expandafter\def\csname PYG@tok@s1\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@gp\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}}
\expandafter\def\csname PYG@tok@sh\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@ow\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@sx\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}}
\expandafter\def\csname PYG@tok@bp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@c1\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}}
\expandafter\def\csname PYG@tok@kc\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@c\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}}
\expandafter\def\csname PYG@tok@mf\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@err\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{\strut ##1}}}
\expandafter\def\csname PYG@tok@kd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@ss\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.32,0.47,0.09}{##1}}}
\expandafter\def\csname PYG@tok@sr\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.14,0.33,0.53}{##1}}}
\expandafter\def\csname PYG@tok@mo\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@mi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@kn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@o\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PYG@tok@kr\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@s\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@kp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@w\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}}
\expandafter\def\csname PYG@tok@kt\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.56,0.13,0.00}{##1}}}
\expandafter\def\csname PYG@tok@sc\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@sb\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@k\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@se\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@sd\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}

\def\PYGZbs{\char`\\}
\def\PYGZus{\char`\_}
\def\PYGZob{\char`\{}
\def\PYGZcb{\char`\}}
\def\PYGZca{\char`\^}
\def\PYGZam{\char`\&}
\def\PYGZlt{\char`\<}
\def\PYGZgt{\char`\>}
\def\PYGZsh{\char`\#}
\def\PYGZpc{\char`\%}
\def\PYGZdl{\char`\$}
\def\PYGZhy{\char`\-}
\def\PYGZsq{\char`\'}
\def\PYGZdq{\char`\"}
\def\PYGZti{\char`\~}
% for compatibility with earlier versions
\def\PYGZat{@}
\def\PYGZlb{[}
\def\PYGZrb{]}
\makeatother

\begin{document}

\maketitle
\tableofcontents
\phantomsection\label{plugindev/index::doc}


Kerberos plugin modules allow increased control over MIT krb5 library
and server behavior.  This guide describes how to create dynamic
plugin modules and the currently available pluggable interfaces.

See \emph{plugin\_config} for information on how to register dynamic
plugin modules and how to enable and disable modules via
\emph{krb5.conf(5)}.


\chapter{Contents}
\label{plugindev/index:for-plugin-module-developers}\label{plugindev/index:contents}

\section{General plugin concepts}
\label{plugindev/general:general-plugin-concepts}\label{plugindev/general::doc}
A krb5 dynamic plugin module is a Unix shared object or Windows DLL.
Typically, the source code for a dynamic plugin module should live in
its own project with a build system using \href{http://www.gnu.org/software/automake/}{automake} and \href{http://www.gnu.org/software/libtool/}{libtool}, or
tools with similar functionality.

A plugin module must define a specific symbol name, which depends on
the pluggable interface and module name.  For most pluggable
interfaces, the exported symbol is a function named
\code{INTERFACE\_MODULE\_initvt}, where \emph{INTERFACE} is the name of the
pluggable interface and \emph{MODULE} is the name of the module.  For these
interfaces, it is possible for one shared object or DLL to implement
multiple plugin modules, either for the same pluggable interface or
for different ones.  For example, a shared object could implement both
KDC and client preauthentication mechanisms, by exporting functions
named \code{kdcpreauth\_mymech\_initvt} and \code{clpreauth\_mymech\_initvt}.

A plugin module implementation should include the header file
\code{\textless{}krb5/INTERFACE\_plugin.h\textgreater{}}, where \emph{INTERFACE} is the name of the
pluggable interface.  For instance, a ccselect plugin module
implementation should use \code{\#include \textless{}krb5/ccselect\_plugin.h\textgreater{}}.

initvt functions have the following prototype:

\begin{Verbatim}[commandchars=\\\{\}]
krb5\PYGZus{}error\PYGZus{}code interface\PYGZus{}modname\PYGZus{}initvt(krb5\PYGZus{}context context,
                                         int maj\PYGZus{}ver, int min\PYGZus{}ver,
                                         krb5\PYGZus{}plugin\PYGZus{}vtable vtable);
\end{Verbatim}

and should do the following:
\begin{enumerate}
\item {} 
Check that the supplied maj\_ver argument is supported by the
module.  If it is not supported, the function should return
KRB5\_PLUGIN\_VER\_NOTSUPP.

\item {} 
Cast the supplied vtable pointer to the structure type
corresponding to the major version, as documented in the pluggable
interface header file.

\item {} 
Fill in the structure fields with pointers to method functions and
static data, stopping at the field indicated by the supplied minor
version.  Fields for unimplemented optional methods can be left
alone; it is not necessary to initialize them to NULL.

\end{enumerate}

In most cases, the context argument will not be used.  The initvt
function should not allocate memory; think of it as a glorified
structure initializer.  Each pluggable interface defines methods for
allocating and freeing module state if doing so is necessary for the
interface.

Pluggable interfaces typically include a \textbf{name} field in the vtable
structure, which should be filled in with a pointer to a string
literal containing the module name.

Here is an example of what an initvt function might look like for a
fictional pluggable interface named fences, for a module named
``wicker'':

\begin{Verbatim}[commandchars=\\\{\}]
krb5\PYGZus{}error\PYGZus{}code
fences\PYGZus{}wicker\PYGZus{}initvt(krb5\PYGZus{}context context, int maj\PYGZus{}ver,
                     int min\PYGZus{}ver, krb5\PYGZus{}plugin\PYGZus{}vtable vtable)
\PYGZob{}
    krb5\PYGZus{}ccselect\PYGZus{}vtable vt;

    if (maj\PYGZus{}ver == 1) \PYGZob{}
        krb5\PYGZus{}fences\PYGZus{}vtable vt = (krb5\PYGZus{}fences\PYGZus{}vtable)vtable;
        vt\PYGZhy{}\PYGZgt{}name = \PYGZdq{}wicker\PYGZdq{};
        vt\PYGZhy{}\PYGZgt{}slats = wicker\PYGZus{}slats;
        vt\PYGZhy{}\PYGZgt{}braces = wicker\PYGZus{}braces;
    \PYGZcb{} else if (maj\PYGZus{}ver == 2) \PYGZob{}
        krb5\PYGZus{}fences\PYGZus{}vtable\PYGZus{}v2 vt = (krb5\PYGZus{}fences\PYGZus{}vtable\PYGZus{}v2)vtable;
        vt\PYGZhy{}\PYGZgt{}name = \PYGZdq{}wicker\PYGZdq{};
        vt\PYGZhy{}\PYGZgt{}material = wicker\PYGZus{}material;
        vt\PYGZhy{}\PYGZgt{}construction = wicker\PYGZus{}construction;
        if (min\PYGZus{}ver \PYGZlt{} 2)
            return 0;
        vt\PYGZhy{}\PYGZgt{}footing = wicker\PYGZus{}footing;
        if (min\PYGZus{}ver \PYGZlt{} 3)
            return 0;
        vt\PYGZhy{}\PYGZgt{}appearance = wicker\PYGZus{}appearance;
    \PYGZcb{} else \PYGZob{}
        return KRB5\PYGZus{}PLUGIN\PYGZus{}VER\PYGZus{}NOTSUPP;
    \PYGZcb{}
    return 0;
\PYGZcb{}
\end{Verbatim}


\section{Client preauthentication interface (clpreauth)}
\label{plugindev/clpreauth:client-preauthentication-interface-clpreauth}\label{plugindev/clpreauth::doc}
During an initial ticket request, a KDC may ask a client to prove its
knowledge of the password before issuing an encrypted ticket, or to
use credentials other than a password.  This process is called
preauthentication, and is described in \index{RFC!RFC 4120}\href{http://tools.ietf.org/html/rfc4120.html}{\textbf{RFC 4120}} and \index{RFC!RFC 6113}\href{http://tools.ietf.org/html/rfc6113.html}{\textbf{RFC 6113}}.
The clpreauth interface allows the addition of client support for
preauthentication mechanisms beyond those included in the core MIT
krb5 code base.  For a detailed description of the clpreauth
interface, see the header file \code{\textless{}krb5/clpreauth\_plugin.h\textgreater{}} (or
\code{\textless{}krb5/preauth\_plugin.h\textgreater{}} before release 1.12).

A clpreauth module is generally responsible for:
\begin{itemize}
\item {} 
Supplying a list of preauth type numbers used by the module in the
\textbf{pa\_type\_list} field of the vtable structure.

\item {} 
Indicating what kind of preauthentication mechanism it implements,
with the \textbf{flags} method.  In the most common case, this method
just returns \code{PA\_REAL}, indicating that it implements a normal
preauthentication type.

\item {} 
Examining the padata information included in a PREAUTH\_REQUIRED or
MORE\_PREAUTH\_DATA\_REQUIRED error and producing padata values for the
next AS request.  This is done with the \textbf{process} method.

\item {} 
Examining the padata information included in a successful ticket
reply, possibly verifying the KDC identity and computing a reply
key.  This is also done with the \textbf{process} method.

\item {} 
For preauthentication types which support it, recovering from errors
by examining the error data from the KDC and producing a padata
value for another AS request.  This is done with the \textbf{tryagain}
method.

\item {} 
Receiving option information (supplied by \code{kinit -X} or by an
application), with the \textbf{gic\_opts} method.

\end{itemize}

A clpreauth module can create and destroy per-library-context and
per-request state objects by implementing the \textbf{init}, \textbf{fini},
\textbf{request\_init}, and \textbf{request\_fini} methods.  Per-context state
objects have the type krb5\_clpreauth\_moddata, and per-request state
objects have the type krb5\_clpreauth\_modreq.  These are abstract
pointer types; a module should typically cast these to internal
types for the state objects.

The \textbf{process} and \textbf{tryagain} methods have access to a callback
function and handle (called a ``rock'') which can be used to get
additional information about the current request, including the
expected enctype of the AS reply, the FAST armor key, and the client
long-term key (prompting for the user password if necessary).  A
callback can also be used to replace the AS reply key if the
preauthentication mechanism computes one.


\section{KDC preauthentication interface (kdcpreauth)}
\label{plugindev/kdcpreauth:kdc-preauthentication-interface-kdcpreauth}\label{plugindev/kdcpreauth::doc}
The kdcpreauth interface allows the addition of KDC support for
preauthentication mechanisms beyond those included in the core MIT
krb5 code base.  For a detailed description of the kdcpreauth
interface, see the header file \code{\textless{}krb5/kdcpreauth\_plugin.h\textgreater{}} (or
\code{\textless{}krb5/preauth\_plugin.h\textgreater{}} before release 1.12).

A kdcpreauth module is generally responsible for:
\begin{itemize}
\item {} 
Supplying a list of preauth type numbers used by the module in the
\textbf{pa\_type\_list} field of the vtable structure.

\item {} 
Indicating what kind of preauthentication mechanism it implements,
with the \textbf{flags} method.  If the mechanism computes a new reply
key, it must specify the \code{PA\_REPLACES\_KEY} flag.  If the mechanism
is generally only used with hardware tokens, the \code{PA\_HARDWARE}
flag allows the mechanism to work with principals which have the
\textbf{requires\_hwauth} flag set.

\item {} 
Producing a padata value to be sent with a preauth\_required error,
with the \textbf{edata} method.

\item {} 
Examining a padata value sent by a client and verifying that it
proves knowledge of the appropriate client credential information.
This is done with the \textbf{verify} method.

\item {} 
Producing a padata response value for the client, and possibly
computing a reply key.  This is done with the \textbf{return\_padata}
method.

\end{itemize}

A module can create and destroy per-KDC state objects by implementing
the \textbf{init} and \textbf{fini} methods.  Per-KDC state objects have the
type krb5\_kdcpreauth\_moddata, which is an abstract pointer types.  A
module should typically cast this to an internal type for the state
object.

A module can create a per-request state object by returning one in the
\textbf{verify} method, receiving it in the \textbf{return\_padata} method, and
destroying it in the \textbf{free\_modreq} method.  Note that these state
objects only apply to the processing of a single AS request packet,
not to an entire authentication exchange (since an authentication
exchange may remain unfinished by the client or may involve multiple
different KDC hosts).  Per-request state objects have the type
krb5\_kdcpreauth\_modreq, which is an abstract pointer type.

The \textbf{edata}, \textbf{verify}, and \textbf{return\_padata} methods have access
to a callback function and handle (called a ``rock'') which can be used
to get additional information about the current request, including the
maximum allowable clock skew, the client's long-term keys, the
DER-encoded request body, the FAST armor key, string attributes on the
client's database entry, and the client's database entry itself.  The
\textbf{verify} method can assert one or more authentication indicators to
be included in the issued ticket using the \code{add\_auth\_indicator}
callback (new in release 1.14).

A module can generate state information to be included with the next
client request using the \code{set\_cookie} callback (new in release
1.14).  On the next request, the module can read this state
information using the \code{get\_cookie} callback.  Cookie information is
encrypted, timestamped, and transmitted to the client in a
\code{PA-FX-COOKIE} pa-data item.  Older clients may not support cookies
and therefore may not transmit the cookie in the next request; in this
case, \code{get\_cookie} will not yield the saved information.

If a module implements a mechanism which requires multiple round
trips, its \textbf{verify} method can respond with the code
\code{KRB5KDC\_ERR\_MORE\_PREAUTH\_DATA\_REQUIRED} and a list of pa-data in
the \emph{e\_data} parameter to be processed by the client.

The \textbf{edata} and \textbf{verify} methods can be implemented
asynchronously.  Because of this, they do not return values directly
to the caller, but must instead invoke responder functions with their
results.  A synchronous implementation can invoke the responder
function immediately.  An asynchronous implementation can use the
callback to get an event context for use with the \href{https://fedorahosted.org/libverto/}{libverto} API.


\section{Credential cache selection interface (ccselect)}
\label{plugindev/ccselect:credential-cache-selection-interface-ccselect}\label{plugindev/ccselect::doc}\label{plugindev/ccselect:ccselect-plugin}
The ccselect interface allows modules to control how credential caches
are chosen when a GSSAPI client contacts a service.  For a detailed
description of the ccselect interface, see the header file
\code{\textless{}krb5/ccselect\_plugin.h\textgreater{}}.

The primary ccselect method is \textbf{choose}, which accepts a server
principal as input and returns a ccache and/or principal name as
output.  A module can use the krb5\_cccol APIs to iterate over the
cache collection in order to find an appropriate ccache to use.

A module can create and destroy per-library-context state objects by
implementing the \textbf{init} and \textbf{fini} methods.  State objects have
the type krb5\_ccselect\_moddata, which is an abstract pointer type.  A
module should typically cast this to an internal type for the state
object.

A module can have one of two priorities, ``authoritative'' or
``heuristic''.  Results from authoritative modules, if any are
available, will take priority over results from heuristic modules.  A
module communicates its priority as a result of the \textbf{init} method.


\section{Password quality interface (pwqual)}
\label{plugindev/pwqual::doc}\label{plugindev/pwqual:password-quality-interface-pwqual}\label{plugindev/pwqual:pwqual-plugin}
The pwqual interface allows modules to control what passwords are
allowed when a user changes passwords.  For a detailed description of
the pwqual interface, see the header file \code{\textless{}krb5/pwqual\_plugin.h\textgreater{}}.

The primary pwqual method is \textbf{check}, which receives a password as
input and returns success (0) or a \code{KADM5\_PASS\_Q\_} failure code
depending on whether the password is allowed.  The \textbf{check} method
also receives the principal name and the name of the principal's
password policy as input; although there is no stable interface for
the module to obtain the fields of the password policy, it can define
its own configuration or data store based on the policy name.

A module can create and destroy per-process state objects by
implementing the \textbf{open} and \textbf{close} methods.  State objects have
the type krb5\_pwqual\_moddata, which is an abstract pointer type.  A
module should typically cast this to an internal type for the state
object.  The \textbf{open} method also receives the name of the realm's
dictionary file (as configured by the \textbf{dict\_file} variable in the
\emph{kdc\_realms} section of \emph{kdc.conf(5)}) if it wishes to use
it.


\section{KADM5 hook interface (kadm5\_hook)}
\label{plugindev/kadm5_hook:kadm5-hook-interface-kadm5-hook}\label{plugindev/kadm5_hook::doc}\label{plugindev/kadm5_hook:kadm5-hook-plugin}
The kadm5\_hook interface allows modules to perform actions when
changes are made to the Kerberos database through \emph{kadmin(1)}.
For a detailed description of the kadm5\_hook interface, see the header
file \code{\textless{}krb5/kadm5\_hook\_plugin.h\textgreater{}}.

The kadm5\_hook interface has five primary methods: \textbf{chpass},
\textbf{create}, \textbf{modify}, \textbf{remove}, and \textbf{rename}.  (The \textbf{rename}
method was introduced in release 1.14.)  Each of these methods is
called twice when the corresponding administrative action takes place,
once before the action is committed and once afterwards.  A module can
prevent the action from taking place by returning an error code during
the pre-commit stage.

A module can create and destroy per-process state objects by
implementing the \textbf{init} and \textbf{fini} methods.  State objects have
the type kadm5\_hook\_modinfo, which is an abstract pointer type.  A
module should typically cast this to an internal type for the state
object.

Because the kadm5\_hook interface is tied closely to the kadmin
interface (which is explicitly unstable), it may not remain as stable
across versions as other public pluggable interfaces.


\section{kadmin authorization interface (kadm5\_auth)}
\label{plugindev/kadm5_auth:kadm5-auth-plugin}\label{plugindev/kadm5_auth:kadmin-authorization-interface-kadm5-auth}\label{plugindev/kadm5_auth::doc}
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 \code{\textless{}krb5/kadm5\_auth\_plugin.h\textgreater{}}.

A module can create and destroy per-process state objects by
implementing the \textbf{init} and \textbf{fini} methods.  State objects have
the type kadm5\_auth\_modinfo, which is an abstract pointer type.  A
module should typically cast this to an internal type for the state
object.

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.

The \textbf{addprinc} and \textbf{modprinc} methods can also impose restrictions
on the principal operation by returning a \code{struct
kadm5\_auth\_restrictions} object.  The module should also implement
the \textbf{free\_restrictions} method if it dynamically allocates
restrictions objects for principal operations.

kadm5\_auth modules can optionally inspect principal or policy objects.
To do this, the module must also include \code{\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.


\section{Host-to-realm interface (hostrealm)}
\label{plugindev/hostrealm:hostrealm-plugin}\label{plugindev/hostrealm::doc}\label{plugindev/hostrealm:host-to-realm-interface-hostrealm}
The host-to-realm interface was first introduced in release 1.12.  It
allows modules to control the local mapping of hostnames to realm
names as well as the default realm.  For a detailed description of the
hostrealm interface, see the header file
\code{\textless{}krb5/hostrealm\_plugin.h\textgreater{}}.

Although the mapping methods in the hostrealm interface return a list
of one or more realms, only the first realm in the list is currently
used by callers.  Callers may begin using later responses in the
future.

Any mapping method may return KRB5\_PLUGIN\_NO\_HANDLE to defer
processing to a later module.

A module can create and destroy per-library-context state objects
using the \textbf{init} and \textbf{fini} methods.  If the module does not need
any state, it does not need to implement these methods.

The optional \textbf{host\_realm} method allows a module to determine
authoritative realm mappings for a hostname.  The first authoritative
mapping is used in preference to KDC referrals when getting service
credentials.

The optional \textbf{fallback\_realm} method allows a module to determine
fallback mappings for a hostname.  The first fallback mapping is tried
if there is no authoritative mapping for a realm, and KDC referrals
failed to produce a successful result.

The optional \textbf{default\_realm} method allows a module to determine the
local default realm.

If a module implements any of the above methods, it must also
implement \textbf{free\_list} to ensure that memory is allocated and
deallocated consistently.


\section{Local authorization interface (localauth)}
\label{plugindev/localauth:local-authorization-interface-localauth}\label{plugindev/localauth:localauth-plugin}\label{plugindev/localauth::doc}
The localauth interface was first introduced in release 1.12.  It
allows modules to control the relationship between Kerberos principals
and local system accounts.  When an application calls
\code{krb5\_kuserok()} or \code{krb5\_aname\_to\_localname()}, localauth
modules are consulted to determine the result.  For a detailed
description of the localauth interface, see the header file
\code{\textless{}krb5/localauth\_plugin.h\textgreater{}}.

A module can create and destroy per-library-context state objects
using the \textbf{init} and \textbf{fini} methods.  If the module does not need
any state, it does not need to implement these methods.

The optional \textbf{userok} method allows a module to control the behavior
of \code{krb5\_kuserok()}.  The module receives the authenticated name
and the local account name as inputs, and can return either 0 to
authorize access, KRB5\_PLUGIN\_NO\_HANDLE to defer the decision to other
modules, or another error (canonically EPERM) to authoritatively deny
access.  Access is granted if at least one module grants access and no
module authoritatively denies access.

The optional \textbf{an2ln} method can work in two different ways.  If the
module sets an array of uppercase type names in \textbf{an2ln\_types}, then
the module's \textbf{an2ln} method will only be invoked by
\code{krb5\_aname\_to\_localname()} if an \textbf{auth\_to\_local} value in
\emph{krb5.conf(5)} refers to one of the module's types.  In this
case, the \emph{type} and \emph{residual} arguments will give the type name and
residual string of the \textbf{auth\_to\_local} value.

If the module does not set \textbf{an2ln\_types} but does implement
\textbf{an2ln}, the module's \textbf{an2ln} method will be invoked for all
\code{krb5\_aname\_to\_localname()} operations unless an earlier module
determines a mapping, with \emph{type} and \emph{residual} set to NULL.  The
module can return KRB5\_LNAME\_NO\_TRANS to defer mapping to later
modules.

If a module implements \textbf{an2ln}, it must also implement
\textbf{free\_string} to ensure that memory is allocated and deallocated
consistently.


\section{Server location interface (locate)}
\label{plugindev/locate:server-location-interface-locate}\label{plugindev/locate::doc}
The locate interface allows modules to control how KDCs and similar
services are located by clients.  For a detailed description of the
ccselect interface, see the header file \code{\textless{}krb5/locate\_plugin.h\textgreater{}}.

A locate module exports a structure object of type
krb5plugin\_service\_locate\_ftable, with the name \code{service\_locator}.
The structure contains a minor version and pointers to the module's
methods.

The primary locate method is \textbf{lookup}, which accepts a service type,
realm name, desired socket type, and desired address family (which
will be AF\_UNSPEC if no specific address family is desired).  The
method should invoke the callback function once for each server
address it wants to return, passing a socket type (SOCK\_STREAM for TCP
or SOCK\_DGRAM for UDP) and socket address.  The \textbf{lookup} method
should return 0 if it has authoritatively determined the server
addresses for the realm, KRB5\_PLUGIN\_NO\_HANDLE if it wants to let
other location mechanisms determine the server addresses, or another
code if it experienced a failure which should abort the location
process.

A module can create and destroy per-library-context state objects by
implementing the \textbf{init} and \textbf{fini} methods.  State objects have
the type void *, and should be cast to an internal type for the state
object.


\section{Configuration interface (profile)}
\label{plugindev/profile:configuration-interface-profile}\label{plugindev/profile::doc}\label{plugindev/profile:profile-plugin}
The profile interface allows a module to control how krb5
configuration information is obtained by the Kerberos library and
applications.  For a detailed description of the profile interface,
see the header file \code{\textless{}profile.h\textgreater{}}.

\begin{notice}{note}{Note:}
The profile interface does not follow the normal conventions
for MIT krb5 pluggable interfaces, because it is part of a
lower-level component of the krb5 library.
\end{notice}

As with other types of plugin modules, a profile module is a Unix
shared object or Windows DLL, built separately from the krb5 tree.
The krb5 library will dynamically load and use a profile plugin module
if it reads a \code{module} directive at the beginning of krb5.conf, as
described in \emph{profile\_plugin\_config}.

A profile module exports a function named \code{profile\_module\_init}
matching the signature of the profile\_module\_init\_fn type.  This
function accepts a residual string, which may be used to help locate
the configuration source.  The function fills in a vtable and may also
create a per-profile state object.  If the module uses state objects,
it should implement the \textbf{copy} and \textbf{cleanup} methods to manage
them.

A basic read-only profile module need only implement the
\textbf{get\_values} and \textbf{free\_values} methods.  The \textbf{get\_values} method
accepts a null-terminated list of C string names (e.g., an array
containing ``libdefaults'', ``clockskew'', and NULL for the \textbf{clockskew}
variable in the \emph{libdefaults} section) and returns a
null-terminated list of values, which will be cleaned up with the
\textbf{free\_values} method when the caller is done with them.

Iterable profile modules must also define the \textbf{iterator\_create},
\textbf{iterator}, \textbf{iterator\_free}, and \textbf{free\_string} methods.  The
core krb5 code does not require profiles to be iterable, but some
applications may iterate over the krb5 profile object in order to
present configuration interfaces.

Writable profile modules must also define the \textbf{writable},
\textbf{modified}, \textbf{update\_relation}, \textbf{rename\_section},
\textbf{add\_relation}, and \textbf{flush} methods.  The core krb5 code does not
require profiles to be writable, but some applications may write to
the krb5 profile in order to present configuration interfaces.

The following is an example of a very basic read-only profile module
which returns a hardcoded value for the \textbf{default\_realm} variable in
\emph{libdefaults}, and provides no other configuration information.
(For conciseness, the example omits code for checking the return
values of malloc and strdup.)

\begin{Verbatim}[commandchars=\\\{\}]
\PYGZsh{}include \PYGZlt{}stdlib.h\PYGZgt{}
\PYGZsh{}include \PYGZlt{}string.h\PYGZgt{}
\PYGZsh{}include \PYGZlt{}profile.h\PYGZgt{}

static long
get\PYGZus{}values(void *cbdata, const char *const *names, char ***values)
\PYGZob{}
    if (names[0] != NULL \PYGZam{}\PYGZam{} strcmp(names[0], \PYGZdq{}libdefaults\PYGZdq{}) == 0 \PYGZam{}\PYGZam{}
        names[1] != NULL \PYGZam{}\PYGZam{} strcmp(names[1], \PYGZdq{}default\PYGZus{}realm\PYGZdq{}) == 0) \PYGZob{}
        *values = malloc(2 * sizeof(char *));
        (*values)[0] = strdup(\PYGZdq{}ATHENA.MIT.EDU\PYGZdq{});
        (*values)[1] = NULL;
        return 0;
    \PYGZcb{}
    return PROF\PYGZus{}NO\PYGZus{}RELATION;
\PYGZcb{}

static void
free\PYGZus{}values(void *cbdata, char **values)
\PYGZob{}
    char **v;

    for (v = values; *v; v++)
        free(*v);
    free(values);
\PYGZcb{}

long
profile\PYGZus{}module\PYGZus{}init(const char *residual, struct profile\PYGZus{}vtable *vtable,
                    void **cb\PYGZus{}ret);

long
profile\PYGZus{}module\PYGZus{}init(const char *residual, struct profile\PYGZus{}vtable *vtable,
                    void **cb\PYGZus{}ret)
\PYGZob{}
    *cb\PYGZus{}ret = NULL;
    vtable\PYGZhy{}\PYGZgt{}get\PYGZus{}values = get\PYGZus{}values;
    vtable\PYGZhy{}\PYGZgt{}free\PYGZus{}values = free\PYGZus{}values;
    return 0;
\PYGZcb{}
\end{Verbatim}


\section{GSSAPI mechanism interface}
\label{plugindev/gssapi::doc}\label{plugindev/gssapi:gssapi-mechanism-interface}
The GSSAPI library in MIT krb5 can load mechanism modules to augment
the set of built-in mechanisms.

A mechanism module is a Unix shared object or Windows DLL, built
separately from the krb5 tree.  Modules are loaded according to the
\code{/etc/gss/mech} or \code{/etc/gss/mech.d/*.conf} config files, as
described in \emph{gssapi\_plugin\_config}.

For the most part, a GSSAPI mechanism module exports the same
functions as would a GSSAPI implementation itself, with the same
function signatures.  The mechanism selection layer within the GSSAPI
library (called the ``mechglue'') will dispatch calls from the
application to the module if the module's mechanism is requested.  If
a module does not wish to implement a GSSAPI extension, it can simply
refrain from exporting it, and the mechglue will fail gracefully if
the application calls that function.

The mechglue does not invoke a module's \textbf{gss\_add\_cred},
\textbf{gss\_add\_cred\_from}, \textbf{gss\_add\_cred\_impersonate\_name}, or
\textbf{gss\_add\_cred\_with\_password} function.  A mechanism only needs to
implement the ``acquire'' variants of those functions.

A module does not need to coordinate its minor status codes with those
of other mechanisms.  If the mechglue detects conflicts, it will map
the mechanism's status codes onto unique values, and then map them
back again when \textbf{gss\_display\_status} is called.


\subsection{Interposer modules}
\label{plugindev/gssapi:interposer-modules}
The mechglue also supports a kind of loadable module, called an
interposer module, which intercepts calls to existing mechanisms
rather than implementing a new mechanism.

An interposer module must export the symbol \textbf{gss\_mech\_interposer}
with the following signature:

\begin{Verbatim}[commandchars=\\\{\}]
gss\PYGZus{}OID\PYGZus{}set gss\PYGZus{}mech\PYGZus{}interposer(gss\PYGZus{}OID mech\PYGZus{}type);
\end{Verbatim}

This function is invoked with the OID of the interposer mechanism as
specified in \code{/etc/gss/mech} or in a \code{/etc/gss/mech.d/*.conf}
file, and returns a set of mechanism OIDs to be interposed.  The
returned OID set must have been created using the mechglue's
gss\_create\_empty\_oid\_set and gss\_add\_oid\_set\_member functions.

An interposer module must use the prefix \code{gssi\_} for the GSSAPI
functions it exports, instead of the prefix \code{gss\_}.

An interposer module can link against the GSSAPI library in order to
make calls to the original mechanism.  To do so, it must specify a
special mechanism OID which is the concatention of the interposer's
own OID byte string and the original mechanism's OID byte string.

Since \textbf{gss\_accept\_sec\_context} does not accept a mechanism argument,
an interposer mechanism must, in order to invoke the original
mechanism's function, acquire a credential for the concatenated OID
and pass that as the \emph{verifier\_cred\_handle} parameter.

Since \textbf{gss\_import\_name}, \textbf{gss\_import\_cred}, and
\textbf{gss\_import\_sec\_context} do not accept mechanism parameters, the SPI
has been extended to include variants which do.  This allows the
interposer module to know which mechanism should be used to interpret
the token.  These functions have the following signatures:

\begin{Verbatim}[commandchars=\\\{\}]
OM\PYGZus{}uint32 gssi\PYGZus{}import\PYGZus{}sec\PYGZus{}context\PYGZus{}by\PYGZus{}mech(OM\PYGZus{}uint32 *minor\PYGZus{}status,
    gss\PYGZus{}OID desired\PYGZus{}mech, gss\PYGZus{}buffer\PYGZus{}t interprocess\PYGZus{}token,
    gss\PYGZus{}ctx\PYGZus{}id\PYGZus{}t *context\PYGZus{}handle);

OM\PYGZus{}uint32 gssi\PYGZus{}import\PYGZus{}name\PYGZus{}by\PYGZus{}mech(OM\PYGZus{}uint32 *minor\PYGZus{}status,
    gss\PYGZus{}OID mech\PYGZus{}type, gss\PYGZus{}buffer\PYGZus{}t input\PYGZus{}name\PYGZus{}buffer,
    gss\PYGZus{}OID input\PYGZus{}name\PYGZus{}type, gss\PYGZus{}name\PYGZus{}t output\PYGZus{}name);

OM\PYGZus{}uint32 gssi\PYGZus{}import\PYGZus{}cred\PYGZus{}by\PYGZus{}mech(OM\PYGZus{}uint32 *minor\PYGZus{}status,
    gss\PYGZus{}OID mech\PYGZus{}type, gss\PYGZus{}buffer\PYGZus{}t token,
    gss\PYGZus{}cred\PYGZus{}id\PYGZus{}t *cred\PYGZus{}handle);
\end{Verbatim}

To re-enter the original mechanism when importing tokens for the above
functions, the interposer module must wrap the mechanism token in the
mechglue's format, using the concatenated OID.  The mechglue token
formats are:
\begin{itemize}
\item {} 
For \textbf{gss\_import\_sec\_context}, a four-byte OID length in big-endian
order, followed by the mechanism OID, followed by the mechanism
token.

\item {} 
For \textbf{gss\_import\_name}, the bytes 04 01, followed by a two-byte OID
length in big-endian order, followed by the mechanism OID, followed
by the bytes 06, followed by the OID length as a single byte,
followed by the mechanism OID, followed by the mechanism token.

\item {} 
For \textbf{gss\_import\_cred}, a four-byte OID length in big-endian order,
followed by the mechanism OID, followed by a four-byte token length
in big-endian order, followed by the mechanism token.  This sequence
may be repeated multiple times.

\end{itemize}


\section{Internal pluggable interfaces}
\label{plugindev/internal::doc}\label{plugindev/internal:internal-pluggable-interfaces}
Following are brief discussions of pluggable interfaces which have not
yet been made public.  These interfaces are functional, but the
interfaces are likely to change in incompatible ways from release to
release.  In some cases, it may be necessary to copy header files from
the krb5 source tree to use an internal interface.  Use these with
care, and expect to need to update your modules for each new release
of MIT krb5.


\subsection{Kerberos database interface (KDB)}
\label{plugindev/internal:kerberos-database-interface-kdb}
A KDB module implements a database back end for KDC principal and
policy information, and can also control many aspects of KDC behavior.
For a full description of the interface, see the header file
\code{\textless{}kdb.h\textgreater{}}.

The KDB pluggable interface is often referred to as the DAL (Database
Access Layer).


\subsection{Authorization data interface (authdata)}
\label{plugindev/internal:authorization-data-interface-authdata}
The authdata interface allows a module to provide (from the KDC) or
consume (in application servers) authorization data of types beyond
those handled by the core MIT krb5 code base.  The interface is
defined in the header file \code{\textless{}krb5/authdata\_plugin.h\textgreater{}}, which is not
installed by the build.


\section{PKINIT certificate authorization interface (certauth)}
\label{plugindev/certauth:certauth-plugin}\label{plugindev/certauth::doc}\label{plugindev/certauth:pkinit-certificate-authorization-interface-certauth}
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
\code{\textless{}krb5/certauth\_plugin.h\textgreater{}}

A certauth module implements the \textbf{authorize} method to determine
whether a client's certificate is authorized to authenticate a client
principal.  \textbf{authorize} receives the DER-encoded certificate, the
requested client principal, and a pointer to the client's
krb5\_db\_entry (for modules that link against libkdb5).  It returns the
authorization status and optionally outputs a list of authentication
indicator strings to be added to the ticket.  A module must use its
own internal or library-provided ASN.1 certificate decoder.

A module can optionally create and destroy module data with the
\textbf{init} and \textbf{fini} methods.  Module data objects last for the
lifetime of the KDC process.

If a module allocates and returns a list of authentication indicators
from \textbf{authorize}, it must also implement the \textbf{free\_ind} method
to free the list.


\section{KDC policy interface (kdcpolicy)}
\label{plugindev/kdcpolicy:kdcpolicy-plugin}\label{plugindev/kdcpolicy::doc}\label{plugindev/kdcpolicy:kdc-policy-interface-kdcpolicy}
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
\code{\textless{}krb5/kdcpolicy\_plugin.h\textgreater{}}.

The optional \textbf{check\_as} and \textbf{check\_tgs} functions allow the module
to perform access control.  Additionally, a module can create and
destroy module data with the \textbf{init} and \textbf{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.

kdcpolicy modules can optionally inspect principal entries.  To do
this, the module must also include \code{\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}