NTSTATUS PvfsEnumerateDirectory( PPVFS_CCB pCcb, PIO_MATCH_FILE_SPEC pFileSpec, LONG Count, BOOLEAN bRescan ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; DIR *pDir = NULL; struct dirent *pDirEntry = NULL; struct dirent dirEntry = { 0 }; PSTR pszPattern = NULL; BOOLEAN bCaseSensitive = FALSE; PSTR pszDiskFilename = NULL; PVFS_STAT Stat = { 0 }; PSTR pszResolvedDirname = NULL; PSTR pszResolvedFilename = NULL; if (Count == 0) { ntError = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntError); } ntError = AllocateCStringFileSpec(&pszPattern, pFileSpec); BAIL_ON_NT_STATUS(ntError); if (bRescan) { if (pCcb->pDirContext->pDir) { PvfsSysCloseDir(pCcb->pDirContext->pDir); } PvfsFreeDirectoryContext(pCcb->pDirContext); pCcb->pDirContext = NULL; ntError = PvfsAllocateMemory( (PVOID)&pCcb->pDirContext, sizeof(PVFS_DIRECTORY_CONTEXT), TRUE); BAIL_ON_NT_STATUS(ntError); pCcb->pDirContext->bScanned = FALSE; } if (!pCcb->pDirContext->bScanned) { if (!strchr(pszPattern, '?') && !strchr(pszPattern, '*')) { // A single file name match is the equivalent of a Windows Stat() ntError = PvfsLookupFile( &pszDiskFilename, &Stat, pCcb->pScb->pOwnerFcb->pszFilename, pszPattern, pFileSpec->Options & IO_NAME_OPTION_CASE_SENSITIVE); BAIL_ON_NT_STATUS(ntError); ntError = PvfsFileSplitPath( &pszResolvedDirname, &pszResolvedFilename, pszDiskFilename); BAIL_ON_NT_STATUS(ntError); if (IsSetFlag(pCcb->Flags, PVFS_CCB_FLAG_ENABLE_ABE)) { ntError = PvfsAccessCheckFileEnumerate( pCcb, pszResolvedFilename); BAIL_ON_NT_STATUS(ntError); } ntError = PvfsDirContextAddEntry( pCcb->pDirContext, pszResolvedFilename); BAIL_ON_NT_STATUS(ntError); pCcb->pDirContext->bScanned = TRUE; // Success goto cleanup; } else { // Prepare to enumerate the entire directory ntError = PvfsSysOpenDir( pCcb->pScb->pOwnerFcb->pszFilename, &pCcb->pDirContext->pDir); BAIL_ON_NT_STATUS(ntError); pCcb->pDirContext->bScanned = TRUE; } } /* Loop to read entries */ pDir = pCcb->pDirContext->pDir; /* -1 means to fill in whatever you can including current and parent directory entries */ if (Count == -1) { /* Always add '.' and '..' first if thet match */ if (PvfsWildcardMatch(".", pszPattern, FALSE)) { ntError = PvfsDirContextAddEntry(pCcb->pDirContext, "."); BAIL_ON_NT_STATUS(ntError); } if (PvfsWildcardMatch("..", pszPattern, FALSE)) { ntError = PvfsDirContextAddEntry(pCcb->pDirContext, ".."); BAIL_ON_NT_STATUS(ntError); } } /* Loop through directory entries */ for(ntError = PvfsSysReadDir(pDir, &dirEntry, &pDirEntry); pDirEntry && ((Count == -1) || (pCcb->pDirContext->dwNumEntries < Count)); ntError = PvfsSysReadDir(pDir, &dirEntry, &pDirEntry)) { /* First check the error return */ BAIL_ON_NT_STATUS(ntError); /* We've already added the "." and ".." directories */ if (RtlCStringIsEqual(pDirEntry->d_name, ".", FALSE) || RtlCStringIsEqual(pDirEntry->d_name, "..", FALSE)) { continue; } if (PvfsWildcardMatch(pDirEntry->d_name, pszPattern, bCaseSensitive)) { if (IsSetFlag(pCcb->Flags, PVFS_CCB_FLAG_ENABLE_ABE)) { ntError = PvfsAccessCheckFileEnumerate( pCcb, pDirEntry->d_name); if (ntError != STATUS_SUCCESS) { continue; } } ntError = PvfsDirContextAddEntry(pCcb->pDirContext, pDirEntry->d_name); BAIL_ON_NT_STATUS(ntError); } } /* Bail if there were no matches */ if (pCcb->pDirContext->dwNumEntries == 0) { ntError = STATUS_NO_SUCH_FILE; BAIL_ON_NT_STATUS(ntError); } cleanup: RtlCStringFree(&pszResolvedFilename); RtlCStringFree(&pszResolvedDirname); RtlCStringFree(&pszDiskFilename); RtlCStringFree(&pszPattern); 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; }