Reputation: 6668
I am using a (.NET2.0) service to periodically carry out privileged actions and return the result to shared memory, via IPC, with a non-admin user's (.NET2.0) process.
I have been using globally named mutexes while developing from my administrator account but when I come to try the application on a limited account I get the error:
Additional information: Access to the path 'Global\timersyncu33sc3c2sd42frandomlynamedmutexoijfvgf9v3f32' is denied.
Is there some other way a non-privileged user can interact with a Service? Or should I just share the period of polling and update time and hope those values get written/read atomically?
Upvotes: 0
Views: 476
Reputation: 6668
I found the following method of granting access to my limited users as they log on and fire up their GUI. Note the function getUsername(/*somehow*/);
had several incarnations and I'm not listing the implementation that worked on XP, I'm sure there are other ways though 3 of the 4 I found didn't work for me.
void grantMutexToCurUser(Mutex ^%fpMutex) {
try {
fpMutex = Mutex::OpenExisting( ServerGUIBridge::NAMEDMUTEXFORTIMERSYNC,
static_cast<MutexRights>(
MutexRights::ReadPermissions | MutexRights::ChangePermissions) );
MutexSecurity^ mSec = fpMutex->GetAccessControl();
String^ user;
try {
user = getUsername(/*somehow*/);
Trace::WriteLine( DateTime::Now.ToLongTimeString() + " - Granting mutex access to: "
+ user , "grantMutexToCurUser" );
} catch (Exception ^ex) {
Trace::WriteLine( "getUsername: " + ex->Message, "grantMutexToCurUser" );
}
// First, the rule that denied the current user the right to enter and
// release the mutex must be removed.
MutexAccessRule^ rule = gcnew MutexAccessRule( user,
static_cast<MutexRights>(MutexRights::Synchronize
| MutexRights::Modify), AccessControlType::Deny );
mSec->RemoveAccessRule( rule );
// Now grant the user the correct rights.
rule = gcnew MutexAccessRule( user,
static_cast<MutexRights>(MutexRights::Synchronize
| MutexRights::Modify), AccessControlType::Allow );
mSec->AddAccessRule( rule );
fpMutex->SetAccessControl( mSec );
// Open the mutex with (MutexRights.Synchronize | MutexRights.Modify), the
// rights required to enter and release the mutex.
fpMutex = Mutex::OpenExisting( ewfmon::ServerGUIBridge::NAMEDMUTEXFORTIMERSYNC );
//noThrowRelease(fpMutex);
}
catch ( UnauthorizedAccessException^ ex )
{
Trace::WriteLine( DateTime::Now.ToLongTimeString() + " - Unable to change permissions: "
+ ex->Message, "grantMutexToCurUser" );
}
}
Upvotes: 0
Reputation: 35146
I would talk to the service using WCF. This eliminates the privileges/identity problem. However since your code is in .NET 2.0 you could use Remoting or NamedPipes to talk to the service.
Upvotes: 1