c++ - 如何在 C++ 中调用 LsaRemoveAccountRights

标签 c++ windows security winapi visual-c++

我正在尝试创建一个代码,这样我(管理员)就无法关闭计算机。我正在学习,这是很容易看出它是否有效的东西。问题是我从 LsaRemoveAccountRights 中得到一个未处理的异常。我从日本网站获得了大部分代码,但所有示例都几乎相同。那为什么我的不起作用?

// This is how I call the function
bool f = DelRights(SE_SHUTDOWN_NAME, true);

bool DelRights(wchar_t *szPrivilege, bool bRevoke)
{
    LSA_UNICODE_STRING Rights = {0};
    LSA_OBJECT_ATTRIBUTES Attr = {0};
    SECURITY_QUALITY_OF_SERVICE Quality = {0};
    bool bRet = false;

    DWORD SidSize = SECURITY_MAX_SID_SIZE;

    Rights.Buffer = szPrivilege;
    Rights.Length = wcslen(szPrivilege) * sizeof(WCHAR);
    Rights.MaximumLength = (wcslen(szPrivilege) + 1) * sizeof(WCHAR);


// Allocate enough memory for the largest possible SID.
    PSID AdminSID = LocalAlloc(LMEM_FIXED, SidSize);

    if (AdminSID) {
        ::SecureZeroMemory(AdminSID, SidSize);

        if (CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &AdminSID, &SidSize)) {
            LSA_HANDLE hPolicy = 0;


            Attr.Length = sizeof(Attr);
            Attr.RootDirectory = NULL;
            Attr.ObjectName = NULL;
            Attr.Attributes = 0;
            Attr.SecurityDescriptor = NULL;
            Attr.SecurityQualityOfService = &Quality;

            Quality.Length = sizeof(Quality);
            Quality.ImpersonationLevel = SecurityImpersonation;
            Quality.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
            Quality.EffectiveOnly = FALSE;

            if (ERROR_SUCCESS == LsaOpenPolicy(NULL, &Attr, POLICY_ALL_ACCESS, &hPolicy)) {
                NTSTATUS status = 0;

                if (bRevoke) {
                    status = LsaRemoveAccountRights(hPolicy, AdminSID, FALSE, &Rights, 1);

                    if (ERROR_SUCCESS == status) {
                        bRet = true;
                    }
                }
                else {
                    status = LsaAddAccountRights(hPolicy, AdminSID, FALSE, 1);

                    if (ERROR_SUCCESS == status) {
                        bRet = true;
                    }
                }

                LsaClose(hPolicy);
            }
        }

        GlobalFree(AdminSID);
    }

    return bRet;
}

最佳答案

您正在将 PPSID (PSID*) 传递给 CreateWellKnownSid,而它正在等待 PSID。这不会在这里崩溃,因为我猜指针只是稍后在 LsaRemoveAccountRights 中被取消引用。

正确的代码应该是:

PSID AdminSID = LocalAlloc(LMEM_FIXED, SidSize);

if (AdminSID) {
    ::SecureZeroMemory(AdminSID, SidSize);

    // pass AdminSID, not &AdminSID
    if (CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, AdminSID, &SidSize))

关于c++ - 如何在 C++ 中调用 LsaRemoveAccountRights,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34475312/

相关文章:

c++ - 如何在Sentry on-premise 版本中创建CPP 项目

web-services - 编码架构问题

java - PKIX 路径构建错误 : Not sure I'm creating keystore correctly

c++ - 如何分配具有 const 成员的数据对象?

c++ - WKT与GeoJson的区别(数据解析)

windows - 查找所有可用的 OLE 容器

regex - Windows 中的 Perl 单行代码

android - 在 Android 应用程序中存储 secret 和凭据

c++ - Boost Spirit Qi Re-Establish skipping with custom skip 语法

c++ - cpp : error when using rename function