C语言 如何正确使用LsaLookupSids2?

qaxu7uf2  于 2023-05-16  发布在  其他
关注(0)|答案(1)|浏览(93)

我正在尝试使用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)

有人能帮我解决这个问题吗?

5n0oy7gb

5n0oy7gb1#

这个问题有点老了,但我只是想发布我最终解决它的方法。代码中有两个主要的问题我必须克服。

  1. NetShareGetInfo以自相关形式返回安全描述符。但是要操作安全描述符,它必须是绝对形式的。我使用MakeAbsoluteSD函数将返回的SD转换为绝对形式。
    1.给定一个SID,查找与之关联的名称的最佳方法是使用LookupAccountSidW函数(而不是我尝试使用的LsaLookupSids2函数)。

相关问题