예제 #1
0
VGAuthError
VGAuth_ValidateUsernamePassword(VGAuthContext *ctx,
                                const char *userName,
                                const char *password,
                                int numExtraParams,
                                const VGAuthExtraParams *extraParams,
                                VGAuthUserHandle **handle)
{
   VGAuthError err;

   if ((NULL == ctx) || (NULL == userName) || (NULL == password) || (NULL == handle)) {
      return VGAUTH_E_INVALID_ARGUMENT;
   }

   if (!g_utf8_validate(userName, -1, NULL)) {
      Warning("User not in UTF-8\n");
      return VGAUTH_E_INVALID_ARGUMENT;
   }
   if (!g_utf8_validate(password, -1, NULL)) {
      Warning("Password not in UTF-8\n");
      return VGAUTH_E_INVALID_ARGUMENT;
   }
   if (userName[0] == '\0') {
      Warning("Empty Username\n");
      return VGAUTH_E_INVALID_ARGUMENT;
   }
   if (!Usercheck_UsernameIsLegal(userName)) {
      Warning("Username '%s' contains invalid characters\n", userName);
      return VGAUTH_E_INVALID_ARGUMENT;
   }

   err = VGAuthValidateExtraParams(numExtraParams, extraParams);
   if (VGAUTH_E_OK != err) {
      return err;
   }

   err = VGAuthValidateUsernamePasswordImpl(ctx,
                                            userName,
                                            password,
                                            handle);

   if (VGAUTH_E_OK == err) {
      VGAuth_AuditEvent(ctx,
                        TRUE,
                        SU_(auth.password.valid,
                            "Username and password successfully validated for '%s'"),
                        userName);
   } else {
      VGAuth_AuditEvent(ctx,
                        FALSE,
                        SU_(auth.password.invalid,
                            "Username and password mismatch for '%s'"),
                        userName);
   }

   return err;
}
예제 #2
0
static int
TimeSyncStatus(void)
{
   Bool status = FALSE;
   if (TimeSyncGetOldOptions() & VMWARE_GUI_SYNC_TIME) {
      status = TRUE;
   }
   if (status) {
      ToolsCmd_Print("%s\n", SU_(option.enabled, "Enabled"));
      return EXIT_SUCCESS;
   } else {
      ToolsCmd_Print("%s\n", SU_(option.disabled, "Disabled"));
      return EX_UNAVAILABLE;
   }
}
예제 #3
0
static int
HelpCommand(char **argv,      // IN: Command line arguments
            int argc,         // IN: Length of argv
            gboolean quiet)   // IN
{
   int retval = EXIT_SUCCESS;

   if (++optind < argc) {
      int i;

      for (i = 0; i < ARRAYSIZE(commands); i++) {
         if (toolbox_strcmp(commands[i].command, argv[optind]) == 0) {
            commands[i].helpFunc(argv[0], commands[i].command);
            return EXIT_SUCCESS;
         }
      }
      ToolsCmd_UnknownEntityError(argv[0],
                                  SU_(arg.subcommand, "subcommand"),
                                  argv[optind]);
      retval = EX_USAGE;
   }

   ToolboxCmdHelp(argv[0], argv[optind - 1]);
   return retval;
}
예제 #4
0
int
Stat_Command(char **argv,      // IN: Command line arguments
             int argc,         // IN: Length of command line arguments
             gboolean quiet)   // IN
{
   if (toolbox_strcmp(argv[optind], "hosttime") == 0) {
      return StatHostTime();
   } else if (toolbox_strcmp(argv[optind], "sessionid") == 0) {
      return StatGetSessionID();
   } else if (toolbox_strcmp(argv[optind], "balloon") == 0) {
      return StatGetMemoryBallooned();
   } else if (toolbox_strcmp(argv[optind], "swap") == 0) {
      return StatGetMemorySwapped();
   } else if (toolbox_strcmp(argv[optind], "memlimit") == 0) {
      return StatGetMemoryLimit();
   } else if (toolbox_strcmp(argv[optind], "memres") == 0) {
      return StatGetMemoryReservation();
   } else if (toolbox_strcmp(argv[optind], "cpures") == 0) {
      return StatGetCpuReservation();
   } else if (toolbox_strcmp(argv[optind], "cpulimit") == 0) {
      return StatGetCpuLimit();
   } else if (toolbox_strcmp(argv[optind], "speed") == 0) {
      return StatProcessorSpeed();
   } else if (toolbox_strcmp(argv[optind], "raw") == 0) {
      return StatGetRaw((optind + 1 < argc) ? argv[optind + 1] : "", // encoding
                        (optind + 2 < argc) ? argv[optind + 2] : "", // stat
                        (optind + 3 < argc) ? argv[optind + 3] : "");// param
   } else {
      ToolsCmd_UnknownEntityError(argv[0],
                                  SU_(arg.subcommand, "subcommand"),
                                  argv[optind]);
      return EX_USAGE;
   }
}
예제 #5
0
void
ToolsCmd_UnknownEntityError(const char *name,    // IN: command name (argv[0])
                            const char *entity,  // IN: what is unknown
                            const char *str)     // IN: errorneous string
{
   g_printerr(SU_(error.unknown, "%s: Unknown %s '%s'\n"), name, entity, str);
}
예제 #6
0
void
Stat_Help(const char *progName, // IN: The name of the program obtained from argv[0]
          const char *cmd)      // IN
{
   g_print(SU_(help.stat, "%s: print useful guest and host information\n"
                          "Usage: %s %s <subcommand>\n\n"
                          "Subcommands:\n"
                          "   hosttime: print the host time\n"
                          "   speed: print the CPU speed in MHz\n"
                          "ESX guests only subcommands:\n"
                          "   sessionid: print the current session id\n"
                          "   balloon: print memory ballooning information\n"
                          "   swap: print memory swapping information\n"
                          "   memlimit: print memory limit information\n"
                          "   memres: print memory reservation information\n"
                          "   cpures: print CPU reservation information\n"
                          "   cpulimit: print CPU limit information\n"
                          "   raw [<encoding> <stat name>]: print raw stat information\n"
                          "      <encoding> can be one of 'text', 'json', 'xml', 'yaml'.\n"
                          "      <stat name> includes session, host, resources, vscsi and\n"
                          "      vnet (Some stats like vscsi are two words, e.g. 'vscsi scsi0:0').\n"
                          "      Prints the available stats if <encoding> and <stat name>\n"
                          "      arguments are not specified.\n"),
           cmd, progName, cmd);
}
예제 #7
0
static int
StatProcessorSpeed(void)
{
   int32 speed;
   Backdoor_proto bp;
   bp.in.cx.halfs.low = BDOOR_CMD_GETMHZ;
   Backdoor(&bp);
   speed = bp.out.ax.word;
   if (speed <= 0) {
      ToolsCmd_PrintErr("%s",
                        SU_(stat.getspeed.failed, "Unable to get processor speed.\n"));
      return EX_TEMPFAIL;
   }
   g_print(SU_(stat.processorSpeed.info, "%u MHz\n"), speed);
   return EXIT_SUCCESS;
}
예제 #8
0
static int
TimeSyncEnable(void)
{
   TimeSyncSet(TRUE);
   ToolsCmd_Print("%s\n", SU_(option.enabled, "Enabled"));
   return EXIT_SUCCESS;
}
예제 #9
0
static int
TimeSyncDisable(void)
{
   TimeSyncSet(FALSE);
   ToolsCmd_Print("%s\n", SU_(option.disabled, "Disabled"));
   return EXIT_SUCCESS;
}
예제 #10
0
static int
StatHostTime(void)
{
   int64 hostSecs;
   int64 hostUsecs;
   time_t sec;
   char buf[256];
   gchar *timeUtf8;
   Backdoor_proto bp;

   bp.in.cx.halfs.low = BDOOR_CMD_GETTIMEFULL;
   Backdoor(&bp);
   if (bp.out.ax.word == BDOOR_MAGIC) {
      hostSecs = ((uint64)bp.out.si.word << 32) | bp.out.dx.word;
   } else {
      /* Falling back to older command. */
      bp.in.cx.halfs.low = BDOOR_CMD_GETTIME;
      Backdoor(&bp);
      hostSecs = bp.out.ax.word;
   }
   hostUsecs = bp.out.bx.word;

   if (hostSecs <= 0) {
      ToolsCmd_PrintErr("%s",
                        SU_(stat.gettime.failed, "Unable to get host time.\n"));
      return EX_TEMPFAIL;
   }

   sec = hostSecs + (hostUsecs / 1000000);
   if (strftime(buf, sizeof buf, "%d %b %Y %H:%M:%S", localtime(&sec)) == 0) {
      ToolsCmd_PrintErr("%s",
                        SU_(stat.formattime.failed, "Unable to format host time.\n"));
      return EX_TEMPFAIL;
   }

   timeUtf8 = g_locale_to_utf8(buf, -1, NULL, NULL, NULL);
   if (timeUtf8 == NULL) {
      ToolsCmd_PrintErr("%s",
                        SU_(stat.formattime.failed, "Unable to format host time.\n"));
      return EX_TEMPFAIL;
   }

   g_print("%s\n", timeUtf8);
   g_free(timeUtf8);
   return EXIT_SUCCESS;
}
int
Script_Command(char **argv,    // IN: command line arguments.
               int argc,       // IN: the length of the command line arguments.
               gboolean quiet) // IN
{
   const char *apm;

   if (++optind >= argc) {
      ToolsCmd_MissingEntityError(argv[0], SU_(arg.scripttype, "script type"));
      return EX_USAGE;
   }

   apm = argv[optind++];

   if (!ScriptCheckName(apm)) {
      ToolsCmd_UnknownEntityError(argv[0], SU_(arg.scripttype, "script type"), apm);
      return EX_USAGE;
   }

   if (optind >= argc) {
      ToolsCmd_MissingEntityError(argv[0], SU_(arg.subcommand, "subcommand"));
      return EX_USAGE;
   }

   if (toolbox_strcmp(argv[optind], "default") == 0) {
      return ScriptGetDefault(argv[0], apm);
   } else if (toolbox_strcmp(argv[optind], "current") == 0) {
      return ScriptGetCurrent(argv[0], apm);
   } else if (toolbox_strcmp(argv[optind], "set") == 0) {
      if (++optind >= argc) {
         ToolsCmd_MissingEntityError(argv[0], SU_(arg.scriptpath, "script path"));
         return EX_USAGE;
      }
      return ScriptSet(argv[0], apm, argv[optind]);
   } else if (toolbox_strcmp(argv[optind], "enable") == 0) {
      return ScriptToggle(argv[0], apm, TRUE);
   } else if (toolbox_strcmp(argv[optind], "disable") == 0) {
      return ScriptToggle(argv[0], apm, FALSE);
   } else {
      ToolsCmd_UnknownEntityError(argv[0],
                                  SU_(arg.subcommand, "subcommand"),
                                  argv[optind]);
      return EX_USAGE;
   }
}
예제 #12
0
void
TimeSync_Help(const char *progName, // IN: The name of the program obtained from argv[0]
              const char *cmd)      // IN
{
   g_print(SU_(help.timesync, "%s: functions for controlling time synchronization on the guest OS\n"
                              "Usage: %s %s <subcommand>\n\n"
                              "Subcommands:\n"
                              "   enable: enable time synchronization\n"
                              "   disable: disable time synchronization\n"
                              "   status: print the time synchronization status\n"),
           cmd, progName, cmd);
}
예제 #13
0
static int
OpenHandle(VMGuestLibHandle *glHandle, // OUT: The guestlib handle
           VMGuestLibError *glError)   // OUT: The errors when opening the handle
{
   *glError = VMGuestLib_OpenHandle(glHandle);
   if (*glError != VMGUESTLIB_ERROR_SUCCESS) {
      ToolsCmd_PrintErr(SU_(stat.openhandle.failed,
                            "OpenHandle failed: %s\n"),
                        VMGuestLib_GetErrorText(*glError));
      return EX_UNAVAILABLE;
   }
   *glError = VMGuestLib_UpdateInfo(*glHandle);
   if (*glError != VMGUESTLIB_ERROR_SUCCESS) {
      ToolsCmd_PrintErr(SU_(stat.update.failed,
                            "UpdateInfo failed: %s\n"),
                        VMGuestLib_GetErrorText(*glError));
      return EX_TEMPFAIL;
   }
   return 0;  // We don't return EXIT_SUCCESSS to indicate that this is not
              // an exit code

}
static int
ScriptToggle(const char *progName,  // IN: program name (argv[0])
             const char *apm,       // IN: APM name
             Bool enable)           // IN: status
{
   const char *path;
   const char *confName;
   int ret = EXIT_SUCCESS;
   GKeyFile *confDict;
   GError *err = NULL;

   confName = GetConfName(apm);

   if (!confName) {
      ToolsCmd_UnknownEntityError(progName,
                                  SU_(script.operation, "operation"),
                                  apm);
      return EX_USAGE;
   }

   confDict = LoadConfFile();

   if (!enable) {
      path = "";
   } else {
      path = GuestApp_GetDefaultScript(confName);
   }

   g_key_file_set_string(confDict, "powerops", confName, path);
   if (!VMTools_WriteConfig(NULL, confDict, &err)) {
      ToolsCmd_PrintErr(SU_(script.write.error, "Error writing config: %s\n"),
                        err->message);
      g_clear_error(&err);
      ret = EX_TEMPFAIL;
   }

   g_key_file_free(confDict);
   return ret;
}
static int
ScriptSet(const char *progName,  // IN: program name (argv[0])
          const char *apm,       // IN: APM name
          const char *path)      // IN: Verbosity flag
{
   const char *confName;
   int ret = EXIT_SUCCESS;
   GKeyFile *confDict = NULL;
   GError *err = NULL;

   if (!File_Exists(path)) {
      ToolsCmd_PrintErr(SU_(script.notfound, "%s doesn't exist.\n"), path);
      return EX_OSFILE;
   }

   confName = GetConfName(apm);
   if (!confName) {
      ToolsCmd_UnknownEntityError(progName,
                                  SU_(script.operation, "operation"),
                                  apm);
      return EX_USAGE;
   }

   confDict = LoadConfFile();
   g_key_file_set_string(confDict, "powerops", confName, path);

   if (!VMTools_WriteConfig(NULL, confDict, &err)) {
      ToolsCmd_PrintErr(SU_(script.write.error, "Error writing config: %s\n"),
                        err->message);
      g_clear_error(&err);
      ret = EX_TEMPFAIL;
   }

   g_key_file_free(confDict);
   return ret;
}
void
Script_Help(const char *progName, // IN: The name of the program obtained from argv[0]
            const char *cmd)      // IN
{
   g_print(SU_(help.script,
               "%s: control the scripts run in response to power operations\n"
               "Usage: %s %s <power|resume|suspend|shutdown> <subcommand> [args]\n\n"
               "Subcommands:\n"
               "   enable: enable the given script and restore its path to the default\n"
               "   disable: disable the given script\n"
               "   set <full_path>: set the given script to the given path\n"
               "   default: print the default path of the given script\n"
               "   current: print the current path of the given script\n"),
           cmd, progName, cmd);
}
예제 #17
0
static int
StatGetCpuLimit(void)
{
   int exitStatus = EXIT_SUCCESS;
   uint32 cpuLimit;
   VMGuestLibHandle glHandle;
   VMGuestLibError glError;

   exitStatus = OpenHandle(&glHandle, &glError);
   if (exitStatus) {
      return exitStatus;
   }
   glError = VMGuestLib_GetCpuLimitMHz(glHandle, &cpuLimit);
   if (glError != VMGUESTLIB_ERROR_SUCCESS) {
      ToolsCmd_PrintErr(SU_(stat.cpumax.failed,
                            "Failed to get CPU limit: %s\n"),
                        VMGuestLib_GetErrorText(glError));
      exitStatus = EX_TEMPFAIL;
   } else {
      g_print(SU_(stat.cpuLimit.info, "%u MHz\n"), cpuLimit);
   }
   VMGuestLib_CloseHandle(glHandle);
   return exitStatus;
}
예제 #18
0
static int
StatGetMemorySwapped(void)
{
   int exitStatus = EXIT_SUCCESS;
   uint32 memSwapped;
   VMGuestLibHandle glHandle;
   VMGuestLibError glError;

   exitStatus = OpenHandle(&glHandle, &glError);
   if (exitStatus) {
      return exitStatus;
   }
   glError = VMGuestLib_GetMemSwappedMB(glHandle, &memSwapped);
   if (glError != VMGUESTLIB_ERROR_SUCCESS) {
      ToolsCmd_PrintErr(SU_(stat.memswap.failed,
                            "Failed to get swapped memory: %s\n"),
                        VMGuestLib_GetErrorText(glError));
      exitStatus = EX_TEMPFAIL;
   } else {
      g_print(SU_(stat.memorySwapped.info, "%u MB\n"), memSwapped);
   }
   VMGuestLib_CloseHandle(glHandle);
   return exitStatus;
}
예제 #19
0
int
TimeSync_Command(char **argv,     // IN: command line arguments
                 int argc,        // IN: The length of the command line arguments
                 gboolean quiet)  // IN
{
   if (toolbox_strcmp(argv[optind], "enable") == 0) {
      return TimeSyncEnable();
   } else if (toolbox_strcmp(argv[optind], "disable") == 0) {
      return TimeSyncDisable();
   } else if (toolbox_strcmp(argv[optind], "status") == 0) {
      return TimeSyncStatus();
   } else {
      ToolsCmd_UnknownEntityError(argv[0],
                                  SU_(arg.subcommand, "subcommand"),
                                  argv[optind]);
      return EX_USAGE;
   }
}
예제 #20
0
static void
ToolboxCmdHelp(const char *progName,   // IN
               const char *cmd)        // IN
{
   g_print(SU_(help.main, "Usage: %s <command> [options] [subcommand]\n"
                          "Type '%s %s <command>' for help on a specific command.\n"
                          "Type '%s -v' to see the VMware Tools version.\n"
                          "Use '-q' option to suppress stdout output.\n"
                          "Most commands take a subcommand.\n\n"
                          "Available commands:\n"
                          "   device\n"
                          "   disk\n"
                          "   script\n"
                          "   stat\n"
                          "   timesync\n"
                          "   upgrade (not available on all operating systems)\n"),
           progName, progName, cmd, progName);
}
예제 #21
0
void
Stat_Help(const char *progName, // IN: The name of the program obtained from argv[0]
          const char *cmd)      // IN
{
   g_print(SU_(help.stat, "%s: print useful guest and host information\n"
                          "Usage: %s %s <subcommand>\n\n"
                          "Subcommands:\n"
                          "   hosttime: print the host time\n"
                          "   speed: print the CPU speed in MHz\n"
                          "ESX guests only subcommands:\n"
                          "   sessionid: print the current session id\n"
                          "   balloon: print memory ballooning information\n"
                          "   swap: print memory swapping information\n"
                          "   memlimit: print memory limit information\n"
                          "   memres: print memory reservation information\n"
                          "   cpures: print CPU reservation information\n"
                          "   cpulimit: print CPU limit information\n"),
           cmd, progName, cmd);
}
예제 #22
0
static int
StatGetSessionID(void)
{
   int exitStatus = EXIT_SUCCESS;
   uint64 session;
   VMGuestLibHandle glHandle;
   VMGuestLibError glError;

   exitStatus = OpenHandle(&glHandle, &glError);
   if (exitStatus) {
      return exitStatus;
   }
   glError = VMGuestLib_GetSessionId(glHandle, &session);
   if (glError != VMGUESTLIB_ERROR_SUCCESS) {
      ToolsCmd_PrintErr(SU_(stat.getsession.failed,
                            "Failed to get session ID: %s\n"),
                        VMGuestLib_GetErrorText(glError));
      exitStatus = EX_TEMPFAIL;
   } else {
      g_print("0x%"FMT64"x\n", session);
   }
   VMGuestLib_CloseHandle(glHandle);
   return exitStatus;
}
예제 #23
0
static int
StatGetRaw(const char *encoding,  // IN
           const char *stat,      // IN
           const char *param)     // IN
{
   int exitStatus = EXIT_SUCCESS;
   VMGuestLibError glError;
   char *result = NULL;
   size_t resultSize = 0;
   char *arg = g_strdup_printf("%s %s", stat, param);

   glError = VMGuestLib_StatGet(encoding, arg, &result, &resultSize);
   if (glError != VMGUESTLIB_ERROR_SUCCESS) {
      ToolsCmd_PrintErr(SU_(stat.get.failed,
                            "Failed to get stat: %s\n"),
                        VMGuestLib_GetErrorText(glError));
      exitStatus = EX_TEMPFAIL;
   } else {
      g_print("%*s", (int)resultSize, result);
   }
   VMGuestLib_StatFree(result, resultSize);
   g_free(arg);
   return exitStatus;
}
static int
GetConfEntry(const char *progName,  // IN: program name (argv[0])
             const char *apm,       // IN: apm name
             ScriptType type)       // IN: Script type (default or current)
{
   gchar *entry;
   GKeyFile *confDict;
   const char *confName;
   int len;
   int ret;

   confName = GetConfName(apm);
   if (!confName) {
      ToolsCmd_UnknownEntityError(progName,
                                  SU_(script.operation, "operation"),
                                  apm);
      return EX_USAGE;
   }

   confDict = LoadConfFile();

   switch (type) {
   case Current:
      entry = g_key_file_get_string(confDict, "powerops", confName, NULL);
      if (entry) {
         break;
      }
      /* Fall through */

   default:
      entry = g_strdup(GuestApp_GetDefaultScript(confName));
      break;
   }

   len = strlen(entry);
   if (len > 0) {

      /* If script path is not absolute, assume the Tools install path. */
      if (!g_path_is_absolute(entry)) {
         char *defaultPath = GuestApp_GetInstallPath();
         char *tmp;
         Bool quoted;

         ASSERT(defaultPath != NULL);

         /* Cope with old configs that added quotes around script paths. */
         quoted = (entry[0] == '"' && entry[len - 1] == '"');
         tmp = g_strdup_printf("%s%c%.*s", defaultPath, DIRSEPC,
                                quoted ? len - 2 : len,
                                quoted ? entry + 1 : entry);

         vm_free(defaultPath);

         g_free(entry);
         entry = tmp;
      }

      g_print("%s\n", entry);
      ret = EXIT_SUCCESS;
   } else {
      ToolsCmd_PrintErr(SU_(script.unknownop, "No script for operation %s.\n"),
                        apm);
      ret = EX_TEMPFAIL;
   }

   g_free(entry);
   g_key_file_free(confDict);
   return ret;
}
예제 #25
0
void
ToolsCmd_MissingEntityError(const char *name,     // IN: command name (argv[0])
                            const char *entity)   // IN: what is missing
{
   g_printerr(SU_(error.missing, "%s: Missing %s\n"), name, entity);
}
예제 #26
0
main(int argc,    // IN: length of command line arguments
     char **argv) // IN: Command line arguments
#endif
{
   Bool show_help = FALSE;
   Bool show_version = FALSE;
   CmdTable *cmd = NULL;
   GKeyFile *conf = NULL;
   int c;
   int retval = EXIT_FAILURE;

#if defined(_WIN32)
   char **argv;
   Unicode_InitW(argc, wargv, NULL, &argv, NULL);
#else
   Unicode_Init(argc, &argv, NULL);
#endif

   setlocale(LC_ALL, "");
   VMTools_LoadConfig(NULL, G_KEY_FILE_NONE, &conf, NULL);
   VMTools_ConfigLogging("toolboxcmd", conf, FALSE, FALSE);
   VMTools_BindTextDomain(VMW_TEXT_DOMAIN, NULL, NULL);

   /*
    * Check if we are in a VM
    */
   if (!VmCheck_IsVirtualWorld()) {
      g_printerr(SU_(error.novirtual, "%s must be run inside a virtual machine.\n"),
                 argv[0]);
      goto exit;
   }

   /*
    * Parse the command line optional arguments
    */
   while (1) {
      int option_index = 0;

      c = getopt_long(argc, argv, options, long_options, &option_index);

      /* Detect the end of the options. */
      if (c == -1) {
         break;
      }

      switch (c) {
      case 'h':
         show_help = TRUE;
         break;

      case 'v':
         show_version = TRUE;
         break;

      case 'q':
         gQuiet = TRUE;
         break;

      case '?':
         /* getopt_long already printed an error message. */
         g_printerr(SU_(help.hint, "Try '%s %s%s%s' for more information.\n"),
                    argv[0], "-h", "", "");
         goto exit;

      default:
         goto exit;
      }
   }

   if (show_version) {
      g_print("%s (%s)\n", TOOLBOXCMD_VERSION_STRING, BUILD_NUMBER);
      retval = EXIT_SUCCESS;
   } else if (show_help) {
      ToolboxCmdHelp(argv[0], "help");
      retval = EXIT_SUCCESS;
   } else {
      /* Process any remaining command line arguments (not options), and
       * execute corresponding command
       */
      if (optind >= argc) {
         ToolsCmd_MissingEntityError(argv[0], SU_(arg.command, "command"));
         retval = EX_USAGE;
      } else if ((cmd = ParseCommand(argv, argc)) == NULL) {
         ToolsCmd_UnknownEntityError(argv[0], SU_(arg.command, "command"), argv[optind]);
         retval = EX_USAGE;
      } else if (cmd->requireRoot && !System_IsUserAdmin()) {
#if defined(_WIN32)
         g_printerr(SU_(error.noadmin.win,
                        "%s: Administrator permissions are needed to perform %s operations.\n"
                        "Use an administrator command prompt to complete these tasks.\n"),
                    argv[0], cmd->command);

#else
         g_printerr(SU_(error.noadmin.posix,
                        "%s: You must be root to perform %s operations.\n"),
                    argv[0], cmd->command);
#endif
         retval = EX_NOPERM;
      } else if (cmd->requireArguments && ++optind >= argc) {
         ToolsCmd_MissingEntityError(argv[0], SU_(arg.subcommand, "subcommand"));
         retval = EX_USAGE;
      } else {
         retval = cmd->func(argv, argc, gQuiet);
      }

      if (retval == EX_USAGE && (cmd == NULL || strcmp(cmd->command, "help"))) {
         g_printerr(SU_(help.hint, "Try '%s %s%s%s' for more information.\n"),
                    argv[0], "help", cmd ? " " : "", cmd ? cmd->command : "");
      }
   }

exit:
   if (conf != NULL) {
      g_key_file_free(conf);
   }

   return retval;
}