00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #pragma once
00026
00027 #include <iosfwd>
00028
00029 #include <boost/regex.hpp>
00030 #include <boost/unordered_map.hpp>
00031 #include <boost/thread/mutex.hpp>
00032
00033 #include <drizzled/configmake.h>
00034 #include <drizzled/plugin/authorization.h>
00035
00036 namespace fs= boost::filesystem;
00037
00038 namespace regex_policy {
00039
00040 static const fs::path DEFAULT_POLICY_FILE= SYSCONFDIR "/drizzle.policy";
00041
00042 static const char *comment_regex = "^[[:space:]]*#.*$";
00043 static const char *empty_regex = "^[[:space:]]*$";
00044 static const char *table_match_regex = "^([^ ]+) table\\=([^ ]+) (ACCEPT|DENY)$";
00045 static const char *process_match_regex = "^([^ ]+) process\\=([^ ]+) (ACCEPT|DENY)$";
00046 static const char *schema_match_regex = "^([^ ]+) schema\\=([^ ]+) (ACCEPT|DENY)$";
00047
00048 static const int MATCH_REGEX_USER_POS= 1;
00049 static const int MATCH_REGEX_OBJECT_POS= 2;
00050 static const int MATCH_REGEX_ACTION_POS= 3;
00051
00052 typedef enum
00053 {
00054 POLICY_ACCEPT,
00055 POLICY_DENY
00056 } PolicyAction;
00057
00058 class PolicyItem
00059 {
00060 const std::string user;
00061 const std::string object;
00062 const boost::regex user_re;
00063 const boost::regex object_re;
00064 PolicyAction action;
00065 public:
00066 PolicyItem(const std::string &u, const std::string &obj, const std::string &act) :
00067 user(u),
00068 object(obj),
00069 user_re(u),
00070 object_re(obj)
00071 {
00072 if (act == "ACCEPT")
00073 {
00074 action = POLICY_ACCEPT;
00075 }
00076 else if (act == "DENY")
00077 {
00078 action = POLICY_DENY;
00079 }
00080 else
00081 {
00082 throw std::exception();
00083 }
00084 }
00085 bool userMatches(std::string &str);
00086 bool objectMatches(std::string &object_id);
00087 bool isRestricted() const;
00088 const std::string&getUser() const
00089 {
00090 return user;
00091 }
00092 const std::string&getObject() const
00093 {
00094 return object;
00095 }
00096 const char *getAction() const
00097 {
00098 return action == POLICY_ACCEPT ? "ACCEPT" : "DENY";
00099 }
00100 };
00101
00102 typedef std::list<PolicyItem *> PolicyItemList;
00103 typedef boost::unordered_map<std::string, bool> CheckMap;
00104
00105 static boost::mutex check_cache_mutex;
00106
00107 class CheckItem
00108 {
00109 std::string user;
00110 std::string object;
00111 std::string key;
00112 bool has_cached_result;
00113 bool cached_result;
00114 CheckMap **check_cache;
00115 public:
00116 CheckItem(const std::string &u, const std::string &obj, CheckMap **check_cache);
00117 bool operator()(PolicyItem *p);
00118 bool hasCachedResult() const
00119 {
00120 return has_cached_result;
00121 }
00122 bool getCachedResult() const
00123 {
00124 return cached_result;
00125 }
00126 void setCachedResult(bool result);
00127 };
00128
00129 inline bool PolicyItem::userMatches(std::string &str)
00130 {
00131 return boost::regex_match(str, user_re);
00132 }
00133
00134 inline bool PolicyItem::objectMatches(std::string &object_id)
00135 {
00136 return boost::regex_match(object_id, object_re);
00137 }
00138
00139 inline bool PolicyItem::isRestricted() const
00140 {
00141 return action == POLICY_DENY;
00142 }
00143
00144 void clearPolicyItemList(PolicyItemList policies);
00145
00146 class Policy :
00147 public drizzled::plugin::Authorization
00148 {
00149 public:
00150 Policy(const fs::path &f_path) :
00151 drizzled::plugin::Authorization("Regex Policy"), policy_file(f_path), error(),
00152 table_check_cache(NULL), schema_check_cache(NULL), process_check_cache(NULL)
00153 { }
00154
00155 virtual bool restrictSchema(const drizzled::identifier::User &user_ctx,
00156 const drizzled::identifier::Schema& schema);
00157
00158 virtual bool restrictProcess(const drizzled::identifier::User &user_ctx,
00159 const drizzled::identifier::User &session_ctx);
00160
00161 virtual bool restrictTable(const drizzled::identifier::User& user_ctx,
00162 const drizzled::identifier::Table& table);
00163
00164 bool loadFile();
00165 std::stringstream &getError() { return error; }
00166 ~Policy();
00167 private:
00168 bool restrictObject(const drizzled::identifier::User &user_ctx,
00169 const std::string &obj, const PolicyItemList &policies,
00170 CheckMap **check_cache);
00171 fs::path policy_file;
00172 std::stringstream error;
00173 PolicyItemList table_policies;
00174 PolicyItemList schema_policies;
00175 PolicyItemList process_policies;
00176 CheckMap *table_check_cache;
00177 CheckMap *schema_check_cache;
00178 CheckMap *process_check_cache;
00179 };
00180
00181 }
00182