En el siguiente ejemplo demuestro como crear un descriptor de seguridad (security descriptor) para permitir el acceso a un objeto del kernel a todos los usuarios, de esta manera puede ser compartido por procesos pertenecientes a diferentes cuentas de usuario. Esto puede resultar útil, por ejemplo, cuando un servicio tiene que compartir un objeto con una aplicación que se esta ejecutando bajo una cuenta de usuario diferente.
La siguiente función inicializa la variable del tipo SECURITY_DESCRIPTOR, que se le pasa como parámetro, con una DACL que permite a todos los usuarios identificados los accesos GERERIC_READ, GENERIC_WRITE y GENERIC_EXECUTE. La función devuelve nil si falla o un puntero si termina con éxito. Este puntero debe ser liberado, una vez lo hemos utilizado para crear el nuevo objeto, llamando a la función FreeRestridtedSD.
const SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5)); SECURITY_AUTHENTICATED_USER_RID = 11; ACL_REVISION = 2; type ACE_HEADER = record AceType, AceFlags: BYTE; AceSize: WORD; end; PACE_HEADER = ^ACE_HEADER; ACCESS_ALLOWED_ACE = record Header: ACE_HEADER; Mask: ACCESS_MASK; SidStart: DWORD; end; function BuildRestrictedSD(pSD: PSECURITY_DESCRIPTOR): Pointer; var dwAclLength: DWORD; pAuthenticatedUsersSID: PSID; pDACL: PACL; bResult: BOOL; siaNT: SID_IDENTIFIER_AUTHORITY; begin pAuthenticatedUsersSID:= nil; pDACL:= nil; bResult:= FALSE; siaNT:= SECURITY_NT_AUTHORITY; if InitializeSecurityDescriptor(pSD,SECURITY_DESCRIPTOR_REVISION) then if AllocateAndInitializeSid(siaNT, 1, SECURITY_AUTHENTICATED_USER_RID, 0, 0, 0, 0, 0, 0, 0,pAuthenticatedUsersSID) then begin dwAclLength:= Sizeof(ACL) + Sizeof(ACCESS_ALLOWED_ACE) - Sizeof(DWORD) + GetLengthSid(pAuthenticatedUsersSID); GetMem(pDACL,dwAclLength); if InitializeAcl(pDACL^, dwAclLength, ACL_REVISION) then if AddAccessAllowedAce(pDACL^, ACL_REVISION, GENERIC_READ or GENERIC_WRITE or GENERIC_EXECUTE, pAuthenticatedUsersSID) then if SetSecurityDescriptorDacl(pSD, TRUE, pDACL, FALSE) then bResult:= TRUE; if pAuthenticatedUsersSID <> nil then FreeSid(pAuthenticatedUsersSID); if not bResult then if pDACL <> nil then begin FreeMem(pDACL); pDACL:= nil; end; end; Result:= pDACL; end;
Ahora vamos a demostrar como, utilizando la función anterior, podemos crear un mutex que puede ser compartido entre distintos usuarios:
function CrearMutex(Nombre: String): THandle; var sa: SECURITY_ATTRIBUTES; sd: SECURITY_DESCRIPTOR; ptr: Pointer; begin Result:= 0; ptr:= BuildRestrictedSD(@sd); if ptr <> nil then try sa.nLength:= Sizeof(sa); sa.lpSecurityDescriptor:= @sd; sa.bInheritHandle:= FALSE; Result:= CreateMutex(@sa, TRUE, PChar(Nombre)); if Result <> 0 then ReleaseMutex(Result); finally FreeMem(ptr); end; end;
Comentarios
Muy interesante este
Muy interesante este código!!!, lo probaré.
saludos seoane