*更新*
答案非常有用,现在我的代码正在返回ERROR_SUCCESS.关键的变化似乎是转向使用SetKernelObjectSecurity().但是,现在我看到了一个不同的问题; 我的代码成功,但如果我查看文件系统或在代码中检查文件,它仍然有以前的所有者.
之前已经报道了SO,但没有一个令人满意的答案.
这是我的代码的公开要点.它增加了一些输出,所以你可以看到我在说什么.您应该能够将它添加到空的Visual Studio C++控制台项目并通过它进行调试.务必使用"以管理员身份运行"打开Visual Studio.
*第二次更新*
我刚刚在MSDN上找到了这个注释SetKernelObjectSecurity().
注意 在文件系统对象上设置安全描述符时,不应使用此函数.相反,使用
SetSecurityInfo或SetNamedSecurityInfo功能.
我不确定我是怎么错过的......它就在顶部.
*原始问题*
我需要fchown()在Windows上实现相同的功能,但经过相当多的研究和努力后,我一直无法使其工作. fchown()更改通过打开的文件描述符指定的文件的所有权.对于Windows,这可以是打开的文件描述符,也可以是HANDLE(您可以从另一个创建一个).似乎无论我尝试什么,我都会得到ERROR_ACCESS_DENIED.
我曾经尝试都SetSecurityInfo()和SetUserObjectInfo().我可以使用相应的Get*函数从打开的文件描述符中获取所有权信息:GetSecurityInfo()和GetUserObjectSecurity().
当我重新编写代码以使用SetNamedSecurityInfo()或者SetFileSecurity(),在指定文件名而不是打开HANDLE的情况下,一切正常.
我是否遇到过操作系统的低级文件系统访问控制规则?
是否无法在Windows上更改打开文件的所有权?
据我所知,当HANDLE打开时,我甚至无法更改DACL. 当我认为我已经保护文件但有人仍然有一个打开的HANDLE时,Windows是否只是试图阻止我的虚假安全感?
在我看来,如果我错过了某些东西,那可能就是我的呼唤方式CreateFile().
期待可能发布的一些答案:
(另外,请记住,我只需将Win32 API的对象版本替换为带有文件名的对象版本)
AdjustTokenPrivileges()给自己SE_TAKE_OWNERSHIP_NAMECreateFile()的dwShareMode.这是一些代码.我删除了所有错误处理,以便这个问题不会太长:
wchar_t* filename = L"test.txt";
HANDLE hFile = CreateFile(filename, GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hToken = NULL;
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
SetPrivilege(hToken, SE_BACKUP_NAME, TRUE);
SetPrivilege(hToken, SE_RESTORE_NAME, TRUE);
SetPrivilege(hToken, SE_SECURITY_NAME, TRUE);
SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE);
DWORD bufSize = 0;
SECURITY_INFORMATION info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
GetUserObjectSecurity(hFile, &info, NULL, 0, &bufSize); /* get buffer size */
PSECURITY_DESCRIPTOR desc = (PSECURITY_DESCRIPTOR)calloc(bufSize, sizeof(BYTE));
GetUserObjectSecurity(hFile, &info, desc, bufSize, &bufSize);
TRUSTEE trustee = { 0 };
BuildTrusteeWithSid(&trustee, newOwnerSid);
PSECURITY_DESCRIPTOR newdesc = NULL;
BuildSecurityDescriptor(&trustee, NULL, 0, NULL, 0, NULL, desc, &bufSize, &newdesc);
SetUserObjectSecurity(hFile, &info, newdesc);
free(desc);
LocalFree(newdesc);
CloseHandle(hToken);
CloseHandle(hFile);
Run Code Online (Sandbox Code Playgroud)
你需要这些标题:
#include <Windows.h>
#include <AclAPI.h>
#include <Sddl.h>
#include <stdio.h>
Run Code Online (Sandbox Code Playgroud)
SetPrivilege()函数是:
static
BOOL
SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) {
TOKEN_PRIVILEGES newState = { 0 };
LUID luid;
if (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid)) {
return FALSE;
}
newState.PrivilegeCount = 1;
newState.Privileges[0].Luid = luid;
if (bEnablePrivilege) {
newState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
}
else {
newState.Privileges[0].Attributes = 0;
}
/* If this returns a failure then your process does not have the ability to grant the privilege. */
if (!AdjustTokenPrivileges(hToken, FALSE, &newState, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
return FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
return FALSE;
}
return TRUE;
}
Run Code Online (Sandbox Code Playgroud)
您已打开具有GENERIC_READ访问权限的句柄.Windows强制执行此操作; 以这种方式打开句柄,你只能在读操作中使用句柄.(这意味着Windows只需在打开句柄时检查您对该对象的访问权限;从那时起,完全根据句柄的访问权限授予或拒绝访问权限.)
在对文档SECURITY_INFORMATION哪些访问权限显示您需要在手柄上,以便查询和设置的各种信息.在您的情况下,您需要WRITE_OWNER分配所有权和主要组,WRITE_DAC分配DACL,以及READ_CONTROL读取所有权,主要组和DACL.
请注意,GENERIC_WRITE不包括任何WRITE_OWNER或者WRITE_DAC所以你必须明确指定.
(我找不到有关包含哪些文件权限的任何文档,GENERIC_ALL但即使它有效,最好明确请求您将使用的权限.)
| 归档时间: |
|
| 查看次数: |
336 次 |
| 最近记录: |