diff --git a/src/libpsl-native/src/CMakeLists.txt b/src/libpsl-native/src/CMakeLists.txt index 6840ceb45..8b5279f8e 100644 --- a/src/libpsl-native/src/CMakeLists.txt +++ b/src/libpsl-native/src/CMakeLists.txt @@ -1,5 +1,6 @@ add_library(psl-native SHARED getstat.cpp + getpwuid.cpp getfileowner.cpp getcurrentprocessorid.cpp getusername.cpp diff --git a/src/libpsl-native/src/getfileowner.cpp b/src/libpsl-native/src/getfileowner.cpp index 53afdb08e..c1bd5b69f 100644 --- a/src/libpsl-native/src/getfileowner.cpp +++ b/src/libpsl-native/src/getfileowner.cpp @@ -9,6 +9,7 @@ #include #include #include "getstat.h" +#include "getpwuid.h" #include "getfileowner.h" //! @brief GetFileOwner returns the owner of a file @@ -22,17 +23,8 @@ //! char* is marshaled as an LPStr, which on Linux is UTF-8. //! @endparblock //! -//! @exception errno Passes these errors via errno to GetLastError: +//! @exception errno Passes this error via errno to GetLastError: //! - ERROR_INVALID_PARAMETER: parameter is not valid -//! - ERROR_FILE_NOT_FOUND: file does not exist -//! - ERROR_ACCESS_DENIED: access is denied -//! - ERROR_INVALID_ADDRESS: attempt to access invalid address -//! - ERROR_STOPPED_ON_SYMLINK: too many symbolic links -//! - ERROR_GEN_FAILURE: I/O error occurred -//! - ERROR_INVALID_NAME: file provided is not a symbolic link -//! - ERROR_INVALID_FUNCTION: incorrect function -//! - ERROR_BAD_PATH_NAME: pathname is too long -//! - ERROR_OUTOFMEMORY insufficient kernal memory //! //! @retval file owner, or NULL if unsuccessful //! @@ -47,59 +39,12 @@ char* GetFileOwner(const char* fileName) return NULL; } - struct stat fileStat; - ret = GetStat(fileName, &fileStat); + struct stat buf; + ret = GetStat(fileName, &buf); if (ret != 0) { return NULL; } - struct passwd pwd; - struct passwd* result = NULL; - char* buf; - - int buflen = sysconf(_SC_GETPW_R_SIZE_MAX); - if (buflen < 1) - { - buflen = 2048; - } - -allocate: - buf = (char*)calloc(buflen, sizeof(char)); - - ret = getpwuid_r(fileStat.st_uid, &pwd, buf, buflen, &result); - - if (ret != 0) - { - switch(errno) - { - case ERANGE: - free(buf); - buflen *= 2; - goto allocate; - case ENOENT: - case ESRCH: - case EBADF: - case EPERM: - errno = ERROR_NO_SUCH_USER; - break; - case ENOMEM: - errno = ERROR_OUTOFMEMORY; - break; - default: - errno = ERROR_GEN_FAILURE; - } - return NULL; - } - - // no result - if (result == NULL) - { - return NULL; - } - - size_t userlen = strnlen(pwd.pw_name, buflen); - char* username = strndup(pwd.pw_name, userlen); - free(buf); - return username; + return GetPwUid(buf.st_uid); } diff --git a/src/libpsl-native/src/getpwuid.cpp b/src/libpsl-native/src/getpwuid.cpp new file mode 100644 index 000000000..62263067e --- /dev/null +++ b/src/libpsl-native/src/getpwuid.cpp @@ -0,0 +1,81 @@ +//! @file getpwuid.cpp +//! @author Andrew Schwartzmeyer +//! @brief returns the username for a uid + +#include +#include +#include +#include +#include +#include +#include "getpwuid.h" + +//! @brief GetPwUid returns the username for a uid +//! +//! GetPwUid +//! +//! @param[in] uid +//! @parblock +//! The user identifier to lookup. +//! @endparblock +//! +//! @exception errno Passes these errors via errno to GetLastError: +//! - ERROR_NO_SUCH_USER: user lookup unsuccessful +//! - ERROR_OUTOFMEMORY insufficient kernel memory +//! - ERROR_GEN_FAILURE: anything else +//! +//! @retval username as UTF-8 string, or NULL if unsuccessful +//! +char* GetPwUid(uid_t uid) +{ + int32_t ret = 0; + struct passwd pwd; + struct passwd* result = NULL; + char* buf; + + int buflen = sysconf(_SC_GETPW_R_SIZE_MAX); + if (buflen < 1) + { + buflen = 2048; + } + +allocate: + buf = (char*)calloc(buflen, sizeof(char)); + + ret = getpwuid_r(uid, &pwd, buf, buflen, &result); + + if (ret != 0) + { + switch(errno) + { + case ERANGE: + free(buf); + buflen *= 2; + goto allocate; + case ENOENT: + case ESRCH: + case EBADF: + case EPERM: + errno = ERROR_NO_SUCH_USER; + break; + case ENOMEM: + errno = ERROR_OUTOFMEMORY; + break; + default: + errno = ERROR_GEN_FAILURE; + } + return NULL; + } + + // no result + if (result == NULL) + { + return NULL; + } + + // allocate copy on heap so CLR can free it + size_t userlen = strnlen(pwd.pw_name, buflen); + char* username = strndup(pwd.pw_name, userlen); + free(buf); + return username; +} diff --git a/src/libpsl-native/src/getpwuid.h b/src/libpsl-native/src/getpwuid.h new file mode 100644 index 000000000..cbf2cca91 --- /dev/null +++ b/src/libpsl-native/src/getpwuid.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include "pal.h" + +PAL_BEGIN_EXTERNC + +char* GetPwUid(uid_t uid); + +PAL_END_EXTERNC diff --git a/src/libpsl-native/src/getusername.cpp b/src/libpsl-native/src/getusername.cpp index 0efab9668..56c3d6d08 100644 --- a/src/libpsl-native/src/getusername.cpp +++ b/src/libpsl-native/src/getusername.cpp @@ -2,64 +2,16 @@ //! @author Andrew Schwartzmeyer //! @brief Implements GetUserName for Linux -#include -#include #include -#include -#include +#include "getpwuid.h" #include "getusername.h" //! @brief GetUserName retrieves the name of the user associated with //! the current thread. //! -//! @exception errno Passes these errors via errno to GetLastError: -//! - ERROR_INVALID_PARAMETER: parameter is not valid -//! - ERROR_NO_SUCH_USER: there was no corresponding user -//! - ERROR_GEN_FAILURE: sysconf() or getpwuid() failed for unknown reasons -//! //! @retval username as UTF-8 string, or null if unsuccessful char* GetUserName() { - errno = 0; - - struct passwd pwd; - struct passwd* result; - // gets the initial suggested size for buf - int buflen = sysconf(_SC_GETPW_R_SIZE_MAX); - if (buflen == -1) - { - errno = ERROR_GEN_FAILURE; - return NULL; - } - std::string buf(buflen, 0); - // geteuid() gets the effective user ID of the calling process, and is always successful - int ret = getpwuid_r(geteuid(), &pwd, &buf[0], buflen, &result); - - // Map errno to Win32 Error Codes - if (ret) - { - switch (errno) - { - case ENOENT: - case ESRCH: - case EBADF: - case EPERM: - errno = ERROR_NO_SUCH_USER; - break; - default: - errno = ERROR_GEN_FAILURE; - } - return NULL; - } - - // Check if no user matched - if (result == NULL) - { - errno = ERROR_NO_SUCH_USER; - return NULL; - } - - // allocate copy on heap so CLR can free it - return strdup(result->pw_name); + return GetPwUid(geteuid()); }