return data;
}
+ virtual Status update(Row& row) {
+ return Status(0, "OK");
+ }
+
protected:
std::string columnDefinition() const;
PluginResponse routeInfo() const;
}
} 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"));
}
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());
+}
}
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,
tables::xEof,
tables::xColumn,
tables::xRowid,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
+ tables::xUpdate,
};
// clang-format on
#include <osquery/core.h>
#include <osquery/tables.h>
+#include <osquery/status.h>
+#include <osquery/logger.h>
namespace osquery {
namespace tables {
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");
+}
}
}
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")
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'",
self.header = ""
self.impl = ""
self.function = ""
+ self.function_update = ""
self.class_name = ""
self.description = ""
self.attributes = {}
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,
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(
#include <osquery/events.h>
#include <osquery/tables.h>
+#include <osquery/status.h>
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 %}\
}
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 %}