Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MessageQueue.CanWrite always returns true

Tags:

c#

c#-4.0

msmq

I have deselected the permissions for Send Message on a private queue, yet MessageQueue.CanWrite never returns false. I can toggle Receive Message permissions and the CanRead property responds as expected. Why would the CanWrite property behave differently?

I have tested this issue with a couple of different AD users and the results are the same.

Is there a different approach to validating whether a specific user account can send a mesage to a specific remote private queue?

public class SendBehavior : IMsmqRuleBehavior
{
    public bool Validate(string queuePath)
    {
        using (var queue = new MessageQueue(queuePath, QueueAccessMode.Send))
        {
            return queue.CanWrite;                                        
        }
    }
}

public class ReceiveBehavior : IMsmqRuleBehavior
{
    public bool Validate(string queuePath)
    {
        using (var queue = new MessageQueue(queuePath, QueueAccessMode.Receive))
        {
            return queue.CanRead;                
        }
    }
}
like image 588
chad Avatar asked Aug 05 '13 19:08

chad


1 Answers

From what I can tell, this behavior is as intended for MessageQueue.CanWrite. If you delve deep enough into the guts of the MessageQueue class, you'll find it creates some helper objects which influence the value of this property in the following manner:

  1. If you pass QueueAccessMode.Send (or SendAndReceive), an internal access mode helper will be created which returns true if (this.accessMode & QueueAccessMode.Send) != (QueueAccessMode)0.

  2. If #1 is true, it then attempts to open the queue to store it into the cache, using the access mode and sharing you have requested. At this point a call to the native method MQOpenQueue is made, which has the following in its remarks (emphasis mine):

    If the access rights for opening the queue in the mode requested are not allowed for the calling application, the following two things can happen:

    • If dwAccess is set to MQ_SEND_ACCESS, MQOpenQueue will succeed, but errors will be returned when the application tries to send a message.
    • If dwAccess is set to MQ_PEEK_ACCESS or MQ_RECEIVE_ACCESS, MQOpenQueue will fail and return MQ_ERROR_ACCESS_DENIED (0xC00E0025). In this case a queue handle is not returned to phQueue.

Therefore, given a QueueAccessMode.Send (or SendAndReceive) with a valid queue name and sharing mode, it is my understanding that CanWrite will return true, even if you truly do not have access to send a message.

Basically it appears that you will only receive CanWrite == false if and only if:

  1. You pass a QueueAccessMode which is not Send or SendAndReceive.
like image 157
user7116 Avatar answered Nov 08 '22 18:11

user7116