@@ -2817,8 +2817,8 @@ func (c *client) processHeaderPub(arg, remaining []byte) error {
28172817 // Do this only for CLIENT connections.
28182818 if c .kind == CLIENT && c .pa .hdr > 0 && len (remaining ) > 0 {
28192819 hdr := remaining [:min (len (remaining ), c .pa .hdr )]
2820- if td := getHeader ( MsgTraceDest , hdr ); len ( td ) > 0 {
2821- c .initAndSendIngressErrEvent (hdr , string ( td ) , ErrMaxPayload )
2820+ if td , ok := c . allowedMsgTraceDest ( hdr , false ); ok && td != _EMPTY_ {
2821+ c .initAndSendIngressErrEvent (hdr , td , ErrMaxPayload )
28222822 }
28232823 }
28242824 c .maxPayloadViolation (c .pa .size , maxPayload )
@@ -4066,6 +4066,41 @@ func (c *client) pubAllowed(subject string) bool {
40664066 return c .pubAllowedFullCheck (subject , true , false )
40674067}
40684068
4069+ // allowedMsgTraceDest returns the trace destination if present and authorized.
4070+ // It only considers static publish permissions and does not consume dynamic
4071+ // reply permissions because the client is not publishing the trace event itself.
4072+ func (c * client ) allowedMsgTraceDest (hdr []byte , hasLock bool ) (string , bool ) {
4073+ if len (hdr ) == 0 {
4074+ return _EMPTY_ , true
4075+ }
4076+ td := sliceHeader (MsgTraceDest , hdr )
4077+ if len (td ) == 0 {
4078+ return _EMPTY_ , true
4079+ }
4080+ dest := bytesToString (td )
4081+ if c .kind == CLIENT {
4082+ if hasGWRoutedReplyPrefix (td ) {
4083+ return dest , false
4084+ }
4085+ var acc * Account
4086+ var srv * Server
4087+ if ! hasLock {
4088+ c .mu .Lock ()
4089+ }
4090+ acc , srv = c .acc , c .srv
4091+ if ! hasLock {
4092+ c .mu .Unlock ()
4093+ }
4094+ if bytes .HasPrefix (td , clientNRGPrefix ) && srv != nil && acc != srv .SystemAccount () {
4095+ return dest , false
4096+ }
4097+ }
4098+ if c .perms != nil && (c .perms .pub .allow != nil || c .perms .pub .deny != nil ) && ! c .pubAllowedFullCheck (dest , false , hasLock ) {
4099+ return dest , false
4100+ }
4101+ return dest , true
4102+ }
4103+
40694104// pubAllowedFullCheck checks on all publish permissioning depending
40704105// on the flag for dynamic reply permissions.
40714106func (c * client ) pubAllowedFullCheck (subject string , fullCheck , hasLock bool ) bool {
@@ -4201,10 +4236,19 @@ func (c *client) processInboundClientMsg(msg []byte) (bool, bool) {
42014236 genidAddr := & acc .sl .genid
42024237
42034238 // Check pub permissions
4204- if c .perms != nil && (c .perms .pub .allow != nil || c .perms .pub .deny != nil ) && ! c .pubAllowedFullCheck (string (c .pa .subject ), true , true ) {
4205- c .mu .Unlock ()
4206- c .pubPermissionViolation (c .pa .subject )
4207- return false , true
4239+ if c .perms != nil && (c .perms .pub .allow != nil || c .perms .pub .deny != nil ) {
4240+ if ! c .pubAllowedFullCheck (string (c .pa .subject ), true , true ) {
4241+ c .mu .Unlock ()
4242+ c .pubPermissionViolation (c .pa .subject )
4243+ return false , true
4244+ }
4245+ }
4246+ if c .pa .hdr > 0 {
4247+ if td , ok := c .allowedMsgTraceDest (msg [:c .pa .hdr ], true ); ! ok {
4248+ c .mu .Unlock ()
4249+ c .pubPermissionViolation (stringToBytes (td ))
4250+ return false , true
4251+ }
42084252 }
42094253 c .mu .Unlock ()
42104254
@@ -4775,29 +4819,40 @@ func (c *client) processServiceImport(si *serviceImport, acc *Account, msg []byt
47754819 if ! isResponse {
47764820 isSysImport := siAcc == c .srv .SystemAccount ()
47774821 var ci * ClientInfo
4778- if hadPrevSi && c .pa .hdr >= 0 {
4779- var cis ClientInfo
4780- if err := json .Unmarshal (sliceHeader (ClientInfoHdr , msg [:c .pa .hdr ]), & cis ); err == nil {
4781- ci = & cis
4822+ var cis * ClientInfo
4823+ if c .pa .hdr >= 0 {
4824+ var hci ClientInfo
4825+ if err := json .Unmarshal (sliceHeader (ClientInfoHdr , msg [:c .pa .hdr ]), & hci ); err == nil {
4826+ cis = & hci
4827+ }
4828+ }
4829+ if c .kind == LEAF && c .pa .hdr >= 0 && len (sliceHeader (ClientInfoHdr , msg [:c .pa .hdr ])) > 0 {
4830+ // Leaf nodes may forward a Nats-Request-Info from a remote domain,
4831+ // but the local server must replace it with the identity of the
4832+ // authenticated leaf connection instead of trusting forwarded values.
4833+ ci = c .getClientInfo (share )
4834+ if hadPrevSi {
47824835 ci .Service = acc .Name
4783- // Check if we are moving into a share details account from a non-shared
4784- // and add in server and cluster details.
47854836 if ! share && (si .share || isSysImport ) {
47864837 c .addServerAndClusterInfo (ci )
47874838 }
4839+ } else if ! share && isSysImport {
4840+ c .addServerAndClusterInfo (ci )
4841+ }
4842+ } else if hadPrevSi && cis != nil {
4843+ ci = cis
4844+ ci .Service = acc .Name
4845+ // Check if we are moving into a share details account from a non-shared
4846+ // and add in server and cluster details.
4847+ if ! share && (si .share || isSysImport ) {
4848+ c .addServerAndClusterInfo (ci )
47884849 }
47894850 } else if c .kind != LEAF || c .pa .hdr < 0 || len (sliceHeader (ClientInfoHdr , msg [:c .pa .hdr ])) == 0 {
47904851 ci = c .getClientInfo (share )
47914852 // If we did not share but the imports destination is the system account add in the server and cluster info.
47924853 if ! share && isSysImport {
47934854 c .addServerAndClusterInfo (ci )
47944855 }
4795- } else if c .kind == LEAF && (si .share || isSysImport ) {
4796- // We have a leaf header here for ci, augment as above.
4797- ci = c .getClientInfo (si .share )
4798- if ! si .share && isSysImport {
4799- c .addServerAndClusterInfo (ci )
4800- }
48014856 }
48024857 // Set clientInfo if present.
48034858 if ci != nil {
0 commit comments