2 * Copyright (c) 2014-present, Facebook, Inc.
5 * This source code is licensed in accordance with the terms specified in
6 * the LICENSE file found in the root directory of this source tree.
10 #include <unordered_set>
12 #include <osquery/core.h>
13 #include <osquery/logger.h>
14 #include <osquery/registry_factory.h>
15 #include <osquery/sql/dynamic_table_row.h>
16 #include <osquery/sql/virtual_table.h>
17 #include <osquery/system.h>
18 #include <osquery/utils/conversions/tryto.h>
20 #include <osquery/logger.h>
24 RecursiveMutex kAttachMutex;
28 /// For planner and debugging an incrementing cursor ID is used.
29 static std::atomic<size_t> kPlannerCursorID{0};
32 * @brief A next-ID for within-query constraints stacking.
34 * As constraints are evaluated within xBestIndex, an IDX is assigned for
35 * operator and operand retrieval during xFilter/scanning.
37 static std::atomic<size_t> kConstraintIndexID{0};
39 static inline std::string opString(unsigned char op) {
45 case LESS_THAN_OR_EQUALS:
49 case GREATER_THAN_OR_EQUALS:
67 // A map containing an sqlite module object for each virtual table
68 std::unordered_map<std::string, struct sqlite3_module> sqlite_module_map;
69 Mutex sqlite_module_map_mutex;
71 bool getColumnValue(std::string& value,
74 sqlite3_value** argv) {
81 auto sqlite_value = argv[index];
82 switch (sqlite3_value_type(sqlite_value)) {
83 case SQLITE_INTEGER: {
84 auto temp = sqlite3_value_int64(sqlite_value);
85 value = std::to_string(temp);
90 auto temp = sqlite3_value_double(sqlite_value);
91 value = std::to_string(temp);
97 auto data_ptr = static_cast<const char*>(sqlite3_value_blob(sqlite_value));
98 auto buffer_size = static_cast<size_t>(sqlite3_value_bytes(sqlite_value));
100 value.assign(data_ptr, buffer_size);
109 LOG(ERROR) << "Invalid column type returned by sqlite";
117 /// PATCH START //////////////////////////////////////////////////////////////
118 int serializeDeleteParameters(std::string& json_value_array,
119 VirtualTable* pVtab) {
120 auto content = pVtab->content;
121 if (content->constraints.size() <= 0) {
122 LOG(ERROR) << "Invalid constraints arguments";
126 auto document = rapidjson::Document();
128 auto& allocator = document.GetAllocator();
130 for (std::size_t i = 0; i < content->constraints.size(); i++) {
131 for (auto& constraint : content->constraints[i]) {
132 auto key = constraint.first;
133 auto value = constraint.second.expr;
135 if (!value.empty()) {
136 /// Since concrete table is not able to know the key, make alias.
137 rapidjson::Value jsonValue((key + ";" + value).c_str(), allocator);
138 document.PushBack(jsonValue, allocator);
143 rapidjson::StringBuffer buffer;
146 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
147 document.Accept(writer);
149 json_value_array = buffer.GetString();
153 /// PATCH END /////////////////////////////////////////////////////////////////
155 // Type-aware serializer to pass parameters between osquery and the extension
156 int serializeUpdateParameters(std::string& json_value_array,
158 sqlite3_value** argv,
159 const TableColumns& columnDescriptors) {
160 if (columnDescriptors.size() != argc - 2U) {
161 VLOG(1) << "Wrong column count: " << argc - 2U
162 << ". Expected: " << columnDescriptors.size();
166 auto document = rapidjson::Document();
169 auto& allocator = document.GetAllocator();
171 for (size_t i = 2U; i < argc; i++) {
172 auto sqlite_value = argv[i];
174 const auto& columnDescriptor = columnDescriptors[i - 2U];
175 const auto& columnType = std::get<1>(columnDescriptor);
177 const auto& columnOptions = std::get<2>(columnDescriptor);
178 bool requiredColumn = (columnOptions == ColumnOptions::INDEX ||
179 columnOptions == ColumnOptions::REQUIRED);
181 auto receivedValueType = sqlite3_value_type(sqlite_value);
182 switch (receivedValueType) {
183 case SQLITE_INTEGER: {
184 if (columnType != INTEGER_TYPE && columnType != BIGINT_TYPE &&
185 columnType != UNSIGNED_BIGINT_TYPE) {
186 return SQLITE_MISMATCH;
190 static_cast<std::int64_t>(sqlite3_value_int64(sqlite_value));
192 document.PushBack(integer, allocator);
197 if (columnType != DOUBLE_TYPE) {
198 return SQLITE_MISMATCH;
201 document.PushBack(sqlite3_value_double(sqlite_value), allocator);
207 bool typeMismatch = false;
208 if (receivedValueType == SQLITE_BLOB) {
209 typeMismatch = columnType != BLOB_TYPE;
211 typeMismatch = columnType != TEXT_TYPE;
215 return SQLITE_MISMATCH;
218 auto data_pointer = sqlite3_value_blob(sqlite_value);
219 auto buffer_size = sqlite3_value_bytes(sqlite_value);
221 std::string string_data;
222 string_data.resize(buffer_size);
223 std::memcpy(&string_data[0], data_pointer, buffer_size);
225 rapidjson::Value value(string_data.c_str(), allocator);
226 document.PushBack(value, allocator);
232 if (requiredColumn) {
233 return SQLITE_MISMATCH;
236 rapidjson::Value value;
239 document.PushBack(value, allocator);
244 LOG(ERROR) << "Invalid column type returned by sqlite";
245 return SQLITE_MISMATCH;
250 rapidjson::StringBuffer buffer;
253 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
254 document.Accept(writer);
256 json_value_array = buffer.GetString();
260 void setTableErrorMessage(sqlite3_vtab* vtable,
261 const std::string& error_message) {
262 // We are required to always replace the pointer with memory
263 // allocated with sqlite3_malloc. This buffer is freed automatically
264 // by sqlite3 on exit
266 // Documentation: https://www.sqlite.org/vtab.html section 1.2
268 if (vtable->zErrMsg != nullptr) {
269 sqlite3_free(vtable->zErrMsg);
272 auto buffer_size = static_cast<int>(error_message.size() + 1);
274 vtable->zErrMsg = static_cast<char*>(sqlite3_malloc(buffer_size));
275 if (vtable->zErrMsg != nullptr) {
276 memcpy(vtable->zErrMsg, error_message.c_str(), buffer_size);
281 inline std::string table_doc(const std::string& name) {
282 return "https://osquery.io/schema/#" + name;
285 static void plan(const std::string& output) {
288 int xOpen(sqlite3_vtab* tab, sqlite3_vtab_cursor** ppCursor) {
289 auto* pCur = new BaseCursor;
290 auto* pVtab = (VirtualTable*)tab;
291 plan("Opening cursor (" + std::to_string(kPlannerCursorID) +
292 ") for table: " + pVtab->content->name);
293 pCur->id = kPlannerCursorID++;
294 pCur->base.pVtab = tab;
295 *ppCursor = (sqlite3_vtab_cursor*)pCur;
300 int xClose(sqlite3_vtab_cursor* cur) {
301 BaseCursor* pCur = (BaseCursor*)cur;
302 plan("Closing cursor (" + std::to_string(pCur->id) + ")");
307 int xEof(sqlite3_vtab_cursor* cur) {
308 BaseCursor* pCur = (BaseCursor*)cur;
310 if (pCur->row >= pCur->n) {
311 // If the requested row exceeds the size of the row set then all rows
312 // have been visited, clear the data container.
318 int xDestroy(sqlite3_vtab* p) {
319 auto* pVtab = (VirtualTable*)p;
324 int xNext(sqlite3_vtab_cursor* cur) {
325 BaseCursor* pCur = (BaseCursor*)cur;
330 int xRowid(sqlite3_vtab_cursor* cur, sqlite_int64* pRowid) {
333 const BaseCursor* pCur = (BaseCursor*)cur;
334 auto data_it = std::next(pCur->rows.begin(), pCur->row);
335 if (data_it >= pCur->rows.end()) {
339 // Use the rowid returned by the extension, if available; most likely, this
340 // will only be used by extensions providing read/write tables
341 const auto& current_row = *data_it;
342 return current_row->get_rowid(pCur->row, pRowid);
345 int xUpdate(sqlite3_vtab* p,
347 sqlite3_value** argv,
348 sqlite3_int64* pRowid) {
349 auto argument_count = static_cast<size_t>(argc);
350 auto* pVtab = (VirtualTable*)p;
352 auto content = pVtab->content;
353 const auto& columnDescriptors = content->columns;
355 std::string table_name = pVtab->content->name;
357 // The SQLite instance communicates to the TablePlugin via the context.
358 QueryContext context(content);
359 PluginRequest plugin_request;
361 if (argument_count == 1U) {
362 // This is a simple delete operation
363 plugin_request = {{"action", "delete"}};
365 auto row_to_delete = sqlite3_value_int64(argv[0]);
366 plugin_request.insert({"id", std::to_string(row_to_delete)});
368 /// PATCH START //////////////////////////////////////////////////////////////
369 std::string json_value_array;
370 /// serialize constraints
371 serializeDeleteParameters(json_value_array, reinterpret_cast<VirtualTable*>(p));
372 plugin_request.insert({"json_value_array", json_value_array});
373 /// PATCH END ////////////////////////////////////////////////////////////////
374 } else if (sqlite3_value_type(argv[0]) == SQLITE_NULL) {
375 // This is an INSERT query; if the rowid has been generated for us, we'll
376 // find it inside argv[1]
377 plugin_request = {{"action", "insert"}};
379 // Add the values to insert; we should have a value for each column present
380 // in the table, even if the user did not specify a value (in which case
381 // we will find a nullptr)
382 std::string json_value_array;
383 auto serializerError = serializeUpdateParameters(
384 json_value_array, argument_count, argv, columnDescriptors);
385 if (serializerError != SQLITE_OK) {
386 VLOG(1) << "Failed to serialize the INSERT request";
387 return serializerError;
390 plugin_request.insert({"json_value_array", json_value_array});
392 if (sqlite3_value_type(argv[1]) != SQLITE_NULL) {
393 plugin_request.insert({"auto_rowid", "true"});
395 std::string auto_generated_rowid;
396 if (!getColumnValue(auto_generated_rowid, 1U, argument_count, argv)) {
397 VLOG(1) << "Failed to retrieve the column value";
401 plugin_request.insert({"id", auto_generated_rowid});
404 plugin_request.insert({"auto_rowid", "false"});
407 } else if (sqlite3_value_type(argv[0]) == SQLITE_INTEGER) {
408 // This is an UPDATE query; we have to update the rowid value in some
409 // cases (if argv[1] is populated)
410 plugin_request = {{"action", "update"}};
412 std::string current_rowid;
413 if (!getColumnValue(current_rowid, 0U, argument_count, argv)) {
414 VLOG(1) << "Failed to retrieve the column value";
418 plugin_request.insert({"id", current_rowid});
420 // Get the new rowid, if any
421 if (sqlite3_value_type(argv[1]) == SQLITE_INTEGER) {
422 std::string new_rowid;
423 if (!getColumnValue(new_rowid, 1U, argument_count, argv)) {
424 VLOG(1) << "Failed to retrieve the column value";
428 if (new_rowid != plugin_request.at("id")) {
429 plugin_request.insert({"new_id", new_rowid});
433 // Get the values to update
434 std::string json_value_array;
435 auto serializerError = serializeUpdateParameters(
436 json_value_array, argument_count, argv, columnDescriptors);
437 if (serializerError != SQLITE_OK) {
438 VLOG(1) << "Failed to serialize the UPDATE request";
439 return serializerError;
442 plugin_request.insert({"json_value_array", json_value_array});
445 VLOG(1) << "Invalid xUpdate call";
449 TablePlugin::setRequestFromContext(context, plugin_request);
451 // Forward the query to the table extension
452 PluginResponse response_list;
453 Registry::call("table", table_name, plugin_request, response_list);
455 // Validate the response
456 if (response_list.size() != 1) {
457 VLOG(1) << "Invalid response from the extension table";
461 const auto& response = response_list.at(0);
462 if (response.count("status") == 0) {
463 VLOG(1) << "Invalid response from the extension table; the status field is "
469 const auto& status_value = response.at("status");
470 if (status_value == "readonly") {
472 "table " + pVtab->content->name + " may not be modified";
474 setTableErrorMessage(p, error_message);
475 return SQLITE_READONLY;
477 } else if (status_value == "failure") {
478 auto custom_error_message_it = response.find("message");
479 if (custom_error_message_it == response.end()) {
483 const auto& custom_error_message = custom_error_message_it->second;
484 setTableErrorMessage(p, custom_error_message);
487 } else if (status_value == "constraint") {
488 return SQLITE_CONSTRAINT;
490 } else if (status_value != "success") {
491 VLOG(1) << "Invalid response from the extension table; the status field "
492 "could not be recognized";
498 // INSERT actions must always return a valid rowid to sqlite
499 if (plugin_request.at("action") == "insert") {
502 if (plugin_request.at("auto_rowid") == "true") {
503 if (!getColumnValue(rowid, 1U, argument_count, argv)) {
504 VLOG(1) << "Failed to retrieve the rowid value";
509 auto id_it = response.find("id");
510 if (id_it == response.end()) {
511 VLOG(1) << "The plugin did not return a row id";
515 rowid = id_it->second;
518 auto exp = tryTo<long long>(rowid);
520 VLOG(1) << "The plugin did not return a valid row id";
523 *pRowid = exp.take();
529 int xCreate(sqlite3* db,
532 const char* const* argv,
533 sqlite3_vtab** ppVtab,
535 auto* pVtab = new VirtualTable;
536 if (argc == 0 || argv[0] == nullptr) {
541 memset(pVtab, 0, sizeof(VirtualTable));
542 pVtab->content = std::make_shared<VirtualTableContent>();
543 pVtab->instance = (SQLiteDBInstance*)pAux;
545 // Create a TablePlugin Registry call, expect column details as the response.
546 PluginResponse response;
547 pVtab->content->name = std::string(argv[0]);
548 const auto& name = pVtab->content->name;
550 // Get the table column information.
552 Registry::call("table", name, {{"action", "columns"}}, response);
553 if (!status.ok() || response.size() == 0) {
558 bool is_extension = false;
560 // Generate an SQL create table statement from the retrieved column details.
561 // This call to columnDefinition requests column aliases (as HIDDEN columns).
563 "CREATE TABLE " + name + columnDefinition(response, true, is_extension);
565 int rc = sqlite3_declare_vtab(db, statement.c_str());
566 if (rc != SQLITE_OK || !status.ok() || response.size() == 0) {
567 LOG(ERROR) << "Error creating virtual table: " << name << " (" << rc
568 << "): " << getStringForSQLiteReturnCode(rc);
570 VLOG(1) << "Cannot create virtual table using: " << statement;
572 return (rc != SQLITE_OK) ? rc : SQLITE_ERROR;
575 // Tables may request aliases as views.
576 std::set<std::string> views;
578 // Keep a local copy of the column details in the VirtualTableContent struct.
579 // This allows introspection into the column type without additional calls.
580 for (const auto& column : response) {
581 auto cid = column.find("id");
582 if (cid == column.end()) {
583 // This does not define a column type.
587 auto cname = column.find("name");
588 auto ctype = column.find("type");
589 if (cid->second == "column" && cname != column.end() &&
590 ctype != column.end()) {
591 // This is a malformed column definition.
592 // Populate the virtual table specific persistent column information.
593 auto options = ColumnOptions::DEFAULT;
594 auto cop = column.find("op");
595 if (cop != column.end()) {
596 auto op = tryTo<long>(cop->second);
598 options = static_cast<ColumnOptions>(op.take());
602 pVtab->content->columns.push_back(std::make_tuple(
603 cname->second, columnTypeName(ctype->second), options));
604 } else if (cid->second == "alias") {
605 // Create associated views for table aliases.
606 auto calias = column.find("alias");
607 if (calias != column.end()) {
608 views.insert(calias->second);
610 } else if (cid->second == "columnAlias" && cname != column.end()) {
611 auto ctarget = column.find("target");
612 if (ctarget == column.end()) {
616 // Record the column in the set of columns.
617 // This is required because SQLITE uses indexes to identify columns.
618 // Use an UNKNOWN_TYPE as a pseudo-mask, since the type does not matter.
619 pVtab->content->columns.push_back(
620 std::make_tuple(cname->second, UNKNOWN_TYPE, ColumnOptions::HIDDEN));
621 // Record a mapping of the requested column alias name.
622 size_t target_index = 0;
623 for (size_t i = 0; i < pVtab->content->columns.size(); i++) {
624 const auto& target_column = pVtab->content->columns[i];
625 if (std::get<0>(target_column) == ctarget->second) {
630 pVtab->content->aliases[cname->second] = target_index;
631 } else if (cid->second == "attributes") {
632 auto cattr = column.find("attributes");
633 // Store the attributes locally so they may be passed to the SQL object.
634 if (cattr != column.end()) {
635 auto attr = tryTo<long>(cattr->second);
637 pVtab->content->attributes =
638 static_cast<TableAttributes>(attr.take());
644 // Create the requested 'aliases'.
645 for (const auto& view : views) {
646 statement = "CREATE VIEW " + view + " AS SELECT * FROM " + name;
647 sqlite3_exec(db, statement.c_str(), nullptr, nullptr, nullptr);
650 *ppVtab = (sqlite3_vtab*)pVtab;
654 int xColumn(sqlite3_vtab_cursor* cur, sqlite3_context* ctx, int col) {
655 BaseCursor* pCur = (BaseCursor*)cur;
656 const auto* pVtab = (VirtualTable*)cur->pVtab;
657 if (col >= static_cast<int>(pVtab->content->columns.size())) {
658 // Requested column index greater than column set size.
662 TableRowHolder& row = pCur->rows[pCur->row];
663 return row->get_column(ctx, cur->pVtab, col);
666 static inline bool sensibleComparison(ColumnType type, unsigned char op) {
667 if (type == TEXT_TYPE) {
668 if (op == GREATER_THAN || op == GREATER_THAN_OR_EQUALS || op == LESS_THAN ||
669 op == LESS_THAN_OR_EQUALS) {
676 static int xBestIndex(sqlite3_vtab* tab, sqlite3_index_info* pIdxInfo) {
677 auto* pVtab = (VirtualTable*)tab;
678 const auto& columns = pVtab->content->columns;
680 ConstraintSet constraints;
681 // Keep track of the index used for each valid constraint.
682 // Expect this index to correspond with argv within xFilter.
683 size_t expr_index = 0;
684 // If any constraints are unusable increment the cost of the index.
687 // Tables may have requirements or use indexes.
688 bool required_satisfied = false;
689 bool index_used = false;
691 // Expressions operating on the same virtual table are loosely identified by
692 // the consecutive sets of terms each of the constraint sets are applied onto.
693 // Subsequent attempts from failed (unusable) constraints replace the set,
694 // while new sets of terms append.
695 if (pIdxInfo->nConstraint > 0) {
696 for (size_t i = 0; i < static_cast<size_t>(pIdxInfo->nConstraint); ++i) {
697 // Record the term index (this index exists across all expressions).
698 const auto& constraint_info = pIdxInfo->aConstraint[i];
700 plan("Evaluating constraints for table: " + pVtab->content->name +
701 " [index=" + std::to_string(i) +
702 " column=" + std::to_string(constraint_info.iColumn) +
703 " term=" + std::to_string((int)constraint_info.iTermOffset) +
704 " usable=" + std::to_string((int)constraint_info.usable) + "]");
706 if (!constraint_info.usable) {
707 // A higher cost less priority, prefer more usable query constraints.
712 // Lookup the column name given an index into the table column set.
713 if (constraint_info.iColumn < 0 ||
714 static_cast<size_t>(constraint_info.iColumn) >=
715 pVtab->content->columns.size()) {
719 const auto& name = std::get<0>(columns[constraint_info.iColumn]);
720 const auto& type = std::get<1>(columns[constraint_info.iColumn]);
721 if (!sensibleComparison(type, constraint_info.op)) {
726 // Check if this constraint is on an index or required column.
727 const auto& options = std::get<2>(columns[constraint_info.iColumn]);
728 if (options & ColumnOptions::REQUIRED) {
730 required_satisfied = true;
731 } else if (options & (ColumnOptions::INDEX | ColumnOptions::ADDITIONAL)) {
735 // Save a pair of the name and the constraint operator.
736 // Use this constraint during xFilter by performing a scan and column
737 // name lookup through out all cursor constraint lists.
738 constraints.push_back(
739 std::make_pair(name, Constraint(constraint_info.op)));
740 pIdxInfo->aConstraintUsage[i].argvIndex = static_cast<int>(++expr_index);
742 plan("Adding constraint for table: " + pVtab->content->name +
743 " [column=" + name + " arg_index=" + std::to_string(expr_index) +
744 " op=" + std::to_string(constraint_info.op) + "]");
749 // Check the table for a required column.
750 for (const auto& column : columns) {
751 auto& options = std::get<2>(column);
752 if ((options & ColumnOptions::REQUIRED) && !required_satisfied) {
753 // A column is marked required, but no constraint satisfies.
754 return SQLITE_CONSTRAINT;
759 // A column is marked index, but no index constraint was provided.
763 UsedColumns colsUsed;
764 UsedColumnsBitset colsUsedBitset(pIdxInfo->colUsed);
765 if (colsUsedBitset.any()) {
766 for (size_t i = 0; i < columns.size(); i++) {
767 // Check whether the column is used. colUsed has one bit for each of the
768 // first 63 columns, and the 64th bit indicates that at least one other
770 auto bit = i < 63 ? i : 63U;
771 if (colsUsedBitset[bit]) {
772 auto column_name = std::get<0>(columns[i]);
774 if (pVtab->content->aliases.count(column_name)) {
775 colsUsedBitset.reset(bit);
776 auto real_column_index = pVtab->content->aliases[column_name];
777 bit = real_column_index < 63 ? real_column_index : 63U;
778 colsUsedBitset.set(bit);
779 column_name = std::get<0>(columns[real_column_index]);
781 colsUsed.insert(column_name);
786 pIdxInfo->idxNum = static_cast<int>(kConstraintIndexID++);
788 plan("Recording constraint set for table: " + pVtab->content->name +
789 " [cost=" + std::to_string(cost) +
790 " size=" + std::to_string(constraints.size()) +
791 " idx=" + std::to_string(pIdxInfo->idxNum) + "]");
793 // Add the constraint set to the table's tracked constraints.
794 pVtab->content->constraints[pIdxInfo->idxNum] = std::move(constraints);
795 pVtab->content->colsUsed[pIdxInfo->idxNum] = std::move(colsUsed);
796 pVtab->content->colsUsedBitsets[pIdxInfo->idxNum] = colsUsedBitset;
797 pIdxInfo->estimatedCost = cost;
801 static int xFilter(sqlite3_vtab_cursor* pVtabCursor,
805 sqlite3_value** argv) {
806 BaseCursor* pCur = (BaseCursor*)pVtabCursor;
807 auto* pVtab = (VirtualTable*)pVtabCursor->pVtab;
808 auto content = pVtab->content;
809 pVtab->instance->addAffectedTable(content);
813 QueryContext context(content);
815 // The SQLite instance communicates to the TablePlugin via the context.
816 context.useCache(pVtab->instance->useCache());
818 // Track required columns, this is different than the requirements check
819 // that occurs within BestIndex because this scan includes a cursor.
820 // For each cursor used, if a requirement exists, we need to scan the
821 // selected set of constraints for a match.
822 bool required_satisfied = true;
824 // The specialized table attribute USER_BASED imposes a special requirement
825 // for UID. This may be represented in the requirements, but otherwise
826 // would benefit from specific notification to the caller.
827 bool user_based_satisfied = !(
828 (content->attributes & TableAttributes::USER_BASED) > 0);
830 // For event-based tables, help the caller if events are disabled.
831 bool events_satisfied =
832 ((content->attributes & TableAttributes::EVENT_BASED) == 0);
834 std::map<std::string, ColumnOptions> options;
835 for (size_t i = 0; i < content->columns.size(); ++i) {
836 // Set the column affinity for each optional constraint list.
837 // There is a separate list for each column name.
838 auto column_name = std::get<0>(content->columns[i]);
839 context.constraints[column_name].affinity =
840 std::get<1>(content->columns[i]);
841 // Save the column options for comparison within constraints enumeration.
842 options[column_name] = std::get<2>(content->columns[i]);
843 if (options[column_name] & ColumnOptions::REQUIRED) {
844 required_satisfied = false;
848 // Filtering between cursors happens iteratively, not consecutively.
849 // If there are multiple sets of constraints, they apply to each cursor.
851 plan("Filtering called for table: " + content->name +
852 " [constraint_count=" + std::to_string(content->constraints.size()) +
853 " argc=" + std::to_string(argc) + " idx=" + std::to_string(idxNum) +
857 // Iterate over every argument to xFilter, filling in constraint values.
858 if (content->constraints.size() > 0) {
859 auto& constraints = content->constraints[idxNum];
861 for (size_t i = 0; i < static_cast<size_t>(argc); ++i) {
862 auto expr = (const char*)sqlite3_value_text(argv[i]);
863 if (expr == nullptr || expr[0] == 0) {
864 // SQLite did not expose the expression value.
867 // Set the expression from SQLite's now-populated argv.
868 auto& constraint = constraints[i];
869 constraint.second.expr = std::string(expr);
870 plan("Adding constraint to cursor (" + std::to_string(pCur->id) +
871 "): " + constraint.first + " " + opString(constraint.second.op) +
872 " " + constraint.second.expr);
873 // Add the constraint to the column-sorted query request map.
874 context.constraints[constraint.first].add(constraint.second);
876 } else if (constraints.size() > 0) {
877 // Constraints failed.
880 // Evaluate index and optimized constraint requirements.
881 // These are satisfied regardless of expression content availability.
882 for (const auto& constraint : constraints) {
883 if (options[constraint.first] & ColumnOptions::REQUIRED) {
884 // A required option exists in the constraints.
885 required_satisfied = true;
888 if (!user_based_satisfied &&
889 (constraint.first == "uid" || constraint.first == "username")) {
890 // UID was required and exists in the constraints.
891 user_based_satisfied = true;
896 if (!content->colsUsedBitsets.empty()) {
897 context.colsUsedBitset = content->colsUsedBitsets[idxNum];
899 // Unspecified; have to assume all columns are used
900 context.colsUsedBitset->set();
902 if (content->colsUsed.size() > 0) {
903 context.colsUsed = content->colsUsed[idxNum];
906 if (!user_based_satisfied) {
907 LOG(WARNING) << "The " << pVtab->content->name
908 << " table returns data based on the current user by default, "
909 "consider JOINing against the users table";
910 } else if (!required_satisfied) {
912 << "Table " << pVtab->content->name
913 << " was queried without a required column in the WHERE clause";
914 } else if (!events_satisfied) {
915 LOG(WARNING) << "Table " << pVtab->content->name
916 << " is event-based but events are disabled";
919 // Provide a helpful reference to table documentation within the shell.
920 if (Initializer::isShell() &&
921 (!user_based_satisfied || !required_satisfied || !events_satisfied)) {
922 LOG(WARNING) << "Please see the table documentation: "
923 << table_doc(pVtab->content->name);
926 // Reset the virtual table contents.
930 // Generate the row data set.
931 plan("Scanning rows for cursor (" + std::to_string(pCur->id) + ")");
932 if (Registry::get().exists("table", pVtab->content->name, true)) {
933 auto plugin = Registry::get().plugin("table", pVtab->content->name);
934 auto table = std::dynamic_pointer_cast<TablePlugin>(plugin);
935 pCur->rows = table->generate(context);
937 PluginRequest request = {{"action", "generate"}};
938 TablePlugin::setRequestFromContext(context, request);
940 Registry::call("table", pVtab->content->name, request, qd);
941 pCur->rows = tableRowsFromQueryData(std::move(qd));
944 // Set the number of rows.
945 pCur->n = pCur->rows.size();
949 struct sqlite3_module* getVirtualTableModule(const std::string& table_name,
952 // UpgradeLock lock(sqlite_module_map_mutex);
954 if (sqlite_module_map.find(table_name) != sqlite_module_map.end()) {
955 return &sqlite_module_map[table_name];
958 // WriteUpgradeLock wlock(lock);
960 sqlite_module_map[table_name] = {};
961 sqlite_module_map[table_name].xCreate = tables::sqlite::xCreate;
962 sqlite_module_map[table_name].xConnect = tables::sqlite::xCreate;
963 sqlite_module_map[table_name].xBestIndex = tables::sqlite::xBestIndex;
964 sqlite_module_map[table_name].xDisconnect = tables::sqlite::xDestroy;
965 sqlite_module_map[table_name].xDestroy = tables::sqlite::xDestroy;
966 sqlite_module_map[table_name].xOpen = tables::sqlite::xOpen;
967 sqlite_module_map[table_name].xClose = tables::sqlite::xClose;
968 sqlite_module_map[table_name].xFilter = tables::sqlite::xFilter;
969 sqlite_module_map[table_name].xNext = tables::sqlite::xNext;
970 sqlite_module_map[table_name].xEof = tables::sqlite::xEof;
971 sqlite_module_map[table_name].xColumn = tables::sqlite::xColumn;
972 sqlite_module_map[table_name].xRowid = tables::sqlite::xRowid;
973 sqlite_module_map[table_name].xUpdate = tables::sqlite::xUpdate;
975 // Allow the table to receive INSERT/UPDATE/DROP events if it is
976 // implemented from an extension and is overwriting the right methods
977 // in the TablePlugin class
979 return &sqlite_module_map[table_name];
981 } // namespace sqlite
982 } // namespace tables
984 Status attachTableInternal(const std::string& name,
985 const std::string& statement,
986 const SQLiteDBInstanceRef& instance,
988 if (SQLiteDBManager::isDisabled(name)) {
989 VLOG(1) << "Table " << name << " is disabled, not attaching";
990 return Status(0, getStringForSQLiteReturnCode(0));
993 struct sqlite3_module* module =
994 tables::sqlite::getVirtualTableModule(name, is_extension);
995 if (module == nullptr) {
996 VLOG(1) << "Failed to retrieve the virtual table module for \"" << name
1001 // Note, if the clientData API is used then this will save a registry call
1003 auto lock(instance->attachLock());
1005 int rc = sqlite3_create_module(
1006 instance->db(), name.c_str(), module, (void*)&(*instance));
1008 if (rc == SQLITE_OK || rc == SQLITE_MISUSE) {
1010 "CREATE VIRTUAL TABLE temp." + name + " USING " + name + statement;
1013 sqlite3_exec(instance->db(), format.c_str(), nullptr, nullptr, nullptr);
1016 LOG(ERROR) << "Error attaching table: " << name << " (" << rc << ")";
1019 return Status(rc, getStringForSQLiteReturnCode(rc));
1022 Status detachTableInternal(const std::string& name,
1023 const SQLiteDBInstanceRef& instance) {
1024 auto lock(instance->attachLock());
1025 auto format = "DROP TABLE IF EXISTS temp." + name;
1026 int rc = sqlite3_exec(instance->db(), format.c_str(), nullptr, nullptr, 0);
1027 if (rc != SQLITE_OK) {
1028 LOG(ERROR) << "Error detaching table: " << name << " (" << rc << ")";
1031 return Status(rc, getStringForSQLiteReturnCode(rc));
1034 Status attachFunctionInternal(
1035 const std::string& name,
1037 void(sqlite3_context* context, int argc, sqlite3_value** argv)> func) {
1038 // Hold the manager connection instance again in callbacks.
1039 auto dbc = SQLiteDBManager::get();
1040 // Add some shell-specific functions to the instance.
1041 auto lock(dbc->attachLock());
1042 int rc = sqlite3_create_function(
1048 *func.target<void (*)(sqlite3_context*, int, sqlite3_value**)>(),
1054 void attachVirtualTables(const SQLiteDBInstanceRef& instance) {
1055 PluginResponse response;
1056 bool is_extension = false;
1058 for (const auto& name : RegistryFactory::get().names("table")) {
1059 // Column information is nice for virtual table create call.
1061 Registry::call("table", name, {{"action", "columns"}}, response);
1063 auto statement = columnDefinition(response, true, is_extension);
1064 attachTableInternal(name, statement, instance, is_extension);
1068 } // namespace osquery