Set default permissions when creating a new Message Queue (MSMQ) in C#
Asked Answered
C

3

6

I am trying to programmatically create several Message Queues on a Windows 2003x64/2008R2 Server. When a Queue is created, Windows automatically applies default permissions to the Queue.

For MSMQ 4, the following users are added by default

  • Everyone
  • Creator of the queue
  • ANONYMOUS LOGIN

When I set the permissions for a queue using MessageQueue.SetPermissions(), the specified AccessControlList is only appended to the default security permissions.

Is there any way the default permissions can be removed or overwritten? In this MSDN Article at the bottom, it states that

You can't, though, customise the defaults as they are hard-coded.

I know that the settings of a queue are persisted in a file, located in C:\Windows\System32\msmq\storage\lqs. In this file there's a Security property that represents the permissions for the queue. Might editing this key be an option? Doing this, however, seems kind of odd to me.

I'm looking for a proper way to specify my own AccessControlList that overwrites the default security permissions of a queue. Either when it's being created, or afterwards.

Any help is appreciated,

Thanks.

Crownwork answered 3/5, 2012 at 6:45 Comment(0)
W
12

If you can't remove or revoke permissions to those default groups you can always try to deny rights to them. Deny takes precedence over allow. This code works:

MessageQueue queue = new MessageQueue(".\\Private$\\QueueName");
queue.SetPermissions("Everyone", MessageQueueAccessRights.ReceiveMessage,
        AccessControlEntryType.Deny);

Revoking permissions (AccessControlEntryType.Revoke) should also work though. Maybe there is an error in your code. Works on my machine.

The article says:

You can't, though, customise the defaults as they are hard-coded.

and it means that you can't change what rights are given during queue creation but you can change them afterwards.

Edit: To get "Everyone" independent of OS-language: How to get the IdentityReference for "Everyone" to create MutexAccessRule on localized systems?

Weeny answered 3/5, 2012 at 7:12 Comment(4)
But since Denys take precedence, and you're Denying Everyone this right, doesn't that mean that no-one can use the queue? Would Revoke be a better option?Chatav
Revoke is better if it works but you wrote you can't do it. It works when I try it. Try again with this code.Weeny
Yes Revoke works. However, how can I revoke the permissions for the Owner/Creator? This username is not always the same.Crownwork
Just revoke for "Creator Owner".Weeny
C
6

I had the same exact issue with the ACL. When I switched to the SetPermissions() method things ran much better.

The code below works for me:

                queue.SetPermissions(
                    "Everyone",
                    MessageQueueAccessRights.FullControl,
                    AccessControlEntryType.Allow);
                queue.SetPermissions(
                    "ANONYMOUS LOGON",
                    MessageQueueAccessRights.FullControl,
                    AccessControlEntryType.Allow);
Catchy answered 28/9, 2012 at 21:11 Comment(0)
N
3

Although Mike's answer is correct, it assumes the server has English as the language. If you use this code on a server which uses a different language (in this case Dutch) ...

 queue.SetPermissions( 
                     "Everyone",
                     MessageQueueAccessRights.FullControl,
                      AccessControlEntryType.Allow);

... you get the following exception:

Kan de naam Everyone niet omzetten (fout = 1332 ). System.Messaging.AccessControlList.MakeAcl(IntPtr oldAcl) bij System.Messaging.MessageQueue.SetPermissions(AccessControlList dacl) bij System.Messaging.MessageQueue.SetPermissions(String user, MessageQueueAccessRights rights, AccessControlEntryType entryType)

which roughly translates to 'Cannot convert name 'Everyone'. Instead if you use this code you will get a localized version of 'Everyone':

using System.Security.Principal;

** code ommitted**

string everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null).Translate(typeof(NTAccount)).Value;
queue.SetPermissions( 
                   everyone,
                   MessageQueueAccessRights.FullControl,
                    AccessControlEntryType.Allow);
Nagana answered 2/5, 2017 at 16:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.