2013-07-04 41 views
2

我正在嘗試編寫備份和恢復工具。我在WinPE CD上運行我的代碼(http://en.wikipedia.org/wiki/Windows_Preinstallation_Environment)。我正在嘗試讀取整個C:分區並將其寫入網絡。就像tar命令,但特定於Windows。除了設置文件所有者之外,我有一切工作。對於未知SID擁有的文件,Windows似乎真的不能容忍。由於我在WinPE中運行,所以在C:上定義的大多數用戶不在本地用戶數據庫中。在Windows中將文件所有者設置爲不存在的用戶/ SID

這裏有一些我已經試過功能:

  • SetFileSecurity(返回1307)
  • SetSecurityInfo(返回1307)
  • SetNamedSecurityInfo(返回1307)
  • 的BackupWrite(返回1307)
  • NtSetSecurityObject(返回0xC000005A)

我知道這可以做到。 SetACL(http://helgeklein.com/setacl/)能夠做到。

所以,這個問題。如何將文件的所有者設置爲不存在的用戶/ SID?任何幫助是極大的讚賞!

下面的代碼的樣本我已經試過:

#define _WIN32_WINNT 0x0500 

#include <windows.h> 
#include <sddl.h> 
#include <aclapi.h> 
#include <tchar.h> 

INT _tmain(){ 

    PSECURITY_DESCRIPTOR psdOwner = LocalAlloc(LPTR,SECURITY_DESCRIPTOR_MIN_LENGTH); 

    if (InitializeSecurityDescriptor(psdOwner,SECURITY_DESCRIPTOR_REVISION)){ 

     PSID psOwner = (PSID)0; 

     if (ConvertStringSidToSid(TEXT("S-1-5-21-3626571138-2175758104-1447827851-1013"),&psOwner)){ 

      if (SetSecurityDescriptorOwner(psdOwner,psOwner,FALSE)){ 

       DWORD dwError = SetNamedSecurityInfo(TEXT("test.txt"),SE_FILE_OBJECT,OWNER_SECURITY_INFORMATION,psdOwner,NULL,NULL,NULL); 

       if (dwError == ERROR_SUCCESS){ 

        _tprintf(TEXT("Success!\n")); 

       }else{ 

        _tprintf(TEXT("Failed to set owner: %u\n"),dwError); 

       } 

      }else{ 

       _tprintf(TEXT("Failed to set owner into SD: %u\n"),GetLastError()); 

      } 

     }else{ 

      _tprintf(TEXT("Failed to covnert Sid string to Sid: %u\n"),GetLastError()); 

     } 

     if (psOwner) LocalFree(psOwner); 

    }else{ 

     _tprintf(TEXT("Failed to initialize SD: %u\n"),GetLastError()); 

    } 

    if (psdOwner) LocalFree(psdOwner); 

    return 0; 

} 

回答

2

原來你需要SE_RESTORE_NAME令牌特權。你可以用下面的調整進程令牌:

BOOL TakeSecurityPriv(LPCTSTR szPriv){ 

    BOOL bReturn = FALSE; 

    HANDLE hProcToken = (HANDLE)0; 

    if (OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hProcToken)){ 

     TOKEN_PRIVILEGES tpTokPriv; 

     if (LookupPrivilegeValue(NULL,szPriv,&tpTokPriv.Privileges[0].Luid)){ 

      tpTokPriv.PrivilegeCount = 1; 
      tpTokPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 

      if (AdjustTokenPrivileges(hProcToken,FALSE,&tpTokPriv,0,NULL,0)){ 

       bReturn = TRUE; 

      } 

     } 

    } 

    return bReturn; 

} 

然後你可以在我的例子中添加以下的主要開頭:

if (TakeSecurityPriv(SE_RESTORE_NAME)){ 

也擺脫了1307的錯誤。不幸的是,在我的示例中有另一個錯誤,因爲所有者未設置爲正確的SID。但是,當我切換回BackupRead/BackupWrite時,我不必創建SID或SECURITY_DESCRIPTOR。我已經思考了一段時間沒有運氣可能會成爲問題。也許別人可以回答那部分。

相關問題