From: VMware, Inc <> Date: Thu, 2 Aug 2012 05:19:43 +0000 (-0700) Subject: Don't use $HOME to get the current user's home directory on Mac OS X-Git-Tag: 2012.10.14-874563~104 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c4e2242b6c6afee3ab9e5a44256b4dcf9f233d27;p=thirdparty%2Fopen-vm-tools.git Don't use $HOME to get the current user's home directory on Mac OS There are some cases on Mac OS where the $HOME environment variable has not been set even though the current user does have a valid home directory. For example, if you enable the "root" user in the UI and then try to start Fusion via Finder, it would fail spectacularly because it was unable to figure out the Log and Preferences directories. In lib/misc, for Mac OS, instead of resorting to $HOME in the case where we are trying to expand "~" for the current user, we instead use the posix passwd API, which according to the man page is properly hooked up to DirectoryServices and thus will give us any user's homedir even if it isn't actually in the /etc/passwd file. Signed-off-by: Dmitry Torokhov --- diff --git a/open-vm-tools/lib/misc/util_misc.c b/open-vm-tools/lib/misc/util_misc.c index 31c225d15..9b577ad16 100644 --- a/open-vm-tools/lib/misc/util_misc.c +++ b/open-vm-tools/lib/misc/util_misc.c @@ -119,7 +119,7 @@ Util_GetCanonicalPath(const char *path) // IN: * If the path is *potentially* a path to remote share, we do not * call GetLongPathName, because if the remote server is unreachable, * that function could hang. We sacrifice two things by doing so: - * 1. The UNC path could refer to the local host and we incorrectly + * 1. The UNC path could refer to the local host and we incorrectly * assume remote. * 2. We do not resolve 8.3 names for remote paths. */ @@ -148,7 +148,7 @@ Util_GetCanonicalPath(const char *path) // IN: * for use as a seed to hash functions. * * Results: - * Canonicalized UTF-8 pathname suitable for use in hashing. + * Canonicalized UTF-8 pathname suitable for use in hashing. * * Side effects: * None. @@ -161,11 +161,11 @@ Util_GetCanonicalPathForHash(const char *path) // IN: UTF-8 { char *ret = NULL; char *cpath = Util_GetCanonicalPath(path); - + if (cpath != NULL) { ret = Unicode_FoldCase(cpath); free(cpath); - } + } return ret; } @@ -182,9 +182,9 @@ Util_GetCanonicalPathForHash(const char *path) // IN: UTF-8 * encoding. Hence, the use of WideCharToMultiByte(). * * Results: - * An allocated string in legacy encoding (MBCS when applicable). + * An allocated string in legacy encoding (MBCS when applicable). * NULL on failure. - * + * * Side effects: * None. * @@ -196,19 +196,19 @@ UtilGetLegacyEncodedString(const char *path) // IN: UTF-8 { char *ret = NULL; char *cpath = Util_GetCanonicalPath(path); - + if (cpath != NULL) { char *apath = NULL; int retlen; WCHAR *wcpath = Unicode_GetAllocUTF16(cpath); /* First get the length of multibyte string */ - int alen = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, wcpath, -1, + int alen = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, wcpath, -1, NULL, 0, NULL, NULL); if (alen > 0) { /* Now get the converted string */ ret = Util_SafeMalloc(alen); - retlen = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, wcpath, -1, + retlen = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, wcpath, -1, ret, alen, NULL, NULL); if (retlen != alen) { free(ret); @@ -218,7 +218,7 @@ UtilGetLegacyEncodedString(const char *path) // IN: UTF-8 free(cpath); free(wcpath); } - + return ret; } @@ -250,7 +250,7 @@ Util_CompatGetCanonicalPath(const char *path) // IN: UTF-8 ret = UtilGetLegacyEncodedString(cpath); free(cpath); } - + return ret; } #endif @@ -262,7 +262,7 @@ Util_CompatGetCanonicalPath(const char *path) // IN: UTF-8 * Util_CanonicalPathsIdentical -- * * Utility function to compare two paths that have already been made - * canonical. This function exists to mask platform differences in + * canonical. This function exists to mask platform differences in * path case-sensitivity. * * XXX: This implementation makes assumptions about the host filesystem's @@ -515,7 +515,7 @@ Util_GetCurrentThreadId(void) * * UtilIsAlphaOrNum -- * - * Checks if character is a numeric digit or a letter of the + * Checks if character is a numeric digit or a letter of the * english alphabet. * * Results: @@ -547,34 +547,25 @@ UtilIsAlphaOrNum(char ch) //IN * * UtilGetHomeDirectory -- * - * Unicode wrapper for posix getpwnam call for working directory. + * Retrieves the home directory for a user, given their passwd struct. * * Results: - * Returns initial working directory or NULL if it fails. + * Returns user's home directory or NULL if it fails. * * Side effects: - * None. + * None. * *----------------------------------------------------------------------------- */ static char * -UtilGetHomeDirectory(const char *name) // IN: user name +UtilGetHomeDirectory(struct passwd *pwd) // IN/OPT: user passwd struct { - char *dir; - struct passwd *pwd; - - ASSERT(name); - - pwd = Posix_Getpwnam(name); if (pwd && pwd->pw_dir) { - dir = Util_SafeStrdup(pwd->pw_dir); + return Util_SafeStrdup(pwd->pw_dir); } else { - dir = NULL; + return NULL; } - endpwent(); - - return dir; } @@ -583,32 +574,25 @@ UtilGetHomeDirectory(const char *name) // IN: user name * * UtilGetLoginName -- * - * Unicode wrapper for posix getpwnam call for working directory. + * Retrieves the login name for a user, given their passwd struct. * * Results: * Returns user's login name or NULL if it fails. * * Side effects: - * None. + * None. * *----------------------------------------------------------------------------- */ static char * -UtilGetLoginName(int uid) //IN: user id +UtilGetLoginName(struct passwd *pwd) // IN/OPT: user passwd struct { - char *name; - struct passwd *pwd; - - pwd = Posix_Getpwuid(uid); if (pwd && pwd->pw_name) { - name = Util_SafeStrdup(pwd->pw_name); + return Util_SafeStrdup(pwd->pw_name); } else { - name = NULL; + return NULL; } - endpwent(); - - return name; } @@ -633,19 +617,38 @@ UtilGetLoginName(int uid) //IN: user id */ static Unicode -UtilDoTildeSubst(Unicode user) // IN - name of user +UtilDoTildeSubst(ConstUnicode user) // IN: name of user { Unicode str = NULL; + struct passwd *pwd = NULL; if (*user == '\0') { +#if defined(__APPLE__) + /* + * The HOME environment variable is not always set on Mac OS. + * (was bug 841728) + */ + pwd = Posix_Getpwuid(getuid()); + if (pwd == NULL) { + Log("Could not get passwd for current user.\n"); + } +#else // !defined(__APPLE__) str = Unicode_Duplicate(Posix_Getenv("HOME")); if (str == NULL) { Log("Could not expand environment variable HOME.\n"); } +#endif // !defined(__APPLE__) } else { - str = UtilGetHomeDirectory(user); + pwd = Posix_Getpwnam(user); + if (pwd == NULL) { + Log("Could not get passwd for user '%s'.\n", user); + } + } + if (str == NULL && pwd != NULL) { + str = UtilGetHomeDirectory(pwd); + endpwent(); if (str == NULL) { - Log("Could not get information for user '%s'.\n", user); + Log("Could not get home directory for user.\n"); } } return str; @@ -701,7 +704,7 @@ Util_ExpandString(ConstUnicode fileName) // IN file path to expand /* * quick exit */ - if (!Unicode_StartsWith(fileName, "~") && + if (!Unicode_StartsWith(fileName, "~") && Unicode_Find(fileName, "$") == UNICODE_INDEX_NOT_FOUND) { return copy; } @@ -807,8 +810,9 @@ Util_ExpandString(ConstUnicode fileName) // IN file path to expand expand = Util_SafeStrdup(buf); } else if (strcasecmp(cp + 1, "USER") == 0) { #if !defined(_WIN32) - int uid = getuid(); - expand = UtilGetLoginName(uid); + struct passwd *pwd = Posix_Getpwuid(getuid()); + expand = UtilGetLoginName(pwd); + endpwent(); #else DWORD n = ARRAYSIZE(bufW); if (GetUserNameW(bufW, &n)) {