d8693de539cfcb113956bd07ce5afd688216153b
[platform/core/security/vist.git] / src / osquery / sql / virtual_table.cpp
1 /**
2  *  Copyright (c) 2014-present, Facebook, Inc.
3  *  All rights reserved.
4  *
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.
7  */
8
9 #include <atomic>
10 #include <unordered_set>
11
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>
19
20 #include <osquery/logger.h>
21
22 namespace osquery {
23
24 RecursiveMutex kAttachMutex;
25
26 namespace tables {
27 namespace sqlite {
28 /// For planner and debugging an incrementing cursor ID is used.
29 static std::atomic<size_t> kPlannerCursorID{0};
30
31 /**
32  * @brief A next-ID for within-query constraints stacking.
33  *
34  * As constraints are evaluated within xBestIndex, an IDX is assigned for
35  * operator and operand retrieval during xFilter/scanning.
36  */
37 static std::atomic<size_t> kConstraintIndexID{0};
38
39 static inline std::string opString(unsigned char op) {
40   switch (op) {
41   case EQUALS:
42     return "=";
43   case GREATER_THAN:
44     return ">";
45   case LESS_THAN_OR_EQUALS:
46     return "<=";
47   case LESS_THAN:
48     return "<";
49   case GREATER_THAN_OR_EQUALS:
50     return ">=";
51   case LIKE:
52     return "LIKE";
53   case MATCH:
54     return "MATCH";
55   case GLOB:
56     return "GLOB";
57   case REGEXP:
58     return "REGEX";
59   case UNIQUE:
60     return "UNIQUE";
61   }
62   return "?";
63 }
64
65 namespace {
66
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;
70
71 bool getColumnValue(std::string& value,
72                     size_t index,
73                     size_t argc,
74                     sqlite3_value** argv) {
75   value.clear();
76
77   if (index >= argc) {
78     return false;
79   }
80
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);
86     break;
87   }
88
89   case SQLITE_FLOAT: {
90     auto temp = sqlite3_value_double(sqlite_value);
91     value = std::to_string(temp);
92     break;
93   }
94
95   case SQLITE_BLOB:
96   case SQLITE3_TEXT: {
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));
99
100     value.assign(data_ptr, buffer_size);
101     break;
102   }
103
104   case SQLITE_NULL: {
105     break;
106   }
107
108   default: {
109     LOG(ERROR) << "Invalid column type returned by sqlite";
110     return false;
111   }
112   }
113
114   return true;
115 }
116
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";
123                 return SQLITE_ERROR;
124         }
125
126         auto document = rapidjson::Document();
127         document.SetArray();
128         auto& allocator = document.GetAllocator();
129
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;
134
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);
139                         }
140                 }
141         }
142
143         rapidjson::StringBuffer buffer;
144         buffer.Clear();
145
146         rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
147         document.Accept(writer);
148
149         json_value_array = buffer.GetString();
150
151         return SQLITE_OK;
152 }
153 /// PATCH END /////////////////////////////////////////////////////////////////
154
155 // Type-aware serializer to pass parameters between osquery and the extension
156 int serializeUpdateParameters(std::string& json_value_array,
157                               size_t argc,
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();
163     return SQLITE_RANGE;
164   }
165
166   auto document = rapidjson::Document();
167   document.SetArray();
168
169   auto& allocator = document.GetAllocator();
170
171   for (size_t i = 2U; i < argc; i++) {
172     auto sqlite_value = argv[i];
173
174     const auto& columnDescriptor = columnDescriptors[i - 2U];
175     const auto& columnType = std::get<1>(columnDescriptor);
176
177     const auto& columnOptions = std::get<2>(columnDescriptor);
178     bool requiredColumn = (columnOptions == ColumnOptions::INDEX ||
179                            columnOptions == ColumnOptions::REQUIRED);
180
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;
187       }
188
189       auto integer =
190           static_cast<std::int64_t>(sqlite3_value_int64(sqlite_value));
191
192       document.PushBack(integer, allocator);
193       break;
194     }
195
196     case SQLITE_FLOAT: {
197       if (columnType != DOUBLE_TYPE) {
198         return SQLITE_MISMATCH;
199       }
200
201       document.PushBack(sqlite3_value_double(sqlite_value), allocator);
202       break;
203     }
204
205     case SQLITE_BLOB:
206     case SQLITE3_TEXT: {
207       bool typeMismatch = false;
208       if (receivedValueType == SQLITE_BLOB) {
209         typeMismatch = columnType != BLOB_TYPE;
210       } else {
211         typeMismatch = columnType != TEXT_TYPE;
212       }
213
214       if (typeMismatch) {
215         return SQLITE_MISMATCH;
216       }
217
218       auto data_pointer = sqlite3_value_blob(sqlite_value);
219       auto buffer_size = sqlite3_value_bytes(sqlite_value);
220
221       std::string string_data;
222       string_data.resize(buffer_size);
223       std::memcpy(&string_data[0], data_pointer, buffer_size);
224
225       rapidjson::Value value(string_data.c_str(), allocator);
226       document.PushBack(value, allocator);
227
228       break;
229     }
230
231     case SQLITE_NULL: {
232       if (requiredColumn) {
233         return SQLITE_MISMATCH;
234       }
235
236       rapidjson::Value value;
237       value.SetNull();
238
239       document.PushBack(value, allocator);
240       break;
241     }
242
243     default: {
244       LOG(ERROR) << "Invalid column type returned by sqlite";
245       return SQLITE_MISMATCH;
246     }
247     }
248   }
249
250   rapidjson::StringBuffer buffer;
251   buffer.Clear();
252
253   rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
254   document.Accept(writer);
255
256   json_value_array = buffer.GetString();
257   return SQLITE_OK;
258 }
259
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
265   //
266   // Documentation: https://www.sqlite.org/vtab.html section 1.2
267
268   if (vtable->zErrMsg != nullptr) {
269     sqlite3_free(vtable->zErrMsg);
270   }
271
272   auto buffer_size = static_cast<int>(error_message.size() + 1);
273
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);
277   }
278 }
279 } // namespace
280
281 inline std::string table_doc(const std::string& name) {
282   return "https://osquery.io/schema/#" + name;
283 }
284
285 static void plan(const std::string& output) {
286 }
287
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;
296
297   return SQLITE_OK;
298 }
299
300 int xClose(sqlite3_vtab_cursor* cur) {
301   BaseCursor* pCur = (BaseCursor*)cur;
302   plan("Closing cursor (" + std::to_string(pCur->id) + ")");
303   delete pCur;
304   return SQLITE_OK;
305 }
306
307 int xEof(sqlite3_vtab_cursor* cur) {
308   BaseCursor* pCur = (BaseCursor*)cur;
309
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.
313     return true;
314   }
315   return false;
316 }
317
318 int xDestroy(sqlite3_vtab* p) {
319   auto* pVtab = (VirtualTable*)p;
320   delete pVtab;
321   return SQLITE_OK;
322 }
323
324 int xNext(sqlite3_vtab_cursor* cur) {
325   BaseCursor* pCur = (BaseCursor*)cur;
326   pCur->row++;
327   return SQLITE_OK;
328 }
329
330 int xRowid(sqlite3_vtab_cursor* cur, sqlite_int64* pRowid) {
331   *pRowid = 0;
332
333   const BaseCursor* pCur = (BaseCursor*)cur;
334   auto data_it = std::next(pCur->rows.begin(), pCur->row);
335   if (data_it >= pCur->rows.end()) {
336     return SQLITE_ERROR;
337   }
338
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);
343 }
344
345 int xUpdate(sqlite3_vtab* p,
346             int argc,
347             sqlite3_value** argv,
348             sqlite3_int64* pRowid) {
349   auto argument_count = static_cast<size_t>(argc);
350   auto* pVtab = (VirtualTable*)p;
351
352   auto content = pVtab->content;
353   const auto& columnDescriptors = content->columns;
354
355   std::string table_name = pVtab->content->name;
356
357   // The SQLite instance communicates to the TablePlugin via the context.
358   QueryContext context(content);
359   PluginRequest plugin_request;
360
361   if (argument_count == 1U) {
362     // This is a simple delete operation
363     plugin_request = {{"action", "delete"}};
364
365     auto row_to_delete = sqlite3_value_int64(argv[0]);
366     plugin_request.insert({"id", std::to_string(row_to_delete)});
367
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"}};
378
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;
388     }
389
390     plugin_request.insert({"json_value_array", json_value_array});
391
392     if (sqlite3_value_type(argv[1]) != SQLITE_NULL) {
393       plugin_request.insert({"auto_rowid", "true"});
394
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";
398         return SQLITE_ERROR;
399       }
400
401       plugin_request.insert({"id", auto_generated_rowid});
402
403     } else {
404       plugin_request.insert({"auto_rowid", "false"});
405     }
406
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"}};
411
412     std::string current_rowid;
413     if (!getColumnValue(current_rowid, 0U, argument_count, argv)) {
414       VLOG(1) << "Failed to retrieve the column value";
415       return SQLITE_ERROR;
416     }
417
418     plugin_request.insert({"id", current_rowid});
419
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";
425         return SQLITE_ERROR;
426       }
427
428       if (new_rowid != plugin_request.at("id")) {
429         plugin_request.insert({"new_id", new_rowid});
430       }
431     }
432
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;
440     }
441
442     plugin_request.insert({"json_value_array", json_value_array});
443
444   } else {
445     VLOG(1) << "Invalid xUpdate call";
446     return SQLITE_ERROR;
447   }
448
449   TablePlugin::setRequestFromContext(context, plugin_request);
450
451   // Forward the query to the table extension
452   PluginResponse response_list;
453   Registry::call("table", table_name, plugin_request, response_list);
454
455   // Validate the response
456   if (response_list.size() != 1) {
457     VLOG(1) << "Invalid response from the extension table";
458     return SQLITE_ERROR;
459   }
460
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 "
464                "missing";
465
466     return SQLITE_ERROR;
467   }
468
469   const auto& status_value = response.at("status");
470   if (status_value == "readonly") {
471     auto error_message =
472         "table " + pVtab->content->name + " may not be modified";
473
474     setTableErrorMessage(p, error_message);
475     return SQLITE_READONLY;
476
477   } else if (status_value == "failure") {
478     auto custom_error_message_it = response.find("message");
479     if (custom_error_message_it == response.end()) {
480       return SQLITE_ERROR;
481     }
482
483     const auto& custom_error_message = custom_error_message_it->second;
484     setTableErrorMessage(p, custom_error_message);
485     return SQLITE_ERROR;
486
487   } else if (status_value == "constraint") {
488     return SQLITE_CONSTRAINT;
489
490   } else if (status_value != "success") {
491     VLOG(1) << "Invalid response from the extension table; the status field "
492                "could not be recognized";
493
494     return SQLITE_ERROR;
495   }
496
497 /*
498   // INSERT actions must always return a valid rowid to sqlite
499   if (plugin_request.at("action") == "insert") {
500     std::string rowid;
501
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";
505         return SQLITE_ERROR;
506       }
507
508     } else {
509       auto id_it = response.find("id");
510       if (id_it == response.end()) {
511         VLOG(1) << "The plugin did not return a row id";
512         return SQLITE_ERROR;
513       }
514
515       rowid = id_it->second;
516     }
517
518     auto exp = tryTo<long long>(rowid);
519     if (exp.isError()) {
520       VLOG(1) << "The plugin did not return a valid row id";
521       return SQLITE_ERROR;
522     }
523     *pRowid = exp.take();
524   }
525 */
526   return SQLITE_OK;
527 }
528
529 int xCreate(sqlite3* db,
530             void* pAux,
531             int argc,
532             const char* const* argv,
533             sqlite3_vtab** ppVtab,
534             char** pzErr) {
535   auto* pVtab = new VirtualTable;
536   if (argc == 0 || argv[0] == nullptr) {
537     delete pVtab;
538     return SQLITE_NOMEM;
539   }
540
541   memset(pVtab, 0, sizeof(VirtualTable));
542   pVtab->content = std::make_shared<VirtualTableContent>();
543   pVtab->instance = (SQLiteDBInstance*)pAux;
544
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;
549
550   // Get the table column information.
551   auto status =
552       Registry::call("table", name, {{"action", "columns"}}, response);
553   if (!status.ok() || response.size() == 0) {
554     delete pVtab;
555     return SQLITE_ERROR;
556   }
557
558   bool is_extension = false;
559
560   // Generate an SQL create table statement from the retrieved column details.
561   // This call to columnDefinition requests column aliases (as HIDDEN columns).
562   auto statement =
563       "CREATE TABLE " + name + columnDefinition(response, true, is_extension);
564
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);
569
570     VLOG(1) << "Cannot create virtual table using: " << statement;
571     delete pVtab;
572     return (rc != SQLITE_OK) ? rc : SQLITE_ERROR;
573   }
574
575   // Tables may request aliases as views.
576   std::set<std::string> views;
577
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.
584       continue;
585     }
586
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);
597         if (op) {
598           options = static_cast<ColumnOptions>(op.take());
599         }
600       }
601
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);
609       }
610     } else if (cid->second == "columnAlias" && cname != column.end()) {
611       auto ctarget = column.find("target");
612       if (ctarget == column.end()) {
613         continue;
614       }
615
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) {
626           target_index = i;
627           break;
628         }
629       }
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);
636         if (attr) {
637           pVtab->content->attributes =
638               static_cast<TableAttributes>(attr.take());
639         }
640       }
641     }
642   }
643
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);
648   }
649
650   *ppVtab = (sqlite3_vtab*)pVtab;
651   return rc;
652 }
653
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.
659     return SQLITE_ERROR;
660   }
661
662   TableRowHolder& row = pCur->rows[pCur->row];
663   return row->get_column(ctx, cur->pVtab, col);
664 }
665
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) {
670       return false;
671     }
672   }
673   return true;
674 }
675
676 static int xBestIndex(sqlite3_vtab* tab, sqlite3_index_info* pIdxInfo) {
677   auto* pVtab = (VirtualTable*)tab;
678   const auto& columns = pVtab->content->columns;
679
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.
685   double cost = 1;
686
687   // Tables may have requirements or use indexes.
688   bool required_satisfied = false;
689   bool index_used = false;
690
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];
699 #if defined(DEBUG)
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) + "]");
705 #endif
706       if (!constraint_info.usable) {
707         // A higher cost less priority, prefer more usable query constraints.
708         cost += 10;
709         continue;
710       }
711
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()) {
716         cost += 10;
717         continue;
718       }
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)) {
722         cost += 10;
723         continue;
724       }
725
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) {
729         index_used = true;
730         required_satisfied = true;
731       } else if (options & (ColumnOptions::INDEX | ColumnOptions::ADDITIONAL)) {
732         index_used = true;
733       }
734
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);
741 #if defined(DEBUG)
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) + "]");
745 #endif
746     }
747   }
748
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;
755     }
756   }
757
758   if (!index_used) {
759     // A column is marked index, but no index constraint was provided.
760     cost += 200;
761   }
762
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
769       // column is used.
770       auto bit = i < 63 ? i : 63U;
771       if (colsUsedBitset[bit]) {
772         auto column_name = std::get<0>(columns[i]);
773
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]);
780         }
781         colsUsed.insert(column_name);
782       }
783     }
784   }
785
786   pIdxInfo->idxNum = static_cast<int>(kConstraintIndexID++);
787 #if defined(DEBUG)
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) + "]");
792 #endif
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;
798   return SQLITE_OK;
799 }
800
801 static int xFilter(sqlite3_vtab_cursor* pVtabCursor,
802                    int idxNum,
803                    const char* idxStr,
804                    int argc,
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);
810
811   pCur->row = 0;
812   pCur->n = 0;
813   QueryContext context(content);
814
815   // The SQLite instance communicates to the TablePlugin via the context.
816   context.useCache(pVtab->instance->useCache());
817
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;
823
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);
829
830   // For event-based tables, help the caller if events are disabled.
831   bool events_satisfied =
832       ((content->attributes & TableAttributes::EVENT_BASED) == 0);
833
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;
845     }
846   }
847
848 // Filtering between cursors happens iteratively, not consecutively.
849 // If there are multiple sets of constraints, they apply to each cursor.
850 #if defined(DEBUG)
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) +
854        "]");
855 #endif
856
857   // Iterate over every argument to xFilter, filling in constraint values.
858   if (content->constraints.size() > 0) {
859     auto& constraints = content->constraints[idxNum];
860     if (argc > 0) {
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.
865           continue;
866         }
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);
875       }
876     } else if (constraints.size() > 0) {
877       // Constraints failed.
878     }
879
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;
886       }
887
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;
892       }
893     }
894   }
895
896   if (!content->colsUsedBitsets.empty()) {
897     context.colsUsedBitset = content->colsUsedBitsets[idxNum];
898   } else {
899     // Unspecified; have to assume all columns are used
900     context.colsUsedBitset->set();
901   }
902   if (content->colsUsed.size() > 0) {
903     context.colsUsed = content->colsUsed[idxNum];
904   }
905
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) {
911     LOG(WARNING)
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";
917   }
918
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);
924   }
925
926   // Reset the virtual table contents.
927   pCur->rows.clear();
928   options.clear();
929
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);
936   } else {
937     PluginRequest request = {{"action", "generate"}};
938     TablePlugin::setRequestFromContext(context, request);
939     QueryData qd;
940     Registry::call("table", pVtab->content->name, request, qd);
941     pCur->rows = tableRowsFromQueryData(std::move(qd));
942   }
943
944   // Set the number of rows.
945   pCur->n = pCur->rows.size();
946   return SQLITE_OK;
947 }
948
949 struct sqlite3_module* getVirtualTableModule(const std::string& table_name,
950                                              bool extension) {
951 // FIXME
952 //  UpgradeLock lock(sqlite_module_map_mutex);
953
954   if (sqlite_module_map.find(table_name) != sqlite_module_map.end()) {
955     return &sqlite_module_map[table_name];
956   }
957
958 //  WriteUpgradeLock wlock(lock);
959
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;
974
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
978
979   return &sqlite_module_map[table_name];
980 }
981 } // namespace sqlite
982 } // namespace tables
983
984 Status attachTableInternal(const std::string& name,
985                            const std::string& statement,
986                            const SQLiteDBInstanceRef& instance,
987                            bool is_extension) {
988   if (SQLiteDBManager::isDisabled(name)) {
989     VLOG(1) << "Table " << name << " is disabled, not attaching";
990     return Status(0, getStringForSQLiteReturnCode(0));
991   }
992
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
997             << "\"";
998     return Status(1);
999   }
1000
1001   // Note, if the clientData API is used then this will save a registry call
1002   // within xCreate.
1003   auto lock(instance->attachLock());
1004
1005   int rc = sqlite3_create_module(
1006       instance->db(), name.c_str(), module, (void*)&(*instance));
1007
1008   if (rc == SQLITE_OK || rc == SQLITE_MISUSE) {
1009     auto format =
1010         "CREATE VIRTUAL TABLE temp." + name + " USING " + name + statement;
1011
1012     rc =
1013         sqlite3_exec(instance->db(), format.c_str(), nullptr, nullptr, nullptr);
1014
1015   } else {
1016     LOG(ERROR) << "Error attaching table: " << name << " (" << rc << ")";
1017   }
1018
1019   return Status(rc, getStringForSQLiteReturnCode(rc));
1020 }
1021
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 << ")";
1029   }
1030
1031   return Status(rc, getStringForSQLiteReturnCode(rc));
1032 }
1033
1034 Status attachFunctionInternal(
1035     const std::string& name,
1036     std::function<
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(
1043       dbc->db(),
1044       name.c_str(),
1045       0,
1046       SQLITE_UTF8,
1047       nullptr,
1048       *func.target<void (*)(sqlite3_context*, int, sqlite3_value**)>(),
1049       nullptr,
1050       nullptr);
1051   return Status(rc);
1052 }
1053
1054 void attachVirtualTables(const SQLiteDBInstanceRef& instance) {
1055   PluginResponse response;
1056   bool is_extension = false;
1057
1058   for (const auto& name : RegistryFactory::get().names("table")) {
1059     // Column information is nice for virtual table create call.
1060     auto status =
1061         Registry::call("table", name, {{"action", "columns"}}, response);
1062     if (status.ok()) {
1063       auto statement = columnDefinition(response, true, is_extension);
1064       attachTableInternal(name, statement, instance, is_extension);
1065     }
1066   }
1067 }
1068 } // namespace osquery