NTSTATUS PvfsGetSecurityDescriptorFileDefault( IN PPVFS_CCB pCcb, IN SECURITY_INFORMATION SecInfo, IN OUT PSECURITY_DESCRIPTOR_RELATIVE pSecDesc, IN OUT PULONG pSecDescLen ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; BYTE pFullSecDesc[SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE]; ULONG FullSecDescLen = SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE; LwRtlZeroMemory(pFullSecDesc, FullSecDescLen); ntError = PvfsGetSecurityDescriptorPosix( pCcb, (PSECURITY_DESCRIPTOR_RELATIVE)pFullSecDesc, &FullSecDescLen); BAIL_ON_NT_STATUS(ntError); ntError = RtlQuerySecurityDescriptorInfo( SecInfo, pSecDesc, pSecDescLen, (PSECURITY_DESCRIPTOR_RELATIVE)pFullSecDesc); BAIL_ON_NT_STATUS(ntError); cleanup: return ntError; error: goto cleanup; }
static NTSTATUS LwRtlAnsiStringAllocateAppendPrintfV( IN OUT PANSI_STRING pString, IN PCSTR Format, IN va_list Args ) { NTSTATUS status = 0; ANSI_STRING addString = { 0 }; ANSI_STRING newString = { 0 }; status = LwRtlAnsiStringAllocatePrintfV(&addString, Format, Args); GOTO_CLEANUP_ON_STATUS(status); if (pString->Buffer) { status = LwRtlAnsiStringAllocatePrintf(&newString, "%Z%Z", pString, &addString); GOTO_CLEANUP_ON_STATUS(status); } else { newString = addString; LwRtlZeroMemory(&addString, sizeof(addString)); } cleanup: if (status) { LW_RTL_ANSI_STRING_FREE(&newString); } else { LW_RTL_ANSI_STRING_FREE(pString); *pString = newString; } LW_RTL_ANSI_STRING_FREE(&addString); return status; }
static NTSTATUS DfsConfigRootAddReferrals( HANDLE hRegistryServer, HKEY hParentKey, PDFS_ROOT_CONTROL_BLOCK pRootCB ) { NTSTATUS ntStatus = STATUS_SUCCESS; HKEY hDfsRootKey = (HKEY)NULL; PDFS_REFERRAL_CONTROL_BLOCK pReferralCB = NULL; PWSTR *ppwszTargets = NULL; DWORD i = 0; DWORD dwIndex = 0; BOOLEAN bFinished = FALSE; DWORD dwValueNameLength = MAX_VALUE_LENGTH; WCHAR pwszValueName[MAX_VALUE_LENGTH] = { 0 }; DWORD dwType = REG_NONE; DWORD dwReserved = 0; BYTE pBuffer[4096] = { 0 }; DWORD dwBufferSize = 0; ntStatus = NtRegOpenKeyExW( hRegistryServer, hParentKey, pRootCB->pwszRootName, 0, KEY_READ, &hDfsRootKey); BAIL_ON_NT_STATUS(ntStatus); for (dwIndex=0; !bFinished; dwIndex++) { dwBufferSize = sizeof(pBuffer); LwRtlZeroMemory(pBuffer, dwBufferSize); ntStatus = NtRegEnumValueW( hRegistryServer, hDfsRootKey, dwIndex, pwszValueName, &dwValueNameLength, &dwReserved, &dwType, pBuffer, &dwBufferSize); if (ntStatus == STATUS_NO_MORE_ENTRIES) { ntStatus = STATUS_SUCCESS; bFinished = TRUE; continue; } BAIL_ON_NT_STATUS(ntStatus); if (dwType != REG_MULTI_SZ) { continue; } ntStatus = NtRegByteArrayToMultiStrsW( pBuffer, dwBufferSize, &ppwszTargets); BAIL_ON_NT_STATUS(ntStatus); ntStatus = DfsAllocateReferralCB(&pReferralCB, pwszValueName); BAIL_ON_NT_STATUS(ntStatus); for (i=0; ppwszTargets[i] != NULL; i++) { ntStatus = DfsReferralParseTarget(pReferralCB, ppwszTargets[i]); BAIL_ON_NT_STATUS(ntStatus); } RegFreeMultiStrsW(ppwszTargets); ppwszTargets = NULL; } cleanup: if (hDfsRootKey) { NtRegCloseKey(hRegistryServer, hDfsRootKey); } return ntStatus; error: goto cleanup; }
NTSTATUS PvfsSysRenameByFileName( IN PPVFS_FILE_NAME OriginalFileName, IN PPVFS_FILE_NAME NewFileName ) { NTSTATUS ntError = STATUS_SUCCESS; int unixerr = 0; PSTR oldFilename = NULL; PSTR newFilename = NULL; PSTR oldStreamDir = NULL; PSTR newStreamDir = NULL; PSTR newStreamDirParent = NULL; PVFS_STAT streamDirStat = { 0 }; ntError = PvfsLookupStreamDiskFileName(&oldFilename, OriginalFileName); BAIL_ON_NT_STATUS(ntError); ntError = PvfsLookupStreamDiskFileName(&newFilename, NewFileName); BAIL_ON_NT_STATUS(ntError); if (rename(oldFilename, newFilename) == -1 ) { PVFS_BAIL_ON_UNIX_ERROR(unixerr, ntError); } if (PvfsIsDefaultStreamName(OriginalFileName)) { // Have to rename the stream directory as well ntError = PvfsLookupStreamDirectoryPath(&oldStreamDir, OriginalFileName); BAIL_ON_NT_STATUS(ntError); ntError = PvfsLookupStreamDirectoryPath(&newStreamDir, NewFileName); BAIL_ON_NT_STATUS(ntError); ntError = PvfsSysStat(oldStreamDir, &streamDirStat); if (ntError == STATUS_SUCCESS) { ntError = PvfsFileDirname(&newStreamDirParent, newStreamDir); BAIL_ON_NT_STATUS(ntError); LwRtlZeroMemory(&streamDirStat, sizeof(streamDirStat)); ntError = PvfsSysStat(newStreamDirParent, &streamDirStat); switch (ntError) { case STATUS_SUCCESS: if (!S_ISDIR(streamDirStat.s_mode)) { ntError = STATUS_NOT_A_DIRECTORY; } break; case STATUS_OBJECT_NAME_NOT_FOUND: ntError = PvfsSysMkDir( newStreamDirParent, (mode_t)gPvfsDriverConfig.CreateDirectoryMode); break; default: break; } BAIL_ON_NT_STATUS(ntError); if (rename(oldStreamDir, newStreamDir) == -1) { // We are now in an inconstsent state -- What should we do? // We cannot safely roll back to the original name // as someone else may have it. Let's BAIL for now although // in the future we may decide that this should just log an error // but not fail PVFS_BAIL_ON_UNIX_ERROR(unixerr, ntError); } } // Squash the error is the stream directory did not exist ntError = STATUS_SUCCESS; } error: if (oldFilename) { LwRtlCStringFree(&oldFilename); } if (newFilename) { LwRtlCStringFree(&newFilename); } if (oldStreamDir) { LwRtlCStringFree(&oldStreamDir); } if (newStreamDir) { LwRtlCStringFree(&newStreamDir); } if (newStreamDirParent) { LwRtlCStringFree(&newStreamDirParent); } return ntError; }
NTSTATUS PvfsAllocateCCB( PPVFS_CCB *ppCCB ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; PPVFS_CCB pCCB = NULL; *ppCCB = NULL; ntError = PvfsAllocateMemory( OUT_PPVOID(&pCCB), sizeof(PVFS_CCB), FALSE); BAIL_ON_NT_STATUS(ntError); InterlockedIncrement(&gPvfsDriverState.Counters.Ccb); /* Initialize mutexes and refcounts */ pthread_mutex_init(&pCCB->ControlBlock, NULL); PVFS_INIT_LINKS(&pCCB->ScbList); pCCB->OplockState = PVFS_OPLOCK_STATE_NONE; pCCB->CurrentLeaseState = IO_LEASE_STATE_NONE; pCCB->NewLeaseState = IO_LEASE_STATE_NONE; pCCB->fd = -1; PVFS_CLEAR_FILEID(pCCB->FileId); pCCB->pScb = NULL; pCCB->pwszShareName = NULL; pCCB->pDirContext = NULL; pCCB->pUserToken = NULL; pCCB->ChangeEvent = 0; pCCB->WriteCount = 0; pCCB->FileSize = 0; pCCB->AccessGranted = 0; pCCB->Flags = PVFS_CCB_FLAG_NONE; LwRtlZeroMemory(&pCCB->LockTable, sizeof(pCCB->LockTable)); ntError = PvfsListInit( &pCCB->pZctContextList, 0, /* no max size */ (PPVFS_LIST_FREE_DATA_FN)PvfsFreeZctContext); BAIL_ON_NT_STATUS(ntError); /* Add initial ref count */ pCCB->RefCount = 1; *ppCCB = pCCB; ntError = STATUS_SUCCESS; cleanup: return ntError; error: if (pCCB) { PvfsFreeCCB(pCCB); } 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; }