我正在尝试编写一个备份和恢复工具。我在 WinPE CD ( http://en.wikipedia.org/wiki/Windows_Preinstallation_Environment ) 上运行我的代码。我正在尝试读取整个 C: 分区并将其写入网络。就像 tar 命令一样,但特定于 Windows。除了设置文件所有者外,我一切正常。 Windows 似乎真的不能容忍未知 SID 拥有的文件。由于我在 WinPE 中运行,因此在 C: 上定义的大多数用户都不在本地用户数据库中。
以下是我尝试过的一些功能:
- 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;
}
最佳答案
原来你需要 SE_RESTORE_NAME token 权限。您可以通过以下方式调整流程 token :
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;
}
然后你可以在我的例子中的main开头添加以下内容:
if (TakeSecurityPriv(SE_RESTORE_NAME)){
这消除了 1307 错误。不幸的是,我的示例中还有另一个错误,因为所有者未设置为正确的 SID。但是,当我切换回 BackupRead/BackupWrite 时,我将不必创建 SID 或 SECURITY_DESCRIPTOR。我已经思考了一段时间可能是什么问题,但没有运气。也许其他人可以回答该部分。
关于c++ - 在 Windows 中将文件所有者设置为不存在的用户/SID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17479152/