summaryrefslogtreecommitdiffstats
path: root/krb5-master-rcache-acquirecred-source.patch
blob: 71c38767d446cb6ecb03faf9266c624211280143 (plain)
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
commit 7dad0bee30fbbde8cfc0eacd2d1487c198a004a1
Author: Simo Sorce <simo@redhat.com>
Date:   Thu Dec 26 19:05:34 2013 -0500

    Add rcache feature to gss_acquire_cred_from
    
    The "rcache" cred store entry can specify a replay cache type and name
    to be used with the credentials being acquired.
    
    [ghudson@mit.edu: split up, simplified, and altered to fit preparatory
    commits]
    
    ticket: 7819 (new)

diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
index f625c0c..5d680f9 100644
--- a/src/lib/gssapi/krb5/acquire_cred.c
+++ b/src/lib/gssapi/krb5/acquire_cred.c
@@ -180,7 +180,8 @@ cleanup:
 
 static OM_uint32
 acquire_accept_cred(krb5_context context, OM_uint32 *minor_status,
-                    krb5_keytab req_keytab, krb5_gss_cred_id_rec *cred)
+                    krb5_keytab req_keytab, const char *rcname,
+                    krb5_gss_cred_id_rec *cred)
 {
     OM_uint32 major;
     krb5_error_code code;
@@ -189,6 +190,20 @@ acquire_accept_cred(krb5_context context, OM_uint32 *minor_status,
 
     assert(cred->keytab == NULL);
 
+    /* If we have an explicit rcache name, open it. */
+    if (rcname != NULL) {
+        code = krb5_rc_resolve_full(context, &rc, rcname);
+        if (code) {
+            major = GSS_S_FAILURE;
+            goto cleanup;
+        }
+        code = krb5_rc_recover_or_initialize(context, rc, context->clockskew);
+        if (code) {
+            major = GSS_S_FAILURE;
+            goto cleanup;
+        }
+    }
+
     if (req_keytab != NULL) {
         code = krb5_kt_dup(context, req_keytab, &kt);
     } else {
@@ -221,12 +236,14 @@ acquire_accept_cred(krb5_context context, OM_uint32 *minor_status,
             goto cleanup;
         }
 
-        /* Open the replay cache for this principal. */
-        code = krb5_get_server_rcache(context, &cred->name->princ->data[0],
-                                      &rc);
-        if (code) {
-            major = GSS_S_FAILURE;
-            goto cleanup;
+        if (rc == NULL) {
+            /* Open the replay cache for this principal. */
+            code = krb5_get_server_rcache(context, &cred->name->princ->data[0],
+                                          &rc);
+            if (code) {
+                major = GSS_S_FAILURE;
+                goto cleanup;
+            }
         }
     } else {
         /* Make sure we have a keytab with keys in it. */
@@ -718,8 +735,8 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status,
                      gss_name_t desired_name, gss_buffer_t password,
                      OM_uint32 time_req, gss_cred_usage_t cred_usage,
                      krb5_ccache ccache, krb5_keytab client_keytab,
-                     krb5_keytab keytab, krb5_boolean iakerb,
-                     gss_cred_id_t *output_cred_handle,
+                     krb5_keytab keytab, const char *rcname,
+                     krb5_boolean iakerb, gss_cred_id_t *output_cred_handle,
                      OM_uint32 *time_rec)
 {
     krb5_gss_cred_id_t cred = NULL;
@@ -775,7 +792,7 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status,
      * in cred->name if desired_princ is specified.
      */
     if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) {
-        ret = acquire_accept_cred(context, minor_status, keytab, cred);
+        ret = acquire_accept_cred(context, minor_status, keytab, rcname, cred);
         if (ret != GSS_S_COMPLETE)
             goto error_out;
     }
@@ -867,7 +884,7 @@ acquire_cred(OM_uint32 *minor_status, gss_name_t desired_name,
 
     ret = acquire_cred_context(context, minor_status, desired_name, password,
                                time_req, cred_usage, ccache, NULL, keytab,
-                               iakerb, output_cred_handle, time_rec);
+                               NULL, iakerb, output_cred_handle, time_rec);
 
 out:
     krb5_free_context(context);
@@ -1135,7 +1152,7 @@ krb5_gss_acquire_cred_from(OM_uint32 *minor_status,
     krb5_keytab client_keytab = NULL;
     krb5_keytab keytab = NULL;
     krb5_ccache ccache = NULL;
-    const char *value;
+    const char *rcname, *value;
     OM_uint32 ret;
 
     code = gss_krb5int_initialize_library();
@@ -1191,9 +1208,14 @@ krb5_gss_acquire_cred_from(OM_uint32 *minor_status,
         }
     }
 
+    ret = kg_value_from_cred_store(cred_store, KRB5_CS_RCACHE_URN, &rcname);
+    if (GSS_ERROR(ret))
+        goto out;
+
     ret = acquire_cred_context(context, minor_status, desired_name, NULL,
                                time_req, cred_usage, ccache, client_keytab,
-                               keytab, 0, output_cred_handle, time_rec);
+                               keytab, rcname, 0, output_cred_handle,
+                               time_rec);
 
 out:
     if (ccache != NULL)
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index 0167816..8e4f6d9 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -1260,6 +1260,7 @@ data_to_gss(krb5_data *input_k5data, gss_buffer_t output_buffer)
 #define KRB5_CS_CLI_KEYTAB_URN "client_keytab"
 #define KRB5_CS_KEYTAB_URN "keytab"
 #define KRB5_CS_CCACHE_URN "ccache"
+#define KRB5_CS_RCACHE_URN "rcache"
 
 OM_uint32
 kg_value_from_cred_store(gss_const_key_value_set_t cred_store,