C++ - правильно реализовать WlanSetSecuritySettings для WlanHostedNetwork-функций

Как видно из названия, я не совсем уверен, как правильно реализовать функцию WlanSetSecuritySettings, чтобы получить полный доступ из системы для редактирования WlanHostedNetwork из родного wlanapi (- >, так как я получаю сообщение об ошибке в некоторых системах, которое говорит, что У меня нет доступа и что мне требуются возвышения!). В документе MSDN есть следующее руководство, как это сделать - я старался следовать ему, насколько это возможно:

Функция WlanHostedNetworkForceStart может завершиться ошибкой, если состояние размещенной сети равно wlan_hosted_network_unavailable или у вызывающей стороны недостаточно прав. Эта функция для принудительного запуска размещенной сети может быть вызвана только в том случае, если у пользователя есть соответствующие связанные привилегии. Разрешения хранятся в списке управления доступом по усмотрению (DACL), связанном с WLAN_SECURABLE_OBJECT. Чтобы вызвать WlanHostedNetworkForceStart, маркер клиентского доступа вызывающей стороны должен иметь повышенные привилегии, предоставляемые следующим перечислением в WLAN_SECURABLE_OBJECT: wlan_secure_hosted_network_elevated_access

и поэтому:

Успешный вызов функции WlanSetSecuritySettings переопределяет разрешения по умолчанию, связанные с объектом. Для получения дополнительной информации о разрешениях по умолчанию см. Разрешения API-интерфейса Wifi. Далее описывается процедура создания объекта дескриптора безопасности и его анализа в виде строки. Вызовите InitializeSecurityDescriptor, чтобы создать дескриптор безопасности в памяти. Вызовите SetSecurityDescriptorOwner, чтобы установить информацию о владельце для дескриптора безопасности. Вызовите InitializeAcl, чтобы создать дискреционный список контроля доступа (DACL) в памяти. Вызовите AddAccessAllowedAce или AddAccessDeniedAce, чтобы добавить записи управления доступом (ACE) в DACL. Задайте для параметра AccessMask одну из следующих побитовых комбинаций ИЛИ в зависимости от ситуации: WLAN_READ_ACCESS WLAN_READ_ACCESS | WLAN_EXECUTE_ACCESS WLAN_READ_ACCESS | WLAN_EXECUTE_ACCESS | WLAN_WRITE_ACCESS Вызовите SetSecurityDescriptorDacl, чтобы добавить DACL в дескриптор безопасности. Вызовите ConvertSecurityDescriptorToStringSecurityDescriptor, чтобы преобразовать дескриптор в строку. Строка, возвращаемая ConvertSecurityDescriptorToStringSecurityDescriptor, может затем использоваться в качестве значения параметра strModifiedSDDL при вызове WlanSetSecuritySettings.

Итак, это мой код в первую очередь (WifiClass является статическим классом и elevateAccess() тоже статическим) - я выполнил все шаги из руководства выше:

bool WifiClass::elevateAccess() {

    PSECURITY_DESCRIPTOR securityDescriptor = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, sizeof(PACL));
    PACL pAcl = (PACL)LocalAlloc(LMEM_FIXED, sizeof(PACL));
    SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
    PSID pEveryoneSID = NULL;
    bool bRet, bRes = true;
    DWORD dRet;


    bRet = InitializeSecurityDescriptor(securityDescriptor, SECURITY_DESCRIPTOR_REVISION);
    if (!bRet)
    {
        bRes = false;
    }

    bRet = IsValidSecurityDescriptor(securityDescriptor);

    bRet = AllocateAndInitializeSid(&SIDAuthWorld, 1,
        SECURITY_WORLD_RID,
        0, 0, 0, 0, 0, 0, 0,
        &pEveryoneSID);
    if (!bRet)
    {
        bRes = false;
    }

    bRet = IsValidSecurityDescriptor(securityDescriptor);

    bRet = SetSecurityDescriptorOwner(securityDescriptor, pEveryoneSID, TRUE);
    if (!bRet)
    {
        bRes = false;
    }

    bRet = IsValidSecurityDescriptor(securityDescriptor);

    DWORD cbAcl = sizeof(ACL) +
        (sizeof(ACCESS_ALLOWED_ACE)) + (GetLengthSid(securityDescriptor) - sizeof(DWORD));
    bRet = InitializeAcl(pAcl, cbAcl, ACL_REVISION);
    if (!bRet)
    {
        bRes = false;
    }

    bRet = IsValidAcl(pAcl);

    bRet = AddAccessAllowedAce(pAcl, ACL_REVISION, WLAN_READ_ACCESS | WLAN_EXECUTE_ACCESS | WLAN_WRITE_ACCESS, securityDescriptor);
    if (!bRet)
    {
        bRes = false;
    }

    bRet = IsValidSecurityDescriptor(securityDescriptor);

    bRet = SetSecurityDescriptorDacl(securityDescriptor, TRUE, NULL, FALSE);
    if (!bRet)
    {
        bRes = false;
    }

    bRet = IsValidSecurityDescriptor(securityDescriptor);

    LPWSTR* pStringSecurityDescriptor = new LPWSTR;
    bRet = ConvertSecurityDescriptorToStringSecurityDescriptor(securityDescriptor,
        SDDL_REVISION_1,
        DACL_SECURITY_INFORMATION,
        pStringSecurityDescriptor,
        NULL
    );
    if (!bRet)
    {
        bRes = false;
    }

    WLAN_SECURABLE_OBJECT wso = wlan_secure_hosted_network_elevated_access;
    dRet = WlanSetSecuritySettings(wlanHandle, wso, (LPCWSTR)pStringSecurityDescriptor);
    if (dRet != ERROR_SUCCESS)
    {
        bRes = false;
    }

    return bRes;

}

МОЯ ПРОБЛЕМА: Кажется, все работает, все функции isValid всегда возвращают 'true'. Единственная часть, которая не работает

ConvertSecurityDescriptorToStringSecurityDescriptor(securityDescriptor,
            SDDL_REVISION_1,
            DACL_SECURITY_INFORMATION,
            pStringSecurityDescriptor,
            NULL
        );

Эта часть возвращается L"D:NO_ACCESS_CONTROL" в pStringSecurityDescriptor, И, как ожидается, следующая функция WlanSetSecuritySettings(wlanHandle, wso, (LPCWSTR)pStringSecurityDescriptor) возвращается 87:INVALID_PARAMETER поскольку строка явно не действительна.

ВОПРОС: Неужели я что-то не так после этого руководства? Нужно ли что-то еще для инициализации или другие значения? Как мне исправить код?

1 ответ

Решение

Это потому, что SetSecurityDescriptorDacl() передается нулевым для DACL, поэтому он говорит, что есть NULL DACL. Должен быть передан pAcl вместо NULL, который работает для меня.

Другие вопросы по тегам