@@ -265,24 +265,7 @@ public override ReadOnlyMemory<byte> ExecuteCore(PreAuthenticationContext contex
265265
266266 var rst = new ServiceTicketRequest
267267 {
268- // In TGS-REP, we should always reply with cname/crealm copied from the TGT, even when the Canonicalize
269- // flag is set in TGS-REQ.
270- //
271- // RFC 4120 § 3.3.3 Generation of KRB_TGS_REP Message
272- // --------------------------------------------------
273- // "By default, the address field, the client's name and realm, the list of transited realms, the time
274- // of initial authentication, the expiration time, and the authorization data of the newly-issued
275- // ticket will be copied from the TGT or renewable ticket."
276- //
277- // RFC 6806 § 6. Name Canonicalization
278- // -----------------------------------
279- // "If the "canonicalize" KDC option is set, then the KDC MAY change the client and server principal
280- // names and types in the AS response and ticket returned from those in the request. Names MUST NOT be
281- // changed in the response to a TGS request, although it is common for KDCs to maintain a set of
282- // aliases for service principals."
283- ClientName = context . Ticket . CName ,
284268 ClientRealmName = context . Ticket . CRealm ,
285-
286269 KdcAuthorizationKey = context . EvidenceTicketKey ,
287270 Principal = context . Principal ,
288271 EncryptedPartKey = context . EncryptedPartKey ,
@@ -307,17 +290,35 @@ public override ReadOnlyMemory<byte> ExecuteCore(PreAuthenticationContext contex
307290 Compatibility = this . RealmService . Settings . Compatibility ,
308291 } ;
309292
310- // The code below introduced an annoying regression in a separate party.
311- // The compatibility flag is a workaround to make sure it can use the original behavior in cases where
312- // that's expected.
313-
314- if ( ! this . RealmService . Settings . Compatibility . HasFlag ( KerberosCompatibilityFlags . DoNotCanonicalizeTgsReqFromTgt ) &&
293+ if ( this . RealmService . Settings . Compatibility . HasFlag ( KerberosCompatibilityFlags . EnableSpecCompliantCNameHandling ) )
294+ {
295+ // In TGS-REP, we should always reply with cname/crealm copied from the TGT, even when the Canonicalize
296+ // flag is set in TGS-REQ.
297+ //
298+ // RFC 4120 § 3.3.3 Generation of KRB_TGS_REP Message
299+ // --------------------------------------------------
300+ // "By default, the address field, the client's name and realm, the list of transited realms, the time
301+ // of initial authentication, the expiration time, and the authorization data of the newly-issued
302+ // ticket will be copied from the TGT or renewable ticket."
303+ //
304+ // RFC 6806 § 6. Name Canonicalization
305+ // -----------------------------------
306+ // "If the "canonicalize" KDC option is set, then the KDC MAY change the client and server principal
307+ // names and types in the AS response and ticket returned from those in the request. Names MUST NOT be
308+ // changed in the response to a TGS request, although it is common for KDCs to maintain a set of
309+ // aliases for service principals."
310+ rst . ClientName = context . Ticket . CName ;
311+ }
312+ else if ( ! this . RealmService . Settings . Compatibility . HasFlag ( KerberosCompatibilityFlags . DoNotCanonicalizeTgsReqFromTgt ) &&
315313 tgsReq . Body . KdcOptions . HasFlag ( KdcOptions . Canonicalize ) )
316314 {
317- rst . ClientName = null ;
318- #pragma warning disable CS0612 // Type or member is obsolete
315+ // The code below introduced an annoying regression in a separate party.
316+ // The compatibility flag is a workaround to make sure it can use the original behavior in cases where
317+ // that's expected.
318+
319+ #pragma warning disable CS0612 // Type or member is obsolete
319320 rst . SamAccountName = context . GetState < TgsState > ( PaDataType . PA_TGS_REQ ) . DecryptedApReq . Ticket . CName . FullyQualifiedName ;
320- #pragma warning restore CS0612 // Type or member is obsolete
321+ #pragma warning restore CS0612 // Type or member is obsolete
321322 }
322323
323324 // this is set here instead of in GenerateServiceTicket because GST is used by unit tests to
0 commit comments