Add command feature
authorSangwan Kwon <sangwan.kwon@samsung.com>
Tue, 20 Aug 2019 05:27:21 +0000 (14:27 +0900)
committerSangwan Kwon <sangwan.kwon@samsung.com>
Thu, 5 Sep 2019 02:33:40 +0000 (11:33 +0900)
- Origin osquery only supports query feature (SELECT)
+ Tizen osquery adds command feature (UPDATE)

Signed-off-by: Sangwan Kwon <sangwan.kwon@samsung.com>
include/osquery/tables.h
osquery/core/tables.cpp
osquery/sql/tests/virtual_table_tests.cpp
osquery/sql/virtual_table.cpp
osquery/tables/system/linux/users.cpp
osquery/tizen/CMakeLists.txt
specs/users.table
tools/codegen/gentable.py
tools/codegen/templates/default.cpp.in

index b7a6369..f2db419 100644 (file)
@@ -318,6 +318,10 @@ class TablePlugin : public Plugin {
     return data;
   }
 
+  virtual Status update(Row& row) {
+    return Status(0, "OK");
+  }
+
  protected:
   std::string columnDefinition() const;
   PluginResponse routeInfo() const;
index b946731..d71fd22 100644 (file)
@@ -116,6 +116,10 @@ Status TablePlugin::call(const PluginRequest& request,
     }
   } else if (request.at("action") == "definition") {
     response.push_back({{"definition", columnDefinition()}});
+  } else if (request.at("action") == "update") {
+    Row row = request;
+    row.erase("action");
+    return update(row);
   } else {
     return Status(1, "Unknown table plugin action: " + request.at("action"));
   }
index d5ac553..c08cce6 100644 (file)
@@ -77,4 +77,24 @@ TEST_F(VirtualTableTests, test_sqlite3_table_joins) {
   EXPECT_TRUE(status.ok());
   EXPECT_EQ(results.size(), 1);
 }
+
+TEST_F(VirtualTableTests, test_sqlite3_table_update_where) {
+  // Get a database connection.
+  auto dbc = SQLiteDBManager::get();
+
+  QueryData results;
+  std::string statement = "UPDATE users SET uid = 1234, gid = 232 WHERE uid = 0";
+  auto status = queryInternal(statement, results, dbc.db());
+  EXPECT_TRUE(status.ok());
+}
+
+TEST_F(VirtualTableTests, test_sqlite3_table_update) {
+  // Get a database connection.
+  auto dbc = SQLiteDBManager::get();
+
+  QueryData results;
+  std::string statement = "UPDATE users SET uid = 1234, gid = 232";
+  auto status = queryInternal(statement, results, dbc.db());
+  EXPECT_TRUE(status.ok());
+}
 }
index c8b62a0..1a51ad9 100644 (file)
@@ -62,6 +62,35 @@ int xRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid) {
   return SQLITE_OK;
 }
 
+int xUpdate(sqlite3_vtab *pVTab,
+            int argc,
+            sqlite3_value **argv,
+            sqlite3_int64 *pRowid)
+{
+  auto * pVtab = (VirtualTable *)pVTab;
+  if (argc <= 1 || argc - 2 !=  pVtab->content->columns.size()) {
+    LOG(ERROR) << "Invalid arguments: " << argc;
+    return SQLITE_ERROR;
+  }
+
+  PluginRequest request = {{"action", "update"}};
+  const auto& columns = pVtab->content->columns;
+  for (size_t i = 2; i < static_cast<size_t>(argc); ++i) {
+    auto expr = (const char *)sqlite3_value_text(argv[i]);
+    if (expr == nullptr) {
+      // SQLite did not expose the expression value.
+      continue;
+    } else {
+       request.insert(std::make_pair(columns[i - 2].first, std::string(expr)));
+    }
+  }
+
+  PluginResponse response;
+  Registry::call("table", pVtab->content->name, request, response);
+
+  return SQLITE_OK;
+}
+
 int xCreate(sqlite3 *db,
             void *pAux,
             int argc,
@@ -278,13 +307,7 @@ Status attachTableInternal(const std::string &name,
       tables::xEof,
       tables::xColumn,
       tables::xRowid,
-      0,
-      0,
-      0,
-      0,
-      0,
-      0,
-      0,
+      tables::xUpdate,
   };
   // clang-format on
 
index a816bac..6108987 100644 (file)
@@ -17,6 +17,8 @@
 
 #include <osquery/core.h>
 #include <osquery/tables.h>
+#include <osquery/status.h>
+#include <osquery/logger.h>
 
 namespace osquery {
 namespace tables {
@@ -50,5 +52,13 @@ QueryData genUsers(QueryContext& context) {
 
   return results;
 }
+
+/// Example of update feature
+Status updateUsers(Row& row) {
+  for (auto& r : row)
+    LOG(ERROR) << "DEBUG: " << r.first << ", " << r.second;
+
+  return Status(0, "OK");
+}
 }
 }
index 8cb3170..669f1bb 100644 (file)
@@ -17,13 +17,13 @@ ADD_OSQUERY_LIBRARY(osquery_tizen property/property.cpp
                                                                  manager/manager_impl.cpp
                                                                  notification/notification.cpp)
 
-FILE(GLOB OSQUERY_TIZEN_TESTS "[!d]*/tests/*.cpp")
 ADD_OSQUERY_TEST(${OSQUERY_TIZEN_TESTS})
 
 IF(DEFINED GBS_BUILD)
        # tables
        FILE(GLOB TIZEN_TABLES "tables/*.cpp")
        ADD_OSQUERY_LIBRARY(tizen_tables ${TIZEN_TABLES})
+       FILE(GLOB OSQUERY_TIZEN_TESTS "[!d]*/tests/*.cpp")
 
 # Verification can be done with full-DPM
 #      FILE(GLOB OSQUERY_GBS_TESTS "device_policy/tests/*.cpp")
index 99be598..e5dab55 100644 (file)
@@ -11,6 +11,7 @@ schema([
     Column("shell", TEXT, "User's configured default shell"),
 ])
 implementation("users@genUsers")
+implementation_update("users@updateUsers")
 examples([
   "select * from users where uid = 1000",
   "select * from users where username = 'root'",
index b7fb75f..163f37a 100755 (executable)
@@ -141,6 +141,7 @@ class TableState(Singleton):
         self.header = ""
         self.impl = ""
         self.function = ""
+        self.function_update = ""
         self.class_name = ""
         self.description = ""
         self.attributes = {}
@@ -162,6 +163,7 @@ class TableState(Singleton):
             header=self.header,
             impl=self.impl,
             function=self.function,
+            function_update=self.function_update,
             class_name=self.class_name,
             attributes=self.attributes,
             examples=self.examples,
@@ -311,6 +313,15 @@ def implementation(impl_string):
             sys.exit(1)
 
 
+def implementation_update(impl_string=None):
+    if impl_string is None:
+        table.function_update = ""
+    else:
+        filename, function = impl_string.split("@")
+        class_parts = function.split("::")[::-1]
+        table.function_update = class_parts[0]
+
+
 def main(argc, argv):
     parser = argparse.ArgumentParser("Generate C++ Table Plugin from specfile.")
     parser.add_argument(
index 473f574..348843c 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <osquery/events.h>
 #include <osquery/tables.h>
+#include <osquery/status.h>
 
 namespace osquery {
 
@@ -21,10 +22,16 @@ namespace osquery {
 namespace tables {
 {% if class_name == "" %}\
 osquery::QueryData {{function}}(QueryContext& request);
+{% if function_update != "" %}\
+osquery::Status {{function_update}}(Row& row);
+{% endif %}\
 {% else %}
 class {{class_name}} {
  public:
   osquery::QueryData {{function}}(QueryContext& request);
+{% if function_update != "" %}\
+  osquery::Status {{function_update}}(Row& row);
+{% endif %}\
 };
 {% endif %}\
 }
@@ -52,8 +59,15 @@ class {{table_name_cc}}TablePlugin : public TablePlugin {
     return tables::{{function}}(request);
 {% endif %}\
   }
+
+{% if function_update != "" %}\
+  Status update(Row& row) {
+    return tables::{{function_update}}(row);
+  }
+{% endif %}\
 };
 
+
 {% if attributes.utility %}
 REGISTER_INTERNAL({{table_name_cc}}TablePlugin, "table", "{{table_name}}");
 {% else %}