Unanswered GetFileSecurity(), lpnLengthNeeded comes as 0

  • Wednesday, December 14, 2011 3:35 AM
     
     

    GetFileSecurity() of Win32API, lpnLengthNeeded updates as 0 after executing the function. But the GetFileSecurity() return value is non zero.

    lpFileName = [Directory in a Mapped drive]

    RequiredInformation  =  OWNER_SECURITY_INFORMATION + GROUP_SECURITY_INFORMATION + DACL_SECURITY_INFORMATION

    Why does lpnLengthNeeded value comes as 0?

    • Moved by Rob Pan Thursday, December 15, 2011 7:35 AM (From:Visual C++ General)
    •  

All Replies

  • Wednesday, December 14, 2011 4:58 AM
     
     
    Show code that reproduces the problem.
    Jose R. MCP
  • Wednesday, December 14, 2011 5:08 AM
     
     
    But the GetFileSecurity() return value is non zero.
    ...and, of course, as instructed by the documentation of GetFileSecurity(), you called GetLastError()? What value did it return?
  • Wednesday, December 14, 2011 5:23 AM
     
     
    GetFileSecurity() doesn't fail. Therefore no need to call GetLastError(). The other thing is pSecurityDescriptor is updated with security information and it's not empty. Problem is lpLengthNeeded is 0 always.
  • Wednesday, December 14, 2011 9:48 AM
     
     
    lpnLengthNeeded is a pointer; are you reporting as 0 the value of the pointer, or the value of the DWORD it is supposed to point at?
    Answering policy: see profile.

  • Thursday, December 15, 2011 4:44 AM
     
     

    PSECURITY_DESCRIPTOR pSecurityDescriptor = SPACE(4096)

    DWORD nLength = 4096

    These two values I pass LPDWORD lpnLengthNeeded updated as 0 after the function.
    But PSECURITY_DESCRIPTOR pSecurityDescriptor value updates with the structure successfully.

    LPDWORD lpnLengthNeeded pointer becomes 0, thats my problem. My OS is Win7 x86 and I pass server path or mapped drive path to LPCTSTR lpFileName. Then lpnLengthNeeded becomes 0. But if LPCTSTR lpFileName  is a local drive (i.e: C:\) then the lpnLengthNeeded is greater than 0.

    Why this happens only for mapped drives and server paths.

  • Thursday, December 15, 2011 7:33 AM
     
     

    Hi,

     

    According to your description, I will move your thread to the correct forum for better support. Thanks for your understanding.

     

    Best Regards,

    Rob


    Rob Pan [MSFT]
    MSDN Community Support | Feedback to us
  • Thursday, December 15, 2011 11:37 AM
     
      Has Code

    You still haven't shown us the code you are actually experiencing this problem with, so I'm going to have to state the code you should be using for your problem to be valid:

     

    char buffer[4096];
    PSECURITY_DESCRIPTOR pSecurityDescriptor = (PSECURITY_DESCRIPTOR) buffer;
    DWORD nLength = sizeof(buffer);
    
    memset(buffer, 0, sizeof(buffer));      // clear the buffer
    
    if (!GetFileSecurity( "some_remote_file_name", 
                          OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
                          pSecurityDescriptor,
                          nLength,
                          & nLength
    		    )
    {
        // error occured
        DWORD error = GetLastError();
        // handle error
    }
    else
    {
        // success of some sort
    
        if (nLength == 0)
        {
            // Is this the case you are worried about?
        }
        else
        {
            // buffer has been populated with descriptor, so pSecurityDescriptor is also valid to use.
        }
    }
    

    Is your code equivalent to that?  If not, please adjust the above code to reflect the situation you are seeing.


    Answering policy: see profile.
  • Friday, December 16, 2011 6:34 AM
     
     

    Yes David, you are correct.

     if (nLength == 0)
        {
            // Is this the case you are worried about?                                                                          

         //Yes this is the case I'm worried abbout. But here also buffer has been populated with descriptor, so pSecurityDescriptor is also valid to use.

        }
        else
        {
            // buffer has been populated with descriptor, so pSecurityDescriptor is also valid to use.
        }

  • Saturday, April 14, 2012 8:59 AM
     
     

    Hi together !

    If have the exact same behaviour here with GetKernelObjectSecurity (which also works with file objects) and lpnLengthNeeded coming back a 0.

    This happens with SMB 2 only (eg. from Windows Server 2008 R2 to UNC path on another W2K8R2). If the remote side is e.g. Windows Server 2003 (so using SMB 1), it comes back "normally".

    And in my case, too, the returned SD is valid.

    If we take a look at the docu (for GetFileSecurity, in this case):

    lpnLengthNeeded

    A pointer to the variable that receives the number of bytes necessary to store the complete security descriptor. If the returned number of bytes is less than or equal to nLength, the entire security descriptor is returned in the output buffer; otherwise, none of the descriptor is returned.

    We may say that this behaviour is not a bug:


    ... If the returned number of bytes is less than or equal to nLength...

    And 0 is less than the given length in nLength...

    There is no notice that the returned lpnLengthNeeded will be the number of bytes actually returned in the SD

    Can some MS developer comment on this ?

    And: even this may not be a bug: yes, this is counter-intuitive ...

     
    Regards, Rainer