A great dela has changed about the client AS-REQ code since 2003, but this criticism remains valid. I'm taking a closer look at this in the context of ticket 7721 (PR 1300).
There are currently four places we could conceivably do the fallback to primary KDC in the initial tickets code:
1. In the password and keytab API implementations, where it is now.
2. In k5_get_init_creds() (a descendant of 1.3's krb5_get_init_creds()).
3. In krb5_init_creds_get(), the function that runs krb5_init_creds_step() until the state machine completes.
4. Inside the stepwise state machine.
Option 4 has some big challenges: krb5_init_creds_step() doesn't currently tell the caller whether to send to the primary KDC, and it doesn't know which KDCs its input packets came from, so it can't internally determine whether the realms it wanted to talk to had primary KDCs or whether the answers it got already came from primary KDCs. There might be ways around this obstacle, but there aren't any obvious advantages to justify the high complexity cost (especially as IAKERB has no way for the initiator to tell the acceptor to use a primary KDC).
Option 3 also has a big challenge: the init_creds state machine has already been instantiated, and there is currently no way to reset an already instantiated state to run it a second time.
Option 2 has a small challenge: krb5_get_init_creds_keytab() doesn't use k5_get_init_creds() any more. This changed in commit d1da158f47ea604bed4d5db5e98a976a9e54ccd0 because we wanted to add request enctype manipulation to krb5_init_creds_set_keytab() and have that logic also apply when using krb5_get_init_creds_keytab(). We could add a keytab parameter to k5_get_init_creds(). It feels a bit wrong to call "up" into gic_keytab.c from get_in_tkt.c, but it doesn't pose a practical issue.
Another minor wrinkle is the password change sequence in krb5_get_init_creds_password(). If we fall back to the primary KDC and get a KRB5KDC_ERR_KEY_EXP error, we remember that we talked to a primary KDC and only talk to the primary KDC when getting the kadmin/changepw ticket and when trying again after the password change. But this seems like a really unimportant optimization; if k5_get_init_creds() handled primary KDC fallback internally, there would be no visible harm from just calling it after the password change and letting it fall back if necessary. If we really cared, k5_get_init_creds() could communicate back to the caller whether it fell back to a primary KDC and got its answer from that.
Option 1