File authenticate_cache.hpp¶
File List > cubrid > src > object > authenticate_cache.hpp
Go to the documentation of this file
/*
*
* Copyright 2016 CUBRID Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* authenticate_cache.hpp - Define cache structures for authorzation module
*
*/
#ifndef _AUTHENTICATE_CACHE_HPP_
#define _AUTHENTICATE_CACHE_HPP_
#include "class_object.h" /* SM_CLASS */
#include <string>
#include <unordered_map>
/* Invalid cache is identified when the high bit is on. */
#define AU_CACHE_INVALID 0x80000000
/*
* AU_CLASS_CACHE
*
* This structure is attached to classes and provides a cache of
* the authorization bits. Once authorization is calculated by examining
* the group/grant hierarchy, the combined vector of bits is stored
* in the cache for faster access.
* In releases prior to 2.0, this was a single vector of bits for the
* active user. With the introduction of views, it became necessary
* to relatively quickly perform a "setuid" operation to switch
* authorization contexts within methods accessed through a view.
* Because of this, the cache has been extended to be a variable length
* array of entries, indexed by a user identifier.
*/
typedef struct au_class_cache AU_CLASS_CACHE;
struct au_class_cache
{
struct au_class_cache *next;
SM_CLASS *class_;
unsigned int *data;
au_class_cache () = delete;
au_class_cache (int depth);
~au_class_cache ();
};
/*
* AU_USER_CACHE
*
* This is used to maintain a list of the users that have been
* registered into the authorization caches. Each time a "setuid" is
* performed, the requested user is added to the caches if it is
* not already present.
*/
typedef struct au_user_cache AU_USER_CACHE;
struct au_user_cache
{
struct au_user_cache *next;
std::string name;
DB_OBJECT *user;
int index;
au_user_cache() = default;
};
/*
* AUTHORIZATION CACHING
*/
class authenticate_cache
{
public:
/*
* Au_user_cache
*
* The list of cached users.
*/
AU_USER_CACHE *user_cache;
/*
* Au_user_name_cache
*
* The map of user name to user cache
*/
using user_name_cache_t = std::unordered_map<std::string, AU_USER_CACHE *>;
user_name_cache_t user_name_cache;
/*
* Au_class_caches
*
* A list of all allocated class caches. These are maintained on a list
* so that we can get to all of them easily when they need to be
* altered.
*/
AU_CLASS_CACHE *class_caches;
/*
* Au_cache_depth
*
* These maintain information about the structure of the class caches.
* Au_cache_depth has largest current index.
* Au_cache_max has the total size of the allocated arrays.
* Au_cache_increment has the growth count when the array needs to be
* extended.
* The caches are usually allocated larger than actually necessary so
* we can avoid reallocating all of them when a new user is added.
* Probably not that big a deal.
*/
int cache_depth = 0;
int cache_max = 0;
int cache_increment = 4;
/*
* Au_cache_index
*
* This is the current index into the class authorization caches.
* It will be maintained in parallel with the current user.
* Each user is assigned a particular index, when the user changes,
* Au_cache_index is changed as well.
*/
int cache_index;
authenticate_cache ();
void init (void);
void flush (void);
int update (DB_OBJECT_TYPE obj_type, MOP mop, void *ptr);
// setter/getter of cache_index
int get_cache_index ();
void set_cache_index (int idx);
unsigned int *get_cache_bits (SM_CLASS *sm_class);
unsigned int *get_procedure_cache_bits (MOP proc_mop);
void free_authorization_cache (void *cache);
AU_USER_CACHE *make_user_cache (const char *name, DB_OBJECT *user, bool sanity_check);
AU_USER_CACHE *find_user_cache_by_name (const char *name);
AU_USER_CACHE *find_user_cache_by_mop (DB_OBJECT *user);
int get_user_cache_index (AU_USER_CACHE *cache, int *index);
void reset_cache_for_user_and_class (SM_CLASS *sm_class);
void reset_cache_for_user_and_procedure (MOP obj);
void reset_authorization_caches (void);
void remove_user_cache (MOP user);
void reset_user_cache (void);
void print_cache (int cache, FILE *fp); // for debugging
private:
// procedure cache
using procedure_cache_t = std::unordered_map<MOP, std::vector<unsigned int>*>; // <procedure, cache bits>
procedure_cache_t procedure_cache;
std::unordered_map<MOP, MOP> procedure_owner_map;
// migrate static methods
AU_CLASS_CACHE *make_class_cache (int depth);
void free_class_cache (AU_CLASS_CACHE *cache);
AU_CLASS_CACHE *install_class_cache (SM_CLASS *sm_class);
int extend_class_caches (int *index);
void free_user_cache (AU_USER_CACHE *u);
};
#endif // _AUTHENTICATE_CACHE_HPP_