c++ - 在 Windows 中将文件所有者设置为不存在的用户/SID

标签 c++ windows winapi file-security

我正在尝试编写一个备份和恢复工具。我在 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/

相关文章:

c++ - Gnuradio C++ block : high CPU

c++ - 一个类中的成员变量数量不定? C++

windows - Windows 中的计划任务需要用户登录这一事实的解决方法

c++ - 如果自定义凭据提供程序无法进行任何身份验证,如何返回到 CTRL+ALT+DELETE 登录页面?

java - 是否有等同于 JAVA pack() 的 WIN32 API?

c++ - 使用 _wtol 与小数转换

c++ - ofstream 两次将所有内容写入我的文件

c++ 03:由于enable_if,互斥方法

c++ - 在 Windows 中获取替代文件名

windows - 将 Windows 窗体应用程序转换为 Metro UI 应用程序