尝试从Windows Server上运行的Win32应用程序在Samba上打开文件时,函数CreateFiles返回无效的句柄,错误代码为0x522(ERROR_PRIVILEGE_NOT_HELD),有一种方法可以查询缺少该特权的系统特定文件?
我模拟了登录的用户(应为管理员)后启用了一些安全特权:SE_SECURITY_NAME,SE_BACKUP_NAME和SE_RESTORE_NAME,但这不起作用。
我只需要对该文件具有读特权,并且我将以下选项提交给CreateFile:
hSrcFile = CreateFile (sourcePath, READ_CONTROL | ACCESS_SYSTEM_SECURITY, 0, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
其他一些可能不是很有用的信息:
有什么建议吗?谢谢
编辑1
要配置SE_SECURITY_NAME标志,我使用OpenProcessToken
来获取Process令牌,然后使用this function from MSDN来启用特权。
我还尝试以登录身份以admin身份使用LogonUser
中的令牌来设置特权,但是在这种情况下,MSDN funtion似乎失败,错误为ACCESS_DENIED。用DuplicateToken(和SecurityDelegation标志)复制令牌后,做同样的事情也不起作用。
在设置SE_SECURITY_NAME时,我已经验证了AdjustTokenPrivileges
的返回值,并且该函数不会失败。我可以调用CreateFile
来打开没有标志ACCESS_SYSTEM_SECURITY的文件,但是然后我不能使用文件句柄来调用GetFileInformationByHandleEx
,因为该函数失败并显示ACCESS DENIED,不确定是否与ACCESS_SYSTEM_SECURITY相关是否。
编辑2
我正在执行以下步骤来启用SE_SECURITY_NAME,然后使用CreateFile:
使用OpenProcessToken
(标志TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY)获取进程令牌,然后使用SE_SECURITY_NAME,SE_BACKUP_NAME和SE_RESTORE_NAME调用AdjustTokenPrivileges
。 (使用LookupPrivilegeValue
获得正确的LUID之后)。该函数返回的错误代码为0x0。
使用OpenThreadToken
(标志TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY)获取线程令牌,并使用SE_SECURITY_NAME,SE_BACKUP_NAME和SE_RESTORE_NAME调用AdjustTokenPrivileges
。 (使用LookupPrivilegeValue
获得正确的LUID之后)。该函数返回的错误代码为0x0。
使用CreateFile(pathTofile, READ_CONTROL | ACCESS_SYSTEM_SECURITY, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTIC,NULL)
调用CreateFile,该函数将返回0x522:特权未获得。 pathToFile的格式类似于“ \ 192.168.0.0 \ folder \ file.txt”
希望这可以澄清流程,启用特权的代码为:
bStatus = LookupPrivilegeValue (NULL, privilegeStr, &luid);
if (!bStatus)
{
dwStatus = GetLastError();
// do stuff
}
ZeroMemory (&tp, sizeof (tp));
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
/* Adjust Token privileges */
bStatus = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
&oldtp, &dwSize);
dwStatus = GetLastError();
if (!bStatus || dwStatus != ERROR_SUCCESS )
{
//do stuff, print error etc.
}
其中privilegeStr例如是SE_SECURITY_NAME
编辑3
为了希望提供一个能使问题重现的代码示例,从而为它提供一个可能的解决方案,我准备了以下丑陋的代码片段:
HANDLE hToken;
bStatus = OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES |
TOKEN_QUERY, TRUE, &hToken);
LUID luid;
LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &luid);
TOKEN_PRIVILEGES tp = { 0, };
TOKEN_PRIVILEGES oldtp = { 0, };
DWORD dwSize = sizeof(TOKEN_PRIVILEGES);
ZeroMemory(&tp, sizeof(tp));
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
/* Adjust Token privileges */
bStatus = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
&oldtp, &dwSize);
dwStatus = GetLastError();
if (!bStatus || dwStatus != ERROR_SUCCESS)
{
//Print error.
}
PRIVILEGE_SET privSet;
ZeroMemory(&privSet, sizeof(PRIVILEGE_SET));
privSet.PrivilegeCount = 1;
privSet.Control = PRIVILEGE_SET_ALL_NECESSARY;
privSet.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
privSet.Privilege[0].Luid = luid;
BOOL bResult;
PrivilegeCheck(hToken, &privSet, &bResult);
fprintf(stderr,"Status bool: %d, attr value:0x%x, error code: 0x%x\n",
bResult,
privSet.Privilege[0].Attributes,
GetLastError());
hSrcFile = CreateFile (sourcePath, READ_CONTROL | ACCESS_SYSTEM_SECURITY, 0, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
if( hSrcFile == INVALID_HANDLE_VALUE )
{
fprintf(stderr,"CreateFile error 0x%x\n", GetLastError());
}
输出为Status bool:1, attr value:0x80000002, error code: 0x0
,后跟CreateFile error 0x522
。
此示例是否确认启用了SE_SECURITY_NAME,但CreateFile
仍然失败?还有什么需要的吗?另外:
ACCESS_SYSTEM_SECURITY