get_creds.c (505d05c7) | get_creds.c (159d09a2) |
---|---|
1/* | 1/* |
2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. | 2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. |
3 * Use is subject to license terms. 4 */ 5 | 3 * Use is subject to license terms. 4 */ 5 |
6#pragma ident "%Z%%M% %I% %E% SMI" | |
7 8/* 9 * lib/krb5/krb/get_creds.c 10 * 11 * Copyright 1990 by the Massachusetts Institute of Technology. 12 * All Rights Reserved. 13 * 14 * Export of this software from the United States of America may 15 * require a specific license from the United States Government. 16 * It is the responsibility of any person or organization contemplating 17 * export to obtain such a license before exporting. | 6 7/* 8 * lib/krb5/krb/get_creds.c 9 * 10 * Copyright 1990 by the Massachusetts Institute of Technology. 11 * All Rights Reserved. 12 * 13 * Export of this software from the United States of America may 14 * require a specific license from the United States Government. 15 * It is the responsibility of any person or organization contemplating 16 * export to obtain such a license before exporting. |
18 * | 17 * |
19 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 20 * distribute this software and its documentation for any purpose and 21 * without fee is hereby granted, provided that the above copyright 22 * notice appear in all copies and that both that copyright notice and 23 * this permission notice appear in supporting documentation, and that 24 * the name of M.I.T. not be used in advertising or publicity pertaining 25 * to distribution of the software without specific, written prior 26 * permission. Furthermore if you modify this software you must label 27 * your software as modified software and not distribute it in such a 28 * fashion that it might be confused with the original M.I.T. software. 29 * M.I.T. makes no representations about the suitability of 30 * this software for any purpose. It is provided "as is" without express 31 * or implied warranty. | 18 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 19 * distribute this software and its documentation for any purpose and 20 * without fee is hereby granted, provided that the above copyright 21 * notice appear in all copies and that both that copyright notice and 22 * this permission notice appear in supporting documentation, and that 23 * the name of M.I.T. not be used in advertising or publicity pertaining 24 * to distribution of the software without specific, written prior 25 * permission. Furthermore if you modify this software you must label 26 * your software as modified software and not distribute it in such a 27 * fashion that it might be confused with the original M.I.T. software. 28 * M.I.T. makes no representations about the suitability of 29 * this software for any purpose. It is provided "as is" without express 30 * or implied warranty. |
31 * |
|
32 * | 32 * |
33 * | |
34 * krb5_get_credentials() 35 */ 36 37 38 39/* 40 Attempts to use the credentials cache or TGS exchange to get an additional 41 ticket for the 42 client identified by in_creds->client, the server identified by 43 in_creds->server, with options options, expiration date specified in 44 in_creds->times.endtime (0 means as long as possible), session key type 45 specified in in_creds->keyblock.enctype (if non-zero) 46 47 Any returned ticket and intermediate ticket-granting tickets are 48 stored in ccache. 49 50 returns errors from encryption routines, system errors 51 */ 52 | 33 * krb5_get_credentials() 34 */ 35 36 37 38/* 39 Attempts to use the credentials cache or TGS exchange to get an additional 40 ticket for the 41 client identified by in_creds->client, the server identified by 42 in_creds->server, with options options, expiration date specified in 43 in_creds->times.endtime (0 means as long as possible), session key type 44 specified in in_creds->keyblock.enctype (if non-zero) 45 46 Any returned ticket and intermediate ticket-granting tickets are 47 stored in ccache. 48 49 returns errors from encryption routines, system errors 50 */ 51 |
53#include <k5-int.h> | 52#include "k5-int.h" |
54 55/*ARGSUSED*/ 56static krb5_error_code 57krb5_get_credentials_core(krb5_context context, krb5_flags options, 58 krb5_creds *in_creds, krb5_creds *mcreds, 59 krb5_flags *fields) 60{ | 53 54/*ARGSUSED*/ 55static krb5_error_code 56krb5_get_credentials_core(krb5_context context, krb5_flags options, 57 krb5_creds *in_creds, krb5_creds *mcreds, 58 krb5_flags *fields) 59{ |
60 /* Solaris Kerberos */ |
|
61 krb5_error_code ret = 0; 62 63 if (!in_creds || !in_creds->server || !in_creds->client) 64 return EINVAL; 65 66 memset((char *)mcreds, 0, sizeof(krb5_creds)); 67 mcreds->magic = KV5M_CREDS; 68 /* | 61 krb5_error_code ret = 0; 62 63 if (!in_creds || !in_creds->server || !in_creds->client) 64 return EINVAL; 65 66 memset((char *)mcreds, 0, sizeof(krb5_creds)); 67 mcreds->magic = KV5M_CREDS; 68 /* |
69 * Solaris Kerberos: |
|
69 * Set endtime appropriately to make sure we do not rope in 70 * expired creds. If endtime is set to 0 (which it almost always 71 * is, courtesy memset/calloc) the krb5_cc_retrieve_cred() call in 72 * krb5_get_credentials() with KRB5_TC_MATCH_TIMES will 73 * succeed and return the expired cred. 74 * 75 * Hence, endtime below is set to "now" if in_creds->times.endtime 76 * is 0, so that krb5_cc_retrieve_cred fails and we get fresh creds, --- 8 unchanged lines hidden (view full) --- 85 ret = krb5_copy_keyblock_data(context, &in_creds->keyblock, 86 &mcreds->keyblock); 87 if (ret) 88 return (ret); 89 90 mcreds->authdata = in_creds->authdata; 91 mcreds->server = in_creds->server; 92 mcreds->client = in_creds->client; | 70 * Set endtime appropriately to make sure we do not rope in 71 * expired creds. If endtime is set to 0 (which it almost always 72 * is, courtesy memset/calloc) the krb5_cc_retrieve_cred() call in 73 * krb5_get_credentials() with KRB5_TC_MATCH_TIMES will 74 * succeed and return the expired cred. 75 * 76 * Hence, endtime below is set to "now" if in_creds->times.endtime 77 * is 0, so that krb5_cc_retrieve_cred fails and we get fresh creds, --- 8 unchanged lines hidden (view full) --- 86 ret = krb5_copy_keyblock_data(context, &in_creds->keyblock, 87 &mcreds->keyblock); 88 if (ret) 89 return (ret); 90 91 mcreds->authdata = in_creds->authdata; 92 mcreds->server = in_creds->server; 93 mcreds->client = in_creds->client; |
93 | 94 |
94 *fields = KRB5_TC_MATCH_TIMES /*XXX |KRB5_TC_MATCH_SKEY_TYPE */ 95 | KRB5_TC_MATCH_AUTHDATA 96 | KRB5_TC_SUPPORTED_KTYPES; 97 if (mcreds->keyblock.enctype) { 98 krb5_enctype *ktypes; 99 int i; 100 101 *fields |= KRB5_TC_MATCH_KTYPE; 102 ret = krb5_get_tgs_ktypes (context, mcreds->server, &ktypes); 103 for (i = 0; ktypes[i]; i++) | 95 *fields = KRB5_TC_MATCH_TIMES /*XXX |KRB5_TC_MATCH_SKEY_TYPE */ 96 | KRB5_TC_MATCH_AUTHDATA 97 | KRB5_TC_SUPPORTED_KTYPES; 98 if (mcreds->keyblock.enctype) { 99 krb5_enctype *ktypes; 100 int i; 101 102 *fields |= KRB5_TC_MATCH_KTYPE; 103 ret = krb5_get_tgs_ktypes (context, mcreds->server, &ktypes); 104 for (i = 0; ktypes[i]; i++) |
104 if (ktypes[i] == mcreds->keyblock.enctype) | 105 if (ktypes[i] == mcreds->keyblock.enctype) |
105 break; 106 if (ktypes[i] == 0) | 106 break; 107 if (ktypes[i] == 0) |
107 ret = KRB5_CC_NOT_KTYPE; | 108 ret = KRB5_CC_NOT_KTYPE; |
108 free (ktypes); 109 if (ret) | 109 free (ktypes); 110 if (ret) |
110 return ret; | 111 return ret; |
111 } 112 if (options & KRB5_GC_USER_USER) { 113 /* also match on identical 2nd tkt and tkt encrypted in a 114 session key */ 115 *fields |= KRB5_TC_MATCH_2ND_TKT|KRB5_TC_MATCH_IS_SKEY; 116 mcreds->is_skey = TRUE; 117 mcreds->second_ticket = in_creds->second_ticket; 118 if (!in_creds->second_ticket.length) --- 23 unchanged lines hidden (view full) --- 142 143 if ((ncreds = (krb5_creds *)malloc(sizeof(krb5_creds))) == NULL) 144 return ENOMEM; 145 146 memset((char *)ncreds, 0, sizeof(krb5_creds)); 147 ncreds->magic = KV5M_CREDS; 148 149 /* The caller is now responsible for cleaning up in_creds */ | 112 } 113 if (options & KRB5_GC_USER_USER) { 114 /* also match on identical 2nd tkt and tkt encrypted in a 115 session key */ 116 *fields |= KRB5_TC_MATCH_2ND_TKT|KRB5_TC_MATCH_IS_SKEY; 117 mcreds->is_skey = TRUE; 118 mcreds->second_ticket = in_creds->second_ticket; 119 if (!in_creds->second_ticket.length) --- 23 unchanged lines hidden (view full) --- 143 144 if ((ncreds = (krb5_creds *)malloc(sizeof(krb5_creds))) == NULL) 145 return ENOMEM; 146 147 memset((char *)ncreds, 0, sizeof(krb5_creds)); 148 ncreds->magic = KV5M_CREDS; 149 150 /* The caller is now responsible for cleaning up in_creds */ |
151 /* Solaris Kerberos */ |
|
150 if ((retval = krb5_cc_retrieve_cred(context, ccache, fields, &mcreds, 151 ncreds)) !=0) { 152 krb5_xfree(ncreds); 153 ncreds = in_creds; 154 } else { 155 *out_creds = ncreds; 156 } 157 --- 6 unchanged lines hidden (view full) --- 164 else 165 not_ktype = 0; 166 167 retval = krb5_get_cred_from_kdc(context, ccache, ncreds, out_creds, &tgts); 168 if (tgts) { 169 register int i = 0; 170 krb5_error_code rv2; 171 while (tgts[i]) { | 152 if ((retval = krb5_cc_retrieve_cred(context, ccache, fields, &mcreds, 153 ncreds)) !=0) { 154 krb5_xfree(ncreds); 155 ncreds = in_creds; 156 } else { 157 *out_creds = ncreds; 158 } 159 --- 6 unchanged lines hidden (view full) --- 166 else 167 not_ktype = 0; 168 169 retval = krb5_get_cred_from_kdc(context, ccache, ncreds, out_creds, &tgts); 170 if (tgts) { 171 register int i = 0; 172 krb5_error_code rv2; 173 while (tgts[i]) { |
174 /* Solaris Kerberos */ |
|
172 if ((rv2 = krb5_cc_store_cred(context, ccache, tgts[i])) != 0) { 173 retval = rv2; 174 break; 175 } 176 i++; 177 } 178 krb5_free_tgt_creds(context, tgts); 179 } --- 7 unchanged lines hidden (view full) --- 187 * krb5_get_cred_from_kdc() is semantically incorrect, since the 188 * actual failure was the non-existence of a ticket of the correct 189 * enctype rather than the missing TGT. 190 */ 191 if ((retval == KRB5_CC_NOTFOUND || retval == KRB5_CC_NOT_KTYPE) 192 && not_ktype) 193 retval = KRB5_CC_NOT_KTYPE; 194 | 175 if ((rv2 = krb5_cc_store_cred(context, ccache, tgts[i])) != 0) { 176 retval = rv2; 177 break; 178 } 179 i++; 180 } 181 krb5_free_tgt_creds(context, tgts); 182 } --- 7 unchanged lines hidden (view full) --- 190 * krb5_get_cred_from_kdc() is semantically incorrect, since the 191 * actual failure was the non-existence of a ticket of the correct 192 * enctype rather than the missing TGT. 193 */ 194 if ((retval == KRB5_CC_NOTFOUND || retval == KRB5_CC_NOT_KTYPE) 195 && not_ktype) 196 retval = KRB5_CC_NOT_KTYPE; 197 |
195 if (!retval) | 198 if (!retval) { 199 /* the purpose of the krb5_get_credentials call is to 200 * obtain a set of credentials for the caller. the 201 * krb5_cc_store_cred() call is to optimize performance 202 * for future calls. Ignore any errors, since the credentials 203 * are still valid even if we fail to store them in the cache. 204 */ 205 /* Solaris Kerberos */ |
196 retval = krb5_cc_store_cred(context, ccache, *out_creds); | 206 retval = krb5_cc_store_cred(context, ccache, *out_creds); |
207 } |
|
197 return retval; 198} 199 200#define INT_GC_VALIDATE 1 201#define INT_GC_RENEW 2 202 203/*ARGSUSED*/ | 208 return retval; 209} 210 211#define INT_GC_VALIDATE 1 212#define INT_GC_RENEW 2 213 214/*ARGSUSED*/ |
204static krb5_error_code | 215static krb5_error_code |
205krb5_get_credentials_val_renew_core(krb5_context context, krb5_flags options, 206 krb5_ccache ccache, krb5_creds *in_creds, 207 krb5_creds **out_creds, int which) 208{ 209 krb5_error_code retval; 210 krb5_principal tmp; 211 krb5_creds **tgts = 0; 212 213 switch(which) { 214 case INT_GC_VALIDATE: | 216krb5_get_credentials_val_renew_core(krb5_context context, krb5_flags options, 217 krb5_ccache ccache, krb5_creds *in_creds, 218 krb5_creds **out_creds, int which) 219{ 220 krb5_error_code retval; 221 krb5_principal tmp; 222 krb5_creds **tgts = 0; 223 224 switch(which) { 225 case INT_GC_VALIDATE: |
215 retval = krb5_get_cred_from_kdc_validate(context, ccache, | 226 retval = krb5_get_cred_from_kdc_validate(context, ccache, |
216 in_creds, out_creds, &tgts); 217 break; 218 case INT_GC_RENEW: | 227 in_creds, out_creds, &tgts); 228 break; 229 case INT_GC_RENEW: |
219 retval = krb5_get_cred_from_kdc_renew(context, ccache, | 230 retval = krb5_get_cred_from_kdc_renew(context, ccache, |
220 in_creds, out_creds, &tgts); 221 break; 222 default: 223 /* Should never happen */ 224 retval = 255; 225 break; 226 } 227 if (retval) return retval; 228 if (tgts) krb5_free_tgt_creds(context, tgts); 229 230 retval = krb5_cc_get_principal(context, ccache, &tmp); 231 if (retval) return retval; | 231 in_creds, out_creds, &tgts); 232 break; 233 default: 234 /* Should never happen */ 235 retval = 255; 236 break; 237 } 238 if (retval) return retval; 239 if (tgts) krb5_free_tgt_creds(context, tgts); 240 241 retval = krb5_cc_get_principal(context, ccache, &tmp); 242 if (retval) return retval; |
232 | 243 |
233 retval = krb5_cc_initialize(context, ccache, tmp); | 244 retval = krb5_cc_initialize(context, ccache, tmp); |
245 /* Solaris Kerberos */ |
|
234 if (retval) { 235 krb5_free_principal(context, tmp); 236 return retval; 237 } 238 239 retval = krb5_cc_store_cred(context, ccache, *out_creds); 240 krb5_free_principal(context, tmp); 241 return retval; 242} 243 244krb5_error_code KRB5_CALLCONV 245krb5_get_credentials_validate(krb5_context context, krb5_flags options, 246 krb5_ccache ccache, krb5_creds *in_creds, 247 krb5_creds **out_creds) 248{ | 246 if (retval) { 247 krb5_free_principal(context, tmp); 248 return retval; 249 } 250 251 retval = krb5_cc_store_cred(context, ccache, *out_creds); 252 krb5_free_principal(context, tmp); 253 return retval; 254} 255 256krb5_error_code KRB5_CALLCONV 257krb5_get_credentials_validate(krb5_context context, krb5_flags options, 258 krb5_ccache ccache, krb5_creds *in_creds, 259 krb5_creds **out_creds) 260{ |
249 return(krb5_get_credentials_val_renew_core(context, options, ccache, 250 in_creds, out_creds, | 261 return(krb5_get_credentials_val_renew_core(context, options, ccache, 262 in_creds, out_creds, |
251 INT_GC_VALIDATE)); 252} 253 254krb5_error_code KRB5_CALLCONV 255krb5_get_credentials_renew(krb5_context context, krb5_flags options, 256 krb5_ccache ccache, krb5_creds *in_creds, 257 krb5_creds **out_creds) 258{ 259 | 263 INT_GC_VALIDATE)); 264} 265 266krb5_error_code KRB5_CALLCONV 267krb5_get_credentials_renew(krb5_context context, krb5_flags options, 268 krb5_ccache ccache, krb5_creds *in_creds, 269 krb5_creds **out_creds) 270{ 271 |
260 return(krb5_get_credentials_val_renew_core(context, options, ccache, 261 in_creds, out_creds, | 272 return(krb5_get_credentials_val_renew_core(context, options, ccache, 273 in_creds, out_creds, |
262 INT_GC_RENEW)); 263} 264 265static krb5_error_code 266krb5_validate_or_renew_creds(krb5_context context, krb5_creds *creds, 267 krb5_principal client, krb5_ccache ccache, 268 char *in_tkt_service, int validate) 269{ --- 38 unchanged lines hidden (view full) --- 308 KRB5_TGS_NAME, 309 in_creds.client->realm.length, 310 in_creds.client->realm.data, 311 0))) 312 goto cleanup; 313 } 314 315 if (validate) | 274 INT_GC_RENEW)); 275} 276 277static krb5_error_code 278krb5_validate_or_renew_creds(krb5_context context, krb5_creds *creds, 279 krb5_principal client, krb5_ccache ccache, 280 char *in_tkt_service, int validate) 281{ --- 38 unchanged lines hidden (view full) --- 320 KRB5_TGS_NAME, 321 in_creds.client->realm.length, 322 in_creds.client->realm.data, 323 0))) 324 goto cleanup; 325 } 326 327 if (validate) |
316 ret = krb5_get_cred_from_kdc_validate(context, ccache, | 328 ret = krb5_get_cred_from_kdc_validate(context, ccache, |
317 &in_creds, &out_creds, &tgts); 318 else | 329 &in_creds, &out_creds, &tgts); 330 else |
319 ret = krb5_get_cred_from_kdc_renew(context, ccache, | 331 ret = krb5_get_cred_from_kdc_renew(context, ccache, |
320 &in_creds, &out_creds, &tgts); | 332 &in_creds, &out_creds, &tgts); |
321 | 333 |
322 /* ick. copy the struct contents, free the container */ 323 if (out_creds) { 324 *creds = *out_creds; 325 krb5_xfree(out_creds); 326 } 327 328cleanup: 329 --- 21 unchanged lines hidden --- | 334 /* ick. copy the struct contents, free the container */ 335 if (out_creds) { 336 *creds = *out_creds; 337 krb5_xfree(out_creds); 338 } 339 340cleanup: 341 --- 21 unchanged lines hidden --- |