Конференция "WinAPI" » Как задать права доступа к мьютексу
 
  • тимохов (15.04.08 16:03) [0]
    Здравствуйте.

    СИТУАЦИЯ
    Я использую именованные мьютексы для запрета запуска более одного приложения из группы. Т.е. есть 6 приложений и один сервис, и только один из них может быть запущен в один момент времени. При создании мьютекса я передаю NIL в первом параметре функции CreateMutex.

    ПРОБЛЕМЫ
    Если первым запускается сервис он создается именованный мьютекс. При этом при запуске обычного приложения и попытке создания мьютекса с аналогичным именем происходит ошибка - недостаточно прав.

    Я так понимаю, что это потому, что сервис работает из под LocalSystem. И мьютекс имеет по умолчанию права этого самого LocalSystem. И обычное приложение доступа к мьютексу не имеет.

    ВОПРОСЫ
    1. Как задать первый параметр в CreateMutex таким образом, чтобы любой эккаунт мог выполнить CreateMutex без ошибки недостаточности прав?
    2. Как поведет себя Win98, если в нем выполнить CreateMutex с заданием прав?

    Спасибо.
  • Игорь Шевченко © (15.04.08 17:42) [1]
    RTFM: SecurityDescriptor

    где-то так...

    function CreateFullAccessSA(var SA: TSecurityAttributes): Boolean;
    type
     TAceHeader = packed record
       AceType: Byte;
       AceFlags: Byte;
       AceSize: Word;
     end;
     TAccessAllowedAce = packed record
       Header: TAceHeader;
       Mask: ACCESS_MASK;
       SidStart: DWORD;
     end;
    const
     FILE_READ_DATA            = $0001; // file & pipe
     FILE_LIST_DIRECTORY       = $0001; // directory
     FILE_WRITE_DATA           = $0002; // file & pipe
     FILE_ADD_FILE             = $0002; // directory
     FILE_APPEND_DATA          = $0004; // file
     FILE_ADD_SUBDIRECTORY     = $0004; // directory
     FILE_CREATE_PIPE_INSTANCE = $0004; // named pipe
     FILE_READ_EA              = $0008; // file & directory
     FILE_WRITE_EA             = $0010; // file & directory
     FILE_EXECUTE              = $0020; // file
     FILE_TRAVERSE             = $0020; // directory
     FILE_DELETE_CHILD         = $0040; // directory
     FILE_READ_ATTRIBUTES      = $0080; // all
     FILE_WRITE_ATTRIBUTES     = $0100; // all
     FILE_ALL_ACCESS           = (STANDARD_RIGHTS_REQUIRED or Windows.SYNCHRONIZE or $1FF);
     FILE_GENERIC_READ         = (STANDARD_RIGHTS_READ or FILE_READ_DATA or
       FILE_READ_ATTRIBUTES or FILE_READ_EA or Windows.SYNCHRONIZE);
     FILE_GENERIC_WRITE        = (STANDARD_RIGHTS_WRITE or FILE_WRITE_DATA or
       FILE_WRITE_ATTRIBUTES or FILE_WRITE_EA or FILE_APPEND_DATA or Windows.SYNCHRONIZE);
     FILE_GENERIC_EXECUTE      = (STANDARD_RIGHTS_EXECUTE or FILE_READ_ATTRIBUTES or
       FILE_EXECUTE or Windows.SYNCHRONIZE);

     HEAP_ZERO_MEMORY   = $00000008;
     ACL_REVISION       = 2;
     SECURITY_WORLD_RID = $00000000;
     SECURITY_WORLD_SID_AUTHORITY: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 1));
    var
     pSD: PSecurityDescriptor;
     psidEveryone: PSID;
     sidAuth: TSidIdentifierAuthority;
     lSDSize, lACLSize: Cardinal;
     lpACL: PACL;
    begin
     Result := False;
     pSD := nil;
     psidEveryone := nil;
     try
       SA.nLength := SizeOf(TSecurityAttributes);
       SA.lpSecurityDescriptor := nil;
       SA.bInheritHandle := False;

       sidAuth := SECURITY_WORLD_SID_AUTHORITY;
       if not AllocateAndInitializeSid(sidAuth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0,
         0, 0, 0, psidEveryone) then begin
         Exit;
       end;
       lSDSize := SizeOf(TSecurityDescriptor);
       lACLSize := GetLengthSID(psidEveryone) + SizeOf(TAccessAllowedACE) + SizeOf(TACL);
       pSD := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, lSDSize + lACLSize);
       if pSD = nil then begin
         Exit;
       end;
       if not InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION) then begin
         Exit;
       end;
       lpACL := PACL(PChar(pSD) + lSDSize);
       if not InitializeAcl(lpACL^, lACLSize, ACL_REVISION) then begin
         Exit;
       end;
       if not AddAccessAllowedAce(lpACL^, ACL_REVISION, FILE_ALL_ACCESS {FILE_GENERIC_READ
         or FILE_GENERIC_WRITE}, psidEveryone) then begin
         Exit;
       end;
       if not SetSecurityDescriptorDacl(pSD, True, lpACL, False) then begin
         Exit;
       end;
       SA.lpSecurityDescriptor := pSD;
       Result := True;

     finally
       if psidEveryone <> nil then
         FreeSID(psidEveryone);
       if (Result = False) and (pSD <> nil) then
         HeapFree(GetProcessHeap, 0, pSD);
     end;
    end;
  • ага (15.04.08 19:52) [2]

    > 1. Как задать первый параметр в CreateMutex таким образом,
    >  чтобы любой эккаунт мог выполнить CreateMutex без ошибки
    > недостаточности прав?

    var
     SD: TSecurityDescriptor;
     SA: TSecurityAttributes;

    Win32Check(InitializeSecurityDescriptor(@SD, SECURITY_DESCRIPTOR_REVISION);
    Win32Check(SetSecurityDescriptorDacl(@SD, true, nil, false));
    SA.nLength:= SizeOf(SA);
    SA.lpSecurityDescriptor := @SD;
    SA.bInheritHandle := False;
    Mutex:= CreateMutex(@SA, false, 'Mymutex');



    > 2. Как поведет себя Win98, если в нем выполнить CreateMutex
    > с заданием прав?

    Ей по барабану.
  • ага (15.04.08 19:56) [3]
    Эта ежель доступ ваще всем и кажнему. Ежель группе "Все", то чуток сложнее. А ежель нать, шоб меж терминальными сессиями видать было, то имя "Global\MyMutex"
  • Ins © (16.04.08 13:26) [4]

    > где-то так...

    Не проще ли nil в качестве DACL задать? ;)


    > 2. Как поведет себя Win98, если в нем выполнить CreateMutex
    > с заданием прав?

    Вылетит при старте приложения, наверное, так как DLL вы видимо подключаете статически, а на Win9x функций для управления безопасности нет.
  • Eraser © (16.04.08 14:39) [5]
    > [4] Ins ©   (16.04.08 13:26)

    там они есть, но в виде заглушек.
  • Ins © (16.04.08 15:57) [6]

    > там они есть, но в виде заглушек.

    Возможно, я этот вопрос не исследовал, поверю на слово ;)
  • bycka (04.06.08 17:56) [7]
    А вот посмотрите, правильно перевел код Игорь Шевченко на C#

    BOOL
    CreateAccessSA(
    SECURITY_ATTRIBUTES * SA
    )      
    {
     SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_LOCAL_SID_AUTHORITY;
        PSECURITY_DESCRIPTOR  pSD;
        PACL lpACL;
        PSID psidEveryone;
        DWORD  lSDSize,
         lACLSize;
        BOOL Result = true;

     SA->nLength = sizeof(SECURITY_ATTRIBUTES);
     SA->bInheritHandle = false;
     SA->lpSecurityDescriptor = NULL;

        if (!AllocateAndInitializeSid(&sidAuth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0,
     0, 0, 0, &psidEveryone)) {

        goto cleanup;
        Result = false;
        }


     lSDSize = sizeof(SECURITY_DESCRIPTOR);
        lACLSize = GetLengthSid(psidEveryone) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(ACL);

     if ((pSD = HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, lSDSize + lACLSize)) == NULL) {

        goto cleanup;
        Result = false;
     }


     if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {

        goto cleanup;
        Result = false;
     }


        lpACL = (PACL)pSD + lSDSize;

     if (!InitializeAcl(lpACL, lACLSize, ACL_REVISION)) {

        goto cleanup;
        Result = false;
     }


     if (!AddAccessAllowedAce(lpACL, ACL_REVISION, FILE_ALL_ACCESS, psidEveryone)) {

        goto cleanup;
        Result = false;
     }


     if (!SetSecurityDescriptorDacl(pSD, true, lpACL, false)) {

        goto cleanup;
        Result = false;
     }


        SA->lpSecurityDescriptor = pSD;

    cleanup:

      if (psidEveryone != NULL)
      FreeSid(psidEveryone);
      if (pSD != NULL)
      HeapFree(GetProcessHeap, 0, pSD);

    return Result;
    }

  • bycka (04.06.08 17:57) [8]
    Ссори, код конечно не Игорь Шевченко, а Игоря Шевченко :)
  • bycka (04.06.08 18:02) [9]
    Блин и код перевел не Игорь Шеченко, а я :) Чорт возьми, плохо без редактирования ;)
    Кстати, не так много качественной инфы по этой теме, респект за код ИШ.
  • Eraser © (06.06.08 19:17) [10]
    > [8] bycka   (04.06.08 17:57)
    > Ссори, код конечно не Игорь Шевченко, а Игоря Шевченко

    и не на C#, а на C++ )
 
Конференция "WinAPI" » Как задать права доступа к мьютексу
Есть новые Нет новых   [134432   +20][b:0][p:0.002]