Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.07.19;
Скачать: CL | DM;

Вниз

Как задать права доступа к мьютексу   Найти похожие ветки 

 
тимохов   (2008-04-15 16:03) [0]

Здравствуйте.

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

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

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

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

Спасибо.


 
Игорь Шевченко ©   (2008-04-15 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;


 
ага   (2008-04-15 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
> с заданием прав?

Ей по барабану.


 
ага   (2008-04-15 19:56) [3]

Эта ежель доступ ваще всем и кажнему. Ежель группе "Все", то чуток сложнее. А ежель нать, шоб меж терминальными сессиями видать было, то имя "Global\MyMutex"


 
Ins ©   (2008-04-16 13:26) [4]


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

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


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

Вылетит при старте приложения, наверное, так как DLL вы видимо подключаете статически, а на Win9x функций для управления безопасности нет.


 
Eraser ©   (2008-04-16 14:39) [5]

> [4] Ins ©   (16.04.08 13:26)

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


 
Ins ©   (2008-04-16 15:57) [6]


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

Возможно, я этот вопрос не исследовал, поверю на слово ;)


 
bycka   (2008-06-04 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   (2008-06-04 17:57) [8]

Ссори, код конечно не Игорь Шевченко, а Игоря Шевченко :)


 
bycka   (2008-06-04 18:02) [9]

Блин и код перевел не Игорь Шеченко, а я :) Чорт возьми, плохо без редактирования ;)
Кстати, не так много качественной инфы по этой теме, респект за код ИШ.


 
Eraser ©   (2008-06-06 19:17) [10]

> [8] bycka   (04.06.08 17:57)
> Ссори, код конечно не Игорь Шевченко, а Игоря Шевченко

и не на C#, а на C++ )



Страницы: 1 вся ветка

Текущий архив: 2009.07.19;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.011 c
15-1242463718
oxffff
2009-05-16 12:48
2009.07.19
Помогите скачать


2-1243354204
ondesly
2009-05-26 20:10
2009.07.19
Canvas.CopyRect


15-1242668346
DmitriyG.
2009-05-18 21:39
2009.07.19
Добавить исходники


15-1242658209
TUser
2009-05-18 18:50
2009.07.19
Господа юристы


2-1243338367
dmitrot
2009-05-26 15:46
2009.07.19
Как убрать вертикальный и горизонтальный скролбары в DBGrid ?