NTSTATUS PvfsSetSecurityFile( PPVFS_IRP_CONTEXT pIrpContext ) { NTSTATUS ntError = STATUS_ACCESS_DENIED; PIRP pIrp = pIrpContext->pIrp; PPVFS_CCB pCcb = NULL; PSECURITY_DESCRIPTOR_RELATIVE pSecDesc = NULL; ULONG SecDescLength = 0; SECURITY_INFORMATION SecInfo = 0; IRP_ARGS_QUERY_SET_SECURITY Args = pIrpContext->pIrp->Args.QuerySetSecurity; ACCESS_MASK RequiredMask = 0; /* Sanity checks */ ntError = PvfsAcquireCCB(pIrp->FileHandle, &pCcb); BAIL_ON_NT_STATUS(ntError); if (!IsSetFlag(pCcb->Flags, PVFS_CCB_FLAG_CREATE_COMPLETE)) { ntError = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntError); } BAIL_ON_INVALID_PTR(Args.SecurityDescriptor, ntError); pSecDesc = Args.SecurityDescriptor; SecDescLength = Args.Length; SecInfo = Args.SecurityInformation; if (SecInfo & OWNER_SECURITY_INFORMATION) { RequiredMask |= WRITE_OWNER; } if (SecInfo & GROUP_SECURITY_INFORMATION) { RequiredMask |= WRITE_OWNER; } if (SecInfo & DACL_SECURITY_INFORMATION) { RequiredMask |= WRITE_DAC; } if (SecInfo & SACL_SECURITY_INFORMATION) { RequiredMask |= ACCESS_SYSTEM_SECURITY; } ntError = PvfsAccessCheckFileHandle(pCcb, RequiredMask); BAIL_ON_NT_STATUS(ntError); /* Real work starts here */ ntError = PvfsSetSecurityDescriptorFile(pCcb, SecInfo, pSecDesc, SecDescLength); BAIL_ON_NT_STATUS(ntError); pIrp->IoStatusBlock.BytesTransferred = 0; ntError = STATUS_SUCCESS; cleanup: if (pCcb) { PvfsReleaseCCB(pCcb); } return ntError; error: goto cleanup; }
NTSTATUS PvfsCreateFileSecurity( PACCESS_TOKEN pUserToken, PPVFS_CCB pCcb, PSECURITY_DESCRIPTOR_RELATIVE pSecurityDescriptor, BOOLEAN bIsDirectory ) { NTSTATUS ntError = STATUS_SUCCESS; PSTR pszParentPath = NULL; PSTR pszBaseFilename = NULL; PSECURITY_DESCRIPTOR_RELATIVE pFinalSecDesc = NULL; ULONG FinalSecDescLength = 0; BYTE ParentSecDescBuffer[SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE]; ULONG ParentSecDescLength = SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE; SECURITY_INFORMATION SecInfoAll = (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION); BYTE DefaultSecDescBuffer[SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE]; ULONG DefaultSecDescLength = SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE; LwRtlZeroMemory(ParentSecDescBuffer, ParentSecDescLength); LwRtlZeroMemory(DefaultSecDescBuffer, DefaultSecDescLength); ntError = PvfsFileSplitPath( &pszParentPath, &pszBaseFilename, pCcb->pszFilename); BAIL_ON_NT_STATUS(ntError); ntError = PvfsGetSecurityDescriptorFilename( pszParentPath, SecInfoAll, (PSECURITY_DESCRIPTOR_RELATIVE)ParentSecDescBuffer, &ParentSecDescLength); BAIL_ON_NT_STATUS(ntError); ntError = RtlCreatePrivateObjectSecurityEx( (PSECURITY_DESCRIPTOR_RELATIVE)ParentSecDescBuffer, pSecurityDescriptor, &pFinalSecDesc, &FinalSecDescLength, NULL, bIsDirectory, SEF_DACL_AUTO_INHERIT|SEF_SACL_AUTO_INHERIT, pUserToken, &gPvfsFileGenericMapping); BAIL_ON_NT_STATUS(ntError); ntError = PvfsSetSecurityDescriptorFile( pCcb, SecInfoAll, pFinalSecDesc, FinalSecDescLength); BAIL_ON_NT_STATUS(ntError); cleanup: LW_RTL_FREE(&pFinalSecDesc); RtlCStringFree(&pszParentPath); RtlCStringFree(&pszBaseFilename); return ntError; error: goto cleanup; }