diff --git a/src/libpsl-native/src/followsymlink.cpp b/src/libpsl-native/src/followsymlink.cpp index 40e12b9b78..6a77bcc52b 100644 --- a/src/libpsl-native/src/followsymlink.cpp +++ b/src/libpsl-native/src/followsymlink.cpp @@ -7,6 +7,7 @@ #include #include #include "followsymlink.h" +#include "issymlink.h" //! @brief Followsymlink determines target path of a sym link //! @@ -38,53 +39,122 @@ char* FollowSymLink(const char* fileName) { errno = 0; - // Check parameters + // if filename is null, return null value if (!fileName) { errno = ERROR_INVALID_PARAMETER; return NULL; } - char buffer[PATH_MAX]; - ssize_t sz = readlink(fileName, buffer, PATH_MAX); - - if (sz == -1) + //if lstat in IsSymLink returns -1, path does not exist + if (IsSymLink(fileName) == -1) { - switch(errno) - { - case EACCES: - errno = ERROR_ACCESS_DENIED; - break; - case EFAULT: - errno = ERROR_INVALID_ADDRESS; - break; - case EINVAL: - errno = ERROR_INVALID_NAME; - break; - case EIO: - errno = ERROR_GEN_FAILURE; - break; - case ELOOP: - errno = ERROR_STOPPED_ON_SYMLINK; - break; - case ENAMETOOLONG: - errno = ERROR_BAD_PATH_NAME; - break; - case ENOENT: - errno = ERROR_FILE_NOT_FOUND; - break; - case ENOMEM: - errno = ERROR_OUTOFMEMORY; - break; - case ENOTDIR: - errno = ERROR_BAD_PATH_NAME; - break; - default: - errno = ERROR_INVALID_FUNCTION; - } return NULL; } - buffer[sz] = '\0'; - return strndup(buffer, sz + 1); + /*If the path is a symlink, the function return the absolute filepath if valid. if not valid, return null*/ + if (IsSymLink(fileName)) + { + //Attempt to resolve with the absolute filepath + char actualpath[PATH_MAX+1]; + char* realPath = realpath(fileName, actualpath); + + //if realPath is null, go onto the readlink implementation + if (realPath == NULL) + { + char buffer[PATH_MAX]; + ssize_t sz = readlink(fileName, buffer, PATH_MAX); + + if (sz == -1) + { + switch(errno) + { + case EACCES: + errno = ERROR_ACCESS_DENIED; + break; + case EFAULT: + errno = ERROR_INVALID_ADDRESS; /*If the path is a symlink, the function return the absolute filepath if valid. if not valid, return null*/ + break; + case EINVAL: + errno = ERROR_INVALID_NAME; + case EIO: + errno = ERROR_GEN_FAILURE; + break; + case ELOOP: + errno = ERROR_STOPPED_ON_SYMLINK; + break; + case ENAMETOOLONG: + errno = ERROR_BAD_PATH_NAME; + break; + case ENOENT: + errno = ERROR_FILE_NOT_FOUND; + break; + case ENOMEM: + errno = ERROR_OUTOFMEMORY; + break; + case ENOTDIR: + errno = ERROR_BAD_PATH_NAME; + break; + default: + errno = ERROR_INVALID_FUNCTION; + } + + return NULL; + } + + buffer[sz] = '\0'; + return strndup(buffer, sz + 1); + } + else + { + return strndup(realPath, strlen(realPath) + 1 ); + } + } + + else + { + char buffer[PATH_MAX]; + ssize_t sz = readlink(fileName, buffer, PATH_MAX); + + if (sz == -1) + { + switch(errno) + { + case EACCES: + errno = ERROR_ACCESS_DENIED; + break; + case EFAULT: + errno = ERROR_INVALID_ADDRESS; /*If the path is a symlink, the function return the absolute filepath if valid. if not valid, return null*/ + break; + case EINVAL: + errno = ERROR_INVALID_NAME; + case EIO: + errno = ERROR_GEN_FAILURE; + break; + case ELOOP: + errno = ERROR_STOPPED_ON_SYMLINK; + break; + case ENAMETOOLONG: + errno = ERROR_BAD_PATH_NAME; + break; + case ENOENT: + errno = ERROR_FILE_NOT_FOUND; + break; + case ENOMEM: + errno = ERROR_OUTOFMEMORY; + break; + case ENOTDIR: + errno = ERROR_BAD_PATH_NAME; + break; + default: + errno = ERROR_INVALID_FUNCTION; + } + + return NULL; + } + + buffer[sz] = '\0'; + return strndup(buffer, sz + 1); + + } } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 index 570b42565c..593f892ad9 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 @@ -36,7 +36,7 @@ Describe "New-Item" { It "Should create a file without error" { New-Item -Name $testfile -Path $tmpDirectory -ItemType file - Test-Path $FullyQualifiedFile | Should Be $true + Test-Path $FullyQualifiedFile | Should Be $true $fileInfo = Get-ChildItem $FullyQualifiedFile $fileInfo.Target | Should Be $null @@ -105,14 +105,14 @@ Describe "New-Item" { } It "Should create a symbolic link of a file without error" { - New-Item -Name $testfile -Path $tmpDirectory -ItemType file - Test-Path $FullyQualifiedFile | Should Be $true + New-Item -Name $testfile -Path $tmpDirectory -ItemType file + Test-Path $FullyQualifiedFile | Should Be $true - New-Item -ItemType SymbolicLink -Target $FullyQualifiedFile -Name $testlink -Path $tmpDirectory - Test-Path $FullyQualifiedLink | Should Be $true + New-Item -ItemType SymbolicLink -Target $FullyQualifiedFile -Name $testlink -Path $tmpDirectory + Test-Path $FullyQualifiedLink | Should Be $true $fileInfo = Get-ChildItem $FullyQualifiedLink - $fileInfo.Target | Should Be $FullyQualifiedFile + $fileInfo.Target | Should Match ([regex]::Escape($FullyQualifiedFile)) $fileInfo.LinkType | Should Be "SymbolicLink" } @@ -128,18 +128,18 @@ Describe "New-Item" { } It "Should create a symbolic link from directory without error" { - New-Item -Name $testFolder -Path $tmpDirectory -ItemType directory - Test-Path $FullyQualifiedFolder | Should Be $true + New-Item -Name $testFolder -Path $tmpDirectory -ItemType directory + Test-Path $FullyQualifiedFolder | Should Be $true - New-Item -ItemType SymbolicLink -Target $FullyQualifiedFolder -Name $testlink -Path $tmpDirectory - Test-Path $FullyQualifiedLink | Should Be $true + New-Item -ItemType SymbolicLink -Target $FullyQualifiedFolder -Name $testlink -Path $tmpDirectory + Test-Path $FullyQualifiedLink | Should Be $true $fileInfo = Get-ChildItem $FullyQualifiedLink - $fileInfo.Target | Should Be $FullyQualifiedFolder + $fileInfo.Target | Should Match ([regex]::Escape($FullyQualifiedFolder)) $fileInfo.LinkType | Should Be "SymbolicLink" - # Remove the link explicitly to avoid broken symlink issue - Remove-Item $FullyQualifiedLink -Force + # Remove the link explicitly to avoid broken symlink issue + Remove-Item $FullyQualifiedLink -Force } It "Should create a hard link of a file without error" { @@ -154,6 +154,4 @@ Describe "New-Item" { $fileInfo.LinkType | Should Be "HardLink" } - - }