openGauss-server/contrib/security_plugin/privileges_audit.cpp

790 lines
32 KiB
C++

/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* privileges_audit.cpp
* grammer for create/update/delete auding policy informations into catalog
*
* IDENTIFICATION
* src/contrib/secuirty_plugin/privileges_audit.cpp
*
* -------------------------------------------------------------------------
*/
#include "gs_audit_policy.h"
#include <memory>
#include "access_audit.h"
#include "parser/parse_func.h"
#include "postgres.h"
#include "catalog/namespace.h"
#include "commands/dbcommands.h"
#include "gs_policy/gs_policy_utils.h"
#include "nodes/params.h"
#include "nodes/nodes.h"
#include "commands/user.h"
#include "workload/gscgroup.h"
#include "miscadmin.h"
#include "access/heapam.h"
#include "utils/lsyscache.h"
#include "privileges_audit.h"
#include "pgaudit.h"
#include "gs_threadlocal.h"
#include "gs_policy_plugin.h"
#include "gs_policy_labels.h"
#include "gs_mask_policy.h"
#include "iprange/iprange.h"
#define ACCESS_CONTROL_CHECK_ACL_PRIVILIGE(type) \
((check_acl_privilige_hook == NULL) ? true : check_acl_privilige_hook(type))
typedef struct AclObjectType {
GrantObjectType grant_type;
PrivObject privi_type;
} AclObjectType;
static AclObjectType aclobject_infos[] = {
{ACL_OBJECT_COLUMN, O_COLUMN},
{ACL_OBJECT_RELATION, O_TABLE},
{ACL_OBJECT_SEQUENCE, O_SEQUENCE},
{ACL_OBJECT_DATABASE, O_DATABASE},
{ACL_OBJECT_DOMAIN, O_DOMAIN},
{ACL_OBJECT_FOREIGN_SERVER, O_SERVER},
{ACL_OBJECT_FUNCTION, O_FUNCTION},
{ACL_OBJECT_LANGUAGE, O_LANGUAGE},
{ACL_OBJECT_NAMESPACE, O_SCHEMA},
{ACL_OBJECT_TABLESPACE, O_TABLESPACE},
{ACL_OBJECT_DATA_SOURCE, O_DATA_SOURCE},
};
void add_current_path(int objtype, List *fqdn, gs_stl::gs_string *buffer);
/*
* grant/revoke sql audit routine
* policy_ids: policy ids after filt by app
* rel: ListCell object
* priv_type: privilege type, grant or revoke
* priv_name: grant or revoke
* objtype: object type, table...
* ignore_db: whether ignore database
*/
void internal_audit_object_str(const policy_set *security_policy_ids, const policy_set *policy_ids, const ListCell *rel,
const names_pair names, int priv_type, const char *priv_name, int objtype,
int target_type, bool is_rolegrant, bool ignore_db)
{
/*
* Note PolicyLabelItem just support table/function/view/column
* so that only "all" label will work for other object type
*/
PolicyLabelItem item;
if (target_type == ACL_TARGET_OBJECT) {
gen_policy_labelitem(item, rel, objtype);
}
/* PolicyLabelItem construction will append schema oid by relid */
policy_simple_set policy_result;
bool security_auditobject_res = (accesscontrol_securityAuditObject_hook != NULL) ?
accesscontrol_securityAuditObject_hook(security_policy_ids, &item, priv_type, priv_name) :
true;
if (security_auditobject_res && check_audit_policy_privileges(policy_ids, &policy_result, priv_type, &item)) {
char buff[2048] = {0};
char user_name[USERNAME_LEN];
const char *direction = (priv_type == T_GRANT) ? "TO" : "FROM";
const char *dbname = get_database_name(u_sess->proc_cxt.MyDatabaseId);
gs_stl::gs_string obj_value;
item.get_fqdn_value(&obj_value);
policy_simple_set::iterator it = policy_result.begin();
policy_simple_set::iterator eit = policy_result.end();
int rc;
for (; it != eit; ++it) {
char session_ip[MAX_IP_LEN] = {0};
get_session_ip(session_ip, MAX_IP_LEN);
if (ignore_db) {
rc = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1,
"AUDIT EVENT: user name: [%s], app_name: [%s], client_ip: [%s], privilege type: [%s ON %s %s %s "
"%s], "
"policy id: [%lld]",
GetUserName(user_name, sizeof(user_name)), get_session_app_name(), session_ip, priv_name,
get_privilege_object_name(objtype),
(is_rolegrant || obj_value == "") ? names.first.c_str() : obj_value.c_str(), direction,
names.second.c_str(), *it);
securec_check_ss(rc, "\0", "\0");
} else {
rc = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1,
"AUDIT EVENT: user name: [%s], app_name: [%s], client_ip: [%s], privilege type: [%s ON %s %s.%s %s "
"%s], "
"policy id: [%lld]",
GetUserName(user_name, sizeof(user_name)), get_session_app_name(), session_ip, priv_name,
get_privilege_object_name(objtype), dbname,
(is_rolegrant || obj_value == "") ? names.first.c_str() : obj_value.c_str(), direction,
names.second.c_str(), *it);
securec_check_ss(rc, "\0", "\0");
}
save_access_logs(AUDIT_POLICY_EVENT, buff);
}
}
}
static void gen_priv_audit_logs(policy_simple_set& policy_result, bool ignore_db, const char* priv_name, const PolicyLabelItem* item,
const char *obj_value)
{
char buff[2048] = {0};
char user_name[USERNAME_LEN];
int rc;
const char* dbname = get_database_name(u_sess->proc_cxt.MyDatabaseId);
policy_simple_set::iterator it = policy_result.begin();
policy_simple_set::iterator eit = policy_result.end();
for (; it != eit; ++it) {
char session_ip[MAX_IP_LEN] = {0};
get_session_ip(session_ip, MAX_IP_LEN);
if (ignore_db) {
rc = snprintf_s(buff,
sizeof(buff),
sizeof(buff) - 1,
"AUDIT EVENT: user name: [%s], app_name: [%s], client_ip: [%s], privilege type: [%s %s %s], policy "
"id: [%lld]",
GetUserName(user_name, sizeof(user_name)),
get_session_app_name(),
session_ip,
priv_name,
get_privilege_object_name(item->m_obj_type),
obj_value,
*it);
securec_check_ss(rc, "\0", "\0");
} else {
rc = snprintf_s(buff,
sizeof(buff),
sizeof(buff) - 1,
"AUDIT EVENT: user name: [%s], app_name: [%s], client_ip: [%s], privilege type: [%s %s %s.%s], "
"policy id: [%lld]",
GetUserName(user_name, sizeof(user_name)),
get_session_app_name(),
session_ip,
priv_name,
get_privilege_object_name(item->m_obj_type),
dbname,
obj_value,
*it);
securec_check_ss(rc, "\0", "\0");
}
save_access_logs(AUDIT_POLICY_EVENT, buff);
}
}
void internal_audit_str(const policy_set *security_policy_ids, const policy_set *policy_ids,
const char *value, int priv_type, const char *priv_name, int objtype, bool ignore_db)
{
policy_simple_set policy_result;
int policy_object = (objtype == O_CURSOR) ? O_TABLE : objtype;
PolicyLabelItem item(0, 0, policy_object);
bool security_auditobject_res = (accesscontrol_securityAuditObject_hook != NULL) ?
accesscontrol_securityAuditObject_hook(security_policy_ids, &item, priv_type, priv_name) :
true;
if (security_auditobject_res && check_audit_policy_privileges(policy_ids, &policy_result, priv_type, &item)) {
gen_priv_audit_logs(policy_result, ignore_db, priv_name, &item, value);
}
}
bool internal_audit_object_str(const policy_set* security_policy_ids, const policy_set* policy_ids,
const PolicyLabelItem* item, int priv_type, const char* priv_name, const char* objname, bool ignore_db)
{
bool is_found = false;
policy_simple_set policy_result;
if (!check_audit_policy_privileges(policy_ids, &policy_result, priv_type, item)) {
return is_found;
}
gs_stl::gs_string obj_value;
switch (item->m_obj_type) {
case O_DATABASE:
case O_ROLE:
obj_value = objname;
break;
case O_SCHEMA:
item->get_fqdn_value(&obj_value);
break;
default:
item->get_fqdn_value(&obj_value);
if (!item->m_object && strlen(objname) > 0) {
if (!obj_value.empty()) {
obj_value.push_back('.');
}
obj_value.append(objname);
}
break;
}
is_found = !policy_result.empty();
gen_priv_audit_logs(policy_result, ignore_db, priv_name, item, obj_value.c_str());
return is_found;
}
void acl_audit_object(const policy_set *security_policy_ids, const policy_set *policy_ids, const ListCell *rel,
const names_pair names, int priv_type, const char *priv_name, int objtype, int target_type)
{
PrivObject type = get_privtype_from_aclobject((GrantObjectType)objtype);
if (type == O_DATABASE) {
internal_audit_object_str(security_policy_ids, policy_ids, rel, names, priv_type, priv_name, type, target_type,
false, true);
} else {
internal_audit_object_str(security_policy_ids, policy_ids, rel, names, priv_type, priv_name, type, target_type);
}
}
void alter_table(const policy_set *security_policy_ids, const policy_set *policy_ids, RangeVar *rel,
int priv_type, const char *priv_name, int objtype)
{
audit_table(security_policy_ids, policy_ids, rel, priv_type, priv_name, objtype);
}
void audit_table(const policy_set *security_policy_ids, const policy_set *policy_ids, RangeVar *rel, int priv_type,
const char *priv_name, int objtype)
{
if (rel->relname == NULL)
return;
PolicyLabelItem item;
if (priv_type == T_CREATE) {
item = PolicyLabelItem(rel->schemaname, rel->relname, "", objtype);
} else {
gen_policy_labelitem(item, (const ListCell *)rel, objtype);
}
char buff[2048] = {0};
if (priv_type == T_DROP) {
if (check_label_has_object(&item, is_masking_has_object)) {
gs_stl::gs_string table_name;
get_name_range_var(rel, &table_name);
int rc = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1,
"Table: %s is part of some resource label, can not be dropped.", table_name.c_str());
securec_check_ss(rc, "\0", "\0");
gs_audit_issue_syslog_message("PGAUDIT", buff, AUDIT_POLICY_EVENT, AUDIT_FAILED);
ereport(ERROR, (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), errmsg("\"%s\"", buff)));
return;
}
}
policy_simple_set policy_result;
bool security_auditobject_res = (accesscontrol_securityAuditObject_hook != NULL) ?
accesscontrol_securityAuditObject_hook(security_policy_ids, &item, priv_type, priv_name) : true;
if (security_auditobject_res && check_audit_policy_privileges(policy_ids, &policy_result, priv_type, &item)) {
gs_stl::gs_string obj_value;
item.get_fqdn_value(&obj_value);
if (item.m_object == 0) { /* create case */
obj_value.push_back('.');
obj_value.append(rel->relname);
}
char user_name[USERNAME_LEN];
const char *dbname = get_database_name(u_sess->proc_cxt.MyDatabaseId);
policy_simple_set::iterator it = policy_result.begin();
policy_simple_set::iterator eit = policy_result.end();
for (; it != eit; ++it) {
char session_ip[MAX_IP_LEN] = {0};
get_session_ip(session_ip, MAX_IP_LEN);
int rc = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1,
"AUDIT EVENT: user name: [%s], app_name: [%s], client_ip: [%s], privilege type: [%s %s %s.%s], policy "
"id: [%lld]", GetUserName(user_name, sizeof(user_name)), get_session_app_name(), session_ip, priv_name,
get_privilege_object_name(objtype), dbname, obj_value.c_str(), *it);
securec_check_ss(rc, "\0", "\0");
save_access_logs(AUDIT_POLICY_EVENT, buff);
}
}
}
void audit_schema(const policy_set security_policy_ids, const policy_set policy_ids, const char *schemaname,
const char *newname, int priv_type, const char *priv_name)
{
char buff[2048] = {0};
policy_simple_set policy_result;
int check_type = (priv_type == T_RENAME) ? T_ALTER : priv_type;
PolicyLabelItem item(schemaname, "", "", O_SCHEMA);
if (priv_type == T_DROP) {
if (check_label_has_object(&item, is_masking_has_object)) {
int rc = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1,
"Schema: %s is part of some resource label, can not be dropped.", schemaname);
securec_check_ss(rc, "\0", "\0");
gs_audit_issue_syslog_message("PGAUDIT", buff, AUDIT_POLICY_EVENT, AUDIT_FAILED);
ereport(ERROR, (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), errmsg("\"%s\"", buff)));
return;
}
}
bool security_auditobject_res = (accesscontrol_securityAuditObject_hook != NULL) ?
accesscontrol_securityAuditObject_hook(&security_policy_ids, &item, check_type, priv_name) :
true;
if (security_auditobject_res &&
check_audit_policy_privileges(&policy_ids, &policy_result, check_type, &item)) {
const char *dbname = get_database_name(u_sess->proc_cxt.MyDatabaseId);
char user_name[USERNAME_LEN];
policy_simple_set::iterator it = policy_result.begin();
policy_simple_set::iterator eit = policy_result.end();
for (; it != eit; ++it) {
char session_ip[MAX_IP_LEN] = {0};
get_session_ip(session_ip, MAX_IP_LEN);
switch (priv_type) {
case T_RENAME: {
int rc = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1,
"AUDIT EVENT: user name: [%s], app_name: [%s], client_ip: [%s], privilege type: [ALTER SCHEMA "
"%s.%s RENAME TO %s], policy id: [%lld]",
GetUserName(user_name, sizeof(user_name)), get_session_app_name(), session_ip, dbname,
schemaname, newname, *it);
securec_check_ss(rc, "\0", "\0");
break;
}
case T_ALTER: {
int rc = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1,
"AUDIT EVENT: user name: [%s], app_name: [%s], client_ip: [%s], privilege type: [ALTER SCHEMA "
"%s.%s OWNER TO %s], policy id: [%lld]",
GetUserName(user_name, sizeof(user_name)), get_session_app_name(), session_ip, dbname,
schemaname, newname, *it);
securec_check_ss(rc, "\0", "\0");
break;
}
default: {
int rc = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1,
"AUDIT EVENT: user name: [%s], app_name: [%s], client_ip: [%s], privilege type: [%s SCHEMA "
"%s.%s], policy id: [%lld]",
GetUserName(user_name, sizeof(user_name)), get_session_app_name(), session_ip, priv_name,
dbname, schemaname, *it);
securec_check_ss(rc, "\0", "\0");
break;
}
}
save_access_logs(AUDIT_POLICY_EVENT, buff);
}
}
}
void drop_command(DropStmt *stmt, const policy_set *policy_ids, const policy_set *security_policy_ids)
{
if (stmt == NULL || stmt->objects == NIL)
return;
ListCell *arg = NULL;
foreach (arg, stmt->objects) {
List *names = (List *)lfirst(arg);
RangeVar *rel = NULL;
switch (stmt->removeType) {
case OBJECT_TABLE: {
if (!check_audited_privilige(T_DROP) && !ACCESS_CONTROL_CHECK_ACL_PRIVILIGE(T_DROP))
break;
rel = makeRangeVarFromNameList(names);
audit_table(security_policy_ids, policy_ids, rel, T_DROP, "DROP", O_TABLE);
break;
}
case OBJECT_STREAM:
case OBJECT_FOREIGN_TABLE: {
if (!check_audited_privilige(T_DROP) && !ACCESS_CONTROL_CHECK_ACL_PRIVILIGE(T_DROP))
break;
rel = makeRangeVarFromNameList(names);
audit_table(security_policy_ids, policy_ids, rel, T_DROP, "DROP", O_TABLE);
break;
}
case OBJECT_SEQUENCE: {
if (!check_audited_privilige(T_DROP) && !ACCESS_CONTROL_CHECK_ACL_PRIVILIGE(T_DROP))
break;
gs_stl::gs_string tmp;
add_current_path(OBJECT_SEQUENCE, names, &tmp);
internal_audit_str(security_policy_ids, policy_ids, tmp.c_str(), T_DROP, "DROP",
O_SEQUENCE);
break;
}
case OBJECT_CONTQUERY:
case OBJECT_VIEW: {
if (!check_audited_privilige(T_DROP) && !ACCESS_CONTROL_CHECK_ACL_PRIVILIGE(T_DROP))
break;
rel = makeRangeVarFromNameList(names);
audit_table(security_policy_ids, policy_ids, rel, T_DROP, "DROP", O_VIEW);
break;
}
case OBJECT_SCHEMA: {
if (!check_audited_privilige(T_DROP) && !ACCESS_CONTROL_CHECK_ACL_PRIVILIGE(T_DROP))
break;
const char *objectname = strVal(linitial(names));
audit_schema(*security_policy_ids, *policy_ids, objectname, "", T_DROP, "DROP");
break;
}
case OBJECT_INDEX: {
if (!check_audited_privilige(T_DROP) && !ACCESS_CONTROL_CHECK_ACL_PRIVILIGE(T_DROP))
break;
rel = makeRangeVarFromNameList(names);
gs_stl::gs_string index_name;
get_name_range_var(rel, &index_name);
internal_audit_str(security_policy_ids, policy_ids, index_name.c_str(), T_DROP, "DROP",
O_INDEX);
break;
}
case OBJECT_FUNCTION: {
PolicyLabelItem find_obj(0, 0, O_FUNCTION);
name_list_to_label(&find_obj, names);
if (check_label_has_object(&find_obj, is_masking_has_object)) {
gs_stl::gs_string tmp;
find_obj.get_fqdn_value(&tmp);
char buff[512] = {0};
int rc = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1,
"Function: %s is part of some resource label, can not be dropped.", tmp.c_str());
securec_check_ss(rc, "\0", "\0");
gs_audit_issue_syslog_message("PGAUDIT", buff, AUDIT_POLICY_EVENT, AUDIT_FAILED);
ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\"", buff)));
return;
}
if (check_audited_privilige(T_DROP) || ACCESS_CONTROL_CHECK_ACL_PRIVILIGE(T_DROP)) {
internal_audit_object_str(security_policy_ids, policy_ids, &find_obj, T_DROP, "DROP");
}
break;
}
case OBJECT_FOREIGN_SERVER: {
if (!check_audited_privilige(T_DROP) && !ACCESS_CONTROL_CHECK_ACL_PRIVILIGE(T_DROP)) {
break;
}
gs_stl::gs_string name;
name_list_to_string(names, &name);
internal_audit_str(security_policy_ids, policy_ids, name.c_str(), T_DROP, "DROP", O_SERVER);
break;
}
case OBJECT_DATA_SOURCE: {
if (!check_audited_privilige(T_DROP) && !ACCESS_CONTROL_CHECK_ACL_PRIVILIGE(T_DROP)) {
break;
}
gs_stl::gs_string name;
name_list_to_string(names, &name);
internal_audit_str(security_policy_ids, policy_ids, name.c_str(), T_DROP, "DROP",
O_DATA_SOURCE);
break;
}
case OBJECT_TRIGGER: {
if (!check_audited_privilige(T_DROP) && !ACCESS_CONTROL_CHECK_ACL_PRIVILIGE(T_DROP)) {
break;
}
const char *objectname = strVal(lfirst(list_tail(names)));
internal_audit_str(security_policy_ids, policy_ids, objectname, T_DROP, "DROP", O_TRIGGER);
break;
}
default:
break;
}
}
}
static inline void check_object_policy(const policy_set *policy_ids, int objecttype, const PolicyLabelItem *item,
const char *priv_type)
{
char buff[2048] = {0};
policy_simple_set policy_result;
if (check_audit_policy_privileges(policy_ids, &policy_result, T_ALTER, item)) {
gs_stl::gs_string objname;
item->get_fqdn_value(&objname);
const char *dbname = get_database_name(u_sess->proc_cxt.MyDatabaseId);
char user_name[USERNAME_LEN];
policy_simple_set::iterator it = policy_result.begin();
policy_simple_set::iterator eit = policy_result.end();
for (; it != eit; ++it) {
char session_ip[MAX_IP_LEN] = {0};
get_session_ip(session_ip, MAX_IP_LEN);
int rc = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1,
"AUDIT EVENT: user name: [%s], app_name: [%s], client_ip: [%s], privilege type: [%s %s %s.%s], policy "
"id: [%lld]", GetUserName(user_name, sizeof(user_name)), get_session_app_name(), session_ip, priv_type,
get_privilege_object_name(objecttype), dbname, objname.c_str(), *it);
securec_check_ss(rc, "\0", "\0");
save_access_logs(AUDIT_POLICY_EVENT, buff);
}
}
}
static inline void check_object_policy_str(const policy_set *policy_ids, const PolicyLabelItem *item,
const char *priv_type, const char *obj_name, bool ignore_db = false)
{
char buff[2048] = {0};
policy_simple_set policy_result;
if (check_audit_policy_privileges(policy_ids, &policy_result, T_ALTER, item)) {
gs_stl::gs_string objname;
switch (item->m_obj_type) {
case O_DATABASE:
case O_ROLE:
objname = obj_name;
break;
case O_SCHEMA:
item->get_fqdn_value(&objname);
break;
default:
item->get_fqdn_value(&objname);
if (!item->m_object && strlen(obj_name) > 0) {
objname.push_back('.');
objname.append(obj_name);
}
break;
}
const char *dbname = get_database_name(u_sess->proc_cxt.MyDatabaseId);
char user_name[USERNAME_LEN];
policy_simple_set::iterator it = policy_result.begin();
policy_simple_set::iterator eit = policy_result.end();
for (; it != eit; ++it) {
char session_ip[MAX_IP_LEN] = {0};
get_session_ip(session_ip, MAX_IP_LEN);
if (ignore_db) {
int rc = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1,
"AUDIT EVENT: user name: [%s], app_name: [%s], client_ip: [%s], privilege type: [%s %s %s], policy "
"id: [%lld]",
GetUserName(user_name, sizeof(user_name)), get_session_app_name(), session_ip, priv_type,
get_privilege_object_name(item->m_obj_type), objname.c_str(), *it);
securec_check_ss(rc, "\0", "\0");
} else {
int rc = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1,
"AUDIT EVENT: user name: [%s], app_name: [%s], client_ip: [%s], privilege type: [%s %s %s.%s], "
"policy id: [%lld]",
GetUserName(user_name, sizeof(user_name)), get_session_app_name(), session_ip, priv_type,
get_privilege_object_name(item->m_obj_type), dbname, objname.c_str(), *it);
securec_check_ss(rc, "\0", "\0");
}
save_access_logs(AUDIT_POLICY_EVENT, buff);
}
}
}
void rename_object(RenameStmt *stmt, const policy_set policy_ids, const policy_set security_policy_ids,
RenameMap *renamed_objects)
{
if (stmt == NULL) {
return;
}
gs_stl::gs_string buffer;
bool ignore_db = false;
PolicyLabelItem item;
const char *objectname = "";
switch (stmt->renameType) {
case OBJECT_DATABASE:
item.m_obj_type = O_DATABASE;
objectname = stmt->subname;
ignore_db = true;
break;
case OBJECT_ROLE:
item.m_obj_type = O_ROLE;
objectname = stmt->subname;
ignore_db = true;
break;
case OBJECT_USER:
item.m_obj_type = O_ROLE;
objectname = stmt->subname;
ignore_db = true;
break;
case OBJECT_TABLESPACE:
item.m_obj_type = O_TABLESPACE;
objectname = stmt->subname;
break;
case OBJECT_TRIGGER:
item.m_obj_type = O_TRIGGER;
objectname = stmt->subname;
break;
case OBJECT_FUNCTION: {
item.m_obj_type = O_FUNCTION;
name_list_to_label(&item, stmt->object);
break;
}
case OBJECT_TABLE:
case OBJECT_STREAM:
case OBJECT_FOREIGN_TABLE:
item.m_obj_type = O_TABLE;
item.m_schema = SchemaNameGetSchemaOid(stmt->relation->schemaname, true);
item.set_object(stmt->relation->relname);
break;
case OBJECT_CONTQUERY:
case OBJECT_VIEW:
item.m_obj_type = O_VIEW;
item.m_schema = SchemaNameGetSchemaOid(stmt->relation->schemaname, true);
item.set_object(stmt->relation->relname);
break;
case OBJECT_INDEX:
item.m_obj_type = O_INDEX;
get_name_range_var(stmt->relation, &buffer);
objectname = buffer.c_str();
break;
case OBJECT_COLUMN: {
item.m_obj_type = O_COLUMN;
item.m_schema = SchemaNameGetSchemaOid(stmt->relation->schemaname, true);
item.set_object(stmt->relation->relname);
int rec = snprintf_s(item.m_column, sizeof(item.m_column), sizeof(item.m_column) - 1, "%s", stmt->subname);
securec_check_ss(rec, "\0", "\0");
if (renamed_objects) {
(*renamed_objects)[O_COLUMN].push_back(RenamePair(stmt->subname, stmt->newname));
}
break;
}
default:
return;
}
if (accesscontrol_securityAuditObject_hook == NULL ||
accesscontrol_securityAuditObject_hook(&security_policy_ids, &item, T_RENAME, "RENAME")) {
check_object_policy_str(&policy_ids, &item, "RENAME", objectname, ignore_db);
}
}
void alter_owner(AlterOwnerStmt *stmt, const policy_set policy_ids, const policy_set security_policy_ids)
{
gs_stl::gs_string tmp;
PolicyLabelItem item;
const char *objectname = "";
switch (stmt->objectType) {
case OBJECT_DATABASE:
item.m_obj_type = O_DATABASE;
objectname = strVal(linitial(stmt->object));
break;
case OBJECT_TABLESPACE:
item.m_obj_type = O_TABLESPACE;
objectname = strVal(linitial(stmt->object));
break;
case OBJECT_FOREIGN_SERVER:
item.m_obj_type = O_SERVER;
objectname = strVal(linitial(stmt->object));
break;
case OBJECT_FUNCTION: {
item.m_obj_type = O_FUNCTION;
name_list_to_label(&item, stmt->object);
break;
}
default:
break;
}
if (accesscontrol_securityAuditObject_hook == NULL ||
accesscontrol_securityAuditObject_hook(&security_policy_ids, &item, T_ALTER, "ALTER")) {
check_object_policy_str(&policy_ids, &item, "ALTER", objectname);
}
}
void add_current_path(int objtype, List *fqdn, gs_stl::gs_string *buffer)
{
const char *schemaname = get_namespace_name(SchemaNameGetSchemaOid(NULL, true));
int listsize = list_length(fqdn);
switch (objtype) {
case OBJECT_INDEX:
case OBJECT_SEQUENCE:
case OBJECT_TABLE:
case OBJECT_VIEW:
case OBJECT_CONTQUERY:
case OBJECT_FOREIGN_TABLE:
case OBJECT_STREAM:
case OBJECT_FUNCTION: {
switch (listsize) {
case 1:
SET_DB_SCHEMA_TABLE
/* don't put break here */
default:
name_list_to_string(fqdn, buffer);
break;
}
break;
}
case OBJECT_COLUMN: {
switch (listsize) {
case 2:
SET_DB_SCHEMA_TABLE
/* don't put break here */
default:
name_list_to_string(fqdn, buffer);
break;
}
break;
}
case OBJECT_SCHEMA: {
name_list_to_string(fqdn, buffer);
break;
}
case OBJECT_ROLE:
case OBJECT_USER:
case OBJECT_DATABASE:
case OBJECT_FOREIGN_SERVER:
case OBJECT_TABLESPACE:
case OBJECT_TRIGGER:
default:
name_list_to_string(fqdn, buffer);
break;
}
}
void get_cursor_tables(List *rtable, char *buff, size_t buff_size, int _printed_size,
gs_stl::gs_vector<PolicyLabelItem> *cursor_objects)
{
int rc;
if (rtable != NIL) {
ListCell *lc = NULL;
bool first = true;
bool has_object = false;
int printed_size = _printed_size;
foreach (lc, rtable) {
RangeTblEntry *rte = (RangeTblEntry *)lfirst(lc);
if (rte != NULL && rte->relname && rte->rtekind == RTE_RELATION) {
PolicyLabelItem item;
get_fqdn_by_relid(rte, &item);
if (cursor_objects) {
cursor_objects->push_back(item);
}
gs_stl::gs_string tbl_name;
item.get_fqdn_value(&tbl_name);
has_object = true;
if (first) {
rc = snprintf_s(buff + printed_size, buff_size - printed_size, buff_size - printed_size - 1,
", TABLES {%s", tbl_name.c_str());
securec_check_ss(rc, "\0", "\0");
printed_size += rc;
} else {
rc = snprintf_s(buff + printed_size, buff_size - printed_size, buff_size - printed_size - 1, ", %s",
tbl_name.c_str());
securec_check_ss(rc, "\0", "\0");
printed_size += rc;
}
first = false;
}
}
if (has_object) {
rc = snprintf_s(buff + printed_size, buff_size - printed_size, buff_size - printed_size - 1, "}");
securec_check_ss(rc, "\0", "\0");
printed_size += rc;
}
}
}
void get_open_cursor_info(PlannedStmt *stmt, char *buff, size_t buff_size)
{
int printed_size = -1;
int rc;
if (stmt->utilityStmt) {
DeclareCursorStmt *cstmt = (DeclareCursorStmt *)stmt->utilityStmt;
printed_size = snprintf_s(buff, buff_size, buff_size - 1, "%s ", cstmt->portalname);
securec_check_ss(printed_size, "\0", "\0");
}
rc = snprintf_s(buff + printed_size, buff_size - printed_size, buff_size - printed_size - 1,
get_cursorinfo(stmt->commandType));
securec_check_ss(rc, "\0", "\0");
printed_size += rc;
get_cursor_tables(stmt->rtable, buff, buff_size, printed_size);
}
PrivObject get_privtype_from_aclobject(GrantObjectType acl_type)
{
for (unsigned int i = 0; i < (sizeof(aclobject_infos) / sizeof(aclobject_infos[0])); ++i) {
if (aclobject_infos[i].grant_type == acl_type) {
return aclobject_infos[i].privi_type;
}
}
return O_UNKNOWN;
}