This commit is contained in:
Cachuela 2023-09-28 09:04:19 +08:00
parent d4ae513702
commit f73fad8bd5
2 changed files with 128 additions and 50 deletions

View File

@ -170,44 +170,69 @@ int PgPolicyPrivilegesAccessStruct::operator - (const PgPolicyPrivilegesAccessSt
// 处理来自解析器树的新筛选器,并将它们转化为字符串
bool process_new_filters(const List *policy_filters, gs_stl::gs_string *flat_tree)
{
// 如果策略过滤器为空直接返回true
if (!policy_filters)
return true;
// 清空输出的扁平化树字符串
flat_tree->clear();
ListCell *policy_filter_item = NULL;
// 用于存储策略树节点的堆栈
gs_stl::gs_vector<PolicyFilterNode *> nodes;
// 遍历策略过滤器列表
ListCell *policy_filter_item = NULL;
foreach(policy_filter_item, policy_filters) {
PolicyFilterNode *root = (PolicyFilterNode *) lfirst(policy_filter_item);
nodes.push_back(root);
// 迭代处理策略树节点
while (nodes.size() > 0) {
PolicyFilterNode* n = nodes.back();
nodes.pop_back();
/* operator type node */
// 如果节点类型为操作符节点
if (!strcmp(n->node_type, "op")) {
if (!strcmp(n->op_value, "and")) {
// 将逻辑与操作符 "*" 添加到扁平化树中
(void)flat_tree->append("*");
} else if (!strcmp(n->op_value, "or")) {
// 将逻辑或操作符 "+" 添加到扁平化树中
(void)flat_tree->append("+");
} else { /* unsupported operator */
} else {
// 不支持的操作符类型返回false表示处理失败
return false;
}
// 将右子节点和左子节点压入堆栈,以便继续处理
nodes.push_back((PolicyFilterNode *)n->right);
nodes.push_back((PolicyFilterNode *)n->left);
} else if (!strcmp(n->node_type, "filter")) { /* value type node */
} else if (!strcmp(n->node_type, "filter")) { // 如果节点类型为值节点
if (n->has_not_operator == true) {
// 如果节点带有 "!" 表示否定操作符,则将 "!" 添加到扁平化树中
(void)flat_tree->append("!");
}
// 添加策略过滤器的类型到扁平化树中
(void)flat_tree->append(n->filter_type);
(void)flat_tree->append("[");
List *filter_item_objects = (List *) n->values;
ListCell *filter_obj = NULL;
// 遍历策略过滤器的值列表
foreach(filter_obj, filter_item_objects) {
const char *filter_value = (const char *)(((Value*)lfirst(filter_obj))->val.str);
// 验证策略过滤器的值是否有效如果无效则返回false表示处理失败
if (!verify_ip_role_app(n->filter_type, filter_value, flat_tree)) {
return false;
}
// 添加策略过滤器的值到扁平化树中,并用逗号分隔
(void)flat_tree->append(",");
}
// 如果扁平化树的最后一个字符是逗号,则删除它
if (flat_tree->back() == ',') {
flat_tree->pop_back();
}
@ -215,9 +240,12 @@ bool process_new_filters(const List *policy_filters, gs_stl::gs_string *flat_tre
}
}
}
// 处理完毕返回true表示处理成功
return true;
}
bool scan_to_delete_from_relation(long long row_id, Relation relation, unsigned int index_id)
{// 如果关系为空返回false
if (relation == NULL) {
@ -372,12 +400,20 @@ bool handle_target(ListCell *target,
const policy_labels_map *existing_labels,
const GsPolicyStruct *policy, const char *acc_action_type)
{
// 用于返回操作结果的变量
bool ret = false;
// 根据策略选项类型进行不同的处理
switch (opt_type) {
case POLICY_OPT_PRIVILEGES: {
// 获取目标对象的RangeVar
RangeVar *rel = (RangeVar*)lfirst(target);
// 构建目标对象的名称字符串
gs_stl::gs_string target_name_s;
construct_resource_name((const RangeVar*)rel, &target_name_s);
// 根据操作类型添加或删除调用add_privileges_access函数处理特权访问控制
if (is_add) {
ret = add_privileges_access(acc_action_type, target_name_s.c_str(), privs_to_add,
existing_labels, policy, err_msg);
@ -388,9 +424,14 @@ bool handle_target(ListCell *target,
}
break;
case POLICY_OPT_ACCESS: {
// 获取目标对象的RangeVar
RangeVar *rel = (RangeVar*)lfirst(target);
// 构建目标对象的名称字符串
gs_stl::gs_string target_name_s;
construct_resource_name((const RangeVar*)rel, &target_name_s);
// 根据操作类型添加或删除调用add_privileges_access函数处理访问控制
if (is_add) {
ret = add_privileges_access(acc_action_type, target_name_s.c_str(), access_to_add, existing_labels,
policy, err_msg);
@ -400,12 +441,15 @@ bool handle_target(ListCell *target,
}
}
break;
// : this is not handled here...
// : 这里未处理其他策略选项类型
default:
break;
}
// 返回操作结果
return ret;
}
// 这个函数用于解析逗号分隔的值,并验证它们的有效性。
static bool parse_values(const gs_stl::gs_string logical_expr_str, int *offset, const char* obj_type)
{

View File

@ -32,6 +32,7 @@ namespace gs_stl {
MemoryContext GetStringMemory()
{
if (t_thrd.security_policy_cxt.StringMemoryContext == NULL) {
// 如果字符串内存上下文尚未创建,则创建一个新的字符串内存上下文
t_thrd.security_policy_cxt.StringMemoryContext =
AllocSetContextCreate(THREAD_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_SECURITY), "StringMemory",
ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE);
@ -42,6 +43,7 @@ MemoryContext GetStringMemory()
void DeleteStringMemory()
{
if (t_thrd.security_policy_cxt.StringMemoryContext != NULL) {
// 如果字符串内存上下文存在,则删除它
MemoryContextDelete(t_thrd.security_policy_cxt.StringMemoryContext);
t_thrd.security_policy_cxt.StringMemoryContext = NULL;
}
@ -50,6 +52,7 @@ void DeleteStringMemory()
MemoryContext GetVectorMemory()
{
if (t_thrd.security_policy_cxt.VectorMemoryContext == NULL) {
// 如果向量内存上下文尚未创建,则创建一个新的向量内存上下文
t_thrd.security_policy_cxt.VectorMemoryContext =
AllocSetContextCreate(THREAD_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_SECURITY), "VectorMemory",
ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE);
@ -60,6 +63,7 @@ MemoryContext GetVectorMemory()
void DeleteVectorMemory()
{
if (t_thrd.security_policy_cxt.VectorMemoryContext != NULL) {
// 如果向量内存上下文存在,则删除它
MemoryContextDelete(t_thrd.security_policy_cxt.VectorMemoryContext);
t_thrd.security_policy_cxt.VectorMemoryContext = NULL;
}
@ -68,6 +72,7 @@ void DeleteVectorMemory()
MemoryContext GetMapMemory()
{
if (!t_thrd.security_policy_cxt.MapMemoryContext) {
// 如果映射内存上下文尚未创建,则创建一个新的映射内存上下文
t_thrd.security_policy_cxt.MapMemoryContext = AllocSetContextCreate(TopMemoryContext, "MapMemory",
ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE);
}
@ -77,6 +82,7 @@ MemoryContext GetMapMemory()
void DeleteMapMemory()
{
if (t_thrd.security_policy_cxt.MapMemoryContext) {
// 如果映射内存上下文存在,则删除它
MemoryContextDelete(t_thrd.security_policy_cxt.MapMemoryContext);
t_thrd.security_policy_cxt.MapMemoryContext = nullptr;
}
@ -84,12 +90,14 @@ void DeleteMapMemory()
void *_HashMapAllocFunc(Size request)
{
// 使用映射内存上下文分配内存
return MemoryContextAlloc(GetMapMemory(), request);
}
MemoryContext GetSetMemory()
{
if (!t_thrd.security_policy_cxt.SetMemoryContext) {
// 如果集合内存上下文尚未创建,则创建一个新的集合内存上下文
t_thrd.security_policy_cxt.SetMemoryContext = AllocSetContextCreate(TopMemoryContext, "SetMemory",
ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE);
}
@ -99,6 +107,7 @@ MemoryContext GetSetMemory()
void DeleteSetMemory()
{
if (t_thrd.security_policy_cxt.SetMemoryContext) {
// 如果集合内存上下文存在,则删除它
MemoryContextDelete(t_thrd.security_policy_cxt.SetMemoryContext);
t_thrd.security_policy_cxt.SetMemoryContext = nullptr;
}
@ -106,16 +115,19 @@ void DeleteSetMemory()
void *_HashSetAllocFunc(Size request)
{
// 使用集合内存上下文分配内存
return MemoryContextAlloc(GetSetMemory(), request);
}
int matchStr(const void *key1, const void *key2, Size keysize)
{
// 比较两个字符串是否相等(不区分大小写)
return strncasecmp((const char *)key1, (const char *)key2, keysize - 1);
}
int gs_stringCompareKeyFunc(const void *keyA, const void *keyB)
{
// 比较两个gs_string对象作为键的大小
if (*(const gs_string *)keyA < *(const gs_string *)keyB) {
return -1;
} else if (*(const gs_string *)keyB < *(const gs_string *)keyA) {
@ -125,23 +137,28 @@ int gs_stringCompareKeyFunc(const void *keyA, const void *keyB)
}
}
// string implementation
// 初始化字符串缓冲区
inline bool gs_string::InitBuff(const char *str, size_t len)
{
if (m_buff == NULL) {
size_t init_len = (len > 0) ? (len + 1) : (strlen(str) + 1);
m_capacity = Max(MIN_STR_CAPACITY, init_len);
m_buff = AllocFunc(m_capacity);
errno_t ret = snprintf_s(m_buff, m_capacity, init_len - 1, "%.*s", (int)(init_len - 1), str);
securec_check_ss(ret, "\0", "\0");
m_len = (size_t)ret;
return true;
// 如果字符串缓冲区为空,执行初始化
size_t init_len = (len > 0) ? (len + 1) : (strlen(str) + 1); // 计算初始化长度
m_capacity = Max(MIN_STR_CAPACITY, init_len); // 设置容量至少为MIN_STR_CAPACITY
m_buff = AllocFunc(m_capacity); // 分配内存
errno_t ret = snprintf_s(m_buff, m_capacity, init_len - 1, "%.*s", (int)(init_len - 1), str); // 格式化字符串
securec_check_ss(ret, "\0", "\0"); // 检查 snprintf_s 的返回值
m_len = (size_t)ret; // 设置字符串长度
return true; // 返回初始化成功
}
return false;
return false; // 如果缓冲区不为空,返回初始化失败
}
// 构造函数,用于创建 gs_string 对象
gs_string::gs_string(const char *str, size_t len) : m_buff(NULL), m_len(0), m_capacity(0)
{
(void)InitBuff(str, len);
(void)InitBuff(str, len); // 调用 InitBuff 进行初始化
}
gs_string::~gs_string()
@ -161,18 +178,20 @@ gs_string::~gs_string()
}
}
// 构造函数,从另一个 gs_string 对象拷贝构造
gs_string::gs_string(const gs_string &arg) : m_buff(NULL), m_len(0), m_capacity(0)
{
operator = (arg);
operator = (arg); // 调用赋值运算符函数来复制内容
}
// 赋值运算符函数,将一个 gs_string 对象的内容赋值给另一个对象
gs_string &gs_string::operator = (const gs_string &arg)
{
if (&arg == this) {
return *this;
return *this; // 避免自赋值
}
/* m_buff should always be free if not NULL as will be taken place with arg */
// 释放当前对象的缓冲区内存
if (m_buff != NULL) {
pfree(m_buff);
m_buff = NULL;
@ -180,13 +199,14 @@ gs_string &gs_string::operator = (const gs_string &arg)
size_t len = arg.size();
if (len > 0) {
(void)InitBuff(arg.c_str(), arg.size());
(void)InitBuff(arg.c_str(), arg.size()); // 初始化当前对象的缓冲区
} else {
(void)InitBuff("", 0);
(void)InitBuff("", 0); // 如果源字符串为空,则初始化为一个空字符串
}
return *this;
}
// 重载运算符 -,用于字符串比较
int gs_string::operator - (const gs_string &arg) const
{
if (this == &arg) {
@ -201,45 +221,50 @@ int gs_string::operator - (const gs_string &arg) const
return 0;
}
// 追加一个 gs_string 对象到当前对象
gs_string &gs_string::append(const gs_string &str)
{
return append(str.c_str(), str.size());
}
// 追加一个字符串到当前对象
gs_string &gs_string::append(const char *str, size_t len)
{
if (!InitBuff(str)) {
size_t init_len = (len > 0) ? (len + 1) : (strlen(str) + 1);
if (init_len > (m_capacity - m_len)) {
m_buff = ReallocFunc(m_capacity + init_len);
m_buff = ReallocFunc(m_capacity + init_len); // 如果空间不足,重新分配更大的空间
}
errno_t ret = snprintf_s(m_buff + m_len, m_capacity - m_len, init_len - 1, "%.*s", (int)(init_len - 1), str);
securec_check_ss(ret, "\0", "\0");
m_len += (size_t)ret;
m_len += (size_t)ret; // 更新字符串长度
}
return *this;
}
// 在字符串末尾添加一个字符
void gs_string::push_back(char ch)
{
char t_chr[2] = {0};
t_chr[1] = ch;
if (!InitBuff(t_chr)) {
if ((m_len + 1) >= m_capacity) {
m_buff = ReallocFunc(m_capacity * 2);
m_buff = ReallocFunc(m_capacity * 2); // 如果空间不足,扩展为当前的两倍
}
m_buff[m_len++] = ch;
m_buff[m_len] = '\0';
m_buff[m_len++] = ch; // 添加字符到缓冲区末尾
m_buff[m_len] = '\0'; // 添加字符串结束符
}
}
// 删除字符串末尾的字符
void gs_string::pop_back()
{
if (m_len > 0) {
m_buff[--m_len] = '\0';
m_buff[--m_len] = '\0'; // 删除最后一个字符并添加结束符
}
}
// 访问字符串的字符,类似于数组下标访问
char gs_string::operator[](int idx) const
{
if (idx > (int)m_len) {
@ -248,14 +273,16 @@ char gs_string::operator[](int idx) const
return m_buff[idx];
}
// 清空字符串
void gs_string::clear()
{
if (m_buff != NULL) {
m_buff[0] = '\0';
m_len = 0;
m_buff[0] = '\0'; // 将字符串清空
m_len = 0; // 长度设为0
}
}
// 在字符串中查找字符的位置
size_t gs_string::find(char arg, size_t start) const
{
for (; start < m_len; ++start) {
@ -263,28 +290,31 @@ size_t gs_string::find(char arg, size_t start) const
return start;
}
}
return npos;
return npos; // 如果未找到返回npos无效位置
}
// 返回字符串的最后一个字符
char gs_string::back() const
{
if (m_len > 0) {
return m_buff[m_len - 1];
return m_buff[m_len - 1]; // 返回最后一个字符
}
return m_buff[0];
return m_buff[0]; // 如果字符串为空,返回第一个字符
}
// 截取字符串的子串
gs_string gs_string::substr(size_t pos, size_t len) const
{
if ((pos + len) < m_len) {
return gs_string((const char *)(m_buff + pos), len);
return gs_string((const char *)(m_buff + pos), len); // 返回指定位置和长度的子串
}
if (pos < m_len) {
return gs_string((const char *)(m_buff + pos), m_len - pos);
return gs_string((const char *)(m_buff + pos), m_len - pos); // 返回从指定位置到末尾的子串
}
return gs_string((const char *)m_buff, m_len);
return gs_string((const char *)m_buff, m_len); // 返回整个字符串
}
// 替换字符串的一部分
gs_string &gs_string::replace(size_t pos, size_t len, const char *s)
{
if (pos < m_len) {
@ -293,7 +323,7 @@ gs_string &gs_string::replace(size_t pos, size_t len, const char *s)
size_t jump = (rep_len - len);
errno_t ret = EOK;
if ((m_len + jump) >= m_capacity) {
(void)ReallocFunc(m_capacity + jump);
(void)ReallocFunc(m_capacity + jump); // 如果空间不足,重新分配更大的空间
}
if (replace_len < m_len) {
@ -315,6 +345,7 @@ gs_string &gs_string::replace(size_t pos, size_t len, const char *s)
return *this;
}
// 删除字符串的一部分
void gs_string::erase(size_t pos, size_t len)
{
if (m_len == 0 || (pos >= m_len)) {
@ -325,48 +356,51 @@ void gs_string::erase(size_t pos, size_t len)
while (idx < m_len) {
m_buff[pos++] = m_buff[idx++];
}
m_len = pos;
m_len = pos; // 更新字符串长度
} else {
m_len = pos;
m_len = pos; // 删除指定位置后的所有字符
}
m_buff[m_len] = '\0';
m_buff[m_len] = '\0'; // 添加字符串结束符
}
// 比较两个字符串是否相等
bool gs_string::operator == (const gs_string &arg) const
{
if (m_len != arg.m_len) {
return false;
return false; // 长度不同,字符串不等
}
if (m_len > 0) {
return (strcasecmp(m_buff, arg.m_buff) == 0);
return (strcasecmp(m_buff, arg.m_buff) == 0); // 大小写不敏感比较字符串
}
return m_len == 0;
return m_len == 0; // 空字符串相等
}
// 比较两个字符串的大小
bool gs_string::operator < (const gs_string &arg) const
{
return strcasecmp(m_buff, arg.m_buff) < 0;
return strcasecmp(m_buff, arg.m_buff) < 0; // 大小写不敏感比较字符串大小
}
// 分配内存并返回指向内存的指针
inline char *gs_string::AllocFunc(size_t _size) const
{
return (char *)MemoryContextAlloc(GetStringMemory(), _size);
return (char *)MemoryContextAlloc(GetStringMemory(), _size); // 分配内存使用GetStringMemory()分配
}
// 重新分配内存
inline char *gs_string::ReallocFunc(size_t _size)
{
m_capacity = _size;
m_capacity = _size; // 更新容量
char *buff = AllocFunc(m_capacity);
/* copy old data */
char *buff = AllocFunc(m_capacity); // 分配新内存
/* 复制旧数据 */
if (m_buff != NULL) {
errno_t ret = snprintf_s(buff, m_capacity, strlen(m_buff), "%s", m_buff);
errno_t ret = snprintf_s(buff, m_capacity, strlen(m_buff), "%s", m_buff); // 复制旧数据
securec_check_ss(ret, "\0", "\0");
m_len = (size_t)ret;
pfree(m_buff);
m_len = (size_t)ret; // 更新字符串长度
pfree(m_buff); // 释放旧内存
}
m_buff = buff;
m_buff = buff; // 更新缓冲区指针
return m_buff;
}
}