int xColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int col) { BaseCursor *pCur = (BaseCursor *)cur; const auto *pVtab = (VirtualTable *)cur->pVtab; if (col >= static_cast<int>(pVtab->content->columns.size())) { // Requested column index greater than column set size. return SQLITE_ERROR; } const auto &column_name = pVtab->content->columns[col].first; const auto &type = pVtab->content->columns[col].second; if (pCur->row >= pCur->data.size()) { // Request row index greater than row set size. return SQLITE_ERROR; } // Attempt to cast each xFilter-populated row/column to the SQLite type. const auto &value = pCur->data[pCur->row][column_name]; if (pCur->data[pCur->row].count(column_name) == 0) { // Missing content. VLOG(1) << "Error " << column_name << " is empty"; sqlite3_result_null(ctx); } else if (type == TEXT_TYPE) { sqlite3_result_text(ctx, value.c_str(), value.size(), SQLITE_STATIC); } else if (type == INTEGER_TYPE) { long afinite; if (!safeStrtol(value, 10, afinite) || afinite < INT_MIN || afinite > INT_MAX) { VLOG(1) << "Error casting " << column_name << " (" << value << ") to INTEGER"; sqlite3_result_null(ctx); } else { sqlite3_result_int(ctx, (int)afinite); } } else if (type == BIGINT_TYPE || type == UNSIGNED_BIGINT_TYPE) { long long afinite; if (!safeStrtoll(value, 10, afinite)) { VLOG(1) << "Error casting " << column_name << " (" << value << ") to BIGINT"; sqlite3_result_null(ctx); } else { sqlite3_result_int64(ctx, afinite); } } else if (type == DOUBLE_TYPE) { char *end = nullptr; double afinite = strtod(value.c_str(), &end); if (end == nullptr || end == value.c_str() || *end != '\0') { afinite = 0; VLOG(1) << "Error casting " << column_name << " (" << value << ") to DOUBLE"; sqlite3_result_null(ctx); } else { sqlite3_result_double(ctx, afinite); } } else { LOG(ERROR) << "Error unknown column type " << column_name; } return SQLITE_OK; }
static inline EventTime timeFromRecord(const std::string& record) { // Convert a stored index "as string bytes" to a time value. long long afinite; if (!safeStrtoll(record, 10, afinite)) { return 0; } return afinite; }
Status EventFactory::registerEventSubscriber(const PluginRef& sub) { // Try to downcast the plugin to an event subscriber. EventSubscriberRef specialized_sub; try { auto base_sub = std::dynamic_pointer_cast<EventSubscriberPlugin>(sub); specialized_sub = std::static_pointer_cast<BaseEventSubscriber>(base_sub); } catch (const std::bad_cast& e) { return Status(1, "Incorrect plugin"); } if (specialized_sub == nullptr || specialized_sub.get() == nullptr) { return Status(1, "Invalid subscriber"); } // The config may use an "events" key to explicitly enabled or disable // event subscribers. See EventSubscriber::disable. auto name = specialized_sub->getName(); auto plugin = Config::getInstance().getParser("events"); if (plugin != nullptr && plugin.get() != nullptr) { const auto& data = plugin->getData(); // First perform explicit enabling. if (data.get_child("events").count("enable_subscribers") > 0) { for (const auto& item : data.get_child("events.enable_subscribers")) { if (item.second.data() == name) { VLOG(1) << "Enabling event subscriber: " << name; specialized_sub->disabled = false; } } } // Then use explicit disabling as an ultimate override. if (data.get_child("events").count("disable_subscribers") > 0) { for (const auto& item : data.get_child("events.disable_subscribers")) { if (item.second.data() == name) { VLOG(1) << "Disabling event subscriber: " << name; specialized_sub->disabled = true; } } } } // Let the module initialize any Subscriptions. auto status = Status(0, "OK"); if (!FLAGS_disable_events && !specialized_sub->disabled) { specialized_sub->expireCheck(true); status = specialized_sub->init(); specialized_sub->state(SUBSCRIBER_RUNNING); } else { specialized_sub->state(SUBSCRIBER_PAUSED); } auto& ef = EventFactory::getInstance(); ef.event_subs_[name] = specialized_sub; // Restore optimize times for a daemon. if (kToolType == OSQUERY_TOOL_DAEMON && FLAGS_events_optimize) { auto index_key = "optimize." + specialized_sub->dbNamespace(); std::string content; if (getDatabaseValue(kEvents, index_key, content)) { long long optimize_time = 0; safeStrtoll(content, 10, optimize_time); specialized_sub->optimize_time_ = static_cast<EventTime>(optimize_time); } } // Set state of subscriber. if (!status.ok()) { specialized_sub->state(SUBSCRIBER_FAILED); return Status(1, status.getMessage()); } else { return Status(0, "OK"); } }