diff --git a/src/bin/pg_dump/pg_dump.cpp b/src/bin/pg_dump/pg_dump.cpp old mode 100755 new mode 100644 index 2740ea328a4756b45f51b5bce7acf68311d6be9a..0b2ba92916fd6c6f58e9113134f0c3d497e19f45 --- a/src/bin/pg_dump/pg_dump.cpp +++ b/src/bin/pg_dump/pg_dump.cpp @@ -20014,6 +20014,8 @@ static const char* getAttrName(int attrnum, TableInfo* tblInfo) return "cmax"; case TableOidAttributeNumber: return "tableoid"; + case SecLabelAttributeNumber: + return "seclabel"; #ifdef PGXC case XC_NodeIdAttributeNumber: return "xc_node_id"; diff --git a/src/common/backend/catalog/Makefile b/src/common/backend/catalog/Makefile index c7d944ede4f79ff7f155ea1fc59a0a5358af43e3..86197d565f12326766e62112c6e79492df8b6ce8 100644 --- a/src/common/backend/catalog/Makefile +++ b/src/common/backend/catalog/Makefile @@ -60,7 +60,7 @@ POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\ pg_streaming_stream.h pg_streaming_cont_query.h pg_streaming_reaper_status.h gs_matview.h\ gs_matview_dependency.h pgxc_slice.h gs_opt_model.h gs_model.h\ pg_recyclebin.h pg_snapshot.h gs_job_argument.h gs_job_attribute.h pg_uid.h gs_db_privilege.h\ - pg_replication_origin.h pg_publication.h pg_publication_rel.h pg_subscription.h gs_sql_patch.h\ + pg_replication_origin.h pg_publication.h pg_publication_rel.h pg_subscription.h gs_sql_patch.h mog_mac_seclabel.h\ ) # location of Catalog.pm diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index 10c7458a4c1a9963a3040d0636907faff9cf54f4..703ad509f9805c92c10c6c445d31d208e7a35d68 100755 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -12331,4 +12331,32 @@ AddFuncGroup( "gs_repair_file", 1, AddBuiltinFunc(_0(4771), _1("gs_repair_file"), _2(3), _3(true), _4(true), _5(gs_repair_file), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(1000), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 26, 25, 23), _21(3, 26, 25, 23), _22(3, 'i', 'i', 'i'), _23(3, "tableoid", "path", "timeout"), _24(NULL), _25("gs_repair_file"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), \ No newline at end of file + ), + AddFuncGroup( + "compare_seclabels", 1, + AddBuiltinFunc(_0(4458), _1("compare_seclabels"), _2(2), _3(false), _4(false), _5(compare_seclabels), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(true), _18('i'), _19(0), _20(3, 26, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("compare_seclabels"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f')) + ), + AddFuncGroup( + "mog_set_rel_label", 1, + AddBuiltinFunc(_0(4459), _1("mog_set_rel_label"), _2(2), _3(true), _4(false), _5(mog_set_rel_label), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(true), _18('s'), _19(0), _20(2, 25, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("mog_set_rel_label"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f')) + ), + AddFuncGroup( + "mog_set_user_label", 1, + AddBuiltinFunc(_0(4470), _1("mog_set_user_label"), _2(2), _3(true), _4(false), _5(mog_set_user_label), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(true), _18('s'), _19(0), _20(2, 2275, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("mog_set_user_label"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f')) + ), + AddFuncGroup( + "mog_set_tuple_label", 1, + AddBuiltinFunc(_0(4471), _1("mog_set_tuple_label"), _2(2), _3(true), _4(false), _5(mog_set_tuple_label), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(true), _18('s'), _19(0), _20(3, 25, 27, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("mog_set_tuple_label"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f')) + ), + AddFuncGroup( + "mog_add_seclabel", 1, + AddBuiltinFunc(_0(4472), _1("mog_add_seclabel"), _2(2), _3(true), _4(false), _5(mog_add_seclabel), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(true), _18('s'), _19(0), _20(3, 19, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("mog_add_seclabel"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f')) + ), + AddFuncGroup( + "mog_drop_seclabel", 1, + AddBuiltinFunc(_0(4473), _1("mog_drop_seclabel"), _2(2), _3(true), _4(false), _5(mog_drop_seclabel), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(true), _18('s'), _19(0), _20(1, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("mog_drop_seclabel"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f')) + ), + AddFuncGroup( + "mog_alter_seclabel", 1, + AddBuiltinFunc(_0(4474), _1("mog_alter_seclabel"), _2(2), _3(true), _4(false), _5(mog_alter_seclabel), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(true), _18('s'), _19(0), _20(3, 23, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("mog_alter_seclabel"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f')) + ), diff --git a/src/common/backend/catalog/heap.cpp b/src/common/backend/catalog/heap.cpp index 6d2e45d7e46670cbd3fc17020825e69ddaa6b311..8870767bab6dc4c9f123def8fe60c1729f737436 100644 --- a/src/common/backend/catalog/heap.cpp +++ b/src/common/backend/catalog/heap.cpp @@ -344,6 +344,24 @@ static FormData_pg_attribute a7 = {0, true, 0}; +static FormData_pg_attribute a8 = {0, + {"seclabel"}, + INT4OID, + 0, + sizeof(int32), + SecLabelAttributeNumber, + 0, + -1, + -1, + true, + 'p', + 'i', + true, + false, + false, + true, + 0}; + #ifdef PGXC /* * In XC we need some sort of node identification for each tuple @@ -352,7 +370,7 @@ static FormData_pg_attribute a7 = {0, * where we want to know the originating Datanode of a tuple received * at the Coordinator */ -static FormData_pg_attribute a8 = {0, +static FormData_pg_attribute a9 = {0, {"xc_node_id"}, INT4OID, 0, @@ -370,7 +388,7 @@ static FormData_pg_attribute a8 = {0, true, 0}; -static FormData_pg_attribute a9 = {0, +static FormData_pg_attribute a10 = {0, {"tablebucketid"}, INT2OID, 0, @@ -388,7 +406,7 @@ static FormData_pg_attribute a9 = {0, true, 0}; -static FormData_pg_attribute a10 = {0, +static FormData_pg_attribute a11 = {0, {"gs_tuple_uid"}, INT8OID, 0, @@ -406,9 +424,9 @@ static FormData_pg_attribute a10 = {0, true, 0}; -static const Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10}; +static const Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11}; #else -static const Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7}; +static const Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8}; #endif /* diff --git a/src/common/backend/parser/analyze.cpp b/src/common/backend/parser/analyze.cpp index 0498c09a6fde652d67d4b95097eaa59d2fe02c66..79d1488879513ef7ce5d0d5b87d92458b61b92a3 100644 --- a/src/common/backend/parser/analyze.cpp +++ b/src/common/backend/parser/analyze.cpp @@ -41,6 +41,7 @@ #include "executor/node/nodeModifyTable.h" #include "foreign/foreign.h" #include "miscadmin.h" +#include "mog_mac/mog_mac.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" #include "optimizer/var.h" @@ -186,6 +187,10 @@ Query* parse_analyze( query->fixed_paramTypes = paramTypes; query->fixed_numParams = numParams; + /*mac privilige check*/ + if(g_instance.attr.attr_security.enable_mog_mac) + mog_mac_seclabel_check(pstate, query); + return query; } diff --git a/src/common/backend/utils/cache/syscache.cpp b/src/common/backend/utils/cache/syscache.cpp index c42b44ea6fb035da9c2d43f3a698749c72f84cc3..9b4a0b5389e63dfb60f3db2f0858d936f3be7d98 100644 --- a/src/common/backend/utils/cache/syscache.cpp +++ b/src/common/backend/utils/cache/syscache.cpp @@ -28,6 +28,7 @@ #include "catalog/gs_opt_model.h" #include "catalog/gs_model.h" #include "catalog/gs_policy_label.h" +#include "catalog/mog_mac_seclabel.h" #include "catalog/indexing.h" #include "catalog/pg_aggregate.h" #include "catalog/gs_client_global_keys.h" diff --git a/src/common/backend/utils/misc/guc.cpp b/src/common/backend/utils/misc/guc.cpp index 27203b0df512b57796d4b0ae15b88fb3fc34f7d1..6522609f5a3b1349e98d45bc5771ee857e99994e 100755 --- a/src/common/backend/utils/misc/guc.cpp +++ b/src/common/backend/utils/misc/guc.cpp @@ -1837,6 +1837,28 @@ static void InitConfigureNamesBool() NULL, NULL }, + {{"enable_mog_mac", + PGC_POSTMASTER, + NODE_SINGLENODE, + QUERY_TUNING_METHOD, + gettext_noop("Enables mogdb mandatory access control."), + NULL}, + &g_instance.attr.attr_security.enable_mog_mac, + false, + NULL, + NULL, + NULL}, + {{"enable_mog_mac_row", + PGC_POSTMASTER, + NODE_SINGLENODE, + QUERY_TUNING_METHOD, + gettext_noop("Enables row level mogdb mandatory access control."), + NULL}, + &g_instance.attr.attr_security.enable_mog_mac_row, + false, + NULL, + NULL, + NULL}, /* End-of-list marker */ {{NULL, (GucContext)0, diff --git a/src/common/backend/utils/misc/postgresql_single.conf.sample b/src/common/backend/utils/misc/postgresql_single.conf.sample index 420932a262c88e2e5737963e830b28ece9b7a9b3..4259ef11c7b45490738a5548b68634453b02d3f4 100644 --- a/src/common/backend/utils/misc/postgresql_single.conf.sample +++ b/src/common/backend/utils/misc/postgresql_single.conf.sample @@ -560,6 +560,12 @@ use_workload_manager = on # Enables workload manager in the system. #cpu_collect_timer = 30 +# MAC PARAMETERS +#------------------------------------------------------------------------------ +#enable_mog_mac = off +#enable_mog_mac_row = off +#------------------------------------------------------------------------------ + #------------------------------------------------------------------------------ # AUTOVACUUM PARAMETERS #------------------------------------------------------------------------------ diff --git a/src/gausskernel/process/tcop/postgres.cpp b/src/gausskernel/process/tcop/postgres.cpp index 33f73183043c50ee6046423993cebad62da2c267..043b065f5a754d49c4461c5b9b4b8328fb003399 100755 --- a/src/gausskernel/process/tcop/postgres.cpp +++ b/src/gausskernel/process/tcop/postgres.cpp @@ -64,6 +64,7 @@ #include "libpq/pqsignal.h" #include "libpq/crypt.h" #include "miscadmin.h" +#include "mog_mac/mog_mac.h" #include "nodes/print.h" #include "optimizer/planner.h" #include "optimizer/bucketpruning.h" @@ -1168,6 +1169,8 @@ static List* pg_rewrite_query(Query* query) } #endif + mac_rewrite_querytree(querytree_list); + if (u_sess->attr.attr_sql.Debug_print_rewritten) elog_node_display(LOG, "rewritten parse tree", querytree_list, u_sess->attr.attr_sql.Debug_pretty_print); diff --git a/src/gausskernel/security/Makefile b/src/gausskernel/security/Makefile index b86539bbd3ee1c27f981d120f8f6fec11244e73d..2624cac0494fb66969d09a11827ebadcbba0609d 100644 --- a/src/gausskernel/security/Makefile +++ b/src/gausskernel/security/Makefile @@ -8,6 +8,6 @@ subdir = src/gausskernel/security top_builddir = ../../.. include $(top_builddir)/src/Makefile.global -SUBDIRS = iprange gs_policy gs_ledger tde_key_management +SUBDIRS = iprange gs_policy gs_ledger tde_key_management mog_mac include $(top_srcdir)/src/gausskernel/common.mk diff --git a/src/gausskernel/security/mog_mac/Makefile b/src/gausskernel/security/mog_mac/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..af4b27a10c6032e98a2f7d1216e37ec63269ebbf --- /dev/null +++ b/src/gausskernel/security/mog_mac/Makefile @@ -0,0 +1,22 @@ +#------------------------------------------------------------------------- +# +# Makefile +# IDENTIFICATION +# src/gausskernel/security/mog_mac/Makefile +# +#------------------------------------------------------------------------- + +top_builddir = ../../../.. +subdir=src/gausskernel/security/mog_mac +include $(top_builddir)/src/Makefile.global + +ifneq "$(MAKECMDGOALS)" "clean" + ifneq "$(MAKECMDGOALS)" "distclean" + ifneq "$(shell which g++ |grep hutaf_llt |wc -l)" "1" + -include $(DEPEND) + endif + endif +endif +OBJS= mog_mac.o + +include $(top_srcdir)/src/gausskernel/common.mk diff --git a/src/gausskernel/security/mog_mac/mog_mac.cpp b/src/gausskernel/security/mog_mac/mog_mac.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c665512e1778b9e0cdf3dd45e7a1d58715469ed8 --- /dev/null +++ b/src/gausskernel/security/mog_mac/mog_mac.cpp @@ -0,0 +1,929 @@ +/* + * mog_mac.cpp + * handle the mandatory access control + * + * IDENTIFICATION + * src/gausskernel/security/mog_mac/mog_mac.cpp + * + * --------------------------------------------------------------------------------------- + */ + + +#include + +#include "utils/lsyscache.h" +#include "catalog/indexing.h" +#include "catalog/pg_namespace.h" +#include "access/transam.h" + +#include "utils/syscache.h" +#include "access/heapam.h" +#include "utils/builtins.h" +#include "access/sysattr.h" +#include "catalog/pg_authid.h" +#include "gs_policy/policy_common.h" +#include "catalog/indexing.h" +#include "mog_mac/mog_mac.h" +#include "catalog/mog_mac_seclabel.h" +#include "utils/fmgroids.h" + +typedef struct FormData_mog_user_label +{ + int32 useroid; + int32 label; +} FormData_mog_user_label; + +static int32 get_relation_label(Oid reloid); +static void row_moc(Query *query); +static void add_mac_qual(Query *query, Index rteindex, CmdType optype); +static bool compare_seclabels(int subject_seclabel_id, int object_seclabel_id, CmdType cmd_type); + +static void +add_mac_qual(Query *query, Index rteindex, CmdType optype) +{ + BoolExpr *mac_bool = NULL; + Const *user_label = NULL; + Const *op_type = NULL; + Var *row_value = NULL; + FuncExpr *cmp_func = NULL; + List *cmp_func_args = NULL; + List *bool_args = NULL; + + row_value = makeNode(Var); + row_value->varno = rteindex; + row_value->varattno = SecLabelAttributeNumber; /*the attribure number of seclable in tuple*/ + row_value->vartype = 23; /*type is int*/ + row_value->vartypmod = -1; + row_value->varcollid = InvalidOid; + row_value->varlevelsup = 0; + row_value->varnoold = rteindex; + row_value->varoattno = SecLabelAttributeNumber; + row_value->location = -1; + + user_label = makeNode(Const); + user_label->consttype = 23; /*type is int*/ + user_label->consttypmod = -1; + user_label->constcollid = InvalidOid; + user_label->constlen = 4; + user_label->constisnull = false; + user_label->constbyval = true; + user_label->constvalue = UInt32GetDatum(get_user_label(GetCurrentUserId())); + user_label->location = -1; + + op_type = makeNode(Const); + op_type->consttype = 23; /*type is int*/ + op_type->consttypmod = -1; + op_type->constcollid = InvalidOid; + op_type->constlen = 4; + op_type->constisnull = false; + op_type->constbyval = true; + op_type->constvalue = UInt32GetDatum((int32)optype); + op_type->location = -1; + + cmp_func_args = list_make1(user_label); + cmp_func_args = lappend(cmp_func_args,row_value); + cmp_func_args = lappend(cmp_func_args,op_type); + cmp_func = makeNode(FuncExpr); + cmp_func->funcid = 4458; /*the funcoid of compare_seclabel()*/ + cmp_func->funcresulttype = 16; /*type bool*/ + cmp_func->funcretset = false; + cmp_func->funcvariadic = false ; + cmp_func->funcformat = COERCE_EXPLICIT_CALL; + cmp_func->funccollid = InvalidOid; + cmp_func->inputcollid = InvalidOid; + cmp_func->args = cmp_func_args; + cmp_func->location = -1; + + bool_args = list_make1(cmp_func); + mac_bool = makeNode(BoolExpr); + mac_bool->boolop = OR_EXPR; + mac_bool->location = -1; + mac_bool->args = bool_args; + + if(query->jointree->quals == NULL) { + query->jointree->quals = (Node*)mac_bool; + } else { + BoolExpr *top_bool = NULL; + BoolExpr *old_bool = NULL; + List *newArgs = NULL; + List *oldArgs = NULL; + Node *oldNode = NULL; + + /*old bool*/ + oldNode = (Node*)query->jointree->quals; + oldArgs = list_make1(oldNode); + old_bool = makeNode(BoolExpr); + old_bool->boolop = OR_EXPR; + old_bool->location = -1; + old_bool->args = oldArgs; + + /*top bool*/ + newArgs = list_make1(old_bool); + newArgs = lappend(newArgs,mac_bool); + + top_bool = makeNode(BoolExpr); + top_bool->boolop = AND_EXPR; + top_bool->location = -1; + top_bool->args = newArgs; + + query->jointree->quals = (Node*)top_bool; + } +} + +static void +row_moc(Query *query) +{ + ListCell *lc = NULL; + Index rteindex = 0; + Oid useroid = InvalidOid; + + if(!g_instance.attr.attr_security.enable_mog_mac) + return; + + if(!query) + return; + + useroid = GetCurrentUserId(); + + if(BOOTSTRAP_SUPERUSERID == useroid) + return; + + foreach(lc, query->rtable) { + Node *node = (Node*)lfirst(lc); + RangeTblEntry *rte = NULL; + char relkind; + int32 rellabel = 0; + int32 userlabel = 0; + + rteindex++; + + if (!IsA(node, RangeTblEntry)) { + continue; + } + + rte = (RangeTblEntry *)node; + + if(rte->relid < FirstNormalObjectId) + continue; + + relkind = get_rel_relkind(rte->relid); + rellabel = get_relation_label(rte->relid); + userlabel = get_user_label(useroid); + + if(relkind == RELKIND_RELATION) { + if(query->commandType == CMD_SELECT) { + if(g_instance.attr.attr_security.enable_mog_mac_row) + add_mac_qual(query, rteindex, query->commandType); + else + if(!compare_seclabels(userlabel, rellabel, CMD_SELECT)) + ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("current user has no permission to select"))); + } else if(query->commandType == CMD_INSERT) { + if(!compare_seclabels(userlabel, rellabel, CMD_INSERT)) + ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("current user has no permission to insert"))); + } else if(query->commandType == CMD_UPDATE) { + if(!compare_seclabels(userlabel, rellabel, CMD_UPDATE)) + ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("current user has no permission to update"))); + + if(g_instance.attr.attr_security.enable_mog_mac_row) + add_mac_qual(query, rteindex, query->commandType); + } else if(query->commandType == CMD_DELETE) { + if(!compare_seclabels(userlabel, rellabel, CMD_DELETE)) + ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("current user has no permission to delete"))); + + if(g_instance.attr.attr_security.enable_mog_mac_row) + add_mac_qual(query, rteindex, query->commandType); + } + } + + row_moc(rte->subquery); + } +} + + +static int32 +get_relation_label(Oid reloid) +{ + int32 res = 0; + + HeapTuple tp = SearchSysCache1(RELOID, ObjectIdGetDatum(reloid)); + res = tp->t_data->t_label; + ReleaseSysCache(tp); + return res; +} + +int32 +get_user_label(Oid useroid) +{ + HeapTuple tup = NULL; + int32 result = 0; + + if(IsBootstrapProcessingMode() || useroid == InvalidOid || !g_instance.attr.attr_security.enable_mog_mac) { + return result; + } + + tup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(useroid)); + + if (HeapTupleIsValid(tup)) { + result = tup->t_data->t_label; + ReleaseSysCache(tup); + } + + return result; +} + + +void +mac_rewrite_querytree(List *querytree_list) +{ + ListCell *lc; + + if(!IsUnderPostmaster) + return; + + if(!g_instance.attr.attr_security.enable_mog_mac) + return; + + foreach(lc, querytree_list) { + Query *query = (Query*)lfirst(lc); + row_moc(query); + } +} + + +PG_FUNCTION_INFO_V1(mog_set_rel_label); +PG_FUNCTION_INFO_V1(mog_set_user_label); +PG_FUNCTION_INFO_V1(mog_set_tuple_label); + + +static Oid convert_table_name(text* tablename) +{ + RangeVar* relrv = NULL; + + relrv = makeRangeVarFromNameList(textToQualifiedNameList(tablename)); + + /* We might not even have permissions on this relation; don't lock it. */ + return RangeVarGetRelid(relrv, NoLock, false); +} + + +void setRelationSecLabelInternal(text *relname, int32 label) +{ + Relation relation = NULL; + HeapTuple reltup = NULL; + + + Oid relid = convert_table_name(relname); + reltup = SearchSysCacheCopy1(RELOID,ObjectIdGetDatum(relid)); + + if (!HeapTupleIsValid(reltup)) { + ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), + errmsg("Cache lookup failed for relation %s", text_to_cstring(relname)))); + } + + reltup->t_data->t_label = label; + relation = heap_open(RelationRelationId, RowExclusiveLock); + simple_heap_update(relation,&reltup->t_self, reltup); + CatalogUpdateIndexes(relation, reltup); + + heap_freetuple(reltup); + heap_close(relation, RowExclusiveLock); +} + + + +void setRoleSecLabelInternal(const char *rolename, int32 label) +{ + + Relation relation = NULL; + HeapTuple reltup = NULL; + + reltup = SearchSysCacheCopy1(AUTHNAME, CStringGetDatum(rolename)); + if (!HeapTupleIsValid(reltup)) { + ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), + errmsg("Cache lookup failed "))); + } + + reltup->t_data->t_label = label; + + relation = heap_open(AuthIdRelationId, RowExclusiveLock); + simple_heap_update(relation,&reltup->t_self, reltup); + CatalogUpdateIndexes(relation, reltup); + + heap_freetuple(reltup); + heap_close(relation, RowExclusiveLock); +} + + +void setTupleSecLabelInternal(text *relname, ItemPointer tid, int32 label) +{ + Relation relation; + Buffer buffer; + HeapTupleData tuple; + struct { + HeapTupleHeaderData hdr; + char data[MaxHeapTupleSize]; + } tbuf; + + Oid relid = convert_table_name(relname); + + if (!OidIsValid(relid)) { + ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), + errmsg("Cache lookup failed for relation %s", text_to_cstring(relname)))); + } + + relation = heap_open(relid, RowExclusiveLock); + tuple.t_data = &tbuf.hdr; + tuple.t_self = *tid; + + if(!heap_fetch(relation,SnapshotNow, &tuple, &buffer, false, NULL)) { + ereport(ERROR, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), + errmsg("failed to fetch tuple "))); + } + + ReleaseBuffer(buffer); + tuple.t_data->t_label = label; + + simple_heap_update(relation,&(tuple.t_self), &tuple); + CatalogUpdateIndexes(relation, &tuple); + + heap_close(relation, RowExclusiveLock); +} + + +Datum mog_set_rel_label(PG_FUNCTION_ARGS) +{ + if(!is_seclabel_enabled()) { + ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("current user has no permission to set label"))); + + PG_RETURN_CSTRING("SET RELATION LABEL FAILED"); + } + + setRelationSecLabelInternal(PG_GETARG_TEXT_P(0),PG_GETARG_INT32(1)); + PG_RETURN_CSTRING("SET RELATION LABEL"); +} + +Datum mog_set_user_label(PG_FUNCTION_ARGS) +{ + if(!is_seclabel_enabled()) { + ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("current user has no permission to set label"))); + + PG_RETURN_CSTRING("SET ROLE LABEL FAILED"); + } + + setRoleSecLabelInternal(PG_GETARG_CSTRING(0),PG_GETARG_INT32(1)); + PG_RETURN_CSTRING("SET ROLE LABEL"); +} + +Datum mog_set_tuple_label(PG_FUNCTION_ARGS) +{ + if(!is_seclabel_enabled()) + { + ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("current user has no permission to set label"))); + + PG_RETURN_CSTRING("SET TUPLE LABEL FAILED"); + } + + setTupleSecLabelInternal(PG_GETARG_TEXT_P(0),(ItemPointer)DatumGetPointer(PG_GETARG_DATUM(1)),PG_GETARG_INT32(2)); + + PG_RETURN_CSTRING("SET TUPLE LABEL"); +} + + + /* + * transfrom_mac_seclabel() + * check if the seclable is legal and transform seclabel into mac_seclabel structure + */ + void +transfrom_mac_seclabel(const char *label_level, const char *label_range, mac_seclabel *mac_label_out, bool justcheck) +{ + char *p; + char *label_copy; + char *left_part_p; + char *label_trunc; + char delim; + char *num_p; + int level; + int lower_bit; + int upper_bit; + int i; + + label_copy = pstrdup(label_level); + p = label_copy; + + /* 'l' means the level of seclabel*/ + if (*label_copy != 'l') + elog(ERROR, "Label Level syntax error"); + + if (*(label_copy + 1) == '\0') + elog(ERROR, "Label Level syntax error"); + + for(num_p = label_copy + 1 ; *num_p != 0; num_p++) { + if (!isdigit(*num_p)) + elog(ERROR, "Label Level syntax error"); + } + + level = atoi(label_copy + 1); + + /*the level's range is 0 ~ 1023*/ + if (level < 0 || level > 1023) { + elog(ERROR, "Label Level is out of range"); + } + + if (!justcheck) + mac_label_out->level = level; + + label_copy = pstrdup(label_range); + p = label_copy; + while (1) { + label_trunc = p; + + while(*p && *p != ',') + p++; + + delim = *p; + + if (delim != 0) + *p++ = 0; + + if((left_part_p = strchr(label_trunc,'.')) != NULL) { + *left_part_p++ = 0; + } + + /* 'r' means the range of seclabel*/ + if(*label_trunc != 'r') { + elog(ERROR, "Label Range syntax error"); + } + + for(num_p = label_trunc + 1 ; *num_p != 0; num_p++) { + if(!isdigit(*num_p)) { + elog(ERROR, "Label Level syntax error"); + } + } + + lower_bit = atoi(label_trunc + 1); + + if(lower_bit < 0|| lower_bit > 1023) { + elog(ERROR, "Label Range is out of range"); + } + + if (!justcheck) { + mac_label_out->range = bms_add_member(mac_label_out->range, lower_bit); + } + + if(left_part_p) { + if(*left_part_p != 'r') { + elog(ERROR, "Label Range syntax error"); + } + + if(*(left_part_p + 1) == '\0') { + elog(ERROR, "Label Range syntax error"); + } + + for(num_p = left_part_p + 1 ; *num_p != 0; num_p++) { + if(!isdigit(*num_p)) { + elog(ERROR, "Label Range syntax error"); + } + } + + upper_bit = atoi(left_part_p+1); + + /*The range of seclabel is from 0 ~ 1023*/ + if(upper_bit < 0|| upper_bit > 1023 || upper_bit < lower_bit) { + elog(ERROR, "Label Range is out of range"); + } + + if (!justcheck) { + for(i = lower_bit + 1; i <= upper_bit; i++) { + mac_label_out->range = bms_add_member(mac_label_out->range, i); + } + } + } + + if(delim != ',') { + break; + } + } + + pfree(label_copy); + return; +} + +/* + * getMacLabelFromId() + * get mac_seclabel from it's ID + */ +mac_seclabel * +getMacLabelFromId(int label_id) +{ + HeapTuple tuple; + char *seclabel_level = NULL; + char *seclabel_range = NULL; + mac_seclabel *macaddr_out_p = NULL; + Datum datum; + bool isnull; + Relation macRelation; + ScanKeyData skey; + SysScanDesc scan; + + macaddr_out_p = (mac_seclabel *)palloc(sizeof(mac_seclabel)); + macaddr_out_p->range = (Bitmapset *)palloc0(sizeof(bitmapword)); + + macRelation = heap_open(MogMacSecLabelRelationId, AccessShareLock); + ScanKeyInit(&skey, Anum_mog_mac_seclabel_labelid, BTEqualStrategyNumber, F_OIDEQ, Int32GetDatum(label_id)); + scan = systable_beginscan(macRelation, MogMacSecLabelIdIndexId, true, SnapshotNow, 1, &skey); + + while (HeapTupleIsValid(tuple = systable_getnext(scan))) { + /* get the level */ + datum = heap_getattr(tuple, Anum_mog_mac_seclabel_labellevel, RelationGetDescr(macRelation), &isnull); + if (!isnull) { + seclabel_level = TextDatumGetCString(datum); + } else { + ReleaseSysCache(tuple); + return NULL; + } + + /* get the range */ + datum = heap_getattr(tuple, Anum_mog_mac_seclabel_labelrange, RelationGetDescr(macRelation), &isnull); + if (!isnull) { + seclabel_range = TextDatumGetCString(datum); + } else { + ReleaseSysCache(tuple); + return NULL; + } + + transfrom_mac_seclabel(seclabel_level, seclabel_range, macaddr_out_p, false); + } + + return macaddr_out_p; +} + + +/* + * compare_two_labels() + * compare two seclabel and return the result. + * + * Result include: + * -- LABEL_SUBJECT_DOMINATE + * -- LABEL_EQUAL + * -- LABEL_OBJECT_DOMINATE + * -- LABEL_UNCOMPARARBLE + */ + +LabelComparison +compare_two_labels(mac_seclabel *subject_label, mac_seclabel *object_label) +{ + BMS_Comparison bitmap_result; + LabelComparison result = LABEL_UNCOMPARARBLE; + + /* + * seclabel range compare result include: + * -- BMS_EQUAL : The Range is equal. + * -- BMS_SUBSET1 - The Range 1 is subset of Range 2 + * -- BMS_SUBSET2 - The Range 2 is subset of Range 1 + * -- BMS_DIFFERENT - Other compare result + */ + + bitmap_result = bms_subset_compare(subject_label->range, object_label->range); + + if (subject_label->level > object_label->level) { + if (bitmap_result == BMS_EQUAL || bitmap_result == BMS_SUBSET2) + result = LABEL_SUBJECT_DOMINATE; + else + result = LABEL_UNCOMPARARBLE; + } else if (subject_label->level == object_label->level) { + if (bitmap_result == BMS_EQUAL) + result = LABEL_EQUAL; + else if (bitmap_result == BMS_SUBSET2) + result = LABEL_SUBJECT_DOMINATE; + else if (bitmap_result == BMS_SUBSET1) + result = LABEL_OBJECT_DOMINATE; + else + result = LABEL_UNCOMPARARBLE; + } else { + if (bitmap_result == BMS_EQUAL || bitmap_result == BMS_SUBSET1) + result = LABEL_OBJECT_DOMINATE; + else + result = LABEL_UNCOMPARARBLE; + } + + return result; +} + + +/* + * compare_seclabels() + * According to the type of operation, compare two seclabels. + */ + +static bool compare_seclabels(int subject_seclabel_id, int object_seclabel_id, CmdType cmd_type) +{ + bool res = false; + LabelComparison compare_result = LABEL_UNCOMPARARBLE; + + mac_seclabel *subject_seclabel = getMacLabelFromId(subject_seclabel_id); + mac_seclabel *object_seclabel = getMacLabelFromId(object_seclabel_id); + + if (object_seclabel == NULL) + return true; + if (subject_seclabel == NULL and object_seclabel != NULL) + return false; + + compare_result = compare_two_labels(subject_seclabel, object_seclabel); + + switch(cmd_type) { + /* + * Only subject's seclabel dominate object's seclabel, it has access to select. + */ + case CMD_SELECT: + if (compare_result == LABEL_SUBJECT_DOMINATE || compare_result == LABEL_EQUAL) + res = true; + break; + /* + * Only object's seclabel dominate subject's seclabel, it has access to insert. + */ + case CMD_INSERT: + if (compare_result == LABEL_OBJECT_DOMINATE || compare_result == LABEL_EQUAL) + res = true; + break; + /* + * Only subject's seclabel is equal object's seclabel, it has access to update or delete. + */ + case CMD_UPDATE: + case CMD_DELETE: + if (compare_result == LABEL_EQUAL) + res = true; + break; + default: + elog(ERROR, "unrecognized operation code: %d", (int)cmd_type); + break; + } + + return res; +} + +PG_FUNCTION_INFO_V1(compare_seclabels); + +Datum +compare_seclabels(PG_FUNCTION_ARGS) +{ + bool res = false; + int subject_seclabel_id = PG_GETARG_INT32(0); + int object_seclabel_id = PG_GETARG_INT32(1); + int cmd = PG_GETARG_INT32(2); + CmdType cmd_type =(CmdType)cmd; + + res = compare_seclabels(subject_seclabel_id, object_seclabel_id, cmd_type); + + PG_RETURN_BOOL(res); +} + + +/* + * generate_labelid() + * Generate label ID + */ +int generate_labelid(void) +{ + int labelid = -1; + Relation rel; + TableScanDesc scan; + HeapTuple tuple; + int exist_labelid; + int max_labelid = 0; + + rel = heap_open(MogMacSecLabelRelationId, AccessShareLock); + + scan = heap_beginscan(rel, SnapshotNow, 0, NULL); + while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { + Form_mog_mac_seclabel mac_seclabel = (Form_mog_mac_seclabel)GETSTRUCT(tuple); + exist_labelid = mac_seclabel->labelid; + + if (max_labelid <= exist_labelid) + max_labelid = exist_labelid; + } + + labelid = max_labelid + 1; + + heap_endscan(scan); + heap_close(rel, AccessShareLock); + + return labelid; +} + + +/* + * labelname_check() + * check if it has the same name of seclabel. + */ +void +labelname_check(char *labelname) +{ + Relation rel; + TableScanDesc scan; + HeapTuple tuple; + char *na; + + rel = heap_open(MogMacSecLabelRelationId, AccessShareLock); + + scan = heap_beginscan(rel, SnapshotNow, 0, NULL); + while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { + Form_mog_mac_seclabel mac_seclabel = (Form_mog_mac_seclabel)GETSTRUCT(tuple); + na = NameStr(mac_seclabel->labelname); + + if (strcmp(na, labelname) == 0) { + elog(ERROR, "The seclabel name has existed"); + break; + } + } + + heap_endscan(scan); + heap_close(rel, AccessShareLock); +} + +/* + * is_seclabel_enabled() + * Only Superuser or Poladmin user has the access to process scelabel. + */ +bool is_seclabel_enabled(void) +{ + if (isRelSuperuser() || isPolicyadmin(GetUserId())) { + return true; + } + + return false; +} + +PG_FUNCTION_INFO_V1(mog_add_seclabel); +PG_FUNCTION_INFO_V1(mog_alter_seclabel); +PG_FUNCTION_INFO_V1(mog_drop_seclabel); + +/* + * mog_add_seclabel() + * Add seclabel to mog_mac_seclabel. + */ +Datum +mog_add_seclabel(PG_FUNCTION_ARGS) +{ + Name labelname = PG_GETARG_NAME(0); + text *level = PG_GETARG_TEXT_P(1); + text *range = PG_GETARG_TEXT_P(2); + Relation rel; + HeapTuple htup; + + if(!is_seclabel_enabled()) { + ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("Only superuser or poladmin has permission to add seclabel"))); + + PG_RETURN_CSTRING("ADD SECLABEL FAILED"); + } + + Datum values[Natts_mog_mac_seclabel] = {0}; + bool nulls[Natts_mog_mac_seclabel] = {false}; + + /*Check if the label name is existed*/ + labelname_check(NameStr(*labelname)); + + /*Label specification check*/ + transfrom_mac_seclabel(text_to_cstring(level), text_to_cstring(range), NULL, true); + + values[Anum_mog_mac_seclabel_labelid - 1] = Int32GetDatum(generate_labelid()); + values[Anum_mog_mac_seclabel_labelname - 1] = NameGetDatum(labelname); + values[Anum_mog_mac_seclabel_labellevel - 1] = PointerGetDatum(level); + values[Anum_mog_mac_seclabel_labelrange - 1] = PointerGetDatum(range); + + rel = heap_open(MogMacSecLabelRelationId, RowExclusiveLock); + + htup = heap_form_tuple(RelationGetDescr(rel), values, nulls); + simple_heap_insert(rel, htup); + + CatalogUpdateIndexes(rel, htup); + heap_freetuple(htup); + heap_close(rel, RowExclusiveLock); + + PG_RETURN_CSTRING("ADD SECLABEL"); +} + + +/* + * mog_alter_seclabel() + * Alter seclabel into mog_mac_seclabel. + */ +Datum +mog_alter_seclabel(PG_FUNCTION_ARGS) +{ + int labelid = PG_GETARG_INT32(0); + text *level = PG_GETARG_TEXT_P(1); + text *range = PG_GETARG_TEXT_P(2); + Relation rel; + HeapTuple htup; + Datum values[Natts_mog_mac_seclabel] = {0}; + bool nulls[Natts_mog_mac_seclabel] = {false}; + bool replaces[Natts_mog_mac_seclabel] = { false }; + Relation macRelation; + ScanKeyData skey; + SysScanDesc scan; + + if (labelid == 0) { + elog(ERROR, "default label cannot be modified!"); + } + + if(!is_seclabel_enabled()) { + ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("Only superuser or poladmin has permission to alter seclabel"))); + + PG_RETURN_CSTRING("ALTER SECLABEL FAILED"); + } + + + /*Label specification check*/ + transfrom_mac_seclabel(text_to_cstring(level), text_to_cstring(range), NULL, true); + + values[Anum_mog_mac_seclabel_labellevel - 1] = PointerGetDatum(level); + replaces[Anum_mog_mac_seclabel_labellevel - 1] = true; + + values[Anum_mog_mac_seclabel_labelrange - 1] = PointerGetDatum(range); + replaces[Anum_mog_mac_seclabel_labelrange - 1] = true; + + rel = heap_open(MogMacSecLabelRelationId, RowExclusiveLock); + ScanKeyInit(&skey, Anum_mog_mac_seclabel_labelid, BTEqualStrategyNumber, F_OIDEQ, Int32GetDatum(labelid)); + scan = systable_beginscan(rel, MogMacSecLabelIdIndexId, true, SnapshotNow, 1, &skey); + + while (HeapTupleIsValid(htup = systable_getnext(scan))) { + HeapTuple newtuple = heap_modify_tuple(htup, RelationGetDescr(rel), values, nulls, replaces); + simple_heap_update(rel, &newtuple->t_self, newtuple); + CatalogUpdateIndexes(rel, newtuple); + } + + heap_close(rel, RowExclusiveLock); + PG_RETURN_CSTRING("ALTER SECLABEL"); +} + + +/* + * mog_drop_seclabel() + * Drop seclabel from mog_mac_seclabel. + */ +Datum +mog_drop_seclabel(PG_FUNCTION_ARGS) +{ + int labelid = PG_GETARG_INT32(0); + HeapTuple htup; + Relation macRelation; + ScanKeyData skey; + SysScanDesc scan; + + if (labelid == 0) + { + elog(ERROR, "default label cannot be droped!"); + } + + if(!is_seclabel_enabled()) { + ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("Only superuser or poladmin has permission to drop seclabel"))); + + PG_RETURN_CSTRING("DROP SECLABEL FAILED"); + } + + Relation rel = heap_open(MogMacSecLabelRelationId, AccessShareLock); + ScanKeyInit(&skey, Anum_mog_mac_seclabel_labelid, BTEqualStrategyNumber, F_OIDEQ, Int32GetDatum(labelid)); + scan = systable_beginscan(rel, MogMacSecLabelIdIndexId, true, SnapshotNow, 1, &skey); + + while (HeapTupleIsValid(htup = systable_getnext(scan))) { + simple_heap_delete(rel, &htup->t_self); + } + + heap_close(rel, AccessShareLock); + PG_RETURN_CSTRING("DROP SECLABEL"); +} + + +void mog_mac_seclabel_check(ParseState *pstate, Query *query) +{ + ListCell *lc; + + /* check if enable_mog_mac is on or off*/ + if(!g_instance.attr.attr_security.enable_mog_mac) + return; + + foreach(lc, query->rtable) { + Node *node = (Node*)lfirst(lc); + RangeTblEntry *rte = (RangeTblEntry *)node; + + if(rte->relid == MogMacSecLabelRelationId && !is_seclabel_enabled()) { + ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("Only superuser or poladmin has permission to access mog_mac_seclabel"))); + + return; + } + + } + + return; +} diff --git a/src/gausskernel/storage/access/common/heaptuple.cpp b/src/gausskernel/storage/access/common/heaptuple.cpp index 47ba9a776d2fc97c19e70409ecacd0ca4acc366f..4b2bd8c101bcb0c8b2b64ee0ba1e0c155965a463 100644 --- a/src/gausskernel/storage/access/common/heaptuple.cpp +++ b/src/gausskernel/storage/access/common/heaptuple.cpp @@ -66,10 +66,12 @@ #include "access/tuptoaster.h" #include "access/tableam.h" #include "access/ustore/knl_utuple.h" +#include "catalog/pg_authid.h" #include "catalog/pg_proc.h" #include "executor/tuptable.h" #include "postmaster/autovacuum.h" #include "storage/buf/bufmgr.h" +#include "mog_mac/mog_mac.h" #include "storage/pagecompress.h" #include "utils/memutils.h" #include "utils/elog.h" @@ -277,6 +279,7 @@ bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupDesc) case MinCommandIdAttributeNumber: case MaxTransactionIdAttributeNumber: case MaxCommandIdAttributeNumber: + case SecLabelAttributeNumber: #ifdef PGXC case XC_NodeIdAttributeNumber: case BucketIdAttributeNumber: @@ -581,6 +584,9 @@ Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnu case TableOidAttributeNumber: result = ObjectIdGetDatum(tup->t_tableOid); break; + case SecLabelAttributeNumber: + result = Int32GetDatum(tup->t_data->t_label); + break; #ifdef PGXC case BucketIdAttributeNumber: result = ObjectIdGetDatum((uint2)tup->t_bucketId); @@ -702,6 +708,7 @@ HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull Form_pg_attribute *att = tupleDescriptor->attrs; int numberOfAttributes = tupleDescriptor->natts; int i; + Oid CurrentUser = InvalidOid; if (numberOfAttributes > MaxTupleAttributeNumber) { ereport(ERROR, @@ -781,6 +788,14 @@ HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull HeapTupleHeaderSetTypMod(td, tupleDescriptor->tdtypmod); HeapTupleHeaderSetNatts(td, numberOfAttributes); + + if (att) + { + if(att[0]->attrelid != AuthIdRelationId) + CurrentUser = GetCurrentUserId(); + } + + td->t_label = get_user_label(CurrentUser); td->t_hoff = hoff; /* else leave infomask = 0 */ diff --git a/src/include/access/htup.h b/src/include/access/htup.h index e32dcf5e6307ba3796b55b7b15e429d6705225d9..0a0851c81f3b2564e09412504108c3dd649948c7 100644 --- a/src/include/access/htup.h +++ b/src/include/access/htup.h @@ -170,9 +170,11 @@ typedef struct HeapTupleHeaderData { uint16 t_infomask; /* various flag bits, see below */ + int32 t_label; /* var for mandatory access control */ + uint8 t_hoff; /* sizeof header incl. bitmap, padding */ - /* ^ - 23 bytes - ^ */ + /* ^ - 24 bytes - ^ */ bits8 t_bits[FLEXIBLE_ARRAY_MEMBER]; /* bitmap of NULLs -- VARIABLE LENGTH */ @@ -359,6 +361,12 @@ typedef HeapTupleHeaderData* HeapTupleHeader; #define HeapTupleSetXmin(tup, xid) \ ((tup)->t_data->t_choice.t_heap.t_xmin = NormalTransactionIdToShort((tup)->t_xid_base, (xid))) +#define HeapTupleSetSafeLable(tup) \ + ((tup)->t_data->t_lable = 1) + +#define HeapTupleGetSafeLable(tup) \ + ((tup)->t_data->t_lable) + /* * HeapTupleHeaderGetRawCommandId will give you what's in the header whether * it is useful or not. Most code should use HeapTupleHeaderGetCmin or @@ -591,6 +599,8 @@ typedef struct MinimalTupleData { uint16 t_infomask; /* various flag bits, see below */ + int32 t_label; /* var for mandatory access control */ + uint8 t_hoff; /* sizeof header incl. bitmap, padding */ /* ^ - 23 bytes - ^ */ diff --git a/src/include/access/sysattr.h b/src/include/access/sysattr.h index 7d8d13932978745da1a55607f24eac09c2be774b..215e94054a2e70cd06446e5dc21e3da486cdb3ad 100644 --- a/src/include/access/sysattr.h +++ b/src/include/access/sysattr.h @@ -24,15 +24,16 @@ #define MaxTransactionIdAttributeNumber (-5) #define MaxCommandIdAttributeNumber (-6) #define TableOidAttributeNumber (-7) +#define SecLabelAttributeNumber (-8) #ifdef PGXC -#define XC_NodeIdAttributeNumber (-8) -#define BucketIdAttributeNumber (-9) -#define UidAttributeNumber (-10) -#define FirstLowInvalidHeapAttributeNumber (-11) +#define XC_NodeIdAttributeNumber (-9) +#define BucketIdAttributeNumber (-10) +#define UidAttributeNumber (-11) +#define FirstLowInvalidHeapAttributeNumber (-12) #else -#define FirstLowInvalidHeapAttributeNumber (-8) +#define FirstLowInvalidHeapAttributeNumber (-9) #endif #endif /* SYSATTR_H */ diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index bad2396752b49698c6b8774f0c7605addc8266cd..8772d1b0c8f6501275463d22e1025bbcd5078aed 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -619,6 +619,10 @@ DECLARE_INDEX(gs_txn_snapshot_csn_xmin_index, 8654, on gs_txn_snapshot using btr DECLARE_INDEX(gs_txn_snapshot_xmin_index, 8655, on gs_txn_snapshot using btree(snpxmin int8_ops)); #define SnapshotXminIndexId 8655 +/* Add index of table oid for mog_mac_seclabel */ +DECLARE_UNIQUE_INDEX(mog_mac_seclabel_id_index, 9994, on mog_mac_seclabel using btree(labelid int4_ops)); +#define MogMacSecLabelIdIndexId 9994 + /* Add index of table model name for gs_opt_model */ DECLARE_UNIQUE_INDEX(gs_opt_model_name_index, 9997, on gs_opt_model using btree(model_name name_ops)); #define GsOPTModelNameIndexId 9997 diff --git a/src/include/catalog/mog_mac_seclabel.h b/src/include/catalog/mog_mac_seclabel.h new file mode 100644 index 0000000000000000000000000000000000000000..b2d0a63aaa1df17833cd3b1dc5f0ee8c55290cea --- /dev/null +++ b/src/include/catalog/mog_mac_seclabel.h @@ -0,0 +1,55 @@ +/* + * 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. + * ------------------------------------------------------------------------- + * + * mog_mac_seclabel.h + * + * IDENTIFICATION + * src/include/catalog/mog_mac_seclabel.h + * + * ------------------------------------------------------------------------- + */ +#ifndef MOG_MAC_SECLABEL_H +#define MOG_MAC_SECLABEL_H + +#include "postgres.h" +#include "catalog/genbki.h" + +#define MogMacSecLabelRelationId 9100 + +CATALOG(mog_mac_seclabel,9100) BKI_SCHEMA_MACRO BKI_WITHOUT_OIDS +{ + int4 labelid; /*label oid*/ + NameData labelname; /*label name*/ +#ifdef CATALOG_VARLEN + text labellevel; /*label level */ + text labelrange; /*label range*/ +#endif +} FormData_mog_mac_seclabel; + +typedef FormData_mog_mac_seclabel *Form_mog_mac_seclabel; + +#define Natts_mog_mac_seclabel 4 + +#define Anum_mog_mac_seclabel_labelid 1 +#define Anum_mog_mac_seclabel_labelname 2 +#define Anum_mog_mac_seclabel_labellevel 3 +#define Anum_mog_mac_seclabel_labelrange 4 + +/* + * initial contents of mog_mac_seclabel + */ +DATA(insert (0 "default_label" "l0" "r0.r1023")); + +#endif /* MOG_MAC_SECLABEL_H */ diff --git a/src/include/catalog/pg_proc.h_for_llt b/src/include/catalog/pg_proc.h_for_llt index a34bd83c479af42c52d907287fb9aa853e82182a..7a6baf0c0a79e2652827c892813abe1066dab24b 100755 --- a/src/include/catalog/pg_proc.h_for_llt +++ b/src/include/catalog/pg_proc.h_for_llt @@ -5778,4 +5778,13 @@ DATA(insert OID = 4463 ( byteawithoutorderwithequalcolcmpbyteal PGNSP PGUID DATA(insert OID = 4369 ( hll_hash_byteawithoutorderwithequalcol PGNSP PGUID 12 1 0 0 - f f f f t f i 1 0 4303 "4402" _null_ _null_ _null_ _null_ hll_hash_varlena _null_ _null_ _null_ "" f f f)); DESCR("hypper log log hash a byteawithoutorderwithequalcol type"); DATA(insert OID = 4449 ( byteawithoutorderwithequalcoltypmodin PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "1263" _null_ _null_ _null_ _null_ byteawithoutorderwithequalcoltypmodin _null_ _null_ _null_ "" f _null_ f)); + +DATA(insert OID = 4458 ( compare_seclabels PGNSP PGUID 12 1 0 0 0 f f f t t f i 3 0 16 "26 26 23" _null_ _null_ _null_ _null_ compare_seclabels _null_ _null_ _null_ "" f)); +DATA(insert OID = 4459 ( mog_set_rel_label PGNSP PGUID 12 1 0 0 0 f f f t t f s 2 0 2275 "25 23" _null_ _null_ _null_ _null_ setRelationSecLabel _null_ _null_ _null_ "" f)); +DATA(insert OID = 4470 ( mog_set_user_label PGNSP PGUID 12 1 0 0 0 f f f t t f s 2 0 2275 "2275 23" _null_ _null_ _null_ _null_ setRoleSecLabel _null_ _null_ _null_ "" f)); +DATA(insert OID = 4471 ( mog_set_tuple_label PGNSP PGUID 12 1 0 0 0 f f f t t f s 3 0 2275 "25 27 23" _null_ _null_ _null_ _null_ setTupleSecLabel _null_ _null_ _nul l_ "" f)); +DATA(insert OID = 4472 ( mog_add_seclabel PGNSP PGUID 12 1 0 0 0 f f f t t f s 3 0 2275 "19 25 25" _null_ _null_ _null_ _null_ mog_add_seclabel _null_ _null_ _null_ "" f)); +DATA(insert OID = 4473 ( mog_drop_seclabel PGNSP PGUID 12 1 0 0 0 f f f t t f s 1 0 2275 "23" _null_ _null_ _null_ _null_ mog_drop_seclabel _null_ _null_ _null_ "" f )); +DATA(insert OID = 4474 ( mog_alter_seclabel PGNSP PGUID 12 1 0 0 0 f f f t t f s 3 0 2275 "23 25 25" _null_ _null_ _null_ _null_ mog_alter_seclabel _null_ _null_ _nu ll_ "" f)); + #endif /* PG_PROC_H */ diff --git a/src/include/knl/knl_guc/knl_instance_attr_security.h b/src/include/knl/knl_guc/knl_instance_attr_security.h index 89b8c731eaee83bfcf428c87cd9fdfe89a3aeed1..131fea43f62f7dbd6d00842fcc812d3767a3ce56 100644 --- a/src/include/knl/knl_guc/knl_instance_attr_security.h +++ b/src/include/knl/knl_guc/knl_instance_attr_security.h @@ -44,6 +44,8 @@ typedef struct knl_instance_attr_security { bool EnableSSL; bool enablePrivilegesSeparate; bool enable_nonsysadmin_execute_direct; + bool enable_mog_mac; + bool enable_mog_mac_row; bool enable_tde; char* ssl_cert_file; char* ssl_key_file; diff --git a/src/include/mog_mac/mog_mac.h b/src/include/mog_mac/mog_mac.h new file mode 100644 index 0000000000000000000000000000000000000000..3480d4c1eb7768ef55966b7f49d483d817143f46 --- /dev/null +++ b/src/include/mog_mac/mog_mac.h @@ -0,0 +1,53 @@ +/* + * mog_mac.h + * handle the mandatory access control + * + * IDENTIFICATION + * src/include/mog_mac/mog_mac.h + * + * --------------------------------------------------------------------------------------- + */ + +#include "postgres.h" +#include "nodes/pg_list.h" +#include "nodes/bitmapset.h" + + +typedef struct mac_seclabel +{ + int4 level; + Bitmapset *range; + +}mac_seclabel; + +/* + * The possible result when comparing two seclabels. + */ +typedef enum +{ + LABEL_SUBJECT_DOMINATE, + LABEL_EQUAL, + LABEL_OBJECT_DOMINATE, + LABEL_UNCOMPARARBLE +}LabelComparison; + + +static void add_mac_qual(Query *query, Index rteindex, CmdType optype); +static void row_moc(Query *query); +int32 get_user_label(Oid useroid); +void mac_rewrite_querytree(List *querytree_list); +bool is_seclabel_enabled(void); +void mac_rewrite_querytree(List *querytree_list); +static Oid convert_table_name(text* tablename); +void setRelationSecLabelInternal(text *relname, int32 label); +void setRoleSecLabelInternal(const char *rolename, int32 label); +void setTupleSecLabelInternal(text *relname, ItemPointer tid, int32 label); +void transfrom_mac_seclabel(const char *label_level, const char *label_range, mac_seclabel *mac_label_out, bool justcheck); +mac_seclabel *getMacLabelFromId(int label_id); +LabelComparison compare_two_labels(mac_seclabel *subject_label, mac_seclabel *object_label); +static bool compare_seclabels(int subject_seclabel_id, int object_seclabel_id, CmdType cmd_type); +int generate_labelid(void); +void labelname_check(char *labelname); +bool is_seclabel_enabled(void); + +void mog_mac_seclabel_check(ParseState *pstate, Query *query); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h old mode 100755 new mode 100644 index 5de8a4d12d7998b61045f2bea92baacf01a1266f..9b3280d715f650132695e8212d2e96c2734f4c18 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -1635,6 +1635,14 @@ extern Datum mot_global_memory_detail(PG_FUNCTION_ARGS); extern Datum mot_local_memory_detail(PG_FUNCTION_ARGS); extern Datum mot_session_memory_detail(PG_FUNCTION_ARGS); +extern Datum compare_seclabels(PG_FUNCTION_ARGS); +extern Datum setRelationSecLabel(PG_FUNCTION_ARGS); +extern Datum setRoleSecLabel(PG_FUNCTION_ARGS); +extern Datum setTupleSecLabel(PG_FUNCTION_ARGS); +extern Datum mog_add_seclabel(PG_FUNCTION_ARGS); +extern Datum mog_drop_seclabel(PG_FUNCTION_ARGS); +extern Datum mog_alter_seclabel(PG_FUNCTION_ARGS); + /* UBtree index */ Datum gs_index_verify(PG_FUNCTION_ARGS); Datum gs_index_recycle_queue(PG_FUNCTION_ARGS);