]>
Commit | Line | Data |
---|---|---|
9cd6965a JR |
1 | |
2 | ||
3 | The complete set of CITI nfs-utils patches rolled into one patch. | |
4 | ||
5 | Changes since 1.0.8-rc4-CITI_NFS4_ALL-3: | |
6 | ||
7 | * Update to the final nfs-utils-1.0.8 | |
8 | ||
9 | * Check for problems with the gssapi library in gssd and svcgssd | |
10 | early on, so we can give a good error message and bail out. | |
11 | ||
12 | * Add temporary patch to svcgssd to use default values when the | |
13 | mapping of the gss principal to uid/gid fails. This may need | |
14 | to somehow coordinate with the anonuid/anongid values for the | |
15 | export. | |
16 | ||
17 | ||
18 | --- | |
19 | ||
20 | nfs-utils-1.0.8-kwc/utils/gssd/context_mit.c | 507 ++++++++++++++++++++++++-- | |
21 | nfs-utils-1.0.8-kwc/utils/gssd/gss_util.c | 25 + | |
22 | nfs-utils-1.0.8-kwc/utils/gssd/gss_util.h | 1 | |
23 | nfs-utils-1.0.8-kwc/utils/gssd/gssd.c | 5 | |
24 | nfs-utils-1.0.8-kwc/utils/gssd/krb5_util.c | 221 +++++++++-- | |
25 | nfs-utils-1.0.8-kwc/utils/gssd/krb5_util.h | 2 | |
26 | nfs-utils-1.0.8-kwc/utils/gssd/svcgssd.c | 5 | |
27 | nfs-utils-1.0.8-kwc/utils/gssd/svcgssd_proc.c | 17 | |
28 | nfs-utils-1.0.8-kwc/utils/gssd/write_bytes.h | 13 | |
29 | 9 files changed, 714 insertions(+), 82 deletions(-) | |
30 | ||
31 | diff -puN utils/gssd/gssd.c~CITI_NFS4_ALL utils/gssd/gssd.c | |
32 | --- nfs-utils-1.0.8/utils/gssd/gssd.c~CITI_NFS4_ALL 2006-04-20 12:41:15.668400000 -0400 | |
33 | +++ nfs-utils-1.0.8-kwc/utils/gssd/gssd.c 2006-04-20 12:41:16.486965000 -0400 | |
34 | @@ -145,6 +145,9 @@ main(int argc, char *argv[]) | |
35 | "support setting debug level\n"); | |
36 | #endif | |
37 | ||
38 | + if (gssd_check_mechs() != 0) | |
39 | + errx(1, "Problem with gssapi library"); | |
40 | + | |
41 | if (!fg && daemon(0, 0) < 0) | |
42 | errx(1, "fork"); | |
43 | ||
44 | @@ -154,6 +157,8 @@ main(int argc, char *argv[]) | |
45 | ||
46 | /* Process keytab file and get machine credentials */ | |
47 | gssd_refresh_krb5_machine_creds(); | |
48 | + /* Determine Kerberos information from the kernel */ | |
49 | + gssd_obtain_kernel_krb5_info(); | |
50 | ||
51 | gssd_run(); | |
52 | printerr(0, "gssd_run returned!\n"); | |
53 | diff -puN utils/gssd/gss_util.c~CITI_NFS4_ALL utils/gssd/gss_util.c | |
54 | --- nfs-utils-1.0.8/utils/gssd/gss_util.c~CITI_NFS4_ALL 2006-04-20 12:41:15.770298000 -0400 | |
55 | +++ nfs-utils-1.0.8-kwc/utils/gssd/gss_util.c 2006-04-20 12:41:16.001067000 -0400 | |
56 | @@ -224,3 +224,28 @@ gssd_acquire_cred(char *server_name) | |
57 | ||
58 | return (maj_stat == GSS_S_COMPLETE); | |
59 | } | |
60 | + | |
61 | +int gssd_check_mechs(void) | |
62 | +{ | |
63 | + u_int32_t maj_stat, min_stat; | |
64 | + gss_OID_set supported_mechs = GSS_C_NO_OID_SET; | |
65 | + int retval = -1; | |
66 | + | |
67 | + maj_stat = gss_indicate_mechs(&min_stat, &supported_mechs); | |
68 | + if (maj_stat != GSS_S_COMPLETE) { | |
69 | + printerr(0, "Unable to obtain list of supported mechanisms. " | |
70 | + "Check that gss library is properly configured.\n"); | |
71 | + goto out; | |
72 | + } | |
73 | + if (supported_mechs == GSS_C_NO_OID_SET || | |
74 | + supported_mechs->count == 0) { | |
75 | + printerr(0, "Unable to obtain list of supported mechanisms. " | |
76 | + "Check that gss library is properly configured.\n"); | |
77 | + goto out; | |
78 | + } | |
79 | + maj_stat = gss_release_oid_set(&min_stat, &supported_mechs); | |
80 | + retval = 0; | |
81 | +out: | |
82 | + return retval; | |
83 | +} | |
84 | + | |
85 | diff -puN utils/gssd/gss_util.h~CITI_NFS4_ALL utils/gssd/gss_util.h | |
86 | --- nfs-utils-1.0.8/utils/gssd/gss_util.h~CITI_NFS4_ALL 2006-04-20 12:41:15.865203000 -0400 | |
87 | +++ nfs-utils-1.0.8-kwc/utils/gssd/gss_util.h 2006-04-20 12:41:16.011057000 -0400 | |
88 | @@ -40,5 +40,6 @@ extern gss_cred_id_t gssd_creds; | |
89 | int gssd_acquire_cred(char *server_name); | |
90 | void pgsserr(char *msg, u_int32_t maj_stat, u_int32_t min_stat, | |
91 | const gss_OID mech); | |
92 | +int gssd_check_mechs(void); | |
93 | ||
94 | #endif /* _GSS_UTIL_H_ */ | |
95 | diff -puN utils/gssd/svcgssd.c~CITI_NFS4_ALL utils/gssd/svcgssd.c | |
96 | --- nfs-utils-1.0.8/utils/gssd/svcgssd.c~CITI_NFS4_ALL 2006-04-20 12:41:15.961107000 -0400 | |
97 | +++ nfs-utils-1.0.8-kwc/utils/gssd/svcgssd.c 2006-04-20 12:41:16.021047000 -0400 | |
98 | @@ -204,6 +204,11 @@ main(int argc, char *argv[]) | |
99 | "support setting debug level\n"); | |
100 | #endif | |
101 | ||
102 | + if (gssd_check_mechs() != 0) { | |
103 | + printerr(0, "ERROR: Problem with gssapi library\n"); | |
104 | + exit(1); | |
105 | + } | |
106 | + | |
107 | if (!fg) | |
108 | mydaemon(0, 0); | |
109 | ||
110 | diff -puN utils/gssd/krb5_util.c~CITI_NFS4_ALL utils/gssd/krb5_util.c | |
111 | --- nfs-utils-1.0.8/utils/gssd/krb5_util.c~CITI_NFS4_ALL 2006-04-20 12:41:16.230965000 -0400 | |
112 | +++ nfs-utils-1.0.8-kwc/utils/gssd/krb5_util.c 2006-04-20 12:41:16.503965000 -0400 | |
113 | @@ -97,6 +97,7 @@ | |
114 | #include "config.h" | |
115 | #include <sys/param.h> | |
116 | #include <rpc/rpc.h> | |
117 | +#include <sys/types.h> | |
118 | #include <sys/stat.h> | |
119 | #include <sys/socket.h> | |
120 | #include <arpa/inet.h> | |
121 | @@ -105,6 +106,7 @@ | |
122 | #include <stdlib.h> | |
123 | #include <string.h> | |
124 | #include <dirent.h> | |
125 | +#include <fcntl.h> | |
126 | #include <errno.h> | |
127 | #include <time.h> | |
128 | #include <gssapi/gssapi.h> | |
129 | @@ -123,6 +125,10 @@ | |
130 | /* Global list of principals/cache file names for machine credentials */ | |
131 | struct gssd_k5_kt_princ *gssd_k5_kt_princ_list = NULL; | |
132 | ||
133 | +/* Encryption types supported by the kernel rpcsec_gss code */ | |
134 | +int num_krb5_enctypes = 0; | |
135 | +krb5_enctype *krb5_enctypes = NULL; | |
136 | + | |
137 | /*==========================*/ | |
138 | /*=== Internal routines ===*/ | |
139 | /*==========================*/ | |
140 | @@ -261,51 +267,6 @@ gssd_find_existing_krb5_ccache(uid_t uid | |
141 | } | |
142 | ||
143 | ||
144 | -#ifdef HAVE_SET_ALLOWABLE_ENCTYPES | |
145 | -/* | |
146 | - * this routine obtains a credentials handle via gss_acquire_cred() | |
147 | - * then calls gss_krb5_set_allowable_enctypes() to limit the encryption | |
148 | - * types negotiated. | |
149 | - * | |
150 | - * XXX Should call some function to determine the enctypes supported | |
151 | - * by the kernel. (Only need to do that once!) | |
152 | - * | |
153 | - * Returns: | |
154 | - * 0 => all went well | |
155 | - * -1 => there was an error | |
156 | - */ | |
157 | - | |
158 | -int | |
159 | -limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid) | |
160 | -{ | |
161 | - u_int maj_stat, min_stat; | |
162 | - gss_cred_id_t credh; | |
163 | - krb5_enctype enctypes[] = { ENCTYPE_DES_CBC_CRC }; | |
164 | - int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]); | |
165 | - | |
166 | - maj_stat = gss_acquire_cred(&min_stat, NULL, 0, | |
167 | - GSS_C_NULL_OID_SET, GSS_C_INITIATE, | |
168 | - &credh, NULL, NULL); | |
169 | - | |
170 | - if (maj_stat != GSS_S_COMPLETE) { | |
171 | - pgsserr("gss_acquire_cred", | |
172 | - maj_stat, min_stat, &krb5oid); | |
173 | - return -1; | |
174 | - } | |
175 | - | |
176 | - maj_stat = gss_set_allowable_enctypes(&min_stat, credh, &krb5oid, | |
177 | - num_enctypes, &enctypes); | |
178 | - if (maj_stat != GSS_S_COMPLETE) { | |
179 | - pgsserr("gss_set_allowable_enctypes", | |
180 | - maj_stat, min_stat, &krb5oid); | |
181 | - return -1; | |
182 | - } | |
183 | - sec->cred = credh; | |
184 | - | |
185 | - return 0; | |
186 | -} | |
187 | -#endif /* HAVE_SET_ALLOWABLE_ENCTYPES */ | |
188 | - | |
189 | /* | |
190 | * Obtain credentials via a key in the keytab given | |
191 | * a keytab handle and a gssd_k5_kt_princ structure. | |
192 | @@ -603,6 +564,56 @@ gssd_set_krb5_ccache_name(char *ccname) | |
193 | #endif | |
194 | } | |
195 | ||
196 | +/* | |
197 | + * Parse the supported encryption type information | |
198 | + */ | |
199 | +static int | |
200 | +parse_enctypes(char *enctypes) | |
201 | +{ | |
202 | + int n = 0; | |
203 | + char *curr, *comma; | |
204 | + int i; | |
205 | + | |
206 | + /* Just in case this ever gets called more than once */ | |
207 | + if (krb5_enctypes != NULL) { | |
208 | + free(krb5_enctypes); | |
209 | + krb5_enctypes = NULL; | |
210 | + num_krb5_enctypes = 0; | |
211 | + } | |
212 | + | |
213 | + /* count the number of commas */ | |
214 | + for (curr = enctypes; curr && *curr != '\0'; curr = ++comma) { | |
215 | + comma = strchr(curr, ','); | |
216 | + if (comma != NULL) | |
217 | + n++; | |
218 | + else | |
219 | + break; | |
220 | + } | |
221 | + /* If no more commas and we're not at the end, there's one more value */ | |
222 | + if (*curr != '\0') | |
223 | + n++; | |
224 | + | |
225 | + /* Empty string, return an error */ | |
226 | + if (n == 0) | |
227 | + return ENOENT; | |
228 | + | |
229 | + /* Allocate space for enctypes array */ | |
230 | + if ((krb5_enctypes = (int *) calloc(n, sizeof(int))) == NULL) { | |
231 | + return ENOMEM; | |
232 | + } | |
233 | + | |
234 | + /* Now parse each value into the array */ | |
235 | + for (curr = enctypes, i = 0; curr && *curr != '\0'; curr = ++comma) { | |
236 | + krb5_enctypes[i++] = atoi(curr); | |
237 | + comma = strchr(curr, ','); | |
238 | + if (comma == NULL) | |
239 | + break; | |
240 | + } | |
241 | + | |
242 | + num_krb5_enctypes = n; | |
243 | + return 0; | |
244 | +} | |
245 | + | |
246 | /*==========================*/ | |
247 | /*=== External routines ===*/ | |
248 | /*==========================*/ | |
249 | @@ -854,3 +865,123 @@ gssd_destroy_krb5_machine_creds(void) | |
250 | krb5_free_context(context); | |
251 | } | |
252 | ||
253 | +#ifdef HAVE_SET_ALLOWABLE_ENCTYPES | |
254 | +/* | |
255 | + * this routine obtains a credentials handle via gss_acquire_cred() | |
256 | + * then calls gss_krb5_set_allowable_enctypes() to limit the encryption | |
257 | + * types negotiated. | |
258 | + * | |
259 | + * Returns: | |
260 | + * 0 => all went well | |
261 | + * -1 => there was an error | |
262 | + */ | |
263 | + | |
264 | +int | |
265 | +limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid) | |
266 | +{ | |
267 | + u_int maj_stat, min_stat; | |
268 | + gss_cred_id_t credh; | |
269 | + gss_OID_set_desc desired_mechs; | |
270 | + krb5_enctype enctypes[] = {ENCTYPE_DES_CBC_CRC}; | |
271 | + int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]); | |
272 | + | |
273 | + /* We only care about getting a krb5 cred */ | |
274 | + desired_mechs.count = 1; | |
275 | + desired_mechs.elements = &krb5oid; | |
276 | + | |
277 | + maj_stat = gss_acquire_cred(&min_stat, NULL, 0, | |
278 | + &desired_mechs, GSS_C_INITIATE, | |
279 | + &credh, NULL, NULL); | |
280 | + | |
281 | + if (maj_stat != GSS_S_COMPLETE) { | |
282 | + pgsserr("gss_acquire_cred", | |
283 | + maj_stat, min_stat, &krb5oid); | |
284 | + return -1; | |
285 | + } | |
286 | + | |
287 | + /* | |
288 | + * If we failed for any reason to produce global | |
289 | + * list of supported enctypes, use local default here. | |
290 | + */ | |
291 | + if (krb5_enctypes == NULL) | |
292 | + maj_stat = gss_set_allowable_enctypes(&min_stat, credh, | |
293 | + &krb5oid, num_enctypes, &enctypes); | |
294 | + else | |
295 | + maj_stat = gss_set_allowable_enctypes(&min_stat, credh, | |
296 | + &krb5oid, num_krb5_enctypes, | |
297 | + krb5_enctypes); | |
298 | + if (maj_stat != GSS_S_COMPLETE) { | |
299 | + pgsserr("gss_set_allowable_enctypes", | |
300 | + maj_stat, min_stat, &krb5oid); | |
301 | + return -1; | |
302 | + } | |
303 | + sec->cred = credh; | |
304 | + | |
305 | + return 0; | |
306 | +} | |
307 | +#endif /* HAVE_SET_ALLOWABLE_ENCTYPES */ | |
308 | + | |
309 | +/* | |
310 | + * Obtain supported enctypes from kernel. | |
311 | + * Set defaults if info is not available. | |
312 | + */ | |
313 | +void | |
314 | +gssd_obtain_kernel_krb5_info(void) | |
315 | +{ | |
316 | + char enctype_file_name[128]; | |
317 | + char buf[1024]; | |
318 | + char enctypes[128]; | |
319 | + char extrainfo[1024]; | |
320 | + int fd; | |
321 | + int use_default_enctypes = 0; | |
322 | + int nbytes, numfields; | |
323 | + char default_enctypes[] = "1,3,2"; | |
324 | + int code; | |
325 | + | |
326 | + snprintf(enctype_file_name, sizeof(enctype_file_name), | |
327 | + "%s/%s", pipefsdir, "krb5_info"); | |
328 | + | |
329 | + if ((fd = open(enctype_file_name, O_RDONLY)) == -1) { | |
330 | + printerr(1, "WARNING: gssd_obtain_kernel_krb5_info: " | |
331 | + "Unable to open '%s'. Unable to determine " | |
332 | + "Kerberos encryption types supported by the " | |
333 | + "kernel; using defaults (%s).\n", | |
334 | + enctype_file_name, default_enctypes); | |
335 | + use_default_enctypes = 1; | |
336 | + goto do_the_parse; | |
337 | + } | |
338 | + if ((nbytes = read(fd, buf, sizeof(buf))) == -1) { | |
339 | + printerr(0, "WARNING: gssd_obtain_kernel_krb5_info: " | |
340 | + "Error reading Kerberos encryption type " | |
341 | + "information file '%s'; using defaults (%s).\n", | |
342 | + enctype_file_name, default_enctypes); | |
343 | + use_default_enctypes = 1; | |
344 | + goto do_the_parse; | |
345 | + } | |
346 | + numfields = sscanf(buf, "enctypes: %s\n%s", enctypes, extrainfo); | |
347 | + if (numfields < 1) { | |
348 | + printerr(0, "WARNING: gssd_obtain_kernel_krb5_info: " | |
349 | + "error parsing Kerberos encryption type " | |
350 | + "information from file '%s'; using defaults (%s).\n", | |
351 | + enctype_file_name, default_enctypes); | |
352 | + use_default_enctypes = 1; | |
353 | + goto do_the_parse; | |
354 | + } | |
355 | + if (numfields > 1) { | |
356 | + printerr(0, "WARNING: gssd_obtain_kernel_krb5_info: " | |
357 | + "Extra information, '%s', from '%s' is ignored\n", | |
358 | + enctype_file_name, extrainfo); | |
359 | + use_default_enctypes = 1; | |
360 | + goto do_the_parse; | |
361 | + } | |
362 | + do_the_parse: | |
363 | + if (use_default_enctypes) | |
364 | + strcpy(enctypes, default_enctypes); | |
365 | + | |
366 | + if ((code = parse_enctypes(enctypes)) != 0) { | |
367 | + printerr(0, "ERROR: gssd_obtain_kernel_krb5_info: " | |
368 | + "parse_enctypes%s failed with code %d\n", | |
369 | + use_default_enctypes ? " (with default enctypes)" : "", | |
370 | + code); | |
371 | + } | |
372 | +} | |
373 | diff -puN utils/gssd/krb5_util.h~CITI_NFS4_ALL utils/gssd/krb5_util.h | |
374 | --- nfs-utils-1.0.8/utils/gssd/krb5_util.h~CITI_NFS4_ALL 2006-04-20 12:41:16.461965000 -0400 | |
375 | +++ nfs-utils-1.0.8-kwc/utils/gssd/krb5_util.h 2006-04-20 12:41:16.513965000 -0400 | |
376 | @@ -22,6 +22,8 @@ int gssd_refresh_krb5_machine_creds(voi | |
377 | void gssd_free_krb5_machine_cred_list(char **list); | |
378 | void gssd_setup_krb5_machine_gss_ccache(char *servername); | |
379 | void gssd_destroy_krb5_machine_creds(void); | |
380 | +void gssd_obtain_kernel_krb5_info(void); | |
381 | + | |
382 | ||
383 | #ifdef HAVE_SET_ALLOWABLE_ENCTYPES | |
384 | int limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid); | |
385 | diff -puN utils/gssd/context_mit.c~CITI_NFS4_ALL utils/gssd/context_mit.c | |
386 | --- nfs-utils-1.0.8/utils/gssd/context_mit.c~CITI_NFS4_ALL 2006-04-20 12:41:16.770847000 -0400 | |
387 | +++ nfs-utils-1.0.8-kwc/utils/gssd/context_mit.c 2006-04-20 12:41:16.894723000 -0400 | |
388 | @@ -32,6 +32,7 @@ | |
389 | #include <stdio.h> | |
390 | #include <syslog.h> | |
391 | #include <string.h> | |
392 | +#include <errno.h> | |
638697cf | 393 | #include <gssapi.h> |
9cd6965a JR |
394 | #include <rpc/rpc.h> |
395 | #include <rpc/auth_gss.h> | |
396 | @@ -43,9 +44,53 @@ | |
397 | #ifdef HAVE_KRB5 | |
398 | #include <krb5.h> | |
399 | ||
400 | +/* for 3DES */ | |
401 | +#define KG_USAGE_SEAL 22 | |
402 | +#define KG_USAGE_SIGN 23 | |
403 | +#define KG_USAGE_SEQ 24 | |
404 | + | |
405 | +/* for rfc???? */ | |
406 | +#define KG_USAGE_ACCEPTOR_SEAL 22 | |
407 | +#define KG_USAGE_ACCEPTOR_SIGN 23 | |
408 | +#define KG_USAGE_INITIATOR_SEAL 24 | |
409 | +#define KG_USAGE_INITIATOR_SIGN 25 | |
410 | + | |
411 | +/* Lifted from mit src/lib/gssapi/krb5/gssapiP_krb5.h */ | |
412 | +enum seal_alg { | |
413 | + SEAL_ALG_NONE = 0xffff, | |
414 | + SEAL_ALG_DES = 0x0000, | |
415 | + SEAL_ALG_1 = 0x0001, /* not published */ | |
416 | + SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; */ | |
417 | + SEAL_ALG_DES3KD = 0x0002 | |
418 | +}; | |
419 | + | |
420 | +#define KEY_USAGE_SEED_ENCRYPTION 0xAA | |
421 | +#define KEY_USAGE_SEED_INTEGRITY 0x55 | |
422 | +#define KEY_USAGE_SEED_CHECKSUM 0x99 | |
423 | +#define K5CLENGTH 5 | |
424 | + | |
425 | +/* Flags for version 2 context flags */ | |
426 | +#define KRB5_CTX_FLAG_INITIATOR 0x00000001 | |
427 | +#define KRB5_CTX_FLAG_CFX 0x00000002 | |
428 | +#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004 | |
429 | + | |
430 | +/* | |
431 | + * XXX Hack alert. We don't have "legal" access to these | |
432 | + * structures located in libk5crypto | |
433 | + */ | |
434 | +extern void krb5int_enc_arcfour; | |
435 | +extern void krb5int_enc_des3; | |
436 | +extern void krb5int_enc_aes128; | |
437 | +extern void krb5int_enc_aes256; | |
438 | +extern int krb5_derive_key(); | |
439 | + | |
440 | +void *get_enc_provider(); | |
441 | + | |
442 | /* XXX spkm3 seems to actually want it this big, yipes. */ | |
443 | #define MAX_CTX_LEN 4096 | |
444 | ||
445 | + | |
446 | + | |
447 | #ifdef HAVE_LUCID_CONTEXT_SUPPORT | |
448 | ||
449 | /* Don't use the private structure, use the exported lucid structure */ | |
450 | @@ -144,6 +189,96 @@ write_lucid_keyblock(char **p, char *end | |
451 | return 0; | |
452 | } | |
453 | ||
454 | +static void | |
455 | +key_lucid_to_krb5(const gss_krb5_lucid_key_t *lin, krb5_keyblock *kout) | |
456 | +{ | |
457 | + memset(kout, '\0', sizeof(kout)); | |
458 | + kout->enctype = lin->type; | |
459 | + kout->length = lin->length; | |
460 | + kout->contents = lin->data; | |
461 | +} | |
462 | + | |
463 | +static void | |
464 | +key_krb5_to_lucid(const krb5_keyblock *kin, gss_krb5_lucid_key_t *lout) | |
465 | +{ | |
466 | + memset(lout, '\0', sizeof(lout)); | |
467 | + lout->type = kin->enctype; | |
468 | + lout->length = kin->length; | |
469 | + lout->data = kin->contents; | |
470 | +} | |
471 | + | |
472 | +/* | |
473 | + * Function to derive a new key from a given key and given constant data. | |
474 | + */ | |
475 | +static krb5_error_code | |
476 | +derive_key_lucid(const gss_krb5_lucid_key_t *in, gss_krb5_lucid_key_t *out, | |
477 | + int usage, char extra) | |
478 | +{ | |
479 | + krb5_error_code code; | |
480 | + unsigned char constant_data[K5CLENGTH]; | |
481 | + krb5_data datain; | |
482 | + int keylength; | |
483 | + void *enc; | |
484 | + krb5_keyblock kin, kout; /* must send krb5_keyblock, not lucid! */ | |
485 | + | |
486 | + /* | |
487 | + * XXX Hack alert. We don't have "legal" access to these | |
488 | + * values and structures located in libk5crypto | |
489 | + */ | |
490 | + switch (in->type) { | |
491 | + case ENCTYPE_DES3_CBC_RAW: | |
492 | + keylength = 24; | |
493 | + enc = &krb5int_enc_des3; | |
494 | + break; | |
495 | + case ENCTYPE_AES128_CTS_HMAC_SHA1_96: | |
496 | + keylength = 16; | |
497 | + enc = &krb5int_enc_aes128; | |
498 | + break; | |
499 | + case ENCTYPE_AES256_CTS_HMAC_SHA1_96: | |
500 | + keylength = 32; | |
501 | + enc = &krb5int_enc_aes256; | |
502 | + break; | |
503 | + default: | |
504 | + code = KRB5_BAD_ENCTYPE; | |
505 | + goto out; | |
506 | + } | |
507 | + | |
508 | + /* allocate memory for output key */ | |
509 | + if ((out->data = malloc(keylength)) == NULL) { | |
510 | + code = ENOMEM; | |
511 | + goto out; | |
512 | + } | |
513 | + out->length = keylength; | |
514 | + out->type = in->type; | |
515 | + | |
516 | + /* Convert to correct format for call to krb5_derive_key */ | |
517 | + key_lucid_to_krb5(in, &kin); | |
518 | + key_lucid_to_krb5(out, &kout); | |
519 | + | |
520 | + datain.data = (char *) constant_data; | |
521 | + datain.length = K5CLENGTH; | |
522 | + | |
523 | + datain.data[0] = (usage>>24)&0xff; | |
524 | + datain.data[1] = (usage>>16)&0xff; | |
525 | + datain.data[2] = (usage>>8)&0xff; | |
526 | + datain.data[3] = usage&0xff; | |
527 | + | |
528 | + datain.data[4] = (char) extra; | |
529 | + | |
530 | + if ((code = krb5_derive_key(enc, &kin, &kout, &datain))) { | |
531 | + free(out->data); | |
532 | + out->data = NULL; | |
533 | + goto out; | |
534 | + } | |
535 | + key_krb5_to_lucid(&kout, out); | |
536 | + | |
537 | + out: | |
538 | + if (code) | |
539 | + printerr(0, "ERROR: derive_key_lucid returning error %d (%s)\n", | |
540 | + code, error_message(code)); | |
541 | + return (code); | |
542 | +} | |
543 | + | |
544 | static int | |
545 | prepare_krb5_rfc1964_buffer(gss_krb5_lucid_context_v1_t *lctx, | |
546 | gss_buffer_desc *buf) | |
547 | @@ -183,7 +318,7 @@ prepare_krb5_rfc1964_buffer(gss_krb5_luc | |
548 | if (WRITE_BYTES(&p, end, lctx->endtime)) goto out_err; | |
549 | word_send_seq = lctx->send_seq; /* XXX send_seq is 64-bit */ | |
550 | if (WRITE_BYTES(&p, end, word_send_seq)) goto out_err; | |
551 | - if (write_buffer(&p, end, (gss_buffer_desc*)&krb5oid)) goto out_err; | |
552 | + if (write_oid(&p, end, &krb5oid)) goto out_err; | |
553 | ||
554 | printerr(2, "prepare_krb5_rfc1964_buffer: serializing keys with " | |
555 | "enctype %d and length %d\n", | |
556 | @@ -212,17 +347,180 @@ prepare_krb5_rfc1964_buffer(gss_krb5_luc | |
557 | return 0; | |
558 | out_err: | |
559 | printerr(0, "ERROR: failed serializing krb5 context for kernel\n"); | |
560 | - if (buf->value) free(buf->value); | |
561 | + if (buf->value) { | |
562 | + free(buf->value); | |
563 | + buf->value = NULL; | |
564 | + } | |
565 | buf->length = 0; | |
566 | - if (enc_key.data) free(enc_key.data); | |
567 | + if (enc_key.data) { | |
568 | + free(enc_key.data); | |
569 | + enc_key.data = NULL; | |
570 | + } | |
571 | return -1; | |
572 | } | |
573 | ||
574 | +/* | |
575 | + * Prepare a new-style buffer to send to the kernel for newer encryption | |
576 | + * types -- or for DES3. | |
577 | + * | |
578 | + * The new format is: | |
579 | + * | |
580 | + * u32 version; This is two (2) | |
581 | + * s32 endtime; | |
582 | + * u32 flags; | |
583 | + * #define KRB5_CTX_FLAG_INITIATOR 0x00000001 | |
584 | + * #define KRB5_CTX_FLAG_CFX 0x00000002 | |
585 | + * #define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004 | |
586 | + * u64 seq_send; | |
587 | + * u32 enctype; ( encrption type of keys ) | |
588 | + * u32 size_of_each_key; ( size of each key in bytes ) | |
589 | + * u32 number_of_keys; ( N -- should always be 3 for now ) | |
590 | + * keydata-1; ( Ke ) | |
591 | + * keydata-2; ( Ki ) | |
592 | + * keydata-3; ( Kc ) | |
593 | + * | |
594 | + */ | |
595 | static int | |
596 | -prepare_krb5_rfc_cfx_buffer(gss_krb5_lucid_context_v1_t *lctx, | |
597 | +prepare_krb5_ctx_v2_buffer(gss_krb5_lucid_context_v1_t *lctx, | |
598 | gss_buffer_desc *buf) | |
599 | { | |
600 | - printerr(0, "ERROR: prepare_krb5_rfc_cfx_buffer: not implemented\n"); | |
601 | + char *p, *end; | |
602 | + static uint32_t version = 2; | |
603 | + uint32_t v2_flags = 0; | |
604 | + gss_krb5_lucid_key_t enc_key; | |
605 | + gss_krb5_lucid_key_t derived_key; | |
606 | + gss_buffer_desc fakeoid; | |
607 | + uint32_t enctype; | |
608 | + uint32_t keysize; | |
609 | + uint32_t numkeys; | |
610 | + | |
611 | + memset(&enc_key, 0, sizeof(enc_key)); | |
612 | + memset(&fakeoid, 0, sizeof(fakeoid)); | |
613 | + | |
614 | + if (!(buf->value = calloc(1, MAX_CTX_LEN))) | |
615 | + goto out_err; | |
616 | + p = buf->value; | |
617 | + end = buf->value + MAX_CTX_LEN; | |
618 | + | |
619 | + /* Version 2 */ | |
620 | + if (WRITE_BYTES(&p, end , version)) goto out_err; | |
621 | + if (WRITE_BYTES(&p, end, lctx->endtime)) goto out_err; | |
622 | + | |
623 | + if (lctx->initiate) | |
624 | + v2_flags |= KRB5_CTX_FLAG_INITIATOR; | |
625 | + if (lctx->protocol != 0) | |
626 | + v2_flags |= KRB5_CTX_FLAG_CFX; | |
627 | + if (lctx->protocol != 0 && lctx->cfx_kd.have_acceptor_subkey == 1) | |
628 | + v2_flags |= KRB5_CTX_FLAG_ACCEPTOR_SUBKEY; | |
629 | + | |
630 | + if (WRITE_BYTES(&p, end, v2_flags)) goto out_err; | |
631 | + | |
632 | + if (WRITE_BYTES(&p, end, lctx->send_seq)) goto out_err; | |
633 | + | |
634 | + /* Protocol 0 here implies DES3 or RC4 */ | |
635 | + if (lctx->protocol == 0) { | |
636 | + enctype = lctx->rfc1964_kd.ctx_key.type; | |
637 | + keysize = lctx->rfc1964_kd.ctx_key.length; | |
638 | + numkeys = 3; /* XXX is always gonna be three? */ | |
639 | + } else { | |
640 | + if (lctx->cfx_kd.have_acceptor_subkey) { | |
641 | + enctype = lctx->cfx_kd.acceptor_subkey.type; | |
642 | + keysize = lctx->cfx_kd.acceptor_subkey.length; | |
643 | + } else { | |
644 | + enctype = lctx->cfx_kd.ctx_key.type; | |
645 | + keysize = lctx->cfx_kd.ctx_key.length; | |
646 | + } | |
647 | + numkeys = 3; | |
648 | + } | |
649 | + printerr(2, "prepare_krb5_ctx_v2_buffer: serializing %d keys with " | |
650 | + "enctype %d and size %d\n", numkeys, enctype, keysize); | |
651 | + if (WRITE_BYTES(&p, end, enctype)) goto out_err; | |
652 | + if (WRITE_BYTES(&p, end, keysize)) goto out_err; | |
653 | + if (WRITE_BYTES(&p, end, numkeys)) goto out_err; | |
654 | + | |
655 | + if (lctx->protocol == 0) { | |
656 | + /* derive and send down: Ke, Ki, and Kc */ | |
657 | + /* Ke */ | |
658 | + if (write_bytes(&p, end, lctx->rfc1964_kd.ctx_key.data, | |
659 | + lctx->rfc1964_kd.ctx_key.length)) | |
660 | + goto out_err; | |
661 | + | |
662 | + /* Ki */ | |
663 | + if (write_bytes(&p, end, lctx->rfc1964_kd.ctx_key.data, | |
664 | + lctx->rfc1964_kd.ctx_key.length)) | |
665 | + goto out_err; | |
666 | + | |
667 | + /* Kc */ | |
668 | + if (derive_key_lucid(&lctx->rfc1964_kd.ctx_key, | |
669 | + &derived_key, | |
670 | + KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM)) | |
671 | + goto out_err; | |
672 | + if (write_bytes(&p, end, derived_key.data, | |
673 | + derived_key.length)) | |
674 | + goto out_err; | |
675 | + free(derived_key.data); | |
676 | + } else { | |
677 | + gss_krb5_lucid_key_t *keyptr; | |
678 | + uint32_t sign_usage, seal_usage; | |
679 | + | |
680 | + if (lctx->cfx_kd.have_acceptor_subkey) | |
681 | + keyptr = &lctx->cfx_kd.acceptor_subkey; | |
682 | + else | |
683 | + keyptr = &lctx->cfx_kd.ctx_key; | |
684 | + | |
685 | + if (lctx->initiate == 1) { | |
686 | + sign_usage = KG_USAGE_INITIATOR_SIGN; | |
687 | + seal_usage = KG_USAGE_INITIATOR_SEAL; | |
688 | + } else { | |
689 | + sign_usage = KG_USAGE_ACCEPTOR_SIGN; | |
690 | + seal_usage = KG_USAGE_ACCEPTOR_SEAL; | |
691 | + } | |
692 | + | |
693 | + /* derive and send down: Ke, Ki, and Kc */ | |
694 | + | |
695 | + /* Ke */ | |
696 | + if (derive_key_lucid(keyptr, &derived_key, | |
697 | + seal_usage, KEY_USAGE_SEED_ENCRYPTION)) | |
698 | + goto out_err; | |
699 | + if (write_bytes(&p, end, derived_key.data, | |
700 | + derived_key.length)) | |
701 | + goto out_err; | |
702 | + free(derived_key.data); | |
703 | + | |
704 | + /* Ki */ | |
705 | + if (derive_key_lucid(keyptr, &derived_key, | |
706 | + seal_usage, KEY_USAGE_SEED_INTEGRITY)) | |
707 | + goto out_err; | |
708 | + if (write_bytes(&p, end, derived_key.data, | |
709 | + derived_key.length)) | |
710 | + goto out_err; | |
711 | + free(derived_key.data); | |
712 | + | |
713 | + /* Kc */ | |
714 | + if (derive_key_lucid(keyptr, &derived_key, | |
715 | + sign_usage, KEY_USAGE_SEED_CHECKSUM)) | |
716 | + goto out_err; | |
717 | + if (write_bytes(&p, end, derived_key.data, | |
718 | + derived_key.length)) | |
719 | + goto out_err; | |
720 | + free(derived_key.data); | |
721 | + } | |
722 | + | |
723 | + buf->length = p - (char *)buf->value; | |
724 | + return 0; | |
725 | + | |
726 | +out_err: | |
727 | + printerr(0, "ERROR: prepare_krb5_ctx_v2_buffer: " | |
728 | + "failed serializing krb5 context for kernel\n"); | |
729 | + if (buf->value) { | |
730 | + free(buf->value); | |
731 | + buf->value = NULL; | |
732 | + } | |
733 | + buf->length = 0; | |
734 | + if (enc_key.data) { | |
735 | + free(enc_key.data); | |
736 | + enc_key.data = NULL; | |
737 | + } | |
738 | return -1; | |
739 | } | |
740 | ||
741 | @@ -258,11 +556,21 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss | |
742 | break; | |
743 | } | |
744 | ||
745 | - /* Now lctx points to a lucid context that we can send down to kernel */ | |
746 | - if (lctx->protocol == 0) | |
747 | + /* | |
748 | + * Now lctx points to a lucid context that we can send down to kernel | |
749 | + * | |
750 | + * Note: we send down different information to the kernel depending | |
751 | + * on the protocol version and the enctyption type. | |
752 | + * For protocol version 0 with all enctypes besides DES3, we use | |
753 | + * the original format. For protocol version != 0 or DES3, we | |
754 | + * send down the new style information. | |
755 | + */ | |
756 | + | |
757 | + if (lctx->protocol == 0 && | |
758 | + lctx->rfc1964_kd.ctx_key.type == ENCTYPE_DES_CBC_RAW) | |
759 | retcode = prepare_krb5_rfc1964_buffer(lctx, buf); | |
760 | else | |
761 | - retcode = prepare_krb5_rfc_cfx_buffer(lctx, buf); | |
762 | + retcode = prepare_krb5_ctx_v2_buffer(lctx, buf); | |
763 | ||
764 | maj_stat = gss_free_lucid_sec_context(&min_stat, ctx, return_ctx); | |
765 | if (maj_stat != GSS_S_COMPLETE) { | |
766 | @@ -300,6 +608,66 @@ write_keyblock(char **p, char *end, stru | |
767 | } | |
768 | ||
769 | /* | |
770 | + * Function to derive a new key from a given key and given constant data. | |
771 | + */ | |
772 | +static krb5_error_code | |
773 | +derive_key(const krb5_keyblock *in, krb5_keyblock *out, int usage, char extra) | |
774 | +{ | |
775 | + krb5_error_code code; | |
776 | + unsigned char constant_data[K5CLENGTH]; | |
777 | + krb5_data datain; | |
778 | + int keylength; | |
779 | + void *enc; | |
780 | + | |
781 | + /* | |
782 | + * XXX Hack alert. We don't have "legal" access to these | |
783 | + * values and structures located in libk5crypto | |
784 | + */ | |
785 | + switch (in->enctype) { | |
786 | + case ENCTYPE_DES3_CBC_RAW: | |
787 | + keylength = 24; | |
788 | + enc = &krb5int_enc_des3; | |
789 | + break; | |
790 | + case ENCTYPE_ARCFOUR_HMAC: | |
791 | + keylength = 16; | |
792 | + enc = &krb5int_enc_arcfour; | |
793 | + break; | |
794 | + default: | |
795 | + code = KRB5_BAD_ENCTYPE; | |
796 | + goto out; | |
797 | + } | |
798 | + | |
799 | + /* allocate memory for output key */ | |
800 | + if ((out->contents = malloc(keylength)) == NULL) { | |
801 | + code = ENOMEM; | |
802 | + goto out; | |
803 | + } | |
804 | + out->length = keylength; | |
805 | + out->enctype = in->enctype; | |
806 | + | |
807 | + datain.data = (char *) constant_data; | |
808 | + datain.length = K5CLENGTH; | |
809 | + | |
810 | + datain.data[0] = (usage>>24)&0xff; | |
811 | + datain.data[1] = (usage>>16)&0xff; | |
812 | + datain.data[2] = (usage>>8)&0xff; | |
813 | + datain.data[3] = usage&0xff; | |
814 | + | |
815 | + datain.data[4] = (char) extra; | |
816 | + | |
817 | + if ((code = krb5_derive_key(enc, in, out, &datain))) { | |
818 | + free(out->contents); | |
819 | + out->contents = NULL; | |
820 | + } | |
821 | + | |
822 | + out: | |
823 | + if (code) | |
824 | + printerr(0, "ERROR: derive_key returning error %d (%s)\n", | |
825 | + code, error_message(code)); | |
826 | + return (code); | |
827 | +} | |
828 | + | |
829 | +/* | |
830 | * We really shouldn't know about glue-layer context structure, but | |
831 | * we need to get at the real krb5 context pointer. This should be | |
832 | * removed as soon as we say there is no support for MIT Kerberos | |
833 | @@ -315,45 +683,114 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss | |
834 | { | |
835 | krb5_gss_ctx_id_t kctx = ((gss_union_ctx_id_t)ctx)->internal_ctx_id; | |
836 | char *p, *end; | |
837 | - static int constant_one = 1; | |
838 | static int constant_zero = 0; | |
839 | + static int constant_one = 1; | |
840 | + static int constant_two = 2; | |
841 | uint32_t word_seq_send; | |
842 | + u_int64_t seq_send_64bit; | |
843 | + uint32_t v2_flags = 0; | |
844 | + krb5_keyblock derived_key; | |
845 | + uint32_t numkeys; | |
846 | ||
847 | if (!(buf->value = calloc(1, MAX_CTX_LEN))) | |
848 | goto out_err; | |
849 | p = buf->value; | |
850 | end = buf->value + MAX_CTX_LEN; | |
851 | ||
852 | - if (kctx->initiate) { | |
853 | - if (WRITE_BYTES(&p, end, constant_one)) goto out_err; | |
854 | - } | |
855 | - else { | |
856 | - if (WRITE_BYTES(&p, end, constant_zero)) goto out_err; | |
857 | - } | |
858 | - if (kctx->seed_init) { | |
859 | - if (WRITE_BYTES(&p, end, constant_one)) goto out_err; | |
860 | - } | |
861 | - else { | |
862 | - if (WRITE_BYTES(&p, end, constant_zero)) goto out_err; | |
863 | - } | |
864 | - if (write_bytes(&p, end, &kctx->seed, sizeof(kctx->seed))) | |
865 | - goto out_err; | |
866 | - if (WRITE_BYTES(&p, end, kctx->signalg)) goto out_err; | |
867 | - if (WRITE_BYTES(&p, end, kctx->sealalg)) goto out_err; | |
868 | - if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err; | |
869 | - word_seq_send = kctx->seq_send; | |
870 | - if (WRITE_BYTES(&p, end, word_seq_send)) goto out_err; | |
871 | - if (write_buffer(&p, end, kctx->mech_used)) goto out_err; | |
872 | - | |
873 | - printerr(2, "serialize_krb5_ctx: serializing keys with " | |
874 | - "enctype %d and length %d\n", | |
875 | - kctx->enc->enctype, kctx->enc->length); | |
876 | + switch (kctx->sealalg) { | |
877 | + case SEAL_ALG_DES: | |
878 | + /* Versions 0 and 1 */ | |
879 | + if (kctx->initiate) { | |
880 | + if (WRITE_BYTES(&p, end, constant_one)) goto out_err; | |
881 | + } | |
882 | + else { | |
883 | + if (WRITE_BYTES(&p, end, constant_zero)) goto out_err; | |
884 | + } | |
885 | + if (kctx->seed_init) { | |
886 | + if (WRITE_BYTES(&p, end, constant_one)) goto out_err; | |
887 | + } | |
888 | + else { | |
889 | + if (WRITE_BYTES(&p, end, constant_zero)) goto out_err; | |
890 | + } | |
891 | + if (write_bytes(&p, end, &kctx->seed, sizeof(kctx->seed))) | |
892 | + goto out_err; | |
893 | + if (WRITE_BYTES(&p, end, kctx->signalg)) goto out_err; | |
894 | + if (WRITE_BYTES(&p, end, kctx->sealalg)) goto out_err; | |
895 | + if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err; | |
896 | + word_seq_send = kctx->seq_send; | |
897 | + if (WRITE_BYTES(&p, end, word_seq_send)) goto out_err; | |
898 | + if (write_buffer(&p, end, kctx->mech_used)) goto out_err; | |
899 | + | |
900 | + printerr(2, "serialize_krb5_ctx: serializing keys with " | |
901 | + "enctype %d and length %d\n", | |
902 | + kctx->enc->enctype, kctx->enc->length); | |
903 | ||
904 | - if (write_keyblock(&p, end, kctx->enc)) goto out_err; | |
905 | - if (write_keyblock(&p, end, kctx->seq)) goto out_err; | |
906 | + if (write_keyblock(&p, end, kctx->enc)) goto out_err; | |
907 | + if (write_keyblock(&p, end, kctx->seq)) goto out_err; | |
908 | + break; | |
909 | + case SEAL_ALG_MICROSOFT_RC4: | |
910 | + case SEAL_ALG_DES3KD: | |
911 | + /* u32 version; ( 2 ) | |
912 | + * s32 endtime; | |
913 | + * u32 flags; | |
914 | + * #define KRB5_CTX_FLAG_INITIATOR 0x00000001 | |
915 | + * #define KRB5_CTX_FLAG_CFX 0x00000002 | |
916 | + * #define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004 | |
917 | + * u64 seq_send; | |
918 | + * u32 enctype; | |
919 | + * u32 size_of_each_key; ( size in bytes ) | |
920 | + * u32 number_of_keys; ( N (assumed to be 3 for now) ) | |
921 | + * keydata-1; ( Ke (Kenc for DES3) ) | |
922 | + * keydata-2; ( Ki (Kseq for DES3) ) | |
923 | + * keydata-3; ( Kc (derived checksum key) ) | |
924 | + */ | |
925 | + /* Version 2 */ | |
926 | + if (WRITE_BYTES(&p, end , constant_two)) goto out_err; | |
927 | + if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err; | |
928 | + | |
929 | + /* Only applicable flag for is initiator */ | |
930 | + if (kctx->initiate) v2_flags |= KRB5_CTX_FLAG_INITIATOR; | |
931 | + if (WRITE_BYTES(&p, end, v2_flags)) goto out_err; | |
932 | + | |
933 | + seq_send_64bit = kctx->seq_send; | |
934 | + if (WRITE_BYTES(&p, end, seq_send_64bit)) goto out_err; | |
935 | + | |
936 | + if (WRITE_BYTES(&p, end, kctx->enc->enctype)) goto out_err; | |
937 | + if (WRITE_BYTES(&p, end, kctx->enc->length)) goto out_err; | |
938 | + numkeys = 3; | |
939 | + if (WRITE_BYTES(&p, end, numkeys)) goto out_err; | |
940 | + printerr(2, "serialize_krb5_ctx: serializing %d keys with " | |
941 | + "enctype %d and size %d\n", | |
942 | + numkeys, kctx->enc->enctype, kctx->enc->length); | |
943 | + | |
944 | + /* Ke */ | |
945 | + if (write_bytes(&p, end, kctx->enc->contents, | |
946 | + kctx->enc->length)) | |
947 | + goto out_err; | |
948 | + | |
949 | + /* Ki */ | |
950 | + if (write_bytes(&p, end, kctx->enc->contents, | |
951 | + kctx->enc->length)) | |
952 | + goto out_err; | |
953 | + | |
954 | + /* Kc */ | |
955 | + if (derive_key(kctx->seq, &derived_key, | |
956 | + KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM)) | |
957 | + goto out_err; | |
958 | + if (write_bytes(&p, end, derived_key.contents, | |
959 | + derived_key.length)) | |
960 | + goto out_err; | |
961 | + free(derived_key.contents); | |
962 | + break; | |
963 | + default: | |
964 | + printerr(0, "ERROR: serialize_krb5_ctx: unsupported seal " | |
965 | + "algorithm %d\n", kctx->sealalg); | |
966 | + goto out_err; | |
967 | + } | |
968 | ||
969 | buf->length = p - (char *)buf->value; | |
970 | return 0; | |
971 | + | |
972 | out_err: | |
973 | printerr(0, "ERROR: failed serializing krb5 context for kernel\n"); | |
974 | if (buf->value) free(buf->value); | |
975 | diff -puN utils/gssd/write_bytes.h~CITI_NFS4_ALL utils/gssd/write_bytes.h | |
976 | --- nfs-utils-1.0.8/utils/gssd/write_bytes.h~CITI_NFS4_ALL 2006-04-20 12:41:16.867750000 -0400 | |
977 | +++ nfs-utils-1.0.8-kwc/utils/gssd/write_bytes.h 2006-04-20 12:41:16.905712000 -0400 | |
978 | @@ -63,6 +63,19 @@ write_buffer(char **p, char *end, gss_bu | |
979 | return 0; | |
980 | } | |
981 | ||
982 | +inline static int | |
983 | +write_oid(char **p, char *end, gss_OID_desc *arg) | |
984 | +{ | |
985 | + int len = (int)arg->length; /* make an int out of size_t */ | |
986 | + if (WRITE_BYTES(p, end, len)) | |
987 | + return -1; | |
988 | + if (*p + arg->length > end) | |
989 | + return -1; | |
990 | + memcpy(*p, arg->elements, len); | |
991 | + *p += len; | |
992 | + return 0; | |
993 | +} | |
994 | + | |
995 | static inline int | |
996 | get_bytes(char **ptr, const char *end, void *res, int len) | |
997 | { | |
998 | diff -puN utils/gssd/svcgssd_proc.c~CITI_NFS4_ALL utils/gssd/svcgssd_proc.c | |
999 | --- nfs-utils-1.0.8/utils/gssd/svcgssd_proc.c~CITI_NFS4_ALL 2006-04-20 12:41:17.109514000 -0400 | |
1000 | +++ nfs-utils-1.0.8-kwc/utils/gssd/svcgssd_proc.c 2006-04-20 12:41:17.133514000 -0400 | |
1001 | @@ -220,8 +220,21 @@ get_ids(gss_name_t client_name, gss_OID | |
1002 | nfs4_init_name_mapping(NULL); /* XXX: should only do this once */ | |
1003 | res = nfs4_gss_princ_to_ids(secname, sname, &uid, &gid); | |
1004 | if (res < 0) { | |
1005 | - printerr(0, "WARNING: get_ids: unable to map " | |
1006 | - "name '%s' to a uid\n", sname); | |
1007 | + /* | |
1008 | + * -ENOENT means there was no mapping, any other error | |
1009 | + * value means there was an error trying to do the | |
1010 | + * mapping. | |
1011 | + */ | |
1012 | + if (res == -ENOENT) { | |
1013 | + cred->cr_uid = -2; /* XXX */ | |
1014 | + cred->cr_gid = -2; /* XXX */ | |
1015 | + cred->cr_groups[0] = -2;/* XXX */ | |
1016 | + cred->cr_ngroups = 1; | |
1017 | + res = 0; | |
1018 | + goto out_free; | |
1019 | + } | |
1020 | + printerr(0, "WARNING: get_ids: failed to map name '%s' " | |
1021 | + "to uid/gid: %s\n", sname, strerror(-res)); | |
1022 | goto out_free; | |
1023 | } | |
1024 | cred->cr_uid = uid; | |
1025 | ||
1026 | _ |