]> git.ipfire.org Git - ipfire-3.x.git/blob - krb5/patches/krb5-trunk-7046.patch
krb5: New package.
[ipfire-3.x.git] / krb5 / patches / krb5-trunk-7046.patch
1 commit 9dc75551cb8cc4c03f7e0fe5e8a705ed678079f4
2 Author: ghudson <ghudson@dc483132-0cff-0310-8789-dd5450dbe970>
3 Date: Wed Dec 7 19:38:13 2011 +0000
4
5 ticket: 7046
6 subject: Allow S4U2Proxy delegated credentials to be saved
7
8 The initial implementation of client-side S4U2Proxy support did not
9 allow delegated proxy credentials to be stored (gss_store_cred would
10 error out, and gss_krb5_copy_ccache would generate a non-working
11 cache). To make this work, we save the impersonator name in a cache
12 config variable and in a cred structure field (replacing the
13 proxy_cred flag), and make the default principal of the proxy cache
14 the subject principal as the caller would expect for a regular
15 delegated cred.
16
17 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25529 dc483132-0cff-0310-8789-dd5450dbe970
18
19 diff --git a/src/include/k5-int.h b/src/include/k5-int.h
20 index 514e2ea..b25c159 100644
21 --- a/src/include/k5-int.h
22 +++ b/src/include/k5-int.h
23 @@ -273,7 +273,10 @@ typedef INT64_TYPE krb5_int64;
24 #define KRB5_CONF_V4_INSTANCE_CONVERT "v4_instance_convert"
25 #define KRB5_CONF_V4_REALM "v4_realm"
26 #define KRB5_CONF_ASTERISK "*"
27 +
28 +/* Cache configuration variables */
29 #define KRB5_CONF_FAST_AVAIL "fast_avail"
30 +#define KRB5_CONF_PROXY_IMPERSONATOR "proxy_impersonator"
31
32 /* Error codes used in KRB_ERROR protocol messages.
33 Return values of library routines are based on a different error table
34 diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
35 index c815b35..c08e059 100644
36 --- a/src/lib/gssapi/krb5/acquire_cred.c
37 +++ b/src/lib/gssapi/krb5/acquire_cred.c
38 @@ -417,6 +417,34 @@ prep_ccache(krb5_context context, krb5_gss_cred_id_rec *cred,
39 return 0;
40 }
41
42 +/* If an impersonator config entry exists in ccache, set *impersonator_out to
43 + * the parsed principal. Otherwise set *impersonator_out to NULL. */
44 +static krb5_error_code
45 +get_impersonator(krb5_context context, krb5_ccache ccache,
46 + krb5_principal *impersonator_out)
47 +{
48 + krb5_error_code code;
49 + krb5_data data = empty_data(), data0 = empty_data();
50 +
51 + *impersonator_out = NULL;
52 +
53 + code = krb5_cc_get_config(context, ccache, NULL,
54 + KRB5_CONF_PROXY_IMPERSONATOR, &data);
55 + if (code)
56 + return (code == KRB5_CC_NOTFOUND) ? 0 : code;
57 +
58 + code = krb5int_copy_data_contents_add0(context, &data, &data0);
59 + if (code)
60 + goto cleanup;
61 +
62 + code = krb5_parse_name(context, data0.data, impersonator_out);
63 +
64 +cleanup:
65 + krb5_free_data_contents(context, &data);
66 + krb5_free_data_contents(context, &data0);
67 + return code;
68 +}
69 +
70 /* Check ccache and scan it for its expiry time. On success, cred takes
71 * ownership of ccache. */
72 static krb5_error_code
73 @@ -493,6 +521,10 @@ scan_ccache(krb5_context context, krb5_gss_cred_id_rec *cred,
74 goto cleanup;
75 }
76
77 + code = get_impersonator(context, ccache, &cred->impersonator);
78 + if (code)
79 + goto cleanup;
80 +
81 (void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE);
82 cred->ccache = ccache;
83
84 @@ -622,6 +654,7 @@ acquire_cred(OM_uint32 *minor_status,
85
86 cred->usage = args->cred_usage;
87 cred->name = NULL;
88 + cred->impersonator = NULL;
89 cred->iakerb_mech = args->iakerb;
90 cred->default_identity = (name == NULL);
91 #ifndef LEAN_CLIENT
92 diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
93 index 016a2e6..6b7d530 100644
94 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h
95 +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
96 @@ -172,7 +172,7 @@ typedef struct _krb5_gss_cred_id_rec {
97 /* name/type of credential */
98 gss_cred_usage_t usage;
99 krb5_gss_name_t name;
100 - unsigned int proxy_cred : 1;
101 + krb5_principal impersonator;
102 unsigned int default_identity : 1;
103 unsigned int iakerb_mech : 1;
104 unsigned int destroy_ccache : 1;
105 diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
106 index 1b8120c..d7b9ffa 100644
107 --- a/src/lib/gssapi/krb5/init_sec_context.c
108 +++ b/src/lib/gssapi/krb5/init_sec_context.c
109 @@ -129,7 +129,6 @@ static krb5_error_code get_credentials(context, cred, server, now,
110 krb5_error_code code;
111 krb5_creds in_creds, evidence_creds, *result_creds = NULL;
112 krb5_flags flags = 0;
113 - krb5_principal cc_princ = NULL;
114
115 *out_creds = NULL;
116
117 @@ -140,16 +139,13 @@ static krb5_error_code get_credentials(context, cred, server, now,
118
119 assert(cred->name != NULL);
120
121 - if ((code = krb5_cc_get_principal(context, cred->ccache, &cc_princ)))
122 - goto cleanup;
123 -
124 /*
125 * Do constrained delegation if we have proxy credentials and
126 * we're not trying to get a ticket to ourselves (in which case
127 * we can just use the S4U2Self or evidence ticket directly).
128 */
129 - if (cred->proxy_cred &&
130 - !krb5_principal_compare(context, cc_princ, server->princ)) {
131 + if (cred->impersonator &&
132 + !krb5_principal_compare(context, cred->impersonator, server->princ)) {
133 krb5_creds mcreds;
134
135 flags |= KRB5_GC_CANONICALIZE |
136 @@ -159,20 +155,18 @@ static krb5_error_code get_credentials(context, cred, server, now,
137 memset(&mcreds, 0, sizeof(mcreds));
138
139 mcreds.magic = KV5M_CREDS;
140 - mcreds.times.endtime = cred->tgt_expire;
141 - mcreds.server = cc_princ;
142 + mcreds.server = cred->impersonator;
143 mcreds.client = cred->name->princ;
144
145 code = krb5_cc_retrieve_cred(context, cred->ccache,
146 - KRB5_TC_MATCH_TIMES | KRB5_TC_MATCH_AUTHDATA,
147 - &mcreds,
148 + KRB5_TC_MATCH_AUTHDATA, &mcreds,
149 &evidence_creds);
150 if (code)
151 goto cleanup;
152
153 assert(evidence_creds.ticket_flags & TKT_FLG_FORWARDABLE);
154
155 - in_creds.client = cc_princ;
156 + in_creds.client = cred->impersonator;
157 in_creds.second_ticket = evidence_creds.ticket;
158 } else {
159 in_creds.client = cred->name->princ;
160 @@ -255,7 +249,6 @@ static krb5_error_code get_credentials(context, cred, server, now,
161
162 cleanup:
163 krb5_free_authdata(context, in_creds.authdata);
164 - krb5_free_principal(context, cc_princ);
165 krb5_free_cred_contents(context, &evidence_creds);
166 krb5_free_creds(context, result_creds);
167
168 diff --git a/src/lib/gssapi/krb5/rel_cred.c b/src/lib/gssapi/krb5/rel_cred.c
169 index 5b2ea2f..4fd3694 100644
170 --- a/src/lib/gssapi/krb5/rel_cred.c
171 +++ b/src/lib/gssapi/krb5/rel_cred.c
172 @@ -71,6 +71,8 @@ krb5_gss_release_cred(minor_status, cred_handle)
173 if (cred->name)
174 kg_release_name(context, &cred->name);
175
176 + krb5_free_principal(context, cred->impersonator);
177 +
178 if (cred->req_enctypes)
179 free(cred->req_enctypes);
180
181 diff --git a/src/lib/gssapi/krb5/s4u_gss_glue.c b/src/lib/gssapi/krb5/s4u_gss_glue.c
182 index 4ac2ce3..4b37c5a 100644
183 --- a/src/lib/gssapi/krb5/s4u_gss_glue.c
184 +++ b/src/lib/gssapi/krb5/s4u_gss_glue.c
185 @@ -169,6 +169,39 @@ krb5_gss_acquire_cred_impersonate_name(OM_uint32 *minor_status,
186
187 }
188
189 +/*
190 + * Set up cred to be an S4U2Proxy credential by copying in the impersonator's
191 + * creds, setting a cache config variable with the impersonator principal name,
192 + * and saving the impersonator principal name in the cred structure.
193 + */
194 +static krb5_error_code
195 +make_proxy_cred(krb5_context context, krb5_gss_cred_id_t cred,
196 + krb5_gss_cred_id_t impersonator_cred)
197 +{
198 + krb5_error_code code;
199 + krb5_data data;
200 + char *str;
201 +
202 + code = krb5_cc_copy_creds(context, impersonator_cred->ccache,
203 + cred->ccache);
204 + if (code)
205 + return code;
206 +
207 + code = krb5_unparse_name(context, impersonator_cred->name->princ, &str);
208 + if (code)
209 + return code;
210 +
211 + data = string2data(str);
212 + code = krb5_cc_set_config(context, cred->ccache, NULL,
213 + KRB5_CONF_PROXY_IMPERSONATOR, &data);
214 + krb5_free_unparsed_name(context, str);
215 + if (code)
216 + return code;
217 +
218 + return krb5_copy_principal(context, impersonator_cred->name->princ,
219 + &cred->impersonator);
220 +}
221 +
222 OM_uint32
223 kg_compose_deleg_cred(OM_uint32 *minor_status,
224 krb5_gss_cred_id_t impersonator_cred,
225 @@ -187,7 +220,7 @@ kg_compose_deleg_cred(OM_uint32 *minor_status,
226
227 if (!kg_is_initiator_cred(impersonator_cred) ||
228 impersonator_cred->name == NULL ||
229 - impersonator_cred->proxy_cred) {
230 + impersonator_cred->impersonator != NULL) {
231 code = G_BAD_USAGE;
232 goto cleanup;
233 }
234 @@ -208,14 +241,7 @@ kg_compose_deleg_cred(OM_uint32 *minor_status,
235 if (code != 0)
236 goto cleanup;
237
238 - /*
239 - * Only return a "proxy" credential for use with constrained
240 - * delegation if the subject credentials are forwardable.
241 - * Submitting non-forwardable credentials to the KDC for use
242 - * with constrained delegation will only return an error.
243 - */
244 cred->usage = GSS_C_INITIATE;
245 - cred->proxy_cred = !!(subject_creds->ticket_flags & TKT_FLG_FORWARDABLE);
246
247 cred->tgt_expire = subject_creds->times.endtime;
248
249 @@ -229,16 +255,18 @@ kg_compose_deleg_cred(OM_uint32 *minor_status,
250 goto cleanup;
251 cred->destroy_ccache = 1;
252
253 - code = krb5_cc_initialize(context, cred->ccache,
254 - cred->proxy_cred ? impersonator_cred->name->princ :
255 - subject_creds->client);
256 + code = krb5_cc_initialize(context, cred->ccache, subject_creds->client);
257 if (code != 0)
258 goto cleanup;
259
260 - if (cred->proxy_cred) {
261 - /* Impersonator's TGT will be necessary for S4U2Proxy */
262 - code = krb5_cc_copy_creds(context, impersonator_cred->ccache,
263 - cred->ccache);
264 + /*
265 + * Only return a "proxy" credential for use with constrained
266 + * delegation if the subject credentials are forwardable.
267 + * Submitting non-forwardable credentials to the KDC for use
268 + * with constrained delegation will only return an error.
269 + */
270 + if (subject_creds->ticket_flags & TKT_FLG_FORWARDABLE) {
271 + code = make_proxy_cred(context, cred, impersonator_cred);
272 if (code != 0)
273 goto cleanup;
274 }
275 diff --git a/src/lib/gssapi/krb5/store_cred.c b/src/lib/gssapi/krb5/store_cred.c
276 index bff3cde..d587589 100644
277 --- a/src/lib/gssapi/krb5/store_cred.c
278 +++ b/src/lib/gssapi/krb5/store_cred.c
279 @@ -91,7 +91,7 @@ copy_initiator_creds(OM_uint32 *minor_status,
280
281 kcred = (krb5_gss_cred_id_t)input_cred_handle;
282
283 - if (kcred->ccache == NULL || kcred->proxy_cred) {
284 + if (kcred->ccache == NULL) {
285 *minor_status = KG_CCACHE_NOMATCH;
286 major_status = GSS_S_DEFECTIVE_CREDENTIAL;
287 goto cleanup;
288 diff --git a/src/lib/gssapi/krb5/val_cred.c b/src/lib/gssapi/krb5/val_cred.c
289 index e87f249..46a9ae1 100644
290 --- a/src/lib/gssapi/krb5/val_cred.c
291 +++ b/src/lib/gssapi/krb5/val_cred.c
292 @@ -50,8 +50,7 @@ krb5_gss_validate_cred_1(OM_uint32 *minor_status, gss_cred_id_t cred_handle,
293 *minor_status = code;
294 return(GSS_S_DEFECTIVE_CREDENTIAL);
295 }
296 - if (!cred->proxy_cred &&
297 - !krb5_principal_compare(context, princ, cred->name->princ)) {
298 + if (!krb5_principal_compare(context, princ, cred->name->princ)) {
299 k5_mutex_unlock(&cred->lock);
300 *minor_status = KG_CCACHE_NOMATCH;
301 return(GSS_S_DEFECTIVE_CREDENTIAL);