static NTSTATUS SrvShareCreateAbsoluteSecDescFromRel( OUT PSECURITY_DESCRIPTOR_ABSOLUTE *ppAbsSecDesc, IN PSECURITY_DESCRIPTOR_RELATIVE pRelSecDesc ) { NTSTATUS ntStatus = STATUS_SUCCESS; PSECURITY_DESCRIPTOR_ABSOLUTE pAbsSecDesc = NULL; ULONG ulAbsSecDescLen = 0; PACL pDacl = NULL; ULONG ulDaclLen = 0; PACL pSacl = NULL; ULONG ulSaclLen = 0; PSID pOwner = NULL; ULONG ulOwnerLen = 0; PSID pGroup = NULL; ULONG ulGroupLen = 0; /* Get sizes for the Absolute SD */ ntStatus = RtlSelfRelativeToAbsoluteSD( pRelSecDesc, pAbsSecDesc, &ulAbsSecDescLen, pDacl, &ulDaclLen, pSacl, &ulSaclLen, pOwner, &ulOwnerLen, pGroup, &ulGroupLen); if (ntStatus == STATUS_BUFFER_TOO_SMALL) { ntStatus = STATUS_SUCCESS; } BAIL_ON_NT_STATUS(ntStatus); /* Allocate -- Always use RTL routines for Absolute SDs */ if (ulOwnerLen) { ntStatus = RTL_ALLOCATE(&pOwner, SID, ulOwnerLen); BAIL_ON_NT_STATUS(ntStatus); } if (ulGroupLen) { ntStatus = RTL_ALLOCATE(&pGroup, SID, ulGroupLen); BAIL_ON_NT_STATUS(ntStatus); } if (ulDaclLen) { ntStatus = RTL_ALLOCATE(&pDacl, VOID, ulDaclLen); BAIL_ON_NT_STATUS(ntStatus); } if (ulSaclLen) { ntStatus = RTL_ALLOCATE(&pSacl, VOID, ulSaclLen); BAIL_ON_NT_STATUS(ntStatus); } ntStatus = RTL_ALLOCATE(&pAbsSecDesc, VOID, ulAbsSecDescLen); BAIL_ON_NT_STATUS(ntStatus); /* Translate the SD */ ntStatus = RtlSelfRelativeToAbsoluteSD( pRelSecDesc, pAbsSecDesc, &ulAbsSecDescLen, pDacl, &ulDaclLen, pSacl, &ulSaclLen, pOwner, &ulOwnerLen, pGroup, &ulGroupLen); BAIL_ON_NT_STATUS(ntStatus); *ppAbsSecDesc = pAbsSecDesc; cleanup: return ntStatus; error: LW_RTL_FREE(&pAbsSecDesc); LW_RTL_FREE(&pOwner); LW_RTL_FREE(&pGroup); LW_RTL_FREE(&pSacl); LW_RTL_FREE(&pDacl); goto cleanup; }
NTSTATUS LwIoFuseTranslateSecurityDescriptor( PSECURITY_DESCRIPTOR_RELATIVE pSecurityDescriptor, struct stat* pStatbuf ) { NTSTATUS status = STATUS_SUCCESS; PSECURITY_DESCRIPTOR_ABSOLUTE pAbsolute = NULL; PACL pDacl = NULL; PACL pSacl = NULL; PSID pOwnerSid = NULL; PSID pGroupSid = NULL; ULONG ulOwnerSidSize = 0; ULONG ulGroupSidSize = 0; ULONG ulDaclSize = 0; ULONG ulSaclSize = 0; ULONG ulAbsSize = 0; /* Get required sizes */ RtlSelfRelativeToAbsoluteSD( pSecurityDescriptor, pAbsolute, &ulAbsSize, pDacl, &ulDaclSize, pSacl, &ulSaclSize, pOwnerSid, &ulOwnerSidSize, pGroupSid, &ulGroupSidSize); /* Allocate space */ status = RTL_ALLOCATE(&pAbsolute, struct _SECURITY_DESCRIPTOR_ABSOLUTE, ulAbsSize); BAIL_ON_NT_STATUS(status); if (ulDaclSize) { status = RTL_ALLOCATE(&pDacl, struct _ACL, ulDaclSize); BAIL_ON_NT_STATUS(status); } if (ulSaclSize) { status = RTL_ALLOCATE(&pSacl, struct _ACL, ulSaclSize); BAIL_ON_NT_STATUS(status); } if (ulOwnerSidSize) { status = RTL_ALLOCATE(&pOwnerSid, SID, ulOwnerSidSize); BAIL_ON_NT_STATUS(status); } if (ulGroupSidSize) { status = RTL_ALLOCATE(&pGroupSid, SID, ulGroupSidSize); BAIL_ON_NT_STATUS(status); } /* Unpack descriptor */ status = RtlSelfRelativeToAbsoluteSD( pSecurityDescriptor, pAbsolute, &ulAbsSize, pDacl, &ulDaclSize, pSacl, &ulSaclSize, pOwnerSid, &ulOwnerSidSize, pGroupSid, &ulGroupSidSize); BAIL_ON_NT_STATUS(status); status = LwIoFuseTranslateAbsoluteSecurityDescriptor( pAbsolute, pOwnerSid, pGroupSid, pStatbuf); BAIL_ON_NT_STATUS(status); error: RTL_FREE(&pAbsolute); RTL_FREE(&pDacl); RTL_FREE(&pSacl); RTL_FREE(&pOwnerSid); RTL_FREE(&pGroupSid); return status; }
static DWORD DeconstructSecurityDescriptor( DWORD dwLength, PSECURITY_DESCRIPTOR_RELATIVE pRelative, PDWORD pdwAllowUserCount, PWSTR** pppwszAllowUsers, PDWORD pdwDenyUserCount, PWSTR** pppwszDenyUsers, PBOOLEAN pbReadOnly ) { NTSTATUS status = STATUS_SUCCESS; DWORD dwError = 0; ULONG ulSize = 0; ULONG ulDaclSize = 0; ULONG ulSaclSize = 0; ULONG ulOwnerSize = 0; ULONG ulGroupSize = 0; PSID pOwner = NULL; PSID pGroup = NULL; PACL pSacl = NULL; PSECURITY_DESCRIPTOR_ABSOLUTE pAbsolute = NULL; PACL pDacl = NULL; ULONG ulIndex = 0; PVOID pAce = NULL; PACCESS_ALLOWED_ACE pAllow = NULL; PACCESS_DENIED_ACE pDeny = NULL; DWORD dwAllowUserCount = 0; PWSTR* ppwszAllowUsers = NULL; DWORD dwDenyUserCount = 0; PWSTR* ppwszDenyUsers = NULL; PSID pSid = NULL; PWSTR pwszUser = NULL; HANDLE hLsa = NULL; ACCESS_MASK leastMask = FILE_ALL_ACCESS; dwError = LsaOpenServer(&hLsa); BAIL_ON_LTNET_ERROR(dwError); status = RtlSelfRelativeToAbsoluteSD( pRelative, pAbsolute, &ulSize, pDacl, &ulDaclSize, pSacl, &ulSaclSize, pOwner, &ulOwnerSize, pGroup, &ulGroupSize); if (status != STATUS_BUFFER_TOO_SMALL) { dwError = LwNtStatusToWin32Error(status); BAIL_ON_LTNET_ERROR(dwError); } dwError = LwNetAllocateMemory(ulSize, OUT_PPVOID(&pAbsolute)); BAIL_ON_LTNET_ERROR(dwError); if (ulDaclSize) { dwError = LwNetAllocateMemory(ulDaclSize, OUT_PPVOID(&pDacl)); BAIL_ON_LTNET_ERROR(dwError); } if (ulSaclSize) { dwError = LwNetAllocateMemory(ulSaclSize, OUT_PPVOID(&pSacl)); BAIL_ON_LTNET_ERROR(dwError); } if (ulOwnerSize) { dwError = LwNetAllocateMemory(ulOwnerSize, OUT_PPVOID(&pOwner)); BAIL_ON_LTNET_ERROR(dwError); } if (ulGroupSize) { dwError = LwNetAllocateMemory(ulGroupSize, OUT_PPVOID(&pGroup)); BAIL_ON_LTNET_ERROR(dwError); } dwError = LwNtStatusToWin32Error( RtlSelfRelativeToAbsoluteSD( pRelative, pAbsolute, &ulSize, pDacl, &ulDaclSize, pSacl, &ulSaclSize, pOwner, &ulOwnerSize, pGroup, &ulGroupSize)); BAIL_ON_LTNET_ERROR(dwError); if (pDacl) { for (ulIndex = 0; ulIndex < RtlGetAclAceCount(pDacl); ulIndex++) { RtlGetAce(pDacl, ulIndex, &pAce); switch(((PACE_HEADER) pAce)->AceType) { case ACCESS_ALLOWED_ACE_TYPE: pAllow = pAce; pSid = (PSID) &pAllow->SidStart; if ((pAllow->Mask & FILE_GENERIC_READ) == FILE_GENERIC_READ) { dwError = MapSidToName(hLsa, pSid, &pwszUser); if (dwError != LW_ERROR_SUCCESS) { dwError = MapBuiltinSidToName(&pwszUser, pSid); } BAIL_ON_LTNET_ERROR(dwError); dwError = LwNetAppendStringArray( &dwAllowUserCount, &ppwszAllowUsers, pwszUser); BAIL_ON_LTNET_ERROR(dwError); pwszUser = NULL; leastMask &= pAllow->Mask; } break; case ACCESS_DENIED_ACE_TYPE: pDeny = pAce; pSid = (PSID) &pDeny->SidStart; if ((pDeny->Mask & FILE_GENERIC_READ) == FILE_GENERIC_READ) { dwError = MapSidToName(hLsa, pSid, &pwszUser); if (dwError != LW_ERROR_SUCCESS) { dwError = MapBuiltinSidToName(&pwszUser, pSid); } BAIL_ON_LTNET_ERROR(dwError); dwError = LwNetAppendStringArray( &dwDenyUserCount, &ppwszDenyUsers, pwszUser); BAIL_ON_LTNET_ERROR(dwError); pwszUser = NULL; } break; default: break; } } } *pppwszAllowUsers = ppwszAllowUsers; *pdwAllowUserCount = dwAllowUserCount; *pppwszDenyUsers = ppwszDenyUsers; *pdwDenyUserCount = dwDenyUserCount; *pbReadOnly = !((leastMask & FILE_GENERIC_WRITE) == FILE_GENERIC_WRITE); cleanup: if (hLsa) { LsaCloseServer(hLsa); } LTNET_SAFE_FREE_MEMORY(pSacl); LTNET_SAFE_FREE_MEMORY(pOwner); LTNET_SAFE_FREE_MEMORY(pGroup); LTNET_SAFE_FREE_MEMORY(pwszUser); LTNET_SAFE_FREE_MEMORY(pDacl); LTNET_SAFE_FREE_MEMORY(pAbsolute); return dwError; error: *pppwszAllowUsers = NULL; *pdwAllowUserCount = 0; *pppwszDenyUsers = NULL; *pdwDenyUserCount = 0; goto cleanup; }
NTSTATUS PvfsSecurityAclSelfRelativeToAbsoluteSD( PSECURITY_DESCRIPTOR_ABSOLUTE *ppAbsolute, PSECURITY_DESCRIPTOR_RELATIVE pRelative ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; PSECURITY_DESCRIPTOR_ABSOLUTE pAbsolute = NULL; PSID pOwnerSid = NULL; PSID pGroupSid = NULL; PACL pDacl = NULL; PACL pSacl = NULL; ULONG SecDescAbsSize = 0; ULONG OwnerSize = 0; ULONG GroupSize = 0; ULONG DaclSize = 0; ULONG SaclSize = 0; /* Get the necessary sizes */ ntError = RtlSelfRelativeToAbsoluteSD( pRelative, pAbsolute, &SecDescAbsSize, pDacl, &DaclSize, pSacl, &SaclSize, pOwnerSid, &OwnerSize, pGroupSid, &GroupSize); if (ntError != STATUS_BUFFER_TOO_SMALL) { BAIL_ON_NT_STATUS(ntError); } ntError = LW_RTL_ALLOCATE( &pAbsolute, VOID, SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE); BAIL_ON_NT_STATUS(ntError); ntError = RtlCreateSecurityDescriptorAbsolute( pAbsolute, SECURITY_DESCRIPTOR_REVISION); BAIL_ON_NT_STATUS(ntError); if (DaclSize) { ntError = LW_RTL_ALLOCATE(&pDacl, VOID, DaclSize); BAIL_ON_NT_STATUS(ntError); } if (SaclSize) { ntError = LW_RTL_ALLOCATE(&pSacl, VOID, SaclSize); BAIL_ON_NT_STATUS(ntError); } if (OwnerSize) { ntError = LW_RTL_ALLOCATE(&pOwnerSid, VOID, OwnerSize); BAIL_ON_NT_STATUS(ntError); } if (GroupSize) { ntError = LW_RTL_ALLOCATE(&pGroupSid, VOID, GroupSize); BAIL_ON_NT_STATUS(ntError); } /* Once more with feeling...This one should succeed. */ ntError = RtlSelfRelativeToAbsoluteSD( pRelative, pAbsolute, &SecDescAbsSize, pDacl, &DaclSize, pSacl, &SaclSize, pOwnerSid, &OwnerSize, pGroupSid, &GroupSize); BAIL_ON_NT_STATUS(ntError); *ppAbsolute = pAbsolute; pAbsolute = NULL; cleanup: return ntError; error: LW_RTL_FREE(&pOwnerSid); LW_RTL_FREE(&pGroupSid); LW_RTL_FREE(&pDacl); LW_RTL_FREE(&pSacl); LW_RTL_FREE(&pAbsolute); goto cleanup; }