]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Internal branch sync. Included in this change:
authorVMware, Inc <>
Mon, 20 Sep 2010 17:53:35 +0000 (10:53 -0700)
committerMarcelo Vanzin <mvanzin@vmware.com>
Mon, 20 Sep 2010 17:53:35 +0000 (10:53 -0700)
. 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 <mvanzin@vmware.com>
16 files changed:
open-vm-tools/lib/file/file.c
open-vm-tools/lib/file/filePosix.c
open-vm-tools/lib/foundryMsg/foundryMsg.c
open-vm-tools/lib/foundryMsg/foundryPropertyListCommon.c
open-vm-tools/lib/include/file.h
open-vm-tools/lib/include/unityCommon.h
open-vm-tools/lib/include/vix.h
open-vm-tools/lib/include/vixCommands.h
open-vm-tools/lib/include/vixOpenSource.h
open-vm-tools/modules/shared/vmxnet/vmxnet3_defs.h
open-vm-tools/services/plugins/dndcp/pointer.cpp
open-vm-tools/services/plugins/unity/unity.x
open-vm-tools/services/plugins/vix/Makefile.am
open-vm-tools/services/plugins/vix/vixTools.c
open-vm-tools/services/plugins/vix/vixToolsEnvVars.c [new file with mode: 0644]
open-vm-tools/services/plugins/vix/vixToolsInt.h

index 3b830648625d44d6f0c0e8916e7890ead8dbe559..c23f0c75db4952ab4a3a15af925015d076ae99ef 100644 (file)
@@ -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 */
index 4a964739503e8341e7750bea0a3f364002edfa9f..1cf8018cc8eb205a599f404c6d28756793e3cd0d 100644 (file)
@@ -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);
+}
+
+
 /*
  *----------------------------------------------------------------------
  *
index aacb80b08cca7c08d6c6daa807a55913a2ecbd6a..8a8a80675dd37a77d54018ecb0aad79699117c80 100644 (file)
@@ -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;
    }
index b00612d14b181a78b372305cd3380328bff29cea..52561e6401cb535f64e2bfbe5dfd137967bd1b65 100644 (file)
@@ -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:
index 00a168a7c33354fbc1eb39a6cb39b41b4573304e..e07b750f08886eb3fd60d31d1aec032bcf2b60a6 100644 (file)
@@ -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);
index a44a51379ea2061f4efa62c7941d7a198e4a02c3..510f1afd69001ab0439120719d8de48664bb3b69 100644 (file)
@@ -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 <tt>{1,2}</tt> 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 <tt>{1,2}</tt> 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.
+
    @}
 */
 
index 38a3e4978ef95957847c903f9eed902414279a94..abaa63d7af77888db0163bebac6766c4a6e8e755 100644 (file)
@@ -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,
index 926bf2cc0c9b2ff859a2ea4d67469c4128ab2dae..a504edb4cbbbc34477d5221f6c4c064f988cb480 100644 (file)
@@ -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,
index 7dc0380108433dab615bd8cb00204a72d6af22cd..f94a55560274766a7c4afbc4c05128e95104b7d7 100644 (file)
@@ -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,
index 04d7716ae71259b173832e7c6dc504b47a27f5c9..23fa8f4d91e6046cfdde777cb6e3c3061d9dc338 100644 (file)
 #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
 
index 8a4f99b25dd9e810da25d5f7c1675e118b53384d..e2217f46c59f40cbc1e652884392b0e8ba0fedef 100644 (file)
@@ -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__);
+   }
 }
index e9cf3aaa3193d334d290a2a8b74d60fb95a1f57d..7484cecb8206bbe1cfe480987182b0cc45896110 100644 (file)
  */
 
 /*
- * 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 */
 };
index cc7d7a94512a2a7a1324a57dfb6c0c69f7b9b1d3..d5a021feda1b949c6199ad625e8bbe582f57b369 100644 (file)
@@ -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
index 29a3896db874700ada90bee656b64353a1daf77e..442a0b9c2f237f086b22d2af690af570a3f50591 100644 (file)
 
 /*
  * 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()
  *
 
 #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<ev>%s</ev>",
-                                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
+ *      <ev>NAME=VALUE</ev> 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<ev>%s</ev>", 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
                                       "<user>%s</user><start>%d</start>"
                                       "<eCode>%d</eCode><eTime>%d</eTime>"
                                       "</proc>",
-                                      epList->name,
+                                      epList->fullCommandLine,
                                       epList->pid,
                                       epList->user,
                                       (int) epList->startTime,
@@ -3423,7 +3517,7 @@ VixToolsListProcessesEx(VixCommandRequestHeader *requestMsg, // IN
                                 "<user>%s</user><start>%d</start>"
                                 "<eCode>%d</eCode><eTime>%d</eTime>"
                                 "</proc>",
-                                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 (file)
index 0000000..3bd2a96
--- /dev/null
@@ -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 <stdlib.h>
+#ifdef __APPLE__
+#include <crt_externs.h>
+#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);
+   }
+}
index 7b452247efb896d9ed4a84fff2070f17db3c77ba..d0bb085a9d4e5c7eacfd3ea970afb0c8430129b6 100644 (file)
 
 #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