Canonical clients in AS-REQ for non-TGS server principals

Jeffrey Altman jaltman at
Tue Feb 7 11:14:27 EST 2017

On 2/7/2017 9:58 AM, Jakob Uhd Jepsen wrote:
> I have run into a limitation of the AS-REQ protocol, when used with 
> canonical clients, that I am not sure why exists. Our code is using v 
> 1.12.1 kerberos, though from what I can tell, this bit has not been 
> changed in a long time and is still present in the latest release 
> version. It was introduced back in 2009 in commit 
> 589ad211b633c9319a074c032c47db6b7bd62237
> The relevant method is verify_as_reply in get_in_tkt.c
> What I am attempting to do, it use an AS-REQ/AS-REP exchange to get a 
> ticket from an NT-ENTERPRISE client to a service, that is *not* the TGS 
> service. I do not want a TGT, but a direct service ticket. I also want 
> the client to be the canonical client. It seems this is not allowed, and 
> I am trying to understand why. There are no cross-realm shennanigans in 
> out setup to complicate matters.
> (For context, I've pasted in the relevant code at the bottom of this).
> Specifically, the canon_req field is set for a canonicalize request or 
> an enterprise client. In the case of client canoncialization, both of 
> these will be true. Yet due to the stipulation that the server principal 
> be a TGS for canon_ok to be true, we end up in the if branch following 
> this. Here, the AS-REP is checked to see if the request client and the 
> as_reply client are identical. If the KDC canonicalized the client, this 
> may not be the case, and the whole exchanged ends up with a 
> It doesn't seem that the intent of the comment to prevent servers to 
> change, matches the full effect of the code, when used in this manner. 
> Is there are reason I'm not seeing, why canonicalizing client names in 
> this instance should not be allowed?
>   /*
>       * We only allow the AS-REP server name to be changed if the
>       * caller set the canonicalize flag (or requested an enterprise
>       * principal) and we requested (and received) a TGT.
>       */
>      canon_req = ((request->kdc_options & KDC_OPT_CANONICALIZE) != 0) ||
>          request->client->type == KRB5_NT_ENTERPRISE_PRINCIPAL ||
>          (request->kdc_options & KDC_OPT_REQUEST_ANONYMOUS);
>      if (canon_req) {
>          canon_ok = IS_TGS_PRINC(request->server) &&
>              IS_TGS_PRINC(as_reply->enc_part2->server);
>          if (!canon_ok && (request->kdc_options & 
>              canon_ok = krb5_principal_compare_any_realm(context,
> as_reply->client,
> krb5_anonymous_principal());
>          }
>      } else
>          canon_ok = 0;
>      if ((!canon_ok &&
>           (!krb5_principal_compare(context, as_reply->client, 
> request->client) ||
>            !krb5_principal_compare(context, as_reply->enc_part2->server, 
> request->server)))
>          || !krb5_principal_compare(context, 
> as_reply->enc_part2->server, as_reply->ticket->server)
>          ....
>         <SNIP>
>         .....
>    } return KRB5_KDCREP_MODIFIED;

I have not looked at the history but it sounds to me that the test
should be whether or not the ticket returned from the KDC is an initial
ticket, not whether or not it is a TGT.

That said, there may be a historical reason why the behavior was
restricted to TGTs.

Jeffrey Altman


-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4081 bytes
Desc: S/MIME Cryptographic Signature
Url :

More information about the krbdev mailing list