Как создать файл с LPSECURITY_ATTRIBUTES с помощью CreateFile в Windows?

Вот документ CreateFile.

Я хочу создать файл через CreateFile с помощью SECURITY_ATTRIBUTES, когда я создаю его под пользователем A учетной записи Windows, файл не должен быть доступен другому пользователю Windows B.

я нашел это Создание дескриптора безопасности для нового объекта на C++

Но все еще не мог понять, как определить определенного пользователя.

Вы, вероятно, хотите LookupAccountName получить SID для пользователя. Замените это на вызов AllocateAndInitializedSid в примере.

Sebastian Redl 21.12.2020 12:56
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
1 255
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Но все еще не мог понять, как определить определенного пользователя.

Сначала вам нужно получить SID определенного пользователя.

Вот несколько шагов,

  1. Подтвердите входные параметры.
  2. Создайте буферы для SID и имени домена, которые могут быть большими достаточно.
  3. В цикле вызовите LookupAccountName, чтобы получить SID для указано имя учетной записи. Если буфер для SID или буфер для доменное имя недостаточно велико, необходимый размер буфера возвращается в cbSid или cchDomainName соответственно, и новый буфер выделяется перед следующим вызовом LookupAccountName. Обратите внимание, что информация извлекается в локальной системе, когда lpSystemName параметр имеет значение NULL.
  4. Освободите память, выделенную для буфера доменного имени.

Затем передайте SID функции SetEntriesInAclA,

Функция SetEntriesInAcl создает новый список управления доступом (ACL). путем объединения новой информации об управлении доступом или аудите в существующая структура ACL.

Модифицированный код:

#pragma comment(lib, "advapi32.lib")

#include <windows.h>
#include <stdio.h>
#include <aclapi.h>
#include <tchar.h>
#include <mq.h.>

HRESULT GetSid(
    LPCWSTR wszAccName,
    PSID* ppSid
)
{

    // Validate the input parameters.  
    if (wszAccName == NULL || ppSid == NULL)
    {
        return MQ_ERROR_INVALID_PARAMETER;
    }

    // Create buffers that may be large enough.  
    // If a buffer is too small, the count parameter will be set to the size needed.  
    const DWORD INITIAL_SIZE = 32;
    DWORD cbSid = 0;
    DWORD dwSidBufferSize = INITIAL_SIZE;
    DWORD cchDomainName = 0;
    DWORD dwDomainBufferSize = INITIAL_SIZE;
    WCHAR* wszDomainName = NULL;
    SID_NAME_USE eSidType;
    DWORD dwErrorCode = 0;
    HRESULT hr = MQ_OK;

    // Create buffers for the SID and the domain name.  
    *ppSid = (PSID) new BYTE[dwSidBufferSize];
    if (*ppSid == NULL)
    {
        return MQ_ERROR_INSUFFICIENT_RESOURCES;
    }
    memset(*ppSid, 0, dwSidBufferSize);
    wszDomainName = new WCHAR[dwDomainBufferSize];
    if (wszDomainName == NULL)
    {
        return MQ_ERROR_INSUFFICIENT_RESOURCES;
    }
    memset(wszDomainName, 0, dwDomainBufferSize * sizeof(WCHAR));

    // Obtain the SID for the account name passed.  
    for (; ; )
    {

        // Set the count variables to the buffer sizes and retrieve the SID.  
        cbSid = dwSidBufferSize;
        cchDomainName = dwDomainBufferSize;
        if (LookupAccountNameW(
            NULL,            // Computer name. NULL for the local computer  
            wszAccName,
            *ppSid,          // Pointer to the SID buffer. Use NULL to get the size needed,  
            &cbSid,          // Size of the SID buffer needed.  
            wszDomainName,   // wszDomainName,  
            &cchDomainName,
            &eSidType
        ))
        {
            if (IsValidSid(*ppSid) == FALSE)
            {
                wprintf(L"The SID for %s is invalid.\n", wszAccName);
                dwErrorCode = MQ_ERROR;
            }
            break;
        }
        dwErrorCode = GetLastError();

        // Check if one of the buffers was too small.  
        if (dwErrorCode == ERROR_INSUFFICIENT_BUFFER)
        {
            if (cbSid > dwSidBufferSize)
            {

                // Reallocate memory for the SID buffer.  
                wprintf(L"The SID buffer was too small. It will be reallocated.\n");
                FreeSid(*ppSid);
                *ppSid = (PSID) new BYTE[cbSid];
                if (*ppSid == NULL)
                {
                    return MQ_ERROR_INSUFFICIENT_RESOURCES;
                }
                memset(*ppSid, 0, cbSid);
                dwSidBufferSize = cbSid;
            }
            if (cchDomainName > dwDomainBufferSize)
            {

                // Reallocate memory for the domain name buffer.  
                wprintf(L"The domain name buffer was too small. It will be reallocated.\n");
                delete[] wszDomainName;
                wszDomainName = new WCHAR[cchDomainName];
                if (wszDomainName == NULL)
                {
                    return MQ_ERROR_INSUFFICIENT_RESOURCES;
                }
                memset(wszDomainName, 0, cchDomainName * sizeof(WCHAR));
                dwDomainBufferSize = cchDomainName;
            }
        }
        else
        {
            wprintf(L"LookupAccountNameW failed. GetLastError returned: %d\n", dwErrorCode);
            hr = HRESULT_FROM_WIN32(dwErrorCode);
            break;
        }
    }

    delete[] wszDomainName;
    return hr;
}

void main()
{
    PSID sid;
    GetSid(L"strives", &sid); // enter a user name
    DWORD dwRes, dwDisposition;
    PACL pACL = NULL;
    PSECURITY_DESCRIPTOR pSD = NULL;
    EXPLICIT_ACCESS ea;
    SECURITY_ATTRIBUTES sa;
    HANDLE lRes = NULL;
    // Initialize an EXPLICIT_ACCESS structure for an ACE.
    // The ACE will allow Everyone read access to the key.
    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
    ea.grfAccessPermissions = GENERIC_ALL;
    ea.grfAccessMode = SET_ACCESS;
    ea.grfInheritance = NO_INHERITANCE;
    ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
    ea.Trustee.ptstrName = (LPTSTR)sid;

    // Create a new ACL that contains the new ACEs.
    dwRes = SetEntriesInAcl(1, &ea, NULL, &pACL);
    if (ERROR_SUCCESS != dwRes)
    {
        _tprintf(_T("SetEntriesInAcl Error %u\n"), GetLastError());
        goto Cleanup;
    }

    // Initialize a security descriptor.  
    pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR,
        SECURITY_DESCRIPTOR_MIN_LENGTH);
    if (NULL == pSD)
    {
        _tprintf(_T("LocalAlloc Error %u\n"), GetLastError());
        goto Cleanup;
    }

    if (!InitializeSecurityDescriptor(pSD,
        SECURITY_DESCRIPTOR_REVISION))
    {
        _tprintf(_T("InitializeSecurityDescriptor Error %u\n"),
            GetLastError());
        goto Cleanup;
    }

    // Add the ACL to the security descriptor. 
    if (!SetSecurityDescriptorDacl(pSD,
        TRUE,     // bDaclPresent flag   
        pACL,
        FALSE))   // not a default DACL 
    {
        _tprintf(_T("SetSecurityDescriptorDacl Error %u\n"),
            GetLastError());
        goto Cleanup;
    }

    // Initialize a security attributes structure.
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = pSD;
    sa.bInheritHandle = FALSE;

    // Use the security attributes to set the security descriptor 
    // when you create a key.
    lRes =  CreateFile(_T("D:\\File.txt"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
        &sa, OPEN_ALWAYS, 0, NULL);
    if (lRes != NULL)
    {
        _tprintf(_T("Create file success\n"));
    }
   
Cleanup:

    if (pACL)
        LocalFree(pACL);
    if (pSD)
        LocalFree(pSD);
    if (lRes)
       CloseHandle(lRes);
    return;

}

Вы можете убедиться, проверив свойства файла.

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