Drizzled Public API Documentation

policy.h

00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2010 Monty Taylor <mordred@inaugust.com>
00005  *  Copyright (C) 2011 Canonical, Ltd.
00006  *  Author: Clint Byrum <clint.byrum@canonical.com>
00007  *
00008  *  Copied from simple_user_policy
00009  *
00010  *  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; version 2 of the License.
00013  *
00014  *  This program is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with this program; if not, write to the Free Software
00021  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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 /* These correspond to the parenthesis above and must stay in sync */
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 } /* namespace regex_policy */
00184