Как добавить пользователю привилегию? c++

269
21 апреля 2017, 21:27

Доброго времени суток. Пытаюсь написать программу, которая может добавлять произвольному пользователю привилегию (ну для примера SeSystemtimePrivilege). Фунция InitLsaString() нагуглена в какой-то статье, но похожа на правду. При получении сида используем первого попавшегося пользователя - ui[0].usri0_name. В целом написан код, который выводит всех и выбирает, но сюда попыталась вставить по минимуму. Функция LsaAddAccountRights() возвращает STATUS_OBJECT_NAME_NOT_FOUND. В целом при дебаггинге все аргументы функции выглядят верно.

#include <stdio.h>
#include <windows.h>
#include <lm.h>
#include <iostream>
#include <AccCtrl.h>
#include <LM.h>
#include <sddl.h>
#include <Ntsecapi.h>
using namespace std;
#pragma comment(lib,"advapi32")
#pragma comment( lib, "netapi32.lib" )
#pragma comment( lib, "user32.lib")
#define SID_DEF_SIZE 28
// для конструирования структуры PLSA_UNICODE_STRING из имени привилегии
void InitLsaString(PLSA_UNICODE_STRING LsaString, LPWSTR String)
{
    DWORD StringLength;
    if (String == NULL) {
        LsaString->Buffer = NULL;
        LsaString->Length = 0;
        LsaString->MaximumLength = 0;
        return;
    }
    StringLength = wcslen(String);
    LsaString->Buffer = String;
    LsaString->Length = (USHORT)StringLength * sizeof(WCHAR);
    LsaString->MaximumLength = (USHORT)(StringLength + 1) * sizeof(WCHAR);
}
int ChangeUserPriv()
{
    LPCWSTR servername = NULL; // имя сервера
    USER_INFO_0 *ui; // информация о пользователе
    DWORD entries_read; // количество прочитанных пользователей
    DWORD total_entries; // общее количество пользователей
    NET_API_STATUS ret_status; // код возврата из функции
                               // получаем информацию о пользователях
    ret_status = NetUserEnum(
        servername, // имя сервера
        0, // узнаем только имена пользователей
        FILTER_NORMAL_ACCOUNT, // перечисляем пользователей,
                               // зарегистрированных на компьютере
        (LPBYTE*)&ui, // адрес информации о пользователях
        MAX_PREFERRED_LENGTH, // перечисляем всех пользователей
        &entries_read, // количество прочитанных пользователей
        &total_entries, // общее количество пользователей
        NULL); // индексации нет
               // проверяем на успешное завершение
    if (ret_status != NERR_Success)
    {
        printf("Net user get info failed.\n");
        printf("Net API Status: %d\n", ret_status);
        NetApiBufferFree(ui); 
        return ret_status;
    }
    DWORD cbSID = SID_DEF_SIZE;
    DWORD *SID = (DWORD*)malloc(cbSID);
    WCHAR* strSID;
    WCHAR szDomain[1024];
    DWORD dwDomainSize = 1024;
    SID_NAME_USE SIDNameUse;
         if (!LookupAccountName(NULL, ui[0].usri0_name, SID, &cbSID, szDomain, &dwDomainSize, &SIDNameUse))
        {
            if (cbSID != SID_DEF_SIZE) {
                SID = (DWORD*)realloc(SID, cbSID);
                i--;
                continue;
            }
        }
        dwDomainSize = 1024;
        ConvertSidToStringSid(SID, &strSID);
        wprintf(L" %s   SID: %s\n", ui[0].usri0_name, strSID);
        // а теперь привилегии. для начала выведем что есть

        ULONG cPrivs = 0;
        LSA_UNICODE_STRING compName = { 0 };
        LSA_OBJECT_ATTRIBUTES lsaOA = { 0 };
        LSA_HANDLE hPolicy;
        NTSTATUS stat;
        stat = LsaOpenPolicy(&compName, &lsaOA, POLICY_LOOKUP_NAMES, &hPolicy);
        ULONG err = LsaNtStatusToWinError(stat);
        if (err != ERROR_SUCCESS) {
            cout << "open policy error" << endl;
            break;
        }
        PLSA_UNICODE_STRING pPrivs;
        stat = LsaEnumerateAccountRights(hPolicy, SID, &pPrivs, &cPrivs);
        if (cPrivs != 0) {
            cout << "Привилегии:" << endl;
            for (ULONG i = 0; i < cPrivs; i++) {
                PWSTR pBuf = new WCHAR[pPrivs[i].MaximumLength];
                wcsncpy(pBuf, pPrivs[i].Buffer, pPrivs[i].Length);
                std::wcout << "    " << i + 1 << ") " << pBuf << endl;
                delete[] pBuf;
            }
        }
        else
            cout << "none" << endl;
                // а теперь само добавление привилегий
        LSA_UNICODE_STRING PrivilegeString;
               // ну например такую
        LPWSTR PrivilegeName = L"SeSystemtimePrivilege";
        InitLsaString(&PrivilegeString, PrivilegeName);
        stat = LsaAddAccountRights(hPolicy, SID, &PrivilegeString, 1);
        if (stat == ERROR_SUCCESS)
            cout << "success" << endl;
        else 
            cout << "fail" << endl;
    }
    NetApiBufferFree(ui); // освобождаем буфер
    return 0;
}

int main()
{
    setlocale(LC_ALL, "Russian");
    ChangeUserPriv();
    return 0;
}
READ ALSO
Распознавание лиц Qt C++

Распознавание лиц Qt C++

Необходимо написать программу для распознавания лиц на фотографиях, и по идентифицированным лицам осуществить сортировку фотоСтоит ли использовать...

453
Работа с Visual Studio 2015

Работа с Visual Studio 2015

Ранее работая в среде разработки - DEV-C++ Для написания таблицы я использовал сочетании клавиш Alt+[введенный код фрагмента таблицы(ASCI-кода)]К...

266