~ubuntu-branches/ubuntu/quantal/open-vm-tools/quantal-201210021442

« back to all changes in this revision

Viewing changes to services/plugins/vix/vixTools.c

  • Committer: Package Import Robot
  • Author(s): Nate Muench
  • Date: 2012-01-23 16:09:45 UTC
  • mfrom: (1.4.6) (2.4.26 sid)
  • Revision ID: package-import@ubuntu.com-20120123160945-b6s0r1vkcovucpf3
Tags: 2011.12.20-562307-0ubuntu1
* Merge latest upstream git tag. Fixes building on Precise
  (LP: #898289, LP: #905612)

* Items merged from Debian unstable:
  - debian/control:
    + open-vm-tools recommends open-vm-dkms. (LP: #598933)
    + open-vm-tools now suggests open-vm-toolbox. (LP: #604998)
  (From 2011.08.21-471295-1 release)
  - Updating maintainer and uploaders fields.
  - Removing vcs fields.
  - Removing references to Daniel's old email address.
  - Updating years in copyright file.
  - Updating to standards version 3.9.2.
  - Updating to debhelper version 8.
  - Switching to source format 3.0 (quilt).
  - Removing manual chrpath setting.
  - Removing exclusion from plugins from debhelper shlibs.
  - Rediffing kvers.patch.
  (From 2011.09.23-491607-1 release)
  - Marking binary architecture-dependend packages as linux and kfreebsd
  only.
  - Removing liburiparser-dev from build-depends as upstream dropped
  unity support.
  - Building with libproc-dev on amd64 again.
  - Dropping disabling of dnet support.
  (From 2011.09.23-491607-2 release)
  - Adding doxygen to build-depends for api documentation.
  - Adding libcunit1-dev to build-depends for test suites.
  - Minimizing rules file.
  - Adding open-vm-tools-dev package, containing only the api
    documentation for now.
  (From 2011.09.23-491607-3 release)
  - Sorting overrides in rules alphabetically.
  - Compacting copyright file.
  - Adding udev rule to set timeout for vmware scsi devices
  (From 2011.12.20-562307-1 release)
  - Adding patch to correct typo in upstreams dkms configuration

* Remaining Changes:
  - Remove Stable part of version numbering.
  - debian folder:
    + Re-added open-vm-dkms.postinst & open-vm-dkms.prerm.
      * Allows dkms modules to compile upon installation.
  - debian/control:
    + Re-add open-vm-source and make into a transitional package
      for open-vm-toolbox.
    + Return dependancies that were moved to open-vm-tools back to
      open-vm-toolbox.
  - debian/rules and debian/open-vm-toolbox.lintian-overrides:
    + Make vmware-user-suid-wrapper suid-root
  - debian/rules:
    + Added CFLAGS field with -Wno-deprecated-declarations
      * Will suppress issues with glib 2.31 or later.
    + Add line to copy vmware-xdg-detect-de into place.
    + Install vmware-user.desktop through toolbox package.
  - debian/open-vm-tools.init:
    + Re-add 'modprobe [-r] vmblock'.
    + Add 'modprobe [-r] vmxnet'.
      * Incase it's not loaded during boot.
    + Remove and re-add pcnet32 module
      * Will be done before (remove) and after (readd) vmxnet module
        is added.
      * If vmxnet doesn't exist (aka modules fail to build), pcnet32 can be
        still used for network connectivity.
      * Workaround until a better fix can be done.
  - Re-add gnome-session to debian/local/xautostart.conf
  - Manpages removed (from debian/manpages):
    + vmmemctl.9
    + vmxnet3.9
    + Remove references to manpages that have been removed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
#include <unistd.h>
55
55
#endif
56
56
 
57
 
#ifdef sun
 
57
#if defined(sun) || defined(__FreeBSD__) || defined(__APPLE__)
58
58
#include <sys/stat.h>
59
59
#endif
60
60
 
69
69
#include "timeutil.h"
70
70
#include "vm_version.h"
71
71
#include "message.h"
 
72
#include "dynarray.h"
72
73
 
73
74
#define G_LOG_DOMAIN  "vix"
74
75
#define Debug         g_debug
102
103
#include "netutil.h"
103
104
#endif
104
105
 
105
 
/* Only Windows and Linux use impersonation functions. */
106
 
#if !defined(__FreeBSD__) && !defined(sun)
107
106
#include "impersonate.h"
108
 
#endif
109
 
 
110
107
#include "vixOpenSource.h"
111
108
#include "vixToolsInt.h"
112
109
 
246
243
typedef struct VixToolsCachedListProcessesResult {
247
244
   char *resultBuffer;
248
245
   size_t resultBufferLen;
 
246
   int key;
249
247
#ifdef _WIN32
250
248
   wchar_t *userName;
251
249
#else
289
287
 */
290
288
static HashTable *userEnvironmentTable = NULL;
291
289
#endif
292
 
#if !defined(__FreeBSD__)
293
290
static HgfsServerMgrData gVixHgfsBkdrConn;
294
 
#endif
 
291
 
 
292
#define SECONDS_BETWEEN_INVALIDATING_HGFS_SESSIONS    120
295
293
 
296
294
static VixError VixToolsGetFileInfo(VixCommandRequestHeader *requestMsg,
297
295
                                    char **result);
300
298
 
301
299
static gboolean VixToolsMonitorAsyncProc(void *clientData);
302
300
static gboolean VixToolsMonitorStartProgram(void *clientData);
 
301
static void VixToolsRegisterHgfsSessionInvalidator(void *clientData);
 
302
static gboolean VixToolsInvalidateInactiveHGFSSessions(void *clientData);
 
303
 
 
304
static GSource *gHgfsSessionInvalidatorTimer = NULL;
 
305
static guint gHgfsSessionInvalidatorTimerId;
303
306
 
304
307
static void VixToolsPrintFileInfo(const char *filePathName,
305
308
                                  char *fileName,
338
341
                                          "<ct>%"FMT64"u</ct>"
339
342
                                          "<at>%"FMT64"u</at>"
340
343
                                          "</fxi>";
341
 
#elif defined(linux) || defined(sun)
 
344
#else
342
345
static const char *fileExtendedInfoLinuxFormatString = "<fxi>"
343
346
                                          "<Name>%s</Name>"
344
347
                                          "<ft>%d</ft>"
442
445
static VixError VixToolsCheckUserAccount(VixCommandRequestHeader *requestMsg);
443
446
 
444
447
static VixError VixToolsProcessHgfsPacket(VixCommandHgfsSendPacket *requestMsg,
 
448
                                          GMainLoop *eventQueue,
445
449
                                          char **result,
446
450
                                          size_t *resultValueResult);
447
451
 
496
500
                                              char const *obfuscatedNamePassword,
497
501
                                              void **userToken);
498
502
 
499
 
#if defined(_WIN32) || defined(linux) || defined(sun)
500
503
static VixError VixToolsDoesUsernameMatchCurrentUser(const char *username);
501
 
#endif
502
504
 
503
505
static Bool VixToolsPidRefersToThisProcess(ProcMgr_Pid pid);
504
506
 
564
566
   VixToolsInitSspiSessionList(VIX_TOOLS_MAX_SSPI_SESSIONS);
565
567
   VixToolsInitTicketedSessionList(VIX_TOOLS_MAX_TICKETED_SESSIONS);
566
568
#endif
567
 
#if !defined(__FreeBSD__)
568
569
   /* Register a straight through connection with the Hgfs server. */
569
570
   HgfsServerManager_DataInit(&gVixHgfsBkdrConn,
570
571
                              VIX_BACKDOORCOMMAND_COMMAND,
571
572
                              NULL,    // no RPC registration
572
573
                              NULL);   // rpc callback
573
574
   HgfsServerManager_Register(&gVixHgfsBkdrConn);
574
 
#endif
575
575
 
576
576
   listProcessesResultsTable = g_hash_table_new_full(g_int_hash, g_int_equal,
577
 
                                                     free,
 
577
                                                     NULL,
578
578
                                                     VixToolsFreeCachedResult);
579
579
 
580
580
 
600
600
void
601
601
VixTools_Uninitialize(void) // IN
602
602
{
603
 
#if !defined(__FreeBSD__)
 
603
   if (NULL != gHgfsSessionInvalidatorTimer) {
 
604
      g_source_remove(gHgfsSessionInvalidatorTimerId);
 
605
      g_source_unref(gHgfsSessionInvalidatorTimer);
 
606
      gHgfsSessionInvalidatorTimer = NULL;
 
607
      gHgfsSessionInvalidatorTimerId = 0;
 
608
      Log("%s: HGFS session Invalidator detached\n",
 
609
          __FUNCTION__);
 
610
   }
 
611
 
604
612
   HgfsServerManager_Unregister(&gVixHgfsBkdrConn);
605
 
#endif
606
613
}
607
614
 
608
615
 
820
827
 * VixTools_SetRunProgramCallback --
821
828
 *
822
829
 * Register a callback that reports when a program has completed.
823
 
 * Different clients of this library will use different IPC mechanisms for 
 
830
 * Different clients of this library will use different IPC mechanisms for
824
831
 * sending this message. For example, it may use the backdoor or a socket.
825
832
 * Different sockets may use different message protocols, such as the backdoor-on-a-socket
826
833
 * or the Foundry network message.
907
914
   if (runProgramRequest->runProgramOptions & VIX_RUNPROGRAM_RUN_AS_LOCAL_SYSTEM) {
908
915
      if (!VixToolsUserIsMemberOfAdministratorGroup(requestMsg)) {
909
916
         err = VIX_E_GUEST_USER_PERMISSIONS;
910
 
         goto abort; 
 
917
         goto abort;
911
918
      }
912
919
      userToken = PROCESS_CREATOR_USER_TOKEN;
913
920
   }
914
921
#endif
915
 
  
 
922
 
916
923
   if (NULL == userToken) {
917
924
      err = VixToolsImpersonateUser(requestMsg, &userToken);
918
925
      if (VIX_OK != err) {
928
935
                                userToken,
929
936
                                eventQueue,
930
937
                                &pid);
931
 
   
 
938
 
932
939
abort:
933
940
   if (impersonatingVMWareUser) {
934
941
      VixToolsUnimpersonateUser(userToken);
1196
1203
    * On linux, we run the program by exec'ing /bin/sh, and that does not
1197
1204
    * return a clear error code indicating that the program does not exist
1198
1205
    * or cannot be executed.
1199
 
    * This is a common and user-correctable error, however, so we want to 
 
1206
    * This is a common and user-correctable error, however, so we want to
1200
1207
    * check for it and return a specific error code in this case.
1201
1208
    *
1202
1209
    */
1203
1210
 
1204
1211
   programExists = File_Exists(startProgramFileName);
1205
 
   programIsExecutable = 
1206
 
      (FileIO_Access(startProgramFileName, FILEIO_ACCESS_EXEC) == 
 
1212
   programIsExecutable =
 
1213
      (FileIO_Access(startProgramFileName, FILEIO_ACCESS_EXEC) ==
1207
1214
                                                       FILEIO_SUCCESS);
1208
1215
 
1209
1216
   free(tempCommandLine);
1275
1282
   si.dwFlags = STARTF_USESHOWWINDOW;
1276
1283
   si.wShowWindow = (VIX_RUNPROGRAM_ACTIVATE_WINDOW & runProgramOptions)
1277
1284
                     ? SW_SHOWNORMAL : SW_MINIMIZE;
1278
 
#else
 
1285
#elif !defined(__FreeBSD__)
1279
1286
   procArgs.envp = VixToolsEnvironmentTableToEnvp(userEnvironmentTable);
1280
1287
#endif
1281
1288
 
1438
1445
    * For non-Windows, we use the user's $HOME if workingDir isn't supplied.
1439
1446
    */
1440
1447
   if (NULL == workingDir) {
1441
 
#if defined(linux) || defined(sun)
 
1448
#if defined(linux) || defined(sun) || defined(__FreeBSD__) || defined(__APPLE__)
1442
1449
      char *username = NULL;
1443
1450
 
1444
1451
      if (!ProcMgr_GetImpersonatedUserInfo(&username, &workingDirectory)) {
1675
1682
 
1676
1683
 
1677
1684
/*
 
1685
 *----------------------------------------------------------------------------
 
1686
 *
 
1687
 * VixToolsInvalidateInactiveHGFSSessions --
 
1688
 *
 
1689
 *    Send a request to HGFS server to invalidate inactive sessions.
 
1690
 *    Registers a timer to call the invalidator.
 
1691
 *
 
1692
 * Return value:
 
1693
 *    TRUE if the timer needs to be re-registerd.
 
1694
 *    FALSE if the timer needs to be deleted.
 
1695
 *
 
1696
 * Side effects:
 
1697
 *    None
 
1698
 *
 
1699
 *----------------------------------------------------------------------------
 
1700
 */
 
1701
 
 
1702
static gboolean
 
1703
VixToolsInvalidateInactiveHGFSSessions(void *clientData)   // IN:
 
1704
{
 
1705
   if (HgfsServerManager_InvalidateInactiveSessions(&gVixHgfsBkdrConn) > 0) {
 
1706
      /*
 
1707
       * There are still active sessions, so keep the periodic timer
 
1708
       * registered.
 
1709
       */
 
1710
      return TRUE;
 
1711
   } else {
 
1712
 
 
1713
      Log("%s: HGFS session Invalidator is successfully detached\n",
 
1714
          __FUNCTION__);
 
1715
 
 
1716
      g_source_unref(gHgfsSessionInvalidatorTimer);
 
1717
      gHgfsSessionInvalidatorTimer = NULL;
 
1718
      gHgfsSessionInvalidatorTimerId = 0;
 
1719
      return FALSE;
 
1720
   }
 
1721
}
 
1722
 
 
1723
 
 
1724
/*
 
1725
 *----------------------------------------------------------------------------
 
1726
 *
 
1727
 * VixToolsRegisterHgfsSessionInvalidator --
 
1728
 *
 
1729
 *    Check bug 783263 for more details. This function is designed to
 
1730
 *    cleanup any hgfs state left by remote clients that got
 
1731
 *    disconnected abruptly during a file copy process.
 
1732
 *
 
1733
 *    If there is a timer already registered, then this function doesn't
 
1734
 *    do anything.
 
1735
 *
 
1736
 * Return value:
 
1737
 *    None.
 
1738
 *
 
1739
 * Side effects:
 
1740
 *    None.
 
1741
 *
 
1742
 *----------------------------------------------------------------------------
 
1743
 */
 
1744
 
 
1745
static void
 
1746
VixToolsRegisterHgfsSessionInvalidator(void *clientData)    // IN:
 
1747
{
 
1748
   ASSERT(clientData);
 
1749
 
 
1750
   if (NULL != gHgfsSessionInvalidatorTimer) {
 
1751
      return;
 
1752
   }
 
1753
 
 
1754
   gHgfsSessionInvalidatorTimer =
 
1755
         g_timeout_source_new(SECONDS_BETWEEN_INVALIDATING_HGFS_SESSIONS * 1000);
 
1756
 
 
1757
   g_source_set_callback(gHgfsSessionInvalidatorTimer,
 
1758
                         VixToolsInvalidateInactiveHGFSSessions,
 
1759
                         NULL,
 
1760
                         NULL);
 
1761
 
 
1762
   gHgfsSessionInvalidatorTimerId =
 
1763
         g_source_attach(gHgfsSessionInvalidatorTimer,
 
1764
                         g_main_loop_get_context((GMainLoop *) clientData));
 
1765
 
 
1766
   Log("%s: HGFS session Invalidator registered\n",
 
1767
       __FUNCTION__);
 
1768
}
 
1769
 
 
1770
 
 
1771
/*
1678
1772
 *-----------------------------------------------------------------------------
1679
1773
 *
1680
1774
 * VixToolsMonitorStartProgram --
1988
2082
   const char *powerOnScript = NULL;
1989
2083
   const char *resumeScript = NULL;
1990
2084
   const char *suspendScript = NULL;
1991
 
   char osNameFull[GUESTINFO_MAX_VALUE_SIZE];
1992
 
   char osName[GUESTINFO_MAX_VALUE_SIZE];
 
2085
   char *osName = NULL;
 
2086
   char *osNameFull = NULL;
1993
2087
   Bool foundHostName;
1994
2088
   char *tempDir = NULL;
1995
2089
   int wordSize = 32;
1996
2090
 
1997
2091
 
1998
2092
   VixPropertyList_Initialize(&propList);
1999
 
   
 
2093
 
2000
2094
   /*
2001
2095
    * Collect some values about the host.
2002
2096
    *
2023
2117
#else
2024
2118
   osFamily = GUEST_OS_FAMILY_LINUX;
2025
2119
#endif
2026
 
   if (!(Hostinfo_GetOSName(sizeof osNameFull, sizeof osName, osNameFull,
2027
 
                            osName))) {
2028
 
      osNameFull[0] = 0;
2029
 
      osName[0] = 0;
2030
 
   }
 
2120
 
 
2121
   osNameFull = Hostinfo_GetOSName();
 
2122
   if (osNameFull == NULL) {
 
2123
      osNameFull = Util_SafeStrdup("");
 
2124
   }
 
2125
 
 
2126
   osName = Hostinfo_GetOSGuestString();
 
2127
   if (osName == NULL) {
 
2128
      osName = Util_SafeStrdup("");
 
2129
   }
 
2130
 
2031
2131
   wordSize = Hostinfo_GetSystemBitness();
2032
2132
   if (wordSize <= 0) {
2033
2133
      wordSize = 32;
2039
2139
   packageList = "";
2040
2140
 
2041
2141
   if (confDictRef != NULL) {
2042
 
      powerOffScript = g_key_file_get_string(confDictRef, "powerops", 
 
2142
      powerOffScript = g_key_file_get_string(confDictRef, "powerops",
2043
2143
                                             CONFNAME_POWEROFFSCRIPT, NULL);
2044
2144
      powerOnScript = g_key_file_get_string(confDictRef, "powerops",
2045
2145
                                            CONFNAME_POWERONSCRIPT, NULL);
2180
2280
   free(guestName);
2181
2281
   free(serializedBuffer);
2182
2282
   free(tempDir);
 
2283
   free(osName);
 
2284
   free(osNameFull);
2183
2285
#else
2184
2286
   /*
2185
 
    * FreeBSD.  Return an empty serialized property list.
 
2287
    * FreeBSD. We do not require all the properties above.
 
2288
    * We only Support VMODL Guest Ops for now (Bug 228398).
2186
2289
    */
2187
2290
 
2188
2291
   VixPropertyList_Initialize(&propList);
2189
2292
 
 
2293
   /* InitiateFileTransfer(From|To)Guest operations require this */
 
2294
   err = VixPropertyList_SetInteger(&propList,
 
2295
                                    VIX_PROPERTY_GUEST_OS_FAMILY,
 
2296
                                    GUEST_OS_FAMILY_LINUX);
 
2297
   if (VIX_OK != err) {
 
2298
      goto abort;
 
2299
   }
2190
2300
   /* Retrieve the share folders UNC root path. */
2191
2301
   err = VixToolsSetSharedFoldersProperties(&propList);
2192
 
 
 
2302
   if (VIX_OK != err) {
 
2303
      goto abort;
 
2304
   }
2193
2305
   /*
2194
2306
    * Set up the API status properties.
2195
 
    * This is done even though none are currently supported, so
2196
 
    * that the client side can tell the difference between OutOfDate
2197
 
    * tools and NotSupported.
 
2307
    * This is done so that the client side can tell the
 
2308
    * difference between OutOfDate tools and NotSupported.
2198
2309
    */
2199
2310
   err = VixToolsSetAPIEnabledProperties(&propList, confDictRef);
2200
2311
   if (VIX_OK != err) {
2219
2330
   VixPropertyList_RemoveAllWithoutHandles(&propList);
2220
2331
   free(serializedBuffer);
2221
2332
#endif // __FreeBSD__
2222
 
   
 
2333
 
2223
2334
   return err;
2224
2335
} // VixTools_GetToolsPropertiesImpl
2225
2336
 
2355
2466
VixToolsComputeEnabledProperty(GKeyFile *confDictRef,            // IN
2356
2467
                               const char *varName)              // IN
2357
2468
{
2358
 
#if defined(_WIN32) || defined(linux) || defined(sun)
2359
2469
   return VixToolsGetAPIDisabledFromConf(confDictRef, varName);
2360
 
#else
2361
 
   return FALSE;
2362
 
#endif
2363
2470
}
2364
2471
 
2365
2472
 
2829
2936
       * if pathName is an invalid symbolic link, we still want to delete it.
2830
2937
       */
2831
2938
      if (FALSE == File_IsSymLink(pathName)) {
2832
 
         if (!(File_Exists(pathName))) {      
 
2939
         if (!(File_Exists(pathName))) {
2833
2940
            err = VIX_E_FILE_NOT_FOUND;
2834
2941
            goto abort;
2835
2942
         }
3383
3490
   }
3384
3491
 
3385
3492
   readRequest = (VixMsgReadEnvironmentVariablesRequest *) requestMsg;
3386
 
 
3387
3493
   err = VixToolsImpersonateUser(requestMsg, &userToken);
3388
3494
   if (VIX_OK != err) {
3389
3495
      goto abort;
3458
3564
   char *resultLocal = Util_SafeStrdup("");  // makes the loop cleaner.
3459
3565
   VixToolsUserEnvironment *env;
3460
3566
 
 
3567
#ifdef __FreeBSD__
 
3568
   if (NULL == userEnvironmentTable) {
 
3569
      err = VIX_E_FAIL;
 
3570
      free(resultLocal);
 
3571
      return err;
 
3572
   }
 
3573
#endif
 
3574
 
3461
3575
   err = VixToolsNewUserEnvironment(userToken, &env);
3462
3576
   if (VIX_FAILED(err)) {
3463
3577
      env = NULL;
3467
3581
   for (i = 0; i < numNames; i++) {
3468
3582
      char *value;
3469
3583
 
 
3584
#ifdef __FreeBSD__
 
3585
      /*
 
3586
       * We should check the original envp for all vars except
 
3587
       * a few whitelisted ones that we set/unset on impersonate
 
3588
       * user start/stop. for them we need to do getenv()
 
3589
       */
 
3590
      if (!strcmp(names, "USER") ||
 
3591
          !strcmp(names, "HOME") ||
 
3592
          !strcmp(names, "SHELL")) {
 
3593
         value = VixToolsGetEnvFromUserEnvironment(env, names);
 
3594
      }
 
3595
      else {
 
3596
         if (HashTable_Lookup(userEnvironmentTable,
 
3597
                              names, (void **) &value)) {
 
3598
            value = Util_SafeStrdup(value);
 
3599
         } else {
 
3600
            value = Util_SafeStrdup("");
 
3601
         }
 
3602
      }
 
3603
#else
3470
3604
      value = VixToolsGetEnvFromUserEnvironment(env, names);
 
3605
#endif
 
3606
 
3471
3607
      if (NULL != value) {
3472
3608
         char *tmp = resultLocal;
3473
3609
         char *tmpVal;
3544
3680
   char *resultLocal;
3545
3681
   VixToolsEnvIterator *itr;
3546
3682
   char *envVar;
 
3683
#ifdef __FreeBSD__
 
3684
   char **envp;
 
3685
   if (NULL == userEnvironmentTable) {
 
3686
      err = VIX_E_FAIL;
 
3687
      return err;
 
3688
   }
 
3689
   envp = VixToolsEnvironmentTableToEnvp(userEnvironmentTable);
 
3690
#endif
3547
3691
 
3548
3692
   if (NULL == result) {
3549
3693
      err = VIX_E_FAIL;
3552
3696
 
3553
3697
   resultLocal = Util_SafeStrdup("");  // makes the loop cleaner.
3554
3698
 
 
3699
#ifdef __FreeBSD__
 
3700
   err = VixToolsNewEnvIterator(userToken, envp, &itr);
 
3701
#else
3555
3702
   err = VixToolsNewEnvIterator(userToken, &itr);
 
3703
#endif
3556
3704
   if (VIX_FAILED(err)) {
3557
3705
      goto abort;
3558
3706
   }
3560
3708
   while ((envVar = VixToolsGetNextEnvVar(itr)) != NULL) {
3561
3709
      char *tmp = resultLocal;
3562
3710
      char *tmpVal;
3563
 
 
 
3711
#ifdef __FreeBSD__
 
3712
      /*
 
3713
       * For variables we change during Impersonatation of user,
 
3714
       * we need to fetch from getenv() system call, all else
 
3715
       * can be read from the hash table of the original envp.
 
3716
       */
 
3717
      if (StrUtil_StartsWith(envVar, "USER=") ||
 
3718
          StrUtil_StartsWith(envVar, "HOME=") ||
 
3719
          StrUtil_StartsWith(envVar, "SHELL=")) {
 
3720
         char *name = NULL;
 
3721
         char *escapedName = NULL;
 
3722
         char *whereToSplit;
 
3723
         size_t nameLen;
 
3724
 
 
3725
         whereToSplit = strchr(envVar, '=');
 
3726
         if (NULL == whereToSplit) {
 
3727
            /* Our code generated this list, so this shouldn't happen. */
 
3728
            ASSERT(0);
 
3729
            continue;
 
3730
         }
 
3731
 
 
3732
         nameLen = whereToSplit - envVar;
 
3733
         name = Util_SafeMalloc(nameLen + 1);
 
3734
         memcpy(name, envVar, nameLen);
 
3735
         name[nameLen] = '\0';
 
3736
 
 
3737
         escapedName = VixToolsEscapeXMLString(name);
 
3738
 
 
3739
         free(envVar);
 
3740
         envVar = Str_SafeAsprintf(NULL, "%s=%s",
 
3741
                                   escapedName, Posix_Getenv(name));
 
3742
 
 
3743
         free(name);
 
3744
         free(escapedName);
 
3745
      }
 
3746
#endif
3564
3747
      tmpVal = VixToolsEscapeXMLString(envVar);
3565
3748
      free(envVar);
3566
3749
      if (NULL == tmpVal) {
3581
3764
 
3582
3765
abort:
3583
3766
   VixToolsDestroyEnvIterator(itr);
 
3767
#ifdef __FreeBSD__
 
3768
   VixToolsFreeEnvp(envp);
 
3769
#endif
3584
3770
   *result = resultLocal;
3585
3771
 
3586
3772
   return err;
3642
3828
         goto abort;
3643
3829
      }
3644
3830
#endif
3645
 
      /* 
 
3831
      /*
3646
3832
       * At this point, we want to set environmental variable for current
3647
3833
       * user, even if the current user is root/administrator
3648
3834
       */
3676
3862
   default:
3677
3863
      err = VIX_E_OP_NOT_SUPPORTED_ON_GUEST;
3678
3864
      break;
3679
 
   } // switch (readRequest->variableType)   
 
3865
   } // switch (readRequest->variableType)
3680
3866
 
3681
3867
abort:
3682
3868
   if (impersonatingVMWareUser) {
4239
4425
   VixError err = VIX_OK;
4240
4426
   int i;
4241
4427
   static char resultBuffer[GUESTMSG_MAX_IN_SIZE];
4242
 
   ProcMgr_ProcList *procList = NULL;
 
4428
   ProcMgrProcInfoArray *procList = NULL;
 
4429
   ProcMgrProcInfo *procInfo;
4243
4430
   char *destPtr;
4244
4431
   char *endDestPtr;
4245
4432
   char *procBufPtr = NULL;
4249
4436
   Bool escapeStrs;
4250
4437
   char *escapedName = NULL;
4251
4438
   char *escapedUser = NULL;
 
4439
   size_t procCount;
4252
4440
 
4253
4441
   ASSERT(maxBufferSize <= GUESTMSG_MAX_IN_SIZE);
4254
4442
 
4277
4465
                             VIX_XML_ESCAPED_TAG);
4278
4466
   }
4279
4467
 
4280
 
   for (i = 0; i < procList->procCount; i++) {
 
4468
   procCount = ProcMgrProcInfoArray_Count(procList);
 
4469
   for (i = 0; i < procCount; i++) {
4281
4470
      const char *name;
4282
4471
      const char *user;
4283
4472
 
 
4473
      procInfo = ProcMgrProcInfoArray_AddressOf(procList, i);
 
4474
 
4284
4475
      if (escapeStrs) {
4285
4476
         name = escapedName =
4286
 
            VixToolsEscapeXMLString(procList->procCmdList[i]);
 
4477
            VixToolsEscapeXMLString(procInfo->procCmd);
4287
4478
         if (NULL == escapedName) {
4288
4479
            err = VIX_E_OUT_OF_MEMORY;
4289
4480
            goto abort;
4290
4481
         }
4291
4482
      } else {
4292
 
         name = procList->procCmdList[i];
 
4483
         name = procInfo->procCmd;
4293
4484
      }
4294
4485
 
4295
 
      if ((NULL != procList->procOwnerList) &&
4296
 
          (NULL != procList->procOwnerList[i])) {
 
4486
      if (NULL != procInfo->procOwner) {
4297
4487
         if (escapeStrs) {
4298
4488
            user = escapedUser =
4299
 
               VixToolsEscapeXMLString(procList->procOwnerList[i]);
 
4489
               VixToolsEscapeXMLString(procInfo->procOwner);
4300
4490
            if (NULL == escapedUser) {
4301
4491
               err = VIX_E_OUT_OF_MEMORY;
4302
4492
               goto abort;
4303
4493
            }
4304
4494
         } else {
4305
 
            user = procList->procOwnerList[i];
 
4495
            user = procInfo->procOwner;
4306
4496
         }
4307
4497
      } else {
4308
4498
         user = "";
4315
4505
#endif
4316
4506
                             "<user>%s</user><start>%d</start></proc>",
4317
4507
                             name,
4318
 
                             (int) procList->procIdList[i],
 
4508
                             (int) procInfo->procId,
4319
4509
#if defined(_WIN32)
4320
 
                             (int) procList->procDebugged[i],
 
4510
                             (int) procInfo->procDebugged,
4321
4511
#endif
4322
4512
                             user,
4323
 
                             (NULL == procList->startTime)
4324
 
                                 ? 0
4325
 
                                 : (int) procList->startTime[i]);
 
4513
                             (int) procInfo->procStartTime);
4326
4514
      if (NULL == procBufPtr) {
4327
4515
         err = VIX_E_OUT_OF_MEMORY;
4328
4516
         goto abort;
4406
4594
static gboolean
4407
4595
VixToolsListProcCacheCleanup(void *clientData) // IN
4408
4596
{
4409
 
   int32 *key = (int32 *)clientData;
 
4597
   int key = (int)(intptr_t)clientData;
4410
4598
   gboolean ret;
4411
4599
 
4412
 
   ret = g_hash_table_remove(listProcessesResultsTable, key);
 
4600
   ret = g_hash_table_remove(listProcessesResultsTable, &key);
4413
4601
   Debug("%s: list proc cache timed out, purged key %d (found? %d)\n",
4414
 
         __FUNCTION__, *key, ret);
4415
 
   free(key);
 
4602
         __FUNCTION__, key, ret);
4416
4603
 
4417
4604
   return FALSE;
4418
4605
}
4441
4628
                                    char **resultBuffer)     // OUT
4442
4629
{
4443
4630
   VixError err = VIX_OK;
4444
 
   ProcMgr_ProcList *procList = NULL;
 
4631
   ProcMgrProcInfoArray *procList = NULL;
 
4632
   ProcMgrProcInfo *procInfo;
4445
4633
   DynBuf dynBuffer;
4446
4634
   VixToolsExitedProgramState *epList;
4447
4635
   int i;
4448
4636
   int j;
4449
4637
   Bool bRet;
 
4638
   size_t procCount;
4450
4639
 
4451
4640
   DynBuf_Init(&dynBuffer);
4452
4641
 
4482
4671
               if (VIX_OK != err) {
4483
4672
                  goto abort;
4484
4673
               }
 
4674
               break;
4485
4675
            }
4486
4676
            epList = epList->next;
4487
4677
         }
4510
4700
    * the Vix side with GetNthProperty, and can have a mix of live and
4511
4701
    * dead processes.
4512
4702
    */
 
4703
   procCount = ProcMgrProcInfoArray_Count(procList);
4513
4704
   if (numPids > 0) {
4514
4705
      for (i = 0; i < numPids; i++) {
4515
 
         for (j = 0; j < procList->procCount; j++) {
4516
 
            // ignore it if its on the exited list -- we added it above
4517
 
            if (VixToolsFindExitedProgramState(pids[i])) {
4518
 
               continue;
4519
 
            }
4520
 
            if (pids[i] == procList->procIdList[j]) {
 
4706
         // ignore it if its on the exited list -- we added it above
 
4707
         if (VixToolsFindExitedProgramState(pids[i])) {
 
4708
            continue;
 
4709
         }
 
4710
         for (j = 0; j < procCount; j++) {
 
4711
            procInfo = ProcMgrProcInfoArray_AddressOf(procList, j);
 
4712
            if (pids[i] == procInfo->procId) {
4521
4713
               err = VixToolsPrintProcInfoEx(&dynBuffer,
4522
 
                                             procList->procCmdList[i],
4523
 
                                             procList->procIdList[i],
4524
 
                                             (NULL == procList->procOwnerList
4525
 
                                              || NULL == procList->procOwnerList[i])
4526
 
                                             ? "" : procList->procOwnerList[i],
4527
 
                                             (NULL == procList->startTime)
4528
 
                                             ? 0 : (int) procList->startTime[i],
 
4714
                                             procInfo->procCmd,
 
4715
                                             procInfo->procId,
 
4716
                                             (NULL == procInfo->procOwner)
 
4717
                                             ? "" : procInfo->procOwner,
 
4718
                                             (int) procInfo->procStartTime,
4529
4719
                                             0, 0);
4530
4720
               if (VIX_OK != err) {
4531
4721
                  goto abort;
4534
4724
         }
4535
4725
      }
4536
4726
   } else {
4537
 
      for (i = 0; i < procList->procCount; i++) {
 
4727
      for (i = 0; i < procCount; i++) {
 
4728
         procInfo = ProcMgrProcInfoArray_AddressOf(procList, i);
4538
4729
         // ignore it if its on the exited list -- we added it above
4539
 
         if (VixToolsFindExitedProgramState(procList->procIdList[i])) {
 
4730
         if (VixToolsFindExitedProgramState(procInfo->procId)) {
4540
4731
            continue;
4541
4732
         }
4542
4733
         err = VixToolsPrintProcInfoEx(&dynBuffer,
4543
 
                                       procList->procCmdList[i],
4544
 
                                       procList->procIdList[i],
4545
 
                                       (NULL == procList->procOwnerList
4546
 
                                        || NULL == procList->procOwnerList[i])
4547
 
                                       ? "" : procList->procOwnerList[i],
4548
 
                                       (NULL == procList->startTime)
4549
 
                                       ? 0 : (int) procList->startTime[i],
 
4734
                                       procInfo->procCmd,
 
4735
                                       procInfo->procId,
 
4736
                                       (NULL == procInfo->procOwner)
 
4737
                                       ? "" : procInfo->procOwner,
 
4738
                                       (int) procInfo->procStartTime,
4550
4739
                                       0, 0);
4551
4740
         if (VIX_OK != err) {
4552
4741
            goto abort;
4651
4840
   uint32 offset;
4652
4841
   int len;
4653
4842
   VixToolsCachedListProcessesResult *cachedResult = NULL;
4654
 
   uint32 *keyBuf;
4655
4843
   GSource *timer;
4656
 
   int32 *timerData;
4657
4844
#ifdef _WIN32
4658
4845
   Bool bRet;
4659
4846
   wchar_t *userName = NULL;
4679
4866
   }
4680
4867
   impersonatingVMWareUser = TRUE;
4681
4868
 
 
4869
#if defined(__APPLE__)
 
4870
   /*
 
4871
    * On MacOS, to fetch info on processes owned by others
 
4872
    * we need to be root. Even /bin/ps and /bin/top in
 
4873
    * MacOS have the setuid bit set to allow any user
 
4874
    * list all processes. For linux & FreeBSD, this API
 
4875
    * does return info on all processes by all users. So
 
4876
    * to keep the result consistent on MacOS, we need to
 
4877
    * stop impersonating user for this API.
 
4878
    *
 
4879
    * NOTE: We still do the impersonation before this
 
4880
    * to authenticate the user as usual.
 
4881
    */
 
4882
   VixToolsUnimpersonateUser(userToken);
 
4883
   impersonatingVMWareUser = FALSE;
 
4884
#endif
 
4885
 
4682
4886
   key = listRequest->key;
4683
4887
   offset = listRequest->offset;
4684
4888
 
4690
4894
 
4691
4895
      // find the cached data
4692
4896
      cachedResult = g_hash_table_lookup(listProcessesResultsTable,
4693
 
                                        &key);
 
4897
                                         &key);
4694
4898
      if (NULL == cachedResult) {
4695
4899
         Debug("%s: failed to find cached data with key %d\n", __FUNCTION__, key);
4696
4900
         err = VIX_E_FAIL;
4762
4966
         /*
4763
4967
          * Save it off in the hashtable.
4764
4968
          */
4765
 
         keyBuf = Util_SafeMalloc(sizeof(uint32));
4766
4969
         key = listProcessesResultsKey++;
4767
 
         *keyBuf = key;
4768
 
         cachedResult = Util_SafeMalloc(sizeof(VixToolsCachedListProcessesResult));
 
4970
         cachedResult = Util_SafeMalloc(sizeof(*cachedResult));
4769
4971
         cachedResult->resultBufferLen = fullResultSize;
4770
4972
         cachedResult->resultBuffer = fullResultBuffer;
 
4973
         cachedResult->key = key;
4771
4974
#ifdef _WIN32
4772
4975
         bRet = VixToolsGetUserName(&cachedResult->userName);
4773
4976
         if (!bRet) {
4778
4981
         cachedResult->euid = Id_GetEUid();
4779
4982
#endif
4780
4983
 
4781
 
         g_hash_table_insert(listProcessesResultsTable, keyBuf, cachedResult);
 
4984
         g_hash_table_replace(listProcessesResultsTable, &cachedResult->key,
 
4985
                              cachedResult);
4782
4986
 
4783
4987
         /*
4784
4988
          * Set timer callback to clean this up in case the Vix side
4785
4989
          * never finishes
4786
4990
          */
4787
 
         timerData = Util_SafeMalloc(sizeof(int32));
4788
 
         *timerData = *keyBuf;
4789
4991
         timer = g_timeout_source_new(SECONDS_UNTIL_LISTPROC_CACHE_CLEANUP * 1000);
4790
 
         g_source_set_callback(timer, VixToolsListProcCacheCleanup, timerData, NULL);
 
4992
         g_source_set_callback(timer, VixToolsListProcCacheCleanup,
 
4993
                               (void *)(intptr_t) key, NULL);
4791
4994
         g_source_attach(timer, g_main_loop_get_context(eventQueue));
4792
4995
         g_source_unref(timer);
4793
4996
      }
5681
5884
 
5682
5885
#ifdef _WIN32
5683
5886
   fileExtendedInfoBufferSize = strlen(fileExtendedInfoWindowsFormatString);
5684
 
#elif defined(linux) || defined(sun)
 
5887
#else
5685
5888
   fileExtendedInfoBufferSize = strlen(fileExtendedInfoLinuxFormatString);
5686
5889
#endif
5687
5890
 
5689
5892
   fileExtendedInfoBufferSize += 10 + 20 + (20 * 2); // properties + size + times
5690
5893
#ifdef _WIN32
5691
5894
   fileExtendedInfoBufferSize += 20;                // createTime
5692
 
#elif defined(linux) || defined(sun)
 
5895
#else
5693
5896
   fileExtendedInfoBufferSize += 10 * 3;            // uid, gid, perms
5694
5897
#endif
5695
5898
 
5696
 
#if defined(linux) || defined(sun)
 
5899
#if defined(linux) || defined(sun) || defined(__FreeBSD__)
5697
5900
   if (File_IsSymLink(filePathName)) {
5698
5901
      char *symlinkTarget;
5699
5902
      symlinkTarget = Posix_ReadLink(filePathName);
5759
5962
      err = VIX_E_INVALID_ARG;
5760
5963
      goto abort;
5761
5964
   }
5762
 
   
 
5965
 
5763
5966
   err = VixToolsImpersonateUser(requestMsg, &userToken);
5764
5967
   if (VIX_OK != err) {
5765
5968
      goto abort;
5819
6022
VixError
5820
6023
VixToolsSetFileAttributes(VixCommandRequestHeader *requestMsg)    // IN
5821
6024
{
5822
 
#if (defined(_WIN32) || defined(__linux__) || defined(sun))
5823
6025
   VixError err = VIX_OK;
5824
6026
   Bool impersonatingVMWareUser = FALSE;
5825
6027
   void *userToken = NULL;
6033
6235
   VixToolsLogoutUser(userToken);
6034
6236
 
6035
6237
   return err;
6036
 
#else
6037
 
   return VIX_E_NOT_SUPPORTED;
6038
 
#endif
6039
6238
} // VixToolsSetGuestFileAttributes
6040
6239
 
6041
6240
 
6088
6287
      ASSERT_MEM_ALLOC(NULL != escapedFileName);
6089
6288
   }
6090
6289
 
6091
 
   *destPtr += Str_Sprintf(*destPtr, 
6092
 
                           endDestPtr - *destPtr, 
 
6290
   *destPtr += Str_Sprintf(*destPtr,
 
6291
                           endDestPtr - *destPtr,
6093
6292
                           fileInfoFormatString,
6094
6293
                           fileName,
6095
6294
                           fileProperties,
6119
6318
                              char **destPtr,               // IN/OUT
6120
6319
                              char *endDestPtr)             // IN
6121
6320
{
6122
 
#if defined(_WIN32) || defined(linux) || defined(sun)
6123
6321
   int64 fileSize = 0;
6124
6322
   VmTimeType modTime = 0;
6125
6323
   VmTimeType accessTime = 0;
6129
6327
   Bool hidden = FALSE;
6130
6328
   Bool readOnly = FALSE;
6131
6329
   VmTimeType createTime = 0;
6132
 
#elif defined(linux) || defined(sun)
 
6330
#else
6133
6331
   int permissions = 0;
6134
6332
   int ownerId = 0;
6135
6333
   int groupId = 0;
6151
6349
      fileSize = File_GetSize(filePathName);
6152
6350
   }
6153
6351
 
6154
 
#if defined(linux) || defined(sun)
 
6352
#if !defined(_WIN32)
6155
6353
   /*
6156
6354
    * If the file is a symlink, figure out where it points.
6157
6355
    */
6186
6384
#endif
6187
6385
 
6188
6386
   if (Posix_Stat(filePathName, &statbuf) != -1) {
6189
 
#if defined(linux) || defined(sun)
 
6387
#if !defined(_WIN32)
6190
6388
      ownerId = statbuf.st_uid;
6191
6389
      groupId = statbuf.st_gid;
6192
6390
      permissions = statbuf.st_mode;
6220
6418
                           accessTime,
6221
6419
                           hidden,
6222
6420
                           readOnly);
6223
 
#elif defined(linux) || defined(sun)
 
6421
#else
6224
6422
   *destPtr += Str_Sprintf(*destPtr,
6225
6423
                           endDestPtr - *destPtr,
6226
6424
                           fileExtendedInfoLinuxFormatString,
6236
6434
   free(symlinkTarget);
6237
6435
#endif
6238
6436
   free(escapedFileName);
6239
 
#endif   // defined(_WIN32) || defined(linux) || defined(sun)
6240
6437
} // VixToolsPrintFileExtendedInfo
6241
6438
 
6242
6439
 
6414
6611
      interpreterName = "/bin/sh";
6415
6612
#endif
6416
6613
   }
6417
 
   
 
6614
 
6418
6615
   if (*interpreterName) {
6419
6616
      programExists = File_Exists(interpreterName);
6420
6617
 
6423
6620
       * thinking.
6424
6621
       */
6425
6622
 
6426
 
      programIsExecutable = 
 
6623
      programIsExecutable =
6427
6624
         (FileIO_Access(interpreterName, FILEIO_ACCESS_EXEC) ==
6428
6625
                                                   FILEIO_SUCCESS);
6429
6626
      if (!programExists) {
6435
6632
         goto abort;
6436
6633
      }
6437
6634
   }
6438
 
   
 
6635
 
6439
6636
   /*
6440
6637
    * Create a temporary file that we can run as a script.
6441
6638
    * TODO: Plumb a file suffix/extention throught to the File
6446
6643
   if (PROCESS_CREATOR_USER_TOKEN != userToken) {
6447
6644
      err = VixToolsGetUserTmpDir(userToken, &tempDirPath);
6448
6645
 
6449
 
      /* 
 
6646
      /*
6450
6647
       * Don't give up if VixToolsGetUserTmpDir() failed. It might just
6451
6648
       * have failed to load DLLs, so we might be running on Win 9x.
6452
6649
       * Just fall through to use the old fashioned File_GetSafeTmpDir().
6465
6662
   }
6466
6663
   for (var = 0; var <= 0xFFFFFFFF; var++) {
6467
6664
      free(tempScriptFilePath);
6468
 
      tempScriptFilePath = Str_Asprintf(NULL, 
6469
 
                                        "%s"DIRSEPS"%s%d%s", 
6470
 
                                        tempDirPath, 
6471
 
                                        scriptFileBaseName, 
6472
 
                                        var, 
 
6665
      tempScriptFilePath = Str_Asprintf(NULL,
 
6666
                                        "%s"DIRSEPS"%s%d%s",
 
6667
                                        tempDirPath,
 
6668
                                        scriptFileBaseName,
 
6669
                                        var,
6473
6670
                                        fileSuffix);
6474
6671
      if (NULL == tempScriptFilePath) {
6475
6672
         err = VIX_E_OUT_OF_MEMORY;
6476
6673
         goto abort;
6477
6674
      }
6478
 
      
 
6675
 
6479
6676
      fd = Posix_Open(tempScriptFilePath, // UTF-8
6480
6677
                      O_CREAT | O_EXCL
6481
6678
#if defined(_WIN32)
6530
6727
 
6531
6728
   if (writeResult < 0) {
6532
6729
      /*
6533
 
       * Yes, I'm duplicating code by running this check before the call to 
 
6730
       * Yes, I'm duplicating code by running this check before the call to
6534
6731
       * close(), but if close() succeeds it will clobber the errno, causing
6535
6732
       * something confusing to be reported to the user.
6536
6733
       */
6559
6756
 
6560
6757
   if ((NULL != interpreterName) && (*interpreterName)) {
6561
6758
      fullCommandLine = Str_Asprintf(NULL, // resulting string length
6562
 
                                     "\"%s\" %s \"%s\"", 
 
6759
                                     "\"%s\" %s \"%s\"",
6563
6760
                                     interpreterName,
6564
6761
                                     interpreterFlags,
6565
6762
                                     tempScriptFilePath);
6566
6763
   } else {
6567
6764
      fullCommandLine = Str_Asprintf(NULL,  // resulting string length
6568
 
                                     "\"%s\"", 
 
6765
                                     "\"%s\"",
6569
6766
                                     tempScriptFilePath);
6570
6767
   }
6571
6768
 
6693
6890
 
6694
6891
   credentialType = requestMsg->userCredentialType;
6695
6892
 
6696
 
   if (VIX_USER_CREDENTIAL_TICKETED_SESSION == credentialType) {
 
6893
   switch (credentialType) {
 
6894
   case VIX_USER_CREDENTIAL_TICKETED_SESSION:
 
6895
   {
6697
6896
      VixCommandTicketedSession *commandTicketedSession = (VixCommandTicketedSession *) credentialField;
6698
6897
      size_t ticketLength = commandTicketedSession->ticketLength;
6699
6898
 
6708
6907
                                          credentialType,
6709
6908
                                          credentialField,
6710
6909
                                          userToken);
6711
 
 
6712
 
   } else if (VIX_USER_CREDENTIAL_SSPI == credentialType) {
6713
 
      /*
6714
 
       * SSPI currently only supported in ticketed sessions
6715
 
       */
6716
 
      err = VIX_E_NOT_SUPPORTED;
6717
 
 
6718
 
   } else {
6719
 
      VixCommandNamePassword *namePasswordStruct = (VixCommandNamePassword *) credentialField;
 
6910
      break;
 
6911
   }
 
6912
   case VIX_USER_CREDENTIAL_ROOT:
 
6913
   case VIX_USER_CREDENTIAL_CONSOLE_USER:
 
6914
      err = VixToolsImpersonateUserImplEx(NULL,
 
6915
                                          credentialType,
 
6916
                                          NULL,
 
6917
                                          userToken);
 
6918
      break;
 
6919
   case VIX_USER_CREDENTIAL_NAME_PASSWORD:
 
6920
   case VIX_USER_CREDENTIAL_NAME_PASSWORD_OBFUSCATED:
 
6921
   case VIX_USER_CREDENTIAL_NAMED_INTERACTIVE_USER:
 
6922
   {
 
6923
      VixCommandNamePassword *namePasswordStruct =
 
6924
         (VixCommandNamePassword *) credentialField;
6720
6925
      credentialField += sizeof(*namePasswordStruct);
6721
6926
 
6722
6927
      err = VixToolsImpersonateUserImplEx(NULL,
6724
6929
                                          credentialField,
6725
6930
                                          userToken);
6726
6931
      if ((VIX_OK != err)
6727
 
            && ((VIX_USER_CREDENTIAL_NAME_PASSWORD_OBFUSCATED == credentialType)
6728
 
                  || (VIX_USER_CREDENTIAL_NAME_PASSWORD == credentialType))) {
 
6932
          && ((VIX_USER_CREDENTIAL_NAME_PASSWORD_OBFUSCATED == credentialType)
 
6933
              || (VIX_USER_CREDENTIAL_NAME_PASSWORD == credentialType))) {
6729
6934
         /*
6730
6935
          * Windows does not allow you to login with an empty password. Only
6731
6936
          * the console allows this login, which means the console does not
6741
6946
         }
6742
6947
#endif
6743
6948
      }
 
6949
      break;
 
6950
   }
 
6951
   case VIX_USER_CREDENTIAL_SSPI:
 
6952
      /*
 
6953
       * SSPI currently only supported in ticketed sessions
 
6954
       */
 
6955
   default:
 
6956
      Debug("%s: credentialType = %d\n", __FUNCTION__, credentialType);
 
6957
      err = VIX_E_NOT_SUPPORTED;
6744
6958
   }
6745
6959
 
6746
6960
   Debug("<%s\n", __FUNCTION__);
6754
6968
 *
6755
6969
 * VixToolsImpersonateUserImpl --
6756
6970
 *
6757
 
 *    Little compatability wrapper for legacy Foundry Tools implementations. 
 
6971
 *    Little compatability wrapper for legacy Foundry Tools implementations.
6758
6972
 *
6759
6973
 * Return value:
6760
6974
 *    TRUE on success
6785
6999
 * VixToolsImpersonateUserImplEx --
6786
7000
 *
6787
7001
 *   On Windows:
6788
 
 *   To retrieve the security context of another user 
6789
 
 *   call LogonUser to log the user whom you want to impersonate on to the 
6790
 
 *   local computer, specifying the name of the user account, the user's 
6791
 
 *   domain, and the user's password. This function returns a pointer to 
 
7002
 *   To retrieve the security context of another user
 
7003
 *   call LogonUser to log the user whom you want to impersonate on to the
 
7004
 *   local computer, specifying the name of the user account, the user's
 
7005
 *   domain, and the user's password. This function returns a pointer to
6792
7006
 *   a handle to the access token of the logged-on user as an out parameter.
6793
 
 *   Call ImpersonateLoggedOnUser using the handle to the access token obtained 
 
7007
 *   Call ImpersonateLoggedOnUser using the handle to the access token obtained
6794
7008
 *   in the call to LogonUser.
6795
 
 *   Run RegEdt32 to load the registry hive of the impersonated user manually. 
 
7009
 *   Run RegEdt32 to load the registry hive of the impersonated user manually.
6796
7010
 *
6797
7011
 * Return value:
6798
7012
 *    VIX_OK on success, or an appropriate error code on failure.
6819
7033
   *userToken = NULL;
6820
7034
 
6821
7035
///////////////////////////////////////////////////////////////////////
6822
 
#if defined(__FreeBSD__)
6823
 
   err = VIX_E_NOT_SUPPORTED;
 
7036
// NOTE: The following lines need to be uncommented to disable either
 
7037
// FreeBSD and/or MacOS support for VMODL Guest Operations completely.
 
7038
//#if defined(__FreeBSD__)
 
7039
//   return VIX_E_NOT_SUPPORTED;
 
7040
//#endif
 
7041
//#if defined(__APPLE__)
 
7042
//   return VIX_E_NOT_SUPPORTED;
 
7043
//#endif
6824
7044
///////////////////////////////////////////////////////////////////////
6825
 
#elif defined(_WIN32) || defined(linux) || defined(sun)
6826
7045
   {
6827
7046
      AuthToken authToken;
6828
7047
      char *unobfuscatedUserName = NULL;
6973
7192
      Util_ZeroFreeString(unobfuscatedPassword);
6974
7193
   }
6975
7194
 
6976
 
#else
6977
 
   err = VIX_E_NOT_SUPPORTED;
6978
 
#endif   // else linux
6979
 
 
6980
7195
   return err;
6981
7196
} // VixToolsImpersonateUserImplEx
6982
7197
 
7001
7216
   if (PROCESS_CREATOR_USER_TOKEN != userToken) {
7002
7217
#if defined(_WIN32)
7003
7218
      Impersonate_Undo();
7004
 
#elif defined(linux) || defined(sun)
 
7219
#else
7005
7220
      ProcMgr_ImpersonateUserStop();
7006
7221
#endif
7007
7222
   }
7029
7244
      return;
7030
7245
   }
7031
7246
 
7032
 
#if !defined(__FreeBSD__)
7033
7247
   if (NULL != userToken) {
7034
7248
      AuthToken authToken = (AuthToken) userToken;
7035
7249
      Auth_CloseToken(authToken);
7036
7250
   }
7037
 
#endif
7038
7251
} // VixToolsLogoutUser
7039
7252
 
7040
7253
 
7056
7269
static char *
7057
7270
VixToolsGetImpersonatedUsername(void *userToken)
7058
7271
{
7059
 
#if defined(_WIN32) || defined(linux) || defined(sun)
7060
7272
   char *userName = NULL;
7061
7273
   char *homeDir = NULL;
7062
7274
 
7066
7278
   free(homeDir);
7067
7279
 
7068
7280
   return userName;
7069
 
#else
7070
 
   return Util_SafeStrdup("XXX failed to get username XXX");
7071
 
#endif
7072
7281
} // VixToolsUnimpersonateUser
7073
7282
 
7074
7283
 
7448
7657
 
7449
7658
VixError
7450
7659
VixToolsProcessHgfsPacket(VixCommandHgfsSendPacket *requestMsg,   // IN
 
7660
                          GMainLoop *eventQueue,                  // IN
7451
7661
                          char **result,                          // OUT
7452
7662
                          size_t *resultValueResult)              // OUT
7453
7663
{
7464
7674
      err = VIX_E_FAIL;
7465
7675
      goto abort;
7466
7676
   }
7467
 
   
 
7677
 
7468
7678
   err = VMAutomationRequestParserInit(&parser,
7469
7679
                                      &requestMsg->header, sizeof *requestMsg);
7470
7680
   if (VIX_OK != err) {
7487
7697
 
7488
7698
   hgfsReplyPacketSize = sizeof hgfsReplyPacket;
7489
7699
 
7490
 
#if !defined(__FreeBSD__)
7491
7700
   /*
7492
7701
    * Impersonation was okay, so let's give our packet to
7493
7702
    * the HGFS server and forward the reply packet back.
7497
7706
                                   requestMsg->hgfsPacketSize, // packet in size
7498
7707
                                   hgfsReplyPacket,            // packet out buf
7499
7708
                                   &hgfsReplyPacketSize);      // in/out size
7500
 
#endif
 
7709
 
 
7710
   if (eventQueue != NULL) {
 
7711
      /*
 
7712
       * Register a timer to periodically invalidate any inactive
 
7713
       * HGFS sessions.
 
7714
       */
 
7715
      VixToolsRegisterHgfsSessionInvalidator(eventQueue);
 
7716
   }
7501
7717
 
7502
7718
   if (NULL != resultValueResult) {
7503
7719
      *resultValueResult = hgfsReplyPacketSize;
7899
8115
 */
7900
8116
 
7901
8117
#if defined(__linux__) || defined(_WIN32)
7902
 
VixError 
 
8118
VixError
7903
8119
VixToolsGetGuestNetworkingConfig(VixCommandRequestHeader *requestMsg,   // IN
7904
8120
                                 char **resultBuffer,                   // OUT
7905
8121
                                 size_t *resultBufferLength)            // OUT
7997
8213
 */
7998
8214
 
7999
8215
#if defined(_WIN32)
8000
 
VixError 
 
8216
VixError
8001
8217
VixToolsSetGuestNetworkingConfig(VixCommandRequestHeader *requestMsg)    // IN
8002
8218
{
8003
8219
   VixError err = VIX_OK;
8007
8223
   VixPropertyListImpl propList;
8008
8224
   VixPropertyValue *propertyPtr = NULL;
8009
8225
   char *messageBody = NULL;
8010
 
   char ipAddr[IP_ADDR_SIZE]; 
 
8226
   char ipAddr[IP_ADDR_SIZE];
8011
8227
   char subnetMask[IP_ADDR_SIZE];
8012
8228
   Bool dhcpEnabled = FALSE;
8013
8229
   HRESULT hrErr;
8014
8230
 
8015
8231
   ASSERT(NULL != requestMsg);
8016
8232
 
8017
 
   ipAddr[0] = '\0';  
 
8233
   ipAddr[0] = '\0';
8018
8234
   subnetMask[0] = '\0';
8019
 
   
 
8235
 
8020
8236
   err = VixToolsImpersonateUser(requestMsg, &userToken);
8021
8237
   if (VIX_OK != err) {
8022
8238
      goto abort;
8027
8243
   messageBody = (char *) requestMsg + sizeof(*setGuestNetworkingConfigRequest);
8028
8244
 
8029
8245
   VixPropertyList_Initialize(&propList);
8030
 
   err = VixPropertyList_Deserialize(&propList, 
8031
 
                                     messageBody, 
 
8246
   err = VixPropertyList_Deserialize(&propList,
 
8247
                                     messageBody,
8032
8248
                                     setGuestNetworkingConfigRequest -> bufferSize,
8033
8249
                                     VIX_PROPERTY_LIST_BAD_ENCODING_ERROR);
8034
8250
   if (VIX_OK != err) {
8040
8256
      switch (propertyPtr->propertyID) {
8041
8257
      ///////////////////////////////////////////
8042
8258
      case VIX_PROPERTY_VM_DHCP_ENABLED:
8043
 
         if (propertyPtr->value.boolValue) { 
 
8259
         if (propertyPtr->value.boolValue) {
8044
8260
            dhcpEnabled = TRUE;
8045
8261
         }
8046
8262
         break;
8047
8263
 
8048
 
      /////////////////////////////////////////// 
 
8264
      ///////////////////////////////////////////
8049
8265
      case VIX_PROPERTY_VM_IP_ADDRESS:
8050
8266
         if (strlen(propertyPtr->value.strValue) < sizeof ipAddr) {
8051
8267
            Str_Strcpy(ipAddr,
8052
 
                       propertyPtr->value.strValue, 
 
8268
                       propertyPtr->value.strValue,
8053
8269
                       sizeof ipAddr);
8054
8270
            } else {
8055
8271
               err = VIX_E_INVALID_ARG;
8060
8276
      ///////////////////////////////////////////
8061
8277
      case VIX_PROPERTY_VM_SUBNET_MASK:
8062
8278
         if (strlen(propertyPtr->value.strValue) < sizeof subnetMask) {
8063
 
            Str_Strcpy(subnetMask, 
 
8279
            Str_Strcpy(subnetMask,
8064
8280
                       propertyPtr->value.strValue,
8065
 
                       sizeof subnetMask); 
 
8281
                       sizeof subnetMask);
8066
8282
         } else {
8067
8283
            err = VIX_E_INVALID_ARG;
8068
8284
            goto abort;
8069
8285
         }
8070
 
         break;   
8071
 
         
 
8286
         break;
 
8287
 
8072
8288
      ///////////////////////////////////////////
8073
8289
      default:
8074
8290
         /*
8075
8291
          * Be more tolerant.  Igonore unknown properties.
8076
8292
          */
8077
8293
         break;
8078
 
      } // switch 
 
8294
      } // switch
8079
8295
 
8080
8296
      propertyPtr = propertyPtr->next;
8081
8297
   } // while {propList.properties != NULL)
8084
8300
      hrErr = VixToolsEnableDHCPOnPrimary();
8085
8301
   } else {
8086
8302
      if (('\0' != ipAddr[0]) ||
8087
 
          ('\0' != subnetMask[0])) { 
 
8303
          ('\0' != subnetMask[0])) {
8088
8304
         hrErr = VixToolsEnableStaticOnPrimary(ipAddr, subnetMask);
8089
8305
      } else {
8090
8306
         /*
8099
8315
         err = Vix_TranslateCOMError(hrErr);
8100
8316
      } else {
8101
8317
         err = Vix_TranslateSystemError(hrErr);
8102
 
      } 
 
8318
      }
8103
8319
   }
8104
8320
 
8105
8321
abort:
8116
8332
#endif
8117
8333
 
8118
8334
 
8119
 
#if defined(_WIN32) || defined(linux) || defined(sun)
8120
8335
/*
8121
8336
 *-----------------------------------------------------------------------------
8122
8337
 *
8275
8490
   struct passwd *ppwd = &pwd;
8276
8491
   char *buffer = NULL; // a pool of memory for Posix_Getpwnam_r() to use.
8277
8492
   size_t bufferSize;
8278
 
   
 
8493
 
8279
8494
   /*
8280
8495
    * For POSIX systems, look up the uid of 'username', and compare
8281
8496
    * it to the uid of the owner of this process. This handles systems
8282
8497
    * where multiple usernames map to the name user.
8283
8498
    */
8284
 
   
 
8499
 
8285
8500
   /*
8286
8501
    * Get the maximum size buffer needed by getpwuid_r.
8287
8502
    * Multiply by 4 to compensate for the conversion to UTF-8 by
8293
8508
 
8294
8509
   if (Posix_Getpwnam_r(username, &pwd, buffer, bufferSize, &ppwd) != 0 ||
8295
8510
       NULL == ppwd) {
8296
 
      /* 
 
8511
      /*
8297
8512
       * This username should exist, since it should have already
8298
8513
       * been validated by guestd. Assume it is a system error.
8299
8514
       */
8320
8535
   Util_ZeroFree(buffer, bufferSize);
8321
8536
 
8322
8537
#endif
8323
 
   
 
8538
 
8324
8539
   return err;
8325
8540
}
8326
 
#endif  /* #if defined(_WIN32) || defined(linux) || defined(sun) */
8327
8541
 
8328
8542
 
8329
8543
/*
8554
8768
   size_t resultValueLength = 0;
8555
8769
   Bool mustSetResultValueLength = TRUE;
8556
8770
   Bool deleteResultValue = FALSE;
8557
 
  
 
8771
 
8558
8772
 
8559
8773
   if (NULL != resultBuffer) {
8560
8774
      *resultBuffer = NULL;
8746
8960
      ///////////////////////////////////
8747
8961
      case VMXI_HGFS_SEND_PACKET_COMMAND:
8748
8962
         err = VixToolsProcessHgfsPacket((VixCommandHgfsSendPacket *) requestMsg,
 
8963
                                         eventQueue,
8749
8964
                                         &resultValue,
8750
8965
                                         &resultValueLength);
8751
8966
         deleteResultValue = FALSE; // TRUE;
8760
8975
                                                &resultValueLength);
8761
8976
         if (VIX_FAILED(err)) {
8762
8977
            /*
8763
 
             * VixToolsGetGuestNetworkingConfig() failed, so resultVal is still NULL, 
8764
 
             * so let it get replaced with the empty string at the abort label.  
 
8978
             * VixToolsGetGuestNetworkingConfig() failed, so resultVal is still NULL,
 
8979
             * so let it get replaced with the empty string at the abort label.
8765
8980
             */
8766
8981
            goto abort;
8767
8982
         }
9014
9229
 *-----------------------------------------------------------------------------
9015
9230
 *
9016
9231
 * VixToolsEnableDHCPOnPrimary --
9017
 
 *      
 
9232
 *
9018
9233
 *      Enable DHCP on primary NIC. A primary NIC is the
9019
9234
 *      first interface you get using ipconfig. You can change the order
9020
9235
 *      of NIC cards on a computer via Windows GUI.
9024
9239
 *
9025
9240
 * Side effects:
9026
9241
 *      None.
9027
 
 * 
 
9242
 *
9028
9243
 *-----------------------------------------------------------------------------
9029
9244
 */
9030
9245
 
9051
9266
 *-----------------------------------------------------------------------------
9052
9267
 *
9053
9268
 * VixToolsEnableStaticOnPrimary --
9054
 
 *      
9055
 
 *      Set the IP address and/or subnet mask of the primary NIC. A primary NIC 
 
9269
 *
 
9270
 *      Set the IP address and/or subnet mask of the primary NIC. A primary NIC
9056
9271
 *      is the first interface you get using ipconfig. You can change the order
9057
 
 *      of NIC cards on a computer via Windows GUI.  
 
9272
 *      of NIC cards on a computer via Windows GUI.
9058
9273
 *
9059
9274
 * Results:
9060
9275
 *      S_OK on success.  COM error codes on failure.
9061
9276
 *
9062
9277
 * Side effects:
9063
9278
 *      None.
9064
 
 * 
 
9279
 *
9065
9280
 *-----------------------------------------------------------------------------
9066
9281
 */
9067
9282
 
9075
9290
   char actualIpAddress[IP_ADDR_SIZE];
9076
9291
   char actualSubnetMask[IP_ADDR_SIZE];
9077
9292
 
9078
 
   if ((NULL == ipAddr) || 
 
9293
   if ((NULL == ipAddr) ||
9079
9294
       (NULL == subnetMask)) {
9080
9295
      return E_INVALIDARG;
9081
9296
   }
9091
9306
   /*
9092
9307
    * Set IP address if client provides it.
9093
9308
    */
9094
 
   
 
9309
 
9095
9310
   primaryIp = &primaryNic->ips.ips_val[0];
9096
 
 
 
9311
 
9097
9312
   if ('\0' != ipAddr[0]) {
9098
9313
      Str_Strcpy(actualIpAddress,
9099
9314
                 ipAddr,
9109
9324
    */
9110
9325
   if ('\0' != subnetMask[0]) {
9111
9326
      Str_Strcpy(actualSubnetMask,
9112
 
                 subnetMask, 
 
9327
                 subnetMask,
9113
9328
                 sizeof actualSubnetMask);
9114
9329
   } else {
9115
9330
      Str_Strcpy(actualSubnetMask,
9117
9332
                 sizeof actualSubnetMask);
9118
9333
   }
9119
9334
 
9120
 
   ret = WMI_EnableStatic(primaryNic->macAddress, 
9121
 
                          actualIpAddress, 
 
9335
   ret = WMI_EnableStatic(primaryNic->macAddress,
 
9336
                          actualIpAddress,
9122
9337
                          actualSubnetMask);
9123
9338
 
9124
9339
   VMX_XDR_FREE(xdr_GuestNic, primaryNic);