4090 lines
133 KiB
Diff
4090 lines
133 KiB
Diff
diff -rpNU3 base/src/backend/Makefile pgace/src/backend/Makefile
|
|
--- base/src/backend/Makefile 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/Makefile 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -16,7 +16,7 @@ include $(top_builddir)/src/Makefile.glo
|
|
|
|
DIRS = access bootstrap catalog parser commands executor lib libpq \
|
|
main nodes optimizer port postmaster regex rewrite \
|
|
- storage tcop tsearch utils $(top_builddir)/src/timezone
|
|
+ security storage tcop tsearch utils $(top_builddir)/src/timezone
|
|
|
|
SUBSYSOBJS = $(DIRS:%=%/SUBSYS.o)
|
|
|
|
diff -rpNU3 base/src/backend/access/common/heaptuple.c pgace/src/backend/access/common/heaptuple.c
|
|
--- base/src/backend/access/common/heaptuple.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/access/common/heaptuple.c 2008-01-10 12:42:25.000000000 +0900
|
|
@@ -67,6 +67,7 @@
|
|
#include "access/heapam.h"
|
|
#include "access/tuptoaster.h"
|
|
#include "executor/tuptable.h"
|
|
+#include "security/pgace.h"
|
|
|
|
|
|
/* Does att's datatype allow packing into the 1-byte-header varlena format? */
|
|
@@ -473,6 +474,9 @@ heap_attisnull(HeapTuple tup, int attnum
|
|
case MinCommandIdAttributeNumber:
|
|
case MaxTransactionIdAttributeNumber:
|
|
case MaxCommandIdAttributeNumber:
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+ case SecurityAttributeNumber:
|
|
+#endif
|
|
/* these are never null */
|
|
break;
|
|
|
|
@@ -785,6 +789,11 @@ heap_getsysattr(HeapTuple tup, int attnu
|
|
case TableOidAttributeNumber:
|
|
result = ObjectIdGetDatum(tup->t_tableOid);
|
|
break;
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+ case SecurityAttributeNumber:
|
|
+ result = ObjectIdGetDatum(HeapTupleGetSecurity(tup));
|
|
+ break;
|
|
+#endif
|
|
default:
|
|
elog(ERROR, "invalid attnum: %d", attnum);
|
|
result = 0; /* keep compiler quiet */
|
|
@@ -816,6 +825,7 @@ heap_copytuple(HeapTuple tuple)
|
|
newTuple->t_tableOid = tuple->t_tableOid;
|
|
newTuple->t_data = (HeapTupleHeader) ((char *) newTuple + HEAPTUPLESIZE);
|
|
memcpy((char *) newTuple->t_data, (char *) tuple->t_data, tuple->t_len);
|
|
+ HeapTupleSetSecurity(newTuple, HeapTupleGetSecurity(tuple));
|
|
return newTuple;
|
|
}
|
|
|
|
@@ -909,6 +919,10 @@ heap_form_tuple(TupleDesc tupleDescripto
|
|
if (tupleDescriptor->tdhasoid)
|
|
len += sizeof(Oid);
|
|
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+ len += sizeof(Oid);
|
|
+#endif
|
|
+
|
|
hoff = len = MAXALIGN(len); /* align user data safely */
|
|
|
|
data_len = heap_compute_data_size(tupleDescriptor, values, isnull);
|
|
@@ -940,6 +954,10 @@ heap_form_tuple(TupleDesc tupleDescripto
|
|
if (tupleDescriptor->tdhasoid) /* else leave infomask = 0 */
|
|
td->t_infomask = HEAP_HASOID;
|
|
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+ td->t_infomask |= HEAP_HASSECURITY;
|
|
+#endif
|
|
+
|
|
heap_fill_tuple(tupleDescriptor,
|
|
values,
|
|
isnull,
|
|
@@ -1020,6 +1038,10 @@ heap_formtuple(TupleDesc tupleDescriptor
|
|
if (tupleDescriptor->tdhasoid)
|
|
len += sizeof(Oid);
|
|
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+ len += sizeof(Oid);
|
|
+#endif
|
|
+
|
|
hoff = len = MAXALIGN(len); /* align user data safely */
|
|
|
|
data_len = ComputeDataSize(tupleDescriptor, values, nulls);
|
|
@@ -1051,6 +1073,10 @@ heap_formtuple(TupleDesc tupleDescriptor
|
|
if (tupleDescriptor->tdhasoid) /* else leave infomask = 0 */
|
|
td->t_infomask = HEAP_HASOID;
|
|
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+ td->t_infomask |= HEAP_HASSECURITY;
|
|
+#endif
|
|
+
|
|
DataFill(tupleDescriptor,
|
|
values,
|
|
nulls,
|
|
@@ -1129,6 +1155,7 @@ heap_modify_tuple(HeapTuple tuple,
|
|
newTuple->t_tableOid = tuple->t_tableOid;
|
|
if (tupleDesc->tdhasoid)
|
|
HeapTupleSetOid(newTuple, HeapTupleGetOid(tuple));
|
|
+ HeapTupleSetSecurity(newTuple, HeapTupleGetSecurity(tuple));
|
|
|
|
return newTuple;
|
|
}
|
|
@@ -1201,6 +1228,7 @@ heap_modifytuple(HeapTuple tuple,
|
|
newTuple->t_tableOid = tuple->t_tableOid;
|
|
if (tupleDesc->tdhasoid)
|
|
HeapTupleSetOid(newTuple, HeapTupleGetOid(tuple));
|
|
+ HeapTupleSetSecurity(newTuple, HeapTupleGetSecurity(tuple));
|
|
|
|
return newTuple;
|
|
}
|
|
@@ -1847,6 +1875,10 @@ heap_form_minimal_tuple(TupleDesc tupleD
|
|
if (tupleDescriptor->tdhasoid)
|
|
len += sizeof(Oid);
|
|
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+ len += sizeof(Oid);
|
|
+#endif
|
|
+
|
|
hoff = len = MAXALIGN(len); /* align user data safely */
|
|
|
|
data_len = heap_compute_data_size(tupleDescriptor, values, isnull);
|
|
@@ -1868,6 +1900,10 @@ heap_form_minimal_tuple(TupleDesc tupleD
|
|
if (tupleDescriptor->tdhasoid) /* else leave infomask = 0 */
|
|
tuple->t_infomask = HEAP_HASOID;
|
|
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+ tuple->t_infomask |= HEAP_HASSECURITY;
|
|
+#endif
|
|
+
|
|
heap_fill_tuple(tupleDescriptor,
|
|
values,
|
|
isnull,
|
|
@@ -1979,6 +2015,11 @@ heap_addheader(int natts, /* max domain
|
|
hoff = offsetof(HeapTupleHeaderData, t_bits);
|
|
if (withoid)
|
|
hoff += sizeof(Oid);
|
|
+
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+ hoff += sizeof(Oid);
|
|
+#endif
|
|
+
|
|
hoff = MAXALIGN(hoff);
|
|
len = hoff + structlen;
|
|
|
|
@@ -1997,6 +2038,10 @@ heap_addheader(int natts, /* max domain
|
|
if (withoid) /* else leave infomask = 0 */
|
|
td->t_infomask = HEAP_HASOID;
|
|
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+ td->t_infomask |= HEAP_HASSECURITY;
|
|
+#endif
|
|
+
|
|
memcpy((char *) td + hoff, structure, structlen);
|
|
|
|
return tuple;
|
|
diff -rpNU3 base/src/backend/access/heap/heapam.c pgace/src/backend/access/heap/heapam.c
|
|
--- base/src/backend/access/heap/heapam.c 2008-02-03 01:11:28.000000000 +0900
|
|
+++ pgace/src/backend/access/heap/heapam.c 2008-02-03 01:18:48.000000000 +0900
|
|
@@ -50,6 +50,7 @@
|
|
#include "catalog/namespace.h"
|
|
#include "miscadmin.h"
|
|
#include "pgstat.h"
|
|
+#include "security/pgace.h"
|
|
#include "storage/procarray.h"
|
|
#include "storage/smgr.h"
|
|
#include "utils/datum.h"
|
|
@@ -1934,6 +1935,9 @@ heap_insert(Relation relation, HeapTuple
|
|
Oid
|
|
simple_heap_insert(Relation relation, HeapTuple tup)
|
|
{
|
|
+ if (!pgaceHeapTupleInsert(relation, tup, true, false))
|
|
+ elog(ERROR, "simple_heap_insert on %s failed due to security reason",
|
|
+ RelationGetRelationName(relation));
|
|
return heap_insert(relation, tup, GetCurrentCommandId(true), true, true);
|
|
}
|
|
|
|
@@ -2215,6 +2219,9 @@ simple_heap_delete(Relation relation, It
|
|
ItemPointerData update_ctid;
|
|
TransactionId update_xmax;
|
|
|
|
+ if (!pgaceHeapTupleDelete(relation, tid, true, false))
|
|
+ elog(ERROR, "simple_heap_delete on %s failed due to security reason",
|
|
+ RelationGetRelationName(relation));
|
|
result = heap_delete(relation, tid,
|
|
&update_ctid, &update_xmax,
|
|
GetCurrentCommandId(true), InvalidSnapshot,
|
|
@@ -2858,6 +2865,9 @@ simple_heap_update(Relation relation, It
|
|
ItemPointerData update_ctid;
|
|
TransactionId update_xmax;
|
|
|
|
+ if (!pgaceHeapTupleUpdate(relation, otid, tup, true, false))
|
|
+ elog(ERROR, "simple_heap_update on %s failed due to security reason",
|
|
+ RelationGetRelationName(relation));
|
|
result = heap_update(relation, otid, tup,
|
|
&update_ctid, &update_xmax,
|
|
GetCurrentCommandId(true), InvalidSnapshot,
|
|
diff -rpNU3 base/src/backend/access/heap/tuptoaster.c pgace/src/backend/access/heap/tuptoaster.c
|
|
--- base/src/backend/access/heap/tuptoaster.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/access/heap/tuptoaster.c 2008-01-10 12:42:25.000000000 +0900
|
|
@@ -35,6 +35,7 @@
|
|
#include "access/tuptoaster.h"
|
|
#include "access/xact.h"
|
|
#include "catalog/catalog.h"
|
|
+#include "security/pgace.h"
|
|
#include "utils/fmgroids.h"
|
|
#include "utils/pg_lzcompress.h"
|
|
#include "utils/typcache.h"
|
|
@@ -588,6 +589,9 @@ toast_insert_or_update(Relation rel, Hea
|
|
hoff += BITMAPLEN(numAttrs);
|
|
if (newtup->t_data->t_infomask & HEAP_HASOID)
|
|
hoff += sizeof(Oid);
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+ hoff += sizeof(Oid);
|
|
+#endif
|
|
hoff = MAXALIGN(hoff);
|
|
Assert(hoff == newtup->t_data->t_hoff);
|
|
/* now convert to a limit on the tuple data size */
|
|
@@ -837,6 +841,9 @@ toast_insert_or_update(Relation rel, Hea
|
|
new_len += BITMAPLEN(numAttrs);
|
|
if (olddata->t_infomask & HEAP_HASOID)
|
|
new_len += sizeof(Oid);
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+ new_len += sizeof(Oid);
|
|
+#endif
|
|
new_len = MAXALIGN(new_len);
|
|
Assert(new_len == olddata->t_hoff);
|
|
new_data_len = heap_compute_data_size(tupleDesc,
|
|
@@ -988,6 +995,9 @@ toast_flatten_tuple_attribute(Datum valu
|
|
new_len += BITMAPLEN(numAttrs);
|
|
if (olddata->t_infomask & HEAP_HASOID)
|
|
new_len += sizeof(Oid);
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+ new_len += sizeof(Oid);
|
|
+#endif
|
|
new_len = MAXALIGN(new_len);
|
|
Assert(new_len == olddata->t_hoff);
|
|
new_data_len = heap_compute_data_size(tupleDesc,
|
|
@@ -1173,6 +1183,8 @@ toast_save_datum(Relation rel, Datum val
|
|
if (!HeapTupleIsValid(toasttup))
|
|
elog(ERROR, "failed to build TOAST tuple");
|
|
|
|
+ if (!pgaceHeapTupleInsert(toastrel, toasttup, true, false))
|
|
+ elog(ERROR, "failed to insert TOAST tuple due to security reason");
|
|
heap_insert(toastrel, toasttup, mycid, use_wal, use_fsm);
|
|
|
|
/*
|
|
diff -rpNU3 base/src/backend/bootstrap/bootparse.y pgace/src/backend/bootstrap/bootparse.y
|
|
--- base/src/backend/bootstrap/bootparse.y 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/bootstrap/bootparse.y 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -212,7 +212,8 @@ Boot_CreateStmt:
|
|
0,
|
|
ONCOMMIT_NOOP,
|
|
(Datum) 0,
|
|
- true);
|
|
+ true,
|
|
+ NIL);
|
|
elog(DEBUG4, "relation created with oid %u", id);
|
|
}
|
|
do_end();
|
|
diff -rpNU3 base/src/backend/catalog/Makefile pgace/src/backend/catalog/Makefile
|
|
--- base/src/backend/catalog/Makefile 2007-09-11 10:53:53.000000000 +0900
|
|
+++ pgace/src/backend/catalog/Makefile 2007-09-21 01:08:03.000000000 +0900
|
|
@@ -35,6 +35,7 @@ POSTGRES_BKI_SRCS = $(addprefix $(top_sr
|
|
pg_enum.h pg_namespace.h pg_conversion.h pg_depend.h \
|
|
pg_database.h pg_tablespace.h pg_pltemplate.h \
|
|
pg_authid.h pg_auth_members.h pg_shdepend.h pg_shdescription.h \
|
|
+ pg_security.h \
|
|
pg_ts_config.h pg_ts_config_map.h pg_ts_dict.h \
|
|
pg_ts_parser.h pg_ts_template.h \
|
|
toasting.h indexing.h \
|
|
diff -rpNU3 base/src/backend/catalog/catalog.c pgace/src/backend/catalog/catalog.c
|
|
--- base/src/backend/catalog/catalog.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/catalog/catalog.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -30,6 +30,7 @@
|
|
#include "catalog/pg_database.h"
|
|
#include "catalog/pg_namespace.h"
|
|
#include "catalog/pg_pltemplate.h"
|
|
+#include "catalog/pg_security.h"
|
|
#include "catalog/pg_shdepend.h"
|
|
#include "catalog/pg_shdescription.h"
|
|
#include "catalog/pg_tablespace.h"
|
|
@@ -257,6 +258,7 @@ IsSharedRelation(Oid relationId)
|
|
relationId == AuthMemRelationId ||
|
|
relationId == DatabaseRelationId ||
|
|
relationId == PLTemplateRelationId ||
|
|
+ relationId == SecurityRelationId ||
|
|
relationId == SharedDescriptionRelationId ||
|
|
relationId == SharedDependRelationId ||
|
|
relationId == TableSpaceRelationId)
|
|
@@ -269,6 +271,8 @@ IsSharedRelation(Oid relationId)
|
|
relationId == DatabaseNameIndexId ||
|
|
relationId == DatabaseOidIndexId ||
|
|
relationId == PLTemplateNameIndexId ||
|
|
+ relationId == SecurityOidIndexId ||
|
|
+ relationId == SecuritySeclabelIndexId ||
|
|
relationId == SharedDescriptionObjIndexId ||
|
|
relationId == SharedDependDependerIndexId ||
|
|
relationId == SharedDependReferenceIndexId ||
|
|
diff -rpNU3 base/src/backend/catalog/genbki.sh pgace/src/backend/catalog/genbki.sh
|
|
--- base/src/backend/catalog/genbki.sh 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/catalog/genbki.sh 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -130,6 +130,22 @@ for dir in $INCLUDE_DIRS; do
|
|
fi
|
|
done
|
|
|
|
+# Get SECURITY_SYSATTR_NAME from security/pgace.h
|
|
+for dir in $INCLUDE_DIRS; do
|
|
+ if [ -f "$dir/pg_config.h" ]; then
|
|
+ SECURITY_SYSATTR_NAME=`grep '#define[ ]*SECURITY_SYSATTR_NAME' $dir/pg_config.h | $AWK '{ print $3 }' | sed 's/\"//g'`
|
|
+ break
|
|
+ fi
|
|
+done
|
|
+
|
|
+function SECURITY_SYSATTR_NAME_filter() {
|
|
+ if [ -z "$SECURITY_SYSATTR_NAME" ]; then
|
|
+ grep -v SECURITY_SYSATTR_NAME;
|
|
+ else
|
|
+ cat
|
|
+ fi
|
|
+}
|
|
+
|
|
touch ${OUTPUT_PREFIX}.description.$$
|
|
touch ${OUTPUT_PREFIX}.shdescription.$$
|
|
|
|
@@ -143,7 +159,7 @@ touch ${OUTPUT_PREFIX}.shdescription.$$
|
|
# Substitute values of configuration constants
|
|
# ----------------
|
|
#
|
|
-cat $INFILES | \
|
|
+cat $INFILES | SECURITY_SYSATTR_NAME_filter | \
|
|
sed -e 's;/\*.*\*/;;g' \
|
|
-e 's;/\*;\
|
|
/*\
|
|
@@ -165,6 +181,7 @@ sed -e "s/;[ ]*$//g" \
|
|
-e "s/PGUID/$BOOTSTRAP_SUPERUSERID/g" \
|
|
-e "s/NAMEDATALEN/$NAMEDATALEN/g" \
|
|
-e "s/PGNSP/$PG_CATALOG_NAMESPACE/g" \
|
|
+ -e "s/SECURITY_SYSATTR_NAME/$SECURITY_SYSATTR_NAME/g" \
|
|
| $AWK '
|
|
# ----------------
|
|
# now use awk to process remaining .h file..
|
|
diff -rpNU3 base/src/backend/catalog/heap.c pgace/src/backend/catalog/heap.c
|
|
--- base/src/backend/catalog/heap.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/catalog/heap.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -53,6 +53,7 @@
|
|
#include "parser/parse_coerce.h"
|
|
#include "parser/parse_expr.h"
|
|
#include "parser/parse_relation.h"
|
|
+#include "security/pgace.h"
|
|
#include "storage/smgr.h"
|
|
#include "utils/builtins.h"
|
|
#include "utils/fmgroids.h"
|
|
@@ -67,7 +68,8 @@ static void AddNewRelationTuple(Relation
|
|
Oid new_rel_oid, Oid new_type_oid,
|
|
Oid relowner,
|
|
char relkind,
|
|
- Datum reloptions);
|
|
+ Datum reloptions,
|
|
+ List *pgace_attr_list);
|
|
static Oid AddNewRelationType(const char *typeName,
|
|
Oid typeNamespace,
|
|
Oid new_rel_oid,
|
|
@@ -144,7 +146,21 @@ static FormData_pg_attribute a7 = {
|
|
true, 'p', 'i', true, false, false, true, 0
|
|
};
|
|
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+/*
|
|
+ * SECURITY_SYSATTR_NAME is defined at PGACE header file.
|
|
+ * If SELinux is enabled, it is defined as "security_context"
|
|
+ */
|
|
+static FormData_pg_attribute a8 = {
|
|
+ 0, {SECURITY_SYSATTR_NAME}, SECLABELOID, 0, sizeof(Oid),
|
|
+ SecurityAttributeNumber, 0, -1, -1,
|
|
+ true, 'p', 'i', true, false, false, true, 0
|
|
+};
|
|
+
|
|
+static const Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8};
|
|
+#else
|
|
static const Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7};
|
|
+#endif
|
|
|
|
/*
|
|
* This function returns a Form_pg_attribute pointer for a system attribute.
|
|
@@ -467,7 +483,8 @@ AddNewAttributeTuples(Oid new_rel_oid,
|
|
TupleDesc tupdesc,
|
|
char relkind,
|
|
bool oidislocal,
|
|
- int oidinhcount)
|
|
+ int oidinhcount,
|
|
+ List *pgace_attr_list)
|
|
{
|
|
const Form_pg_attribute *dpp;
|
|
int i;
|
|
@@ -502,6 +519,7 @@ AddNewAttributeTuples(Oid new_rel_oid,
|
|
false,
|
|
ATTRIBUTE_TUPLE_SIZE,
|
|
(void *) *dpp);
|
|
+ pgaceCreateAttributeCommon(rel, tup, pgace_attr_list);
|
|
|
|
simple_heap_insert(rel, tup);
|
|
|
|
@@ -592,7 +610,8 @@ void
|
|
InsertPgClassTuple(Relation pg_class_desc,
|
|
Relation new_rel_desc,
|
|
Oid new_rel_oid,
|
|
- Datum reloptions)
|
|
+ Datum reloptions,
|
|
+ List *pgace_attr_list)
|
|
{
|
|
Form_pg_class rd_rel = new_rel_desc->rd_rel;
|
|
Datum values[Natts_pg_class];
|
|
@@ -642,6 +661,7 @@ InsertPgClassTuple(Relation pg_class_des
|
|
* be embarrassing to do this sort of thing in polite company.
|
|
*/
|
|
HeapTupleSetOid(tup, new_rel_oid);
|
|
+ pgaceCreateRelationCommon(pg_class_desc, tup, pgace_attr_list);
|
|
|
|
/* finally insert the new tuple, update the indexes, and clean up */
|
|
simple_heap_insert(pg_class_desc, tup);
|
|
@@ -665,7 +685,8 @@ AddNewRelationTuple(Relation pg_class_de
|
|
Oid new_type_oid,
|
|
Oid relowner,
|
|
char relkind,
|
|
- Datum reloptions)
|
|
+ Datum reloptions,
|
|
+ List *pgace_attr_list)
|
|
{
|
|
Form_pg_class new_rel_reltup;
|
|
|
|
@@ -725,7 +746,7 @@ AddNewRelationTuple(Relation pg_class_de
|
|
new_rel_desc->rd_att->tdtypeid = new_type_oid;
|
|
|
|
/* Now build and insert the tuple */
|
|
- InsertPgClassTuple(pg_class_desc, new_rel_desc, new_rel_oid, reloptions);
|
|
+ InsertPgClassTuple(pg_class_desc, new_rel_desc, new_rel_oid, reloptions, pgace_attr_list);
|
|
}
|
|
|
|
|
|
@@ -791,7 +812,8 @@ heap_create_with_catalog(const char *rel
|
|
int oidinhcount,
|
|
OnCommitAction oncommit,
|
|
Datum reloptions,
|
|
- bool allow_system_table_mods)
|
|
+ bool allow_system_table_mods,
|
|
+ List *pgace_attr_list)
|
|
{
|
|
Relation pg_class_desc;
|
|
Relation new_rel_desc;
|
|
@@ -963,13 +985,14 @@ heap_create_with_catalog(const char *rel
|
|
new_type_oid,
|
|
ownerid,
|
|
relkind,
|
|
- reloptions);
|
|
+ reloptions,
|
|
+ pgace_attr_list);
|
|
|
|
/*
|
|
* now add tuples to pg_attribute for the attributes in our new relation.
|
|
*/
|
|
AddNewAttributeTuples(relid, new_rel_desc->rd_att, relkind,
|
|
- oidislocal, oidinhcount);
|
|
+ oidislocal, oidinhcount, pgace_attr_list);
|
|
|
|
/*
|
|
* Make a dependency link to force the relation to be deleted if its
|
|
diff -rpNU3 base/src/backend/catalog/index.c pgace/src/backend/catalog/index.c
|
|
--- base/src/backend/catalog/index.c 2008-02-03 01:11:28.000000000 +0900
|
|
+++ pgace/src/backend/catalog/index.c 2008-02-03 01:18:48.000000000 +0900
|
|
@@ -624,7 +624,7 @@ index_create(Oid heapRelationId,
|
|
*/
|
|
InsertPgClassTuple(pg_class, indexRelation,
|
|
RelationGetRelid(indexRelation),
|
|
- reloptions);
|
|
+ reloptions, NIL);
|
|
|
|
/* done with pg_class */
|
|
heap_close(pg_class, RowExclusiveLock);
|
|
diff -rpNU3 base/src/backend/catalog/pg_aggregate.c pgace/src/backend/catalog/pg_aggregate.c
|
|
--- base/src/backend/catalog/pg_aggregate.c 2008-01-14 22:59:48.000000000 +0900
|
|
+++ pgace/src/backend/catalog/pg_aggregate.c 2008-01-14 23:08:31.000000000 +0900
|
|
@@ -213,8 +213,9 @@ AggregateCreate(const char *aggName,
|
|
PointerGetDatum(NULL), /* parameterModes */
|
|
PointerGetDatum(NULL), /* parameterNames */
|
|
PointerGetDatum(NULL), /* proconfig */
|
|
- 1, /* procost */
|
|
- 0); /* prorows */
|
|
+ 1, /* procost */
|
|
+ 0, /* prorows */
|
|
+ NULL); /* PGACE opaque */
|
|
|
|
/*
|
|
* Okay to create the pg_aggregate entry.
|
|
diff -rpNU3 base/src/backend/catalog/pg_largeobject.c pgace/src/backend/catalog/pg_largeobject.c
|
|
--- base/src/backend/catalog/pg_largeobject.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/catalog/pg_largeobject.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -18,6 +18,8 @@
|
|
#include "access/heapam.h"
|
|
#include "catalog/indexing.h"
|
|
#include "catalog/pg_largeobject.h"
|
|
+#include "catalog/pg_security.h"
|
|
+#include "security/pgace.h"
|
|
#include "utils/builtins.h"
|
|
#include "utils/fmgroids.h"
|
|
|
|
@@ -57,6 +59,8 @@ LargeObjectCreate(Oid loid)
|
|
|
|
ntup = heap_formtuple(pg_largeobject->rd_att, values, nulls);
|
|
|
|
+ pgaceLargeObjectCreate(pg_largeobject, ntup);
|
|
+
|
|
/*
|
|
* Insert it
|
|
*/
|
|
@@ -91,6 +95,8 @@ LargeObjectDrop(Oid loid)
|
|
|
|
while ((tuple = systable_getnext(sd)) != NULL)
|
|
{
|
|
+ if (!found)
|
|
+ pgaceLargeObjectDrop(pg_largeobject, tuple);
|
|
simple_heap_delete(pg_largeobject, &tuple->t_self);
|
|
found = true;
|
|
}
|
|
diff -rpNU3 base/src/backend/catalog/pg_proc.c pgace/src/backend/catalog/pg_proc.c
|
|
--- base/src/backend/catalog/pg_proc.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/catalog/pg_proc.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -27,6 +27,7 @@
|
|
#include "mb/pg_wchar.h"
|
|
#include "miscadmin.h"
|
|
#include "parser/parse_type.h"
|
|
+#include "security/pgace.h"
|
|
#include "tcop/pquery.h"
|
|
#include "tcop/tcopprot.h"
|
|
#include "utils/acl.h"
|
|
@@ -74,7 +75,8 @@ ProcedureCreate(const char *procedureNam
|
|
Datum parameterNames,
|
|
Datum proconfig,
|
|
float4 procost,
|
|
- float4 prorows)
|
|
+ float4 prorows,
|
|
+ void *pgaceItem)
|
|
{
|
|
Oid retval;
|
|
int parameterCount;
|
|
@@ -339,6 +341,7 @@ ProcedureCreate(const char *procedureNam
|
|
|
|
/* Okay, do it... */
|
|
tup = heap_modifytuple(oldtup, tupDesc, values, nulls, replaces);
|
|
+ pgaceGramCreateFunction(rel, tup, (DefElem *)pgaceItem);
|
|
simple_heap_update(rel, &tup->t_self, tup);
|
|
|
|
ReleaseSysCache(oldtup);
|
|
@@ -348,6 +351,7 @@ ProcedureCreate(const char *procedureNam
|
|
{
|
|
/* Creating a new procedure */
|
|
tup = heap_formtuple(tupDesc, values, nulls);
|
|
+ pgaceGramCreateFunction(rel, tup, (DefElem *)pgaceItem);
|
|
simple_heap_insert(rel, tup);
|
|
is_update = false;
|
|
}
|
|
diff -rpNU3 base/src/backend/catalog/toasting.c pgace/src/backend/catalog/toasting.c
|
|
--- base/src/backend/catalog/toasting.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/catalog/toasting.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -199,7 +199,8 @@ create_toast_table(Relation rel, Oid toa
|
|
0,
|
|
ONCOMMIT_NOOP,
|
|
(Datum) 0,
|
|
- true);
|
|
+ true,
|
|
+ NIL);
|
|
|
|
/* make the toast relation visible, else index creation will fail */
|
|
CommandCounterIncrement();
|
|
diff -rpNU3 base/src/backend/commands/async.c pgace/src/backend/commands/async.c
|
|
--- base/src/backend/commands/async.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/commands/async.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -85,6 +85,7 @@
|
|
#include "libpq/libpq.h"
|
|
#include "libpq/pqformat.h"
|
|
#include "miscadmin.h"
|
|
+#include "security/pgace.h"
|
|
#include "storage/ipc.h"
|
|
#include "storage/sinval.h"
|
|
#include "tcop/tcopprot.h"
|
|
@@ -544,7 +545,8 @@ AtCommit_Notify(void)
|
|
|
|
rTuple = heap_modifytuple(lTuple, tdesc,
|
|
value, nulls, repl);
|
|
-
|
|
+ if (!pgaceHeapTupleUpdate(lRel, &lTuple->t_self, rTuple, true, false))
|
|
+ elog(ERROR, "could not update a tuple due to security reason");
|
|
/*
|
|
* We cannot use simple_heap_update here because the tuple
|
|
* could have been modified by an uncommitted transaction;
|
|
diff -rpNU3 base/src/backend/commands/cluster.c pgace/src/backend/commands/cluster.c
|
|
--- base/src/backend/commands/cluster.c 2008-02-03 01:11:28.000000000 +0900
|
|
+++ pgace/src/backend/commands/cluster.c 2008-02-03 01:18:48.000000000 +0900
|
|
@@ -666,7 +666,8 @@ make_new_heap(Oid OIDOldHeap, const char
|
|
0,
|
|
ONCOMMIT_NOOP,
|
|
reloptions,
|
|
- allowSystemTableMods);
|
|
+ allowSystemTableMods,
|
|
+ NIL);
|
|
|
|
ReleaseSysCache(tuple);
|
|
|
|
diff -rpNU3 base/src/backend/commands/copy.c pgace/src/backend/commands/copy.c
|
|
--- base/src/backend/commands/copy.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/commands/copy.c 2008-02-01 11:24:01.000000000 +0900
|
|
@@ -22,6 +22,7 @@
|
|
|
|
#include "access/heapam.h"
|
|
#include "access/xact.h"
|
|
+#include "catalog/heap.h"
|
|
#include "catalog/namespace.h"
|
|
#include "catalog/pg_type.h"
|
|
#include "commands/copy.h"
|
|
@@ -34,6 +35,7 @@
|
|
#include "optimizer/planner.h"
|
|
#include "parser/parse_relation.h"
|
|
#include "rewrite/rewriteHandler.h"
|
|
+#include "security/pgace.h"
|
|
#include "storage/fd.h"
|
|
#include "tcop/tcopprot.h"
|
|
#include "utils/acl.h"
|
|
@@ -159,6 +161,11 @@ typedef struct CopyStateData
|
|
char *raw_buf;
|
|
int raw_buf_index; /* next byte to process */
|
|
int raw_buf_len; /* total # of bytes stored */
|
|
+
|
|
+ /* dumpable/restorable system column support */
|
|
+ FmgrInfo security_out_function;
|
|
+ bool security_force_quot;
|
|
+ bool security_force_notnull;
|
|
} CopyStateData;
|
|
|
|
typedef CopyStateData *CopyState;
|
|
@@ -242,7 +249,7 @@ static const char BinarySignature[11] =
|
|
/* non-export function prototypes */
|
|
static void DoCopyTo(CopyState cstate);
|
|
static void CopyTo(CopyState cstate);
|
|
-static void CopyOneRowTo(CopyState cstate, Oid tupleOid,
|
|
+static void CopyOneRowTo(CopyState cstate, Oid tupleOid, Oid securityOid,
|
|
Datum *values, bool *nulls);
|
|
static void CopyFrom(CopyState cstate);
|
|
static bool CopyReadLine(CopyState cstate);
|
|
@@ -1073,6 +1080,8 @@ DoCopy(const CopyStmt *stmt, const char
|
|
/* Generate or convert list of attributes to process */
|
|
cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
|
|
|
|
+ pgaceCopyTable(cstate->rel, cstate->attnumlist, is_from);
|
|
+
|
|
num_phys_attrs = tupDesc->natts;
|
|
|
|
/* Convert FORCE QUOTE name list to per-column flags, check validity */
|
|
@@ -1093,6 +1102,10 @@ DoCopy(const CopyStmt *stmt, const char
|
|
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
|
|
errmsg("FORCE QUOTE column \"%s\" not referenced by COPY",
|
|
NameStr(tupDesc->attrs[attnum - 1]->attname))));
|
|
+ if (pgaceIsSecuritySystemColumn(attnum)) {
|
|
+ cstate->security_force_quot = true;
|
|
+ continue;
|
|
+ }
|
|
cstate->force_quote_flags[attnum - 1] = true;
|
|
}
|
|
}
|
|
@@ -1115,6 +1128,9 @@ DoCopy(const CopyStmt *stmt, const char
|
|
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
|
|
errmsg("FORCE NOT NULL column \"%s\" not referenced by COPY",
|
|
NameStr(tupDesc->attrs[attnum - 1]->attname))));
|
|
+ if (pgaceIsSecuritySystemColumn(attnum))
|
|
+ continue; /* ignore, if specified */
|
|
+
|
|
cstate->force_notnull_flags[attnum - 1] = true;
|
|
}
|
|
}
|
|
@@ -1305,16 +1321,27 @@ CopyTo(CopyState cstate)
|
|
int attnum = lfirst_int(cur);
|
|
Oid out_func_oid;
|
|
bool isvarlena;
|
|
+ FmgrInfo *out_fmgr;
|
|
+ Form_pg_attribute pg_attribute;
|
|
+
|
|
+ if (pgaceIsSecuritySystemColumn(attnum)) {
|
|
+ /* PGACE: dumpable system column */
|
|
+ pg_attribute = SystemAttributeDefinition(attnum, false);
|
|
+ out_fmgr = &cstate->security_out_function;
|
|
+ } else {
|
|
+ pg_attribute = attr[attnum - 1];
|
|
+ out_fmgr = &cstate->out_functions[attnum - 1];
|
|
+ }
|
|
|
|
if (cstate->binary)
|
|
- getTypeBinaryOutputInfo(attr[attnum - 1]->atttypid,
|
|
+ getTypeBinaryOutputInfo(pg_attribute->atttypid,
|
|
&out_func_oid,
|
|
&isvarlena);
|
|
else
|
|
- getTypeOutputInfo(attr[attnum - 1]->atttypid,
|
|
+ getTypeOutputInfo(pg_attribute->atttypid,
|
|
&out_func_oid,
|
|
&isvarlena);
|
|
- fmgr_info(out_func_oid, &cstate->out_functions[attnum - 1]);
|
|
+ fmgr_info(out_func_oid, out_fmgr);
|
|
}
|
|
|
|
/*
|
|
@@ -1370,6 +1397,12 @@ CopyTo(CopyState cstate)
|
|
hdr_delim = true;
|
|
|
|
colname = NameStr(attr[attnum - 1]->attname);
|
|
+ if (pgaceIsSecuritySystemColumn(attnum)) {
|
|
+ Form_pg_attribute sysatt = SystemAttributeDefinition(attnum, false);
|
|
+ colname = NameStr(sysatt->attname);
|
|
+ } else {
|
|
+ colname = NameStr(attr[attnum - 1]->attname);
|
|
+ }
|
|
|
|
CopyAttributeOutCSV(cstate, colname, false,
|
|
list_length(cstate->attnumlist) == 1);
|
|
@@ -1395,11 +1428,14 @@ CopyTo(CopyState cstate)
|
|
{
|
|
CHECK_FOR_INTERRUPTS();
|
|
|
|
+ if (!pgaceCopyToTuple(cstate->rel, cstate->attnumlist, tuple))
|
|
+ continue;
|
|
+
|
|
/* Deconstruct the tuple ... faster than repeated heap_getattr */
|
|
heap_deform_tuple(tuple, tupDesc, values, nulls);
|
|
|
|
/* Format and send the data */
|
|
- CopyOneRowTo(cstate, HeapTupleGetOid(tuple), values, nulls);
|
|
+ CopyOneRowTo(cstate, HeapTupleGetOid(tuple), HeapTupleGetSecurity(tuple), values, nulls);
|
|
}
|
|
|
|
heap_endscan(scandesc);
|
|
@@ -1425,7 +1461,7 @@ CopyTo(CopyState cstate)
|
|
* Emit one row during CopyTo().
|
|
*/
|
|
static void
|
|
-CopyOneRowTo(CopyState cstate, Oid tupleOid, Datum *values, bool *nulls)
|
|
+CopyOneRowTo(CopyState cstate, Oid tupleOid, Oid tupleSecurity, Datum *values, bool *nulls)
|
|
{
|
|
bool need_delim = false;
|
|
FmgrInfo *out_functions = cstate->out_functions;
|
|
@@ -1464,8 +1500,10 @@ CopyOneRowTo(CopyState cstate, Oid tuple
|
|
foreach(cur, cstate->attnumlist)
|
|
{
|
|
int attnum = lfirst_int(cur);
|
|
- Datum value = values[attnum - 1];
|
|
- bool isnull = nulls[attnum - 1];
|
|
+ Datum value;
|
|
+ bool isnull;
|
|
+ bool force_quot;
|
|
+ FmgrInfo *out_fmgr;
|
|
|
|
if (!cstate->binary)
|
|
{
|
|
@@ -1474,6 +1512,19 @@ CopyOneRowTo(CopyState cstate, Oid tuple
|
|
need_delim = true;
|
|
}
|
|
|
|
+ /* PGACE: dumpable system column support */
|
|
+ if (pgaceIsSecuritySystemColumn(attnum)) {
|
|
+ value = tupleSecurity;
|
|
+ isnull = false;
|
|
+ force_quot = cstate->security_force_quot;
|
|
+ out_fmgr = &cstate->security_out_function;
|
|
+ } else {
|
|
+ value = values[attnum - 1];
|
|
+ isnull = nulls[attnum - 1];
|
|
+ force_quot = cstate->force_quote_flags[attnum - 1];
|
|
+ out_fmgr = &out_functions[attnum - 1];
|
|
+ }
|
|
+
|
|
if (isnull)
|
|
{
|
|
if (!cstate->binary)
|
|
@@ -1485,11 +1536,9 @@ CopyOneRowTo(CopyState cstate, Oid tuple
|
|
{
|
|
if (!cstate->binary)
|
|
{
|
|
- string = OutputFunctionCall(&out_functions[attnum - 1],
|
|
- value);
|
|
+ string = OutputFunctionCall(out_fmgr, value);
|
|
if (cstate->csv_mode)
|
|
- CopyAttributeOutCSV(cstate, string,
|
|
- cstate->force_quote_flags[attnum - 1],
|
|
+ CopyAttributeOutCSV(cstate, string, force_quot,
|
|
list_length(cstate->attnumlist) == 1);
|
|
else
|
|
CopyAttributeOutText(cstate, string);
|
|
@@ -1498,8 +1547,7 @@ CopyOneRowTo(CopyState cstate, Oid tuple
|
|
{
|
|
bytea *outputbytes;
|
|
|
|
- outputbytes = SendFunctionCall(&out_functions[attnum - 1],
|
|
- value);
|
|
+ outputbytes = SendFunctionCall(out_fmgr, value);
|
|
CopySendInt32(cstate, VARSIZE(outputbytes) - VARHDRSZ);
|
|
CopySendData(cstate, VARDATA(outputbytes),
|
|
VARSIZE(outputbytes) - VARHDRSZ);
|
|
@@ -1633,8 +1681,11 @@ CopyFrom(CopyState cstate)
|
|
num_defaults;
|
|
FmgrInfo *in_functions;
|
|
FmgrInfo oid_in_function;
|
|
+ FmgrInfo security_in_function;
|
|
+ bool security_in_function_prepared = false;
|
|
Oid *typioparams;
|
|
Oid oid_typioparam;
|
|
+ Oid security_typioparam;
|
|
int attnum;
|
|
int i;
|
|
Oid in_func_oid;
|
|
@@ -1904,6 +1955,7 @@ CopyFrom(CopyState cstate)
|
|
{
|
|
bool skip_tuple;
|
|
Oid loaded_oid = InvalidOid;
|
|
+ Oid loaded_security = InvalidOid;
|
|
|
|
CHECK_FOR_INTERRUPTS();
|
|
|
|
@@ -1978,6 +2030,35 @@ CopyFrom(CopyState cstate)
|
|
int attnum = lfirst_int(cur);
|
|
int m = attnum - 1;
|
|
|
|
+ if (pgaceIsSecuritySystemColumn(attnum)) {
|
|
+ Form_pg_attribute sysatt = SystemAttributeDefinition(attnum, false);
|
|
+ if (fieldno >= fldct)
|
|
+ ereport(ERROR,
|
|
+ (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
|
|
+ errmsg("missing data for column \"%s\"",
|
|
+ NameStr(sysatt->attname))));
|
|
+ string = field_strings[fieldno++];
|
|
+ cstate->cur_attname = NameStr(attr[m]->attname);
|
|
+ cstate->cur_attval = string;
|
|
+
|
|
+ if (!security_in_function_prepared) {
|
|
+ getTypeInputInfo(sysatt->atttypid, &in_func_oid,
|
|
+ &security_typioparam);
|
|
+ fmgr_info(in_func_oid, &security_in_function);
|
|
+ security_in_function_prepared = true;
|
|
+ }
|
|
+ if (string) {
|
|
+ Datum d = InputFunctionCall(&security_in_function,
|
|
+ string,
|
|
+ security_typioparam,
|
|
+ sysatt->atttypmod);
|
|
+ loaded_security = ObjectIdGetDatum(d);
|
|
+ }
|
|
+ cstate->cur_attname = NULL;
|
|
+ cstate->cur_attval = NULL;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
if (fieldno >= fldct)
|
|
ereport(ERROR,
|
|
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
|
|
@@ -2048,6 +2129,33 @@ CopyFrom(CopyState cstate)
|
|
int attnum = lfirst_int(cur);
|
|
int m = attnum - 1;
|
|
|
|
+ if (pgaceIsSecuritySystemColumn(attnum)) {
|
|
+ Form_pg_attribute sysatt = SystemAttributeDefinition(attnum, false);
|
|
+ Datum d;
|
|
+
|
|
+ cstate->cur_attname = NameStr(sysatt->attname);
|
|
+ i++;
|
|
+
|
|
+ if (!security_in_function_prepared) {
|
|
+ Oid security_in_func_oid;
|
|
+ getTypeBinaryInputInfo(sysatt->atttypid,
|
|
+ &security_in_func_oid,
|
|
+ &security_typioparam);
|
|
+ fmgr_info(security_in_func_oid, &security_in_function);
|
|
+ security_in_function_prepared = true;
|
|
+ }
|
|
+ d = CopyReadBinaryAttribute(cstate,
|
|
+ i,
|
|
+ &security_in_function,
|
|
+ security_typioparam,
|
|
+ sysatt->atttypmod,
|
|
+ &isnull);
|
|
+ if (!isnull)
|
|
+ loaded_security = ObjectIdGetDatum(d);
|
|
+ cstate->cur_attname = NULL;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
cstate->cur_attname = NameStr(attr[m]->attname);
|
|
i++;
|
|
values[m] = CopyReadBinaryAttribute(cstate,
|
|
@@ -2079,6 +2187,7 @@ CopyFrom(CopyState cstate)
|
|
|
|
if (cstate->oids && file_has_oids)
|
|
HeapTupleSetOid(tuple, loaded_oid);
|
|
+ HeapTupleSetSecurity(tuple, loaded_security);
|
|
|
|
/* Triggers and stuff need to be invoked in query context. */
|
|
MemoryContextSwitchTo(oldcontext);
|
|
@@ -2102,6 +2211,9 @@ CopyFrom(CopyState cstate)
|
|
}
|
|
}
|
|
|
|
+ if (!skip_tuple && !pgaceHeapTupleInsert(cstate->rel, tuple, false, false))
|
|
+ skip_tuple = true;
|
|
+
|
|
if (!skip_tuple)
|
|
{
|
|
/* Place tuple in tuple slot */
|
|
@@ -3364,6 +3476,17 @@ CopyGetAttnums(TupleDesc tupDesc, Relati
|
|
break;
|
|
}
|
|
}
|
|
+
|
|
+ /* PGACE: writable system column support */
|
|
+ if (attnum == InvalidAttrNumber)
|
|
+ {
|
|
+ Form_pg_attribute sysatt = SystemAttributeByName(name, true);
|
|
+ if (sysatt) {
|
|
+ if (pgaceIsSecuritySystemColumn(sysatt->attnum))
|
|
+ attnum = sysatt->attnum;
|
|
+ }
|
|
+ }
|
|
+
|
|
if (attnum == InvalidAttrNumber)
|
|
{
|
|
if (rel != NULL)
|
|
@@ -3413,7 +3536,7 @@ copy_dest_receive(TupleTableSlot *slot,
|
|
slot_getallattrs(slot);
|
|
|
|
/* And send the data */
|
|
- CopyOneRowTo(cstate, InvalidOid, slot->tts_values, slot->tts_isnull);
|
|
+ CopyOneRowTo(cstate, InvalidOid, InvalidOid, slot->tts_values, slot->tts_isnull);
|
|
}
|
|
|
|
/*
|
|
diff -rpNU3 base/src/backend/commands/dbcommands.c pgace/src/backend/commands/dbcommands.c
|
|
--- base/src/backend/commands/dbcommands.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/commands/dbcommands.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -40,6 +40,7 @@
|
|
#include "miscadmin.h"
|
|
#include "pgstat.h"
|
|
#include "postmaster/bgwriter.h"
|
|
+#include "security/pgace.h"
|
|
#include "storage/freespace.h"
|
|
#include "storage/procarray.h"
|
|
#include "storage/smgr.h"
|
|
@@ -92,6 +93,7 @@ createdb(const CreatedbStmt *stmt)
|
|
DefElem *dtemplate = NULL;
|
|
DefElem *dencoding = NULL;
|
|
DefElem *dconnlimit = NULL;
|
|
+ DefElem *dpgace_item = NULL;
|
|
char *dbname = stmt->dbname;
|
|
char *dbowner = NULL;
|
|
const char *dbtemplate = NULL;
|
|
@@ -151,6 +153,13 @@ createdb(const CreatedbStmt *stmt)
|
|
errmsg("LOCATION is not supported anymore"),
|
|
errhint("Consider using tablespaces instead.")));
|
|
}
|
|
+ else if (pgaceIsGramSecurityItem(defel)) {
|
|
+ if (dpgace_item)
|
|
+ ereport(ERROR,
|
|
+ (errcode(ERRCODE_SYNTAX_ERROR),
|
|
+ errmsg("conflicting or redundant options")));
|
|
+ dpgace_item = defel;
|
|
+ }
|
|
else
|
|
elog(ERROR, "option \"%s\" not recognized",
|
|
defel->defname);
|
|
@@ -424,6 +433,7 @@ createdb(const CreatedbStmt *stmt)
|
|
new_record, new_record_nulls);
|
|
|
|
HeapTupleSetOid(tuple, dboid);
|
|
+ pgaceGramCreateDatabase(pg_database_rel, tuple, dpgace_item);
|
|
|
|
simple_heap_insert(pg_database_rel, tuple);
|
|
|
|
@@ -832,6 +842,7 @@ AlterDatabase(AlterDatabaseStmt *stmt)
|
|
ListCell *option;
|
|
int connlimit = -1;
|
|
DefElem *dconnlimit = NULL;
|
|
+ DefElem *dpgace_item = NULL;
|
|
Datum new_record[Natts_pg_database];
|
|
char new_record_nulls[Natts_pg_database];
|
|
char new_record_repl[Natts_pg_database];
|
|
@@ -849,6 +860,13 @@ AlterDatabase(AlterDatabaseStmt *stmt)
|
|
errmsg("conflicting or redundant options")));
|
|
dconnlimit = defel;
|
|
}
|
|
+ else if (pgaceIsGramSecurityItem(defel)) {
|
|
+ if (dpgace_item)
|
|
+ ereport(ERROR,
|
|
+ (errcode(ERRCODE_SYNTAX_ERROR),
|
|
+ errmsg("conflicting or redundant options")));
|
|
+ dpgace_item = defel;
|
|
+ }
|
|
else
|
|
elog(ERROR, "option \"%s\" not recognized",
|
|
defel->defname);
|
|
@@ -894,6 +912,7 @@ AlterDatabase(AlterDatabaseStmt *stmt)
|
|
|
|
newtuple = heap_modifytuple(tuple, RelationGetDescr(rel), new_record,
|
|
new_record_nulls, new_record_repl);
|
|
+ pgaceGramAlterDatabase(rel, newtuple, dpgace_item);
|
|
simple_heap_update(rel, &tuple->t_self, newtuple);
|
|
|
|
/* Update indexes */
|
|
diff -rpNU3 base/src/backend/commands/functioncmds.c pgace/src/backend/commands/functioncmds.c
|
|
--- base/src/backend/commands/functioncmds.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/commands/functioncmds.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -47,6 +47,7 @@
|
|
#include "miscadmin.h"
|
|
#include "parser/parse_func.h"
|
|
#include "parser/parse_type.h"
|
|
+#include "security/pgace.h"
|
|
#include "utils/acl.h"
|
|
#include "utils/builtins.h"
|
|
#include "utils/fmgroids.h"
|
|
@@ -412,7 +413,8 @@ compute_attributes_sql_style(List *optio
|
|
bool *security_definer,
|
|
ArrayType **proconfig,
|
|
float4 *procost,
|
|
- float4 *prorows)
|
|
+ float4 *prorows,
|
|
+ DefElem **pgaceItem)
|
|
{
|
|
ListCell *option;
|
|
DefElem *as_item = NULL;
|
|
@@ -444,6 +446,14 @@ compute_attributes_sql_style(List *optio
|
|
errmsg("conflicting or redundant options")));
|
|
language_item = defel;
|
|
}
|
|
+ else if (pgaceIsGramSecurityItem(defel))
|
|
+ {
|
|
+ if (*pgaceItem)
|
|
+ ereport(ERROR,
|
|
+ (errcode(ERRCODE_SYNTAX_ERROR),
|
|
+ errmsg("conflicting or redundant options")));
|
|
+ *pgaceItem = defel;
|
|
+ }
|
|
else if (compute_common_attribute(defel,
|
|
&volatility_item,
|
|
&strict_item,
|
|
@@ -624,6 +634,7 @@ CreateFunction(CreateFunctionStmt *stmt)
|
|
HeapTuple languageTuple;
|
|
Form_pg_language languageStruct;
|
|
List *as_clause;
|
|
+ DefElem *pgaceItem = NULL;
|
|
|
|
/* Convert list of names to a name and namespace */
|
|
namespaceId = QualifiedNameGetCreationNamespace(stmt->funcname,
|
|
@@ -647,7 +658,7 @@ CreateFunction(CreateFunctionStmt *stmt)
|
|
compute_attributes_sql_style(stmt->options,
|
|
&as_clause, &language,
|
|
&volatility, &isStrict, &security,
|
|
- &proconfig, &procost, &prorows);
|
|
+ &proconfig, &procost, &prorows, &pgaceItem);
|
|
|
|
/* Convert language name to canonical case */
|
|
languageName = case_translate_language_name(language);
|
|
@@ -801,7 +812,8 @@ CreateFunction(CreateFunctionStmt *stmt)
|
|
PointerGetDatum(parameterNames),
|
|
PointerGetDatum(proconfig),
|
|
procost,
|
|
- prorows);
|
|
+ prorows,
|
|
+ pgaceItem);
|
|
}
|
|
|
|
|
|
@@ -1151,6 +1163,7 @@ AlterFunction(AlterFunctionStmt *stmt)
|
|
List *set_items = NIL;
|
|
DefElem *cost_item = NULL;
|
|
DefElem *rows_item = NULL;
|
|
+ DefElem *pgaceItem = NULL;
|
|
|
|
rel = heap_open(ProcedureRelationId, RowExclusiveLock);
|
|
|
|
@@ -1182,6 +1195,15 @@ AlterFunction(AlterFunctionStmt *stmt)
|
|
{
|
|
DefElem *defel = (DefElem *) lfirst(l);
|
|
|
|
+ if (pgaceIsGramSecurityItem(defel)) {
|
|
+ if (pgaceItem)
|
|
+ ereport(ERROR,
|
|
+ (errcode(ERRCODE_SYNTAX_ERROR),
|
|
+ errmsg("conflicting or redundant options")));
|
|
+ pgaceItem = defel;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
if (compute_common_attribute(defel,
|
|
&volatility_item,
|
|
&strict_item,
|
|
@@ -1252,6 +1274,7 @@ AlterFunction(AlterFunctionStmt *stmt)
|
|
tup = heap_modifytuple(tup, RelationGetDescr(rel),
|
|
repl_val, repl_null, repl_repl);
|
|
}
|
|
+ pgaceGramAlterFunction(rel, tup, pgaceItem);
|
|
|
|
/* Do the update */
|
|
simple_heap_update(rel, &tup->t_self, tup);
|
|
diff -rpNU3 base/src/backend/commands/lockcmds.c pgace/src/backend/commands/lockcmds.c
|
|
--- base/src/backend/commands/lockcmds.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/commands/lockcmds.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -18,6 +18,7 @@
|
|
#include "catalog/namespace.h"
|
|
#include "commands/lockcmds.h"
|
|
#include "miscadmin.h"
|
|
+#include "security/pgace.h"
|
|
#include "utils/acl.h"
|
|
#include "utils/lsyscache.h"
|
|
|
|
@@ -59,6 +60,8 @@ LockTableCommand(LockStmt *lockstmt)
|
|
aclcheck_error(aclresult, ACL_KIND_CLASS,
|
|
get_rel_name(reloid));
|
|
|
|
+ pgaceLockTable(reloid);
|
|
+
|
|
if (lockstmt->nowait)
|
|
rel = relation_open_nowait(reloid, lockstmt->mode);
|
|
else
|
|
diff -rpNU3 base/src/backend/commands/proclang.c pgace/src/backend/commands/proclang.c
|
|
--- base/src/backend/commands/proclang.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/commands/proclang.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -144,7 +144,8 @@ CreateProceduralLanguage(CreatePLangStmt
|
|
PointerGetDatum(NULL),
|
|
PointerGetDatum(NULL),
|
|
1,
|
|
- 0);
|
|
+ 0,
|
|
+ NULL);
|
|
}
|
|
|
|
/*
|
|
@@ -177,7 +178,8 @@ CreateProceduralLanguage(CreatePLangStmt
|
|
PointerGetDatum(NULL),
|
|
PointerGetDatum(NULL),
|
|
1,
|
|
- 0);
|
|
+ 0,
|
|
+ NULL);
|
|
}
|
|
}
|
|
else
|
|
diff -rpNU3 base/src/backend/commands/tablecmds.c pgace/src/backend/commands/tablecmds.c
|
|
--- base/src/backend/commands/tablecmds.c 2008-02-03 01:11:28.000000000 +0900
|
|
+++ pgace/src/backend/commands/tablecmds.c 2008-02-03 01:18:48.000000000 +0900
|
|
@@ -57,6 +57,7 @@
|
|
#include "parser/parser.h"
|
|
#include "rewrite/rewriteDefine.h"
|
|
#include "rewrite/rewriteHandler.h"
|
|
+#include "security/pgace.h"
|
|
#include "storage/smgr.h"
|
|
#include "utils/acl.h"
|
|
#include "utils/builtins.h"
|
|
@@ -434,7 +435,8 @@ DefineRelation(CreateStmt *stmt, char re
|
|
parentOidCount,
|
|
stmt->oncommit,
|
|
reloptions,
|
|
- allowSystemTableMods);
|
|
+ allowSystemTableMods,
|
|
+ pgaceRelationAttrList(stmt));
|
|
|
|
StoreCatalogInheritance(relationId, inheritOids);
|
|
|
|
@@ -2031,6 +2033,7 @@ ATPrepCmd(List **wqueue, Relation rel, A
|
|
case AT_DisableRule:
|
|
case AT_AddInherit: /* INHERIT / NO INHERIT */
|
|
case AT_DropInherit:
|
|
+ case AT_SetSecurityLabel:
|
|
ATSimplePermissions(rel, false);
|
|
/* These commands never recurse */
|
|
/* No command-specific prep needed */
|
|
@@ -2253,6 +2256,9 @@ ATExecCmd(AlteredTableInfo *tab, Relatio
|
|
case AT_DropInherit:
|
|
ATExecDropInherit(rel, (RangeVar *) cmd->def);
|
|
break;
|
|
+ case AT_SetSecurityLabel:
|
|
+ pgaceAlterRelationCommon(rel, cmd);
|
|
+ break;
|
|
default: /* oops */
|
|
elog(ERROR, "unrecognized alter table type: %d",
|
|
(int) cmd->subtype);
|
|
diff -rpNU3 base/src/backend/commands/trigger.c pgace/src/backend/commands/trigger.c
|
|
--- base/src/backend/commands/trigger.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/commands/trigger.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -31,6 +31,7 @@
|
|
#include "miscadmin.h"
|
|
#include "nodes/makefuncs.h"
|
|
#include "parser/parse_func.h"
|
|
+#include "security/pgace.h"
|
|
#include "tcop/utility.h"
|
|
#include "utils/acl.h"
|
|
#include "utils/builtins.h"
|
|
@@ -1574,6 +1575,12 @@ ExecCallTriggerFunc(TriggerData *trigdat
|
|
*/
|
|
InitFunctionCallInfoData(fcinfo, finfo, 0, (Node *) trigdata, NULL);
|
|
|
|
+ /* PGACE: permission check for trigegr function */
|
|
+ if (!pgaceCallFunctionTrigger(finfo, trigdata)) {
|
|
+ MemoryContextSwitchTo(oldContext);
|
|
+ return (HeapTuple) DatumGetPointer(NULL);
|
|
+ }
|
|
+
|
|
result = FunctionCallInvoke(&fcinfo);
|
|
|
|
MemoryContextSwitchTo(oldContext);
|
|
diff -rpNU3 base/src/backend/executor/execMain.c pgace/src/backend/executor/execMain.c
|
|
--- base/src/backend/executor/execMain.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/executor/execMain.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -48,6 +48,7 @@
|
|
#include "optimizer/clauses.h"
|
|
#include "parser/parse_clause.h"
|
|
#include "parser/parsetree.h"
|
|
+#include "security/pgace.h"
|
|
#include "storage/smgr.h"
|
|
#include "utils/acl.h"
|
|
#include "utils/lsyscache.h"
|
|
@@ -136,6 +137,8 @@ ExecutorStart(QueryDesc *queryDesc, int
|
|
Assert(queryDesc != NULL);
|
|
Assert(queryDesc->estate == NULL);
|
|
|
|
+ pgaceExecutorStart(queryDesc, eflags);
|
|
+
|
|
/*
|
|
* If the transaction is read-only, we need to check if any writes are
|
|
* planned to non-temporary tables. EXPLAIN is considered read-only.
|
|
@@ -1216,6 +1219,8 @@ ExecutePlan(EState *estate,
|
|
|
|
for (;;)
|
|
{
|
|
+ Oid __tts_security = InvalidOid; /* PGACE: explicit security labaling */
|
|
+
|
|
/* Reset the per-output-tuple exprcontext */
|
|
ResetPerTupleExprContext(estate);
|
|
|
|
@@ -1357,6 +1362,13 @@ lnext: ;
|
|
}
|
|
|
|
/*
|
|
+ * PGACE: security attribute system columnt support.
|
|
+ * If client specified a explicit security label,
|
|
+ * pgaceFetchSecurityLabel() fetch it via junk attribute.
|
|
+ */
|
|
+ pgaceFetchSecurityAttribute(junkfilter, slot, &__tts_security);
|
|
+
|
|
+ /*
|
|
* Create a new "clean" tuple with all junk attributes removed. We
|
|
* don't need to do this for DELETE, however (there will in fact
|
|
* be no non-junk attributes in a DELETE!)
|
|
@@ -1364,6 +1376,7 @@ lnext: ;
|
|
if (operation != CMD_DELETE)
|
|
slot = ExecFilterJunk(junkfilter, slot);
|
|
}
|
|
+ slot->tts_security = __tts_security;
|
|
|
|
/*
|
|
* now that we have a tuple, do the appropriate thing with it.. either
|
|
@@ -1484,6 +1497,9 @@ ExecInsert(TupleTableSlot *slot,
|
|
resultRelInfo = estate->es_result_relation_info;
|
|
resultRelationDesc = resultRelInfo->ri_RelationDesc;
|
|
|
|
+ /* PGACE: put an explicit security labeling */
|
|
+ HeapTupleStoreSecurityFromSlot(tuple, slot);
|
|
+
|
|
/* BEFORE ROW INSERT Triggers */
|
|
if (resultRelInfo->ri_TrigDesc &&
|
|
resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_INSERT] > 0)
|
|
@@ -1520,6 +1536,13 @@ ExecInsert(TupleTableSlot *slot,
|
|
ExecConstraints(resultRelInfo, slot, estate);
|
|
|
|
/*
|
|
+ * PGACE: check HeapTuple Insertion permission
|
|
+ */
|
|
+ if (!pgaceHeapTupleInsert(resultRelationDesc, tuple,
|
|
+ false, !!resultRelInfo->ri_projectReturning))
|
|
+ return;
|
|
+
|
|
+ /*
|
|
* insert the tuple
|
|
*
|
|
* Note: heap_insert returns the tid (location) of the new tuple in the
|
|
@@ -1586,6 +1609,10 @@ ExecDelete(ItemPointer tupleid,
|
|
return;
|
|
}
|
|
|
|
+ if (!pgaceHeapTupleDelete(resultRelationDesc, tupleid,
|
|
+ false, !!resultRelInfo->ri_projectReturning))
|
|
+ return;
|
|
+
|
|
/*
|
|
* delete the tuple
|
|
*
|
|
@@ -1722,6 +1749,9 @@ ExecUpdate(TupleTableSlot *slot,
|
|
resultRelInfo = estate->es_result_relation_info;
|
|
resultRelationDesc = resultRelInfo->ri_RelationDesc;
|
|
|
|
+ /* PGACE: put an explicit security attribute */
|
|
+ HeapTupleStoreSecurityFromSlot(tuple, slot);
|
|
+
|
|
/* BEFORE ROW UPDATE Triggers */
|
|
if (resultRelInfo->ri_TrigDesc &&
|
|
resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_UPDATE] > 0)
|
|
@@ -1765,6 +1795,11 @@ lreplace:;
|
|
if (resultRelationDesc->rd_att->constr)
|
|
ExecConstraints(resultRelInfo, slot, estate);
|
|
|
|
+ /* PGACE: check HeapTuple update permission */
|
|
+ if (!pgaceHeapTupleUpdate(resultRelationDesc, tupleid, tuple,
|
|
+ false, !!resultRelInfo->ri_projectReturning))
|
|
+ return;
|
|
+
|
|
/*
|
|
* replace the heap tuple
|
|
*
|
|
@@ -2629,7 +2664,8 @@ OpenIntoRel(QueryDesc *queryDesc)
|
|
0,
|
|
into->onCommit,
|
|
reloptions,
|
|
- allowSystemTableMods);
|
|
+ allowSystemTableMods,
|
|
+ NIL);
|
|
|
|
FreeTupleDesc(tupdesc);
|
|
|
|
@@ -2735,6 +2771,13 @@ intorel_receive(TupleTableSlot *slot, De
|
|
|
|
tuple = ExecCopySlotTuple(slot);
|
|
|
|
+ /* PGACE: store explicit security labeling and check HeapTuple insertion permission */
|
|
+ HeapTupleStoreSecurityFromSlot(tuple, slot);
|
|
+ if (!pgaceHeapTupleInsert(estate->es_into_relation_descriptor, tuple, false, false)) {
|
|
+ heap_freetuple(tuple);
|
|
+ return;
|
|
+ }
|
|
+
|
|
heap_insert(estate->es_into_relation_descriptor,
|
|
tuple,
|
|
estate->es_output_cid,
|
|
diff -rpNU3 base/src/backend/executor/execQual.c pgace/src/backend/executor/execQual.c
|
|
--- base/src/backend/executor/execQual.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/executor/execQual.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -47,6 +47,7 @@
|
|
#include "nodes/makefuncs.h"
|
|
#include "optimizer/planmain.h"
|
|
#include "parser/parse_expr.h"
|
|
+#include "security/pgace.h"
|
|
#include "utils/acl.h"
|
|
#include "utils/builtins.h"
|
|
#include "utils/lsyscache.h"
|
|
@@ -1750,6 +1751,8 @@ ExecEvalFunc(FuncExprState *fcache,
|
|
/* Go directly to ExecMakeFunctionResult on subsequent uses */
|
|
fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
|
|
|
|
+ pgaceCallFunction(&fcache->func);
|
|
+
|
|
return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
|
|
}
|
|
|
|
diff -rpNU3 base/src/backend/libpq/be-fsstubs.c pgace/src/backend/libpq/be-fsstubs.c
|
|
--- base/src/backend/libpq/be-fsstubs.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/libpq/be-fsstubs.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -45,6 +45,7 @@
|
|
#include "libpq/be-fsstubs.h"
|
|
#include "libpq/libpq-fs.h"
|
|
#include "miscadmin.h"
|
|
+#include "security/pgace.h"
|
|
#include "storage/fd.h"
|
|
#include "storage/large_object.h"
|
|
#include "utils/memutils.h"
|
|
@@ -353,6 +354,8 @@ lo_import(PG_FUNCTION_ARGS)
|
|
errmsg("could not open server file \"%s\": %m",
|
|
fnamebuf)));
|
|
|
|
+ pgaceLargeObjectImport(fd);
|
|
+
|
|
/*
|
|
* create an inversion object
|
|
*/
|
|
@@ -434,6 +437,8 @@ lo_export(PG_FUNCTION_ARGS)
|
|
errmsg("could not create server file \"%s\": %m",
|
|
fnamebuf)));
|
|
|
|
+ pgaceLargeObjectExport(fd, lobjId);
|
|
+
|
|
/*
|
|
* read in from the inversion file and write to the filesystem
|
|
*/
|
|
diff -rpNU3 base/src/backend/nodes/copyfuncs.c pgace/src/backend/nodes/copyfuncs.c
|
|
--- base/src/backend/nodes/copyfuncs.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/nodes/copyfuncs.c 2008-03-02 12:21:10.000000000 +0900
|
|
@@ -24,6 +24,7 @@
|
|
|
|
#include "nodes/plannodes.h"
|
|
#include "nodes/relation.h"
|
|
+#include "security/pgace.h"
|
|
#include "utils/datum.h"
|
|
|
|
|
|
@@ -85,6 +86,7 @@ _copyPlannedStmt(PlannedStmt *from)
|
|
COPY_NODE_FIELD(rowMarks);
|
|
COPY_NODE_FIELD(relationOids);
|
|
COPY_SCALAR_FIELD(nParamExec);
|
|
+ COPY_NODE_FIELD(pgaceItem);
|
|
|
|
return newnode;
|
|
}
|
|
@@ -1789,6 +1791,7 @@ _copyColumnDef(ColumnDef *from)
|
|
COPY_NODE_FIELD(raw_default);
|
|
COPY_STRING_FIELD(cooked_default);
|
|
COPY_NODE_FIELD(constraints);
|
|
+ COPY_NODE_FIELD(pgaceItem);
|
|
|
|
return newnode;
|
|
}
|
|
@@ -1869,6 +1872,7 @@ _copyQuery(Query *from)
|
|
COPY_NODE_FIELD(limitCount);
|
|
COPY_NODE_FIELD(rowMarks);
|
|
COPY_NODE_FIELD(setOperations);
|
|
+ COPY_NODE_FIELD(pgaceItem);
|
|
|
|
return newnode;
|
|
}
|
|
@@ -2105,6 +2109,7 @@ _copyCreateStmt(CreateStmt *from)
|
|
COPY_NODE_FIELD(options);
|
|
COPY_SCALAR_FIELD(oncommit);
|
|
COPY_STRING_FIELD(tablespacename);
|
|
+ COPY_NODE_FIELD(pgaceItem);
|
|
|
|
return newnode;
|
|
}
|
|
@@ -3570,6 +3575,10 @@ copyObject(void *from)
|
|
break;
|
|
|
|
default:
|
|
+ retval = pgaceCopyObject(from);
|
|
+ if (retval)
|
|
+ break;
|
|
+
|
|
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(from));
|
|
retval = from; /* keep compiler quiet */
|
|
break;
|
|
diff -rpNU3 base/src/backend/nodes/outfuncs.c pgace/src/backend/nodes/outfuncs.c
|
|
--- base/src/backend/nodes/outfuncs.c 2008-01-14 22:59:48.000000000 +0900
|
|
+++ pgace/src/backend/nodes/outfuncs.c 2008-01-14 23:08:31.000000000 +0900
|
|
@@ -26,6 +26,7 @@
|
|
#include "lib/stringinfo.h"
|
|
#include "nodes/plannodes.h"
|
|
#include "nodes/relation.h"
|
|
+#include "security/pgace.h"
|
|
#include "utils/datum.h"
|
|
|
|
|
|
@@ -252,6 +253,7 @@ _outPlannedStmt(StringInfo str, PlannedS
|
|
WRITE_NODE_FIELD(rowMarks);
|
|
WRITE_NODE_FIELD(relationOids);
|
|
WRITE_INT_FIELD(nParamExec);
|
|
+ WRITE_NODE_FIELD(pgaceItem);
|
|
}
|
|
|
|
/*
|
|
@@ -1748,6 +1750,7 @@ _outQuery(StringInfo str, Query *node)
|
|
WRITE_NODE_FIELD(limitCount);
|
|
WRITE_NODE_FIELD(rowMarks);
|
|
WRITE_NODE_FIELD(setOperations);
|
|
+ WRITE_NODE_FIELD(pgaceItem);
|
|
}
|
|
|
|
static void
|
|
@@ -2440,6 +2443,8 @@ _outNode(StringInfo str, void *obj)
|
|
break;
|
|
|
|
default:
|
|
+ if (pgaceOutObject(str, obj))
|
|
+ break;
|
|
|
|
/*
|
|
* This should be an ERROR, but it's too useful to be able to
|
|
diff -rpNU3 base/src/backend/nodes/readfuncs.c pgace/src/backend/nodes/readfuncs.c
|
|
--- base/src/backend/nodes/readfuncs.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/nodes/readfuncs.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -154,6 +154,7 @@ _readQuery(void)
|
|
READ_NODE_FIELD(limitCount);
|
|
READ_NODE_FIELD(rowMarks);
|
|
READ_NODE_FIELD(setOperations);
|
|
+ READ_NODE_FIELD(pgaceItem);
|
|
|
|
READ_DONE();
|
|
}
|
|
@@ -1126,8 +1127,9 @@ parseNodeString(void)
|
|
return_value = _readDeclareCursorStmt();
|
|
else
|
|
{
|
|
- elog(ERROR, "badly formatted node string \"%.32s\"...", token);
|
|
- return_value = NULL; /* keep compiler quiet */
|
|
+ return_value = pgaceReadObject(token);
|
|
+ if (!return_value)
|
|
+ elog(ERROR, "badly formatted node string \"%.32s\"...", token);
|
|
}
|
|
|
|
return (Node *) return_value;
|
|
diff -rpNU3 base/src/backend/optimizer/plan/planner.c pgace/src/backend/optimizer/plan/planner.c
|
|
--- base/src/backend/optimizer/plan/planner.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/optimizer/plan/planner.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -101,6 +101,10 @@ planner(Query *parse, int cursorOptions,
|
|
result = (*planner_hook) (parse, cursorOptions, boundParams);
|
|
else
|
|
result = standard_planner(parse, cursorOptions, boundParams);
|
|
+
|
|
+ /* PGACE: pgaceItem is passed to PlannedStmt */
|
|
+ result->pgaceItem = parse->pgaceItem;
|
|
+
|
|
return result;
|
|
}
|
|
|
|
diff -rpNU3 base/src/backend/parser/analyze.c pgace/src/backend/parser/analyze.c
|
|
--- base/src/backend/parser/analyze.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/parser/analyze.c 2008-01-11 16:13:01.000000000 +0900
|
|
@@ -36,6 +36,7 @@
|
|
#include "parser/parse_relation.h"
|
|
#include "parser/parse_target.h"
|
|
#include "parser/parsetree.h"
|
|
+#include "security/pgace.h"
|
|
|
|
|
|
typedef struct
|
|
@@ -404,6 +405,9 @@ transformInsertStmt(ParseState *pstate,
|
|
Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable));
|
|
pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
|
|
|
|
+ /* security attribute system column support */
|
|
+ pgaceTransformInsertStmt(&icolumns, &attrnos, selectQuery->targetList);
|
|
+
|
|
/*----------
|
|
* Generate an expression list for the INSERT that selects all the
|
|
* non-resjunk columns from the subquery. (INSERT's tlist must be
|
|
@@ -563,14 +567,15 @@ transformInsertStmt(ParseState *pstate,
|
|
Expr *expr = (Expr *) lfirst(lc);
|
|
ResTarget *col;
|
|
TargetEntry *tle;
|
|
+ AttrNumber anum = (AttrNumber) lfirst_int(attnos);
|
|
|
|
col = (ResTarget *) lfirst(icols);
|
|
Assert(IsA(col, ResTarget));
|
|
|
|
tle = makeTargetEntry(expr,
|
|
- (AttrNumber) lfirst_int(attnos),
|
|
+ anum,
|
|
col->name,
|
|
- false);
|
|
+ anum < 0 ? true : false);
|
|
qry->targetList = lappend(qry->targetList, tle);
|
|
|
|
icols = lnext(icols);
|
|
@@ -733,6 +738,7 @@ transformSelectStmt(ParseState *pstate,
|
|
/* handle any SELECT INTO/CREATE TABLE AS spec */
|
|
if (stmt->intoClause)
|
|
{
|
|
+ pgaceTransformSelectStmt(qry->targetList);
|
|
qry->intoClause = stmt->intoClause;
|
|
if (stmt->intoClause->colNames)
|
|
applyColumnNames(qry->targetList, stmt->intoClause->colNames);
|
|
diff -rpNU3 base/src/backend/parser/gram.y pgace/src/backend/parser/gram.y
|
|
--- base/src/backend/parser/gram.y 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/parser/gram.y 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -56,6 +56,7 @@
|
|
#include "commands/defrem.h"
|
|
#include "nodes/makefuncs.h"
|
|
#include "parser/gramparse.h"
|
|
+#include "security/pgace.h"
|
|
#include "storage/lmgr.h"
|
|
#include "utils/date.h"
|
|
#include "utils/datetime.h"
|
|
@@ -351,6 +352,8 @@ static Node *makeXmlExpr(XmlExprOp op, c
|
|
%type <str> OptTableSpace OptConsTableSpace OptTableSpaceOwner
|
|
%type <list> opt_check_option
|
|
|
|
+%type <defelt> OptSecurityItem SecurityItem
|
|
+
|
|
%type <target> xml_attribute_el
|
|
%type <list> xml_attribute_list xml_attributes
|
|
%type <node> xml_root_version opt_xml_root_standalone
|
|
@@ -1637,6 +1640,24 @@ alter_table_cmd:
|
|
n->def = (Node *) $3;
|
|
$$ = (Node *)n;
|
|
}
|
|
+ /* ALTER TABLE <relation> CONTEXT = '...' */
|
|
+ | SecurityItem
|
|
+ {
|
|
+ AlterTableCmd *n = makeNode(AlterTableCmd);
|
|
+ n->subtype = AT_SetSecurityLabel;
|
|
+ n->name = NULL;
|
|
+ n->def = (Node *) $1;
|
|
+ $$ = (Node *) n;
|
|
+ }
|
|
+ /* ALTER TABLE <relation> ALTER [COLUMN] <colname> CONTEXT = '...' */
|
|
+ | ALTER opt_column ColId SecurityItem
|
|
+ {
|
|
+ AlterTableCmd *n = makeNode(AlterTableCmd);
|
|
+ n->subtype = AT_SetSecurityLabel;
|
|
+ n->name = $3;
|
|
+ n->def = (Node *) $4;
|
|
+ $$ = (Node *) n;
|
|
+ }
|
|
| alter_rel_cmd
|
|
{
|
|
$$ = $1;
|
|
@@ -1883,7 +1904,7 @@ opt_using:
|
|
*****************************************************************************/
|
|
|
|
CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
|
|
- OptInherit OptWith OnCommitOption OptTableSpace
|
|
+ OptInherit OptWith OnCommitOption OptTableSpace OptSecurityItem
|
|
{
|
|
CreateStmt *n = makeNode(CreateStmt);
|
|
$4->istemp = $2;
|
|
@@ -1894,10 +1915,11 @@ CreateStmt: CREATE OptTemp TABLE qualifi
|
|
n->options = $9;
|
|
n->oncommit = $10;
|
|
n->tablespacename = $11;
|
|
+ n->pgaceItem = (Node *) $12;
|
|
$$ = (Node *)n;
|
|
}
|
|
| CREATE OptTemp TABLE qualified_name OF qualified_name
|
|
- '(' OptTableElementList ')' OptWith OnCommitOption OptTableSpace
|
|
+ '(' OptTableElementList ')' OptWith OnCommitOption OptTableSpace OptSecurityItem
|
|
{
|
|
/* SQL99 CREATE TABLE OF <UDT> (cols) seems to be satisfied
|
|
* by our inheritance capabilities. Let's try it...
|
|
@@ -1911,6 +1933,7 @@ CreateStmt: CREATE OptTemp TABLE qualifi
|
|
n->options = $10;
|
|
n->oncommit = $11;
|
|
n->tablespacename = $12;
|
|
+ n->pgaceItem = (Node *) $13;
|
|
$$ = (Node *)n;
|
|
}
|
|
;
|
|
@@ -1953,13 +1976,14 @@ TableElement:
|
|
| TableConstraint { $$ = $1; }
|
|
;
|
|
|
|
-columnDef: ColId Typename ColQualList
|
|
+columnDef: ColId Typename ColQualList OptSecurityItem
|
|
{
|
|
ColumnDef *n = makeNode(ColumnDef);
|
|
n->colname = $1;
|
|
n->typename = $2;
|
|
n->constraints = $3;
|
|
n->is_local = true;
|
|
+ n->pgaceItem = (Node *) $4;
|
|
$$ = (Node *)n;
|
|
}
|
|
;
|
|
@@ -4278,6 +4302,10 @@ common_func_opt_item:
|
|
/* we abuse the normal content of a DefElem here */
|
|
$$ = makeDefElem("set", (Node *)$1);
|
|
}
|
|
+ | SecurityItem
|
|
+ {
|
|
+ $$ = $1;
|
|
+ }
|
|
;
|
|
|
|
createfunc_opt_item:
|
|
@@ -5361,6 +5389,10 @@ createdb_opt_item:
|
|
{
|
|
$$ = makeDefElem("owner", NULL);
|
|
}
|
|
+ | SecurityItem
|
|
+ {
|
|
+ $$ = $1;
|
|
+ }
|
|
;
|
|
|
|
/*
|
|
@@ -5409,6 +5441,10 @@ alterdb_opt_item:
|
|
{
|
|
$$ = makeDefElem("connectionlimit", (Node *)makeInteger($4));
|
|
}
|
|
+ | SecurityItem
|
|
+ {
|
|
+ $$ = $1;
|
|
+ }
|
|
;
|
|
|
|
|
|
@@ -8736,6 +8772,26 @@ target_el: a_expr AS ColLabel
|
|
}
|
|
;
|
|
|
|
+/*****************************************************************************
|
|
+ *
|
|
+ * PGACE Security Items
|
|
+ *
|
|
+ *****************************************************************************/
|
|
+
|
|
+OptSecurityItem:
|
|
+ SecurityItem { $$ = $1; }
|
|
+ | /* EMPTY */ { $$ = NULL; }
|
|
+ ;
|
|
+
|
|
+SecurityItem:
|
|
+ IDENT '=' Sconst
|
|
+ {
|
|
+ DefElem *n = pgaceGramSecurityItem($1, $3);
|
|
+ if (n == NULL)
|
|
+ yyerror("syntax error");
|
|
+ $$ = n;
|
|
+ }
|
|
+ ;
|
|
|
|
/*****************************************************************************
|
|
*
|
|
diff -rpNU3 base/src/backend/parser/parse_target.c pgace/src/backend/parser/parse_target.c
|
|
--- base/src/backend/parser/parse_target.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/parser/parse_target.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -26,6 +26,7 @@
|
|
#include "parser/parse_relation.h"
|
|
#include "parser/parse_target.h"
|
|
#include "parser/parse_type.h"
|
|
+#include "security/pgace.h"
|
|
#include "utils/builtins.h"
|
|
#include "utils/lsyscache.h"
|
|
#include "utils/typcache.h"
|
|
@@ -335,14 +336,19 @@ transformAssignedExpr(ParseState *pstate
|
|
Relation rd = pstate->p_target_relation;
|
|
|
|
Assert(rd != NULL);
|
|
- if (attrno <= 0)
|
|
+ if (attrno > 0) {
|
|
+ attrtype = attnumTypeId(rd, attrno);
|
|
+ attrtypmod = rd->rd_att->attrs[attrno - 1]->atttypmod;
|
|
+ } else if (pgaceIsSecuritySystemColumn(attrno)) {
|
|
+ attrtype = SECLABELOID;
|
|
+ attrtypmod = -1;
|
|
+ } else {
|
|
ereport(ERROR,
|
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
|
errmsg("cannot assign to system column \"%s\"",
|
|
colname),
|
|
parser_errposition(pstate, location)));
|
|
- attrtype = attnumTypeId(rd, attrno);
|
|
- attrtypmod = rd->rd_att->attrs[attrno - 1]->atttypmod;
|
|
+ }
|
|
|
|
/*
|
|
* If the expression is a DEFAULT placeholder, insert the attribute's
|
|
@@ -483,6 +489,9 @@ updateTargetListEntry(ParseState *pstate
|
|
*/
|
|
tle->resno = (AttrNumber) attrno;
|
|
tle->resname = colname;
|
|
+
|
|
+ if (pgaceIsSecuritySystemColumn(attrno))
|
|
+ tle->resjunk = true;
|
|
}
|
|
|
|
|
|
@@ -749,6 +758,7 @@ checkInsertTargets(ParseState *pstate, L
|
|
Bitmapset *wholecols = NULL;
|
|
Bitmapset *partialcols = NULL;
|
|
ListCell *tl;
|
|
+ bool security_attr = false;
|
|
|
|
foreach(tl, cols)
|
|
{
|
|
@@ -757,14 +767,31 @@ checkInsertTargets(ParseState *pstate, L
|
|
int attrno;
|
|
|
|
/* Lookup column name, ereport on failure */
|
|
- attrno = attnameAttNum(pstate->p_target_relation, name, false);
|
|
- if (attrno == InvalidAttrNumber)
|
|
+ attrno = attnameAttNum(pstate->p_target_relation, name, true);
|
|
+ if (attrno == InvalidAttrNumber) {
|
|
ereport(ERROR,
|
|
(errcode(ERRCODE_UNDEFINED_COLUMN),
|
|
errmsg("column \"%s\" of relation \"%s\" does not exist",
|
|
name,
|
|
RelationGetRelationName(pstate->p_target_relation)),
|
|
parser_errposition(pstate, col->location)));
|
|
+ } else if (attrno <= 0) {
|
|
+ if (pgaceIsSecuritySystemColumn(attrno)) {
|
|
+ if (security_attr)
|
|
+ ereport(ERROR,
|
|
+ (errcode(ERRCODE_DUPLICATE_COLUMN),
|
|
+ errmsg("column \"%s\" specified more than once", name),
|
|
+ parser_errposition(pstate, col->location)));
|
|
+ security_attr = true;
|
|
+ *attrnos = lappend_int(*attrnos, attrno);
|
|
+ continue;
|
|
+ }
|
|
+ ereport(ERROR,
|
|
+ (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
|
|
+ errmsg("column \"%s\" of relation \"%s\" is system column",
|
|
+ name, RelationGetRelationName(pstate->p_target_relation)),
|
|
+ parser_errposition(pstate, col->location)));
|
|
+ }
|
|
|
|
/*
|
|
* Check for duplicates, but only of whole columns --- we allow
|
|
diff -rpNU3 base/src/backend/postmaster/postmaster.c pgace/src/backend/postmaster/postmaster.c
|
|
--- base/src/backend/postmaster/postmaster.c 2008-01-14 22:59:48.000000000 +0900
|
|
+++ pgace/src/backend/postmaster/postmaster.c 2008-01-25 19:04:56.000000000 +0900
|
|
@@ -107,6 +107,7 @@
|
|
#include "postmaster/pgarch.h"
|
|
#include "postmaster/postmaster.h"
|
|
#include "postmaster/syslogger.h"
|
|
+#include "security/pgace.h"
|
|
#include "storage/fd.h"
|
|
#include "storage/ipc.h"
|
|
#include "storage/pg_shmem.h"
|
|
@@ -1026,6 +1027,9 @@ PostmasterMain(int argc, char *argv[])
|
|
Assert(StartupPID != 0);
|
|
pmState = PM_STARTUP;
|
|
|
|
+ if (!pgaceInitializePostmaster())
|
|
+ ExitPostmaster(1);
|
|
+
|
|
status = ServerLoop();
|
|
|
|
/*
|
|
@@ -2039,9 +2043,11 @@ pmdie(SIGNAL_ARGS)
|
|
signal_child(PgArchPID, SIGQUIT);
|
|
if (PgStatPID != 0)
|
|
signal_child(PgStatPID, SIGQUIT);
|
|
+ pgaceFinalizePostmaster();
|
|
ExitPostmaster(0);
|
|
break;
|
|
}
|
|
+ pgaceFinalizePostmaster();
|
|
|
|
PG_SETMASK(&UnBlockSig);
|
|
|
|
diff -rpNU3 base/src/backend/rewrite/rewriteHandler.c pgace/src/backend/rewrite/rewriteHandler.c
|
|
--- base/src/backend/rewrite/rewriteHandler.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/rewrite/rewriteHandler.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -24,6 +24,7 @@
|
|
#include "rewrite/rewriteDefine.h"
|
|
#include "rewrite/rewriteHandler.h"
|
|
#include "rewrite/rewriteManip.h"
|
|
+#include "security/pgace.h"
|
|
#include "utils/builtins.h"
|
|
#include "utils/lsyscache.h"
|
|
#include "commands/trigger.h"
|
|
@@ -1880,5 +1881,8 @@ QueryRewrite(Query *parsetree)
|
|
if (!foundOriginalQuery && lastInstead != NULL)
|
|
lastInstead->canSetTag = true;
|
|
|
|
+ /* PGACE: general queries proxy */
|
|
+ results = pgaceProxyQuery(results);
|
|
+
|
|
return results;
|
|
}
|
|
diff -rpNU3 base/src/backend/security/Makefile pgace/src/backend/security/Makefile
|
|
--- base/src/backend/security/Makefile 1970-01-01 09:00:00.000000000 +0900
|
|
+++ pgace/src/backend/security/Makefile 2007-10-15 00:14:18.000000000 +0900
|
|
@@ -0,0 +1,28 @@
|
|
+#
|
|
+# src/backend/security/Makefile
|
|
+# Makefile for Security Purpose Extensions
|
|
+#
|
|
+# Copyright (c) 2006 - 2007 KaiGai Kohei <kaigai@kaigai.gr.jp>
|
|
+#
|
|
+ubdir = src/backend/security
|
|
+top_builddir = ../../..
|
|
+include $(top_builddir)/src/Makefile.global
|
|
+
|
|
+OBJS := pgaceCommon.o
|
|
+
|
|
+OBJS += pgaceHooks.o
|
|
+
|
|
+all: SUBSYS.o
|
|
+
|
|
+SUBSYS.o: $(OBJS)
|
|
+ $(LD) $(LDREL) $(LDOUT) $@ $^
|
|
+
|
|
+depend dep:
|
|
+ $(CC) -MM $(CFLAGS) *.c >depend
|
|
+
|
|
+clean:
|
|
+ rm -f SUBSYS.o $(OBJS)
|
|
+
|
|
+ifeq (depend,$(wildcard depend))
|
|
+include depend
|
|
+endif
|
|
diff -rpNU3 base/src/backend/security/pgaceCommon.c pgace/src/backend/security/pgaceCommon.c
|
|
--- base/src/backend/security/pgaceCommon.c 1970-01-01 09:00:00.000000000 +0900
|
|
+++ pgace/src/backend/security/pgaceCommon.c 2008-02-01 17:24:11.000000000 +0900
|
|
@@ -0,0 +1,714 @@
|
|
+/*
|
|
+ * src/backend/security/pgaceCommon.c
|
|
+ * Common part of PostgreSQL Access Control Extension
|
|
+ * Copyright 2007 KaiGai Kohei <kaigai@kaigai.gr.jp>
|
|
+ */
|
|
+#include "postgres.h"
|
|
+
|
|
+#include "access/genam.h"
|
|
+#include "access/heapam.h"
|
|
+#include "access/xact.h"
|
|
+#include "catalog/catalog.h"
|
|
+#include "catalog/indexing.h"
|
|
+#include "catalog/pg_attribute.h"
|
|
+#include "catalog/pg_largeobject.h"
|
|
+#include "catalog/pg_security.h"
|
|
+#include "catalog/pg_type.h"
|
|
+#include "executor/executor.h"
|
|
+#include "miscadmin.h"
|
|
+#include "nodes/makefuncs.h"
|
|
+#include "nodes/parsenodes.h"
|
|
+#include "parser/parse_expr.h"
|
|
+#include "security/pgace.h"
|
|
+#include "utils/builtins.h"
|
|
+#include "utils/fmgroids.h"
|
|
+#include "utils/syscache.h"
|
|
+#include <unistd.h>
|
|
+#include <sys/file.h>
|
|
+
|
|
+/*****************************************************************************
|
|
+ * Security attribute system column support
|
|
+ *****************************************************************************/
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+
|
|
+bool pgaceIsSecuritySystemColumn(int attrno)
|
|
+{
|
|
+ return ((attrno == SecurityAttributeNumber) ? true : false);
|
|
+}
|
|
+
|
|
+void pgaceTransformSelectStmt(List *targetList) {
|
|
+ ListCell *l;
|
|
+
|
|
+ foreach (l, targetList) {
|
|
+ TargetEntry *tle = lfirst(l);
|
|
+
|
|
+ if (tle->resjunk)
|
|
+ continue;
|
|
+ if (!strcmp(tle->resname, SECURITY_SYSATTR_NAME)) {
|
|
+ if (exprType((Node *) tle->expr) != SECLABELOID)
|
|
+ elog(ERROR, "type mismatch in explicit labeling");
|
|
+ tle->resjunk = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void pgaceTransformInsertStmt(List **p_icolumns, List **p_attrnos, List *targetList) {
|
|
+ AttrNumber security_attrno = 0;
|
|
+ ListCell *lc;
|
|
+
|
|
+ foreach (lc, targetList) {
|
|
+ TargetEntry *tle = (TargetEntry *) lfirst(lc);
|
|
+
|
|
+ security_attrno++;
|
|
+ if (strcmp(tle->resname, SECURITY_SYSATTR_NAME))
|
|
+ continue;
|
|
+
|
|
+ if (list_length(*p_icolumns) < list_length(targetList)) {
|
|
+ List *__icolumns = NIL;
|
|
+ List *__attrnos = NIL;
|
|
+ ListCell *l1, *l2;
|
|
+ int index = 0;
|
|
+
|
|
+ forboth(l1, *p_icolumns, l2, *p_attrnos) {
|
|
+ if (++index == security_attrno) {
|
|
+ ResTarget *col = makeNode(ResTarget);
|
|
+ col->name = pstrdup(SECURITY_SYSATTR_NAME);
|
|
+ col->indirection = NIL;
|
|
+ col->val = NULL;
|
|
+ col->location = -1;
|
|
+
|
|
+ __icolumns = lappend(__icolumns, col);
|
|
+ __attrnos = lappend_int(__attrnos, SecurityAttributeNumber);
|
|
+ }
|
|
+ if (lfirst_int(l2) == SecurityAttributeNumber)
|
|
+ return;
|
|
+ __icolumns = lappend(__icolumns, lfirst(l1));
|
|
+ __attrnos = lappend_int(__attrnos, lfirst_int(l2));
|
|
+ }
|
|
+ *p_icolumns = __icolumns;
|
|
+ *p_attrnos = __attrnos;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+void pgaceFetchSecurityAttribute(JunkFilter *junkfilter, TupleTableSlot *slot, Oid *tts_security)
|
|
+{
|
|
+ AttrNumber attno;
|
|
+ Datum datum;
|
|
+ bool isnull;
|
|
+
|
|
+ attno = ExecFindJunkAttribute(junkfilter, SECURITY_SYSATTR_NAME);
|
|
+ if (attno != InvalidAttrNumber) {
|
|
+ datum = ExecGetJunkAttribute(slot, attno, &isnull);
|
|
+ if (!isnull)
|
|
+ *tts_security = DatumGetObjectId(datum);
|
|
+ }
|
|
+}
|
|
+#else /* SECURITY_SYSATTR_NAME */
|
|
+
|
|
+bool pgaceIsSecuritySystemColumn(int attrno) {
|
|
+ return false;
|
|
+}
|
|
+
|
|
+void pgaceTransformSelectStmt(List *targetList) {
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+void pgaceTransformInsertStmt(List **p_icolumns,
|
|
+ List **p_attrnos,
|
|
+ List *targetList) {
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+void pgaceFetchSecurityAttribute(JunkFilter *junkfilter,
|
|
+ TupleTableSlot *slot,
|
|
+ Oid *tts_security) {
|
|
+ /* do nothing */
|
|
+}
|
|
+#endif /* SECURITY_SYSATTR_NAME */
|
|
+
|
|
+/*****************************************************************************
|
|
+ * Extended SQL statements support
|
|
+ *****************************************************************************/
|
|
+
|
|
+/* CREATE TABLE with explicit CONTEXT */
|
|
+List *pgaceRelationAttrList(CreateStmt *stmt)
|
|
+{
|
|
+ List *result = NIL;
|
|
+ ListCell *l;
|
|
+ DefElem *defel, *newel;
|
|
+
|
|
+ if (stmt->pgaceItem) {
|
|
+ defel = (DefElem *) stmt->pgaceItem;
|
|
+
|
|
+ Assert(IsA(defel, DefElem));
|
|
+ if (!pgaceIsGramSecurityItem(defel))
|
|
+ elog(ERROR, "node is not a pgace security item");
|
|
+ newel = makeDefElem(NULL, (Node *) copyObject(defel));
|
|
+ result = lappend(result, newel);
|
|
+ }
|
|
+
|
|
+ foreach (l, stmt->tableElts) {
|
|
+ ColumnDef *cdef = (ColumnDef *) lfirst(l);
|
|
+ defel = (DefElem *) cdef->pgaceItem;
|
|
+
|
|
+ if (defel) {
|
|
+ Assert(IsA(defel, DefElem));
|
|
+ if (!pgaceIsGramSecurityItem(defel))
|
|
+ elog(ERROR, "node is not a pgace security item");
|
|
+ newel = makeDefElem(pstrdup(cdef->colname),
|
|
+ (Node *) copyObject(defel));
|
|
+ result = lappend(result, newel);
|
|
+ }
|
|
+ }
|
|
+ return result;
|
|
+}
|
|
+
|
|
+void pgaceCreateRelationCommon(Relation rel, HeapTuple tuple, List *pgace_attr_list) {
|
|
+ ListCell *l;
|
|
+
|
|
+ foreach (l, pgace_attr_list) {
|
|
+ DefElem *defel = (DefElem *) lfirst(l);
|
|
+
|
|
+ if (!defel->defname) {
|
|
+ Assert(pgaceIsGramSecurityItem((DefElem *)defel->arg));
|
|
+ pgaceGramCreateRelation(rel, tuple, (DefElem *)defel->arg);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void pgaceCreateAttributeCommon(Relation rel, HeapTuple tuple, List *pgace_attr_list) {
|
|
+ Form_pg_attribute attr = (Form_pg_attribute) GETSTRUCT(tuple);
|
|
+ ListCell *l;
|
|
+
|
|
+ foreach (l, pgace_attr_list) {
|
|
+ DefElem *defel = lfirst(l);
|
|
+
|
|
+ if (!defel->defname)
|
|
+ continue; /* for table */
|
|
+ if (!strcmp(defel->defname, NameStr(attr->attname))) {
|
|
+ Assert(pgaceIsGramSecurityItem((DefElem *)defel->arg));
|
|
+ pgaceGramCreateAttribute(rel, tuple, (DefElem *)defel->arg);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+/* ALTER <tblname> [ALTER <colname>] CONTEXT = 'xxx' statement */
|
|
+static void alterRelationCommon(Relation rel, DefElem *defel) {
|
|
+ Relation pg_class;
|
|
+ HeapTuple tuple;
|
|
+
|
|
+ pg_class = heap_open(RelationRelationId, RowExclusiveLock);
|
|
+
|
|
+ tuple = SearchSysCacheCopy(RELOID,
|
|
+ ObjectIdGetDatum(RelationGetRelid(rel)),
|
|
+ 0, 0, 0);
|
|
+ if (!HeapTupleIsValid(tuple))
|
|
+ elog(ERROR, "cache lookup failed for relation '%s'", RelationGetRelationName(rel));
|
|
+ pgaceGramAlterRelation(rel, tuple, defel);
|
|
+
|
|
+ simple_heap_update(pg_class, &tuple->t_self, tuple);
|
|
+ CatalogUpdateIndexes(pg_class, tuple);
|
|
+
|
|
+ heap_freetuple(tuple);
|
|
+ heap_close(pg_class, RowExclusiveLock);
|
|
+}
|
|
+
|
|
+static void alterAttributeCommon(Relation rel, char *colName, DefElem *defel) {
|
|
+ Relation pg_attr;
|
|
+ HeapTuple tuple;
|
|
+
|
|
+ pg_attr = heap_open(AttributeRelationId, RowExclusiveLock);
|
|
+
|
|
+ tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
|
|
+ if (!HeapTupleIsValid(tuple))
|
|
+ elog(ERROR, "cache lookup failed for attribute '%s' of relation '%s'",
|
|
+ colName, RelationGetRelationName(rel));
|
|
+ pgaceGramAlterAttribute(rel, tuple, defel);
|
|
+
|
|
+ simple_heap_update(pg_attr, &tuple->t_self, tuple);
|
|
+ CatalogUpdateIndexes(pg_attr, tuple);
|
|
+
|
|
+ heap_freetuple(tuple);
|
|
+ heap_close(pg_attr, RowExclusiveLock);
|
|
+}
|
|
+
|
|
+void pgaceAlterRelationCommon(Relation rel, AlterTableCmd *cmd) {
|
|
+ DefElem *defel = (DefElem *) cmd->def;
|
|
+
|
|
+ Assert(IsA(defel, DefElem));
|
|
+
|
|
+ if (!pgaceIsGramSecurityItem(defel))
|
|
+ elog(ERROR, "unsupported pgace security item");
|
|
+
|
|
+ if (!cmd->name) {
|
|
+ alterRelationCommon(rel, defel);
|
|
+ } else {
|
|
+ alterAttributeCommon(rel, cmd->name, defel);
|
|
+ }
|
|
+}
|
|
+
|
|
+/*****************************************************************************
|
|
+ * security_label type input/output handler
|
|
+ *****************************************************************************/
|
|
+static Oid early_security_label_to_sid(char *seclabel);
|
|
+static char *early_sid_to_security_label(Oid sid);
|
|
+#define EARLY_PG_SECURITY "global/pg_security.bootstrap"
|
|
+
|
|
+static bool pg_security_is_available() {
|
|
+ /* -1 : early mode, 0: now in transfer, 1: available */
|
|
+ static int pg_security_state = -1;
|
|
+ char fname[MAXPGPATH];
|
|
+ FILE *filp;
|
|
+
|
|
+ if (pg_security_state > 0)
|
|
+ return true;
|
|
+ if (IsBootstrapProcessingMode() || pg_security_state==0)
|
|
+ return false;
|
|
+ /*
|
|
+ * if initial setting up was not done, the cache file is remaining.
|
|
+ * so we have to insert its contains into pg_selinux.
|
|
+ * we can make decision of whether it already done, or not, by looking
|
|
+ * the existance of 'EARLY_PG_SECURITY'.
|
|
+ */
|
|
+ snprintf(fname, sizeof(fname), "%s/%s", DataDir, EARLY_PG_SECURITY);
|
|
+ filp = fopen(fname, "rb");
|
|
+ if (filp) {
|
|
+ Relation rel;
|
|
+ CatalogIndexState ind;
|
|
+ HeapTuple tuple;
|
|
+ char buffer[1024];
|
|
+ Oid secoid, metaoid;
|
|
+ Datum value;
|
|
+ char isnull;
|
|
+
|
|
+ pg_security_state = 0;
|
|
+
|
|
+ PG_TRY();
|
|
+ {
|
|
+ rel = heap_open(SecurityRelationId, RowExclusiveLock);
|
|
+ ind = CatalogOpenIndexes(rel);
|
|
+ while (fscanf(filp, "%u %s", &secoid, buffer) == 2) {
|
|
+ metaoid = early_security_label_to_sid(pgaceSecurityLabelOfLabel(buffer));
|
|
+
|
|
+ value = DirectFunctionCall1(textin, CStringGetDatum(buffer));
|
|
+ isnull = ' ';
|
|
+ tuple = heap_formtuple(RelationGetDescr(rel), &value, &isnull);
|
|
+
|
|
+ HeapTupleSetOid(tuple, secoid);
|
|
+ HeapTupleSetSecurity(tuple, metaoid);
|
|
+
|
|
+ simple_heap_insert(rel, tuple);
|
|
+ CatalogIndexInsert(ind, tuple);
|
|
+
|
|
+ heap_freetuple(tuple);
|
|
+ }
|
|
+ CatalogCloseIndexes(ind);
|
|
+ heap_close(rel, RowExclusiveLock);
|
|
+
|
|
+ CommandCounterIncrement();
|
|
+ }
|
|
+ PG_CATCH();
|
|
+ {
|
|
+ fclose(filp);
|
|
+ PG_RE_THROW();
|
|
+ }
|
|
+ PG_END_TRY();
|
|
+ fclose(filp);
|
|
+ if (unlink(fname) != 0)
|
|
+ elog(ERROR, "PGACE: could not unlink '%s'", fname);
|
|
+ }
|
|
+ pg_security_state = 1;
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static Oid early_security_label_to_sid(char *seclabel)
|
|
+{
|
|
+ char fname[MAXPGPATH], buffer[1024];
|
|
+ Oid sid, minsid = SecurityRelationId;
|
|
+ FILE *filp;
|
|
+
|
|
+ snprintf(fname, sizeof(fname), "%s/%s", DataDir, EARLY_PG_SECURITY);
|
|
+ filp = fopen(fname, "a+b");
|
|
+ if (!filp)
|
|
+ ereport(ERROR,
|
|
+ (errcode(ERRCODE_INTERNAL_ERROR),
|
|
+ errmsg("could not open '%s'", fname)));
|
|
+ flock(fileno(filp), LOCK_EX);
|
|
+ while (fscanf(filp, "%u %s", &sid, buffer) == 2) {
|
|
+ if (!strcmp(seclabel, buffer)) {
|
|
+ fclose(filp);
|
|
+ return sid;
|
|
+ }
|
|
+ if (sid < minsid)
|
|
+ minsid = sid;
|
|
+ }
|
|
+ sid = minsid - 1;
|
|
+ fprintf(filp, "%u %s\n", sid, seclabel);
|
|
+ fclose(filp);
|
|
+
|
|
+ return sid;
|
|
+}
|
|
+
|
|
+static char *early_sid_to_security_label(Oid sid)
|
|
+{
|
|
+ char fname[MAXPGPATH], buffer[1024], *seclabel;
|
|
+ FILE *filp;
|
|
+ Oid __sid;
|
|
+
|
|
+ snprintf(fname, sizeof(fname), "%s/%s", DataDir, EARLY_PG_SECURITY);
|
|
+ filp = fopen(fname, "rb");
|
|
+ if (!filp)
|
|
+ goto not_found;
|
|
+
|
|
+ flock(fileno(filp), LOCK_SH);
|
|
+ while (fscanf(filp, "%u %s", &__sid, buffer) == 2) {
|
|
+ if (sid == __sid) {
|
|
+ fclose(filp);
|
|
+ return pstrdup(buffer);
|
|
+ }
|
|
+ }
|
|
+ fclose(filp);
|
|
+
|
|
+not_found:
|
|
+ seclabel = pgaceSecurityLabelCheckValid(NULL);
|
|
+ elog(seclabel ? NOTICE : ERROR,
|
|
+ "PGACE: No text representation for sid = %u", sid);
|
|
+ return seclabel;
|
|
+}
|
|
+
|
|
+static Oid get_security_label_oid(Relation rel, CatalogIndexState ind, char *new_label)
|
|
+{
|
|
+ /* rel has to be opened with RowExclusiveLock */
|
|
+ char *mlabel_str, *__mlabel_str;
|
|
+ Datum mlabel_text;
|
|
+ HeapTuple tuple;
|
|
+ Oid label_oid;
|
|
+
|
|
+ mlabel_str = pgaceSecurityLabelOfLabel(new_label);
|
|
+ __mlabel_str = pgaceSecurityLabelCheckValid(mlabel_str);
|
|
+ if (mlabel_str != __mlabel_str)
|
|
+ elog(NOTICE, "PGACE: '%s' is not a valid security label,"
|
|
+ " '%s' is applied instead.", mlabel_str, __mlabel_str);
|
|
+
|
|
+ /* 1. lookup syscache */
|
|
+ mlabel_text = DirectFunctionCall1(textin, CStringGetDatum(mlabel_str));
|
|
+ tuple = SearchSysCache(SECURITYLABEL,
|
|
+ mlabel_text,
|
|
+ 0, 0, 0);
|
|
+ if (HeapTupleIsValid(tuple)) {
|
|
+ label_oid = HeapTupleGetSecurity(tuple);
|
|
+ ReleaseSysCache(tuple);
|
|
+ } else {
|
|
+ /* 2. lookup table on SnapshotSelf */
|
|
+ SysScanDesc scan;
|
|
+ ScanKeyData skey;
|
|
+
|
|
+ ScanKeyInit(&skey,
|
|
+ Anum_pg_security_seclabel,
|
|
+ BTEqualStrategyNumber, F_TEXTEQ,
|
|
+ PointerGetDatum(mlabel_text));
|
|
+ scan = systable_beginscan(rel, SecuritySeclabelIndexId,
|
|
+ true, SnapshotSelf, 1, &skey);
|
|
+ tuple = systable_getnext(scan);
|
|
+ if (HeapTupleIsValid(tuple)) {
|
|
+ label_oid = HeapTupleGetSecurity(tuple);
|
|
+ } else {
|
|
+ /* 3. insert a new tuple into pg_security */
|
|
+ Datum value = PointerGetDatum(mlabel_text);
|
|
+ char isnull = ' ';
|
|
+ Oid meta_oid;
|
|
+
|
|
+ tuple = heap_formtuple(RelationGetDescr(rel),
|
|
+ &value, &isnull);
|
|
+ meta_oid = GetNewOid(rel);
|
|
+ HeapTupleSetOid(tuple, meta_oid);
|
|
+ HeapTupleSetSecurity(tuple, meta_oid);
|
|
+
|
|
+ label_oid = simple_heap_insert(rel, tuple);
|
|
+ Assert(label_oid == meta_oid);
|
|
+
|
|
+ CatalogIndexInsert(ind, tuple);
|
|
+ }
|
|
+ systable_endscan(scan);
|
|
+ }
|
|
+ return label_oid;
|
|
+}
|
|
+
|
|
+static Oid security_label_to_sid(char *label_str)
|
|
+{
|
|
+ Datum label_text;
|
|
+ Oid label_oid;
|
|
+ HeapTuple tuple;
|
|
+
|
|
+ if (!pg_security_is_available())
|
|
+ return early_security_label_to_sid(label_str);
|
|
+
|
|
+ /* 1. lookup system cache first */
|
|
+ label_text = DirectFunctionCall1(textin, CStringGetDatum(label_str));
|
|
+ tuple = SearchSysCache(SECURITYLABEL,
|
|
+ label_text,
|
|
+ 0, 0, 0);
|
|
+ if (HeapTupleIsValid(tuple)) {
|
|
+ label_oid = HeapTupleGetOid(tuple);
|
|
+ ReleaseSysCache(tuple);
|
|
+ } else {
|
|
+ /* 2. lookup within the current command ID */
|
|
+ Relation rel;
|
|
+ SysScanDesc scan;
|
|
+ ScanKeyData skey;
|
|
+ Oid meta_oid;
|
|
+
|
|
+ rel = heap_open(SecurityRelationId, RowExclusiveLock);
|
|
+ ScanKeyInit(&skey,
|
|
+ Anum_pg_security_seclabel,
|
|
+ BTEqualStrategyNumber, F_TEXTEQ,
|
|
+ PointerGetDatum(label_text));
|
|
+ scan = systable_beginscan(rel, SecuritySeclabelIndexId,
|
|
+ true, SnapshotSelf, 1, &skey);
|
|
+ tuple = systable_getnext(scan);
|
|
+ if (HeapTupleIsValid(tuple)) {
|
|
+ label_oid = HeapTupleGetOid(tuple);
|
|
+ } else {
|
|
+ CatalogIndexState ind;
|
|
+ Datum value = PointerGetDatum(label_text);
|
|
+ char isnull = ' ';
|
|
+
|
|
+ ind = CatalogOpenIndexes(rel);
|
|
+
|
|
+ tuple = heap_formtuple(RelationGetDescr(rel),
|
|
+ &value, &isnull);
|
|
+ meta_oid = get_security_label_oid(rel, ind, label_str);
|
|
+ HeapTupleSetSecurity(tuple, meta_oid);
|
|
+
|
|
+ label_oid = simple_heap_insert(rel, tuple);
|
|
+
|
|
+ CatalogIndexInsert(ind, tuple);
|
|
+ CatalogCloseIndexes(ind);
|
|
+ }
|
|
+ systable_endscan(scan);
|
|
+ heap_close(rel, RowExclusiveLock);
|
|
+ }
|
|
+ return label_oid;
|
|
+}
|
|
+
|
|
+static char *sid_to_security_label(Oid sid)
|
|
+{
|
|
+ HeapTuple tuple;
|
|
+ Datum tcon;
|
|
+ char *seclabel;
|
|
+ bool isnull, syscache = true;
|
|
+
|
|
+ if (!pg_security_is_available())
|
|
+ return early_sid_to_security_label(sid);
|
|
+
|
|
+ tuple = SearchSysCache(SECURITYOID,
|
|
+ ObjectIdGetDatum(sid),
|
|
+ 0, 0, 0);
|
|
+ if (!HeapTupleIsValid(tuple)) {
|
|
+ Relation rel;
|
|
+ SysScanDesc scan;
|
|
+ ScanKeyData skey;
|
|
+
|
|
+ syscache = false;
|
|
+ rel = heap_open(SecurityRelationId, AccessShareLock);
|
|
+ ScanKeyInit(&skey,
|
|
+ ObjectIdAttributeNumber,
|
|
+ BTEqualStrategyNumber, F_OIDEQ,
|
|
+ ObjectIdGetDatum(sid));
|
|
+ scan = systable_beginscan(rel, SecurityOidIndexId,
|
|
+ true, SnapshotSelf, 1, &skey);
|
|
+ tuple = systable_getnext(scan);
|
|
+ if (HeapTupleIsValid(tuple))
|
|
+ tuple = heap_copytuple(tuple);
|
|
+ systable_endscan(scan);
|
|
+ heap_close(rel, AccessShareLock);
|
|
+
|
|
+ if (!HeapTupleIsValid(tuple)) {
|
|
+ seclabel = pgaceSecurityLabelCheckValid(NULL);
|
|
+ elog(seclabel ? NOTICE : ERROR,
|
|
+ "PGACE: No text representation for sid = %u", sid);
|
|
+ return seclabel;
|
|
+ }
|
|
+ }
|
|
+ tcon = SysCacheGetAttr(SECURITYOID,
|
|
+ tuple,
|
|
+ Anum_pg_security_seclabel,
|
|
+ &isnull);
|
|
+ seclabel = DatumGetCString(DirectFunctionCall1(textout,
|
|
+ PointerGetDatum(tcon)));
|
|
+ if (syscache)
|
|
+ ReleaseSysCache(tuple);
|
|
+
|
|
+ return seclabel;
|
|
+}
|
|
+
|
|
+/* security_label_in -- security_label input function */
|
|
+Datum
|
|
+security_label_in(PG_FUNCTION_ARGS)
|
|
+{
|
|
+ char *label = PG_GETARG_CSTRING(0);
|
|
+ char *__label;
|
|
+
|
|
+ label = pgaceSecurityLabelIn(label);
|
|
+ __label = pgaceSecurityLabelCheckValid(label);
|
|
+ if (label != __label)
|
|
+ elog(ERROR, "PGACE: '%s' is not a valid security label", label);
|
|
+
|
|
+ PG_RETURN_OID(security_label_to_sid(label));
|
|
+}
|
|
+
|
|
+/* security_label_out -- security_label output function */
|
|
+Datum
|
|
+security_label_out(PG_FUNCTION_ARGS)
|
|
+{
|
|
+ Oid sid = PG_GETARG_OID(0);
|
|
+ char *label = sid_to_security_label(sid);
|
|
+ char *__label = pgaceSecurityLabelCheckValid(label);
|
|
+ if (label != __label)
|
|
+ elog(NOTICE, "PGACE: '%s' is not a valid security label,"
|
|
+ " '%s' is applied instead.", label, __label);
|
|
+ PG_RETURN_CSTRING(pgaceSecurityLabelOut(__label));
|
|
+}
|
|
+
|
|
+/* security_label_raw_in -- security_label input function in raw format */
|
|
+Datum
|
|
+security_label_raw_in(PG_FUNCTION_ARGS)
|
|
+{
|
|
+ char *label = PG_GETARG_CSTRING(0);
|
|
+ char *__label;
|
|
+
|
|
+ __label = pgaceSecurityLabelCheckValid(label);
|
|
+ if (label != __label)
|
|
+ elog(ERROR, "PGACE: '%s' is not a valid security label", label);
|
|
+
|
|
+ PG_RETURN_OID(security_label_to_sid(label));
|
|
+}
|
|
+
|
|
+/* security_label_raw_out -- security_label output function in raw format */
|
|
+Datum
|
|
+security_label_raw_out(PG_FUNCTION_ARGS)
|
|
+{
|
|
+ Oid sid = PG_GETARG_OID(0);
|
|
+ char *label = sid_to_security_label(sid);
|
|
+ char *__label = pgaceSecurityLabelCheckValid(label);
|
|
+
|
|
+ if (label != __label)
|
|
+ elog(NOTICE, "PGACE: '%s' is not a valid security label,"
|
|
+ " '%s' is applied instead.", label, __label);
|
|
+ PG_RETURN_CSTRING(__label);
|
|
+}
|
|
+
|
|
+/* text_to_security_label -- security_label cast function */
|
|
+Datum
|
|
+text_to_security_label(PG_FUNCTION_ARGS)
|
|
+{
|
|
+ text *t = PG_GETARG_TEXT_P(0);
|
|
+ Datum seclabel;
|
|
+
|
|
+ seclabel = DirectFunctionCall1(textout,
|
|
+ PointerGetDatum(t));
|
|
+ return DirectFunctionCall1(security_label_in, seclabel);
|
|
+}
|
|
+
|
|
+/* security_label_to_text -- security_label cast function */
|
|
+Datum
|
|
+security_label_to_text(PG_FUNCTION_ARGS)
|
|
+{
|
|
+ Oid sid = PG_GETARG_OID(0);
|
|
+ Datum seclabel;
|
|
+
|
|
+ seclabel = DirectFunctionCall1(security_label_out,
|
|
+ ObjectIdGetDatum(sid));
|
|
+ return DirectFunctionCall1(textin, seclabel);
|
|
+}
|
|
+
|
|
+/*****************************************************************************
|
|
+ * Set/Get security attribute of Large Object
|
|
+ *****************************************************************************/
|
|
+Datum
|
|
+lo_get_security(PG_FUNCTION_ARGS)
|
|
+{
|
|
+ Oid loid = PG_GETARG_OID(0);
|
|
+ Oid lo_security = InvalidOid;
|
|
+ Relation rel;
|
|
+ ScanKeyData skey;
|
|
+ SysScanDesc sd;
|
|
+ HeapTuple tuple;
|
|
+ bool found = false;
|
|
+
|
|
+ ScanKeyInit(&skey,
|
|
+ Anum_pg_largeobject_loid,
|
|
+ BTEqualStrategyNumber, F_OIDEQ,
|
|
+ ObjectIdGetDatum(loid));
|
|
+
|
|
+ rel = heap_open(LargeObjectRelationId, AccessShareLock);
|
|
+
|
|
+ sd = systable_beginscan(rel, LargeObjectLOidPNIndexId, true,
|
|
+ SnapshotNow, 1, &skey);
|
|
+
|
|
+ while ((tuple = systable_getnext(sd)) != NULL) {
|
|
+ lo_security = HeapTupleGetSecurity(tuple);
|
|
+ pgaceLargeObjectGetSecurity(tuple);
|
|
+ found = true;
|
|
+ break;
|
|
+ }
|
|
+ systable_endscan(sd);
|
|
+
|
|
+ heap_close(rel, AccessShareLock);
|
|
+
|
|
+ if (!found)
|
|
+ elog(ERROR, "large object %u does not exist", loid);
|
|
+
|
|
+ PG_RETURN_OID(lo_security);
|
|
+}
|
|
+
|
|
+Datum
|
|
+lo_set_security(PG_FUNCTION_ARGS)
|
|
+{
|
|
+ Oid loid = PG_GETARG_OID(0);
|
|
+ Oid lo_security = PG_GETARG_OID(1);
|
|
+ Relation rel;
|
|
+ ScanKeyData skey;
|
|
+ SysScanDesc sd;
|
|
+ HeapTuple tuple, newtup;
|
|
+ CatalogIndexState indstate;
|
|
+ bool found = false;
|
|
+
|
|
+ ScanKeyInit(&skey,
|
|
+ Anum_pg_largeobject_loid,
|
|
+ BTEqualStrategyNumber, F_OIDEQ,
|
|
+ ObjectIdGetDatum(loid));
|
|
+
|
|
+ rel = heap_open(LargeObjectRelationId, RowExclusiveLock);
|
|
+
|
|
+ indstate = CatalogOpenIndexes(rel);
|
|
+
|
|
+ sd = systable_beginscan(rel, LargeObjectLOidPNIndexId, true,
|
|
+ SnapshotNow, 1, &skey);
|
|
+
|
|
+ while ((tuple = systable_getnext(sd)) != NULL) {
|
|
+ newtup = heap_copytuple(tuple);
|
|
+ if (!found)
|
|
+ pgaceLargeObjectSetSecurity(newtup, lo_security);
|
|
+ HeapTupleSetSecurity(newtup, lo_security);
|
|
+ simple_heap_update(rel, &newtup->t_self, newtup);
|
|
+ CatalogUpdateIndexes(rel, newtup);
|
|
+ found = true;
|
|
+ }
|
|
+ systable_endscan(sd);
|
|
+ CatalogCloseIndexes(indstate);
|
|
+ heap_close(rel, RowExclusiveLock);
|
|
+
|
|
+ CommandCounterIncrement();
|
|
+
|
|
+ if (!found)
|
|
+ elog(ERROR, "large object %u does not exist.", loid);
|
|
+
|
|
+ PG_RETURN_BOOL(true);
|
|
+}
|
|
diff -rpNU3 base/src/backend/security/pgaceHooks.c pgace/src/backend/security/pgaceHooks.c
|
|
--- base/src/backend/security/pgaceHooks.c 1970-01-01 09:00:00.000000000 +0900
|
|
+++ pgace/src/backend/security/pgaceHooks.c 2008-02-01 20:22:14.000000000 +0900
|
|
@@ -0,0 +1,619 @@
|
|
+/*
|
|
+ * src/backend/security/pgaceHooks.c
|
|
+ * Dummy functions of PostgreSQL Access Control Extension
|
|
+ * when no users enables the framework.
|
|
+ * Copyright 2007 KaiGai Kohei <kaigai@kaigai.gr.jp>
|
|
+ */
|
|
+#include "postgres.h"
|
|
+
|
|
+#include "security/pgace.h"
|
|
+
|
|
+/******************************************************************
|
|
+ * Initialize / Finalize related hooks
|
|
+ ******************************************************************/
|
|
+
|
|
+/*
|
|
+ * pgaceShmemSize() have to return the size of shared memory segment
|
|
+ * required by PGACE implementation. If no shared memory segment needed,
|
|
+ * it should return 0.
|
|
+ */
|
|
+Size pgaceShmemSize(void)
|
|
+{
|
|
+ return (Size) 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceInitialize() is called when a new PostgreSQL instance is generated.
|
|
+ * A PGACE implementation can initialize itself.
|
|
+ *
|
|
+ * @is_bootstrap : true, if bootstraping mode.
|
|
+ */
|
|
+void pgaceInitialize(bool is_bootstrap)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceInitializePostmaster() is called when a postmaster server process
|
|
+ * is started up. If it returns false, the server starting up process
|
|
+ * will be aborted.
|
|
+ */
|
|
+bool pgaceInitializePostmaster(void)
|
|
+{
|
|
+ return true;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceFinalizePostmaster() is called when a postmaster server process
|
|
+ * is just ending up.
|
|
+ */
|
|
+void pgaceFinalizePostmaster(void)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/******************************************************************
|
|
+ * SQL proxy hooks
|
|
+ ******************************************************************/
|
|
+
|
|
+/*
|
|
+ * pgaceProxyQuery() is called just after query rewrite phase.
|
|
+ * PGACE implementation can modify the query trees in this hook,
|
|
+ * if necessary.
|
|
+ *
|
|
+ * @queryList : a list of Query typed objects.
|
|
+ */
|
|
+List *pgaceProxyQuery(List *queryList)
|
|
+{
|
|
+ return queryList;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgacePortalStart() is called on the top of PortalStart().
|
|
+ *
|
|
+ * @portal : a Portal object currently executed.
|
|
+ */
|
|
+void pgacePortalStart(Portal portal)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceExecutorStart() is called on the top of ExecutorStart().
|
|
+ *
|
|
+ * @queryDesc : a QueryDesc object given to ExecutorStart().
|
|
+ * @eflags : eflags valus given to ExecutorStart().
|
|
+ * if EXEC_FLAG_EXPLAIN_ONLY is set, no real access will run.
|
|
+ */
|
|
+void pgaceExecutorStart(QueryDesc *queryDesc, int eflags)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/******************************************************************
|
|
+ * HeapTuple modification hooks
|
|
+ ******************************************************************/
|
|
+
|
|
+/*
|
|
+ * pgaceHeapTupleInsert() is called when a new tuple attempt to be inserted.
|
|
+ * If it returns false, this insertion of a new tuple will be cancelled.
|
|
+ * However, it does not generate any error.
|
|
+ *
|
|
+ * @rel : the target relation
|
|
+ * @tuple : the tuple attmpt to be inserted
|
|
+ * @is_internal : true, if this operation is invoked by system internal processes.
|
|
+ * @with_returning : true, if INSERT statement has RETURNING clause.
|
|
+ */
|
|
+bool pgaceHeapTupleInsert(Relation rel, HeapTuple tuple,
|
|
+ bool is_internal, bool with_returning)
|
|
+{
|
|
+ return true;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceHeapTupleUpdate() is called when a tuple attempt to be updated.
|
|
+ * If it returns false, this update will be cancelled.
|
|
+ * However, it does not generate any error.
|
|
+ *
|
|
+ * @rel : the target relation
|
|
+ * @otid : ItemPointer of the tuple to be updated
|
|
+ * @newtup : the new contains of the updated tuple
|
|
+ * @is_internal : true, if this operation is invoked by system internal processes.
|
|
+ * @with_returning : true, if INSERT statement has RETURNING clause.
|
|
+ */
|
|
+bool pgaceHeapTupleUpdate(Relation rel, ItemPointer otid, HeapTuple newtup,
|
|
+ bool is_internal, bool with_returning)
|
|
+{
|
|
+ return true;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceHeapTupleDelete() is called when a tuple attempt to be deleted.
|
|
+ * If it returns false, this deletion will be cancelled.
|
|
+ * However, it does not generate any error.
|
|
+ *
|
|
+ * @rel : the target relation
|
|
+ * @otid : ItemPointer of the tuple to be deleted
|
|
+ * @is_internal : true, if this operation is invoked by system internal processes.
|
|
+ * @with_returning : true, if INSERT statement has RETURNING clause.
|
|
+ */
|
|
+bool pgaceHeapTupleDelete(Relation rel, ItemPointer otid,
|
|
+ bool is_internal, bool with_returning)
|
|
+{
|
|
+ return true;
|
|
+}
|
|
+
|
|
+/******************************************************************
|
|
+ * Extended SQL statement hooks
|
|
+ ******************************************************************/
|
|
+/*
|
|
+ * PGACE implementation can use pgaceGramSecurityItem() hook to extend
|
|
+ * SQL statement for security purpose. This hook is deployed on parser/gram.y
|
|
+ * as a part of the SQL grammer. If no SQL extension is necessary, it has to
|
|
+ * return NULL to cause yyerror().
|
|
+ *
|
|
+ * @defname : given <parameter> string
|
|
+ * @value : given <value> string
|
|
+ */
|
|
+DefElem *pgaceGramSecurityItem(char *defname, char *value)
|
|
+{
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * PGACE implementation has to return true, if the given DefElem holds
|
|
+ * security item generated in pgaceGramSecurityItem(). false, if any other.
|
|
+ *
|
|
+ * @defel : given DefElem object
|
|
+ */
|
|
+bool pgaceIsGramSecurityItem(DefElem *defel)
|
|
+{
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceGramCreateRelation() is called to modify a tuple just before inserting
|
|
+ * a new relation with CREATE TABLE, if extended statement is used.
|
|
+ *
|
|
+ * @rel : pg_class relation
|
|
+ * @tuple : a tuple of new relation
|
|
+ * @defel : extended statement
|
|
+ */
|
|
+void pgaceGramCreateRelation(Relation rel, HeapTuple tuple, DefElem *defel)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceGramCreateAttribute() is called to modify a tuple just before inserting
|
|
+ * a new attribute with CREATE TABLE, if extended statement is used.
|
|
+ *
|
|
+ * @rel : pg_attribute relation
|
|
+ * @tuple : a tuple of new attribute
|
|
+ * @defel : extended statement
|
|
+ */
|
|
+void pgaceGramCreateAttribute(Relation rel, HeapTuple tuple, DefElem *defel)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceGramAlterRelation() is called to modify a tuple just before updating
|
|
+ * a relation with ALTER TABLE, if extended statement is used.
|
|
+ *
|
|
+ * @rel : target relation
|
|
+ * @tuple : a tuple of new relation
|
|
+ * @defel : extended statement
|
|
+ */
|
|
+void pgaceGramAlterRelation(Relation rel, HeapTuple tuple, DefElem *defel)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceGramAlterAttribute() is called to modify a tuple just before updating
|
|
+ * an attribute with ALTER TABLE, if extended statement is specified.
|
|
+ *
|
|
+ * @rel : target relation
|
|
+ * @tuple : a tuple of new attribute
|
|
+ * @defel : extended statement
|
|
+ */
|
|
+void pgaceGramAlterAttribute(Relation rel, HeapTuple tuple, DefElem *defel)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceGramCreateDatabase() is called to modify a tuple just before inserting
|
|
+ * a new database with CREATE DATABASE, if extended statement is used.
|
|
+ *
|
|
+ * @rel : pg_database relation
|
|
+ * @tuple : a tuple of the new database
|
|
+ * @defel : extended statement
|
|
+ */
|
|
+void pgaceGramCreateDatabase(Relation rel, HeapTuple tuple, DefElem *defel)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceGramAlterDatabase() is called to modify a tuple just before updating
|
|
+ * a database with ALTER DATABASE, if extended statement is used.
|
|
+ *
|
|
+ * @rel : pg_database relation
|
|
+ * @tuple : a tuple of the updated database
|
|
+ * @defel : extended statement
|
|
+ */
|
|
+void pgaceGramAlterDatabase(Relation rel, HeapTuple tuple, DefElem *defel)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceGramCreateFunction() is called to modify a tuple just before inserting
|
|
+ * a new function into pg_proc, if extended statement is used.
|
|
+ *
|
|
+ * @rel : pg_proc relation
|
|
+ * @tuple : a tuple of the new function
|
|
+ * @defel : extended statement
|
|
+ */
|
|
+void pgaceGramCreateFunction(Relation rel, HeapTuple tuple, DefElem *defel)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceGramAlterFunction() is called to modify a tuple just before updating
|
|
+ * a function with ALTER FUNCTION, if extended statement is used.
|
|
+ *
|
|
+ * @rel : pg_proc relation
|
|
+ * @tuple : a tuple of the function
|
|
+ * @defel : extended statement
|
|
+ */
|
|
+void pgaceGramAlterFunction(Relation rel, HeapTuple tuple, DefElem *defel)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/******************************************************************
|
|
+ * DATABASE related hooks
|
|
+ ******************************************************************/
|
|
+
|
|
+/*
|
|
+ * pgaceSetDatabaseParam() is called when clients tries to set GUC variables
|
|
+ *
|
|
+ * @name : The name of GUC variable
|
|
+ * @argstr : The new valus of GUC variable. If argstr is NULL, it means
|
|
+ * clients tries to reset the variable.
|
|
+ */
|
|
+void pgaceSetDatabaseParam(const char *name, char *argstring)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceGetDatabaseParam() is called when clients tries to refer GUC variables
|
|
+ *
|
|
+ * @name : The name of GUC variable
|
|
+ */
|
|
+void pgaceGetDatabaseParam(const char *name)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/******************************************************************
|
|
+ * FUNCTION related hooks
|
|
+ ******************************************************************/
|
|
+
|
|
+/*
|
|
+ * pgaceCallFunction() is called just before executing SQL function
|
|
+ * as a part of query.
|
|
+ *
|
|
+ * @finfo : FmgrInfo object for the target function
|
|
+ */
|
|
+void pgaceCallFunction(FmgrInfo *finfo)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceCallFunctionTrigger() is called just before executing
|
|
+ * trigger function.
|
|
+ * If it returns false, the trigger function will not be called and caller
|
|
+ * receives NULL tuple as a result. In the case when Before-Row triggers,
|
|
+ * it means the current operations on the tuple should be skipped.
|
|
+ *
|
|
+ * @finfo : FmgrInfo object for the target function
|
|
+ * @tgdata : TriggerData object for the current trigger invokation
|
|
+ */
|
|
+bool pgaceCallFunctionTrigger(FmgrInfo *finfo, TriggerData *tgdata)
|
|
+{
|
|
+ return true;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceCallFunctionFastPath() is called just before executing
|
|
+ * SQL function in the fast path.
|
|
+ *
|
|
+ * @finfo : FmgrInfo object for the target function
|
|
+ */
|
|
+void pgaceCallFunctionFastPath(FmgrInfo *finfo)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgacePreparePlanCheck() is called before foreign key/primary key constraint checks,
|
|
+ * at ri_PlanCheck(). PGACE implementation can return its opaque data for any purpose.
|
|
+ *
|
|
+ * @rel : the target relation in which a constraint is configured
|
|
+ */
|
|
+Datum pgacePreparePlanCheck(Relation rel)
|
|
+{
|
|
+ return (Datum) 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceRestorePlanCheck() is called after foreign key/primary key constraint checks,
|
|
+ * at ri_PlanCheck(). PGACE implementation can use an opaque data generated in the above
|
|
+ * pgacePreparePlanCheck().
|
|
+ *
|
|
+ * @rel : the target relation in which a constraint is configured
|
|
+ * @pgace_saved : an opaque data returned from pgacePreparePlanCheck()
|
|
+ */
|
|
+void pgaceRestorePlanCheck(Relation rel, Datum pgace_saved)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/******************************************************************
|
|
+ * TABLE related hooks
|
|
+ ******************************************************************/
|
|
+
|
|
+/*
|
|
+ * pgaceLockTable() is called when explicit LOCK statement used.
|
|
+ *
|
|
+ * @relid : the target relation id
|
|
+ */
|
|
+void pgaceLockTable(Oid relid)
|
|
+{
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/******************************************************************
|
|
+ * COPY TO/COPY FROM statement hooks
|
|
+ ******************************************************************/
|
|
+
|
|
+/*
|
|
+ * pgaceCopyTable() is called when COPY TO/COPY FROM statement is processed
|
|
+ *
|
|
+ * @rel : the target relation
|
|
+ * @attNumList : the list of attribute numbers
|
|
+ * @isFrom : true, if the given statement is 'COPY FROM'
|
|
+ */
|
|
+void pgaceCopyTable(Relation rel, List *attNumList, bool isFrom) {
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceCopyToTuple() is called to check whether the given tuple should be
|
|
+ * filtered, or not in the process of COPY TO statement.
|
|
+ * If it returns false, the given tuple will be filtered from the result set
|
|
+ *
|
|
+ * @rel : the target relation
|
|
+ * @attNumList : the list of attribute numbers
|
|
+ * @tuple : the target tuple
|
|
+ */
|
|
+bool pgaceCopyToTuple(Relation rel, List *attNumList, HeapTuple tuple) {
|
|
+ return true;
|
|
+}
|
|
+
|
|
+/******************************************************************
|
|
+ * Loadable shared library module hooks
|
|
+ ******************************************************************/
|
|
+
|
|
+/*
|
|
+ * pgaceLoadSharedModule() is called just before load a shared library
|
|
+ * module.
|
|
+ *
|
|
+ * @filename : full path name of the shared library module
|
|
+ */
|
|
+void pgaceLoadSharedModule(const char *filename) {
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/******************************************************************
|
|
+ * Binary Large Object (BLOB) hooks
|
|
+ ******************************************************************/
|
|
+
|
|
+/*
|
|
+ * pgaceLargeObjectGetSecurity() is called when lo_get_security() is executed
|
|
+ * It returns its security attribute.
|
|
+ *
|
|
+ * @tuple : a tuple which is a part of the target largeobject.
|
|
+ */
|
|
+void pgaceLargeObjectGetSecurity(HeapTuple tuple) {
|
|
+ elog(ERROR, "PGACE: There is no guest module.");
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceLargeObjectSetSecurity() is called when lo_set_security() is executed
|
|
+ *
|
|
+ * @tuple : a tuple which is a part of the target largeobject.
|
|
+ * @lo_security : new security attribute specified
|
|
+ */
|
|
+void pgaceLargeObjectSetSecurity(HeapTuple tuple, Oid lo_security) {
|
|
+ elog(ERROR, "PGACE: There is no guest module.");
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceLargeObjectCreate() is called when a new large object is created
|
|
+ *
|
|
+ * @rel : pg_largeobject relation opened with RowExclusiveLock
|
|
+ * @tuple : a new tuple for the new large object
|
|
+ */
|
|
+void pgaceLargeObjectCreate(Relation rel, HeapTuple tuple) {
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceLargeObjectDrop() is called when a large object is dropped once for
|
|
+ * a large object
|
|
+ *
|
|
+ * @rel : pg_largeobject relation opened with RowExclusiveLock
|
|
+ * @tuple : one of the tuples within the target large object
|
|
+ */
|
|
+void pgaceLargeObjectDrop(Relation rel, HeapTuple tuple) {
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceLargeObjectRead is called when they read from a large object
|
|
+ *
|
|
+ * @rel : pg_largeobject relation opened with AccessShareLock
|
|
+ * @tuple : the head tuple within the given large object
|
|
+ */
|
|
+void pgaceLargeObjectRead(Relation rel, HeapTuple tuple) {
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceLargeObjectWrite() is called when they write to a large object
|
|
+ *
|
|
+ * @rel : pg_largeobject relation opened with RowExclusiveLock
|
|
+ * @newtup : the head tuple within the given large object
|
|
+ * @oldtup : the head tuple in older version, if exist
|
|
+ */
|
|
+void pgaceLargeObjectWrite(Relation rel, HeapTuple newtup, HeapTuple oldtup) {
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceLargeObjectTruncate() is called when they truncate a large object.
|
|
+ *
|
|
+ * @rel : pg_largeobject relation opened with RowExclusiveLock
|
|
+ * @loid : large object identifier
|
|
+ * @headtup : the head tuple to be truncated. NULL means this BLOB will be expanded.
|
|
+ */
|
|
+void pgaceLargeObjectTruncate(Relation rel, Oid loid, HeapTuple headtup) {
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceLargeObjectImport() is called when lo_import() is processed
|
|
+ *
|
|
+ * @fd : file descriptor to be inported
|
|
+ */
|
|
+void pgaceLargeObjectImport(int fd) {
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceLargeObjectExport() is called when lo_import() is processed
|
|
+ *
|
|
+ * @fd : file descriptor to be exported
|
|
+ * @loid : large object to be exported
|
|
+ */
|
|
+void pgaceLargeObjectExport(int fd, Oid loid) {
|
|
+ /* do nothing */
|
|
+}
|
|
+
|
|
+/******************************************************************
|
|
+ * Security Label hooks
|
|
+ ******************************************************************/
|
|
+
|
|
+/*
|
|
+ * PGACE implementation can use pgaceSecurityLabelIn() hook to translate
|
|
+ * a input security label from external representation into internal one.
|
|
+ * If no translation is necessary, it has to return @seclabel as is.
|
|
+ *
|
|
+ * @seclabel : security label being input
|
|
+ */
|
|
+char *pgaceSecurityLabelIn(char *seclabel)
|
|
+{
|
|
+ return seclabel;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * PGACE implementation can use pgaceSecurityLabelOut() hook to translate
|
|
+ * a security label in internal representation into external one.
|
|
+ * If no translation is necessary, it has to return @seclabel as is.
|
|
+ *
|
|
+ * @seclabel : security label being output
|
|
+ */
|
|
+char *pgaceSecurityLabelOut(char *seclabel)
|
|
+{
|
|
+ return seclabel;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceSecurityLabelCheckValid() checks whether the @seclabel is valid or not.
|
|
+ * In addition, it can returns an alternative security label, if possible.
|
|
+ *
|
|
+ * It has to return @seclabel as is, if @seclabel is a valid security label.
|
|
+ * It can return an alternative label, if @seclabel is NOT a valid one and
|
|
+ * there is an alternative. In any other case, it returns NULL.
|
|
+ * @seclabel may be NULL. In this case, @seclabel is always invalid.
|
|
+ *
|
|
+ * @seclabel : security label to be checked
|
|
+ */
|
|
+char *pgaceSecurityLabelCheckValid(char *seclabel)
|
|
+{
|
|
+ return seclabel;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceSecurityLabelOfLabel() returns the security attribute of a newly
|
|
+ * generated tuple within pg_security
|
|
+ *
|
|
+ * @new_label : a text representation of security context which will be newly
|
|
+ * inserted into pg_security.
|
|
+ */
|
|
+char *pgaceSecurityLabelOfLabel(char *new_label)
|
|
+{
|
|
+ return pstrdup("unlabeled");
|
|
+}
|
|
+
|
|
+/******************************************************************
|
|
+ * Extended node type hooks
|
|
+ ******************************************************************/
|
|
+
|
|
+/*
|
|
+ * If PGACE implementation requires new node type, a method to copy object.
|
|
+ * pgaceCopyObject() provides a hook to copy new node typed object.
|
|
+ * If a given object (@orig) has a tag extended by PGACE implementation,
|
|
+ * it have to copy and return it.
|
|
+ * If it returns NULL, @orig is not available for the PGACE implementation.
|
|
+ *
|
|
+ * @orig : a object which to copy
|
|
+ */
|
|
+Node *pgaceCopyObject(Node *orig)
|
|
+{
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceOutObject() provides a hook to translate a object to text representation.
|
|
+ * If a given object (@node) has a tag extended by PGACE implementation, it have
|
|
+ * to put a text representation into StringInfo.
|
|
+ * If it returns false, @node is not available for the PGACE implementation.
|
|
+ *
|
|
+ * @str : StringInfo which to put the text representation
|
|
+ * @node : a object that text representation is required
|
|
+ */
|
|
+bool pgaceOutObject(StringInfo str, Node *node)
|
|
+{
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * pgaceReadObject() provides a hook to read a text representation of an object.
|
|
+ * If a given token is a tag extended by PGACE implementation, it have to create
|
|
+ * an object same as original one.
|
|
+ *
|
|
+ * @token : a tag for the object
|
|
+ */
|
|
+void *pgaceReadObject(char *token)
|
|
+{
|
|
+ return NULL;
|
|
+}
|
|
diff -rpNU3 base/src/backend/storage/ipc/ipci.c pgace/src/backend/storage/ipc/ipci.c
|
|
--- base/src/backend/storage/ipc/ipci.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/storage/ipc/ipci.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -25,6 +25,7 @@
|
|
#include "postmaster/autovacuum.h"
|
|
#include "postmaster/bgwriter.h"
|
|
#include "postmaster/postmaster.h"
|
|
+#include "security/pgace.h"
|
|
#include "storage/freespace.h"
|
|
#include "storage/ipc.h"
|
|
#include "storage/pg_shmem.h"
|
|
@@ -117,6 +118,7 @@ CreateSharedMemoryAndSemaphores(bool mak
|
|
#ifdef EXEC_BACKEND
|
|
size = add_size(size, ShmemBackendArraySize());
|
|
#endif
|
|
+ size = add_size(size, pgaceShmemSize());
|
|
|
|
/* freeze the addin request size and include it */
|
|
addin_request_allowed = false;
|
|
diff -rpNU3 base/src/backend/storage/large_object/inv_api.c pgace/src/backend/storage/large_object/inv_api.c
|
|
--- base/src/backend/storage/large_object/inv_api.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/storage/large_object/inv_api.c 2008-02-01 20:22:14.000000000 +0900
|
|
@@ -39,6 +39,7 @@
|
|
#include "catalog/pg_largeobject.h"
|
|
#include "commands/comment.h"
|
|
#include "libpq/libpq-fs.h"
|
|
+#include "security/pgace.h"
|
|
#include "storage/large_object.h"
|
|
#include "utils/fmgroids.h"
|
|
#include "utils/resowner.h"
|
|
@@ -445,6 +446,10 @@ inv_read(LargeObjectDesc *obj_desc, char
|
|
|
|
if (HeapTupleHasNulls(tuple)) /* paranoia */
|
|
elog(ERROR, "null field found in pg_largeobject");
|
|
+
|
|
+ if (!nread)
|
|
+ pgaceLargeObjectRead(lo_heap_r, tuple);
|
|
+
|
|
data = (Form_pg_largeobject) GETSTRUCT(tuple);
|
|
|
|
/*
|
|
@@ -632,6 +637,8 @@ inv_write(LargeObjectDesc *obj_desc, con
|
|
replace[Anum_pg_largeobject_data - 1] = 'r';
|
|
newtup = heap_modifytuple(oldtuple, RelationGetDescr(lo_heap_r),
|
|
values, nulls, replace);
|
|
+ if (nwritten - n == 0)
|
|
+ pgaceLargeObjectWrite(lo_heap_r, newtup, oldtuple);
|
|
simple_heap_update(lo_heap_r, &newtup->t_self, newtup);
|
|
CatalogIndexInsert(indstate, newtup);
|
|
heap_freetuple(newtup);
|
|
@@ -675,6 +682,8 @@ inv_write(LargeObjectDesc *obj_desc, con
|
|
values[Anum_pg_largeobject_pageno - 1] = Int32GetDatum(pageno);
|
|
values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
|
|
newtup = heap_formtuple(lo_heap_r->rd_att, values, nulls);
|
|
+ if (nwritten - n == 0)
|
|
+ pgaceLargeObjectWrite(lo_heap_r, newtup, NULL);
|
|
simple_heap_insert(lo_heap_r, newtup);
|
|
CatalogIndexInsert(indstate, newtup);
|
|
heap_freetuple(newtup);
|
|
@@ -754,6 +763,7 @@ inv_truncate(LargeObjectDesc *obj_desc,
|
|
olddata = (Form_pg_largeobject) GETSTRUCT(oldtuple);
|
|
Assert(olddata->pageno >= pageno);
|
|
}
|
|
+ pgaceLargeObjectTruncate(lo_heap_r, obj_desc->id, oldtuple);
|
|
|
|
/*
|
|
* If we found the page of the truncation point we need to truncate the
|
|
diff -rpNU3 base/src/backend/tcop/fastpath.c pgace/src/backend/tcop/fastpath.c
|
|
--- base/src/backend/tcop/fastpath.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/tcop/fastpath.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -26,6 +26,7 @@
|
|
#include "libpq/pqformat.h"
|
|
#include "mb/pg_wchar.h"
|
|
#include "miscadmin.h"
|
|
+#include "security/pgace.h"
|
|
#include "tcop/fastpath.h"
|
|
#include "tcop/tcopprot.h"
|
|
#include "utils/acl.h"
|
|
@@ -353,6 +354,8 @@ HandleFunctionRequest(StringInfo msgBuf)
|
|
*/
|
|
InitFunctionCallInfoData(fcinfo, &fip->flinfo, 0, NULL, NULL);
|
|
|
|
+ pgaceCallFunctionFastPath(fcinfo.flinfo);
|
|
+
|
|
if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
|
|
rformat = parse_fcall_arguments(msgBuf, fip, &fcinfo);
|
|
else
|
|
diff -rpNU3 base/src/backend/tcop/postgres.c pgace/src/backend/tcop/postgres.c
|
|
--- base/src/backend/tcop/postgres.c 2008-01-28 16:06:37.000000000 +0900
|
|
+++ pgace/src/backend/tcop/postgres.c 2008-01-28 16:14:33.000000000 +0900
|
|
@@ -53,6 +53,7 @@
|
|
#include "parser/parser.h"
|
|
#include "postmaster/autovacuum.h"
|
|
#include "rewrite/rewriteHandler.h"
|
|
+#include "security/pgace.h"
|
|
#include "storage/freespace.h"
|
|
#include "storage/ipc.h"
|
|
#include "storage/proc.h"
|
|
@@ -629,6 +630,9 @@ pg_rewrite_query(Query *query)
|
|
{
|
|
/* don't rewrite utilities, just dump 'em into result list */
|
|
querytree_list = list_make1(query);
|
|
+
|
|
+ /* PGACE rewrite utility query, if necessary */
|
|
+ querytree_list = pgaceProxyQuery(querytree_list);
|
|
}
|
|
else
|
|
{
|
|
diff -rpNU3 base/src/backend/tcop/pquery.c pgace/src/backend/tcop/pquery.c
|
|
--- base/src/backend/tcop/pquery.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/tcop/pquery.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -19,6 +19,7 @@
|
|
#include "commands/prepare.h"
|
|
#include "commands/trigger.h"
|
|
#include "miscadmin.h"
|
|
+#include "security/pgace.h"
|
|
#include "tcop/pquery.h"
|
|
#include "tcop/tcopprot.h"
|
|
#include "tcop/utility.h"
|
|
@@ -455,6 +456,9 @@ PortalStart(Portal portal, ParamListInfo
|
|
AssertArg(PortalIsValid(portal));
|
|
AssertState(portal->status == PORTAL_DEFINED);
|
|
|
|
+ /* PGACE: PosrtalStart hook */
|
|
+ pgacePortalStart(portal);
|
|
+
|
|
/*
|
|
* Set up global portal context pointers.
|
|
*/
|
|
diff -rpNU3 base/src/backend/utils/adt/ri_triggers.c pgace/src/backend/utils/adt/ri_triggers.c
|
|
--- base/src/backend/utils/adt/ri_triggers.c 2008-01-28 16:06:37.000000000 +0900
|
|
+++ pgace/src/backend/utils/adt/ri_triggers.c 2008-01-28 16:14:33.000000000 +0900
|
|
@@ -37,6 +37,7 @@
|
|
#include "parser/parse_coerce.h"
|
|
#include "parser/parse_relation.h"
|
|
#include "miscadmin.h"
|
|
+#include "security/pgace.h"
|
|
#include "utils/acl.h"
|
|
#include "utils/fmgroids.h"
|
|
#include "utils/lsyscache.h"
|
|
@@ -3185,6 +3186,7 @@ ri_PlanCheck(const char *querystr, int n
|
|
Relation query_rel;
|
|
Oid save_userid;
|
|
bool save_secdefcxt;
|
|
+ Datum save_pgace;
|
|
|
|
/*
|
|
* The query is always run against the FK table except when this is an
|
|
@@ -3202,7 +3204,18 @@ ri_PlanCheck(const char *querystr, int n
|
|
SetUserIdAndContext(RelationGetForm(query_rel)->relowner, true);
|
|
|
|
/* Create the plan */
|
|
- qplan = SPI_prepare(querystr, nargs, argtypes);
|
|
+ save_pgace = pgacePreparePlanCheck(query_rel);
|
|
+ PG_TRY();
|
|
+ {
|
|
+ qplan = SPI_prepare(querystr, nargs, argtypes);
|
|
+ }
|
|
+ PG_CATCH();
|
|
+ {
|
|
+ pgaceRestorePlanCheck(query_rel, save_pgace);
|
|
+ PG_RE_THROW();
|
|
+ }
|
|
+ PG_END_TRY();
|
|
+ pgaceRestorePlanCheck(query_rel, save_pgace);
|
|
|
|
if (qplan == NULL)
|
|
elog(ERROR, "SPI_prepare returned %d for %s", SPI_result, querystr);
|
|
diff -rpNU3 base/src/backend/utils/cache/syscache.c pgace/src/backend/utils/cache/syscache.c
|
|
--- base/src/backend/utils/cache/syscache.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/utils/cache/syscache.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -39,6 +39,7 @@
|
|
#include "catalog/pg_opfamily.h"
|
|
#include "catalog/pg_proc.h"
|
|
#include "catalog/pg_rewrite.h"
|
|
+#include "catalog/pg_security.h"
|
|
#include "catalog/pg_statistic.h"
|
|
#include "catalog/pg_ts_config.h"
|
|
#include "catalog/pg_ts_config_map.h"
|
|
@@ -676,7 +677,31 @@ static const struct cachedesc cacheinfo[
|
|
0
|
|
},
|
|
1024
|
|
- }
|
|
+ },
|
|
+ {SecurityRelationId, /*SECURITYOID */
|
|
+ SecurityOidIndexId,
|
|
+ 0,
|
|
+ 1,
|
|
+ {
|
|
+ ObjectIdAttributeNumber,
|
|
+ 0,
|
|
+ 0,
|
|
+ 0
|
|
+ },
|
|
+ 128
|
|
+ },
|
|
+ {SecurityRelationId, /* SECURITYLABEL */
|
|
+ SecuritySeclabelIndexId,
|
|
+ 0,
|
|
+ 1,
|
|
+ {
|
|
+ Anum_pg_security_seclabel,
|
|
+ 0,
|
|
+ 0,
|
|
+ 0
|
|
+ },
|
|
+ 128
|
|
+ },
|
|
};
|
|
|
|
static CatCache *SysCache[
|
|
diff -rpNU3 base/src/backend/utils/fmgr/dfmgr.c pgace/src/backend/utils/fmgr/dfmgr.c
|
|
--- base/src/backend/utils/fmgr/dfmgr.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/utils/fmgr/dfmgr.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -22,6 +22,7 @@
|
|
#include "port/dynloader/win32.h"
|
|
#endif
|
|
#include "miscadmin.h"
|
|
+#include "security/pgace.h"
|
|
#include "utils/dynamic_loader.h"
|
|
#include "utils/hsearch.h"
|
|
|
|
@@ -73,7 +74,7 @@ char *Dynamic_library_path;
|
|
static void *internal_load_library(const char *libname);
|
|
static void internal_unload_library(const char *libname);
|
|
static bool file_exists(const char *name);
|
|
-static char *expand_dynamic_library_name(const char *name);
|
|
+//static char *expand_dynamic_library_name(const char *name);
|
|
static void check_restricted_library_name(const char *name);
|
|
static char *substitute_libpath_macro(const char *name);
|
|
static char *find_in_dynamic_libpath(const char *basename);
|
|
@@ -106,6 +107,9 @@ load_external_function(char *filename, c
|
|
/* Expand the possibly-abbreviated filename to an exact path name */
|
|
fullname = expand_dynamic_library_name(filename);
|
|
|
|
+ /* PGACE: check whether the module can be loaded, or not */
|
|
+ pgaceLoadSharedModule(fullname);
|
|
+
|
|
/* Load the shared library, unless we already did */
|
|
lib_handle = internal_load_library(fullname);
|
|
|
|
@@ -146,6 +150,9 @@ load_file(const char *filename, bool res
|
|
/* Expand the possibly-abbreviated filename to an exact path name */
|
|
fullname = expand_dynamic_library_name(filename);
|
|
|
|
+ /* PGACE: check whether the module can be loaded, or not */
|
|
+ pgaceLoadSharedModule(fullname);
|
|
+
|
|
/* Unload the library if currently loaded */
|
|
internal_unload_library(fullname);
|
|
|
|
@@ -395,7 +402,7 @@ file_exists(const char *name)
|
|
*
|
|
* The result will always be freshly palloc'd.
|
|
*/
|
|
-static char *
|
|
+char *
|
|
expand_dynamic_library_name(const char *name)
|
|
{
|
|
bool have_slash;
|
|
diff -rpNU3 base/src/backend/utils/init/postinit.c pgace/src/backend/utils/init/postinit.c
|
|
--- base/src/backend/utils/init/postinit.c 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/backend/utils/init/postinit.c 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -31,6 +31,7 @@
|
|
#include "pgstat.h"
|
|
#include "postmaster/autovacuum.h"
|
|
#include "postmaster/postmaster.h"
|
|
+#include "security/pgace.h"
|
|
#include "storage/backendid.h"
|
|
#include "storage/fd.h"
|
|
#include "storage/ipc.h"
|
|
@@ -601,6 +602,9 @@ InitPostgres(const char *in_dbname, Oid
|
|
if (!bootstrap)
|
|
pgstat_bestart();
|
|
|
|
+ /* PGACE: initialize access control extension facility */
|
|
+ pgaceInitialize(bootstrap);
|
|
+
|
|
/* close the transaction we started above */
|
|
if (!bootstrap)
|
|
CommitTransactionCommand();
|
|
diff -rpNU3 base/src/backend/utils/misc/guc.c pgace/src/backend/utils/misc/guc.c
|
|
--- base/src/backend/utils/misc/guc.c 2008-02-03 01:11:28.000000000 +0900
|
|
+++ pgace/src/backend/utils/misc/guc.c 2008-02-03 01:18:48.000000000 +0900
|
|
@@ -54,6 +54,7 @@
|
|
#include "postmaster/postmaster.h"
|
|
#include "postmaster/syslogger.h"
|
|
#include "postmaster/walwriter.h"
|
|
+#include "security/pgace.h"
|
|
#include "storage/fd.h"
|
|
#include "storage/freespace.h"
|
|
#include "tcop/tcopprot.h"
|
|
@@ -268,6 +269,7 @@ static int max_index_keys;
|
|
static int max_identifier_length;
|
|
static int block_size;
|
|
static bool integer_datetimes;
|
|
+static char *security_sysattr_name;
|
|
|
|
/* should be static, but commands/variable.c needs to get at these */
|
|
char *role_string;
|
|
@@ -2460,6 +2462,20 @@ static struct config_string ConfigureNam
|
|
},
|
|
#endif /* USE_SSL */
|
|
|
|
+ {
|
|
+ {"security_sysattr_name", PGC_INTERNAL, PRESET_OPTIONS,
|
|
+ gettext_noop("Shows the name of security attribute system column"),
|
|
+ NULL,
|
|
+ GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
|
+ },
|
|
+ &security_sysattr_name,
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+ SECURITY_SYSATTR_NAME, NULL, NULL,
|
|
+#else
|
|
+ "undefined", NULL, NULL,
|
|
+#endif
|
|
+ },
|
|
+
|
|
/* End-of-list marker */
|
|
{
|
|
{NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL
|
|
@@ -3300,6 +3316,8 @@ ResetAllOptions(void)
|
|
{
|
|
int i;
|
|
|
|
+ pgaceSetDatabaseParam("all", NULL);
|
|
+
|
|
for (i = 0; i < num_guc_variables; i++)
|
|
{
|
|
struct config_generic *gconf = guc_variables[i];
|
|
@@ -4982,6 +5000,7 @@ ExecSetVariableStmt(VariableSetStmt *stm
|
|
{
|
|
case VAR_SET_VALUE:
|
|
case VAR_SET_CURRENT:
|
|
+ pgaceSetDatabaseParam(stmt->name, ExtractSetVariableArgs(stmt));
|
|
set_config_option(stmt->name,
|
|
ExtractSetVariableArgs(stmt),
|
|
(superuser() ? PGC_SUSET : PGC_USERSET),
|
|
@@ -5039,6 +5058,7 @@ ExecSetVariableStmt(VariableSetStmt *stm
|
|
break;
|
|
case VAR_SET_DEFAULT:
|
|
case VAR_RESET:
|
|
+ pgaceSetDatabaseParam(stmt->name, NULL);
|
|
set_config_option(stmt->name,
|
|
NULL,
|
|
(superuser() ? PGC_SUSET : PGC_USERSET),
|
|
@@ -5367,6 +5387,9 @@ EmitWarningsOnPlaceholders(const char *c
|
|
void
|
|
GetPGVariable(const char *name, DestReceiver *dest)
|
|
{
|
|
+ /* PGACE: check get param permission */
|
|
+ pgaceGetDatabaseParam(name);
|
|
+
|
|
if (guc_name_compare(name, "all") == 0)
|
|
ShowAllGUCConfig(dest);
|
|
else
|
|
diff -rpNU3 base/src/include/access/htup.h pgace/src/include/access/htup.h
|
|
--- base/src/include/access/htup.h 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/include/access/htup.h 2008-01-10 12:42:25.000000000 +0900
|
|
@@ -161,7 +161,7 @@ typedef HeapTupleHeaderData *HeapTupleHe
|
|
#define HEAP_HASVARWIDTH 0x0002 /* has variable-width attribute(s) */
|
|
#define HEAP_HASEXTERNAL 0x0004 /* has external stored attribute(s) */
|
|
#define HEAP_HASOID 0x0008 /* has an object-id field */
|
|
-/* bit 0x0010 is available */
|
|
+#define HEAP_HASSECURITY 0x0010 /* has an security attribute field */
|
|
#define HEAP_COMBOCID 0x0020 /* t_cid is a combo cid */
|
|
#define HEAP_XMAX_EXCL_LOCK 0x0040 /* xmax is exclusive locker */
|
|
#define HEAP_XMAX_SHARED_LOCK 0x0080 /* xmax is shared locker */
|
|
@@ -347,6 +347,28 @@ do { \
|
|
(tup)->t_infomask2 = ((tup)->t_infomask2 & ~HEAP_NATTS_MASK) | (natts) \
|
|
)
|
|
|
|
+#define HeapTupleHeaderGetSecurity(tup) \
|
|
+ ( \
|
|
+ ((tup)->t_infomask & HEAP_HASSECURITY) \
|
|
+ ? (*((Oid *)((char *)(tup) + (tup)->t_hoff \
|
|
+ - (((tup)->t_infomask & HEAP_HASOID) ? sizeof(Oid) : 0) \
|
|
+ - sizeof(Oid)))) \
|
|
+ : InvalidOid \
|
|
+ )
|
|
+
|
|
+#define HeapTupleHeaderSetSecurity(tup, security) \
|
|
+ do { \
|
|
+ Assert((tup)->t_infomask & HEAP_HASSECURITY); \
|
|
+ *((Oid *)((char *)(tup) + (tup)->t_hoff \
|
|
+ - (((tup)->t_infomask & HEAP_HASOID) ? sizeof(Oid) : 0) \
|
|
+ - sizeof(Oid))) = (security); \
|
|
+ } while(0)
|
|
+
|
|
+#define HeapTupleGetSecurity(tuple) \
|
|
+ HeapTupleHeaderGetSecurity((tuple)->t_data)
|
|
+
|
|
+#define HeapTupleSetSecurity(tuple, security) \
|
|
+ HeapTupleHeaderSetSecurity((tuple)->t_data, (security))
|
|
|
|
/*
|
|
* BITMAPLEN(NATTS) -
|
|
@@ -402,7 +424,12 @@ do { \
|
|
#define MaxTransactionIdAttributeNumber (-5)
|
|
#define MaxCommandIdAttributeNumber (-6)
|
|
#define TableOidAttributeNumber (-7)
|
|
+#ifdef SECURITY_SYSATTR_NAME
|
|
+#define SecurityAttributeNumber (-8)
|
|
+#define FirstLowInvalidHeapAttributeNumber (-9)
|
|
+#else
|
|
#define FirstLowInvalidHeapAttributeNumber (-8)
|
|
+#endif
|
|
|
|
|
|
/*
|
|
diff -rpNU3 base/src/include/catalog/heap.h pgace/src/include/catalog/heap.h
|
|
--- base/src/include/catalog/heap.h 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/include/catalog/heap.h 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -52,7 +52,8 @@ extern Oid heap_create_with_catalog(cons
|
|
int oidinhcount,
|
|
OnCommitAction oncommit,
|
|
Datum reloptions,
|
|
- bool allow_system_table_mods);
|
|
+ bool allow_system_table_mods,
|
|
+ List *pgace_attr_list);
|
|
|
|
extern void heap_drop_with_catalog(Oid relid);
|
|
|
|
@@ -65,7 +66,8 @@ extern List *heap_truncate_find_FKs(List
|
|
extern void InsertPgClassTuple(Relation pg_class_desc,
|
|
Relation new_rel_desc,
|
|
Oid new_rel_oid,
|
|
- Datum reloptions);
|
|
+ Datum reloptions,
|
|
+ List *pgace_attr_list);
|
|
|
|
extern List *AddRelationRawConstraints(Relation rel,
|
|
List *rawColDefaults,
|
|
diff -rpNU3 base/src/include/catalog/indexing.h pgace/src/include/catalog/indexing.h
|
|
--- base/src/include/catalog/indexing.h 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/include/catalog/indexing.h 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -252,6 +252,11 @@ DECLARE_UNIQUE_INDEX(pg_type_oid_index,
|
|
DECLARE_UNIQUE_INDEX(pg_type_typname_nsp_index, 2704, on pg_type using btree(typname name_ops, typnamespace oid_ops));
|
|
#define TypeNameNspIndexId 2704
|
|
|
|
+DECLARE_UNIQUE_INDEX(pg_security_oid_index, 3401, on pg_security using btree(oid oid_ops));
|
|
+#define SecurityOidIndexId 3401
|
|
+DECLARE_UNIQUE_INDEX(pg_security_seclabel_index, 3402, on pg_security using btree(seclabel text_ops));
|
|
+#define SecuritySeclabelIndexId 3402
|
|
+
|
|
/* last step of initialization script: build the indexes declared above */
|
|
BUILD_INDICES
|
|
|
|
diff -rpNU3 base/src/include/catalog/pg_attribute.h pgace/src/include/catalog/pg_attribute.h
|
|
--- base/src/include/catalog/pg_attribute.h 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/include/catalog/pg_attribute.h 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -282,6 +282,7 @@ DATA(insert ( 1247 cmin 29 0 4 -4 0
|
|
DATA(insert ( 1247 xmax 28 0 4 -5 0 -1 -1 t p i t f f t 0));
|
|
DATA(insert ( 1247 cmax 29 0 4 -6 0 -1 -1 t p i t f f t 0));
|
|
DATA(insert ( 1247 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0));
|
|
+DATA(insert ( 1247 SECURITY_SYSATTR_NAME 3403 0 4 -8 0 -1 -1 t p i t f f t 0));
|
|
|
|
/* ----------------
|
|
* pg_proc
|
|
@@ -338,6 +339,7 @@ DATA(insert ( 1255 cmin 29 0 4 -4 0
|
|
DATA(insert ( 1255 xmax 28 0 4 -5 0 -1 -1 t p i t f f t 0));
|
|
DATA(insert ( 1255 cmax 29 0 4 -6 0 -1 -1 t p i t f f t 0));
|
|
DATA(insert ( 1255 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0));
|
|
+DATA(insert ( 1255 SECURITY_SYSATTR_NAME 3403 0 4 -8 0 -1 -1 t p i t f f t 0));
|
|
|
|
/* ----------------
|
|
* pg_attribute
|
|
@@ -386,6 +388,7 @@ DATA(insert ( 1249 cmin 29 0 4 -4 0
|
|
DATA(insert ( 1249 xmax 28 0 4 -5 0 -1 -1 t p i t f f t 0));
|
|
DATA(insert ( 1249 cmax 29 0 4 -6 0 -1 -1 t p i t f f t 0));
|
|
DATA(insert ( 1249 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0));
|
|
+DATA(insert ( 1249 SECURITY_SYSATTR_NAME 3403 0 4 -8 0 -1 -1 t p i t f f t 0));
|
|
|
|
/* ----------------
|
|
* pg_class
|
|
@@ -454,6 +457,7 @@ DATA(insert ( 1259 cmin 29 0 4 -4 0
|
|
DATA(insert ( 1259 xmax 28 0 4 -5 0 -1 -1 t p i t f f t 0));
|
|
DATA(insert ( 1259 cmax 29 0 4 -6 0 -1 -1 t p i t f f t 0));
|
|
DATA(insert ( 1259 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0));
|
|
+DATA(insert ( 1259 SECURITY_SYSATTR_NAME 3403 0 4 -8 0 -1 -1 t p i t f f t 0));
|
|
|
|
/* ----------------
|
|
* pg_index
|
|
diff -rpNU3 base/src/include/catalog/pg_cast.h pgace/src/include/catalog/pg_cast.h
|
|
--- base/src/include/catalog/pg_cast.h 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/include/catalog/pg_cast.h 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -331,4 +331,10 @@ DATA(insert ( 1560 1560 1685 i ));
|
|
DATA(insert ( 1562 1562 1687 i ));
|
|
DATA(insert ( 1700 1700 1703 i ));
|
|
|
|
+/*
|
|
+ * Security Label to/from text representation
|
|
+ */
|
|
+DATA(insert (25 3403 3408 i));
|
|
+DATA(insert (3403 25 3409 i));
|
|
+
|
|
#endif /* PG_CAST_H */
|
|
diff -rpNU3 base/src/include/catalog/pg_proc.h pgace/src/include/catalog/pg_proc.h
|
|
--- base/src/include/catalog/pg_proc.h 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/include/catalog/pg_proc.h 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -4113,6 +4113,16 @@ DESCR("I/O");
|
|
DATA(insert OID = 2963 ( uuid_hash PGNSP PGUID 12 1 0 f f t f i 1 23 "2950" _null_ _null_ _null_ uuid_hash - _null_ _null_ ));
|
|
DESCR("hash");
|
|
|
|
+/* PostgreSQL Access Control Extension related functions */
|
|
+DATA(insert OID = 3404 ( security_label_in PGNSP PGUID 12 1 0 f f t f i 1 3403 "2275" _null_ _null_ _null_ security_label_in - _null_ _null_ ));
|
|
+DATA(insert OID = 3405 ( security_label_out PGNSP PGUID 12 1 0 f f t f i 1 2275 "3403" _null_ _null_ _null_ security_label_out - _null_ _null_ ));
|
|
+DATA(insert OID = 3406 ( security_label_raw_in PGNSP PGUID 12 1 0 f f t f i 1 3403 "2275" _null_ _null_ _null_ security_label_raw_in - _null_ _null_ ));
|
|
+DATA(insert OID = 3407 ( security_label_raw_out PGNSP PGUID 12 1 0 f f t f i 1 2275 "3403" _null_ _null_ _null_ security_label_raw_out - _null_ _null_ ));
|
|
+DATA(insert OID = 3408 ( text_to_security_label PGNSP PGUID 12 1 0 f f t f i 1 3403 "25" _null_ _null_ _null_ text_to_security_label - _null_ _null_ ));
|
|
+DATA(insert OID = 3409 ( security_label_to_text PGNSP PGUID 12 1 0 f f t f i 1 25 "3403" _null_ _null_ _null_ security_label_to_text - _null_ _null_ ));
|
|
+DATA(insert OID = 3410 ( lo_get_security PGNSP PGUID 12 1 0 f f t f v 1 3403 "26" _null_ _null_ _null_ lo_get_security - _null_ _null_ ));
|
|
+DATA(insert OID = 3411 ( lo_set_security PGNSP PGUID 12 1 0 f f t f v 2 16 "26 3403" _null_ _null_ _null_ lo_set_security - _null_ _null_ ));
|
|
+
|
|
/* enum related procs */
|
|
DATA(insert OID = 3504 ( anyenum_in PGNSP PGUID 12 1 0 f f t f i 1 3500 "2275" _null_ _null_ _null_ anyenum_in - _null_ _null_ ));
|
|
DESCR("I/O");
|
|
@@ -4460,7 +4470,8 @@ extern Oid ProcedureCreate(const char *p
|
|
Datum parameterNames,
|
|
Datum proconfig,
|
|
float4 procost,
|
|
- float4 prorows);
|
|
+ float4 prorows,
|
|
+ void *pgace_item);
|
|
|
|
extern bool function_parse_error_transpose(const char *prosrc);
|
|
|
|
diff -rpNU3 base/src/include/catalog/pg_security.h pgace/src/include/catalog/pg_security.h
|
|
--- base/src/include/catalog/pg_security.h 1970-01-01 09:00:00.000000000 +0900
|
|
+++ pgace/src/include/catalog/pg_security.h 2007-09-21 01:08:03.000000000 +0900
|
|
@@ -0,0 +1,31 @@
|
|
+/*
|
|
+ * src/include/catalog/pg_security.h
|
|
+ * Definition of the security label relation (pg_security)
|
|
+ *
|
|
+ * Copyright (c) 2006 - 2007 KaiGai Kohei <kaigai@kaigai.gr.jp>
|
|
+ */
|
|
+#ifndef PG_SECURITY_H
|
|
+#define PG_SECURITY_H
|
|
+
|
|
+#define SecurityRelationId 3400
|
|
+
|
|
+CATALOG(pg_security,3400) BKI_SHARED_RELATION
|
|
+{
|
|
+ text seclabel; /* text representation of security label */
|
|
+} FormData_pg_security;
|
|
+
|
|
+/* ----------------
|
|
+ * Form_pg_security corresponds to a pointer to a tuple with
|
|
+ * the format of pg_security relation.
|
|
+ * ----------------
|
|
+ */
|
|
+typedef FormData_pg_security *Form_pg_security;
|
|
+
|
|
+/* ----------------
|
|
+ * compiler constants for pg_selinux
|
|
+ * ----------------
|
|
+ */
|
|
+#define Natts_pg_security 1
|
|
+#define Anum_pg_security_seclabel 1
|
|
+
|
|
+#endif /* PG_SELINUX_H */
|
|
diff -rpNU3 base/src/include/catalog/pg_type.h pgace/src/include/catalog/pg_type.h
|
|
--- base/src/include/catalog/pg_type.h 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/include/catalog/pg_type.h 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -611,6 +611,9 @@ DATA(insert OID = 2283 ( anyelement PGN
|
|
#define ANYELEMENTOID 2283
|
|
DATA(insert OID = 2776 ( anynonarray PGNSP PGUID 4 t p t \054 0 0 0 anynonarray_in anynonarray_out - - - - - i p f 0 -1 0 _null_ _null_ ));
|
|
#define ANYNONARRAYOID 2776
|
|
+DATA(insert OID = 3403 ( security_label PGNSP PGUID 4 t b t \054 0 0 0 security_label_in security_label_out - - - - - i p f 0 -1 0 _null_ _null_ ));
|
|
+DESCR("Security Label Identifier for PGACE");
|
|
+#define SECLABELOID 3403
|
|
DATA(insert OID = 3500 ( anyenum PGNSP PGUID 4 t p t \054 0 0 0 anyenum_in anyenum_out - - - - - i p f 0 -1 0 _null_ _null_ ));
|
|
#define ANYENUMOID 3500
|
|
|
|
diff -rpNU3 base/src/include/executor/tuptable.h pgace/src/include/executor/tuptable.h
|
|
--- base/src/include/executor/tuptable.h 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/include/executor/tuptable.h 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -118,6 +118,7 @@ typedef struct TupleTableSlot
|
|
MinimalTuple tts_mintuple; /* set if it's a minimal tuple, else NULL */
|
|
HeapTupleData tts_minhdr; /* workspace if it's a minimal tuple */
|
|
long tts_off; /* saved state for slot_deform_tuple */
|
|
+ Oid tts_security; /* pgace security system attribute */
|
|
} TupleTableSlot;
|
|
|
|
/*
|
|
@@ -139,6 +140,12 @@ typedef TupleTableData *TupleTable;
|
|
#define TupIsNull(slot) \
|
|
((slot) == NULL || (slot)->tts_isempty)
|
|
|
|
+/*
|
|
+ * PGACE: HeapTupleStoreSecurityFromSlot
|
|
+ */
|
|
+#define HeapTupleStoreSecurityFromSlot(tuple, slot) \
|
|
+ HeapTupleSetSecurity((tuple), (slot)->tts_security)
|
|
+
|
|
/* in executor/execTuples.c */
|
|
extern TupleTable ExecCreateTupleTable(int tableSize);
|
|
extern void ExecDropTupleTable(TupleTable table, bool shouldFree);
|
|
diff -rpNU3 base/src/include/fmgr.h pgace/src/include/fmgr.h
|
|
--- base/src/include/fmgr.h 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/include/fmgr.h 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -52,6 +52,9 @@ typedef struct FmgrInfo
|
|
void *fn_extra; /* extra space for use by handler */
|
|
MemoryContext fn_mcxt; /* memory context to store fn_extra in */
|
|
fmNodePtr fn_expr; /* expression parse tree for call, or NULL */
|
|
+
|
|
+ PGFunction fn_pgace_addr; /* PGACE opaque addr field */
|
|
+ Datum fn_pgace_data; /* PGACE opaque data field */
|
|
} FmgrInfo;
|
|
|
|
/*
|
|
@@ -511,6 +514,7 @@ extern Oid get_call_expr_argtype(fmNodeP
|
|
*/
|
|
extern char *Dynamic_library_path;
|
|
|
|
+extern char *expand_dynamic_library_name(const char *name);
|
|
extern PGFunction load_external_function(char *filename, char *funcname,
|
|
bool signalNotFound, void **filehandle);
|
|
extern PGFunction lookup_external_function(void *filehandle, char *funcname);
|
|
diff -rpNU3 base/src/include/libpq/be-fsstubs.h pgace/src/include/libpq/be-fsstubs.h
|
|
--- base/src/include/libpq/be-fsstubs.h 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/include/libpq/be-fsstubs.h 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -36,6 +36,9 @@ extern Datum lo_tell(PG_FUNCTION_ARGS);
|
|
extern Datum lo_unlink(PG_FUNCTION_ARGS);
|
|
extern Datum lo_truncate(PG_FUNCTION_ARGS);
|
|
|
|
+extern Datum lo_get_security(PG_FUNCTION_ARGS);
|
|
+extern Datum lo_set_security(PG_FUNCTION_ARGS);
|
|
+
|
|
/*
|
|
* These are not fmgr-callable, but are available to C code.
|
|
* Probably these should have had the underscore-free names,
|
|
diff -rpNU3 base/src/include/nodes/parsenodes.h pgace/src/include/nodes/parsenodes.h
|
|
--- base/src/include/nodes/parsenodes.h 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/include/nodes/parsenodes.h 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -131,6 +131,7 @@ typedef struct Query
|
|
|
|
Node *setOperations; /* set-operation tree if this is top level of
|
|
* a UNION/INTERSECT/EXCEPT query */
|
|
+ Node *pgaceItem; /* PGACE: an opaque item for security purpose */
|
|
} Query;
|
|
|
|
|
|
@@ -391,6 +392,7 @@ typedef struct ColumnDef
|
|
Node *raw_default; /* default value (untransformed parse tree) */
|
|
char *cooked_default; /* nodeToString representation */
|
|
List *constraints; /* other constraints on column */
|
|
+ Node *pgaceItem; /* PGACE: security attribute */
|
|
} ColumnDef;
|
|
|
|
/*
|
|
@@ -917,7 +919,8 @@ typedef enum AlterTableType
|
|
AT_EnableReplicaRule, /* ENABLE REPLICA RULE name */
|
|
AT_DisableRule, /* DISABLE RULE name */
|
|
AT_AddInherit, /* INHERIT parent */
|
|
- AT_DropInherit /* NO INHERIT parent */
|
|
+ AT_DropInherit, /* NO INHERIT parent */
|
|
+ AT_SetSecurityLabel, /* PGACE: set security label */
|
|
} AlterTableType;
|
|
|
|
typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */
|
|
@@ -1108,6 +1111,7 @@ typedef struct CreateStmt
|
|
List *options; /* options from WITH clause */
|
|
OnCommitAction oncommit; /* what do we do at COMMIT? */
|
|
char *tablespacename; /* table space to use, or NULL */
|
|
+ Node *pgaceItem; /* PGACE: security attribute */
|
|
} CreateStmt;
|
|
|
|
/* ----------
|
|
diff -rpNU3 base/src/include/nodes/plannodes.h pgace/src/include/nodes/plannodes.h
|
|
--- base/src/include/nodes/plannodes.h 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/include/nodes/plannodes.h 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -73,6 +73,8 @@ typedef struct PlannedStmt
|
|
List *relationOids; /* OIDs of relations the plan depends on */
|
|
|
|
int nParamExec; /* number of PARAM_EXEC Params used */
|
|
+
|
|
+ Node *pgaceItem; /* PGACE: an opaque item for security purpose */
|
|
} PlannedStmt;
|
|
|
|
/* macro for fetching the Plan associated with a SubPlan node */
|
|
diff -rpNU3 base/src/include/pg_config.h.in pgace/src/include/pg_config.h.in
|
|
--- base/src/include/pg_config.h.in 2008-01-28 16:06:37.000000000 +0900
|
|
+++ pgace/src/include/pg_config.h.in 2008-01-28 16:14:33.000000000 +0900
|
|
@@ -637,6 +637,9 @@
|
|
your system. */
|
|
#undef PTHREAD_CREATE_JOINABLE
|
|
|
|
+/* The name of security attribute. */
|
|
+#undef SECURITY_SYSATTR_NAME
|
|
+
|
|
/* The size of a `size_t', as computed by sizeof. */
|
|
#undef SIZEOF_SIZE_T
|
|
|
|
diff -rpNU3 base/src/include/security/pgace.h pgace/src/include/security/pgace.h
|
|
--- base/src/include/security/pgace.h 1970-01-01 09:00:00.000000000 +0900
|
|
+++ pgace/src/include/security/pgace.h 2008-02-01 20:22:14.000000000 +0900
|
|
@@ -0,0 +1,147 @@
|
|
+/*
|
|
+ * include/security/pgace.h
|
|
+ * headers for PostgreSQL Access Control Extensions (PGACE)
|
|
+ * Copyright 2007 KaiGai Kohei <kaigai@kaigai.gr.jp>
|
|
+ */
|
|
+#ifndef PGACE_H
|
|
+#define PGACE_H
|
|
+
|
|
+#include "access/htup.h"
|
|
+#include "commands/trigger.h"
|
|
+#include "executor/execdesc.h"
|
|
+#include "nodes/parsenodes.h"
|
|
+#include "utils/builtins.h"
|
|
+#include "utils/rel.h"
|
|
+
|
|
+/*
|
|
+ * SECURITY_SYSATTR_NAME is the name of system column name
|
|
+ * for security attribute, defined in pg_config.h
|
|
+ * If it is not defined, security attribute support is disabled
|
|
+ *
|
|
+ * see, src/include/pg_config.h
|
|
+ */
|
|
+
|
|
+/******************************************************************
|
|
+ * Initialize / Finalize related hooks
|
|
+ ******************************************************************/
|
|
+extern Size pgaceShmemSize(void);
|
|
+extern void pgaceInitialize(bool is_bootstrap);
|
|
+extern bool pgaceInitializePostmaster(void);
|
|
+extern void pgaceFinalizePostmaster(void);
|
|
+
|
|
+/******************************************************************
|
|
+ * SQL proxy hooks
|
|
+ ******************************************************************/
|
|
+extern List *pgaceProxyQuery(List *queryList);
|
|
+extern void pgacePortalStart(Portal portal);
|
|
+extern void pgaceExecutorStart(QueryDesc *queryDesc, int eflags);
|
|
+
|
|
+/******************************************************************
|
|
+ * HeapTuple modification hooks
|
|
+ ******************************************************************/
|
|
+extern bool pgaceHeapTupleInsert(Relation rel, HeapTuple tuple,
|
|
+ bool is_internal, bool with_returning);
|
|
+extern bool pgaceHeapTupleUpdate(Relation rel, ItemPointer otid, HeapTuple newtup,
|
|
+ bool is_internal, bool with_returning);
|
|
+extern bool pgaceHeapTupleDelete(Relation rel, ItemPointer otid,
|
|
+ bool is_internal, bool with_returning);
|
|
+
|
|
+/******************************************************************
|
|
+ * Extended SQL statement hooks
|
|
+ ******************************************************************/
|
|
+extern DefElem *pgaceGramSecurityItem(char *defname, char *value);
|
|
+extern bool pgaceIsGramSecurityItem(DefElem *defel);
|
|
+extern void pgaceGramCreateRelation(Relation rel, HeapTuple tuple, DefElem *defel);
|
|
+extern void pgaceGramCreateAttribute(Relation rel, HeapTuple tuple, DefElem *defel);
|
|
+extern void pgaceGramAlterRelation(Relation rel, HeapTuple tuple, DefElem *defel);
|
|
+extern void pgaceGramAlterAttribute(Relation rel, HeapTuple tuple, DefElem *defel);
|
|
+extern void pgaceGramCreateDatabase(Relation rel, HeapTuple tuple, DefElem *defel);
|
|
+extern void pgaceGramAlterDatabase(Relation rel, HeapTuple tuple, DefElem *defel);
|
|
+extern void pgaceGramCreateFunction(Relation rel, HeapTuple tuple, DefElem *defel);
|
|
+extern void pgaceGramAlterFunction(Relation rel, HeapTuple tuple, DefElem *defel);
|
|
+
|
|
+/******************************************************************
|
|
+ * DATABASE related hooks
|
|
+ ******************************************************************/
|
|
+extern void pgaceSetDatabaseParam(const char *name, char *argstring);
|
|
+extern void pgaceGetDatabaseParam(const char *name);
|
|
+
|
|
+/******************************************************************
|
|
+ * FUNCTION related hooks
|
|
+ ******************************************************************/
|
|
+extern void pgaceCallFunction(FmgrInfo *finfo);
|
|
+extern bool pgaceCallFunctionTrigger(FmgrInfo *finfo, TriggerData *tgdata);
|
|
+extern void pgaceCallFunctionFastPath(FmgrInfo *finfo);
|
|
+extern Datum pgacePreparePlanCheck(Relation rel);
|
|
+extern void pgaceRestorePlanCheck(Relation rel, Datum pgace_saved);
|
|
+
|
|
+/******************************************************************
|
|
+ * TABLE related hooks
|
|
+ ******************************************************************/
|
|
+extern void pgaceLockTable(Oid relid);
|
|
+
|
|
+/******************************************************************
|
|
+ * COPY TO/COPY FROM statement hooks
|
|
+ ******************************************************************/
|
|
+extern void pgaceCopyTable(Relation rel, List *attNumList, bool isFrom);
|
|
+extern bool pgaceCopyToTuple(Relation rel, List *attNumList, HeapTuple tuple);
|
|
+
|
|
+/******************************************************************
|
|
+ * Loadable shared library module hooks
|
|
+ ******************************************************************/
|
|
+extern void pgaceLoadSharedModule(const char *filename);
|
|
+
|
|
+/******************************************************************
|
|
+ * Binary Large Object (BLOB) hooks
|
|
+ ******************************************************************/
|
|
+extern void pgaceLargeObjectGetSecurity(HeapTuple tuple);
|
|
+extern void pgaceLargeObjectSetSecurity(HeapTuple tuple, Oid lo_security);
|
|
+extern void pgaceLargeObjectCreate(Relation rel, HeapTuple tuple);
|
|
+extern void pgaceLargeObjectDrop(Relation rel, HeapTuple tuple);
|
|
+extern void pgaceLargeObjectRead(Relation rel, HeapTuple tuple);
|
|
+extern void pgaceLargeObjectWrite(Relation rel, HeapTuple newtup, HeapTuple oldtup);
|
|
+extern void pgaceLargeObjectTruncate(Relation rel, Oid loid, HeapTuple headtup);
|
|
+extern void pgaceLargeObjectImport(int fd);
|
|
+extern void pgaceLargeObjectExport(int fd, Oid loid);
|
|
+
|
|
+/******************************************************************
|
|
+ * Security Label hooks
|
|
+ ******************************************************************/
|
|
+extern char *pgaceSecurityLabelIn(char *seclabel);
|
|
+extern char *pgaceSecurityLabelOut(char *seclabel);
|
|
+extern char *pgaceSecurityLabelCheckValid(char *seclabel);
|
|
+extern char *pgaceSecurityLabelOfLabel(char *new_label);
|
|
+
|
|
+/******************************************************************
|
|
+ * Extended node type hooks
|
|
+ ******************************************************************/
|
|
+extern Node *pgaceCopyObject(Node *orig);
|
|
+extern bool pgaceOutObject(StringInfo str, Node *node);
|
|
+extern void *pgaceReadObject(char *token);
|
|
+
|
|
+/******************************************************************
|
|
+ * PGACE common facilities (not a hooks)
|
|
+ ******************************************************************/
|
|
+/* Security attribute system column support */
|
|
+extern bool pgaceIsSecuritySystemColumn(int attrno);
|
|
+extern void pgaceFetchSecurityAttribute(JunkFilter *junkfilter, TupleTableSlot *slot, Oid *tts_security);
|
|
+extern void pgaceTransformSelectStmt(List *targetList);
|
|
+extern void pgaceTransformInsertStmt(List **p_icolumns, List **p_attrnos, List *targetList);
|
|
+
|
|
+/* Extended SQL statements related */
|
|
+extern List *pgaceRelationAttrList(CreateStmt *stmt);
|
|
+extern void pgaceCreateRelationCommon(Relation rel, HeapTuple tuple, List *pgace_attr_list);
|
|
+extern void pgaceCreateAttributeCommon(Relation rel, HeapTuple tuple, List *pgace_attr_list);
|
|
+extern void pgaceAlterRelationCommon(Relation rel, AlterTableCmd *cmd);
|
|
+
|
|
+/* SQL functions */
|
|
+extern Datum security_label_in(PG_FUNCTION_ARGS);
|
|
+extern Datum security_label_out(PG_FUNCTION_ARGS);
|
|
+extern Datum security_label_raw_in(PG_FUNCTION_ARGS);
|
|
+extern Datum security_label_raw_out(PG_FUNCTION_ARGS);
|
|
+extern Datum text_to_security_label(PG_FUNCTION_ARGS);
|
|
+extern Datum security_label_to_text(PG_FUNCTION_ARGS);
|
|
+extern Datum lo_get_security(PG_FUNCTION_ARGS);
|
|
+extern Datum lo_set_security(PG_FUNCTION_ARGS);
|
|
+
|
|
+#endif // PGACE_H
|
|
diff -rpNU3 base/src/include/utils/syscache.h pgace/src/include/utils/syscache.h
|
|
--- base/src/include/utils/syscache.h 2008-01-07 23:51:33.000000000 +0900
|
|
+++ pgace/src/include/utils/syscache.h 2008-01-08 01:39:49.000000000 +0900
|
|
@@ -76,6 +76,8 @@
|
|
#define TSTEMPLATEOID 45
|
|
#define TYPENAMENSP 46
|
|
#define TYPEOID 47
|
|
+#define SECURITYOID 48
|
|
+#define SECURITYLABEL 49
|
|
|
|
extern void InitCatalogCache(void);
|
|
extern void InitCatalogCachePhase2(void);
|