コード例 #1
0
VMGuestLibError
VMGuestLib_CloseHandle(VMGuestLibHandle handle) // IN
{
   void *data;

   if (NULL == handle) {
      return VMGUESTLIB_ERROR_INVALID_HANDLE;
   }

   data = HANDLE_DATA(handle);
   if (data != NULL &&
       HANDLE_SESSIONID(handle) != 0 &&
       HANDLE_VERSION(handle) == 3) {
      VMGuestLibStatisticsV3 *v3stats = data;
      GuestLibV3StatCount count;

      for (count = 0; count < v3stats->numStats; count++) {
         VMX_XDR_FREE(xdr_GuestLibV3Stat, &v3stats->stats[count]);
      }
   }
   free(data);

   /* Be paranoid. */
   HANDLE_DATA(handle) = NULL;
   free(handle);

   return VMGUESTLIB_ERROR_SUCCESS;
}
コード例 #2
0
ファイル: testDebug.c プロジェクト: bzed/pkg-open-vm-tools
static gboolean
TestDebugValidateRpc3(RpcInData *data,
                      gboolean ret)
{
   TestPluginData pdata = { NULL, };

   CU_ASSERT(XdrUtil_Deserialize(data->result, data->resultLen,
                                 xdr_TestPluginData, &pdata));

   CU_ASSERT_STRING_EQUAL(pdata.data, "Hello World!");
   CU_ASSERT_EQUAL(pdata.f_int, 8642);
   CU_ASSERT(pdata.f_bool);

   VMX_XDR_FREE(xdr_TestPluginData, &pdata);
   return ret;
}
コード例 #3
0
ファイル: xdrutil.c プロジェクト: bzed/pkg-open-vm-tools
Bool
XdrUtil_Deserialize(const void *data,  // IN
                    size_t dataLen,    // IN
                    void *xdrProc,     // IN
                    void *dest)        // IN
{
   Bool ret;
   xdrproc_t proc = xdrProc;
   XDR xdrs;

   ASSERT(data != NULL);
   ASSERT(xdrProc != NULL);
   ASSERT(dest != NULL);

   xdrmem_create(&xdrs, (char *) data, dataLen, XDR_DECODE);
   ret = (Bool) proc(&xdrs, dest, 0);
   xdr_destroy(&xdrs);

   if (!ret) {
      VMX_XDR_FREE(proc, dest);
   }

   return ret;
}
コード例 #4
0
static VMGuestLibError
VMGuestLibUpdateInfo(VMGuestLibHandle handle) // IN
{
   char *reply = NULL;
   size_t replyLen;
   VMGuestLibError ret = VMGUESTLIB_ERROR_INVALID_ARG;
   uint32 hostVersion = HANDLE_VERSION(handle);

   /* 
    * Starting with the highest supported protocol (major) version, negotiate
    * down to the highest host supported version. Host supports minimum version
    * 2.
    */
   if (hostVersion == 0) {
      hostVersion = VMGUESTLIB_DATA_VERSION;
   }

   do {
      char commandBuf[64];
      unsigned int index = 0;

      /* Free the last reply when retrying. */
      free(reply);
      reply = NULL;

      /*
       * Construct command string with the command name and the version
       * of the data struct that we want.
       */
      Str_Sprintf(commandBuf, sizeof commandBuf, "%s %d",
                  VMGUESTLIB_BACKDOOR_COMMAND_STRING,
                  hostVersion);

      /* Send the request. */
      if (RpcChannel_SendOne(&reply, &replyLen, commandBuf)) {
         VMGuestLibDataV2 *v2reply = (VMGuestLibDataV2 *)reply;
         VMSessionId sessionId = HANDLE_SESSIONID(handle);

         ASSERT(hostVersion == v2reply->hdr.version);

         if (sessionId != 0 && sessionId != v2reply->hdr.sessionId) {
            /* Renegotiate protocol if sessionId changed. */
            hostVersion = VMGUESTLIB_DATA_VERSION;
            HANDLE_SESSIONID(handle) = 0;
            continue;
         }
         ret = VMGUESTLIB_ERROR_SUCCESS;
         break;
      }

      /* 
       * Host is older and doesn't support the requested protocol version.
       * Request the highest version the host supports.
       */
      Debug("Failed to retrieve info: %s\n", reply ? reply : "NULL");

      if (hostVersion == 2 ||
          Str_Strncmp(reply, "Unknown command", sizeof "Unknown command") == 0) {
         /* 
          * Host does not support this feature. Older (v2) host would return
          * "Unsupported version" if it doesn't recognize the requested version.
          *
          * XXX: Maybe use another error code for this case where the host
          * product doesn't support this feature?
          */
         ret = VMGUESTLIB_ERROR_NOT_ENABLED;
         break;
      } else if (hostVersion == 3) {
         /*
          * Host supports v2 at a minimum. If request for v3 fails, then just use
          * v2, since v2 host does not send the highest supported version in the
          * reply.
          */
         hostVersion = 2;
         HANDLE_SESSIONID(handle) = 0;
         continue;
      } else if (!StrUtil_GetNextUintToken(&hostVersion, &index, reply, ":")) {
         /*
          * v3 and onwards, the host returns the highest major version it supports,
          * if the requested version is not supported. So parse out the host
          * version from the reply and return error if it didn't.
          */
         Debug("Bad reply received from host.\n");
         ret = VMGUESTLIB_ERROR_OTHER;
         break;
      }
      ASSERT(hostVersion < VMGUESTLIB_DATA_VERSION);
   } while (ret != VMGUESTLIB_ERROR_SUCCESS);

   if (ret != VMGUESTLIB_ERROR_SUCCESS) {
      goto done;
   }

   /* Sanity check the results. */
   if (replyLen < sizeof hostVersion) {
      Debug("Unable to retrieve version\n");
      ret = VMGUESTLIB_ERROR_OTHER;
      goto done;
   }

   if (hostVersion == 2) {
      VMGuestLibDataV2 *v2reply = (VMGuestLibDataV2 *)reply;
      size_t dataSize = sizeof *v2reply;

      /* More sanity checks. */
      if (v2reply->hdr.version != hostVersion) {
         Debug("Incorrect data version returned\n");
         ret = VMGUESTLIB_ERROR_OTHER;
         goto done;
      }
      if (replyLen != dataSize) {
         Debug("Incorrect data size returned\n");
         ret = VMGUESTLIB_ERROR_OTHER;
         goto done;
      }

      /* Store the reply in the handle. */
      HANDLE_VERSION(handle) = v2reply->hdr.version;
      HANDLE_SESSIONID(handle) = v2reply->hdr.sessionId;
      if (HANDLE_DATASIZE(handle) < dataSize) {
         /* [Re]alloc if the local handle buffer is not big enough. */
         free(HANDLE_DATA(handle));
         HANDLE_DATA(handle) = Util_SafeCalloc(1, dataSize);
         HANDLE_DATASIZE(handle) = dataSize;
      }
      memcpy(HANDLE_DATA(handle), reply, replyLen);

      /* Make sure resourcePoolPath is NUL terminated. */
      v2reply = HANDLE_DATA(handle);
      v2reply->resourcePoolPath.value[sizeof v2reply->resourcePoolPath.value - 1] = '\0';
      ret = VMGUESTLIB_ERROR_SUCCESS;
   } else if (hostVersion == 3) {
      VMGuestLibDataV3 *v3reply = (VMGuestLibDataV3 *)reply;
      size_t dataSize;
      XDR xdrs;
      GuestLibV3StatCount count;
      VMGuestLibStatisticsV3 *v3stats;

      /* More sanity checks. */
      if (v3reply->hdr.version != hostVersion) {
         Debug("Incorrect data version returned\n");
         ret = VMGUESTLIB_ERROR_OTHER;
         goto done;
      }
      if (replyLen < sizeof *v3reply) {
         Debug("Incorrect data size returned\n");
         ret = VMGUESTLIB_ERROR_OTHER;
         goto done;
      }

      /* 0. Copy the reply version and sessionId to the handle. */
      HANDLE_VERSION(handle) = v3reply->hdr.version;
      HANDLE_SESSIONID(handle) = v3reply->hdr.sessionId;

      /* 
       * 1. Retrieve the length of the statistics array from the XDR encoded
       * part of the reply.
       */
      xdrmem_create(&xdrs, v3reply->data, v3reply->dataSize, XDR_DECODE);

      if (!xdr_GuestLibV3StatCount(&xdrs, &count)) {
         xdr_destroy(&xdrs);
         goto done;
      }
      if (count >= GUESTLIB_MAX_STATISTIC_ID) {
         /* 
          * Host has more than we can process. So process only what this side
          * can.
          */
         count = GUESTLIB_MAX_STATISTIC_ID - 1;
      }

      /* 2. [Re]alloc if the local handle buffer is not big enough. */
      dataSize = sizeof *v3stats + (count * sizeof (GuestLibV3Stat));
      if (HANDLE_DATASIZE(handle) < dataSize) {
         free(HANDLE_DATA(handle));
         HANDLE_DATA(handle) = Util_SafeCalloc(1, dataSize);
         HANDLE_DATASIZE(handle) = dataSize;
      }

      /* 3. Unmarshal the array of statistics. */
      v3stats = HANDLE_DATA(handle);
      v3stats->numStats = count;
      for (count = 0; count < v3stats->numStats; count++) {
         GuestLibV3TypeIds statId = count + 1;

         /* Unmarshal the statistic. */
         if (!xdr_GuestLibV3Stat(&xdrs, &v3stats->stats[count])) {
            break;
         }

         /* Host sends all the V3 statistics it supports, in order. */
         if (v3stats->stats[count].d != statId) {
            break;
         }
      }
      if (count >= v3stats->numStats) {
         ret = VMGUESTLIB_ERROR_SUCCESS;
      } else {
         /* 
          * Error while unmarshalling. Deep-free already unmarshalled
          * statistics and invalidate the data in the handle.
          */
         GuestLibV3StatCount c;

         for (c = 0; c < count; c++) {
            VMX_XDR_FREE(xdr_GuestLibV3Stat, &v3stats->stats[c]);
         }
         HANDLE_SESSIONID(handle) = 0;
      }

      /* 4. Free resources. */
      xdr_destroy(&xdrs);
   } else {
      /*
       * Host should never reply with a higher version protocol than requested.
       */
      ret = VMGUESTLIB_ERROR_OTHER;
   }

done:
   free(reply);
   return ret;
}
static Bool
RecordResolverInfo(NicInfoV3 *nicInfo)  // OUT
{
   DnsConfigInfo *dnsConfigInfo = NULL;
   char namebuf[DNSINFO_MAX_ADDRLEN + 1];
   char **s;

   if (res_init() == -1) {
      return FALSE;
   }

   dnsConfigInfo = Util_SafeCalloc(1, sizeof *dnsConfigInfo);

   /*
    * Copy in the host name. not this
    */
   if (!GuestInfoGetFqdn(sizeof namebuf, namebuf)) {
      goto fail;
   }
   dnsConfigInfo->hostName =
      Util_SafeCalloc(1, sizeof *dnsConfigInfo->hostName);
   *dnsConfigInfo->hostName = Util_SafeStrdup(namebuf);

   /*
    * Repeat with the domain name. not this
    */
   dnsConfigInfo->domainName =
      Util_SafeCalloc(1, sizeof *dnsConfigInfo->domainName);
   *dnsConfigInfo->domainName = Util_SafeStrdup(_res.defdname);

   /*
    * Name servers.
    */
   RecordResolverNS(dnsConfigInfo);

   /*
    * Search suffixes.
    */
   for (s = _res.dnsrch; *s; s++) {
      DnsHostname *suffix;

      /* Check to see if we're going above our limit. See bug 605821. */
      if (dnsConfigInfo->searchSuffixes.searchSuffixes_len == DNSINFO_MAX_SUFFIXES) {
         g_message("%s: dns search suffix limit (%d) reached, skipping overflow.",
                   __FUNCTION__, DNSINFO_MAX_SUFFIXES);
         break;
      }

      suffix = XDRUTIL_ARRAYAPPEND(dnsConfigInfo, searchSuffixes, 1);
      ASSERT_MEM_ALLOC(suffix);
      *suffix = Util_SafeStrdup("test suffix");
   }

   /*
    * "Commit" dnsConfigInfo to nicInfo.
    */
   nicInfo->dnsConfigInfo = dnsConfigInfo;

   return TRUE;

fail:
   VMX_XDR_FREE(xdr_DnsConfigInfo, dnsConfigInfo);
   free(dnsConfigInfo);
   return FALSE;
}
コード例 #6
0
static gboolean
RpcDebugSend(RpcChannel *chan,
             char const *data,
             size_t dataLen,
             char **result,
             size_t *resultLen)
{
   char *copy;
   gpointer xdrdata = NULL;
   DbgChannelData *cdata = chan->_private;
   RpcDebugPlugin *plugin = cdata->plugin;
   RpcDebugRecvMapping *mapping = NULL;
   RpcDebugRecvFn recvFn = NULL;
   gboolean ret = TRUE;

   ASSERT(cdata->ctx != NULL);

   /* Be paranoid. Like the VMX, NULL-terminate the incoming data. */
   copy = g_malloc(dataLen + 1);
   memcpy(copy, data, dataLen);
   copy[dataLen] = '\0';

   /* Try to find a mapping the the command in the RPC. */
   if (plugin->recvFns) {
      char *cmd;
      unsigned int idx = 0;

      cmd = StrUtil_GetNextToken(&idx, copy, " ");
      if (cmd != NULL) {
         RpcDebugRecvMapping *test;
         for (test = plugin->recvFns; test->name != NULL; test++) {
            if (strcmp(test->name, cmd) == 0) {
               mapping = test;
               break;
            }
         }
      }
      vm_free(cmd);
   }

   if (mapping != NULL) {
      recvFn = mapping->recvFn;
      if (mapping->xdrProc != NULL) {
         char *start;

         ASSERT(mapping->xdrSize > 0);

         /* Find out where the XDR data starts. */
         start = strchr(copy, ' ');
         if (start == NULL) {
            RpcDebug_SetResult("Can't find command delimiter.", result, resultLen);
            ret = FALSE;
            goto exit;
         }
         start++;

         xdrdata = g_malloc0(mapping->xdrSize);
         if (!XdrUtil_Deserialize(start,
                                  dataLen - (start - copy),
                                  mapping->xdrProc,
                                  xdrdata)) {
            RpcDebug_SetResult("XDR deserialization failed.", result, resultLen);
            ret = FALSE;
            goto exit;
         }
      }
   } else {
      recvFn = plugin->dfltRecvFn;
   }

   if (recvFn != NULL) {
      ret = recvFn((xdrdata != NULL) ? xdrdata : copy, dataLen, result, resultLen);
   } else {
      RpcDebug_SetResult("", result, resultLen);
   }

exit:
   if (xdrdata != NULL) {
      VMX_XDR_FREE(mapping->xdrProc, xdrdata);
      g_free(xdrdata);
   }
   g_free(copy);
   return ret;
}
コード例 #7
0
ファイル: rpcChannel.c プロジェクト: nf-mlo/open-vm-tools
static Bool
RpcChannelXdrWrapper(RpcInData *data,
                     RpcChannelCallback *rpc)
{
   Bool ret;
   RpcInData copy;
   void *xdrData = NULL;

   if (rpc->xdrIn != NULL) {
      xdrData = malloc(rpc->xdrInSize);
      if (xdrData == NULL) {
         ret = RPCIN_SETRETVALS(data, "Out of memory.", FALSE);
         goto exit;
      }

      memset(xdrData, 0, rpc->xdrInSize);
      if (!XdrUtil_Deserialize(data->args + 1, data->argsSize - 1,
                               rpc->xdrIn, xdrData)) {
         ret = RPCIN_SETRETVALS(data, "XDR deserialization failed.", FALSE);
         free(xdrData);
         goto exit;
      }

      copy.name = data->name;
      copy.args = xdrData;
      copy.argsSize = rpc->xdrInSize;
      copy.result = data->result;
      copy.resultLen = data->resultLen;
      copy.freeResult = data->freeResult;
      copy.appCtx = data->appCtx;
      copy.clientData = rpc->clientData;
   } else {
      memcpy(&copy, data, sizeof copy);
   }

   ret = rpc->callback(&copy);

   if (rpc->xdrIn != NULL) {
      VMX_XDR_FREE(rpc->xdrIn, xdrData);
      free(xdrData);
      copy.args = NULL;
      data->result = copy.result;
      data->resultLen = copy.resultLen;
      data->freeResult = copy.freeResult;
   }

   if (rpc->xdrOut != NULL && copy.result != NULL) {
      XDR xdrs;
      xdrproc_t xdrProc = rpc->xdrOut;

      if (DynXdr_Create(&xdrs) == NULL) {
         ret = RPCIN_SETRETVALS(data, "Out of memory.", FALSE);
         goto exit;
      }

      if (!xdrProc(&xdrs, copy.result)) {
         ret = RPCIN_SETRETVALS(data, "XDR serialization failed.", FALSE);
         DynXdr_Destroy(&xdrs, TRUE);
         goto exit;
      }

      if (copy.freeResult) {
         VMX_XDR_FREE(rpc->xdrOut, copy.result);
      }
      data->result = DynXdr_Get(&xdrs);
      data->resultLen = XDR_GETPOS(&xdrs);
      data->freeResult = TRUE;
      DynXdr_Destroy(&xdrs, FALSE);
   }

exit:
   if (copy.freeResult && copy.result != NULL) {
      g_free(copy.result);
   }
   return ret;
}