Source file client_cred_cache.ml
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
open! Core
open Async
open Import
type t =
| Single_cache of Internal.Cred_cache.t
| Double_cache of
{ memory_cache : Internal.Cred_cache.t
; default_cache : Internal.Cred_cache.t
}
[@@deriving sexp_of]
let cred_cache = function
| Single_cache cache -> cache
| Double_cache { memory_cache; default_cache = _ } -> memory_cache
;;
let of_cred_cache cred_cache =
let open Deferred.Or_error.Let_syntax in
let%bind principal = Cred_cache.principal cred_cache in
let%bind () =
match Krb_internal_public.Cred_cache.type_ cred_cache with
| `Normal -> Tgt.ensure_valid ~cred_cache ~keytab:User principal
| `S4U2Self _ -> return ()
in
return (Single_cache cred_cache)
;;
let in_memory () =
let%bind principal =
match%bind Cred_cache.default_principal () with
| Ok principal -> return principal
| Error _ ->
let%bind username = Currently_running_user.name () in
return (Principal.Name.User username)
in
let open Deferred.Or_error.Let_syntax in
let%bind memory_cache = Cred_cache.in_memory_for_principal principal in
let%bind default_cache = Internal.Cred_cache.default () in
let%bind () =
Tgt.keep_valid_indefinitely ~cred_cache:memory_cache ~keytab:User principal
in
return (Double_cache { memory_cache; default_cache })
;;
let get_cached ~flags cred_cache ~request =
let open Deferred.Let_syntax in
match%bind
Internal.Cred_cache.get_credentials
~tag_error_with_all_credentials:false
cred_cache
~request
~flags:(Internal.Krb_flags.Get_credentials.KRB5_GC_CACHED :: flags)
with
| Ok x -> return (Ok (Some x))
| Error _ -> return (Ok None)
;;
let get_credentials ~flags t ~request =
let open Deferred.Or_error.Let_syntax in
let with_default_cache_error error d =
Deferred.Or_error.map d ~f:(fun x -> x, `Error_getting_creds_from_default_cache error)
in
match t with
| Single_cache cred_cache ->
Internal.Cred_cache.get_credentials ~flags cred_cache ~request
|> with_default_cache_error None
| Double_cache { memory_cache; default_cache } ->
(match%bind get_cached ~flags memory_cache ~request with
| Some cred -> return cred |> with_default_cache_error None
| None ->
(match%bind.Deferred
Internal.Cred_cache.get_credentials ~flags default_cache ~request
with
| Ok cred ->
let%bind () =
Internal.Cred_cache.store_if_not_in_cache memory_cache ~request cred
in
return cred |> with_default_cache_error None
| Error error ->
Internal.Cred_cache.get_credentials ~flags memory_cache ~request
|> with_default_cache_error (Some error)))
;;
module For_testing = struct
let create ~memory_cache ~default_cache = Double_cache { memory_cache; default_cache }
let cred_caches = function
| Single_cache cache -> [ cache ]
| Double_cache { memory_cache; default_cache } -> [ memory_cache; default_cache ]
;;
end