Форум: "WinAPI";
Текущий архив: 2009.07.19;
Скачать: [xml.tar.bz2];
ВнизКак задать права доступа к мьютексу Найти похожие ветки
← →
тимохов (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 вся ветка
Форум: "WinAPI";
Текущий архив: 2009.07.19;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.004 c