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