Ask a questionAsk a question
 

AnswerName pipe access denied error

  • Wednesday, September 23, 2009 7:15 PMVentsislav Velev Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I wrote a program that creates a named pipe and sends a message to another program to use that pipe to send call back messages. The problem is that the client is not able to connect to the pipe due to Access Denied error (error 5).
    When the client and the server run as the same user everything works fine, the problem appears when the client app runs as a different user. Both users are members of the admin group (authentication is done via domain controller).

    Edit: I'm using a NULL security attribute and PIPE_ACCESS_INBOUND mode.

    Any ideas ?

    By the way, I'm not sure this is the best forum for this question, if not feel free to move it to the appropriate section.

Answers

  • Monday, September 28, 2009 5:27 PMDavid Tyler Hunt Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    A null lpSecurityAttributes isn't what you're looking for - the default is too restrictive for your needs. To confirm this is what's going wrong for you, you can call GetSecurityInfo after you create the pipe, then ConvertSecurityDescriptorToStringSecurityDescriptor to make sense of the ACL.

    To fix the problem, I think the easiest way is to read up on SDDL, figure out the correct string for your purposes (or, how to build the correct string, in the event you're not using built-in groups), call ConvertStringSecurityDescriptorToSecurityDescriptor and roll that up in your call to create the named pipe.
  • Tuesday, November 03, 2009 4:50 PMVentsislav Velev Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    OK, I'm back working on this problem again. As a first step I rewrote the application to use security descriptor that uses a null DACL. I assign the descriptor to the security attribute and use it to create the pipe. If that would've worked, I was going to modify the DACL to implement actual security restrictions.

    However, the problem is that even with the null DACL the connection fails with access denied error code. Now, I thought null DACL would mean open access - meaning everyone can connect is that not correct?

    I'll try to use the GetSecurityInfo and ConvertSecurityDescriptorToStringSecurityDescriptor functions and try to make some sense of the descriptor ...

    What else do you guys think might be causing the problem?
  • Thursday, November 05, 2009 12:26 AMVentsislav Velev Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    It turns out my data marshaling was incorrect. I was doing something along the lines of:


    SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
    SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR();
    
    if (InitializeSecurityDescriptor(out sd, 1))
    {
        if (SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false))
        {
                        
            sa.lpSecurityDescriptor = &sd;
            clientPipeHandle = CreateNamedPipe(temp, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE, 1, 0, BUFFER_SIZE, 0, out sa);
        }
    }
    
    
    The result of this was that the security descriptor was being passed as NULL and that was causing the security problem.

    What I ended up doing was the following (all structs are declared "unsafe"):

    SECURITY_DESCRIPTOR sd;     
    if (InitializeSecurityDescriptor(out sd, 1))
    {
        if (SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false))
        {
            unsafe
            {
                SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); //creates fixed unmanaged structure
                sa.lpSecurityDescriptor = &sd; //declared this as a pointer
                clientPipeHandle = CreateNamedPipe(temp, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE, 1, 0, BUFFER_SIZE, 0, ref sa);
            }
            error = Marshal.GetLastWin32Error();
        }
    }
                            
    
    Make sure you use Marshal.GetLastWin32Error() function to get any error codes the unmanaged functions are generating, otherwise you'll have no way to debug (unless you are lucky and exception is thrown)



All Replies

  • Friday, September 25, 2009 4:29 PMVentsislav Velev Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Bump
  • Monday, September 28, 2009 5:27 PMDavid Tyler Hunt Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    A null lpSecurityAttributes isn't what you're looking for - the default is too restrictive for your needs. To confirm this is what's going wrong for you, you can call GetSecurityInfo after you create the pipe, then ConvertSecurityDescriptorToStringSecurityDescriptor to make sense of the ACL.

    To fix the problem, I think the easiest way is to read up on SDDL, figure out the correct string for your purposes (or, how to build the correct string, in the event you're not using built-in groups), call ConvertStringSecurityDescriptorToSecurityDescriptor and roll that up in your call to create the named pipe.
  • Tuesday, November 03, 2009 4:50 PMVentsislav Velev Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    OK, I'm back working on this problem again. As a first step I rewrote the application to use security descriptor that uses a null DACL. I assign the descriptor to the security attribute and use it to create the pipe. If that would've worked, I was going to modify the DACL to implement actual security restrictions.

    However, the problem is that even with the null DACL the connection fails with access denied error code. Now, I thought null DACL would mean open access - meaning everyone can connect is that not correct?

    I'll try to use the GetSecurityInfo and ConvertSecurityDescriptorToStringSecurityDescriptor functions and try to make some sense of the descriptor ...

    What else do you guys think might be causing the problem?
  • Thursday, November 05, 2009 12:26 AMVentsislav Velev Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    It turns out my data marshaling was incorrect. I was doing something along the lines of:


    SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
    SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR();
    
    if (InitializeSecurityDescriptor(out sd, 1))
    {
        if (SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false))
        {
                        
            sa.lpSecurityDescriptor = &sd;
            clientPipeHandle = CreateNamedPipe(temp, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE, 1, 0, BUFFER_SIZE, 0, out sa);
        }
    }
    
    
    The result of this was that the security descriptor was being passed as NULL and that was causing the security problem.

    What I ended up doing was the following (all structs are declared "unsafe"):

    SECURITY_DESCRIPTOR sd;     
    if (InitializeSecurityDescriptor(out sd, 1))
    {
        if (SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false))
        {
            unsafe
            {
                SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); //creates fixed unmanaged structure
                sa.lpSecurityDescriptor = &sd; //declared this as a pointer
                clientPipeHandle = CreateNamedPipe(temp, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE, 1, 0, BUFFER_SIZE, 0, ref sa);
            }
            error = Marshal.GetLastWin32Error();
        }
    }
                            
    
    Make sure you use Marshal.GetLastWin32Error() function to get any error codes the unmanaged functions are generating, otherwise you'll have no way to debug (unless you are lucky and exception is thrown)