Drizzled Public API Documentation

authorization.cc

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
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 #include <config.h>
00022 
00023 #include <vector>
00024 
00025 #include <drizzled/plugin/authorization.h>
00026 #include <drizzled/identifier.h>
00027 #include <drizzled/error.h>
00028 #include <drizzled/session.h>
00029 #include <drizzled/gettext.h>
00030 
00031 namespace drizzled
00032 {
00033 
00034 std::vector<plugin::Authorization *> authorization_plugins;
00035 
00036 
00037 bool plugin::Authorization::addPlugin(plugin::Authorization *auth)
00038 {
00039   if (auth != NULL)
00040     authorization_plugins.push_back(auth);
00041 
00042   return false;
00043 }
00044 
00045 void plugin::Authorization::removePlugin(plugin::Authorization *auth)
00046 {
00047   if (auth != NULL)
00048   {
00049     authorization_plugins.erase(std::find(authorization_plugins.begin(),
00050                                           authorization_plugins.end(),
00051                                           auth));
00052   }
00053 }
00054 
00055 namespace
00056 {
00057 
00058 class RestrictDbFunctor :
00059   public std::unary_function<plugin::Authorization *, bool>
00060 {
00061   const identifier::User &user_ctx;
00062   identifier::Schema::const_reference schema;
00063 
00064 public:
00065   RestrictDbFunctor(const identifier::User &user_ctx_arg,
00066                     identifier::Schema::const_reference schema_arg) :
00067     std::unary_function<plugin::Authorization *, bool>(),
00068     user_ctx(user_ctx_arg),
00069     schema(schema_arg)
00070   { }
00071 
00072   inline result_type operator()(argument_type auth)
00073   {
00074     return auth->restrictSchema(user_ctx, schema);
00075   }
00076 };
00077 
00078 class RestrictTableFunctor :
00079   public std::unary_function<plugin::Authorization *, bool>
00080 {
00081   identifier::User::const_reference user_ctx;
00082   identifier::Table::const_reference table;
00083 public:
00084   RestrictTableFunctor(identifier::User::const_reference user_ctx_arg,
00085                        identifier::Table::const_reference table_arg) :
00086     std::unary_function<plugin::Authorization *, bool>(),
00087     user_ctx(user_ctx_arg),
00088     table(table_arg)
00089   { }
00090 
00091   inline result_type operator()(argument_type auth)
00092   {
00093     return auth->restrictTable(user_ctx, table);
00094   }
00095 };
00096 
00097 class RestrictProcessFunctor :
00098   public std::unary_function<plugin::Authorization *, bool>
00099 {
00100   const identifier::User &user_ctx;
00101   const identifier::User &session_ctx;
00102 public:
00103   RestrictProcessFunctor(const identifier::User &user_ctx_arg,
00104                          const identifier::User &session_ctx_arg) :
00105     std::unary_function<plugin::Authorization *, bool>(),
00106     user_ctx(user_ctx_arg),
00107     session_ctx(session_ctx_arg)
00108   { }
00109 
00110   inline result_type operator()(argument_type auth)
00111   {
00112     return auth->restrictProcess(user_ctx, session_ctx);
00113   }
00114 };
00115 
00116 class PruneSchemaFunctor :
00117   public std::unary_function<identifier::Schema&, bool>
00118 {
00119   drizzled::identifier::User::const_reference user_ctx;
00120 public:
00121   PruneSchemaFunctor(drizzled::identifier::User::const_reference user_ctx_arg) :
00122     std::unary_function<identifier::Schema&, bool>(),
00123     user_ctx(user_ctx_arg)
00124   { }
00125 
00126   inline result_type operator()(argument_type auth)
00127   {
00128     return not plugin::Authorization::isAuthorized(user_ctx, auth, false);
00129   }
00130 };
00131 
00132 } /* namespace */
00133 
00134 bool plugin::Authorization::isAuthorized(identifier::User::const_reference user_ctx,
00135                                          identifier::Schema::const_reference schema_identifier,
00136                                          bool send_error)
00137 {
00138   /* If we never loaded any authorization plugins, just return true */
00139   if (authorization_plugins.empty())
00140     return true;
00141 
00142   /* Use find_if instead of foreach so that we can collect return codes */
00143   std::vector<plugin::Authorization *>::const_iterator iter=
00144     std::find_if(authorization_plugins.begin(),
00145                  authorization_plugins.end(),
00146                  RestrictDbFunctor(user_ctx, schema_identifier));
00147 
00148 
00149   /*
00150    * If iter is == end() here, that means that all of the plugins returned
00151    * false, which means that that each of them believe the user is authorized
00152    * to view the resource in question.
00153    */
00154   if (iter != authorization_plugins.end())
00155   {
00156     if (send_error)
00157     {
00158       error::access(user_ctx, schema_identifier);
00159     }
00160     return false;
00161   }
00162   return true;
00163 }
00164 
00165 bool plugin::Authorization::isAuthorized(drizzled::identifier::User::const_reference user_ctx,
00166                                          identifier::Table::const_reference table_identifier,
00167                                          bool send_error)
00168 {
00169   /* If we never loaded any authorization plugins, just return true */
00170   if (authorization_plugins.empty())
00171     return true;
00172 
00173   /* Use find_if instead of foreach so that we can collect return codes */
00174   std::vector<plugin::Authorization *>::const_iterator iter=
00175     std::find_if(authorization_plugins.begin(),
00176             authorization_plugins.end(),
00177             RestrictTableFunctor(user_ctx, table_identifier));
00178 
00179   /*
00180    * If iter is == end() here, that means that all of the plugins returned
00181    * false, which means that that each of them believe the user is authorized
00182    * to view the resource in question.
00183    */
00184   if (iter != authorization_plugins.end())
00185   {
00186     if (send_error)
00187     {
00188       error::access(user_ctx, table_identifier);
00189     }
00190     return false;
00191   }
00192   return true;
00193 }
00194 
00195 bool plugin::Authorization::isAuthorized(drizzled::identifier::User::const_reference user_ctx,
00196                                          Session::const_reference session,
00197                                          bool send_error)
00198 {
00199   /* If we never loaded any authorization plugins, just return true */
00200   if (authorization_plugins.empty())
00201     return true;
00202   
00203   // To make sure we hold the user structure we need to have a shred_ptr so
00204   // that we increase the count on the object.
00205   drizzled::identifier::User::const_shared_ptr session_ctx= session.user();
00206 
00207 
00208   /* Use find_if instead of foreach so that we can collect return codes */
00209   std::vector<plugin::Authorization *>::const_iterator iter=
00210     std::find_if(authorization_plugins.begin(),
00211                  authorization_plugins.end(),
00212                  RestrictProcessFunctor(user_ctx, *session_ctx));
00213 
00214   /*
00215    * If iter is == end() here, that means that all of the plugins returned
00216    * false, which means that that each of them believe the user is authorized
00217    * to view the resource in question.
00218    */
00219 
00220   if (iter != authorization_plugins.end())
00221   {
00222     if (send_error)
00223     {
00224       my_error(ER_KILL_DENIED_ERROR, MYF(0), session.thread_id);
00225     }
00226     return false;
00227   }
00228 
00229   return true;
00230 }
00231 
00232 void plugin::Authorization::pruneSchemaNames(drizzled::identifier::User::const_reference user_ctx,
00233                                              identifier::Schema::vector &set_of_schemas)
00234 {
00235   /* If we never loaded any authorization plugins, just return true */
00236   if (authorization_plugins.empty())
00237     return;
00238 
00239   set_of_schemas.erase(std::remove_if(set_of_schemas.begin(),
00240                                       set_of_schemas.end(),
00241                                       PruneSchemaFunctor(user_ctx)),
00242                        set_of_schemas.end());
00243 }
00244 
00245 } /* namespace drizzled */