我正在尝试使用C Windows API从共享中检索信息。对于编译,我使用MSYS2(https://www.msys2.org/docs/environments/)的MINGW64风格。但是当我尝试将安全描述符中的SID转换为纯文本名称时遇到了问题。这是我的代码的简化版本:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <lm.h>
#include <ntstatus.h>
#include <ntsecapi.h>
int main(int argc, char **argv) {
NET_API_STATUS res1;
NTSTATUS res2;
// Get info from share
SHARE_INFO_502 *info;
res1 = NetShareGetInfo(L"domain.tld", L"test", 502, (LPBYTE *)&info);
if (res1 != 0) {
fprintf(stderr,
"NetShareGetInfo failed with error %d\n",
res1);
exit(EXIT_FAILURE);
}
// Validate security descriptor
SECURITY_DESCRIPTOR *sd = info->shi502_security_descriptor;
if (IsValidSecurityDescriptor(sd) == 0) {
fprintf(stderr, "Security descriptor is not valid\n");
exit(EXIT_FAILURE);
}
// Open policy handle
LSA_HANDLE polHandle;
LSA_OBJECT_ATTRIBUTES polAttrs;
memset(&polAttrs, '\0', sizeof(polAttrs)); // must be zero according to docs
res2 = LsaOpenPolicy(NULL, &polAttrs, POLICY_EXECUTE, &polHandle);
if (res2 != STATUS_SUCCESS) {
fprintf(stderr,
"LsaOpenPolicy failed with error %d (converted from %lX)\n",
LsaNtStatusToWinError(res2), res2);
exit(EXIT_FAILURE);
}
// Translate owner SID
LSA_TRANSLATED_NAME *names;
LSA_REFERENCED_DOMAIN_LIST *domains;
res2 = LsaLookupSids2(polHandle, 0, 1, &sd->Owner, &domains, &names);
if (res2 != STATUS_SUCCESS) {
fprintf(stderr,
"LsaLookupSids2 failed with error %d (converted from %lX)\n",
LsaNtStatusToWinError(res2), res2);
exit(EXIT_FAILURE);
}
// do something here with names and domains
LsaFreeMemory(names);
LsaFreeMemory(domains);
return 0;
}
然后编译并执行它:
C:\Users\myname\Desktop\c-tests\sdproblem>main.exe
LsaLookupSids2 failed with error 87 (converted from C000000D)
错误87表示“参数不正确”。似乎我没有正确地将参数传递给LsaLookupSids2
函数。但我不知道我做错了什么。我尝试在第二个参数中传递一些标志而不是0
,但没有用。我也尝试过使用LsaLookupSids
(并删除第二个参数),但仍然没有成功。共享已存在,icacls
可以检索权限:
C:\Users\myname\Desktop\c-tests\sdproblem>icacls \\domain.tld\test
\\domain.tld\test Everyone:(OI)(CI)(F)
有人能帮我解决这个问题吗?
1条答案
按热度按时间5n0oy7gb1#
这个问题有点老了,但我只是想发布我最终解决它的方法。代码中有两个主要的问题我必须克服。
NetShareGetInfo
以自相关形式返回安全描述符。但是要操作安全描述符,它必须是绝对形式的。我使用MakeAbsoluteSD
函数将返回的SD转换为绝对形式。1.给定一个SID,查找与之关联的名称的最佳方法是使用
LookupAccountSidW
函数(而不是我尝试使用的LsaLookupSids2
函数)。