Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Дать пользователю право на SeLockMemoryPrivilege, программно выставить права пользователю 
V
    Опции темы
GremlinProg
Дата 6.11.2008, 06:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Собственно, проблема в развернутом виде: программно добавить текущего пользователя (у него подразумеваются права админа) в список правила политики безопасности "Закрепление страниц в памяти", т.е. сделать с использованием SecurityAPI то, что мы обычно делаем ручками: Пуск -- Панель управления -- Администрирование -- Локальная политика безопасности -- Параметры безопасности -- Локальные политики -- назначение прав пользователя -- закрепление страниц в памяти -- Добавить пользователя или группу и т.д.

конечно, политика начнет функционировать только после перезагрузки, это не критично, главное за пользователя выставить это правило в системе, если попытка включить привилегию SeLockMemoryPrivilege не прошла.

программа работает с физической памятью, поэтому без этой привилегии ей делать нечего.

да, операционка, конечно, ХР.


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Pulse69
Дата 7.11.2008, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 138
Регистрация: 28.4.2006
Где: Хабаровск

Репутация: 8
Всего: 10



Вот как-то так. Если где есть косяки, прошу сильно не пинать. 

Код

#include <windows.h>
#include <ntsecapi.h>
#include <Sddl.h>


#ifndef STATUS_SUCCESS
    #define STATUS_SUCCESS 0
#endif


void FreeTokenUser(TOKEN_USER* token_ptr)
{
    if(token_ptr)
    {
        operator delete(token_ptr);
    }
}

//------------------------------------------------------------------------
//      Получает пользователя определённого токена безопасности
//
//  IN:
//      hToken - токен безопасности
//      
//  RETURNS:
//      Указатель на токен или NULL в случае ошибки.
//      За удаление отвечает вызывающая функция.
//      используйте free_token_user
//------------------------------------------------------------------------
TOKEN_USER* GetTokenUser(HANDLE hToken)
{    
    TOKEN_USER* pTokUser = NULL;
    DWORD dwLength;

    //  Узнаём размер, необходимый для получения SID.
    if(!GetTokenInformation( hToken, TokenUser, NULL, 0, &dwLength ) 
        && GetLastError()==ERROR_INSUFFICIENT_BUFFER )
    {
        //  выделяем память для SID
        pTokUser = (TOKEN_USER*) operator new (dwLength);        

        //  Получаем SID.
        if(!GetTokenInformation( hToken, TokenUser, 
            pTokUser, dwLength, &dwLength ) )
        {            
            FreeTokenUser(pTokUser);
            pTokUser = NULL;
        }
    }

    return pTokUser;
}

void FreeSidInformation(PSID psid)
{
    if(psid)
    {
        operator delete (psid);
    }
}

PSID GetSIDInformation (const wchar_t* server, const wchar_t* AccountName)
{
    PSID psid    = NULL;
    DWORD dwSize = 0;

    TCHAR *buf  = NULL;
    DWORD dwBuf = 0;

    SID_NAME_USE siu;

    //    Узнаем необходимые размеры буферов
    LookupAccountName( server,
        AccountName,
        NULL,
        &dwSize,
        NULL,
        &dwBuf,
        &siu );

    //    Выделим память под буферы
    psid = operator new ( dwSize );//    За освобождение этого указателя отвечает вызывающая функция
    buf  = (TCHAR*)operator new ( dwBuf*sizeof( TCHAR ) );

    //    Получим описатель безопасности
    if(!LookupAccountName( server,
        AccountName,
        psid,
        &dwSize,
        buf,
        &dwBuf,
        &siu ))
    {        
        FreeSidInformation(psid);
        psid = NULL;
    }

    //    нам не нужны имена доменов, в которых происходил поиск
    if( buf ) operator delete ( buf );

    return psid;
}



LSA_HANDLE GetPolicyHandle(const wchar_t *SystemName)
{
    LSA_OBJECT_ATTRIBUTES ObjectAttributes;
    USHORT SystemNameLength;
    LSA_UNICODE_STRING lusSystemName;
    NTSTATUS ntsResult;
    LSA_HANDLE lsahPolicyHandle;

    //    Инициализация
    ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));

    //    Инициализация
    wchar_t buffer[1024];
    if(SystemName != NULL)
    {
        wcscpy_s(buffer, sizeof(buffer)/sizeof(buffer[0]), SystemName);
    }

    SystemNameLength = (SystemName!=NULL)?static_cast<USHORT>(wcslen(SystemName)) : 0;
    lusSystemName.Buffer = (SystemName==NULL) ? NULL : buffer;
    lusSystemName.Length = SystemNameLength * sizeof(WCHAR);
    lusSystemName.MaximumLength = (SystemNameLength+1) * sizeof(WCHAR);

    // Get a handle to the Policy object.
    ntsResult = LsaOpenPolicy(
        &lusSystemName,    //Name of the target system.
        &ObjectAttributes, //Object attributes.
        POLICY_ALL_ACCESS, //Desired access permissions.
        &lsahPolicyHandle  //Receives the policy handle.
        );

    if (ntsResult != STATUS_SUCCESS)
    {
        // An error occurred. Display it as a win32 error code.
        return NULL;
    } 
    return lsahPolicyHandle;
}


bool InitLsaString( PLSA_UNICODE_STRING pLsaString,
                    LPCWSTR pwszString )
{
    DWORD dwLen = 0;    

    if (NULL == pLsaString)
        return FALSE;

    //    Длина строки
    if (NULL != pwszString) 
    {
        dwLen = static_cast<int>(wcslen(pwszString));
        if (dwLen > 0x7ffe)   // Слишком большая строка
            return FALSE;
    }

    // Сохраняем строку
    pLsaString->Buffer = (WCHAR *)pwszString;
    pLsaString->Length =  (USHORT)dwLen * sizeof(WCHAR);
    pLsaString->MaximumLength= (USHORT)(dwLen+1) * sizeof(WCHAR);

    return TRUE;
}




/*
 *  server - сервер, для которого устанавливается политика (NULL для локального)
 *  wacct  - учётная запись для которой устанавливается политика. 
 *           NULL   - для текущего пользователя.
 *  policy - имя политики
 *  add    - добавить или удалить политику
 */
BOOL SetPolicy(const wchar_t* server, const wchar_t *wacct, const wchar_t *policy, bool add)
{
    NTSTATUS ntsResult      = 0;
    PSID user_sid           = NULL;
    TOKEN_USER* token_user  = NULL;

    //    Получаем описатель безопасности для учётной записи
    if(wacct == NULL)
    {
        //  Учётная запись не указана. Получаем текущую
        HANDLE process_token = NULL;
        if(OpenProcessToken(GetCurrentProcess(),
            TOKEN_QUERY,
            &process_token))
        {
            token_user = GetTokenUser(process_token);
            if(token_user)
            {
                //  Описатель безопасности текущего пользователя
                user_sid = token_user->User.Sid;
            }
            CloseHandle(process_token);
        }
    }
    else
    {
        //  Получаем описатель безопасности для текущей учётной записи
        user_sid = GetSIDInformation(NULL, wacct);
    }

    //  Не нашли описатель пользвоателя
    if(user_sid == NULL)
    {
        return FALSE;
    }

    //    Создаём LSA-строку
    LSA_UNICODE_STRING lucPrivilege;
    if (!InitLsaString(&lucPrivilege, policy))
    {
        return FALSE;
    }

    //    Получаем дескриптор политик для компьютера
    LSA_HANDLE  ph = GetPolicyHandle( server );
    

    //    Добавляем политику
    if( add )
    {
        ntsResult = LsaAddAccountRights(ph, user_sid, &lucPrivilege, 1 );     
    }
    else
    {
        ntsResult = LsaRemoveAccountRights( ph, user_sid, FALSE, &lucPrivilege, 1 );
    }    

    //    закрываем описатель политики
    LsaClose( ph );

    //    удаляем память, выделенную под описатель безопасности УЗ
    if(wacct == NULL)
    {
        FreeTokenUser(token_user);        
    }
    else
    {
        FreeSidInformation(user_sid);
    }

    return (ntsResult == STATUS_SUCCESS) ? TRUE : FALSE;
}


int _tmain(int argc, _TCHAR* argv[])
{
    SetPolicy(NULL, NULL, L"SeLockMemoryPrivilege", true);
    return 0;
}




Это сообщение отредактировал(а) Pulse69 - 7.11.2008, 16:52
--------------------
Ctrl+Alt+Reset 
PM MAIL   Вверх
GremlinProg
Дата 7.11.2008, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Pulse69

большой спасибо
похоже это оно самое, +1
сейчас подправлю локализацию из юникода
потестирую и выложу общий вариант


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
GremlinProg
Дата 7.11.2008, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Проверил, работает!
код практически не менял, все корректно, просто подправил пару вызовов, чтобы его можно было использовать в обоих режимах локализации, и выделил инлайном в заголовочном файле:
Код

//////////////
//  policy.h
//

#include <ntsecapi.h>
#include <Sddl.h>


#ifndef STATUS_SUCCESS
    #define STATUS_SUCCESS 0
#endif

inline void FreeTokenUser(TOKEN_USER* token_ptr){
    if(token_ptr){
        operator delete(token_ptr);
    }
}
//------------------------------------------------------------------------
//      Получает пользователя определённого токена безопасности
//
//  IN:
//      hToken - токен безопасности
//      
//  RETURNS:
//      Указатель на токен или NULL в случае ошибки.
//      За удаление отвечает вызывающая функция.
//      используйте free_token_user
//------------------------------------------------------------------------
inline TOKEN_USER*GetTokenUser(HANDLE hToken){
    TOKEN_USER* pTokUser = NULL;
    DWORD dwLength;

    //  Узнаём размер, необходимый для получения SID.
    if(!GetTokenInformation( hToken, TokenUser, NULL, 0, &dwLength ) 
        && GetLastError()==ERROR_INSUFFICIENT_BUFFER )
    {
        //  выделяем память для SID
        pTokUser = (TOKEN_USER*) operator new (dwLength);        

        //  Получаем SID.
        if(!GetTokenInformation( hToken, TokenUser, 
            pTokUser, dwLength, &dwLength ) )
        {            
            FreeTokenUser(pTokUser);
            pTokUser = NULL;
        }
    }

    return pTokUser;
}
inline void FreeSidInformation(PSID psid){
    if(psid){
        operator delete (psid);
    }
}
inline PSID GetSIDInformation(LPCTSTR server,LPCTSTR AccountName){
    PSID psid    = NULL;
    DWORD dwSize = 0;

    TCHAR *buf  = NULL;
    DWORD dwBuf = 0;

    SID_NAME_USE siu;

    //    Узнаем необходимые размеры буферов
    ::LookupAccountName(
        server,
        AccountName,
        NULL,
        &dwSize,
        NULL,
        &dwBuf,
        &siu
    );
    //    Выделим память под буферы
    psid = operator new ( dwSize );//    За освобождение этого указателя отвечает вызывающая функция
    buf  = (TCHAR*)operator new ( dwBuf*sizeof( TCHAR ) );

    //    Получим описатель безопасности
    if( !LookupAccountName(server,AccountName,psid,&dwSize,buf,&dwBuf,&siu) ){        
        FreeSidInformation(psid);
        psid = NULL;
    }

    //    нам не нужны имена доменов, в которых происходил поиск
    if( buf ) operator delete ( buf );

    return psid;
}



inline LSA_HANDLE GetPolicyHandle(LPCWSTR SystemName){
    LSA_OBJECT_ATTRIBUTES ObjectAttributes;
    USHORT SystemNameLength;
    LSA_UNICODE_STRING lusSystemName;
    NTSTATUS ntsResult;
    LSA_HANDLE lsahPolicyHandle;

    //    Инициализация
    ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));

    //    Инициализация
    WCHAR buffer[1024];
    if(SystemName != NULL){
        wcsncpy(buffer,SystemName,sizeof(buffer)/sizeof(buffer[0]));
    }

    SystemNameLength = (SystemName != NULL)? (USHORT)wcslen(SystemName) : 0;
    lusSystemName.Buffer = (SystemName == NULL) ? NULL : buffer;
    lusSystemName.Length = SystemNameLength * sizeof(WCHAR);
    lusSystemName.MaximumLength = (SystemNameLength+1) * sizeof(WCHAR);

    // Get a handle to the Policy object.
    ntsResult = LsaOpenPolicy(
        &lusSystemName,    //Name of the target system.
        &ObjectAttributes, //Object attributes.
        POLICY_ALL_ACCESS, //Desired access permissions.
        &lsahPolicyHandle  //Receives the policy handle.
        );

    if (ntsResult != STATUS_SUCCESS)
    {
        // An error occurred. Display it as a win32 error code.
        return NULL;
    } 
    return lsahPolicyHandle;
}
inline bool InitLsaString(PLSA_UNICODE_STRING pLsaString,LPCWSTR pwszString){
    DWORD dwLen = 0;    

    if (NULL == pLsaString)
        return FALSE;

    //    Длина строки
    if (NULL != pwszString) 
    {
        dwLen = static_cast<int>(wcslen(pwszString));
        if (dwLen > 0x7ffe)   // Слишком большая строка
            return FALSE;
    }

    // Сохраняем строку
    pLsaString->Buffer = (WCHAR *)pwszString;
    pLsaString->Length =  (USHORT)dwLen * sizeof(WCHAR);
    pLsaString->MaximumLength= (USHORT)(dwLen+1) * sizeof(WCHAR);

    return TRUE;
}
/*
 *  server - сервер, для которого устанавливается политика (NULL для локального)
 *  wacct  - учётная запись для которой устанавливается политика. NULL   - для текущего пользователя.
 *  policy - имя политики
 *  add    - добавить или удалить политику
 */
inline BOOL SetPolicy(LPCWSTR server, LPCTSTR wacct, LPCWSTR policy, bool add){
    NTSTATUS ntsResult        = 0;
    PSID user_sid            = NULL;
    TOKEN_USER* token_user    = NULL;

    //    Получаем описатель безопасности для учётной записи
    if(wacct == NULL)
    {
        //  Учётная запись не указана. Получаем текущую
        HANDLE process_token = NULL;
        if(OpenProcessToken(GetCurrentProcess(),
            TOKEN_QUERY,
            &process_token))
        {
            token_user = GetTokenUser(process_token);
            if(token_user)
            {
                //  Описатель безопасности текущего пользователя
                user_sid = token_user->User.Sid;
            }
            CloseHandle(process_token);
        }
    }
    else
    {
        //  Получаем описатель безопасности для текущей учётной записи
        user_sid = GetSIDInformation(NULL, wacct);
    }

    //  Не нашли описатель пользвоателя
    if(user_sid == NULL)
    {
        return FALSE;
    }

    //    Создаём LSA-строку
    LSA_UNICODE_STRING lucPrivilege;
    if (!InitLsaString(&lucPrivilege, policy))
    {
        return FALSE;
    }

    //    Получаем дескриптор политик для компьютера
    LSA_HANDLE  ph = GetPolicyHandle( server );
    

    //    Добавляем политику
    if( add )
    {
        ntsResult = LsaAddAccountRights(ph, user_sid, &lucPrivilege, 1 );     
    }
    else
    {
        ntsResult = LsaRemoveAccountRights( ph, user_sid, FALSE, &lucPrivilege, 1 );
    }    

    //    закрываем описатель политики
    LsaClose( ph );

    //    удаляем память, выделенную под описатель безопасности УЗ
    if(wacct == NULL)
    {
        FreeTokenUser(token_user);        
    }
    else
    {
        FreeSidInformation(user_sid);
    }

    return (ntsResult == STATUS_SUCCESS) ? TRUE : FALSE;
}



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0839 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.