Example #1
0
 void broadcastPMIObject(T*& ptr) {
   if (isWorker()) {
     ptr = receivePMIObjectPtr<T*>();
   } else {
     broadcastPMIObject<T>(*ptr);
   }
 }
/*
** Return the current contents of the free-list as a list of integers.
*/
int lsmSnapshotFreelist(lsm_db *pDb, int **paFree, int *pnFree){
  int rc = LSM_OK;                /* Return Code */
  int *aFree = 0;                 /* Integer array to return via *paFree */
  int nFree;                      /* Value to return via *pnFree */
  Freelist *p;                    /* Database free list object */
  Snapshot *pSnap = pDb->pWorker;

  assert( isWorker(pSnap) );

  p = &pSnap->freelist;
  nFree = p->nEntry;
  if( nFree && paFree ){
    aFree = lsmMallocRc(pDb->pEnv, sizeof(int) * nFree, &rc);
    if( aFree ){
      int i;
      for(i=0; i<nFree; i++){
        aFree[i] = p->aEntry[i].iBlk;
      }
    }
  }

  *pnFree = nFree;
  *paFree = aFree;
  return rc;
}
int lsmSnapshotSetFreelist(lsm_db *pDb, int *aElem, int nElem){
  lsm_env *pEnv = pDb->pEnv;
  int rc = LSM_OK;                /* Return code */
  int i;                          /* Iterator variable */
  int nIgnore;                    /* Number of entries to ignore */
  int iRefree1;                   /* A refreed block (or 0) */
  int iRefree2;                   /* A refreed block (or 0) */
  Freelist *pFree;                /* Database free-list */
  Snapshot *pSnap = pDb->pWorker;

  assert( isWorker(pSnap) );

  nIgnore = pSnap->aDelta[0];
  iRefree1 = pSnap->aDelta[1];
  iRefree2 = pSnap->aDelta[2];

  pFree = &pSnap->freelist;
  for(i=nIgnore; rc==LSM_OK && i<nElem; i++){
    rc = flAppendEntry(pEnv, pFree, aElem[i], 0);
  }

  if( rc==LSM_OK && iRefree1!=0 ) rc = flAppendEntry(pEnv, pFree, iRefree1, 0);
  if( rc==LSM_OK && iRefree2!=0 ) rc = flAppendEntry(pEnv, pFree, iRefree2, 0);

  return rc;
}
Example #4
0
void Initializer::initWorkerWatcher(const std::string& name) const {
  if (isWorker()) {
    initWorker(name);
  } else {
    // The watcher will forever monitor and spawn additional workers.
    initWatcher();
  }
}
Example #5
0
void Initializer::start() {
  // Load registry/extension modules before extensions.
  osquery::loadModules();

  // Pre-extension manager initialization options checking.
  if (FLAGS_config_check && !Watcher::hasManagedExtensions()) {
    FLAGS_disable_extensions = true;
  }

  // Bind to an extensions socket and wait for registry additions.
  osquery::startExtensionManager();

  // Then set the config plugin, which uses a single/active plugin.
  initActivePlugin("config", FLAGS_config_plugin);

  // Run the setup for all lazy registries (tables, SQL).
  Registry::setUp();

  if (FLAGS_config_check) {
    // The initiator requested an initialization and config check.
    auto s = Config::checkConfig();
    if (!s.ok()) {
      std::cerr << "Error reading config: " << s.toString() << "\n";
    }
    // A configuration check exits the application.
    ::exit(s.getCode());
  }

  // Load the osquery config using the default/active config plugin.
  Config::load();

  // Check the backing store by allocating and exiting on error.
  if (!DBHandle::checkDB()) {
    LOG(ERROR) << binary_ << " initialize failed: Could not create DB handle";
    if (isWorker()) {
      ::exit(EXIT_CATASTROPHIC);
    } else {
      ::exit(EXIT_FAILURE);
    }
  }

  // Initialize the status and result plugin logger.
  initActivePlugin("logger", FLAGS_logger_plugin);
  initLogger(binary_);

  // Start event threads.
  osquery::attachEvents();
  EventFactory::delay();
}
/*
** Release a snapshot reference obtained by calling lsmDbSnapshotWorker()
** or lsmDbSnapshotClient().
*/
void lsmDbSnapshotRelease(lsm_env *pEnv, Snapshot *pSnap){
  if( pSnap ){
    Database *p = pSnap->pDatabase;

    /* If this call is to release a pointer to the worker snapshot, relinquish
    ** the worker mutex.  
    **
    ** If pSnap is a client snapshot, decrement the reference count. When the
    ** reference count reaches zero, free the snapshot object. The decrement
    ** and (nRef==0) test are protected by the database client mutex.
    */
    if( isWorker(pSnap) ){
      lsmMutexLeave(pEnv, p->pWorkerMutex);
    }else{
      lsmMutexEnter(pEnv, p->pClientMutex);
      snapshotDecrRefcnt(pEnv, pSnap);
      lsmMutexLeave(pEnv, p->pClientMutex);
    }
  }
}
Example #7
0
void Initializer::start() const {
  // Load registry/extension modules before extensions.
  osquery::loadModules();

  // Pre-extension manager initialization options checking.
  // If the shell or daemon does not need extensions and it will exit quickly,
  // prefer to disable the extension manager.
  if ((FLAGS_config_check || FLAGS_config_dump) &&
      !Watcher::hasManagedExtensions()) {
    FLAGS_disable_extensions = true;
  }

  // A watcher should not need access to the backing store.
  // If there are spurious access then warning logs will be emitted since the
  // set-allow-open will never be called.
  if (!isWatcher()) {
    DatabasePlugin::setAllowOpen(true);
    // A daemon must always have R/W access to the database.
    DatabasePlugin::setRequireWrite(tool_ == OSQUERY_TOOL_DAEMON);
    if (!DatabasePlugin::initPlugin()) {
      LOG(ERROR) << RLOG(1629) << binary_
                 << " initialize failed: Could not initialize database";
      auto retcode = (isWorker()) ? EXIT_CATASTROPHIC : EXIT_FAILURE;
      requestShutdown(retcode);
    }
  }

  // Bind to an extensions socket and wait for registry additions.
  // After starting the extension manager, osquery MUST shutdown using the
  // internal 'shutdown' method.
  osquery::startExtensionManager();

  // Then set the config plugin, which uses a single/active plugin.
  initActivePlugin("config", FLAGS_config_plugin);

  // Run the setup for all lazy registries (tables, SQL).
  Registry::setUp();

  if (FLAGS_config_check) {
    // The initiator requested an initialization and config check.
    auto s = Config::getInstance().load();
    if (!s.ok()) {
      std::cerr << "Error reading config: " << s.toString() << "\n";
    }
    // A configuration check exits the application.
    // Make sure to request a shutdown as plugins may have created services.
    requestShutdown(s.getCode());
  }

  if (FLAGS_database_dump) {
    dumpDatabase();
    requestShutdown();
  }

  // Load the osquery config using the default/active config plugin.
  auto s = Config::getInstance().load();
  if (!s.ok()) {
    auto message = "Error reading config: " + s.toString();
    if (tool_ == OSQUERY_TOOL_DAEMON) {
      LOG(WARNING) << message;
    } else {
      LOG(INFO) << message;
    }
  }

  // Initialize the status and result plugin logger.
  if (!FLAGS_disable_logging) {
    initActivePlugin("logger", FLAGS_logger_plugin);
  }
  initLogger(binary_);

  // Initialize the distributed plugin, if necessary
  if (!FLAGS_disable_distributed) {
    if (Registry::exists("distributed", FLAGS_distributed_plugin)) {
      initActivePlugin("distributed", FLAGS_distributed_plugin);
    }
  }

  // Start event threads.
  osquery::attachEvents();
  EventFactory::delay();
}
Example #8
0
Initializer::Initializer(int& argc, char**& argv, ToolType tool)
    : argc_(&argc),
      argv_(&argv),
      tool_(tool),
      binary_((tool == OSQUERY_TOOL_DAEMON) ? "osqueryd" : "osqueryi") {
  std::srand(chrono_clock::now().time_since_epoch().count());
  // The 'main' thread is that which executes the initializer.
  kMainThreadId = std::this_thread::get_id();

  // Handled boost filesystem locale problems fixes in 1.56.
  // See issue #1559 for the discussion and upstream boost patch.
  try {
    boost::filesystem::path::codecvt();
  } catch (const std::runtime_error& e) {
    setenv("LC_ALL", "C", 1);
  }

  // osquery implements a custom help/usage output.
  for (int i = 1; i < *argc_; i++) {
    auto help = std::string((*argv_)[i]);
    if ((help == "--help" || help == "-help" || help == "--h" ||
         help == "-h") &&
        tool != OSQUERY_TOOL_TEST) {
      printUsage(binary_, tool_);
      shutdown();
    }
  }

// To change the default config plugin, compile osquery with
// -DOSQUERY_DEFAULT_CONFIG_PLUGIN=<new_default_plugin>
#ifdef OSQUERY_DEFAULT_CONFIG_PLUGIN
  FLAGS_config_plugin = STR(OSQUERY_DEFAULT_CONFIG_PLUGIN);
#endif

// To change the default logger plugin, compile osquery with
// -DOSQUERY_DEFAULT_LOGGER_PLUGIN=<new_default_plugin>
#ifdef OSQUERY_DEFAULT_LOGGER_PLUGIN
  FLAGS_logger_plugin = STR(OSQUERY_DEFAULT_LOGGER_PLUGIN);
#endif

  // Set version string from CMake build
  GFLAGS_NAMESPACE::SetVersionString(kVersion.c_str());

  // Let gflags parse the non-help options/flags.
  GFLAGS_NAMESPACE::ParseCommandLineFlags(
      argc_, argv_, (tool == OSQUERY_TOOL_SHELL));

  // Set the tool type to allow runtime decisions based on daemon, shell, etc.
  kToolType = tool;
  if (tool == OSQUERY_TOOL_SHELL) {
    // The shell is transient, rewrite config-loaded paths.
    FLAGS_disable_logging = true;
    // The shell never will not fork a worker.
    FLAGS_disable_watchdog = true;
    // Get the caller's home dir for temporary storage/state management.
    auto homedir = osqueryHomeDirectory();
    boost::system::error_code ec;
    if (osquery::pathExists(homedir).ok() ||
        boost::filesystem::create_directory(homedir, ec)) {
      // Only apply user/shell-specific paths if not overridden by CLI flag.
      if (Flag::isDefault("database_path")) {
        osquery::FLAGS_database_path = homedir + "/shell.db";
      }
      if (Flag::isDefault("extensions_socket")) {
        osquery::FLAGS_extensions_socket = homedir + "/shell.em";
      }
    } else {
      LOG(INFO) << "Cannot access or create osquery home directory";
      FLAGS_disable_extensions = true;
      FLAGS_database_path = "/dev/null";
    }
  }

  // All tools handle the same set of signals.
  // If a daemon process is a watchdog the signal is passed to the worker,
  // unless the worker has not yet started.
  std::signal(SIGTERM, signalHandler);
  std::signal(SIGABRT, signalHandler);
  std::signal(SIGINT, signalHandler);
  std::signal(SIGHUP, signalHandler);
  std::signal(SIGALRM, signalHandler);
  std::signal(SIGUSR1, signalHandler);

  // If the caller is checking configuration, disable the watchdog/worker.
  if (FLAGS_config_check) {
    FLAGS_disable_watchdog = true;
  }

  // Initialize the status and results logger.
  initStatusLogger(binary_);
  if (tool != OSQUERY_EXTENSION) {
    if (isWorker()) {
      VLOG(1) << "osquery worker initialized [watcher=" << getppid() << "]";
    } else {
      VLOG(1) << "osquery initialized [version=" << kVersion << "]";
    }
  } else {
    VLOG(1) << "osquery extension initialized [sdk=" << kSDKVersion << "]";
  }
}
Example #9
0
Initializer::Initializer(int& argc, char**& argv, ToolType tool)
    : argc_(&argc),
      argv_(&argv),
      tool_(tool),
      binary_((tool == ToolType::DAEMON) ? "osqueryd" : "osqueryi") {
  std::srand(static_cast<unsigned int>(
      chrono_clock::now().time_since_epoch().count()));

  // Initialize registries and plugins
  registryAndPluginInit();

  // The 'main' thread is that which executes the initializer.
  kMainThreadId = std::this_thread::get_id();
  // Set the tool type to allow runtime decisions based on daemon, shell, etc.
  kToolType = tool;

  // Handled boost filesystem locale problems fixes in 1.56.
  // See issue #1559 for the discussion and upstream boost patch.
  try {
    boost::filesystem::path::codecvt();
  } catch (const std::runtime_error& /* e */) {
#ifdef WIN32
    setlocale(LC_ALL, "C");
#else
    setenv("LC_ALL", "C", 1);
#endif
  }

  Flag::create("logtostderr",
               {"Log messages to stderr in addition to the logger plugin(s)",
                false,
                false,
                true,
                false});
  Flag::create("stderrthreshold",
               {"Stderr log level threshold", false, false, true, false});

  // osquery implements a custom help/usage output.
  for (int i = 1; i < *argc_; i++) {
    auto help = std::string((*argv_)[i]);
    if ((help == "--help" || help == "-help" || help == "--h" ||
         help == "-h") &&
        tool != ToolType::TEST) {
      printUsage(binary_, tool_);
      shutdown();
    }
  }

  if (tool == ToolType::SHELL) {
    // The shell is transient, rewrite config-loaded paths.
    FLAGS_disable_logging = true;
    // The shell never will not fork a worker.
    FLAGS_disable_watchdog = true;
    FLAGS_disable_events = true;
  }

  bool default_flags = false;
  if (FLAGS_flagfile.empty() && isReadable(kDefaultFlagfile)) {
    // No flagfile was set (daemons and services always set a flagfile).
    default_flags = true;
    FLAGS_flagfile = kDefaultFlagfile;
  }

  // Set version string from CMake build
  GFLAGS_NAMESPACE::SetVersionString(kVersion.c_str());

  // Let gflags parse the non-help options/flags.
  GFLAGS_NAMESPACE::ParseCommandLineFlags(
      argc_, argv_, (tool == ToolType::SHELL));

  if (tool == ToolType::SHELL) {
    if (Flag::isDefault("database_path") &&
        Flag::isDefault("disable_database")) {
      // The shell should not use a database by default, but should use the DB
      // specified by database_path if it is set
      FLAGS_disable_database = true;
    }
    // Initialize the shell after setting modified defaults and parsing flags.
    initShell();
  } else {
    // The daemon will only output ERROR logs to stderr.
    if (Flag::isDefault("stderrthreshold")) {
      Flag::updateValue("stderrthreshold", "2");
    }
  }

#ifndef WIN32
  // All tools handle the same set of signals.
  // If a daemon process is a watchdog the signal is passed to the worker,
  // unless the worker has not yet started.
  std::signal(SIGTERM, signalHandler);
  std::signal(SIGINT, signalHandler);
  std::signal(SIGHUP, signalHandler);
  std::signal(SIGALRM, signalHandler);
  std::signal(SIGCHLD, SIG_IGN);
#endif

  std::signal(SIGABRT, signalHandler);
  std::signal(SIGUSR1, signalHandler);

  // If the caller is checking configuration, disable the watchdog/worker.
  if (FLAGS_config_check) {
    FLAGS_disable_watchdog = true;
  }

  // Initialize the status and results logger.
  initStatusLogger(binary_);
  if (tool != ToolType::EXTENSION) {
    if (isWorker()) {
      VLOG(1) << "osquery worker initialized [watcher="
              << PlatformProcess::getLauncherProcess()->pid() << "]";
    } else {
      VLOG(1) << "osquery initialized [version=" << kVersion << "]";
    }
  } else {
    VLOG(1) << "osquery extension initialized [sdk=" << kSDKVersion << "]";
  }

  if (default_flags) {
    VLOG(1) << "Using default flagfile: " << kDefaultFlagfile;
  }

  // Initialize the COM libs
  platformSetup();
}
Example #10
0
Initializer::Initializer(int& argc, char**& argv, ToolType tool)
    : argc_(&argc),
      argv_(&argv),
      tool_(tool),
      binary_(fs::path(std::string(argv[0])).filename().string()) {
  std::srand(time(nullptr));

  // osquery implements a custom help/usage output.
  for (int i = 1; i < *argc_; i++) {
    auto help = std::string((*argv_)[i]);
    if ((help == "--help" || help == "-help" || help == "--h" ||
         help == "-h") &&
        tool != OSQUERY_TOOL_TEST) {
      printUsage(binary_, tool_);
      ::exit(0);
    }
  }

// To change the default config plugin, compile osquery with
// -DOSQUERY_DEFAULT_CONFIG_PLUGIN=<new_default_plugin>
#ifdef OSQUERY_DEFAULT_CONFIG_PLUGIN
  FLAGS_config_plugin = STR(OSQUERY_DEFAULT_CONFIG_PLUGIN);
#endif

// To change the default logger plugin, compile osquery with
// -DOSQUERY_DEFAULT_LOGGER_PLUGIN=<new_default_plugin>
#ifdef OSQUERY_DEFAULT_LOGGER_PLUGIN
  FLAGS_logger_plugin = STR(OSQUERY_DEFAULT_LOGGER_PLUGIN);
#endif

  // Set version string from CMake build
  GFLAGS_NAMESPACE::SetVersionString(OSQUERY_VERSION);

  // Let gflags parse the non-help options/flags.
  GFLAGS_NAMESPACE::ParseCommandLineFlags(
      argc_, argv_, (tool == OSQUERY_TOOL_SHELL));

  if (tool == OSQUERY_TOOL_SHELL) {
    // The shell is transient, rewrite config-loaded paths.
    FLAGS_disable_logging = true;
    // Get the caller's home dir for temporary storage/state management.
    auto homedir = osqueryHomeDirectory();
    if (osquery::pathExists(homedir).ok() ||
        boost::filesystem::create_directory(homedir)) {
      osquery::FLAGS_database_path = homedir + "/shell.db";
      osquery::FLAGS_extensions_socket = homedir + "/shell.em";
    }
  }

  // If the caller is checking configuration, disable the watchdog/worker.
  if (FLAGS_config_check) {
    FLAGS_disable_watchdog = true;
  }

  // Initialize the status and results logger.
  initStatusLogger(binary_);
  if (tool != OSQUERY_EXTENSION) {
    if (isWorker()) {
      VLOG(1) << "osquery worker initialized [watcher="
              << getenv("OSQUERY_WORKER") << "]";
    } else {
      VLOG(1) << "osquery initialized [version=" << OSQUERY_VERSION << "]";
    }
  } else {
    VLOG(1) << "osquery extension initialized [sdk=" << OSQUERY_SDK_VERSION
            << "]";
  }
}
Example #11
0
void Initializer::start() {
  // Load registry/extension modules before extensions.
  osquery::loadModules();

  // Pre-extension manager initialization options checking.
  if (FLAGS_config_check && !Watcher::hasManagedExtensions()) {
    FLAGS_disable_extensions = true;
  }

  // A daemon must always have R/W access to the database.
  DBHandle::setAllowOpen(true);
  DBHandle::setRequireWrite(tool_ == OSQUERY_TOOL_DAEMON);
  if (!DBHandle::checkDB()) {
    LOG(ERROR) << RLOG(1629) << binary_
               << " initialize failed: Could not open RocksDB";
    if (isWorker()) {
      ::exit(EXIT_CATASTROPHIC);
    } else {
      ::exit(EXIT_FAILURE);
    }
  }

  // Bind to an extensions socket and wait for registry additions.
  osquery::startExtensionManager();

  // Then set the config plugin, which uses a single/active plugin.
  initActivePlugin("config", FLAGS_config_plugin);

  // Run the setup for all lazy registries (tables, SQL).
  Registry::setUp();

  if (FLAGS_config_check) {
    // The initiator requested an initialization and config check.
    auto s = Config::getInstance().load();
    if (!s.ok()) {
      std::cerr << "Error reading config: " << s.toString() << "\n";
    }
    // A configuration check exits the application.
    ::exit(s.getCode());
  }

  if (FLAGS_database_dump) {
    dumpDatabase();
    ::exit(EXIT_SUCCESS);
  }

  // Load the osquery config using the default/active config plugin.
  auto s = Config::getInstance().load();
  if (!s.ok()) {
    auto message = "Error reading config: " + s.toString();
    if (tool_ == OSQUERY_TOOL_DAEMON) {
      LOG(WARNING) << message;
    } else {
      LOG(INFO) << message;
    }
  }

  // Initialize the status and result plugin logger.
  initActivePlugin("logger", FLAGS_logger_plugin);
  initLogger(binary_);

  // Initialize the distributed plugin, if necessary
  if (!FLAGS_disable_distributed) {
    if (Registry::exists("distributed", FLAGS_distributed_plugin)) {
      initActivePlugin("distributed", FLAGS_distributed_plugin);
    }
  }

  // Start event threads.
  osquery::attachEvents();
  EventFactory::delay();
}
void lsmSnapshotSetCkptid(Snapshot *pSnap, i64 iNew){
  assert( isWorker(pSnap) );
  pSnap->iId = iNew;
}
int lsmSnapshotGetNBlock(Snapshot *pSnap){
  assert( isWorker(pSnap) );
  return pSnap->nBlock;
}
/*
** Get/set methods for the snapshot block-count. These should only be
** used with worker snapshots.
*/
void lsmSnapshotSetNBlock(Snapshot *pSnap, int nNew){
  assert( isWorker(pSnap) );
  pSnap->nBlock = nNew;
}
void lsmDbSnapshotSetLevel(Snapshot *pSnap, Level *pLevel){
  assert( isWorker(pSnap) );
  pSnap->pLevel = pLevel;
}