17 #include "catalog/pg_type.h" 18 #include "access/xact.h" 19 #include "executor/spi.h" 20 #include "access/htup_details.h" 21 #include "utils/builtins.h" 159 if (!session_roleprivs) {
168 else if ((
this < 0) || (
this >= upper)) {
177 cmp = this_cp->
scope - scope;
194 this = (upper + lower) >> 1;
225 return bitmapTestbit(
239 pfree((
void *) cp->
roles);
253 MemoryContext old_context;
254 old_context = MemoryContextSwitchTo(TopMemoryContext);
256 if (session_roleprivs) {
263 MemoryContextSwitchTo(old_context);
270 #define CONTEXT_ROLEPRIVS_INCREMENT 16 277 #define CONTEXT_ROLEPRIVS_SIZE(elems) ( \ 278 sizeof(SessionRolePrivs) + \ 279 (sizeof(ContextRolePrivs) * \ 280 (elems + CONTEXT_ROLEPRIVS_INCREMENT))) 294 if (session_roleprivs) {
300 i < session_roleprivs->array_len; i++)
310 if (!session_roleprivs) {
312 (errcode(ERRCODE_INTERNAL_ERROR),
313 errmsg(
"Unable to create session memory in " 314 "extendSessionPrivs()")));
331 MemoryContext old_context;
334 if (!session_roleprivs) {
349 old_context = MemoryContextSwitchTo(TopMemoryContext);
352 MemoryContextSwitchTo(old_context);
368 MemoryContext old_context;
376 old_context = MemoryContextSwitchTo(TopMemoryContext);
380 MemoryContextSwitchTo(old_context);
397 static bool init_done =
false;
398 static bool error =
true;
403 "select parameter_value::boolean" 404 " from veil2.system_parameters" 405 " where parameter_name = 'error on uninitialized session'",
406 0, NULL, NULL, NULL, &error);
432 my_tup->
f1 = DatumGetInt32(SPI_getbinval(tuple, tupdesc, 1, &isnull));
433 my_tup->
f2 = DatumGetInt32(SPI_getbinval(tuple, tupdesc, 2, &isnull));
448 "create temporary table veil2_ancestor_privileges" 449 " of veil2.session_privileges_t",
469 "select count(*)::integer," 470 " sum(case when c.relacl is null then 1 else 0 end)" 471 " from pg_catalog.pg_class c" 472 " where c.relname = 'veil2_ancestor_privileges'" 473 " and c.relkind = 'r'" 474 " and c.relpersistence = 't'" 475 " and pg_catalog.pg_table_is_visible(c.oid)",
480 if (processed == 0) {
483 (errcode(ERRCODE_INTERNAL_ERROR),
484 errmsg(
"Temp tables query fails in veil2_reset_session()")));
487 if (processed != 1) {
490 (errcode(ERRCODE_INTERNAL_ERROR),
491 errmsg(
"Unexpected processing error in " 492 "veil2_reset_session: %d", processed)));
494 if (my_tup.f1 == 0) {
499 else if (my_tup.f1 == 1) {
502 if (my_tup.f2 != 1) {
504 (errcode(ERRCODE_INTERNAL_ERROR),
505 errmsg(
"Unexpected access to temp table in " 506 "veil2_reset_session"),
507 errdetail(
"This indicates an attempt to bypass " 513 session_context.
loaded =
false;
520 (errcode(ERRCODE_INTERNAL_ERROR),
521 errmsg(
"Unexpected count of temp tables in " 522 "veil2_reset_session: %d", my_tup.f1),
523 errdetail(
"This indicates an attempt to bypass " 601 static bool allnulls[9] = {
true,
true,
true,
true,
602 true,
true,
true,
true,
true};
603 static bool nonulls[9] = {
false,
false,
false,
false,
604 false,
false,
false,
false,
false};
606 TupleDesc tuple_desc;
608 if (get_call_result_type(fcinfo, NULL,
609 &tuple_desc) != TYPEFUNC_COMPOSITE) {
611 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
612 errmsg(
"function returning record called in context " 613 "that cannot accept type record")));
615 tuple_desc = BlessTupleDesc(tuple_desc);
617 if (!PG_ARGISNULL(0)) {
619 session_context.
session_id = PG_GETARG_INT64(1);
626 if (PG_ARGISNULL(8)) {
632 session_context.
loaded =
true;
634 if (session_context.
loaded) {
635 results[0] = Int32GetDatum(session_context.
accessor_id);
636 results[1] = Int64GetDatum(session_context.
session_id);
657 tuple = heap_form_tuple(tuple_desc, results, nulls);
658 tuple_desc = BlessTupleDesc(tuple_desc);
659 return HeapTupleGetDatum(tuple);
674 FuncCallContext *funcctx;
675 AttInMetadata *attinmeta;
676 MemoryContext oldcontext;
679 bool nulls[4] = {
false,
false,
false,
false};
681 if (SRF_IS_FIRSTCALL()) {
682 funcctx = SRF_FIRSTCALL_INIT();
683 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
685 tupdesc = RelationNameGetTupleDesc(
"veil2.session_privileges_t");
686 funcctx->tuple_desc = tupdesc;
687 attinmeta = TupleDescGetAttInMetadata(tupdesc);
688 funcctx->attinmeta = attinmeta;
690 MemoryContextSwitchTo(oldcontext);
693 funcctx->user_fctx = (
void *) 0;
696 funcctx = SRF_PERCALL_SETUP();
697 idx = (long) funcctx->user_fctx;
699 if (session_roleprivs &&
700 (idx < session_roleprivs->active_contexts)) {
705 results[0] = Int32GetDatum(session_roleprivs->
706 context_roleprivs[idx].scope_type);
707 results[1] = Int32GetDatum(session_roleprivs->
708 context_roleprivs[idx].scope);
710 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
712 results[2] = (Datum) bitmapCopy(bitmap);
719 results[3] = (Datum) bitmapCopy(bitmap);
724 MemoryContextSwitchTo(oldcontext);
725 tupdesc = funcctx->tuple_desc;
726 tuple = heap_form_tuple(tupdesc, results, nulls);
727 tupdesc = BlessTupleDesc(tupdesc);
728 datum = TupleGetDatum(tupdesc, tuple);
729 funcctx->user_fctx = (
void *) (idx + 1);
730 SRF_RETURN_NEXT(funcctx, datum);
733 SRF_RETURN_DONE(funcctx);
753 int scope_type_id = PG_GETARG_INT32(0);
754 int scope_id = PG_GETARG_INT32(1);
755 Bitmap *roles = PG_GETARG_BITMAP(2);
756 Bitmap *privs = PG_GETARG_BITMAP(3);
777 int scope_type_id = PG_GETARG_INT32(0);
778 int scope_id = PG_GETARG_INT32(1);
779 Bitmap *roles = PG_GETARG_BITMAP(2);
780 Bitmap *privs = PG_GETARG_BITMAP(3);
817 (errcode(ERRCODE_INTERNAL_ERROR),
818 errmsg(
"Attempt to check privileges before call to " 819 "veil2_reset_session.")));
837 static int context_idx = -1;
838 int priv = PG_GETARG_INT32(0);
866 static int context_idx = -1;
868 int priv = PG_GETARG_INT32(0);
869 int accessor_id = PG_GETARG_INT32(1);
872 result =
checkContext(&context_idx, 2, accessor_id, priv);
897 static int context_idx = -1;
899 int priv = PG_GETARG_INT32(0);
900 int scope_type_id = PG_GETARG_INT32(1);
901 int scope_id = PG_GETARG_INT32(2);
904 result =
checkContext(&context_idx, scope_type_id, scope_id, priv);
929 static int global_context_idx = -1;
930 static int given_context_idx = -1;
932 int priv = PG_GETARG_INT32(0);
933 int scope_type_id = PG_GETARG_INT32(1);
934 int scope_id = PG_GETARG_INT32(2);
965 static void *saved_plan = NULL;
969 int priv = PG_GETARG_INT32(0);
970 int scope_type_id = PG_GETARG_INT32(1);
971 int scope_id = PG_GETARG_INT32(2);
972 Oid argtypes[] = {INT4OID, INT4OID, INT4OID};
973 Datum args[] = {Int32GetDatum(priv),
974 Int32GetDatum(scope_type_id),
975 Int32GetDatum(scope_id)};
979 "SPI connect failed in " 980 "veil2_i_have_priv_in_superior_scope()");
983 " from veil2.all_superior_scopes asp" 984 " inner join veil2.session_privileges() sp" 985 " on sp.scope_type_id = asp.superior_scope_type_id" 986 " and sp.scope_id = asp.superior_scope_id" 987 " where asp.scope_type_id = $2" 988 " and asp.scope_id = $3" 989 " and sp.privs ? $1",
991 &saved_plan, &result);
994 "SPI finish failed in " 995 "veil2_i_have_priv_in_superior_scope()");
996 result = found && result;
1021 static int context_idx = -1;
1022 static void *saved_plan = NULL;
1026 int priv = PG_GETARG_INT32(0);
1027 int scope_type_id = PG_GETARG_INT32(1);
1028 int scope_id = PG_GETARG_INT32(2);
1029 Oid argtypes[] = {INT4OID, INT4OID, INT4OID};
1030 Datum args[] = {Int32GetDatum(priv),
1031 Int32GetDatum(scope_type_id),
1032 Int32GetDatum(scope_id)};
1038 result =
checkContext(&context_idx, scope_type_id, scope_id, priv);
1042 "SPI connect failed in " 1043 "veil2_i_have_priv_in_scope_or_superior()");
1046 " from veil2.all_superior_scopes asp" 1047 " inner join veil2.session_privileges() sp" 1048 " on sp.scope_type_id = asp.superior_scope_type_id" 1049 " and sp.scope_id = asp.superior_scope_id" 1050 " where asp.scope_type_id = $2" 1051 " and asp.scope_id = $3" 1052 " and sp.privs ? $1",
1054 &saved_plan, &result);
1057 "SPI finish failed in " 1058 "veil2_i_have_priv_in_scope_or_superior()");
1059 result = found && result;
1087 static int global_context_idx = -1;
1088 static int given_context_idx = -1;
1089 static void *saved_plan = NULL;
1093 int priv = PG_GETARG_INT32(0);
1094 int scope_type_id = PG_GETARG_INT32(1);
1095 int scope_id = PG_GETARG_INT32(2);
1096 Oid argtypes[] = {INT4OID, INT4OID, INT4OID};
1097 Datum args[] = {Int32GetDatum(priv),
1098 Int32GetDatum(scope_type_id),
1099 Int32GetDatum(scope_id)};
1108 "SPI connect failed in " 1109 "veil2_i_have_priv_in_scope_or_superior()");
1112 " from veil2.all_superior_scopes asp" 1113 " inner join veil2.session_privileges() sp" 1114 " on sp.scope_type_id = asp.superior_scope_type_id" 1115 " and sp.scope_id = asp.superior_scope_id" 1116 " where asp.scope_type_id = $2" 1117 " and asp.scope_id = $3" 1118 " and sp.privs ? $1",
1120 &saved_plan, &result);
1123 "SPI finish failed in " 1124 "veil2_i_have_priv_in_scope_or_superior()");
1125 result = found && result;
1144 Datum results[2] = {Int32GetDatum(
result_counts[0] & INT_MAX),
1146 bool nulls[2] = {
false,
false};
1147 TupleDesc tuple_desc;
1149 if (get_call_result_type(fcinfo, NULL,
1150 &tuple_desc) != TYPEFUNC_COMPOSITE) {
1152 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1153 errmsg(
"function returning record called in context " 1154 "that cannot accept type record")));
1156 tuple_desc = BlessTupleDesc(tuple_desc);
1157 tuple = heap_form_tuple(tuple_desc, results, nulls);
1158 return HeapTupleGetDatum(tuple);
1171 int len = strlen(in);
1172 text *out = palloc(len + VARHDRSZ);
1173 memcpy(VARDATA(out), in, len);
1174 SET_VARSIZE(out, (len + VARHDRSZ));
static SessionContext session_context
Datum veil2_datapath(FunctionCallInfo fcinfo)
Datum veil2_reset_session_privs(FunctionCallInfo fcinfo)
static int result_counts[]
#define CONTEXT_ROLEPRIVS_INCREMENT
Datum veil2_update_session_privileges(FunctionCallInfo fcinfo)
Main header file for veil2.
Datum veil2_i_have_priv_in_scope_or_global(FunctionCallInfo fcinfo)
static void freeContextRolePrivs(ContextRolePrivs *cp)
void veil2_spi_finish(bool pushed, const char *msg)
Datum veil2_i_have_priv_in_scope_or_superior_or_global(FunctionCallInfo fcinfo)
Datum veil2_true(FunctionCallInfo fcinfo)
static void findContext(int *p_idx, int scope_type, int scope)
static bool fetch_2ints(HeapTuple tuple, TupleDesc tupdesc, void *p_result)
static bool checkContext(int *p_idx, int scope_type, int scope, int priv)
static SessionRolePrivs * extendSessionRolePrivs(SessionRolePrivs *session_roleprivs)
static void add_scope_roleprivs(int scope_type, int scope, Bitmap *roles, Bitmap *privs)
Datum veil2_session_ready(FunctionCallInfo fcinfo)
Datum veil2_i_have_priv_in_scope_or_superior(FunctionCallInfo fcinfo)
Datum veil2_session_privileges(FunctionCallInfo fcinfo)
static void create_temp_tables()
Datum veil2_i_have_global_priv(FunctionCallInfo fcinfo)
static text * textfromstr(char *in)
Datum veil2_add_session_privileges(FunctionCallInfo fcinfo)
Datum veil2_session_context(FunctionCallInfo fcinfo)
static SessionRolePrivs * session_roleprivs
static bool checkSessionReady()
bool veil2_bool_from_query(const char *qry, int nargs, Oid *argtypes, Datum *args, void **saved_plan, bool *result)
int login_context_type_id
ContextRolePrivs context_roleprivs[0]
Datum veil2_reset_session(FunctionCallInfo fcinfo)
#define CONTEXT_ROLEPRIVS_SIZE(elems)
Datum veil2_i_have_priv_in_scope(FunctionCallInfo fcinfo)
Datum veil2_result_counts(FunctionCallInfo fcinfo)
static void do_reset_session(bool clear_context)
Datum veil2_docpath(FunctionCallInfo fcinfo)
int veil2_query(const char *qry, int nargs, Oid *argtypes, Datum *args, bool read_only, void **saved_plan, Fetch_fn process_row, void *fn_param)
static bool error_if_no_session()
Datum veil2_version(FunctionCallInfo fcinfo)
int session_context_type_id
static bool session_roleprivs_loaded
static void update_scope_roleprivs(int scope_type, int scope, Bitmap *roles, Bitmap *privs)
void veil2_spi_connect(bool *p_pushed, const char *msg)
int mapping_context_type_id
static void clear_session_roleprivs()
Datum veil2_i_have_personal_priv(FunctionCallInfo fcinfo)
Datum veil2_i_have_priv_in_superior_scope(FunctionCallInfo fcinfo)
static bool session_ready