kadmin 0.7.2

Rust bindings for the Kerberos administration interface (kadm5)
Documentation
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
kadmin
======

.. py:module:: kadmin

.. py:class:: KAdm5Variant

   kadm5 library variant

   Represent a kadm5 library to use. This struct will determine which C library kadmin will link
   against. The list of currently supported options consist of the enum variants.

   Depending on how kadmin was compiled, not all variants may be supported on your system. Refer
   to the package documentation on how to compile for all possible options.

   .. py:attribute:: MitClient

      MIT krb5 client-side library

      :type: KAdm5Variant

   .. py:attribute:: MitServer

      MIT krb5 server-side library

      :type: KAdm5Variant

   .. py:attribute:: HeimdalClient

      Heimdal client-side library

      :type: KAdm5Variant

   .. py:attribute:: HeimdalServer

      Heimdal server-side library

      :type: KAdm5Variant

.. py:class:: KAdminApiVersion

   kadm5 API version

   MIT krb5 supports up to version 4. Heimdal supports up to version 2.

   This changes which fields will be available in the Policy and Principal structs. If the version
   is too low, some fields may not be populated. We try our best to document those in the fields
   documentation themselves.

   If no version is provided during the KAdmin initialization, it defaults to the most conservative
   one, currently version 2.

   .. py:attribute:: Version2

      Version 2

      :type: KAdminApiVersion

   .. py:attribute:: Version3

      Version 3

      :type: KAdminApiVersion

   .. py:attribute:: Version4

      Version 4

      :type: KAdminApiVersion

.. py:class:: KAdmin

   Interface to kadm5
   
   This class has no constructor. Instead, use the `with_` methods

   .. py:staticmethod:: with_password(variant, client_name, password, params=None, db_args=None, api_version=None, library_path=None)

      Construct a KAdmin object using a password
      
      :param variant: Which kadm5 variant to use
      :type variant: KAdm5Variant
      :param client_name: client name, usually a principal name
      :type client_name: str
      :param password: password to authenticate with
      :type password: str
      :param params: additional kadm5 config options
      :type params: Params | None
      :param db_args: additional database specific arguments
      :type db_args: DbArgs | None
      :param api_version: kadm5 API version to use
      :type api_version: KAdminApiVersion | None
      :param library_path: path to libkadm5.so to load
      :type library_path: str | None
      :return: an initialized :py:class:`KAdmin` object
      :rtype: KAdmin
      
      .. code-block:: python
      
         kadm = KAdmin.with_password("user@EXAMPLE.ORG", "vErYsEcUrE")

   .. py:staticmethod:: with_keytab(variant, client_name=None, keytab=None, params=None, db_args=None, library_path=None)

      Construct a KAdmin object using a keytab
      
      :param variant: Which kadm5 variant to use
      :type variant: KAdm5Variant
      :param client_name: client name, usually a principal name. If not provided,
          `host/hostname` will be used
      :type client_name: str | None
      :param keytab: path to the keytab to use. If not provided, the default keytab will be
          used
      :type keytab: str | None
      :param params: additional kadm5 config options
      :type params: Params | None
      :param db_args: additional database specific arguments
      :type db_args: DbArgs | None
      :param api_version: kadm5 API version to use
      :type api_version: KAdminApiVersion | None
      :param library_path: path to libkadm5.so to load
      :type library_path: str | None
      :return: an initialized :py:class:`KAdmin` object
      :rtype: KAdmin

   .. py:staticmethod:: with_ccache(variant, client_name=None, ccache_name=None, params=None, db_args=None, library_path=None)

      Construct a KAdmin object using a credentials cache
      
      :param variant: Which kadm5 variant to use
      :type variant: KAdm5Variant
      :param client_name: client name, usually a principal name. If not provided, the default
          principal from the credentials cache will be used
      :type client_name: str | None
      :param ccache_name: credentials cache name. If not provided, the default credentials
          cache will be used
      :type ccache_name: str | None
      :param params: additional kadm5 config options
      :type params: Params | None
      :param db_args: additional database specific arguments
      :type db_args: DbArgs | None
      :param api_version: kadm5 API version to use
      :type api_version: KAdminApiVersion | None
      :param library_path: path to libkadm5.so to load
      :type library_path: str | None
      :return: an initialized :py:class:`KAdmin` object
      :rtype: KAdmin

   .. py:staticmethod:: with_anonymous(variant, client_name, params=None, db_args=None, library_path=None)

      Not implemented

   .. py:staticmethod:: with_local(variant, params=None, db_args=None, api_version=None, library_path=None)

      Construct a :py:class:`KAdmin` object for local database manipulation.
      
      :param variant: Which kadm5 variant to use
      :type variant: KAdm5Variant
      :param params: additional kadm5 config options
      :type params: :py:class:`Params<kadmin.Params>` | None
      :param db_args: additional database specific arguments
      :type db_args: :py:class:`DbArgs<kadmin.DbArgs>` | None
      :param api_version: kadm5 API version to use
      :type api_version: :py:class:`KAdminApiVersion<kadmin.KAdminApiVersion>` | None
      :param library_path: path to libkadm5.so to load
      :type library_path: str | None
      :return: an initialized :py:class:`KAdmin` object
      :rtype: KAdmin

   .. py:method:: add_principal(name, **kwargs)

      Create a principal

      :param name: the name of the principal to create
      :type name: str
      :param kwargs: Extra args for the creation. The name of those arguments must match the
          attributes name of the :py:class:`Principal` class that are not marked as read-only.
          Same goes for their types.
      :return: the newly created :py:class:`Principal`
      :rtype: Principal

      In addition, the following arguments are available

      :param db_args: database specific arguments
      :type db_args: DbArgs
      :param key: how to set the principal key
      :type key: NewPrincipalKey
      :param keysalts: Use the specified keysalt list for setting the keys of the principal
      :type keysalts: KeySalts

   .. py:method:: rename_principal(old_name, new_name)

      Rename a principal

      :param old_name: the current name of the principal
      :type old_name: str
      :param new_name: the new name of the principal
      :type old_name: str

   .. py:method:: delete_principal(name)

      Delete a principal
      
      :py:meth:`Principal.delete` is also available
      
      :param name: name of the principal to delete
      :type name: str

   .. py:method:: get_principal(name)

      Retrieve a principal
      
      :param name: principal name to retrieve
      :type name: str
      :return: :py:class:`Principal` if found, None otherwise
      :rtype: Principal | None

   .. py:method:: principal_exists(name)

      Check if a principal exists
      
      :param name: principal name to check for
      :type name: str
      :return: `True` if the principal exists, `False` otherwise
      :rtype: bool

   .. py:method:: principal_change_password(name, password, keepold=None, keysalts=None)

      Change the password of a principal
      
      :py:meth:`Principal.change_password` is also available
      
      :param name: name of the principal to change the password of
      :type name: str
      :param password: the new password
      :type password: str
      :param keepold: Keeps the existing keys in the database. This flag is usually not necessary except
         perhaps for krbtgt principals. Defaults to false. With Heimdal client, this option is silently
         ignored
      :type keepold: bool | None
      :param keysalts: Uses the specified keysalt list for setting the keys of the principal. With Heimdal
         client, this option is silently ignored
      :type keysalts: KeySalts | None

   .. py:method:: principal_randkey(name, keepold=None, keysalts=None)

      Sets the key of the principal to a random value
      
      :py:meth:`Principal.randkey` is also available
      
      :param name: name of the principal to randomize the key of
      :type name: str
      :param keepold: Keeps the existing keys in the database. This flag is usually not necessary except
         perhaps for krbtgt principals. Defaults to false. With Heimdal client, this option is silently
         ignored
      :type keepold: bool | None
      :param keysalts: Uses the specified keysalt list for setting the keys of the principal. With Heimdal
         client, this option is silently ignored
      :type keysalts: KeySalts | None

   .. py:method:: principal_get_strings(name)

      Retrieve string attributes on this principal

      Only available for MIT variants

      :param name: name of the principal to randomize the key of
      :type name: str
      :return: a dictionary containing the string attributes set on this principal
      :rtype: dict[str, str]

   .. py:method:: principal_set_string(name, key, value)

      Set string attribute on this principal

      Only available for MIT variants

      :param name: name of the principal to randomize the key of
      :type name: str
      :param key: The string key
      :type key: str
      :param value: The string value. Set to None to remove the attribute
      :type value: str | None

   .. py:method:: list_principals(query=None)

      List principals
      
      :param query: a shell-style glob expression that can contain the wild-card characters
          `?`, `*`, and `[]`. All principal names matching the expression are retuned. If
          the expression does not contain an `@` character, an `@` character followed by
          the local realm is appended to the expression. If no query is provided, all
          principals are returned.
      :type query: str, optional
      :return: the list of principal names matching the query
      :rtype: list[str]

   .. py:method:: add_policy(name, **kwargs)

      Create a policy

      Only available for MIT and Heimdal server-side libraries.
      
      :param name: the name of the policy to create
      :type name: str
      :param kwargs: Extra args for the creation. The name of those arguments must match the
          attributes name of the :py:class:`Policy` class. Same goes for their types.
      :return: the newly created :py:class:`Policy`
      :rtype: Policy

   .. py:method:: delete_policy(name)

      Delete a policy

      Only available for MIT and Heimdal server-side libraries.
      
      :py:meth:`Policy.delete` is also available
      
      :param name: name of the policy to delete
      :type name: str

   .. py:method:: get_policy(name)

      Retrieve a policy

      Only available for MIT and Heimdal server-side libraries.
      
      :param name: policy name to retrieve
      :type name: str
      :return: :py:class:`Policy` if found, None otherwise
      :rtype: Policy | None

   .. py:method:: policy_exists(name)

      Check if a policy exists

      Only available for MIT and Heimdal server-side libraries.
      
      :param name: policy name to check for
      :type name: str
      :return: `True` if the policy exists, `False` otherwise
      :rtype: bool

   .. py:method:: list_policies(query=None)

      List policies

      Only available for MIT and Heimdal server-side libraries.
      
      :param query: a shell-style glob expression that can contain the wild-card characters
          `?`, `*`, and `[]`. All policy names matching the expression are returned.
          If no query is provided, all existing policy names are returned.
      :type query: str | None
      :return: the list of policy names matching the query
      :rtype: list[str]

   .. py:method:: get_privileges()

      Get current privileges

      :return: The current session privileges
      :rtype: int

.. py:class:: Principal

   .. py:attribute:: name

      Principal name

      :type: str

   .. py:attribute:: expire_time

      When the principal expires

      :type: datetime.datetime | None

   .. py:attribute:: last_password_change

      When the password was last changed

      Read-only

      :type: datetime.datetime | None

   .. py:attribute:: password_expiration

      When the password expires

      :type: datetime.datetime | None

   .. py:attribute:: max_life

      Maximum ticket life

      :type: datetime.timedelta | None

   .. py:attribute:: modified_by

      Last principal to modify this principal

      Read-only

      :type: str

   .. py:attribute:: modified_at

      When the principal was last modified

      Read-only

      :type: datetime.datetime | None

   .. py:attribute:: attributes

      Principal attributes

      :type: int

   .. py:attribute:: kvno

      Current key version number

      Read-only, but can be set on principal creation

      :type: int

   .. py:attribute:: mkvno

      Master key version number

      Read-only

      :type: int

   .. py:attribute:: policy

      Associated policy

      :type: str | None

   .. py:attribute:: aux_attributes

      Extra attributes

      :type: int

   .. py:attribute:: max_renewable_life

      Maximum renewable ticket life

      :type: datetime.timedelta | None

   .. py:attribute:: last_success

      When the last successful authentication occurred

      Read-only

      :type: datetime.datetime | None

   .. py:attribute:: last_failed

      When the last failed authentication occurred

      Read-only

      :type: datetime.datetime | None

   .. py:attribute:: fail_auth_count

      Number of failed authentication attempts

      :type: int

   .. py:attribute:: tl_dats

      TL-data

      :type: TlData

   .. py:method:: modify(kadmin, **kwargs)

      Change this principal
      
      :param kadmin: A :py:class:`KAdmin` instance
      :type kadmin: KAdmin
      :param kwargs: Attributes to change. The name of those arguments must match the
          attributes name of the :py:class:`Principal` class that are not marked as read-only.
          Same goes for their types
      :return: a new :py:class:`Principal` object with the modifications made to it. The old
         object is still available, but will not be up-to-date
      :rtype: Principal

   .. py:method:: delete(kadmin)

      Delete this principal
      
      The object will still be available, but shouldn’t be used for modifying, as the policy
      may not exist anymore

      :param kadmin: A :py:class:`KAdmin` instance
      :type kadmin: KAdmin

   .. py:method:: change_password(kadmin, password, keepold=None, keysalts=None)

      Change the password of the principal

      Note that principal data will have changed after this, so you may need to refresh it
      
      :param kadmin: A :py:class:`KAdmin` instance
      :type kadmin: KAdmin
      :param password: the new password
      :type password: str
      :param keepold: Keeps the existing keys in the database. This flag is usually not necessary except
         perhaps for krbtgt principals. Defaults to false. With Heimdal client, this option is silently
         ignored
      :type keepold: bool | None
      :param keysalts: Uses the specified keysalt list for setting the keys of the principal. With Heimdal
         client, this option is silently ignored
      :type keysalts: KeySalts | None

   .. py:method:: randkey(kadmin, keepold=None, keysalts=None)

      Sets the key of the principal to a random value

      Note that principal data will have changed after this, so you may need to refresh it
      
      :param kadmin: A :py:class:`KAdmin` instance
      :type kadmin: KAdmin
      :param keepold: Keeps the existing keys in the database. This flag is usually not necessary except
         perhaps for krbtgt principals. Defaults to false. With Heimdal client, this option is silently
         ignored
      :type keepold: bool | None
      :param keysalts: Uses the specified keysalt list for setting the keys of the principal. With Heimdal
         client, this option is silently ignored
      :type keysalts: KeySalts | None

   .. py:method:: unlock(kadmin)

      Unlocks a locked principal (one which has received too many failed authentication attempts without
      enough time between them according to its password policy) so that it can successfully authenticate

      Note that principal data will have changed after this, so you may need to refresh it
      
      :param kadmin: A :py:class:`KAdmin` instance
      :type kadmin: KAdmin

   .. py:method:: get_strings(kadmin)

      Retrieve string attributes on this principal

      Only available for MIT variants

      :param kadmin: A :py:class:`KAdmin` instance
      :type kadmin: KAdmin
      :return: a dictionary containing the string attributes set on this principal
      :rtype: dict[str, str]

   .. py:method:: set_string(kadmin, key, value)

      Set string attribute on this principal

      Only available for MIT variants

      :param kadmin: A :py:class:`KAdmin` instance
      :type kadmin: KAdmin
      :param key: The string key
      :type key: str
      :param value: The string value. Set to None to remove the attribute
      :type value: str | None

.. py:class:: NewPrincipalKey

   Method to use to set the principal key when creating it

   Passing the class itself is not enough. An object should be created from those subclasses.

   .. py:class:: Password(password)

      Provide a password to use

      :type password: str

   .. py:class:: NoKey()

      No key should be set on the principal

   .. py:class:: RandKey()

      A random key should be generated for the principal. Tries `ServerRandKey` and falls back to `OldStyleRandKey`

   .. py:class:: ServerRandKey()

      A random key should be generated for the principal by the server

   .. py:class:: OldStyleRandKey()

      Old-style random key. Creates the principal with KRB5_KDB_DISALLOW_ALL_TIX and a generated dummy key, then calls randkey on the principal and finally removes KRB5_KDB_DISALLOW_ALL_TIX

.. py:class:: Policy

   Only available for MIT and Heimdal server-side libraries.

   .. py:attribute:: name

      The policy name

      :type: str

   .. py:attribute:: password_min_life

      Minimum lifetime of a password

      :type: datetime.timedelta | None

   .. py:attribute:: password_max_life

      Maximum lifetime of a password

      :type: datetime.timedelta | None

   .. py:attribute:: password_min_length

      Minimum length of a password

      :type: int

   .. py:attribute:: password_min_classes

      Minimum number of character classes required in a password. The five character classes are
      lower case, upper case, numbers, punctuation, and whitespace/unprintable characters

      :type: int

   .. py:attribute:: password_history_num

      Number of past keys kept for a principal. May not be filled if used with other database
      modules such as the MIT krb5 LDAP KDC database module

      :type: int

   .. py:attribute:: policy_refcnt

      How many principals use this policy. Not filled for at least MIT krb5

      :type: int

   .. py:attribute:: password_max_fail

      Number of authentication failures before the principal is locked. Authentication failures
      are only tracked for principals which require preauthentication. The counter of failed
      attempts resets to 0 after a successful attempt to authenticate. A value of 0 disables
      lock‐out

      Only available in :py:class:`version<KAdminApiVersion>` 3 and above

      :type: int

   .. py:attribute:: password_failcount_interval

      Allowable time between authentication failures. If an authentication failure happens after
      this duration has elapsed since the previous failure, the number of authentication failures
      is reset to 1. A value of `None` means forever

      Only available in MIT and :py:class:`version<KAdminApiVersion>` 3 and above

      :type: datetime.timedelta | None

   .. py:attribute:: password_lockout_duration

      Duration for which the principal is locked from authenticating if too many authentication
      failures occur without the specified failure count interval elapsing. A duration of `None`
      means the principal remains locked out until it is administratively unlocked

      Only available in MIT and :py:class:`version<KAdminApiVersion>` 3 and above

      :type: datetime.timedelta | None

   .. py:attribute:: attributes

      Policy attributes

      Only available in MIT and :py:class:`version<KAdminApiVersion>` 4 and above

      :type: int

   .. py:attribute:: max_life

      Maximum ticket life

      Only available in MIT and :py:class:`version<KAdminApiVersion>` 4 and above

      :type: datetime.timedelta | None

   .. py:attribute:: max_renewable_life

      Maximum renewable ticket life

      Only available in MIT and :py:class:`version<KAdminApiVersion>` 4 and above

      :type: datetime.timedelta | None

   .. py:attribute:: allowed_keysalts

      Allowed keysalts

      Only available in MIT and :py:class:`version<KAdminApiVersion>` 4 and above

      :type: KeySalts | None

   .. py:attribute:: tl_data

      TL-data

      Only available in MIT and :py:class:`version<KAdminApiVersion>` 4 and above

      :type: TlData

   .. py:method:: modify(kadmin, **kwargs)

      Change this policy
      
      :param kadmin: A :py:class:`KAdmin` instance
      :type kadmin: KAdmin
      :param kwargs: Attributes to change. The name of those arguments must match the
          attributes name of the :py:class:`Policy` class. Same goes for their types. The
          `name` attribute is ignored.
      :return: a new :py:class:`Policy` object with the modifications made to it. The old
         object is still available, but will not be up-to-date
      :rtype: Policy

   .. py:method:: delete(kadmin)

      Delete this policy
      
      The object will still be available, but shouldn’t be used for modifying, as the policy
      may not exist anymore

      :param kadmin: A :py:class:`KAdmin` instance
      :type kadmin: KAdmin

.. py:class:: Params(realm=None, kadmind_port=None, kpasswd_port=None, admin_server=None, dbname=None, acl_file=None, dict_file=None, stash_file=None)

   kadm5 config options
   
   :param realm: Default realm database
   :type realm: str | None
   :param kadmind_port: kadmind port to connect to
   :type kadmind_port: int | None
   :param kpasswd_port: kpasswd port to connect to. Only available on MIT variants.
   :type kpasswd_port: int | None
   :param admin_server: Admin server which kadmin should contact
   :type admin_server: str | None
   :param dbname: Name of the KDC database
   :type dbname: str | None
   :param acl_file: Location of the access control list file
   :type acl_file: str | None
   :param dict_file: Location of the dictionary file containing strings that are not allowed
      as passwords. Only available on MIT variants.
   :type dict_file: str | None
   :param stash_file: Location where the master key has been stored
   :type stash_file: str | None
   
   .. code-block:: python
   
      params = Params(realm="EXAMPLE.ORG")

.. py:class:: DbArgs(/, *args, **kwargs)

   Database specific arguments
   
   See `man kadmin(1)` for a list of supported arguments
   
   :param \*args: Database arguments (without value)
   :type \*args: str
   :param \**kwargs: Database arguments (with or without value)
   :type \**kwargs: str | None
   
   .. code-block:: python
   
      db_args = DbArgs(host="ldap.example.org")

.. py:class:: EncryptionType(enctype)

   Kerberos encryption type

   :param enctype: Encryption type.
   :type enctype: int

.. py:class:: SaltType(salttype)

   Kerberos salt type

   :param salttype: Salt type.
   :type salttype: int | None

.. py:class:: KeySalt(enctype, salttype)

   Kerberos keysalt

   :param enctype: Encryption type
   :type enctype: EncryptionType
   :param salttype: Salt type
   :type salttype: SaltType

   .. py:attribute:: enctype

      Encryption type

      :type: EncryptionType

   .. py:attribute:: salttype

      Salt type

      :type: SaltType

.. py:class:: KeySalts(keysalts)

   Kerberos keysalt list

   :param keysalts: Keysalt list
   :type keysalts: set[KeySalt]

   .. py:attribute:: keysalts

      Keysalt list

      :type: set[KeySalt]

.. py:class:: TlDataEntry(data_type, contents)

   A single TL-data entry

   :param data_type: Entry type
   :type data_type: int
   :param contents: Entry contents
   :type contents: list[int]

   .. py:attribute:: data_type

      :type: int

   .. py:attribute:: contents

      :type: list[int]

.. py:class:: TlData(entries)

   TL-data entries

   :param entries: TL-data entries
   :type entries: list[TlDataEntry]

   .. py:attribute:: entries

      :type: list[TlDataEntry]