osquery-1/include/osquery/tables.h

175 lines
5.1 KiB
C
Raw Normal View History

2014-11-25 20:30:29 +00:00
// Copyright 2004-present Facebook. All Rights Reserved.
#pragma once
#include <map>
2014-12-03 04:36:46 +00:00
#include <memory>
2014-11-25 20:30:29 +00:00
#include <vector>
#include <boost/lexical_cast.hpp>
2014-12-03 04:36:46 +00:00
#include <sqlite3.h>
#include <osquery/database/results.h>
#include <osquery/status.h>
2014-11-25 20:30:29 +00:00
namespace osquery {
namespace tables {
/**
* @brief The SQLite type affinities are available as macros
*
* Type affinities: TEXT, INTEGER, BIGINT
*
* You can represent any data that can be lexically casted to a string.
* Using the type affinity names helps table developers understand the data
* types they are storing, and more importantly how they are treated at query
* time.
*/
#define TEXT(x) boost::lexical_cast<std::string>(x)
/// See the affinity type documentation for TEXT.
2014-11-25 20:30:29 +00:00
#define INTEGER(x) boost::lexical_cast<std::string>(x)
/// See the affinity type documentation for TEXT.
2014-11-25 20:30:29 +00:00
#define BIGINT(x) boost::lexical_cast<std::string>(x)
/// See the affinity type documentation for TEXT.
2014-11-25 20:30:29 +00:00
#define UNSIGNED_BIGINT(x) boost::lexical_cast<std::string>(x)
/**
* @brief The SQLite type affinities as represented as implementation literals.
*
* Type affinities: TEXT=std::string, INTEGER=int, BIGINT=long long int
*
* Just as the SQLite data is represented as lexically casted strings, as table
* may make use of the implementation language literals.
*/
2014-11-25 20:30:29 +00:00
#define TEXT_LITERAL std::string
/// See the literal type documentation for TEXT_LITERAL.
2014-11-25 20:30:29 +00:00
#define INTEGER_LITERAL int
/// See the literal type documentation for TEXT_LITERAL.
2014-11-25 20:30:29 +00:00
#define BIGINT_LITERAL long long int
/// See the literal type documentation for TEXT_LITERAL.
2014-11-25 20:30:29 +00:00
#define UNSIGNED_BIGINT_LITERAL unsigned long long int
/// Cast an SQLite affinity type to the literal type.
2014-11-25 20:30:29 +00:00
#define AS_LITERAL(literal, value) boost::lexical_cast<literal>(value)
/**
* @brief A ConstraintOperator is applied in an query predicate.
*
* If the query contains a join or where clause with a constraint operator and
* expression the table generator may limit the data appropriately.
*/
enum ConstraintOperator {
2014-11-25 20:30:29 +00:00
EQUALS = 2,
GREATER_THAN = 4,
LESS_THAN_OR_EQUALS = 8,
LESS_THAN = 16,
GREATER_THAN_OR_EQUALS = 32
};
/**
* @brief A Constraint is an operator and expression.
*
* The constraint is applied to columns which have literal and affinity types.
*/
2014-11-25 20:30:29 +00:00
struct Constraint {
unsigned char op;
std::string expr;
/// Construct a Constraint with the most-basic information, the operator.
2014-11-25 20:30:29 +00:00
Constraint(unsigned char _op) { op = _op; }
};
/**
* @brief A ConstraintList is a set of constraints for a column. This list
* should be mapped to a left-hand-side column name.
*
* The table generator does not need to check each constraint in its decision
* logic. The common constraint checking patterns (match) are abstracted using
* simple logic operators on the literal SQLite affinity types.
*
* A constraint list supports all AS_LITERAL types, and all ConstraintOperators.
*/
2014-11-25 20:30:29 +00:00
struct ConstraintList {
/// List of constraint operator/expressions.
2014-11-25 20:30:29 +00:00
std::vector<struct Constraint> constraints;
/// The SQLite affinity type.
std::string affinity;
/**
* @brief Check if an expression matches the query constraints.
*
* @param expr a TEXT representation of the column literal type to check.
* @return If the expression matched all constraints.
*/
bool matches(const std::string& expr);
2014-11-25 20:30:29 +00:00
template <typename T>
bool matches(const T& expr) {
return literal_matches<T>(expr);
}
/**
* @brief If there is a constraint on this column.
*/
bool exists() { return (constraints.size() > 0); }
bool existsAndMatches(const std::string& expr) {
return (exists() && matches(expr));
}
bool notExistsOrMatches(const std::string& expr) {
return (!exists() || matches(expr));
}
template <typename T>
bool existsAndMatches(const T& expr);
template <typename T>
bool notExistsOrMatches(const T& expr);
/**
* @brief Helper templated function for ConstraintList::matches
*/
2014-11-25 20:30:29 +00:00
template <typename T>
bool literal_matches(const T& base_expr);
2014-11-25 20:30:29 +00:00
/**
* @brief Get all expressions for a given ConstraintOperator.
*
* This is most useful if the table generation requires as column.
* The generator may `getAll(EQUALS)` then iterate.
*
* @param op the ConstraintOperator.
* @return A list of TEXT%-represented types matching the operator.
*/
std::vector<std::string> getAll(ConstraintOperator op);
2014-11-25 20:30:29 +00:00
/**
* @brief Add a new Constraint to the list of constraints.
*
* @param constraint a new operator/expression to constrain.
*/
2014-11-25 20:30:29 +00:00
void add(const struct Constraint& constraint) {
constraints.push_back(constraint);
}
};
/// Pass a constraint map to the query request.
typedef std::map<std::string, struct ConstraintList> ConstraintMap;
/// Populate a containst list from a query's parsed predicate.
typedef std::vector<std::pair<std::string, struct Constraint> > ConstraintSet;
/**
* @brief A QueryContext is provided to every table generator for optimization
* on query components like predicate constraints and limits.
*/
struct QueryContext {
2014-11-25 20:30:29 +00:00
ConstraintMap constraints;
/// Support a limit to the number of results.
int limit;
};
typedef struct QueryContext QueryContext;
2014-11-25 20:30:29 +00:00
typedef struct Constraint Constraint;
}
2014-12-03 04:36:46 +00:00
}