EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Can't get security descriptors working

Also by EldoS: CallbackDisk
Create virtual disks backed by memory or custom location, expose disk images as disks and more.
#20481
Posted: 06/15/2012 10:55:59
by Rob Zimmerman (Basic support level)
Joined: 06/12/2012
Posts: 5

I'm eval'ing CBFS and for now am just implementing a mirror (echo all the operations to the local file system using Win32 calls).

I set both the Get & Set FileSecurity callbacks to implement security descriptor support. I've got a test Win32 app that calls GetSecurityInfo() on a file within the virtual drive. It isn't able to query the SD with the error "A device attached to the system is not functioning".

Below is my implementation of a GetFileSecurity() callback. In the debugger I've stepped through and the function does indeed get called twice (the first time to query the pdwLengthNeeded parameter). None of the calls to get the SD fail and it appears that I am passing back a valid SD to CBFS. I see that CBFS still doesn't have any SD examples to a little guidance here would be appreciated. Thanks!

Code
void FSHook::CbFsGetFileSecurity(CallbackFileSystem *pSender,
                         CbFsFileInfo *pInfo,
                         void *pHandleContext,
                         SECURITY_INFORMATION securityInfo,
                         PSECURITY_DESCRIPTOR pSecurityDescriptor,
                         DWORD dwLength,
                         DWORD *pdwLengthNeeded) {
   FSHook::GetInstance()->m_pLog->Log(LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG, _T("Inside CbFsGetFileSecurity()"));

   HANDLE hFile = (HANDLE)pHandleContext;

   TCHAR *pFileName = NULL;
   pFileName = (TCHAR *)malloc((pInfo->get_FileName(NULL) + 1) * sizeof(TCHAR));
   pInfo->get_FileName(pFileName);

   std::wstring fullPath = BASE_DIR;
   fullPath += pFileName;
   free(pFileName);

   FileHistory::GetInstance()->AddFileOperation(fullPath, _T("CbFsGetFileSecurity()"));

   // CBFS is providing us with a buffer, no need to query the SD size
   if(dwLength) {
      if(GetSecurityInfo(hFile, SE_FILE_OBJECT, securityInfo, NULL, NULL, NULL, NULL, &pSecurityDescriptor) != ERROR_SUCCESS) {
         std::wstring err = _T("GetSecurityInfo() failed: ");
         err += GetLastErrorAsString();
         FSHook::GetInstance()->m_pLog->Log(LOG_LEVEL_ERROR, LOG_LEVEL_ERROR, (TCHAR *)err.c_str());
         throw ECBFSError(GetLastError());
      }
   
      *pdwLengthNeeded = GetSecurityDescriptorLength(pSecurityDescriptor);
   // CBFS doesn't know how big of a buffer to give us, snag the SD and stash the size in pdwLengthNeeded
   } else {
      PSECURITY_DESCRIPTOR pLocalSD;

      
      if(GetSecurityInfo(hFile, SE_FILE_OBJECT, securityInfo, NULL, NULL, NULL, NULL, &pLocalSD) != ERROR_SUCCESS) {
         std::wstring err = _T("GetSecurityInfo() failed: ");
         err += GetLastErrorAsString();
         FSHook::GetInstance()->m_pLog->Log(LOG_LEVEL_ERROR, LOG_LEVEL_ERROR, (TCHAR *)err.c_str());
         throw ECBFSError(GetLastError());
      }
      *pdwLengthNeeded = GetSecurityDescriptorLength(pLocalSD);
      LocalFree(pLocalSD);
   }
}//end of FSHook::CbFsGetFileSecurity()
#20482
Posted: 06/15/2012 11:19:03
by Volodymyr Zinin (EldoS Corp.)

Hello Rob,

The Mapper sample has implementation of the security callbacks. But they are commented there, so uncomment them in order to use.
#20525
Posted: 06/19/2012 08:23:16
by Rob Zimmerman (Basic support level)
Joined: 06/12/2012
Posts: 5

I switched up from using GetSecurityInfo() and SetSecurityInfo() over to what you were using in the example (GetFileSecurity() and SetFileSecurity()). Everything works just fine now.

Thanks!
#20698
Posted: 06/30/2012 16:31:33
by Rob Zimmerman (Basic support level)
Joined: 06/12/2012
Posts: 5

So, using GetSecurityInfo() and SetSecurityInfo() definitely works fine. Now, I'm moving my concept on to hosting file metadata information in a database. For the security descriptor that means converting it to a string and tossing it into the database (ConvertSecurityDescriptorToStringSecurityDescriptor()).

Here's the tricky part:

In CbFsGetFileSecurity() I can convert back to a SD using ConvertStringSecurityDescriptorToSecurityDescriptor() (seriously, that's a ridiculously long function name!) but now how do I get the temp SD into the SD that is passed in by CBFS?

Here's what I've got so far:
1) When CbFsGetFileSecurity() is called the first time, just fill in the "required size" parameter.

2) When CbFsGetFileSecurity() is called the second time, memcpy() the temp SD (converted from my string) into the buffer passed in by CBFS.

At this point things go absolutely haywire and no security descriptor information seems to be presented to the file system. Has anyone else got security descriptor stuff working without using GetSecrutyInfo() and SetSecurityInfo() ?

Thanks,
~Rob

Reply

Statistics

Topic viewed 1514 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!