. 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>
{
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 */
/*
*----------------------------------------------------------------------
*
- * 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) {
}
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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);
+}
+
+
/*
*----------------------------------------------------------------------
*
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),
+
};
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
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;
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;
}
////////////////////////////////////////////////////////
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:
////////////////////////////////////////////////////////
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:
int *intPtr;
Bool *boolPtr;
int64 *int64Ptr;
- void **ptrPtr;
unsigned char* blobPtr;
int *propertyIDPtr;
int *lengthPtr;
////////////////////////////////////////////////////////
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:
EXTERN Bool File_SupportsZeroedThick(ConstUnicode pathName);
+EXTERN Bool File_SupportsMultiWriter(ConstUnicode pathName);
+
EXTERN Bool File_Exists(ConstUnicode pathName);
EXTERN int File_Unlink(ConstUnicode pathName);
#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.
@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.
+
@}
*/
@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.
+
@}
*/
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,
#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__"
#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;
/*
* **********************************************************
typedef
#include "vmware_pack_begin.h"
struct VixMsgVProbeLoadRequest {
- VixCommandResponseHeader header;
+ VixCommandRequestHeader header;
char string[1]; /* variable length */
}
#include "vmware_pack_end.h"
#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;
/*
* **********************************************************
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.
*
* 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,
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,
#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
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__);
+ }
}
*/
/*
- * 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
};
/*
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 */
};
libvix_la_SOURCES += foundryToolsDaemon.c
libvix_la_SOURCES += vixPlugin.c
libvix_la_SOURCES += vixTools.c
-
+libvix_la_SOURCES += vixToolsEnvVars.c
/*
* 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
/*
* 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;
static VixError VixToolsReadEnvVariables(VixCommandRequestHeader *requestMsg,
char **result);
+static VixError VixToolsGetAllEnvVarsForUser(void *userToken, char **result);
+
static VixError VixToolsWriteVariable(VixCommandRequestHeader *requestMsg);
static VixError VixToolsListProcesses(VixCommandRequestHeader *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,
#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. */
int64 pid;
static char resultBuffer[32];
-
runProgramRequest = (VixMsgRunProgramRequest *) requestMsg;
commandLine = ((char *) runProgramRequest) + sizeof(*runProgramRequest);
if (0 == *commandLine) {
&pid);
if (VIX_OK == err) {
+
/*
* Save off the program so ListProcessesEx can find it.
*
* 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);
* 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) {
* 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) {
* and endTime.
*/
exitState = Util_SafeMalloc(sizeof(VixToolsExitedProgramState));
- exitState->name = NULL;
+ exitState->fullCommandLine = NULL;
exitState->user = NULL;
exitState->pid = pid;
exitState->startTime = 0;
return;
}
- free(exitState->name);
+ free(exitState->fullCommandLine);
free(exitState->user);
free(exitState);
*
* Helper function for fetching the API config setting.
*
+ * If the varName is NULL, only the global switch is checked.
+ *
* Return value:
* Bool
*
/*
* 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,
}
/*
- * 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,
/*
* 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;
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;
+}
/*
* 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;
}
"<user>%s</user><start>%d</start>"
"<eCode>%d</eCode><eTime>%d</eTime>"
"</proc>",
- epList->name,
+ epList->fullCommandLine,
epList->pid,
epList->user,
(int) epList->startTime,
"<user>%s</user><start>%d</start>"
"<eCode>%d</eCode><eTime>%d</eTime>"
"</proc>",
- epList->name,
+ epList->fullCommandLine,
epList->pid,
epList->user,
(int) epList->startTime,
int maxResults = 0;
int count = 0;
int numResults;
-#if defined(VMTOOLS_USE_GLIB)
GRegex *regex = NULL;
GError *gerr = NULL;
-#endif
ASSERT(NULL != requestMsg);
__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",
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)) {
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
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);
{
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__);
AuthToken authToken;
char *unobfuscatedUserName = NULL;
char *unobfuscatedPassword = NULL;
+ char *ticketID = NULL;
if (NULL != credentialTypeStr) {
if (!StrUtil_StrToInt(&credentialType, credentialTypeStr)) {
* 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);
abort:
free(unobfuscatedUserName);
Util_ZeroFreeString(unobfuscatedPassword);
+
+ Util_ZeroFreeString(ticketID);
}
#else
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;
+}
+
/*
*-----------------------------------------------------------------------------
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.
////////////////////////////////////
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)
--- /dev/null
+/*********************************************************
+ * 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);
+ }
+}
#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