We created (private) queues by a dll, and when I tried to delete a queue, I
got 'Access Denied' error. I also noticed the queue's owner is "SYSTEM". How
can I change the queue's owner to be 'Everyone' (or Administrators)? I am
looking for the programatic (not manual) way to do it.
To give you more info, here is the method that creating queues:
HRESULT CreateQueue(
LPCSTR sPathName,
LPCSTR sLabelName,
bool bTranscnl
)
{
HRESULT hr = S_OK;
try
{
CoInitialize(NULL);
IMSMQQueueInfoPtr pInfo("MSMQ.MSMQQueueInfo");
// Set the queue's path name and label.
pInfo->PathName = sPathName;
pInfo->Label = sLabelName;
if(bTranscnl == true)
{
// Create the queue as a Transactional queue.
VARIANT V;
V.vt = VT_BOOL;
V.bVal = VARIANT_TRUE;
V.boolVal = VARIANT_TRUE;
pInfo->Create(&V);
}
else
{
//Create the queue as Non-Transactional.
pInfo->Create();
}
pInfo->Refresh();
CoUninitialize();
}
catch (const _com_error& comerr)
{
_bstr_t berror = comerr.Description();
//Since we are not deleting the queues, then if the code runs it will
// give a msg saying the q already exists , so suppress any error messages.
//MessageBox(NULL, berror ,NULL,NULL);
}
return hr;
}
Thanks in advance,
Peter
As far as I know, there's no way to simply "take ownership" of a private
queue, like you could with other objects. Non-programatically, you could
simply delete the entry for that queue from the
windows\system32\msmq\storage\lqs directory.
I hope this reply isn't too late...
The code in this post...
http://groups.google.com/group/microsoft.public.msmq.security/browse_thread/thread/39a486cc11de7cb7/740ea8d57778bd15
... does a little more than you want to do. It changes the owner and
then sets the Discretionary Access Control List. But, if you just
ommitted the DACL_SECURITY_INFORMATION call to MQSetQueueSecurity it
should set owner without changing security permissions.
The code pretty much has to run from an administrator account. You
could run it from a non-administrator account with Take Ownership
privileges, but if you already had take ownership privileges you
probably wouldn't need this code.
As written, the code sets the owner to the identity running the program.
To use Everyone or Administrators instead you'd need to create a well
known sid instead of retrieving User.sid.
One way to do that (I think) would be to call CreateWellKnownSid passing
in WinWorldSid or WinBuiltinAdministratorsSid
http://msdn2.microsoft.com/en-us/library/aa446585(VS.85).aspx