Refactor libpsl to use GetPwUid()

This commit is contained in:
Andrew Schwartzmeyer committed 2016-07-13 15:46:25 -07:00
1 parent 6f938bd860
commit 8ac64286e1
5 files changed
+99 -110

No files matched your search

+1
View File
@@ -1,5 +1,6 @@
add_library(psl-native SHARED
getstat.cpp
getpwuid.cpp
getfileowner.cpp
getcurrentprocessorid.cpp
getusername.cpp
+5 -60
View File
@@ -9,6 +9,7 @@
#include <string.h>
#include <unistd.h>
#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);
}
+81
View File
@@ -0,0 +1,81 @@
//! @file getpwuid.cpp
//! @author Andrew Schwartzmeyer <andschwa@microsoft.com>
//! @brief returns the username for a uid
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <string.h>
#include <unistd.h>
#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;
}
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#include <sys/types.h>
#include "pal.h"
PAL_BEGIN_EXTERNC
char* GetPwUid(uid_t uid);
PAL_END_EXTERNC
+2 -50
View File
@@ -2,64 +2,16 @@
//! @author Andrew Schwartzmeyer <andschwa@microsoft.com>
//! @brief Implements GetUserName for Linux
#include <errno.h>
#include <locale.h>
#include <unistd.h>
#include <string>
#include <pwd.h>
#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());
}