none
AddAccessRule to Pipe cause exception RRS feed

  • Question

  • using System;

    using System.IO;

    using System.IO.Pipes;

    using System.Runtime.InteropServices;

    using Microsoft.Win32;


    using System.Security.Principal;

    using System.Security.AccessControl; 

    class Program    {

            static void Main(string[] args)

            {

                int i = 0;

                while (i <= 60)

                {

                    try

                    {

                        PipeSecurity pipeSecurity = new PipeSecurity();

                        Console.WriteLine((WellKnownSidType)i);

                        pipeSecurity.AddAccessRule(new PipeAccessRule(new SecurityIdentifier((WellKnownSidType)i, null),

                        PipeAccessRights.Read, AccessControlType.Allow));

                        i++; 

                      NamedPipeServerStream var = new NamedPipeServerStream(i.ToString(), PipeDirection.InOut);

                        var.SetAccessControl(pipeSecurity);

                                    }

                    catch (Exception e)

                    {

                        Console.WriteLine(e.Message);

                        i++;

                    }

                }

            }

        }

    Code above throws exception. As you can see i've tried all possible options of AcessRules.


    Friday, October 19, 2018 12:27 PM

All replies

  • I don't think your looping logic is going to work because not all SIDs can be used for this. But I tried with a single SID and kept getting an UnauthorizedAccessException. Googling it appears there have been problems for years with this code which is odd since it just calls Win32 for this. Nevertheless there are lots of combinations that don't work. Some people have found creating a new PipeSecurity and just setting the appropriate rights. Others have suggested cloning the pipe and then using its security because trying to use the original security doesn't work.

    The version that I found to work was to create the security up front and then pass it to the constructor. Unfortunately it requires you pass a lot more parameters to the constructor.

    using System;
    using System.IO.Pipes;
    using System.Security.AccessControl;
    using System.Security.Principal;
    
    namespace ConsoleApp1
    {
        class Program
        {
            static void Main ( string[] args )
            {
                try
                {
                    new AnonymousPipeServerStream();
    
                    var security = new PipeSecurity();
    
                    var rule = new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.AnonymousSid, null), PipeAccessRights.ReadWrite, AccessControlType.Allow);
                    security.AddAccessRule(rule);
    
                    using (var server = new NamedPipeServerStream("MyPipe", PipeDirection.InOut, 100, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 1, 1, security))
                    {
                        //var security = server.GetAccessControl();
                        
                        //server.SetAccessControl(security);
                    };                
                } catch (Exception e)
                {
                    Console.WriteLine(e.Message);             
                };
    
                Console.ReadLine();
            }
        }
    }
    


    Michael Taylor http://www.michaeltaylorp3.net

    Friday, October 19, 2018 2:41 PM
    Moderator