From: VMware, Inc <> Date: Mon, 20 Sep 2010 17:53:35 +0000 (-0700) Subject: Internal branch sync. Included in this change: X-Git-Tag: stable-8.6.0~41 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9a4de64ca3fdab877fe7e176ac79e67e4733eec4;p=thirdparty%2Fopen-vm-tools.git Internal branch sync. Included in this change: . relocate the Unity operations enums into unityCommon.h. . fix File_DeleteDirectoryTree to not fail when asked to delete a dir that doesn't exist. . refactor VIX code that deals with environment variables. . changes in shared code that don't affect open-vm-tools functionality. Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/lib/file/file.c b/open-vm-tools/lib/file/file.c index 3b8306486..c23f0c75d 100644 --- a/open-vm-tools/lib/file/file.c +++ b/open-vm-tools/lib/file/file.c @@ -2044,20 +2044,33 @@ File_DeleteDirectoryTree(ConstUnicode pathName) // IN: directory to delete { int i; int numFiles; + int err = 0; Unicode base; Unicode *fileList = NULL; Bool sawFileError = FALSE; - if (Posix_EuidAccess(pathName, F_OK)) { - switch (errno) { + if (Posix_EuidAccess(pathName, F_OK) != 0) { + /* + * If Posix_EuidAccess failed with errno == ENOSYS, then fall back + * to FileAttributes. + */ + if (errno == ENOSYS) { + /* FileAttributes returns the error code instead of setting errno. */ + err = FileAttributes(pathName, NULL); + } else { + /* Use the error value that was set by Posix_EuidAccess. */ + err = errno; + } + } + + switch (err) { case ENOENT: case ENOTDIR: /* path does not exist or is inaccessible */ return TRUE; default: break; - } } /* get list of files in current directory */ diff --git a/open-vm-tools/lib/file/filePosix.c b/open-vm-tools/lib/file/filePosix.c index 4a9647395..1cf8018cc 100644 --- a/open-vm-tools/lib/file/filePosix.c +++ b/open-vm-tools/lib/file/filePosix.c @@ -1203,29 +1203,27 @@ File_GetVMFSMountInfo(ConstUnicode pathName, // IN: /* *---------------------------------------------------------------------- * - * File_SupportsZeroedThick -- + * FileIsVMFS -- * - * Check if the given file is on an FS supports creation of - * the zeroed-thick files. - * Currently only VMFS on ESX does support zeroed-thick files, but - * this may change in the future. + * Is the given file on a filesystem that supports vmfs-specific + * features like zeroed-thick and multiwriter files? * * Results: - * TRUE if FS supports creation of the zeroed-thick files. + * TRUE if we're on VMFS. * * Side effects: - * None + * None * *---------------------------------------------------------------------- */ Bool -File_SupportsZeroedThick(ConstUnicode pathName) // IN: File name to test +FileIsVMFS(ConstUnicode pathName) // IN { Bool result = FALSE; #if defined(VMX86_SERVER) - /* Right now only VMFS supports ZeroedThick */ + /* Right now only VMFS supports zeroedThick and multiWriter. */ FS_PartitionListResult *fsAttrs = NULL; if (File_GetVMFSAttributes(pathName, &fsAttrs) >= 0) { @@ -1244,6 +1242,58 @@ File_SupportsZeroedThick(ConstUnicode pathName) // IN: File name to test } +/* + *---------------------------------------------------------------------- + * + * File_SupportsZeroedThick -- + * + * Check if the given file is on an FS supports creation of + * the zeroed-thick files. + * Currently only VMFS on ESX does support zeroed-thick files, but + * this may change in the future. + * + * Results: + * TRUE if FS supports creation of the zeroed-thick files. + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ + +Bool +File_SupportsZeroedThick(ConstUnicode pathName) // IN +{ + return FileIsVMFS(pathName); +} + + +/* + *---------------------------------------------------------------------- + * + * File_SupportsMultiWriter -- + * + * Check if the given file is on an FS supports opening files + * in multi-writer mode. + * Currently only VMFS on ESX supports multi-writer mode, but + * this may change in the future. + * + * Results: + * TRUE if FS supports opening files in multi-writer mode. + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ + +Bool +File_SupportsMultiWriter(ConstUnicode pathName) // IN +{ + return FileIsVMFS(pathName); +} + + /* *---------------------------------------------------------------------- * diff --git a/open-vm-tools/lib/foundryMsg/foundryMsg.c b/open-vm-tools/lib/foundryMsg/foundryMsg.c index aacb80b08..8a8a80675 100644 --- a/open-vm-tools/lib/foundryMsg/foundryMsg.c +++ b/open-vm-tools/lib/foundryMsg/foundryMsg.c @@ -462,6 +462,13 @@ static const VixCommandInfo vixCommandInfoTable[] = { VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_INITIATE_FILE_TRANSFER_TO_GUEST, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), + VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_ACQUIRE_CREDENTIALS, + VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), + VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_RELEASE_CREDENTIALS, + VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), + VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_VALIDATE_CREDENTIALS, + VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), + }; @@ -617,36 +624,38 @@ VixMsg_InitResponseMsg(VixCommandResponseHeader *responseHeader, // IN VixCommandRequestHeader * VixMsg_AllocRequestMsg(size_t msgHeaderAndBodyLength, // IN - int opCode, // IN - uint64 cookie, // IN - int credentialType, // IN - const char *userNamePassword) // IN + int opCode, // IN + uint64 cookie, // IN + int credentialType, // IN + const char *credential) // IN { size_t totalMessageSize; VixCommandRequestHeader *commandRequest = NULL; - size_t credentialLength = 0; - size_t namePasswordLength = 0; + size_t providedCredentialLength = 0; + size_t totalCredentialLength = 0; char *destPtr; - if ((VIX_USER_CREDENTIAL_NAME_PASSWORD == credentialType) + if ((VIX_USER_CREDENTIAL_NAME_PASSWORD == credentialType) || (VIX_USER_CREDENTIAL_HOST_CONFIG_SECRET == credentialType) - || (VIX_USER_CREDENTIAL_HOST_CONFIG_HASHED_SECRET == credentialType)) { + || (VIX_USER_CREDENTIAL_HOST_CONFIG_HASHED_SECRET == credentialType) + || (VIX_USER_CREDENTIAL_TICKETED_SESSION == credentialType) + || (VIX_USER_CREDENTIAL_SSPI == credentialType)) { /* - * Both of these are optional. + * All of these are optional. */ - if (NULL != userNamePassword) { - namePasswordLength = strlen(userNamePassword); - credentialLength += namePasswordLength; + if (NULL != credential) { + providedCredentialLength = strlen(credential); + totalCredentialLength += providedCredentialLength; } /* * Add 1 to each string to include '\0' for the end of the string. */ - credentialLength += 1; + totalCredentialLength += 1; } else { - credentialLength = 0; + totalCredentialLength = 0; } - totalMessageSize = msgHeaderAndBodyLength + credentialLength; + totalMessageSize = msgHeaderAndBodyLength + totalCredentialLength; if (totalMessageSize > VIX_COMMAND_MAX_REQUEST_SIZE) { /* * We don't want to allocate any requests larger than @@ -664,11 +673,11 @@ VixMsg_AllocRequestMsg(size_t msgHeaderAndBodyLength, // IN commandRequest->commonHeader.magic = VIX_COMMAND_MAGIC_WORD; commandRequest->commonHeader.messageVersion = VIX_COMMAND_MESSAGE_VERSION; commandRequest->commonHeader.totalMessageLength = - msgHeaderAndBodyLength + credentialLength; + msgHeaderAndBodyLength + totalCredentialLength; commandRequest->commonHeader.headerLength = sizeof(VixCommandRequestHeader); commandRequest->commonHeader.bodyLength = msgHeaderAndBodyLength - sizeof(VixCommandRequestHeader); - commandRequest->commonHeader.credentialLength = credentialLength; + commandRequest->commonHeader.credentialLength = totalCredentialLength; commandRequest->commonHeader.commonFlags = VIX_COMMAND_REQUEST; commandRequest->opCode = opCode; @@ -680,13 +689,15 @@ VixMsg_AllocRequestMsg(size_t msgHeaderAndBodyLength, // IN if ((VIX_USER_CREDENTIAL_NAME_PASSWORD == credentialType) || (VIX_USER_CREDENTIAL_HOST_CONFIG_SECRET == credentialType) - || (VIX_USER_CREDENTIAL_HOST_CONFIG_HASHED_SECRET == credentialType)) { + || (VIX_USER_CREDENTIAL_HOST_CONFIG_HASHED_SECRET == credentialType) + || (VIX_USER_CREDENTIAL_TICKETED_SESSION == credentialType) + || (VIX_USER_CREDENTIAL_SSPI == credentialType)) { destPtr = (char *) commandRequest; destPtr += commandRequest->commonHeader.headerLength; destPtr += commandRequest->commonHeader.bodyLength; - if (NULL != userNamePassword) { - Str_Strcpy(destPtr, userNamePassword, namePasswordLength + 1); - destPtr += namePasswordLength; + if (NULL != credential) { + Str_Strcpy(destPtr, credential, providedCredentialLength + 1); + destPtr += providedCredentialLength; } *(destPtr++) = 0; } diff --git a/open-vm-tools/lib/foundryMsg/foundryPropertyListCommon.c b/open-vm-tools/lib/foundryMsg/foundryPropertyListCommon.c index b00612d14..52561e640 100644 --- a/open-vm-tools/lib/foundryMsg/foundryPropertyListCommon.c +++ b/open-vm-tools/lib/foundryMsg/foundryPropertyListCommon.c @@ -230,8 +230,14 @@ VixPropertyList_Serialize(VixPropertyListImpl *propList, // IN //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_POINTER: - bufferSize += PROPERTY_SIZE_POINTER; - break; + /* + * We should not serialize any pointer. + * Catch such programming errors. + */ + err = VIX_E_INVALID_ARG; + Log("%s:%d, pointer properties cannot be serialized.\n", + __FUNCTION__, __LINE__); + goto abort; //////////////////////////////////////////////////////// default: @@ -318,16 +324,7 @@ VixPropertyList_Serialize(VixPropertyListImpl *propList, // IN //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_POINTER: - if (property->value.ptrValue) { - valueLength = PROPERTY_SIZE_POINTER; - memcpy(&(serializeBuffer[pos]), &valueLength, propertyValueLengthSize); - pos += propertyValueLengthSize; - memcpy(&(serializeBuffer[pos]), &(property->value.ptrValue), sizeof(property->value.ptrValue)); - } else { - err = VIX_E_INVALID_ARG; - goto abort; - } - break; + NOT_IMPLEMENTED(); //////////////////////////////////////////////////////// default: @@ -448,7 +445,6 @@ VixPropertyListDeserializeImpl(VixPropertyListImpl *propList, // IN int *intPtr; Bool *boolPtr; int64 *int64Ptr; - void **ptrPtr; unsigned char* blobPtr; int *propertyIDPtr; int *lengthPtr; @@ -588,15 +584,14 @@ VixPropertyListDeserializeImpl(VixPropertyListImpl *propList, // IN //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_POINTER: - // The size may be different on different machines. - // To be safe, we always use 8 bytes. - if (PROPERTY_SIZE_POINTER != *lengthPtr) { - err = VIX_E_INVALID_SERIALIZED_DATA; - goto abort; - } - ptrPtr = (void**) &(buffer[pos]); - property->value.ptrValue = *ptrPtr; - break; + /* + * Deserialize an pointer property should not be allowed. + * An evil peer could send us such data. + */ + err = VIX_E_INVALID_SERIALIZED_DATA; + Log("%s:%d, pointer properties cannot be serialized.\n", + __FUNCTION__, __LINE__); + goto abort; //////////////////////////////////////////////////////// default: diff --git a/open-vm-tools/lib/include/file.h b/open-vm-tools/lib/include/file.h index 00a168a7c..e07b750f0 100644 --- a/open-vm-tools/lib/include/file.h +++ b/open-vm-tools/lib/include/file.h @@ -120,6 +120,8 @@ EXTERN int File_GetVMFSMountInfo(ConstUnicode pathName, EXTERN Bool File_SupportsZeroedThick(ConstUnicode pathName); +EXTERN Bool File_SupportsMultiWriter(ConstUnicode pathName); + EXTERN Bool File_Exists(ConstUnicode pathName); EXTERN int File_Unlink(ConstUnicode pathName); diff --git a/open-vm-tools/lib/include/unityCommon.h b/open-vm-tools/lib/include/unityCommon.h index a44a51379..510f1afd6 100644 --- a/open-vm-tools/lib/include/unityCommon.h +++ b/open-vm-tools/lib/include/unityCommon.h @@ -434,6 +434,26 @@ typedef uint32 UnityIconSize; // Number of pixels on the larger side of the icon #define UNITY_DEFAULT_COLOR "#c0c0c0" +/* + * List of operations that can be interlocked with the host, via a request, confirm, + * acknowledge sequence of RPCs. + */ +typedef enum { + MINIMIZE = 1 +} UnityOperations; + + +/* + * List of features (as a bitmask) which may be optionally enabled when entering + * Unity mode. By default all these features are disabled. + */ +typedef enum { + UNITY_ADD_HIDDEN_WINDOWS_TO_TRACKER = 1, + UNITY_INTERLOCK_MINIMIZE_OPERATION = 1 << 1, + UNITY_SEND_WINDOW_CONTENTS = 1 << 2, + UNITY_DISABLE_COMPOSITING_IN_GUEST = 1 << 3 +} UnityFeatures; + /* * Multipage Doxygen documentation. @@ -802,6 +822,13 @@ desktop where the upper right {1,2} is the currently active desktop. @param[in] deltaZ the distance the wheel is rotated in the Z axis @param[in] modifierFlags modifier flags pressed during the event + @def UNITY_RPC_WINDOW_CONTENTS_REQUEST + @brief Request the asynchronous delivery of window contents. + @code + UNITY_RPC_WINDOW_CONTENTS_REQUEST XDR_REP + @endcode + @param[in] XDR_REP XDR Encoded (see unity.x) representation of arguments. + @} */ @@ -884,6 +911,27 @@ desktop where the upper right {1,2} is the currently active desktop. @endcode @param[in] XDR_REP XDR Encoded (see unity.x) representation of arguments. + @def UNITY_RPC_WINDOW_CONTENTS_START + @brief The start of data for the pixel contents of the window. + @code + UNITY_RPC_WINDOW_CONTENTS_START XDR_REP + @endcode + @param[in] XDR_REP XDR Encoded (see unity.x) representation of arguments. + + @def UNITY_RPC_WINDOW_CONTENTS_CHUNK + @brief One (<64KB) chunk of Pixel Data for a previously started window. + @code + UNITY_RPC_WINDOW_CONTENTS_CHUNK XDR_REP + @endcode + @param[in] XDR_REP XDR Encoded (see unity.x) representation of arguments. + + @def UNITY_RPC_WINDOW_CONTENTS_END + @brief The end of data for the pixel contents of the window. + @code + UNITY_RPC_WINDOW_CONTENTS_END XDR_REP + @endcode + @param[in] XDR_REP XDR Encoded (see unity.x) representation of arguments. + @} */ diff --git a/open-vm-tools/lib/include/vix.h b/open-vm-tools/lib/include/vix.h index 38a3e4978..abaa63d7a 100644 --- a/open-vm-tools/lib/include/vix.h +++ b/open-vm-tools/lib/include/vix.h @@ -169,8 +169,10 @@ enum { VIX_E_NO_DISPLAY_SERVER = 3043, VIX_E_VM_NOT_RECORDING = 3044, VIX_E_VM_NOT_REPLAYING = 3045, + VIX_E_TOO_MANY_LOGONS = 3046, + VIX_E_INVALID_AUTHENTICATION_SESSION = 3047, - /* VM Errors */ + /* VM Errors */ VIX_E_VM_NOT_FOUND = 4000, VIX_E_NOT_SUPPORTED_FOR_VM_VERSION = 4001, VIX_E_CANNOT_READ_VM_CONFIG = 4002, diff --git a/open-vm-tools/lib/include/vixCommands.h b/open-vm-tools/lib/include/vixCommands.h index 926bf2cc0..a504edb4c 100644 --- a/open-vm-tools/lib/include/vixCommands.h +++ b/open-vm-tools/lib/include/vixCommands.h @@ -59,6 +59,8 @@ #define VIX_USER_CREDENTIAL_HOST_CONFIG_SECRET 6 #define VIX_USER_CREDENTIAL_HOST_CONFIG_HASHED_SECRET 7 #define VIX_USER_CREDENTIAL_NAMED_INTERACTIVE_USER 8 +#define VIX_USER_CREDENTIAL_TICKETED_SESSION 9 +#define VIX_USER_CREDENTIAL_SSPI 10 #define VIX_SHARED_SECRET_CONFIG_USER_NAME "__VMware_Vix_Shared_Secret_1__" @@ -287,6 +289,29 @@ struct VixCommandNamePassword { #include "vmware_pack_end.h" VixCommandNamePassword; +/* + * ********************************************************** + * This is a ticketed session for authentication. + */ +typedef +#include "vmware_pack_begin.h" +struct VixCommandTicketedSession { + uint32 ticketLength; +} +#include "vmware_pack_end.h" +VixCommandTicketedSession; + +/* + * ********************************************************** + * This is a SSPI token for acquiring credentials + */ +typedef +#include "vmware_pack_begin.h" +struct VixCommandSSPI { + uint32 tokenLength; +} +#include "vmware_pack_end.h" +VixCommandSSPI; /* * ********************************************************** @@ -1643,7 +1668,7 @@ VixMsgGetVProbesResponse; typedef #include "vmware_pack_begin.h" struct VixMsgVProbeLoadRequest { - VixCommandResponseHeader header; + VixCommandRequestHeader header; char string[1]; /* variable length */ } #include "vmware_pack_end.h" @@ -2049,6 +2074,20 @@ struct VixCommandListFileSystemsRequest { #include "vmware_pack_end.h" VixCommandListFileSystemsRequest; +/* + * ********************************************************** + * Acquire Credentials. + */ + +typedef +#include "vmware_pack_begin.h" +struct VixCommandAcquireCredentialsRequest { + VixCommandRequestHeader header; + + int64 sessionID; +} +#include "vmware_pack_end.h" +VixCommandAcquireCredentialsRequest; /* * ********************************************************** @@ -2341,9 +2380,12 @@ enum { VIX_COMMAND_READ_ENV_VARIABLES = 187, VIX_COMMAND_INITIATE_FILE_TRANSFER_FROM_GUEST = 188, - VIX_COMMAND_INITIATE_FILE_TRANSFER_TO_GUEST = 189, + VIX_COMMAND_ACQUIRE_CREDENTIALS = 190, + VIX_COMMAND_RELEASE_CREDENTIALS = 191, + VIX_COMMAND_VALIDATE_CREDENTIALS = 192, + /* * HOWTO: Adding a new Vix Command. Step 2a. * @@ -2354,7 +2396,7 @@ enum { * Once a new command is added here, a command info field needs to be added * in bora/lib/foundryMsg/foundryMsg.c as well. */ - VIX_COMMAND_LAST_NORMAL_COMMAND = 190, + VIX_COMMAND_LAST_NORMAL_COMMAND = 193, VIX_TEST_UNSUPPORTED_TOOLS_OPCODE_COMMAND = 998, VIX_TEST_UNSUPPORTED_VMX_OPCODE_COMMAND = 999, diff --git a/open-vm-tools/lib/include/vixOpenSource.h b/open-vm-tools/lib/include/vixOpenSource.h index 7dc038010..f94a55560 100644 --- a/open-vm-tools/lib/include/vixOpenSource.h +++ b/open-vm-tools/lib/include/vixOpenSource.h @@ -152,6 +152,10 @@ enum { VIX_PROPERTY_GUEST_TOOLS_WORD_SIZE = 4519, VIX_PROPERTY_GUEST_OS_VERSION_SHORT = 4520, + VIX_PROPERTY_GUEST_AUTH_SSPI_TOKEN = 4531, + VIX_PROPERTY_GUEST_AUTH_SSPI_SESSION_ID = 4532, + VIX_PROPERTY_GUEST_AUTH_SESSION_TICKET = 4533, + /* VI guest operation status */ VIX_PROPERTY_GUEST_START_PROGRAM_ENABLED = 4540, VIX_PROPERTY_GUEST_LIST_PROCESSES_ENABLED = 4541, diff --git a/open-vm-tools/modules/shared/vmxnet/vmxnet3_defs.h b/open-vm-tools/modules/shared/vmxnet/vmxnet3_defs.h index 04d7716ae..23fa8f4d9 100644 --- a/open-vm-tools/modules/shared/vmxnet/vmxnet3_defs.h +++ b/open-vm-tools/modules/shared/vmxnet/vmxnet3_defs.h @@ -74,6 +74,17 @@ #define VMXNET3_PT_REG_SIZE 4096 /* BAR 0 */ #define VMXNET3_VD_REG_SIZE 4096 /* BAR 1 */ +/* + * The two Vmxnet3 MMIO Register PCI BARs (BAR 0 at offset 10h and BAR 1 at + * offset 14h) as well as the MSI-X BAR are combined into one PhysMem region: + * <-VMXNET3_PT_REG_SIZE-><-VMXNET3_VD_REG_SIZE-><-VMXNET3_MSIX_BAR_SIZE--> + * ------------------------------------------------------------------------- + * |Pass Thru Registers | Virtual Dev Registers | MSI-X Vector/PBA Table | + * ------------------------------------------------------------------------- + * VMXNET3_MSIX_BAR_SIZE is defined in "vmxnet3Int.h" + */ +#define VMXNET3_PHYSMEM_PAGES 4 + #define VMXNET3_REG_ALIGN 8 /* All registers are 8-byte aligned. */ #define VMXNET3_REG_ALIGN_MASK 0x7 diff --git a/open-vm-tools/services/plugins/dndcp/pointer.cpp b/open-vm-tools/services/plugins/dndcp/pointer.cpp index 8a4f99b25..e2217f46c 100644 --- a/open-vm-tools/services/plugins/dndcp/pointer.cpp +++ b/open-vm-tools/services/plugins/dndcp/pointer.cpp @@ -310,8 +310,18 @@ PointerUpdatePointerLoop(gpointer clientData) // IN: unused void Pointer_Init(ToolsAppCtx *ctx) { - g_debug("%s: enter\n", __FUNCTION__); - absoluteMouseState = GuestApp_GetAbsoluteMouseState(); - PointerUpdatePointerLoop(NULL); - mouseIsGrabbed = FALSE; + /* + * XXX There is a performance issue with timer in this module. As a + * temporarily workaround, this module will be disabled by default, but can + * be enabled with tools.conf. Please refer to bug 598078 for more detail. + */ + if (g_key_file_get_boolean(ctx->config, "dndcp", + "pointer.enable", NULL)) { + g_debug("%s: pointer is enabled\n", __FUNCTION__); + absoluteMouseState = GuestApp_GetAbsoluteMouseState(); + PointerUpdatePointerLoop(NULL); + mouseIsGrabbed = FALSE; + } else { + g_debug("%s: pointer is disabled\n", __FUNCTION__); + } } diff --git a/open-vm-tools/services/plugins/unity/unity.x b/open-vm-tools/services/plugins/unity/unity.x index e9cf3aaa3..7484cecb8 100644 --- a/open-vm-tools/services/plugins/unity/unity.x +++ b/open-vm-tools/services/plugins/unity/unity.x @@ -27,21 +27,15 @@ */ /* - * Enumerates the different versions of the messages. + * Include unityCommon for the definitions of the types of operations. */ -enum UnityOptionsVersion { - UNITY_OPTIONS_V1 = 1 -}; +%#include "unityCommon.h" /* - * List of features (as a bitmask) which may be optionally enabled when entering - * Unity mode. By default all these features are disabled. + * Enumerates the different versions of the messages. */ -enum UnityFeatures { - UNITY_ADD_HIDDEN_WINDOWS_TO_TRACKER = 1, - UNITY_INTERLOCK_MINIMIZE_OPERATION = 2, - UNITY_SEND_WINDOW_CONTENTS = 4, - UNITY_DISABLE_COMPOSITING_IN_GUEST = 8 +enum UnityOptionsVersion { + UNITY_OPTIONS_V1 = 1 }; /* @@ -86,14 +80,10 @@ enum UnityOperationVersion { UNITY_OP_V1 = 1 }; -enum UnityOperations { - MINIMIZE = 1 -}; - /* * The structure used to distinguish the operations of the message. */ -union UnityOperationDetails switch (UnityOperations op) { +union UnityOperationDetails switch (int op) { case MINIMIZE: int dummy; /* Dummy value to avoid empty union */ }; diff --git a/open-vm-tools/services/plugins/vix/Makefile.am b/open-vm-tools/services/plugins/vix/Makefile.am index cc7d7a945..d5a021fed 100644 --- a/open-vm-tools/services/plugins/vix/Makefile.am +++ b/open-vm-tools/services/plugins/vix/Makefile.am @@ -36,4 +36,4 @@ libvix_la_SOURCES = libvix_la_SOURCES += foundryToolsDaemon.c libvix_la_SOURCES += vixPlugin.c libvix_la_SOURCES += vixTools.c - +libvix_la_SOURCES += vixToolsEnvVars.c diff --git a/open-vm-tools/services/plugins/vix/vixTools.c b/open-vm-tools/services/plugins/vix/vixTools.c index 29a3896db..442a0b9c2 100644 --- a/open-vm-tools/services/plugins/vix/vixTools.c +++ b/open-vm-tools/services/plugins/vix/vixTools.c @@ -24,10 +24,11 @@ /* * When adding new functions, be sure to update - * VixToolsSetAPIEnabledProperties() (adding a property and associated code - * in apps/lib/foundry/foundryVM.c if necessary). The enabled properties - * provide hints to an API developer as to which APIs are available, - * and can be affected to guest OS attributes or guest-side conifguration. + * VixToolsCheckIfVixCommandEnabled() and VixToolsSetAPIEnabledProperties() + * (adding a property and associated code in apps/lib/foundry/foundryVM.c + * if necessary). The enabled properties provide hints to an API developer + * as to which APIs are available, and can be affected to guest OS attributes + * or guest-side configuration. * * See Vim.Vm.Guest.QueryDisabledMethods() * @@ -114,8 +115,6 @@ #define SECONDS_BETWEEN_POLL_TEST_FINISHED 1 -#define PROCESS_CREATOR_USER_TOKEN ((void *)1) - #define MAX_PROCESS_LIST_RESULT_LENGTH 81920 /* @@ -199,7 +198,7 @@ typedef struct VixToolsStartProgramState { * if we don't save it off for before the timer fires. */ typedef struct VixToolsExitedProgramState { - char *name; + char *fullCommandLine; char *user; uint64 pid; time_t startTime; @@ -337,6 +336,8 @@ static VixError VixToolsReadVariable(VixCommandRequestHeader *requestMsg, static VixError VixToolsReadEnvVariables(VixCommandRequestHeader *requestMsg, char **result); +static VixError VixToolsGetAllEnvVarsForUser(void *userToken, char **result); + static VixError VixToolsWriteVariable(VixCommandRequestHeader *requestMsg); static VixError VixToolsListProcesses(VixCommandRequestHeader *requestMsg, @@ -372,6 +373,12 @@ static VixError VixToolsProcessHgfsPacket(VixCommandHgfsSendPacket *requestMsg, static VixError VixToolsListFileSystems(VixCommandRequestHeader *requestMsg, char **result); +static VixError VixToolsValidateCredentials(VixCommandRequestHeader *requestMsg); + +static VixError VixToolsAcquireCredentials(VixCommandRequestHeader *requestMsg, + char **result); + +static VixError VixToolsReleaseCredentials(VixCommandRequestHeader *requestMsg); #if defined(__linux__) || defined(_WIN32) static VixError VixToolsGetGuestNetworkingConfig(VixCommandRequestHeader *requestMsg, @@ -451,6 +458,15 @@ VixTools_Initialize(Bool thisProcessRunsAsRootParam, #ifndef _WIN32 VixToolsBuildUserEnvironmentTable(originalEnvp); +#else + /* + * Ensure that we never allow more SSPI sessions than ticketed sessions + * because there must be a ticketed session available for each SSPI session. + */ + ASSERT_ON_COMPILE(VIX_TOOLS_MAX_TICKETED_SESSIONS >= VIX_TOOLS_MAX_SSPI_SESSIONS); + + VixToolsInitSspiSessionList(VIX_TOOLS_MAX_SSPI_SESSIONS); + VixToolsInitTicketedSessionList(VIX_TOOLS_MAX_TICKETED_SESSIONS); #endif #if !defined(__FreeBSD__) /* Register a straight through connection with the Hgfs server. */ @@ -757,7 +773,6 @@ VixTools_RunProgram(VixCommandRequestHeader *requestMsg, // IN int64 pid; static char resultBuffer[32]; - runProgramRequest = (VixMsgRunProgramRequest *) requestMsg; commandLine = ((char *) runProgramRequest) + sizeof(*runProgramRequest); if (0 == *commandLine) { @@ -892,6 +907,7 @@ VixTools_StartProgram(VixCommandRequestHeader *requestMsg, // IN &pid); if (VIX_OK == err) { + /* * Save off the program so ListProcessesEx can find it. * @@ -899,7 +915,26 @@ VixTools_StartProgram(VixCommandRequestHeader *requestMsg, // IN * exited process polling proc. */ exitState = Util_SafeMalloc(sizeof(VixToolsExitedProgramState)); - exitState->name = Util_SafeStrdup(programPath); + + /* + * Build up the command line so the args are passed to the command. + * To be safe, always put quotes around the program name. If the name + * contains spaces (either in the file name of its directory path), + * then the quotes are required. If the name doesn't contain spaces, then + * unnecessary quotes don't seem to create a problem for both Windows and + * Linux. + */ + if (NULL != arguments) { + exitState->fullCommandLine = Str_Asprintf(NULL, + "\"%s\" %s", + programPath, + arguments); + } else { + exitState->fullCommandLine = Str_Asprintf(NULL, + "\"%s\"", + programPath); + } + exitState->user = Util_SafeStrdup(VixToolsGetImpersonatedUsername(&userToken)); exitState->pid = (uint64) pid; exitState->startTime = time(NULL); @@ -1021,7 +1056,7 @@ VixToolsRunProgramImpl(char *requestName, // IN * To be safe, always put quotes around the program name. If the name * contains spaces (either in the file name of its directory path), * then the quotes are required. If the name doesn't contain spaces, then - * unnecessary quotes don't seem to create aproblem for both Windows and + * unnecessary quotes don't seem to create a problem for both Windows and * Linux. */ if (NULL != commandLineArgs) { @@ -1211,7 +1246,7 @@ VixToolsStartProgramImpl(char *requestName, // IN * To be safe, always put quotes around the program name. If the name * contains spaces (either in the file name of its directory path), * then the quotes are required. If the name doesn't contain spaces, then - * unnecessary quotes don't seem to create aproblem for both Windows and + * unnecessary quotes don't seem to create a problem for both Windows and * Linux. */ if (NULL != arguments) { @@ -1443,7 +1478,7 @@ done: * and endTime. */ exitState = Util_SafeMalloc(sizeof(VixToolsExitedProgramState)); - exitState->name = NULL; + exitState->fullCommandLine = NULL; exitState->user = NULL; exitState->pid = pid; exitState->startTime = 0; @@ -1568,7 +1603,7 @@ VixToolsFreeExitedProgramState(VixToolsExitedProgramState *exitState) // IN return; } - free(exitState->name); + free(exitState->fullCommandLine); free(exitState->user); free(exitState); @@ -1952,6 +1987,8 @@ exit: * * Helper function for fetching the API config setting. * + * If the varName is NULL, only the global switch is checked. + * * Return value: * Bool * @@ -1976,7 +2013,7 @@ VixToolsGetAPIDisabledFromConf(GKeyFile *confDictRef, // IN /* * First check the global kill-switch, which will override the - * per-API configs. + * per-API configs if its set. */ if (confDictRef != NULL) { disabled = g_key_file_get_boolean(confDictRef, @@ -1989,10 +2026,10 @@ VixToolsGetAPIDisabledFromConf(GKeyFile *confDictRef, // IN } /* - * Check the individual API + * Check the individual API if the global kill-switch isn't on. */ if (NULL != varName) { - snprintf(disabledName, sizeof(disabledName), "%s.disabled", varName); + Str_Snprintf(disabledName, sizeof(disabledName), "%s.disabled", varName); if (confDictRef != NULL) { disabled = g_key_file_get_boolean(confDictRef, VIX_TOOLS_CONFIG_API_GROUPNAME, @@ -2844,24 +2881,10 @@ VixToolsReadEnvVariables(VixCommandRequestHeader *requestMsg, // IN /* * If none are specified, return all of them. */ -#ifdef _WIN32 - /* XXX TODO XXX */ -#elif defined(linux) - char **ep; - - /* - * The full env var list is in a magic char ** extern in the form - * 'VAR=VAL' - */ - ep = __environ; - while (*ep) { - tmp = results; - results = Str_Asprintf(NULL, "%s%s", - tmp, *ep); - free(tmp); - ep++; + err = VixToolsGetAllEnvVarsForUser(userToken, &results); + if (VIX_FAILED(err)) { + goto abort; } -#endif } *result = results; @@ -2873,7 +2896,67 @@ abort: VixToolsLogoutUser(userToken); return err; -} // VixToolsReadVariable +} // VixToolsReadEnvVariables + + +/* + *----------------------------------------------------------------------------- + * + * VixToolsGetAllEnvVarsForUser -- + * + * Populates result with an XML-like string containing all the + * environment variables set for the user represented by 'userToken'. + * The result string will contain zero or more entries of the form + * NAME=VALUE without any delimiting characters. + * + * Results: + * VixError + * + * Side effects: + * None + * + *----------------------------------------------------------------------------- + */ + +static VixError +VixToolsGetAllEnvVarsForUser(void *userToken, // IN + char **result) // OUT +{ + VixError err; + char *resultLocal; + VixToolsEnvIterator *itr; + char *envVar; + + if (NULL == result) { + err = VIX_E_FAIL; + return err; + } + + resultLocal = Util_SafeStrdup(""); // makes the loop cleaner. + + err = VixToolsNewEnvIterator(userToken, &itr); + if (VIX_FAILED(err)) { + goto abort; + } + + while ((envVar = VixToolsGetNextEnvVar(itr)) != NULL) { + char *tmp = resultLocal; + resultLocal = Str_Asprintf(NULL, "%s%s", tmp, envVar); + free(tmp); + free(envVar); + if (NULL == resultLocal) { + Debug("%s: Out of memory.\n", __FUNCTION__); + err = VIX_E_OUT_OF_MEMORY; + goto abort; + } + } + +abort: + VixToolsDestroyEnvIterator(itr); + *result = resultLocal; + + return err; +} /* @@ -3063,7 +3146,18 @@ VixToolsMoveObject(VixCommandRequestHeader *requestMsg) // IN * diff err codes depending on OS, so catch it up front (bug 133165) */ if (File_IsDirectory(destFilePathName)) { - err = VIX_E_ALREADY_EXISTS; + if ((VIX_COMMAND_MOVE_GUEST_FILE_EX == requestMsg->opCode) || + (VIX_COMMAND_MOVE_GUEST_DIRECTORY == requestMsg->opCode)) { + /* + * If we are implementing opcodes related to VI Guest operations, + * then return VIX_E_FILE_ALREADY_EXISTS. Don't change the error + * code for opcode related to VIX C api. It will break the existing + * tests. + */ + err = VIX_E_FILE_ALREADY_EXISTS; + } else { + err = VIX_E_ALREADY_EXISTS; + } goto abort; } @@ -3404,7 +3498,7 @@ VixToolsListProcessesEx(VixCommandRequestHeader *requestMsg, // IN "%s%d" "%d%d" "", - epList->name, + epList->fullCommandLine, epList->pid, epList->user, (int) epList->startTime, @@ -3423,7 +3517,7 @@ VixToolsListProcessesEx(VixCommandRequestHeader *requestMsg, // IN "%s%d" "%d%d" "", - epList->name, + epList->fullCommandLine, epList->pid, epList->user, (int) epList->startTime, @@ -3870,10 +3964,8 @@ VixToolsListFiles(VixCommandRequestHeader *requestMsg, // IN int maxResults = 0; int count = 0; int numResults; -#if defined(VMTOOLS_USE_GLIB) GRegex *regex = NULL; GError *gerr = NULL; -#endif ASSERT(NULL != requestMsg); @@ -3912,7 +4004,6 @@ VixToolsListFiles(VixCommandRequestHeader *requestMsg, // IN __FUNCTION__, dirPathName, pattern); if (pattern) { -#if defined(VMTOOLS_USE_GLIB) regex = g_regex_new(pattern, 0, 0, &gerr); if (!regex) { Debug("%s: bad regex pattern '%s'; failing with INVALID_ARG\n", @@ -3920,12 +4011,6 @@ VixToolsListFiles(VixCommandRequestHeader *requestMsg, // IN err = VIX_E_INVALID_ARG; goto abort; } -#else - Debug("%s: pattern filter support desired but not built in\n", - __FUNCTION__); - err = VIX_E_NOT_SUPPORTED; - goto abort; -#endif } if (File_IsDirectory(dirPathName)) { @@ -3975,13 +4060,11 @@ VixToolsListFiles(VixCommandRequestHeader *requestMsg, // IN fileNum++) { currentFileName = fileNameList[fileNum]; -#if defined(VMTOOLS_USE_GLIB) if (regex) { if (!g_regex_match(regex, currentFileName, 0, NULL)) { continue; } } -#endif resultBufferSize += formatStringLength; resultBufferSize += 2; // DIRSEPC chars @@ -4036,13 +4119,11 @@ VixToolsListFiles(VixCommandRequestHeader *requestMsg, // IN currentFileName = fileNameList[fileNum]; -#if defined(VMTOOLS_USE_GLIB) if (regex) { if (!g_regex_match(regex, currentFileName, 0, NULL)) { continue; } } -#endif if (listingSingleFile) { pathName = Util_SafeStrdup(currentFileName); @@ -4797,40 +4878,64 @@ VixToolsImpersonateUser(VixCommandRequestHeader *requestMsg, // IN { VixError err = VIX_OK; char *credentialField; - VixCommandNamePassword *namePasswordStruct; int credentialType; Debug(">%s\n", __FUNCTION__); credentialField = ((char *) requestMsg) - + requestMsg->commonHeader.headerLength + + requestMsg->commonHeader.headerLength + requestMsg->commonHeader.bodyLength; - namePasswordStruct = (VixCommandNamePassword *) credentialField; - credentialField += sizeof(VixCommandNamePassword); credentialType = requestMsg->userCredentialType; - err = VixToolsImpersonateUserImplEx(NULL, - credentialType, - credentialField, - userToken); - if ((VIX_OK != err) - && ((VIX_USER_CREDENTIAL_NAME_PASSWORD_OBFUSCATED == credentialType) - || (VIX_USER_CREDENTIAL_NAME_PASSWORD == credentialType))) { + if (VIX_USER_CREDENTIAL_TICKETED_SESSION == credentialType) { + VixCommandTicketedSession *commandTicketedSession = (VixCommandTicketedSession *) credentialField; + size_t ticketLength = commandTicketedSession->ticketLength; + + credentialField += sizeof(VixCommandTicketedSession); + + if (ticketLength != strlen(credentialField)) { + Debug("%s: Ticket Length Does Not Match Expected\n", __FUNCTION__); + return VIX_E_INVALID_MESSAGE_BODY; + } + + err = VixToolsImpersonateUserImplEx(NULL, + credentialType, + credentialField, + userToken); + + } else if (VIX_USER_CREDENTIAL_SSPI == credentialType) { /* - * Windows does not allow you to login with an empty password. Only - * the console allows this login, which means the console does not - * call the simple public LogonUser api. - * - * See the description for ERROR_ACCOUNT_RESTRICTION. - * For example, the error codes are described here: - * http://support.microsoft.com/kb/155012 + * SSPI currently only supported in ticketed sessions */ + err = VIX_E_NOT_SUPPORTED; + + } else { + VixCommandNamePassword *namePasswordStruct = (VixCommandNamePassword *) credentialField; + credentialField += sizeof(*namePasswordStruct); + + err = VixToolsImpersonateUserImplEx(NULL, + credentialType, + credentialField, + userToken); + if ((VIX_OK != err) + && ((VIX_USER_CREDENTIAL_NAME_PASSWORD_OBFUSCATED == credentialType) + || (VIX_USER_CREDENTIAL_NAME_PASSWORD == credentialType))) { + /* + * Windows does not allow you to login with an empty password. Only + * the console allows this login, which means the console does not + * call the simple public LogonUser api. + * + * See the description for ERROR_ACCOUNT_RESTRICTION. + * For example, the error codes are described here: + * http://support.microsoft.com/kb/155012 + */ #ifdef _WIN32 - if (namePasswordStruct->passwordLength <= 0) { - err = VIX_E_EMPTY_PASSWORD_NOT_ALLOWED_IN_GUEST; - } + if (namePasswordStruct->passwordLength <= 0) { + err = VIX_E_EMPTY_PASSWORD_NOT_ALLOWED_IN_GUEST; + } #endif + } } Debug("<%s\n", __FUNCTION__); @@ -4915,6 +5020,7 @@ VixToolsImpersonateUserImplEx(char const *credentialTypeStr, // IN AuthToken authToken; char *unobfuscatedUserName = NULL; char *unobfuscatedPassword = NULL; + char *ticketID = NULL; if (NULL != credentialTypeStr) { if (!StrUtil_StrToInt(&credentialType, credentialTypeStr)) { @@ -5003,34 +5109,79 @@ VixToolsImpersonateUserImplEx(char const *credentialTypeStr, // IN * by the VMX. If this is something else, then we are talking to a newer * version of the VMX. */ - if ((VIX_USER_CREDENTIAL_NAME_PASSWORD != credentialType) - && (VIX_USER_CREDENTIAL_NAME_PASSWORD_OBFUSCATED != credentialType)) { + if ((VIX_USER_CREDENTIAL_NAME_PASSWORD != credentialType) + && (VIX_USER_CREDENTIAL_NAME_PASSWORD_OBFUSCATED != credentialType) + && (VIX_USER_CREDENTIAL_TICKETED_SESSION != credentialType)) { err = VIX_E_NOT_SUPPORTED; goto abort; } - success = VixMsg_DeObfuscateNamePassword(obfuscatedNamePassword, - &unobfuscatedUserName, - &unobfuscatedPassword); - if (!success) { - err = VIX_E_FAIL; - goto abort; - } + if (VIX_USER_CREDENTIAL_TICKETED_SESSION == credentialType) { +#ifdef _WIN32 + size_t ticketSize; + char *username; - authToken = Auth_AuthenticateUser(unobfuscatedUserName, unobfuscatedPassword); - if (NULL == authToken) { - err = VIX_E_GUEST_USER_PERMISSIONS; + ticketSize = Base64_DecodedLength(obfuscatedNamePassword, + strlen(obfuscatedNamePassword)); + + /* + * Leave room for null terminator + */ + ticketID = Util_SafeMalloc(ticketSize + 1); + + if (!Base64_Decode(obfuscatedNamePassword, + ticketID, + ticketSize, + &ticketSize)) { + Debug("%s: Decode Failed\n", __FUNCTION__); + err = VIX_E_FAIL; + goto abort; + } + + ticketID[ticketSize] = '\0'; + + if (ticketSize != strlen(ticketID)) { + Debug("%s: Invalid Ticket\n", __FUNCTION__); + err = VIX_E_FAIL; + goto abort; + } + + err = VixToolsGetTokenHandleFromTicketID(ticketID, + &username, + &authToken); + + if (VIX_OK != err) { + goto abort; + } + + unobfuscatedUserName = Util_SafeStrdup(username); +#else + err = VIX_E_NOT_SUPPORTED; goto abort; - } - if (NULL != userToken) { - *userToken = (void *) authToken; - } +#endif + } else { + success = VixMsg_DeObfuscateNamePassword(obfuscatedNamePassword, + &unobfuscatedUserName, + &unobfuscatedPassword); + if (!success) { + err = VIX_E_FAIL; + goto abort; + } + authToken = Auth_AuthenticateUser(unobfuscatedUserName, unobfuscatedPassword); + if (NULL == authToken) { + err = VIX_E_GUEST_USER_PERMISSIONS; + goto abort; + } + if (NULL != userToken) { + *userToken = (void *) authToken; + } + } #ifdef _WIN32 success = Impersonate_Do(unobfuscatedUserName, authToken); #else /* - * Use a tools-special version of user impersonation, since + * Use a tools-special version of user impersonation, since * lib/impersonate model isn't quite what we want on linux. */ success = ProcMgr_ImpersonateUserStart(unobfuscatedUserName, authToken); @@ -5045,6 +5196,8 @@ VixToolsImpersonateUserImplEx(char const *credentialTypeStr, // IN abort: free(unobfuscatedUserName); Util_ZeroFreeString(unobfuscatedPassword); + + Util_ZeroFreeString(ticketID); } #else @@ -5733,6 +5886,125 @@ abort: return(err); } // VixToolsListFileSystems +/* + *----------------------------------------------------------------------------- + * + * VixToolsValidateCredentials -- + * + * + * Return value: + * VixError + * + * Side effects: + * None + * + *----------------------------------------------------------------------------- + */ + +VixError +VixToolsValidateCredentials(VixCommandRequestHeader *requestMsg) // IN +{ + VixError err = VIX_OK; + void *userToken = NULL; + Bool impersonatingVMWareUser = FALSE; + + Debug(">%s\n", __FUNCTION__); + + if (NULL == requestMsg) { + ASSERT(0); + err = VIX_E_FAIL; + goto abort; + } + + err = VixToolsImpersonateUser((VixCommandRequestHeader *) requestMsg, + &userToken); + if (VIX_OK != err) { + goto abort; + } + impersonatingVMWareUser = TRUE; + +abort: + if (impersonatingVMWareUser) { + VixToolsUnimpersonateUser(userToken); + } + VixToolsLogoutUser(userToken); + + Debug("<%s\n", __FUNCTION__); + + return err; +} + +/* + *----------------------------------------------------------------------------- + * + * VixToolsAcquireCredentials -- + * + * + * Return value: + * VixError + * + * Side effects: + * None + * + *----------------------------------------------------------------------------- + */ + +VixError +VixToolsAcquireCredentials(VixCommandRequestHeader *requestMsg, // IN + char **result) // OUT +{ + VixError err; + Debug(">%s\n", __FUNCTION__); + +#if !defined(_WIN32) + err = VIX_E_NOT_SUPPORTED; + goto abort; +#else + err = VixToolsAuthenticateWithSSPI(requestMsg, result); + + if (VIX_OK != err) { + Debug("%s: Failed to authenticate with SSPI with error %d\n", __FUNCTION__, err); + goto abort; + } +#endif + +abort: + Debug("<%s\n", __FUNCTION__); + return err; +} + + +/* + *----------------------------------------------------------------------------- + * + * VixToolsReleaseCredentials -- + * + * + * Return value: + * VixError + * + * Side effects: + * None + * + *----------------------------------------------------------------------------- + */ + +VixError +VixToolsReleaseCredentials(VixCommandRequestHeader *requestMsg) // IN +{ + VixError err = VIX_OK; + + Debug(">%s\n", __FUNCTION__); +#if !defined(_WIN32) + err = VIX_E_NOT_SUPPORTED; +#else + err = VixToolsReleaseCredentialsImpl(requestMsg); +#endif + + Debug("<%s\n", __FUNCTION__); + return err; +} + /* *----------------------------------------------------------------------------- @@ -6317,6 +6589,21 @@ VixToolsCheckIfVixCommandEnabled(int opcode, // IN VIX_TOOLS_CONFIG_API_INITIATE_FILE_TRANSFER_TO_GUEST_NAME); break; + case VIX_COMMAND_VALIDATE_CREDENTIALS: + enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, + VIX_TOOLS_CONFIG_API_VALIDATE_CREDENTIALS_NAME); + break; + + case VIX_COMMAND_ACQUIRE_CREDENTIALS: + enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, + VIX_TOOLS_CONFIG_API_ACQUIRE_CREDENTIALS_NAME); + break; + + case VIX_COMMAND_RELEASE_CREDENTIALS: + enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, + VIX_TOOLS_CONFIG_API_RELEASE_CREDENTIALS_NAME); + break; + /* * None of these opcode have a matching config entry (yet), * so they can all share. @@ -6616,10 +6903,31 @@ VixTools_ProcessVixCommand(VixCommandRequestHeader *requestMsg, // IN //////////////////////////////////// case VIX_COMMAND_INITIATE_FILE_TRANSFER_TO_GUEST: err = VixToolsInitiateFileTransferToGuest(requestMsg); + break; + + case VIX_COMMAND_VALIDATE_CREDENTIALS: + err = VixToolsValidateCredentials(requestMsg); + break; + + //////////////////////////////////// + case VIX_COMMAND_ACQUIRE_CREDENTIALS: + err = VixToolsAcquireCredentials(requestMsg, &resultValue); + // resultValue is static. Do not free it. + break; + + //////////////////////////////////// + case VIX_COMMAND_RELEASE_CREDENTIALS: + err = VixToolsReleaseCredentials(requestMsg); break; //////////////////////////////////// default: + /* + * If the opcode is not recognized, tools might be old and the + * VIX client might be sending new opcodes. In such case, + * we should return VIX_E_UNRECOGNIZED_COMMAND_IN_GUEST. + */ + err = VIX_E_UNRECOGNIZED_COMMAND_IN_GUEST; break; } // switch (requestMsg->opCode) diff --git a/open-vm-tools/services/plugins/vix/vixToolsEnvVars.c b/open-vm-tools/services/plugins/vix/vixToolsEnvVars.c new file mode 100644 index 000000000..3bd2a968f --- /dev/null +++ b/open-vm-tools/services/plugins/vix/vixToolsEnvVars.c @@ -0,0 +1,228 @@ +/********************************************************* + * Copyright (C) 2010 VMware, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation version 2.1 and no later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + *********************************************************/ + +/* + * vixToolsEnvVars.c -- + * + * Routines that encapsulate the complexity of dealing with + * environment variables when the process may be impersonating + * a user. + */ + +#include +#ifdef __APPLE__ +#include +#endif + +#include "util.h" +#include "unicode.h" +#include "vixToolsInt.h" + + +#ifndef _WIN32 +extern char **environ; +#endif + +struct VixToolsEnvIterator { +#ifdef _WIN32 + enum { + VIX_TOOLS_ENV_TYPE_ENV_BLOCK = 1, + VIX_TOOLS_ENV_TYPE_ENVIRON, + } envType; + union { + /* Used when envType is VIX_TOOLS_ENV_TYPE_ENV_BLOCK. */ + struct { + wchar_t *envBlock; // Keep the original around to free. + wchar_t *currEnvVar; + } eb; + /* Used when envType is VIX_TOOLS_ENV_TYPE_ENVIRON. */ + wchar_t **environ; + } data; +#else + char **environ; +#endif +}; + + +/* + *----------------------------------------------------------------------------- + * + * VixToolsNewEnvIterator -- + * + * Create a new environment variable iterator for the user + * represented by 'userToken'. + * The resulting VixToolsEnvIterator must be freed using + * VixToolsDestroyEnvIterator. + * + * Results: + * VixError + * + * Side effects: + * None + * + *----------------------------------------------------------------------------- + */ + +VixError +VixToolsNewEnvIterator(void *userToken, // IN + VixToolsEnvIterator **envItr) // OUT +{ + VixError err = VIX_OK; + VixToolsEnvIterator *it = Util_SafeMalloc(sizeof *it); + + if (NULL == envItr) { + err = VIX_E_FAIL; + goto abort; + } + + *envItr = NULL; + +#ifdef _WIN32 + if (PROCESS_CREATOR_USER_TOKEN != userToken) { + /* + * The process is impersonating a user, so retrieve the user's + * environment block instead of using the process's environment. + */ + it->envType = VIX_TOOLS_ENV_TYPE_ENV_BLOCK; + err = VixToolsGetEnvBlock(userToken, &it->data.eb.envBlock); + if (VIX_FAILED(err)) { + goto abort; + } + it->data.eb.currEnvVar = it->data.eb.envBlock; + } else { + /* + * The action is being performed as the user running the process + * so the process's environment is fine. + * TODO: Is this totally equivilent to the behavior when impersonated? + * Would fetching the environment block include changes to the user's + * or system's environment made after the process is running? + */ + it->envType = VIX_TOOLS_ENV_TYPE_ENVIRON; + it->data.environ = _wenviron; + } +#elif defined(__APPLE__) + it->environ = *_NSGetEnviron(); +#elif defined(__FreeBSD__) + /* + * Looking at /build/toolchain/bsd32/freebsd-6.3/usr/include/stand.h, + * environ is a pointer to a doubly linked list of structs. I guess they + * just want to be different. Anyway, this is something that needs + * work if we want to support FreeBSD. + */ + err = VIX_E_NOT_SUPPORTED; + goto abort; +#else + it->environ = environ; +#endif + *envItr = it; +abort: + if (VIX_FAILED(err)) { + free(it); + } + + return err; +} + + +/* + *----------------------------------------------------------------------------- + * + * VixToolsGetNextEnvVar -- + * + * Get the next envariable variable pair in the form NAME=VALUE. + * + * Results: + * A heap-allocated UTF-8 string, or NULL when the iterator has + * reached the end. + * + * Side effects: + * Advances the iterator. + * + *----------------------------------------------------------------------------- + */ + +char * +VixToolsGetNextEnvVar(VixToolsEnvIterator *envItr) // IN +{ + char *envVar; + + if (NULL == envItr) { + return NULL; + } + +#ifdef _WIN32 + if (VIX_TOOLS_ENV_TYPE_ENV_BLOCK == envItr->envType) { + if (L'\0' == envItr->data.eb.currEnvVar[0]) { + envVar = NULL; + } else { + envVar = Unicode_AllocWithUTF16(envItr->data.eb.currEnvVar); + while(*envItr->data.eb.currEnvVar++); + } + } else if (VIX_TOOLS_ENV_TYPE_ENVIRON == envItr->envType) { + if (NULL == *envItr->data.environ) { + envVar = NULL; + } else { + Unicode_AllocWithUTF16(*envItr->data.environ); + envItr->data.environ++; + } + } else { + /* Is someone using uninitialized memory? */ + NOT_IMPLEMENTED(); + } +#else + if (NULL == *envItr->environ) { + envVar = NULL; + } else { + envVar = Unicode_Alloc(*envItr->environ, STRING_ENCODING_DEFAULT); + envItr->environ++; + } +#endif + return envVar; +} + + +/* + *----------------------------------------------------------------------------- + * + * VixToolsDestroyEnvIterator -- + * + * Free()s any memory associated with the VixToolsEnvIterator. + * + * Results: + * None + * + * Side effects: + * None + * + *----------------------------------------------------------------------------- + */ + +void +VixToolsDestroyEnvIterator(VixToolsEnvIterator *envItr) // IN +{ + if (NULL != envItr) { +#ifdef _WIN32 + if (VIX_TOOLS_ENV_TYPE_ENV_BLOCK == envItr->envType) { + if (NULL != envItr->data.eb.envBlock) { + VixToolsDestroyEnvironmentBlock(envItr->data.eb.envBlock); + } + } +#endif + free(envItr); + } +} diff --git a/open-vm-tools/services/plugins/vix/vixToolsInt.h b/open-vm-tools/services/plugins/vix/vixToolsInt.h index 7b452247e..d0bb085a9 100644 --- a/open-vm-tools/services/plugins/vix/vixToolsInt.h +++ b/open-vm-tools/services/plugins/vix/vixToolsInt.h @@ -28,13 +28,54 @@ #include "vmware.h" #include "vix.h" +#include "vixCommands.h" +#define PROCESS_CREATOR_USER_TOKEN ((void *)1) + +#ifdef _WIN32 + +#define VIX_TOOLS_MAX_SSPI_SESSIONS 50 +#define VIX_TOOLS_MAX_TICKETED_SESSIONS 50 + +#endif + + +typedef struct VixToolsEnvIterator VixToolsEnvIterator; + +VixError VixToolsNewEnvIterator(void *userToken, VixToolsEnvIterator **envItr); + +char *VixToolsGetNextEnvVar(VixToolsEnvIterator *envItr); + +void VixToolsDestroyEnvIterator(VixToolsEnvIterator *envItr); + #ifdef _WIN32 + +VixError VixToolsGetEnvBlock(void *userToken, + wchar_t **envBlock); + +Bool VixToolsDestroyEnvironmentBlock(wchar_t *envBlock); + VixError VixToolsGetUserTmpDir(void *userToken, char **tmpDirPath); Bool VixToolsUserIsMemberOfAdministratorGroup(VixCommandRequestHeader *requestMsg); + +void VixToolsInitSspiSessionList(const unsigned int maxSessions); +void VixToolsDeinitSspiSessionList(); +void VixToolsInitTicketedSessionList(const unsigned int maxSessions); +void VixToolsDeinitTicketedSessionList(); + + +VixError VixToolsAuthenticateWithSSPI(VixCommandRequestHeader *requestMsg, + char **resultBuffer); + +VixError VixToolsGetTokenHandleFromTicketID(const char *ticketID, + char **username, + HANDLE *hToken); + +VixError VixToolsReleaseCredentialsImpl(VixCommandRequestHeader *requestMsg); + #endif // _WIN32