I'm trying to use PipeSecurity
to secure a NamedPipeServerStream
. When I call this.pipeServer.SetAccessControl(pipeSecurity)
in the snippet below I get the following exception:
Attempted to perform an unauthorized operation.
at System.Security.AccessControl.Win32.SetSecurityInfo(ResourceType type, String name, SafeHandle handle, SecurityInfos securityInformation, SecurityIdentifier owner, SecurityIdentifier group, GenericAcl sacl, GenericAcl dacl)
at System.Security.AccessControl.NativeObjectSecurity.Persist(String name, SafeHandle handle, AccessControlSections includeSections, Object exceptionContext)
at System.Security.AccessControl.NativeObjectSecurity.Persist(SafeHandle handle, AccessControlSections includeSections, Object exceptionContext)
at System.IO.Pipes.PipeSecurity.Persist(SafeHandle handle)
code:
this.pipeServer =
new NamedPipeServerStream(
pipeName,
PipeDirection.InOut,
1,
PipeTransmissionMode.Byte,
PipeOptions.Asynchronous);
PipeSecurity pipeSecurity = new PipeSecurity();
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
if (principal.IsInRole(WindowsBuiltInRole.Administrator))
{
// Allow the Administrators group full access to the pipe.
pipeSecurity.AddAccessRule(new PipeAccessRule(
new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null).Translate(typeof(NTAccount)),
PipeAccessRights.FullControl, AccessControlType.Allow));
} else {
// Allow current user read and write access to the pipe.
pipeSecurity.AddAccessRule(new PipeAccessRule(
WindowsIdentity.GetCurrent().User,
PipeAccessRights.ReadWrite, AccessControlType.Allow));
}
this.pipeServer.SetAccessControl(pipeSecurity);
Any ideas of what I'm doing wrong?
This is happening in .NET Framework (targeting net451) and .NET Standard 1.6 using the System.IO.AccessControl nuget package:
https://www.nuget.org/packages/System.IO.Pipes.AccessControl/
Edit:
I was able to use an #ifdef to use the following constructor that worked for .NET Framework:
public NamedPipeServerStream (string pipeName, System.IO.Pipes.PipeDirection direction, int maxNumberOfServerInstances, System.IO.Pipes.PipeTransmissionMode transmissionMode, System.IO.Pipes.PipeOptions options, int inBufferSize, int outBufferSize, System.IO.Pipes.PipeSecurity pipeSecurity)
However, this constructor does not exist in .NET Standard. I tried using this function that was added to .NET Core:
PipesAclExtensions.SetAccessControl(PipeStream, PipeSecurity)
But that yields the same exception from before.
I created a gist to show this.
I just had the same issue and tried to track it down.
The current status (Feb-2019) is sad but true: it just does not work with the classes that are given in today's NET Standard.
Also interesting in this context could be the *nix-related
One still can use native API calls to get security set up as desired, but that's not for the faint of heart. One basically needs to implement these steps:
SECURITY_ATTRIBUTES
structure
CreateNamedPipe()
SafeHandle
PS: At least we now can look it up in the code where it is hitting the wall. Just imagine having that problem 20 years ago ...
In NET 5 you can create a NamedPipeServerStream available to all user accounts by defining it like this:
PipeSecurity pipeSecurity = new PipeSecurity();
pipeSecurity.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), PipeAccessRights.ReadWrite, AccessControlType.Allow));
using (var pipe = NamedPipeServerStreamAcl.Create("MyAppPipeName", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.None, 0, 0, pipeSecurity))
{
pipe.WaitForConnection();
// ...
}
Please note that this is for Windows operating system only.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With