static DWORD EVTAddAllowAces( PACL pDacl, DWORD dwCount, PSID* ppSidArray, ACCESS_MASK dwAccessMask ) { DWORD dwInputIndex = 0; DWORD dwError = 0; for (dwInputIndex = 0; dwInputIndex < dwCount; dwInputIndex++) { dwError = LwNtStatusToWin32Error( RtlAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, dwAccessMask, ppSidArray[dwInputIndex])); BAIL_ON_EVT_ERROR(dwError); } cleanup: return dwError; error: goto cleanup; }
static NTSTATUS RtlpSysVolCreateSecurityDescriptor(OUT PISECURITY_DESCRIPTOR *SecurityDescriptor, OUT PSID *SystemSid) { PSECURITY_DESCRIPTOR AbsSD = NULL; PSID LocalSystemSid = NULL; PACL Dacl = NULL; ULONG DaclSize; NTSTATUS Status; /* create the local SYSTEM SID */ Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &LocalSystemSid); if (!NT_SUCCESS(Status)) { return Status; } /* allocate and initialize the security descriptor */ AbsSD = RtlpAllocateMemory(sizeof(SECURITY_DESCRIPTOR), 'dSeS'); if (AbsSD == NULL) { Status = STATUS_NO_MEMORY; goto Cleanup; } Status = RtlCreateSecurityDescriptor(AbsSD, SECURITY_DESCRIPTOR_REVISION); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* allocate and create the DACL */ DaclSize = sizeof(ACL) + sizeof(ACE) + RtlLengthSid(LocalSystemSid); Dacl = RtlpAllocateMemory(DaclSize, 'cAeS'); if (Dacl == NULL) { Status = STATUS_NO_MEMORY; goto Cleanup; } Status = RtlCreateAcl(Dacl, DaclSize, ACL_REVISION); if (!NT_SUCCESS(Status)) { goto Cleanup; } Status = RtlAddAccessAllowedAceEx(Dacl, ACL_REVISION, OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE, STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, LocalSystemSid); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* set the DACL in the security descriptor */ Status = RtlSetDaclSecurityDescriptor(AbsSD, TRUE, Dacl, FALSE); /* all done */ if (NT_SUCCESS(Status)) { *SecurityDescriptor = AbsSD; *SystemSid = LocalSystemSid; } else { Cleanup: if (LocalSystemSid != NULL) { RtlFreeSid(LocalSystemSid); } if (Dacl != NULL) { RtlpFreeMemory(Dacl, 'cAeS'); } if (AbsSD != NULL) { RtlpFreeMemory(AbsSD, 'dSeS'); } } return Status; }
NTSTATUS SrvShareSetDefaultSecurity( PSRV_SHARE_INFO pShareInfo ) { NTSTATUS ntStatus = STATUS_SUCCESS; PSECURITY_DESCRIPTOR_RELATIVE pRelSecDesc = NULL; ULONG ulRelSecDescLen = 0; PSECURITY_DESCRIPTOR_ABSOLUTE pAbsSecDesc = NULL; DWORD dwAceCount = 0; PSID pOwnerSid = NULL; PSID pGroupSid = NULL; PACL pDacl = NULL; DWORD dwSizeDacl = 0; union { SID sid; BYTE buffer[SID_MAX_SIZE]; } administratorsSid; union { SID sid; BYTE buffer[SID_MAX_SIZE]; } powerUsersSid; union { SID sid; BYTE buffer[SID_MAX_SIZE]; } everyoneSid; ULONG ulAdministratorsSidSize = sizeof(administratorsSid.buffer); ULONG ulPowerUsersSidSize = sizeof(powerUsersSid.buffer); ULONG ulEveryoneSidSize = sizeof(everyoneSid.buffer); ACCESS_MASK worldAccessMask = 0; /* Clear out any existing SecDesc's. This is not a normal use case, but be paranoid */ if (pShareInfo->ulSecDescLen) { SrvShareFreeSecurity(pShareInfo); } /* Build the new Absolute Security Descriptor */ ntStatus = RTL_ALLOCATE( &pAbsSecDesc, VOID, SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlCreateSecurityDescriptorAbsolute( pAbsSecDesc, SECURITY_DESCRIPTOR_REVISION); BAIL_ON_NT_STATUS(ntStatus); /* Create some SIDs */ ntStatus = RtlCreateWellKnownSid( WinBuiltinAdministratorsSid, NULL, (PSID)administratorsSid.buffer, &ulAdministratorsSidSize); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlCreateWellKnownSid( WinBuiltinPowerUsersSid, NULL, (PSID)powerUsersSid.buffer, &ulPowerUsersSidSize); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlCreateWellKnownSid( WinWorldSid, NULL, (PSID)everyoneSid.buffer, &ulEveryoneSidSize); BAIL_ON_NT_STATUS(ntStatus); /* Owner: Administrators */ ntStatus = RtlDuplicateSid(&pOwnerSid, &administratorsSid.sid); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlSetOwnerSecurityDescriptor( pAbsSecDesc, pOwnerSid, FALSE); BAIL_ON_NT_STATUS(ntStatus); /* Group: Power Users */ ntStatus = RtlDuplicateSid(&pGroupSid, &powerUsersSid.sid); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlSetGroupSecurityDescriptor( pAbsSecDesc, pGroupSid, FALSE); BAIL_ON_NT_STATUS(ntStatus); /* DACL: Administrators - (Full Control) Everyone - (Read) for disk shares, (Read/Write) to IPC shares */ dwAceCount = 2; dwSizeDacl = ACL_HEADER_SIZE + dwAceCount * sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(&administratorsSid.sid) + RtlLengthSid(&everyoneSid.sid) - dwAceCount * sizeof(ULONG); ntStatus= RTL_ALLOCATE(&pDacl, VOID, dwSizeDacl); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlCreateAcl(pDacl, dwSizeDacl, ACL_REVISION); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlAddAccessAllowedAceEx( pDacl, ACL_REVISION, 0, FILE_ALL_ACCESS, &administratorsSid.sid); BAIL_ON_NT_STATUS(ntStatus); worldAccessMask = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE; if (pShareInfo->service == SHARE_SERVICE_NAMED_PIPE) { worldAccessMask |= FILE_GENERIC_WRITE; } ntStatus = RtlAddAccessAllowedAceEx( pDacl, ACL_REVISION, 0, worldAccessMask, &everyoneSid.sid); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlSetDaclSecurityDescriptor( pAbsSecDesc, TRUE, pDacl, FALSE); BAIL_ON_NT_STATUS(ntStatus); /* Create the SelfRelative SD and assign them to the Share */ ntStatus = RtlAbsoluteToSelfRelativeSD( pAbsSecDesc, NULL, &ulRelSecDescLen); if (ntStatus == STATUS_BUFFER_TOO_SMALL) { ntStatus = SrvAllocateMemory(ulRelSecDescLen, (PVOID*)&pRelSecDesc); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlAbsoluteToSelfRelativeSD( pAbsSecDesc, pRelSecDesc, &ulRelSecDescLen); } BAIL_ON_NT_STATUS(ntStatus); pShareInfo->pSecDesc = pRelSecDesc; pShareInfo->ulSecDescLen = ulRelSecDescLen; pShareInfo->pAbsSecDesc = pAbsSecDesc; ntStatus = STATUS_SUCCESS; cleanup: return ntStatus; error: RTL_FREE(&pAbsSecDesc); RTL_FREE(&pOwnerSid); RTL_FREE(&pGroupSid); RTL_FREE(&pDacl); if (pRelSecDesc) { SrvFreeMemory(pRelSecDesc); } goto cleanup; }
static DWORD LwpsLegacyBuildRestrictedDaclForKey( IN PSID pAllAccessSid, IN OPTIONAL PSID pReadAccessSid, OUT PACL *ppDacl ) { NTSTATUS status = STATUS_SUCCESS; int EE = 0; DWORD dwSidCount = 0; DWORD dwTotalSidSize = 0; DWORD dwDaclSize = 0; PACL pDacl = NULL; DWORD dwError = 0; dwSidCount++; dwTotalSidSize = RtlLengthSid(pAllAccessSid); if (pReadAccessSid) { dwSidCount++; dwTotalSidSize += RtlLengthSid(pReadAccessSid); } dwDaclSize = ACL_HEADER_SIZE + dwSidCount * LW_FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + dwTotalSidSize; status = LW_RTL_ALLOCATE(&pDacl, VOID, dwDaclSize); GOTO_CLEANUP_ON_STATUS_EE(status, EE); status = RtlCreateAcl(pDacl, dwDaclSize, ACL_REVISION); GOTO_CLEANUP_ON_STATUS_EE(status, EE); status = RtlAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, KEY_ALL_ACCESS, pAllAccessSid); GOTO_CLEANUP_ON_STATUS_EE(status, EE); if (pReadAccessSid) { status = RtlAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, KEY_READ, pReadAccessSid); GOTO_CLEANUP_ON_STATUS_EE(status, EE); } cleanup: if (status) { LW_RTL_FREE(&pDacl); } *ppDacl = pDacl; dwError = LwNtStatusToWin32Error(status); LSA_PSTORE_LOG_LEAVE_ERROR_EE(dwError, EE); return dwError; }
static DWORD ConstructSecurityDescriptor( DWORD dwAllowUserCount, PWSTR* ppwszAllowUsers, DWORD dwDenyUserCount, PWSTR* ppwszDenyUsers, BOOLEAN bReadOnly, PSECURITY_DESCRIPTOR_RELATIVE* ppRelative, PDWORD pdwRelativeSize ) { DWORD dwError = 0; PSECURITY_DESCRIPTOR_ABSOLUTE pAbsolute = NULL; PSECURITY_DESCRIPTOR_RELATIVE pRelative = NULL; union { SID sid; BYTE buffer[SID_MAX_SIZE]; } Owner; union { SID sid; BYTE buffer[SID_MAX_SIZE]; } Group; ULONG OwnerSidSize = sizeof(Owner.buffer); ULONG GroupSidSize = sizeof(Group.buffer); DWORD dwDaclSize = 0; PACL pDacl = NULL; DWORD dwIndex = 0; PSID pSid = NULL; ULONG ulRelativeSize = 0; HANDLE hLsa = NULL; ACCESS_MASK mask = bReadOnly ? (FILE_GENERIC_READ|FILE_GENERIC_EXECUTE) : FILE_ALL_ACCESS; dwError = LsaOpenServer(&hLsa); BAIL_ON_LTNET_ERROR(dwError); dwError = LwNtStatusToWin32Error( RtlCreateWellKnownSid( WinBuiltinAdministratorsSid, NULL, &Owner.sid, &OwnerSidSize)); BAIL_ON_LTNET_ERROR(dwError); dwError = LwNtStatusToWin32Error( RtlCreateWellKnownSid( WinBuiltinPowerUsersSid, NULL, &Group.sid, &GroupSidSize)); BAIL_ON_LTNET_ERROR(dwError); dwDaclSize = ACL_HEADER_SIZE + dwAllowUserCount * (sizeof(ACCESS_ALLOWED_ACE) + SID_MAX_SIZE) + dwDenyUserCount * (sizeof(ACCESS_DENIED_ACE) + SID_MAX_SIZE) + RtlLengthSid(&Owner.sid) + RtlLengthSid(&Group.sid); dwError = LwNetAllocateMemory( dwDaclSize, OUT_PPVOID(&pDacl)); BAIL_ON_LTNET_ERROR(dwError); dwError = LwNtStatusToWin32Error( RtlCreateAcl(pDacl, dwDaclSize, ACL_REVISION)); BAIL_ON_LTNET_ERROR(dwError); for (dwIndex = 0; dwIndex < dwDenyUserCount; dwIndex++) { dwError = MapNameToSid(hLsa, ppwszDenyUsers[dwIndex], &pSid); if (dwError != LW_ERROR_SUCCESS) { dwError = MapBuiltinNameToSid(&pSid, ppwszDenyUsers[dwIndex]); } BAIL_ON_LTNET_ERROR(dwError); dwError = LwNtStatusToWin32Error( RtlAddAccessDeniedAceEx( pDacl, ACL_REVISION, 0, FILE_ALL_ACCESS, pSid)); BAIL_ON_LTNET_ERROR(dwError); RTL_FREE(&pSid); } for (dwIndex = 0; dwIndex < dwAllowUserCount; dwIndex++) { dwError = MapNameToSid(hLsa, ppwszAllowUsers[dwIndex], &pSid); if (dwError != LW_ERROR_SUCCESS) { dwError = MapBuiltinNameToSid(&pSid, ppwszAllowUsers[dwIndex]); } BAIL_ON_LTNET_ERROR(dwError); dwError = LwNtStatusToWin32Error( RtlAddAccessAllowedAceEx( pDacl, ACL_REVISION, 0, mask, pSid)); BAIL_ON_LTNET_ERROR(dwError); RTL_FREE(&pSid); } dwError = LwNetAllocateMemory( SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE, OUT_PPVOID(&pAbsolute)); BAIL_ON_LTNET_ERROR(dwError); dwError = LwNtStatusToWin32Error( RtlCreateSecurityDescriptorAbsolute( pAbsolute, SECURITY_DESCRIPTOR_REVISION)); BAIL_ON_LTNET_ERROR(dwError); dwError = LwNtStatusToWin32Error( RtlSetOwnerSecurityDescriptor( pAbsolute, &Owner.sid, FALSE)); BAIL_ON_LTNET_ERROR(dwError); dwError = LwNtStatusToWin32Error( RtlSetGroupSecurityDescriptor( pAbsolute, &Group.sid, FALSE)); BAIL_ON_LTNET_ERROR(dwError); dwError = LwNtStatusToWin32Error( RtlSetDaclSecurityDescriptor( pAbsolute, TRUE, pDacl, FALSE)); BAIL_ON_LTNET_ERROR(dwError); RtlAbsoluteToSelfRelativeSD( pAbsolute, NULL, &ulRelativeSize); dwError = LwNetAllocateMemory(ulRelativeSize, OUT_PPVOID(&pRelative)); BAIL_ON_LTNET_ERROR(dwError); dwError = LwNtStatusToWin32Error( RtlAbsoluteToSelfRelativeSD( pAbsolute, pRelative, &ulRelativeSize)); BAIL_ON_LTNET_ERROR(dwError); *ppRelative = pRelative; *pdwRelativeSize = ulRelativeSize; cleanup: if (hLsa) { LsaCloseServer(hLsa); } LTNET_SAFE_FREE_MEMORY(pSid); LTNET_SAFE_FREE_MEMORY(pDacl); LTNET_SAFE_FREE_MEMORY(pAbsolute); return dwError; error: *ppRelative = NULL; *pdwRelativeSize = 0; LTNET_SAFE_FREE_MEMORY(pRelative); goto cleanup; }
static NTSTATUS SrvBuildDefaultShareSID( PSECURITY_DESCRIPTOR_RELATIVE* ppSecDesc ) { NTSTATUS ntStatus = STATUS_SUCCESS; PSECURITY_DESCRIPTOR_RELATIVE pRelSecDesc = NULL; ULONG ulRelSecDescLen = 0; PSECURITY_DESCRIPTOR_ABSOLUTE pAbsSecDesc = NULL; DWORD dwAceCount = 0; PSID pOwnerSid = NULL; PSID pGroupSid = NULL; PACL pDacl = NULL; DWORD dwSizeDacl = 0; union { SID sid; BYTE buffer[SID_MAX_SIZE]; } localSystemSid; union { SID sid; BYTE buffer[SID_MAX_SIZE]; } administratorsSid; union { SID sid; BYTE buffer[SID_MAX_SIZE]; } builtinUsersSid; ULONG ulLocalSystemSidSize = sizeof(localSystemSid.buffer); ULONG ulAdministratorsSidSize = sizeof(administratorsSid.buffer); ULONG ulBuiltinUsersSidSize = sizeof(builtinUsersSid.buffer); ACCESS_MASK builtinUsersAccessMask = 0; ULONG ulAceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; /* Build the new Absolute Security Descriptor */ ntStatus = RTL_ALLOCATE( &pAbsSecDesc, VOID, SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlCreateSecurityDescriptorAbsolute( pAbsSecDesc, SECURITY_DESCRIPTOR_REVISION); BAIL_ON_NT_STATUS(ntStatus); /* Create some SIDs */ ntStatus = RtlCreateWellKnownSid( WinLocalSystemSid, NULL, (PSID)localSystemSid.buffer, &ulLocalSystemSidSize); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlCreateWellKnownSid( WinBuiltinAdministratorsSid, NULL, (PSID)administratorsSid.buffer, &ulAdministratorsSidSize); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlCreateWellKnownSid( WinBuiltinUsersSid, NULL, (PSID)builtinUsersSid.buffer, &ulBuiltinUsersSidSize); BAIL_ON_NT_STATUS(ntStatus); /* Owner: Local System */ ntStatus = RtlDuplicateSid(&pOwnerSid, &localSystemSid.sid); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlSetOwnerSecurityDescriptor( pAbsSecDesc, pOwnerSid, FALSE); BAIL_ON_NT_STATUS(ntStatus); /* Group: Administrators */ ntStatus = RtlDuplicateSid(&pGroupSid, &administratorsSid.sid); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlSetGroupSecurityDescriptor( pAbsSecDesc, pGroupSid, FALSE); BAIL_ON_NT_STATUS(ntStatus); /* DACL: Administrators - (Full Control) LocalSystem - (Full Control) Builtin Users - (Read && Execute && List Directory Contents) */ dwAceCount = 3; dwSizeDacl = ACL_HEADER_SIZE + dwAceCount * sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(&localSystemSid.sid) + RtlLengthSid(&administratorsSid.sid) + RtlLengthSid(&builtinUsersSid.sid) - dwAceCount * sizeof(ULONG); ntStatus= RTL_ALLOCATE(&pDacl, VOID, dwSizeDacl); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlCreateAcl(pDacl, dwSizeDacl, ACL_REVISION); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlAddAccessAllowedAceEx( pDacl, ACL_REVISION, ulAceFlags, FILE_ALL_ACCESS, &localSystemSid.sid); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlAddAccessAllowedAceEx( pDacl, ACL_REVISION, ulAceFlags, FILE_ALL_ACCESS, &administratorsSid.sid); BAIL_ON_NT_STATUS(ntStatus); builtinUsersAccessMask = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE; ntStatus = RtlAddAccessAllowedAceEx( pDacl, ACL_REVISION, ulAceFlags, builtinUsersAccessMask, &builtinUsersSid.sid); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlSetDaclSecurityDescriptor( pAbsSecDesc, TRUE, pDacl, FALSE); BAIL_ON_NT_STATUS(ntStatus); /* Create the SelfRelative SD */ ntStatus = RtlAbsoluteToSelfRelativeSD( pAbsSecDesc, NULL, &ulRelSecDescLen); if (ntStatus == STATUS_BUFFER_TOO_SMALL) { ntStatus = SrvAllocateMemory(ulRelSecDescLen, (PVOID*)&pRelSecDesc); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlAbsoluteToSelfRelativeSD( pAbsSecDesc, pRelSecDesc, &ulRelSecDescLen); } BAIL_ON_NT_STATUS(ntStatus); *ppSecDesc = pRelSecDesc; cleanup: RTL_FREE(&pAbsSecDesc); RTL_FREE(&pOwnerSid); RTL_FREE(&pGroupSid); RTL_FREE(&pDacl); return ntStatus; error: *ppSecDesc = NULL; if (pRelSecDesc) { SrvFreeMemory(pRelSecDesc); } goto cleanup; }
static DWORD LocalDirCreateDacl( PACL *ppDacl, PACCESS_LIST pList ) { DWORD dwError = ERROR_SUCCESS; NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwDaclSize = 0; PACL pDacl = NULL; DWORD i = 0; ULONG ulSidSize = 0; dwDaclSize += ACL_HEADER_SIZE; for (i = 0; pList[i].ppSid && (*pList[i].ppSid); i++) { ulSidSize = RtlLengthSid(*(pList[i].ppSid)); if (pList[i].ulAccessType == ACCESS_ALLOWED_ACE_TYPE) { dwDaclSize += ulSidSize + sizeof(ACCESS_ALLOWED_ACE); } else if (pList[i].ulAccessType == ACCESS_DENIED_ACE_TYPE) { dwDaclSize += ulSidSize + sizeof(ACCESS_DENIED_ACE); } } dwError = LwAllocateMemory(dwDaclSize, OUT_PPVOID(&pDacl)); BAIL_ON_LSA_ERROR(dwError); ntStatus = RtlCreateAcl(pDacl, dwDaclSize, ACL_REVISION); BAIL_ON_NT_STATUS(ntStatus); for (i = 0; pList[i].ppSid && (*pList[i].ppSid); i++) { if (pList[i].ulAccessType == ACCESS_ALLOWED_ACE_TYPE) { ntStatus = RtlAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, pList[i].AccessMask, *(pList[i].ppSid)); } else if (pList[i].ulAccessType == ACCESS_DENIED_ACE_TYPE) { ntStatus = RtlAddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, pList[i].AccessMask, *(pList[i].ppSid)); } BAIL_ON_NT_STATUS(ntStatus); } *ppDacl = pDacl; cleanup: if (dwError == ERROR_SUCCESS && ntStatus != STATUS_SUCCESS) { dwError = LwNtStatusToWin32Error(ntStatus); } return dwError; error: LW_SAFE_FREE_MEMORY(pDacl); *ppDacl = NULL; goto cleanup; }