DWORD LsaInitCacheFolders( VOID ) { DWORD dwError = 0; PSTR pszCachePath = NULL; BOOLEAN bExists = FALSE; dwError = LsaSrvGetCachePath(&pszCachePath); BAIL_ON_LSA_ERROR(dwError); dwError = LsaCheckDirectoryExists( pszCachePath, &bExists); BAIL_ON_LSA_ERROR(dwError); if (!bExists) { mode_t cacheDirMode = S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH; dwError = LsaCreateDirectory(pszCachePath, cacheDirMode); BAIL_ON_LSA_ERROR(dwError); } cleanup: LW_SAFE_FREE_STRING(pszCachePath); return dwError; error: goto cleanup; }
static DWORD LsaCreateDirectoryRecursive( PSTR pszCurDirPath, PSTR pszTmpPath, PSTR *ppszTmp, PSELINUX pSELinux, DWORD dwFileMode, DWORD dwWorkingFileMode, int iPart ) { DWORD dwError = 0; PSTR pszDirPath = NULL; BOOLEAN bDirCreated = FALSE; BOOLEAN bDirExists = FALSE; CHAR szDelimiters[] = "/"; PSELINUX pSELinuxLocal = NULL; PSTR pszToken = strtok_r((iPart ? NULL : pszTmpPath), szDelimiters, ppszTmp); if (pSELinux == NULL) { dwError = SELinuxCreate(&pSELinuxLocal); BAIL_ON_LSA_ERROR(dwError); pSELinux = pSELinuxLocal; } if (pszToken != NULL) { dwError = LwAllocateMemory(strlen(pszCurDirPath)+strlen(pszToken)+2, (PVOID*)&pszDirPath); BAIL_ON_LSA_ERROR(dwError); sprintf(pszDirPath, "%s/%s", (!strcmp(pszCurDirPath, "/") ? "" : pszCurDirPath), pszToken); dwError = LsaCheckDirectoryExists(pszDirPath, &bDirExists); BAIL_ON_LSA_ERROR(dwError); if (!bDirExists) { if (mkdir(pszDirPath, dwWorkingFileMode) < 0) { dwError = LwMapErrnoToLwError(errno); BAIL_ON_LSA_ERROR(dwError); } SELinuxSetContext(pszDirPath, dwWorkingFileMode, pSELinux); bDirCreated = TRUE; } dwError = LsaChangeDirectory(pszDirPath); BAIL_ON_LSA_ERROR(dwError); dwError = LsaCreateDirectoryRecursive( pszDirPath, pszTmpPath, ppszTmp, pSELinux, dwFileMode, dwWorkingFileMode, iPart+1 ); BAIL_ON_LSA_ERROR(dwError); } if (bDirCreated && (dwFileMode != dwWorkingFileMode)) { dwError = LsaChangePermissions(pszDirPath, dwFileMode); BAIL_ON_LSA_ERROR(dwError); dwError = SELinuxSetContext(pszDirPath, dwFileMode, pSELinux); BAIL_ON_LSA_ERROR(dwError); } if (pszDirPath) { LwFreeMemory(pszDirPath); } if (pSELinuxLocal) { SELinuxFree(pSELinuxLocal); pSELinuxLocal = NULL; } return dwError; error: if (bDirCreated) { LsaRemoveDirectory(pszDirPath); } if (pszDirPath) { LwFreeMemory(pszDirPath); } if (pSELinuxLocal) { SELinuxFree(pSELinuxLocal); pSELinuxLocal = NULL; } return dwError; }
DWORD LsaGetMatchingFilePathsInFolder( PCSTR pszDirPath, PCSTR pszFileNameRegExp, PSTR** pppszHostFilePaths, PDWORD pdwNPaths ) { typedef struct __PATHNODE { PSTR pszPath; struct __PATHNODE *pNext; } PATHNODE, *PPATHNODE; DWORD dwError = 0; DIR* pDir = NULL; struct dirent* pDirEntry = NULL; regex_t rx; BOOLEAN rxAllocated = FALSE; regmatch_t* pResult = NULL; size_t nMatch = 1; DWORD dwNPaths = 0; DWORD iPath = 0; PSTR* ppszHostFilePaths = NULL; CHAR szBuf[PATH_MAX+1]; struct stat statbuf; PPATHNODE pPathList = NULL; PPATHNODE pPathNode = NULL; BOOLEAN bDirExists = FALSE; dwError = LsaCheckDirectoryExists(pszDirPath, &bDirExists); BAIL_ON_LSA_ERROR(dwError); if(!bDirExists) { dwError = ERROR_FILE_NOT_FOUND; BAIL_ON_LSA_ERROR(dwError); } if (regcomp(&rx, pszFileNameRegExp, REG_EXTENDED) != 0) { dwError = LW_ERROR_REGEX_COMPILE_FAILED; BAIL_ON_LSA_ERROR(dwError); } rxAllocated = TRUE; dwError = LwAllocateMemory(sizeof(regmatch_t), (PVOID*)&pResult); BAIL_ON_LSA_ERROR(dwError); pDir = opendir(pszDirPath); if (!pDir) { dwError = LwMapErrnoToLwError(errno); BAIL_ON_LSA_ERROR(dwError); } while ((pDirEntry = readdir(pDir)) != NULL) { int copied = snprintf( szBuf, sizeof(szBuf), "%s/%s", pszDirPath, pDirEntry->d_name); if (copied >= sizeof(szBuf)) { //Skip pathnames that are too long continue; } memset(&statbuf, 0, sizeof(struct stat)); if (lstat(szBuf, &statbuf) < 0) { if(errno == ENOENT) { //This occurs when there is a symbolic link pointing to a //location that doesn't exist, because stat looks at the final //file, not the link. Since this file doesn't exist anyway, //just skip it. continue; } dwError = LwMapErrnoToLwError(errno); BAIL_ON_LSA_ERROR(dwError); } /* * For now, we are searching only for regular files * This may be enhanced in the future to support additional * file system entry types */ if (((statbuf.st_mode & S_IFMT) == S_IFREG) && (regexec(&rx, pDirEntry->d_name, nMatch, pResult, 0) == 0)) { dwNPaths++; dwError = LwAllocateMemory(sizeof(PATHNODE), (PVOID*)&pPathNode); BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateString(szBuf, &pPathNode->pszPath); BAIL_ON_LSA_ERROR(dwError); pPathNode->pNext = pPathList; pPathList = pPathNode; pPathNode = NULL; } } if (pPathList) { dwError = LwAllocateMemory(sizeof(PSTR)*dwNPaths, (PVOID*)&ppszHostFilePaths); BAIL_ON_LSA_ERROR(dwError); /* * The linked list is in reverse. * Assign values in reverse to get it right */ iPath = dwNPaths-1; pPathNode = pPathList; while (pPathNode) { *(ppszHostFilePaths+iPath) = pPathNode->pszPath; pPathNode->pszPath = NULL; pPathNode = pPathNode->pNext; iPath--; } } *pppszHostFilePaths = ppszHostFilePaths; *pdwNPaths = dwNPaths; cleanup: if (pPathNode) { LW_SAFE_FREE_STRING(pPathNode->pszPath); LwFreeMemory(pPathNode); } while(pPathList) { pPathNode = pPathList; pPathList = pPathList->pNext; LW_SAFE_FREE_STRING(pPathNode->pszPath); LwFreeMemory(pPathNode); } if (rxAllocated) { regfree(&rx); } LW_SAFE_FREE_MEMORY(pResult); if (pDir) { closedir(pDir); } return dwError; error: if (ppszHostFilePaths) { LwFreeStringArray(ppszHostFilePaths, dwNPaths); } goto cleanup; }