Add start_realm cc config
This commit is contained in:
		| @@ -639,7 +639,12 @@ krb5_cc_initialize(krb5_context context, | ||||
| 		   krb5_ccache id, | ||||
| 		   krb5_principal primary_principal) | ||||
| { | ||||
|     return (*id->ops->init)(context, id, primary_principal); | ||||
|     krb5_error_code ret; | ||||
|  | ||||
|     ret = (*id->ops->init)(context, id, primary_principal); | ||||
|     if (ret == 0) | ||||
|         id->initialized = 1; | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -696,7 +701,36 @@ krb5_cc_store_cred(krb5_context context, | ||||
| 		   krb5_ccache id, | ||||
| 		   krb5_creds *creds) | ||||
| { | ||||
|     return (*id->ops->store)(context, id, creds); | ||||
|     krb5_error_code ret; | ||||
|     krb5_data realm; | ||||
|  | ||||
|     ret = (*id->ops->store)(context, id, creds); | ||||
|  | ||||
|     /* Look for and mark the first root TGT's realm as the start realm */ | ||||
|     if (ret == 0 && id->initialized && | ||||
|         !krb5_is_config_principal(context, creds->server) && | ||||
|         krb5_principal_is_root_krbtgt(context, creds->server)) { | ||||
|  | ||||
|         id->initialized = 1; | ||||
|         realm.length = strlen(creds->server->realm) + 1; | ||||
|         realm.data = creds->server->realm; | ||||
|         (void) krb5_cc_set_config(context, id, NULL, "start_realm", &realm); | ||||
|     } else if (ret == 0 && id->initialized && | ||||
|         krb5_is_config_principal(context, creds->server) && | ||||
|         strcmp(creds->server->name.name_string.val[1], "start_realm") == 0) { | ||||
|  | ||||
|         /* | ||||
|          * But if the caller is storing a start_realm ccconfig, then | ||||
|          * stop looking for root TGTs to mark as the start_realm. | ||||
|          * | ||||
|          * By honoring any start_realm cc config stored, we interop | ||||
|          * both, with ccache implementations that don't preserve | ||||
|          * insertion order, and Kerberos implementations that store this | ||||
|          * cc config before the TGT. | ||||
|          */ | ||||
|         id->initialized = 1; | ||||
|     } | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -1679,6 +1713,11 @@ krb5_cc_get_lifetime(krb5_context context, krb5_ccache id, time_t *t) | ||||
| 	/** | ||||
| 	 * If we find a krbtgt in the cache, use that as the lifespan. | ||||
| 	 */ | ||||
|         /* | ||||
|          * FIXME We should try to find the start_realm cc config and | ||||
|          * look for root TGTs for that realm instead of any random | ||||
|          * (first) root TGT. | ||||
|          */ | ||||
| 	if (krb5_principal_is_root_krbtgt(context, cred.server)) { | ||||
| 	    if (now < cred.times.endtime) | ||||
| 		endtime = cred.times.endtime; | ||||
|   | ||||
| @@ -951,7 +951,8 @@ get_cred_kdc_referral(krb5_context context, | ||||
| 		      Ticket *second_ticket, | ||||
| 		      krb5_creds **out_creds) | ||||
| { | ||||
|     krb5_const_realm client_realm; | ||||
|     krb5_realm start_realm = NULL; | ||||
|     krb5_data config_start_realm; | ||||
|     krb5_error_code ret; | ||||
|     krb5_creds tgt, referral, ticket; | ||||
|     krb5_creds **referral_tgts = NULL;  /* used for loop detection */ | ||||
| @@ -972,33 +973,49 @@ get_cred_kdc_referral(krb5_context context, | ||||
|  | ||||
|     *out_creds = NULL; | ||||
|  | ||||
|     client_realm = krb5_principal_get_realm(context, in_creds->client); | ||||
|  | ||||
|     ret = krb5_cc_get_config(context, ccache, NULL, "start_realm", &config_start_realm); | ||||
|     if (ret == 0) { | ||||
|         start_realm = strndup(config_start_realm.data, config_start_realm.length); | ||||
| 	krb5_data_free(&config_start_realm); | ||||
|     } else { | ||||
|         start_realm = strdup(krb5_principal_get_realm(context, in_creds->client)); | ||||
|     } | ||||
|     if (start_realm == NULL) | ||||
|         return krb5_enomem(context); | ||||
|  | ||||
|     /* find tgt for the clients base realm */ | ||||
|     { | ||||
| 	krb5_principal tgtname; | ||||
|  | ||||
| 	ret = krb5_make_principal(context, &tgtname, | ||||
| 				  client_realm, | ||||
| 				  start_realm, | ||||
| 				  KRB5_TGS_NAME, | ||||
| 				  client_realm, | ||||
| 				  start_realm, | ||||
| 				  NULL); | ||||
| 	if(ret) | ||||
| 	if (ret) { | ||||
|             free(start_realm); | ||||
| 	    return ret; | ||||
|         } | ||||
|  | ||||
| 	ret = find_cred(context, ccache, tgtname, NULL, &tgt); | ||||
| 	krb5_free_principal(context, tgtname); | ||||
| 	if (ret) | ||||
| 	if (ret) { | ||||
|             free(start_realm); | ||||
| 	    return ret; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     referral = *in_creds; | ||||
|     ret = krb5_copy_principal(context, in_creds->server, &referral.server); | ||||
|     if (ret) { | ||||
| 	krb5_free_cred_contents(context, &tgt); | ||||
|         free(start_realm); | ||||
| 	return ret; | ||||
|     } | ||||
|     ret = krb5_principal_set_realm(context, referral.server, client_realm); | ||||
|     ret = krb5_principal_set_realm(context, referral.server, start_realm); | ||||
|     free(start_realm); | ||||
|     start_realm = NULL; | ||||
|     if (ret) { | ||||
| 	krb5_free_cred_contents(context, &tgt); | ||||
| 	krb5_free_principal(context, referral.server); | ||||
|   | ||||
| @@ -381,6 +381,7 @@ typedef struct krb5_cccol_cursor_data *krb5_cccol_cursor; | ||||
| typedef struct krb5_ccache_data { | ||||
|     const struct krb5_cc_ops *ops; | ||||
|     krb5_data data; | ||||
|     int initialized; /* if non-zero: krb5_cc_initialize() called, now empty */ | ||||
| }krb5_ccache_data; | ||||
|  | ||||
| typedef struct krb5_ccache_data *krb5_ccache; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Nicolas Williams
					Nicolas Williams