From 6c204f4da74d75959c49a8c93c441ded1ca5756a Mon Sep 17 00:00:00 2001 From: Jesse Keating Date: Tue, 29 Sep 2009 06:50:09 +0000 Subject: [PATCH 1/8] Initialize branch F-12 for sepostgresql --- branch | 1 + 1 file changed, 1 insertion(+) create mode 100644 branch diff --git a/branch b/branch new file mode 100644 index 0000000..06de2d2 --- /dev/null +++ b/branch @@ -0,0 +1 @@ +F-12 From 152ca2e0ec5c8e549b9e55b5e17b8622b6d0bc36 Mon Sep 17 00:00:00 2001 From: KaiGai Kohei Date: Mon, 16 Nov 2009 13:47:57 +0000 Subject: [PATCH 2/8] - rebild for ppc/ppc64 libraries --- sepostgresql.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sepostgresql.spec b/sepostgresql.spec index 49d6727..ba07df7 100644 --- a/sepostgresql.spec +++ b/sepostgresql.spec @@ -12,7 +12,7 @@ Summary: Security Enhanced PostgreSQL Name: sepostgresql Version: 8.4.1 -Release: 2305%{?dist} +Release: 2306%{?dist} License: BSD Group: Applications/Databases Url: http://code.google.com/p/sepgsql/ @@ -192,6 +192,9 @@ fi %attr(700,sepgsql,sepgsql) %dir %{_localstatedir}/lib/sepgsql/backups %changelog +* Mon Nov 16 2009 KaiGai Kohei - 8.4.1-2306 +- rebild for ppc/ppc64 libraries + * Fri Sep 11 2009 KaiGai Kohei - 8.4.1-2305 - Upgrade base SE-PostgreSQL v8.4.0->v8.4.1 - rework: backport features from v8.5devel tree From 953750f6cdb0e0f5e85838b1ca127cb0c387168b Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Thu, 26 Nov 2009 01:38:43 +0000 Subject: [PATCH 3/8] Fix typo that causes a failure to update the common directory. (releng #2781) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index dad7c56..59ecad3 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ NAME := sepostgresql SPECFILE = $(firstword $(wildcard *.spec)) define find-makefile-common -for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done +for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$d/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done endef MAKEFILE_COMMON := $(shell $(find-makefile-common)) From 2be0f329901a49b538792b380ced2a112c886028 Mon Sep 17 00:00:00 2001 From: KaiGai Kohei Date: Tue, 8 Dec 2009 05:59:39 +0000 Subject: [PATCH 4/8] - rework: backport features from v8.5devel tree - fixbug: selinux netlink receiver process didn't have correct ps display --- sepostgresql-8.4.patch | 8381 ++++++++++++++++++++++++++++------------ sepostgresql.spec | 6 +- 2 files changed, 6012 insertions(+), 2375 deletions(-) diff --git a/sepostgresql-8.4.patch b/sepostgresql-8.4.patch index 4e35401..b703db3 100644 --- a/sepostgresql-8.4.patch +++ b/sepostgresql-8.4.patch @@ -406,7 +406,7 @@ diff -Nrpc base/src/backend/access/common/tupdesc.c sepgsql/src/backend/access/c { diff -Nrpc base/src/backend/access/heap/heapam.c sepgsql/src/backend/access/heap/heapam.c *** base/src/backend/access/heap/heapam.c Sun Sep 6 19:40:49 2009 ---- sepgsql/src/backend/access/heap/heapam.c Tue Sep 8 23:55:48 2009 +--- sepgsql/src/backend/access/heap/heapam.c Tue Dec 8 14:53:28 2009 *************** *** 54,59 **** --- 54,60 ---- @@ -591,7 +591,7 @@ diff -Nrpc base/src/backend/access/transam/xact.c sepgsql/src/backend/access/tra diff -Nrpc base/src/backend/bootstrap/bootparse.y sepgsql/src/backend/bootstrap/bootparse.y *** base/src/backend/bootstrap/bootparse.y Sat Jan 3 13:01:35 2009 ---- sepgsql/src/backend/bootstrap/bootparse.y Wed Jul 15 19:35:52 2009 +--- sepgsql/src/backend/bootstrap/bootparse.y Thu Oct 8 09:29:32 2009 *************** *** 42,47 **** --- 42,48 ---- @@ -604,15 +604,17 @@ diff -Nrpc base/src/backend/bootstrap/bootparse.y sepgsql/src/backend/bootstrap/ #include "storage/ipc.h" *************** Boot_CreateStmt: *** 211,216 **** ---- 212,222 ---- +--- 212,224 ---- else { Oid id; + Oid *secLabels = -+ sepgsqlCreateTableColumns(NULL, -+ LexIDStr($5), -+ PG_CATALOG_NAMESPACE, -+ tupdesc, RELKIND_RELATION); ++ sepgsql_relation_create(LexIDStr($5), ++ RELKIND_RELATION, ++ tupdesc, ++ PG_CATALOG_NAMESPACE, ++ NULL, NIL, ++ false, false); id = heap_create_with_catalog(LexIDStr($5), PG_CATALOG_NAMESPACE, @@ -625,7 +627,7 @@ diff -Nrpc base/src/backend/bootstrap/bootparse.y sepgsql/src/backend/bootstrap/ elog(DEBUG4, "relation created with oid %u", id); } do_end(); ---- 231,238 ---- +--- 233,240 ---- 0, ONCOMMIT_NOOP, (Datum) 0, @@ -636,10 +638,10 @@ diff -Nrpc base/src/backend/bootstrap/bootparse.y sepgsql/src/backend/bootstrap/ do_end(); diff -Nrpc base/src/backend/bootstrap/bootstrap.c sepgsql/src/backend/bootstrap/bootstrap.c *** base/src/backend/bootstrap/bootstrap.c Fri Feb 20 22:15:36 2009 ---- sepgsql/src/backend/bootstrap/bootstrap.c Wed Sep 9 13:14:37 2009 +--- sepgsql/src/backend/bootstrap/bootstrap.c Tue Dec 8 14:04:25 2009 *************** -*** 26,31 **** ---- 26,32 ---- +*** 26,37 **** +--- 26,39 ---- #include "access/xact.h" #include "bootstrap/bootstrap.h" #include "catalog/index.h" @@ -647,9 +649,45 @@ diff -Nrpc base/src/backend/bootstrap/bootstrap.c sepgsql/src/backend/bootstrap/ #include "catalog/pg_type.h" #include "libpq/pqsignal.h" #include "miscadmin.h" + #include "nodes/makefuncs.h" + #include "postmaster/bgwriter.h" + #include "postmaster/walwriter.h" ++ #include "security/sepgsql.h" + #include "storage/bufmgr.h" + #include "storage/ipc.h" + #include "storage/proc.h" +*************** AuxiliaryProcessMain(int argc, char *arg +*** 338,343 **** +--- 340,350 ---- + case WalWriterProcess: + statmsg = "wal writer process"; + break; ++ #ifdef HAVE_SELINUX ++ case SelinuxReceiverProcess: ++ statmsg = "selinux netlink receiver"; ++ break; ++ #endif + default: + statmsg = "??? process"; + break; +*************** AuxiliaryProcessMain(int argc, char *arg +*** 430,435 **** +--- 437,448 ---- + WalWriterMain(); + proc_exit(1); /* should never return */ + ++ #ifdef HAVE_SELINUX ++ case SelinuxReceiverProcess: ++ sepgsqlReceiverMain(); ++ proc_exit(1); /* should nener return */ ++ #endif ++ + default: + elog(PANIC, "unrecognized process type: %d", auxType); + proc_exit(1); *************** BootstrapModeMain(void) *** 497,502 **** ---- 498,508 ---- +--- 510,520 ---- */ boot_yyparse(); @@ -663,7 +701,7 @@ diff -Nrpc base/src/backend/bootstrap/bootstrap.c sepgsql/src/backend/bootstrap/ CreateCheckPoint(CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_IMMEDIATE); *************** InsertOneTuple(Oid objectid) *** 794,799 **** ---- 800,807 ---- +--- 812,819 ---- tupDesc = CreateTupleDesc(numattr, RelationGetForm(boot_reldesc)->relhasoids, attrtypes); @@ -711,7 +749,7 @@ diff -Nrpc base/src/backend/catalog/Makefile sepgsql/src/backend/catalog/Makefil toasting.h indexing.h \ diff -Nrpc base/src/backend/catalog/aclchk.c sepgsql/src/backend/catalog/aclchk.c *** base/src/backend/catalog/aclchk.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/catalog/aclchk.c Wed Sep 9 21:29:33 2009 +--- sepgsql/src/backend/catalog/aclchk.c Fri Sep 18 14:51:00 2009 *************** *** 35,40 **** --- 35,41 ---- @@ -747,25 +785,91 @@ diff -Nrpc base/src/backend/catalog/aclchk.c sepgsql/src/backend/catalog/aclchk. /* Views don't have any system columns at all */ if (classForm->relkind == RELKIND_VIEW && curr_att < 0) continue; +*************** ExecGrant_Attribute(InternalGrant *istmt +*** 774,779 **** +--- 782,789 ---- + relOid, grantorId, ACL_KIND_COLUMN, + relname, attnum, + NameStr(pg_attribute_tuple->attname)); ++ /* SELinux checks */ ++ sepgsql_attribute_grant(relOid, attnum); + + /* + * Generate new ACL. +*************** ExecGrant_Relation(InternalGrant *istmt) +*** 1029,1034 **** +--- 1039,1046 ---- + ? ACL_KIND_SEQUENCE : ACL_KIND_CLASS, + NameStr(pg_class_tuple->relname), + 0, NULL); ++ /* SELinux checks */ ++ sepgsql_relation_grant(relOid); + + /* + * Generate new ACL. +*************** ExecGrant_Database(InternalGrant *istmt) +*** 1217,1222 **** +--- 1229,1236 ---- + datId, grantorId, ACL_KIND_DATABASE, + NameStr(pg_database_tuple->datname), + 0, NULL); ++ /* SELinux permission checks */ ++ sepgsql_database_grant(datId); + + /* + * Generate new ACL. +*************** ExecGrant_Fdw(InternalGrant *istmt) +*** 1335,1340 **** +--- 1349,1356 ---- + fdwid, grantorId, ACL_KIND_FDW, + NameStr(pg_fdw_tuple->fdwname), + 0, NULL); ++ /* SELinux permission checks */ ++ sepgsql_fdw_grant(fdwid); + + /* + * Generate new ACL. +*************** ExecGrant_ForeignServer(InternalGrant *i +*** 1454,1459 **** +--- 1470,1477 ---- + srvid, grantorId, ACL_KIND_FOREIGN_SERVER, + NameStr(pg_server_tuple->srvname), + 0, NULL); ++ /* SELinux checks */ ++ sepgsql_foreign_server_grant(srvid); + + /* + * Generate new ACL. *************** ExecGrant_Function(InternalGrant *istmt) *** 1572,1577 **** ---- 1580,1587 ---- +--- 1590,1597 ---- funcId, grantorId, ACL_KIND_PROC, NameStr(pg_proc_tuple->proname), 0, NULL); + /* SELinux: db_procedure:{setattr} */ -+ sepgsqlCheckProcedureSetattr(funcId); ++ sepgsql_proc_grant(funcId); + + /* + * Generate new ACL. +*************** ExecGrant_Language(InternalGrant *istmt) +*** 1696,1701 **** +--- 1716,1723 ---- + langId, grantorId, ACL_KIND_LANGUAGE, + NameStr(pg_language_tuple->lanname), + 0, NULL); ++ /* SELinux checks */ ++ sepgsql_language_grant(langId); /* * Generate new ACL. *************** ExecGrant_Namespace(InternalGrant *istmt *** 1815,1820 **** ---- 1825,1833 ---- +--- 1837,1845 ---- NameStr(pg_namespace_tuple->nspname), 0, NULL); + /* SELinux: db_schema:{setattr} */ -+ sepgsqlCheckSchemaSetattr(nspid); ++ sepgsql_schema_grant(nspid); + /* * Generate new ACL. @@ -817,7 +921,7 @@ diff -Nrpc base/src/backend/catalog/catalog.c sepgsql/src/backend/catalog/catalo return true; diff -Nrpc base/src/backend/catalog/dependency.c sepgsql/src/backend/catalog/dependency.c *** base/src/backend/catalog/dependency.c Sun Sep 6 19:40:49 2009 ---- sepgsql/src/backend/catalog/dependency.c Mon Sep 7 00:55:45 2009 +--- sepgsql/src/backend/catalog/dependency.c Thu Sep 17 23:44:07 2009 *************** *** 63,68 **** --- 63,69 ---- @@ -968,7 +1072,7 @@ diff -Nrpc base/src/backend/catalog/dependency.c sepgsql/src/backend/catalog/dep + /* SELinux checks db_xxx:{drop}, if necessary */ + if (permission) -+ sepgsqlCheckSysobjDrop(object); ++ sepgsql_sysobj_drop(object); + /* * First remove any pg_depend records that link from this object to @@ -1332,7 +1436,7 @@ diff -Nrpc base/src/backend/catalog/heap.c sepgsql/src/backend/catalog/heap.c diff -Nrpc base/src/backend/catalog/index.c sepgsql/src/backend/catalog/index.c *** base/src/backend/catalog/index.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/catalog/index.c Wed Jul 15 19:39:56 2009 +--- sepgsql/src/backend/catalog/index.c Fri Sep 18 17:02:48 2009 *************** *** 48,53 **** --- 48,54 ---- @@ -1343,49 +1447,6 @@ diff -Nrpc base/src/backend/catalog/index.c sepgsql/src/backend/catalog/index.c #include "storage/bufmgr.h" #include "storage/lmgr.h" #include "storage/procarray.h" -*************** static TupleDesc ConstructTupleDescripto -*** 81,87 **** - Oid *classObjectId); - static void InitializeAttributeOids(Relation indexRelation, - int numatts, Oid indexoid); -! static void AppendAttributeTuples(Relation indexRelation, int numatts); - static void UpdateIndexRelation(Oid indexoid, Oid heapoid, - IndexInfo *indexInfo, - Oid *classOids, ---- 82,88 ---- - Oid *classObjectId); - static void InitializeAttributeOids(Relation indexRelation, - int numatts, Oid indexoid); -! static void AppendAttributeTuples(Relation indexRelation, int numatts, Oid *secLabels); - static void UpdateIndexRelation(Oid indexoid, Oid heapoid, - IndexInfo *indexInfo, - Oid *classOids, -*************** InitializeAttributeOids(Relation indexRe -*** 323,333 **** - * ---------------------------------------------------------------- - */ - static void -! AppendAttributeTuples(Relation indexRelation, int numatts) - { - Relation pg_attribute; - CatalogIndexState indstate; - TupleDesc indexTupDesc; - int i; - - /* ---- 324,335 ---- - * ---------------------------------------------------------------- - */ - static void -! AppendAttributeTuples(Relation indexRelation, int numatts, Oid *secLabels) - { - Relation pg_attribute; - CatalogIndexState indstate; - TupleDesc indexTupDesc; -+ Oid attsid = InvalidOid; - int i; - - /* *************** AppendAttributeTuples(Relation indexRela *** 351,357 **** Assert(indexTupDesc->attrs[i]->attnum == i + 1); @@ -1395,47 +1456,16 @@ diff -Nrpc base/src/backend/catalog/index.c sepgsql/src/backend/catalog/index.c } CatalogCloseIndexes(indstate); ---- 353,363 ---- +--- 352,359 ---- Assert(indexTupDesc->attrs[i]->attnum == i + 1); Assert(indexTupDesc->attrs[i]->attcacheoff == -1); -! if (secLabels) -! attsid = secLabels[i - FirstLowInvalidHeapAttributeNumber]; -! ! InsertPgAttributeTuple(pg_attribute, indexTupDesc->attrs[i], -! indstate, attsid); +! indstate, InvalidOid); } CatalogCloseIndexes(indstate); *************** index_create(Oid heapRelationId, -*** 519,524 **** ---- 525,532 ---- - TupleDesc indexTupDesc; - bool shared_relation; - Oid namespaceId; -+ Oid *secLabels; -+ Oid relsid = InvalidOid; - int i; - - pg_class = heap_open(RelationRelationId, RowExclusiveLock); -*************** index_create(Oid heapRelationId, -*** 604,609 **** ---- 612,625 ---- - classObjectId); - - /* -+ * compute security labels to be assigned on index relation -+ */ -+ secLabels = sepgsqlCreateTableColumns(NULL, indexRelationName, namespaceId, -+ indexTupDesc, RELKIND_INDEX); -+ if (secLabels) -+ relsid = secLabels[0]; -+ -+ /* - * Allocate an OID for the index, unless we were told what to use. - * - * The OID will be the relfilenode as well, so make sure it doesn't -*************** index_create(Oid heapRelationId, *** 652,658 **** */ InsertPgClassTuple(pg_class, indexRelation, @@ -1444,34 +1474,17 @@ diff -Nrpc base/src/backend/catalog/index.c sepgsql/src/backend/catalog/index.c /* done with pg_class */ heap_close(pg_class, RowExclusiveLock); ---- 668,674 ---- +--- 654,660 ---- */ InsertPgClassTuple(pg_class, indexRelation, RelationGetRelid(indexRelation), -! reloptions, relsid); +! reloptions, InvalidOid); /* done with pg_class */ heap_close(pg_class, RowExclusiveLock); -*************** index_create(Oid heapRelationId, -*** 668,674 **** - /* - * append ATTRIBUTE tuples for the index - */ -! AppendAttributeTuples(indexRelation, indexInfo->ii_NumIndexAttrs); - - /* ---------------- - * update pg_index ---- 684,690 ---- - /* - * append ATTRIBUTE tuples for the index - */ -! AppendAttributeTuples(indexRelation, indexInfo->ii_NumIndexAttrs, secLabels); - - /* ---------------- - * update pg_index diff -Nrpc base/src/backend/catalog/namespace.c sepgsql/src/backend/catalog/namespace.c *** base/src/backend/catalog/namespace.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/catalog/namespace.c Mon Sep 7 00:55:45 2009 +--- sepgsql/src/backend/catalog/namespace.c Thu Sep 17 17:04:16 2009 *************** *** 39,44 **** --- 39,45 ---- @@ -1489,7 +1502,7 @@ diff -Nrpc base/src/backend/catalog/namespace.c sepgsql/src/backend/catalog/name { if (OidIsValid(myTempNamespace)) + { -+ sepgsqlCheckSchemaSearch(myTempNamespace, true); ++ sepgsql_schema_search(myTempNamespace, true); return myTempNamespace; + } @@ -1501,7 +1514,7 @@ diff -Nrpc base/src/backend/catalog/namespace.c sepgsql/src/backend/catalog/name if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_NAMESPACE, nspname); -+ sepgsqlCheckSchemaSearch(namespaceId, true); ++ sepgsql_schema_search(namespaceId, true); return namespaceId; } @@ -1519,7 +1532,7 @@ diff -Nrpc base/src/backend/catalog/namespace.c sepgsql/src/backend/catalog/name !list_member_oid(oidlist, namespaceId) && pg_namespace_aclcheck(namespaceId, roleid, ! ACL_USAGE) == ACLCHECK_OK && -! sepgsqlCheckSchemaSearch(namespaceId, false)) +! sepgsql_schema_search(namespaceId, false)) oidlist = lappend_oid(oidlist, namespaceId); } } @@ -1537,7 +1550,7 @@ diff -Nrpc base/src/backend/catalog/namespace.c sepgsql/src/backend/catalog/name if (OidIsValid(myTempNamespace)) { ! if (!list_member_oid(oidlist, myTempNamespace) && -! sepgsqlCheckSchemaSearch(myTempNamespace, false)) +! sepgsql_schema_search(myTempNamespace, false)) oidlist = lappend_oid(oidlist, myTempNamespace); } else @@ -1555,7 +1568,7 @@ diff -Nrpc base/src/backend/catalog/namespace.c sepgsql/src/backend/catalog/name !list_member_oid(oidlist, namespaceId) && pg_namespace_aclcheck(namespaceId, roleid, ! ACL_USAGE) == ACLCHECK_OK && -! sepgsqlCheckSchemaSearch(namespaceId, false)) +! sepgsql_schema_search(namespaceId, false)) oidlist = lappend_oid(oidlist, namespaceId); } } @@ -1576,7 +1589,7 @@ diff -Nrpc base/src/backend/catalog/namespace.c sepgsql/src/backend/catalog/name get_database_name(MyDatabaseId)))); + /* SELinux checks permission to create temp schema */ -+ nspsecid = sepgsqlCheckSchemaCreate(namespaceName, NULL, true); ++ nspsecid = sepgsql_schema_create(namespaceName, true, NULL); + snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId); @@ -1656,6 +1669,37 @@ diff -Nrpc base/src/backend/catalog/pg_aggregate.c sepgsql/src/backend/catalog/p /* * Okay to create the pg_aggregate entry. +diff -Nrpc base/src/backend/catalog/pg_conversion.c sepgsql/src/backend/catalog/pg_conversion.c +*** base/src/backend/catalog/pg_conversion.c Sat Jan 3 13:01:35 2009 +--- sepgsql/src/backend/catalog/pg_conversion.c Thu Sep 17 22:10:19 2009 +*************** Oid +*** 40,46 **** + ConversionCreate(const char *conname, Oid connamespace, + Oid conowner, + int32 conforencoding, int32 contoencoding, +! Oid conproc, bool def) + { + int i; + Relation rel; +--- 40,46 ---- + ConversionCreate(const char *conname, Oid connamespace, + Oid conowner, + int32 conforencoding, int32 contoencoding, +! Oid conproc, Oid consecid, bool def) + { + int i; + Relation rel; +*************** ConversionCreate(const char *conname, Oi +*** 104,109 **** +--- 104,111 ---- + values[Anum_pg_conversion_condefault - 1] = BoolGetDatum(def); + + tup = heap_form_tuple(tupDesc, values, nulls); ++ if (HeapTupleHasSecid(tup)) ++ HeapTupleSetSecid(tup, consecid); + + /* insert a new tuple */ + oid = simple_heap_insert(rel, tup); diff -Nrpc base/src/backend/catalog/pg_largeobject.c sepgsql/src/backend/catalog/pg_largeobject.c *** base/src/backend/catalog/pg_largeobject.c Sat Jan 3 13:01:35 2009 --- sepgsql/src/backend/catalog/pg_largeobject.c Wed Jul 15 19:48:58 2009 @@ -1724,9 +1768,101 @@ diff -Nrpc base/src/backend/catalog/pg_namespace.c sepgsql/src/backend/catalog/p nspoid = simple_heap_insert(nspdesc, tup); Assert(OidIsValid(nspoid)); +diff -Nrpc base/src/backend/catalog/pg_operator.c sepgsql/src/backend/catalog/pg_operator.c +*** base/src/backend/catalog/pg_operator.c Thu Jun 18 10:20:52 2009 +--- sepgsql/src/backend/catalog/pg_operator.c Thu Sep 17 22:10:19 2009 +*************** +*** 28,33 **** +--- 28,34 ---- + #include "catalog/pg_type.h" + #include "miscadmin.h" + #include "parser/parse_oper.h" ++ #include "security/sepgsql.h" + #include "utils/acl.h" + #include "utils/builtins.h" + #include "utils/lsyscache.h" +*************** OperatorShellMake(const char *operatorNa +*** 204,209 **** +--- 205,211 ---- + { + Relation pg_operator_desc; + Oid operatorObjectId; ++ Oid secid; + int i; + HeapTuple tup; + Datum values[Natts_pg_operator]; +*************** OperatorShellMake(const char *operatorNa +*** 220,225 **** +--- 222,231 ---- + errmsg("\"%s\" is not a valid operator name", + operatorName))); + ++ /* SELinux permission check */ ++ secid = sepgsql_operator_create(operatorName, InvalidOid, ++ operatorNamespace, ++ InvalidOid, InvalidOid, InvalidOid); + /* + * initialize our *nulls and *values arrays + */ +*************** OperatorShellMake(const char *operatorNa +*** 260,265 **** +--- 266,273 ---- + * create a new operator tuple + */ + tup = heap_form_tuple(tupDesc, values, nulls); ++ if (HeapTupleHasSecid(tup) && OidIsValid(secid)) ++ HeapTupleSetSecid(tup, secid); + + /* + * insert our "shell" operator tuple +*************** OperatorCreate(const char *operatorName, +*** 347,352 **** +--- 355,361 ---- + bool selfCommutator = false; + NameData oname; + TupleDesc tupDesc; ++ Oid secid; + int i; + + /* +*************** OperatorCreate(const char *operatorName, +*** 476,481 **** +--- 485,494 ---- + else + negatorId = InvalidOid; + ++ /* SELinux permission checks */ ++ secid = sepgsql_operator_create(operatorName, operatorObjectId, ++ operatorNamespace, ++ procedureId, restrictionId, joinId); + /* + * set up values in the operator tuple + */ +*************** OperatorCreate(const char *operatorName, +*** 523,528 **** +--- 536,543 ---- + values, + nulls, + replaces); ++ if (HeapTupleHasSecid(tup)) ++ HeapTupleSetSecid(tup, secid); + + simple_heap_update(pg_operator_desc, &tup->t_self, tup); + } +*************** OperatorCreate(const char *operatorName, +*** 530,535 **** +--- 545,552 ---- + { + tupDesc = pg_operator_desc->rd_att; + tup = heap_form_tuple(tupDesc, values, nulls); ++ if (HeapTupleHasSecid(tup)) ++ HeapTupleSetSecid(tup, secid); + + operatorObjectId = simple_heap_insert(pg_operator_desc, tup); + } diff -Nrpc base/src/backend/catalog/pg_proc.c sepgsql/src/backend/catalog/pg_proc.c *** base/src/backend/catalog/pg_proc.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/catalog/pg_proc.c Tue Sep 8 23:55:48 2009 +--- sepgsql/src/backend/catalog/pg_proc.c Fri Sep 18 17:39:46 2009 *************** *** 29,34 **** --- 29,35 ---- @@ -1767,37 +1903,32 @@ diff -Nrpc base/src/backend/catalog/pg_proc.c sepgsql/src/backend/catalog/pg_pro bool is_update; *************** ProcedureCreate(const char *procedureNam *** 343,348 **** ---- 346,361 ---- +--- 346,356 ---- ObjectIdGetDatum(procNamespace), 0); + /* Check permission to create/replace a function */ -+ prosecid = sepgsqlCheckProcedureCreate(procedureName, -+ HeapTupleIsValid(oldtup) -+ ? HeapTupleGetOid(oldtup) -+ : InvalidOid, -+ procNamespace, -+ languageObjectId, -+ (DefElem *)proseclabel); -+ sepgsqlCheckSchemaAddName(procNamespace); ++ prosecid = sepgsql_proc_create(procedureName, oldtup, ++ procNamespace, languageObjectId, ++ (DefElem *)proseclabel); + if (HeapTupleIsValid(oldtup)) { /* There is one; okay to replace it? */ *************** ProcedureCreate(const char *procedureNam *** 477,482 **** ---- 490,497 ---- +--- 485,492 ---- /* Okay, do it... */ tup = heap_modify_tuple(oldtup, tupDesc, values, nulls, replaces); -+ if (HeapTupleHasSecid(tup) && OidIsValid(prosecid)) ++ if (HeapTupleHasSecid(tup)) + HeapTupleSetSecid(tup, prosecid); simple_heap_update(rel, &tup->t_self, tup); ReleaseSysCache(oldtup); *************** ProcedureCreate(const char *procedureNam *** 486,491 **** ---- 501,508 ---- +--- 496,503 ---- { /* Creating a new procedure */ tup = heap_form_tuple(tupDesc, values, nulls); @@ -2451,7 +2582,7 @@ diff -Nrpc base/src/backend/catalog/pg_security.c sepgsql/src/backend/catalog/pg + } diff -Nrpc base/src/backend/catalog/pg_shdepend.c sepgsql/src/backend/catalog/pg_shdepend.c *** base/src/backend/catalog/pg_shdepend.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/catalog/pg_shdepend.c Tue Sep 8 23:55:48 2009 +--- sepgsql/src/backend/catalog/pg_shdepend.c Fri Sep 18 14:51:00 2009 *************** *** 36,41 **** --- 36,42 ---- @@ -2464,23 +2595,12 @@ diff -Nrpc base/src/backend/catalog/pg_shdepend.c sepgsql/src/backend/catalog/pg #include "utils/acl.h" *************** shdepReassignOwned(List *roleids, Oid ne *** 1336,1341 **** ---- 1337,1355 ---- +--- 1337,1344 ---- break; case TypeRelationId: -+ /* -+ * NOTE: SELinux does not check anything inside -+ * AlterTypeOwnerInternal() -+ */ -+ tuple = SearchSysCache(TYPEOID, -+ ObjectIdGetDatum(sdepForm->objid), -+ 0, 0, 0); -+ if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "cache lookup failed for type: %u", sdepForm->objid); -+ sepgsqlCheckSysobjSetattr(TypeRelationId, -+ HeapTupleGetSecid(tuple), -+ NameStr(((Form_pg_type) GETSTRUCT(tuple))->typname)); -+ ReleaseSysCache(tuple); ++ /* SELinux checks */ ++ sepgsql_type_alter(sdepForm->objid, NULL, InvalidOid); AlterTypeOwnerInternal(sdepForm->objid, newrole, true); break; @@ -2493,17 +2613,18 @@ diff -Nrpc base/src/backend/catalog/pg_shdepend.c sepgsql/src/backend/catalog/pg /* * Pass recursing = true so that we don't fail on indexes, * owned sequences, etc when we happen to visit them ---- 1362,1368 ---- +--- 1351,1358 ---- break; case RelationRelationId: -! sepgsqlCheckTableSetattr(sdepForm->objid); +! /* SELinux checks */ +! sepgsql_relation_alter(sdepForm->objid, NULL, InvalidOid); /* * Pass recursing = true so that we don't fail on indexes, * owned sequences, etc when we happen to visit them diff -Nrpc base/src/backend/catalog/pg_type.c sepgsql/src/backend/catalog/pg_type.c *** base/src/backend/catalog/pg_type.c Sun Sep 6 19:40:49 2009 ---- sepgsql/src/backend/catalog/pg_type.c Tue Sep 8 23:55:48 2009 +--- sepgsql/src/backend/catalog/pg_type.c Fri Sep 18 17:39:46 2009 *************** *** 25,30 **** --- 25,31 ---- @@ -2516,7 +2637,7 @@ diff -Nrpc base/src/backend/catalog/pg_type.c sepgsql/src/backend/catalog/pg_typ #include "utils/fmgroids.h" *************** TypeShellMake(const char *typeName, Oid *** 56,65 **** ---- 57,72 ---- +--- 57,73 ---- Datum values[Natts_pg_type]; bool nulls[Natts_pg_type]; Oid typoid; @@ -2526,16 +2647,17 @@ diff -Nrpc base/src/backend/catalog/pg_type.c sepgsql/src/backend/catalog/pg_typ Assert(PointerIsValid(typeName)); + /* SELinux check permission to create a shell type */ -+ typsid = sepgsqlCheckSysobjCreate(TypeRelationId, typeName); -+ sepgsqlCheckProcedureInstall(F_SHELL_IN); -+ sepgsqlCheckProcedureInstall(F_SHELL_OUT); ++ typsid = sepgsql_type_create(typeName, InvalidOid, typeNamespace, ++ F_SHELL_IN, F_SHELL_OUT, ++ InvalidOid, InvalidOid, ++ InvalidOid, InvalidOid, InvalidOid); + /* * open pg_type */ *************** TypeCreate(Oid newTypeOid, *** 201,206 **** ---- 208,214 ---- +--- 209,215 ---- { Relation pg_type_desc; Oid typeObjectId; @@ -2545,30 +2667,25 @@ diff -Nrpc base/src/backend/catalog/pg_type.c sepgsql/src/backend/catalog/pg_typ bool nulls[Natts_pg_type]; *************** TypeCreate(Oid newTypeOid, *** 367,372 **** ---- 375,394 ---- +--- 376,390 ---- CStringGetDatum(typeName), ObjectIdGetDatum(typeNamespace), 0, 0); + + /* SELinux checks to create/replace type */ + if (!isImplicitArray && typeType != TYPTYPE_COMPOSITE) -+ { -+ if (!HeapTupleIsValid(tup)) -+ typeSecid = sepgsqlCheckSysobjCreate(TypeRelationId, typeName); -+ else -+ { -+ typeSecid = HeapTupleGetSecid(tup); -+ sepgsqlCheckSysobjSetattr(TypeRelationId, typeSecid, typeName); -+ } -+ sepgsqlCheckSchemaAddName(typeNamespace); -+ } ++ typeSecid = sepgsql_type_create(typeName, tup, typeNamespace, ++ inputProcedure, outputProcedure, ++ receiveProcedure, sendProcedure, ++ typmodinProcedure, typmodoutProcedure, ++ analyzeProcedure); + if (HeapTupleIsValid(tup)) { /* *************** TypeCreate(Oid newTypeOid, *** 412,417 **** ---- 434,441 ---- +--- 430,437 ---- /* Force the OID if requested by caller, else heap_insert does it */ if (OidIsValid(newTypeOid)) HeapTupleSetOid(tup, newTypeOid); @@ -2579,7 +2696,7 @@ diff -Nrpc base/src/backend/catalog/pg_type.c sepgsql/src/backend/catalog/pg_typ } diff -Nrpc base/src/backend/catalog/toasting.c sepgsql/src/backend/catalog/toasting.c *** base/src/backend/catalog/toasting.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/catalog/toasting.c Wed Jul 15 19:35:52 2009 +--- sepgsql/src/backend/catalog/toasting.c Thu Oct 8 09:29:32 2009 *************** *** 28,33 **** --- 28,34 ---- @@ -2602,13 +2719,14 @@ diff -Nrpc base/src/backend/catalog/toasting.c sepgsql/src/backend/catalog/toast ObjectAddress baseobject, *************** create_toast_table(Relation rel, Oid toa *** 199,204 **** ---- 201,210 ---- +--- 201,211 ---- else namespaceid = PG_TOAST_NAMESPACE; -+ secLabels = sepgsqlCreateTableColumns(NULL, -+ toast_relname, namespaceid, -+ tupdesc, RELKIND_TOASTVALUE); ++ secLabels = sepgsql_relation_create(toast_relname, ++ RELKIND_TOASTVALUE, ++ tupdesc, namespaceid, ++ NULL, NIL, false, false); + toast_relid = heap_create_with_catalog(toast_relname, namespaceid, @@ -2622,7 +2740,7 @@ diff -Nrpc base/src/backend/catalog/toasting.c sepgsql/src/backend/catalog/toast /* make the toast relation visible, else index creation will fail */ CommandCounterIncrement(); ---- 218,225 ---- +--- 219,226 ---- 0, ONCOMMIT_NOOP, reloptions, @@ -2633,7 +2751,7 @@ diff -Nrpc base/src/backend/catalog/toasting.c sepgsql/src/backend/catalog/toast CommandCounterIncrement(); diff -Nrpc base/src/backend/commands/aggregatecmds.c sepgsql/src/backend/commands/aggregatecmds.c *** base/src/backend/commands/aggregatecmds.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/commands/aggregatecmds.c Mon Sep 7 00:55:45 2009 +--- sepgsql/src/backend/commands/aggregatecmds.c Thu Sep 17 22:10:19 2009 *************** *** 32,37 **** --- 32,38 ---- @@ -2646,46 +2764,22 @@ diff -Nrpc base/src/backend/commands/aggregatecmds.c sepgsql/src/backend/command #include "utils/lsyscache.h" *************** RenameAggregate(List *name, List *args, *** 311,316 **** ---- 312,322 ---- +--- 312,320 ---- aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(namespaceOid)); + /* SELinux permission checks */ -+ sepgsqlCheckProcedureSetattr(procOid); -+ sepgsqlCheckSchemaRemoveName(namespaceOid); -+ sepgsqlCheckSchemaAddName(namespaceOid); ++ sepgsql_proc_alter(procOid, newname, InvalidOid); + /* rename */ namestrcpy(&(((Form_pg_proc) GETSTRUCT(tup))->proname), newname); simple_heap_update(rel, &tup->t_self, tup); diff -Nrpc base/src/backend/commands/alter.c sepgsql/src/backend/commands/alter.c *** base/src/backend/commands/alter.c Sat Jan 3 13:01:35 2009 ---- sepgsql/src/backend/commands/alter.c Thu Jul 16 17:22:29 2009 -*************** -*** 28,33 **** ---- 28,34 ---- - #include "commands/user.h" - #include "miscadmin.h" - #include "parser/parse_clause.h" -+ #include "security/sepgsql.h" - #include "tcop/utility.h" - #include "utils/acl.h" - #include "utils/lsyscache.h" -*************** ExecRenameStmt(RenameStmt *stmt) -*** 117,122 **** ---- 118,126 ---- - aclcheck_error(aclresult, ACL_KIND_NAMESPACE, - get_namespace_name(namespaceId)); - -+ /* SELinux checks db_table/db_sequence:{setattr} */ -+ sepgsqlCheckTableSetattr(relid); -+ - RenameRelation(relid, stmt->newname, stmt->renameType); - break; - } +--- sepgsql/src/backend/commands/alter.c Fri Sep 18 14:51:00 2009 *************** ExecAlterOwnerStmt(AlterOwnerStmt *stmt) *** 284,286 **** ---- 288,319 ---- +--- 284,315 ---- (int) stmt->objectType); } } @@ -2720,7 +2814,7 @@ diff -Nrpc base/src/backend/commands/alter.c sepgsql/src/backend/commands/alter. + } diff -Nrpc base/src/backend/commands/cluster.c sepgsql/src/backend/commands/cluster.c *** base/src/backend/commands/cluster.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/commands/cluster.c Tue Sep 8 23:55:48 2009 +--- sepgsql/src/backend/commands/cluster.c Fri Sep 18 14:51:00 2009 *************** *** 36,41 **** --- 36,42 ---- @@ -2765,7 +2859,7 @@ diff -Nrpc base/src/backend/commands/cluster.c sepgsql/src/backend/commands/clus ONCOMMIT_NOOP, reloptions, ! allowSystemTableMods, -! sepgsqlCopyTableColumns(OldHeap)); +! sepgsql_relation_copy(OldHeap)); ReleaseSysCache(tuple); @@ -2784,7 +2878,7 @@ diff -Nrpc base/src/backend/commands/cluster.c sepgsql/src/backend/commands/clus diff -Nrpc base/src/backend/commands/conversioncmds.c sepgsql/src/backend/commands/conversioncmds.c *** base/src/backend/commands/conversioncmds.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/commands/conversioncmds.c Wed Jul 15 19:48:58 2009 +--- sepgsql/src/backend/commands/conversioncmds.c Thu Sep 17 22:10:19 2009 *************** *** 24,29 **** --- 24,30 ---- @@ -2796,20 +2890,70 @@ diff -Nrpc base/src/backend/commands/conversioncmds.c sepgsql/src/backend/comman #include "utils/builtins.h" #include "utils/lsyscache.h" *************** CreateConversionCommand(CreateConversion +*** 45,50 **** +--- 46,52 ---- + int from_encoding; + int to_encoding; + Oid funcoid; ++ Oid secid; + const char *from_encoding_name = stmt->for_encoding_name; + const char *to_encoding_name = stmt->to_encoding_name; + List *func_name = stmt->func_name; +*************** CreateConversionCommand(CreateConversion *** 96,101 **** ---- 97,105 ---- +--- 98,106 ---- aclcheck_error(aclresult, ACL_KIND_PROC, NameListToString(func_name)); -+ /* SELinux checks db_procedure:{install} */ -+ sepgsqlCheckProcedureInstall(funcoid); ++ /* SELinux checks */ ++ secid = sepgsql_conversion_create(conversion_name, namespaceId, funcoid); + /* * Check that the conversion function is suitable for the requested source * and target encodings. We do that by calling the function with an empty +*************** CreateConversionCommand(CreateConversion +*** 114,120 **** + * name) + */ + ConversionCreate(conversion_name, namespaceId, GetUserId(), +! from_encoding, to_encoding, funcoid, stmt->def); + } + + /* +--- 119,125 ---- + * name) + */ + ConversionCreate(conversion_name, namespaceId, GetUserId(), +! from_encoding, to_encoding, funcoid, secid, stmt->def); + } + + /* +*************** RenameConversion(List *name, const char +*** 240,245 **** +--- 245,253 ---- + aclcheck_error(aclresult, ACL_KIND_NAMESPACE, + get_namespace_name(namespaceOid)); + ++ /* SELinux checks */ ++ sepgsql_conversion_alter(conversionOid, newname); ++ + /* rename */ + namestrcpy(&(((Form_pg_conversion) GETSTRUCT(tup))->conname), newname); + simple_heap_update(rel, &tup->t_self, tup); +*************** AlterConversionOwner_internal(Relation r +*** 336,341 **** +--- 344,351 ---- + aclcheck_error(aclresult, ACL_KIND_NAMESPACE, + get_namespace_name(convForm->connamespace)); + } ++ /* SELinux checks */ ++ sepgsql_conversion_alter(HeapTupleGetOid(tup), NULL); + + /* + * Modify the owner --- okay to scribble on tup because it's a copy diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c *** base/src/backend/commands/copy.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/commands/copy.c Thu Sep 10 15:18:03 2009 +--- sepgsql/src/backend/commands/copy.c Mon Sep 28 09:29:32 2009 *************** *** 21,28 **** --- 21,31 ---- @@ -2868,8 +3012,42 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c static bool CopyReadLine(CopyState cstate); static bool CopyReadLineText(CopyState cstate); *************** DoCopy(const CopyStmt *stmt, const char +*** 958,969 **** + errmsg("CSV quote character must not appear in the NULL specification"))); + + /* Disallow file COPY except to superusers. */ +! if (!pipe && !superuser()) +! ereport(ERROR, +! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), +! errmsg("must be superuser to COPY to or from a file"), +! errhint("Anyone can COPY to stdout or from stdin. " +! "psql's \\copy command also works for anyone."))); + + if (stmt->relation) + { +--- 967,985 ---- + errmsg("CSV quote character must not appear in the NULL specification"))); + + /* Disallow file COPY except to superusers. */ +! if (!pipe) +! { +! if (!superuser()) +! ereport(ERROR, +! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), +! errmsg("must be superuser to COPY to or from a file"), +! errhint("Anyone can COPY to stdout or from stdin. " +! "psql's \\copy command also works for anyone."))); +! if (is_from) +! sepgsql_file_read(stmt->filename); +! else +! sepgsql_file_write(stmt->filename); +! } + + if (stmt->relation) + { +*************** DoCopy(const CopyStmt *stmt, const char *** 1090,1095 **** ---- 1099,1107 ---- +--- 1106,1114 ---- num_phys_attrs = tupDesc->natts; @@ -2892,7 +3070,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c } } ---- 1116,1146 ---- +--- 1123,1153 ---- int attnum = lfirst_int(cur); if (!list_member_int(cstate->attnumlist, attnum)) @@ -2936,7 +3114,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c cstate->force_notnull_flags[attnum - 1] = true; } } ---- 1158,1180 ---- +--- 1165,1187 ---- int attnum = lfirst_int(cur); if (!list_member_int(cstate->attnumlist, attnum)) @@ -2960,18 +3138,6 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c cstate->force_notnull_flags[attnum - 1] = true; } } -*************** DoCopyTo(CopyState cstate) -*** 1258,1263 **** ---- 1303,1311 ---- - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is a directory", cstate->filename))); -+ -+ /* SELinux checks file:{write} permission */ -+ sepgsqlCheckFileWrite(fileno(cstate->copy_file), cstate->filename); - } - - PG_TRY(); *************** CopyTo(CopyState cstate) *** 1321,1336 **** int attnum = lfirst_int(cur); @@ -2990,7 +3156,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c } /* ---- 1369,1399 ---- +--- 1373,1403 ---- int attnum = lfirst_int(cur); Oid out_func_oid; bool isvarlena; @@ -3031,7 +3197,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c CopyAttributeOutCSV(cstate, colname, false, list_length(cstate->attnumlist) == 1); ---- 1448,1461 ---- +--- 1452,1465 ---- CopySendChar(cstate, cstate->delim[0]); hdr_delim = true; @@ -3059,7 +3225,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c } heap_endscan(scandesc); ---- 1481,1495 ---- +--- 1485,1499 ---- { CHECK_FOR_INTERRUPTS(); @@ -3084,7 +3250,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c { bool need_delim = false; FmgrInfo *out_functions = cstate->out_functions; ---- 1515,1522 ---- +--- 1519,1526 ---- * Emit one row during CopyTo(). */ static void @@ -3102,7 +3268,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c } } else ---- 1536,1542 ---- +--- 1540,1546 ---- { /* Hack --- assume Oid is same size as int32 */ CopySendInt32(cstate, sizeof(int32)); @@ -3119,7 +3285,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c CopySendString(cstate, string); need_delim = true; } ---- 1546,1552 ---- +--- 1550,1556 ---- if (cstate->oids) { string = DatumGetCString(DirectFunctionCall1(oidout, @@ -3137,7 +3303,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c if (!cstate->binary) { ---- 1555,1565 ---- +--- 1559,1569 ---- foreach(cur, cstate->attnumlist) { int attnum = lfirst_int(cur); @@ -3151,7 +3317,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c { *************** CopyOneRowTo(CopyState cstate, Oid tuple *** 1490,1495 **** ---- 1568,1591 ---- +--- 1572,1595 ---- need_delim = true; } @@ -3189,7 +3355,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c list_length(cstate->attnumlist) == 1); else CopyAttributeOutText(cstate, string); ---- 1597,1605 ---- +--- 1601,1609 ---- { if (!cstate->binary) { @@ -3209,7 +3375,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c CopySendInt32(cstate, VARSIZE(outputbytes) - VARHDRSZ); CopySendData(cstate, VARDATA(outputbytes), VARSIZE(outputbytes) - VARHDRSZ); ---- 1608,1614 ---- +--- 1612,1618 ---- { bytea *outputbytes; @@ -3219,7 +3385,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c VARSIZE(outputbytes) - VARHDRSZ); *************** CopyFrom(CopyState cstate) *** 1649,1656 **** ---- 1742,1751 ---- +--- 1746,1755 ---- num_defaults; FmgrInfo *in_functions; FmgrInfo oid_in_function; @@ -3231,20 +3397,8 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c int i; Oid in_func_oid; *************** CopyFrom(CopyState cstate) -*** 1753,1758 **** ---- 1848,1856 ---- - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is a directory", cstate->filename))); -+ -+ /* SELinux checks file:{read} permission */ -+ sepgsqlCheckFileRead(fileno(cstate->copy_file), cstate->filename); - } - - tupDesc = RelationGetDescr(cstate->rel); -*************** CopyFrom(CopyState cstate) *** 1888,1893 **** ---- 1986,2003 ---- +--- 1987,2004 ---- fmgr_info(in_func_oid, &oid_in_function); } @@ -3265,7 +3419,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c *************** CopyFrom(CopyState cstate) *** 1922,1927 **** ---- 2032,2038 ---- +--- 2033,2039 ---- { bool skip_tuple; Oid loaded_oid = InvalidOid; @@ -3289,7 +3443,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c string = field_strings[fieldno++]; if (cstate->csv_mode && string == NULL && ---- 2104,2124 ---- +--- 2105,2125 ---- /* Loop to read the user attributes on the line. */ foreach(cur, cstate->attnumlist) { @@ -3327,7 +3481,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c cstate->cur_attname = NULL; cstate->cur_attval = NULL; } ---- 2128,2167 ---- +--- 2129,2168 ---- string = cstate->null_print; } @@ -3387,7 +3541,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c cstate->cur_attname = NULL; } } ---- 2207,2247 ---- +--- 2208,2248 ---- i = 0; foreach(cur, cstate->attnumlist) { @@ -3431,7 +3585,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c } *************** CopyFrom(CopyState cstate) *** 2094,2099 **** ---- 2262,2269 ---- +--- 2263,2270 ---- if (cstate->oids && file_has_oids) HeapTupleSetOid(tuple, loaded_oid); @@ -3442,7 +3596,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c MemoryContextSwitchTo(oldcontext); *************** CopyFrom(CopyState cstate) *** 2118,2123 **** ---- 2288,2296 ---- +--- 2289,2297 ---- } if (!skip_tuple) @@ -3454,7 +3608,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c ExecStoreTuple(tuple, slot, InvalidBuffer, false); *************** CopyGetAttnums(TupleDesc tupDesc, Relati *** 3398,3403 **** ---- 3571,3583 ---- +--- 3572,3584 ---- } if (attnum == InvalidAttrNumber) { @@ -3477,7 +3631,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c } /* ---- 3625,3632 ---- +--- 3626,3633 ---- slot_getallattrs(slot); /* And send the data */ @@ -3488,7 +3642,7 @@ diff -Nrpc base/src/backend/commands/copy.c sepgsql/src/backend/commands/copy.c /* diff -Nrpc base/src/backend/commands/dbcommands.c sepgsql/src/backend/commands/dbcommands.c *** base/src/backend/commands/dbcommands.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/commands/dbcommands.c Tue Sep 8 23:55:48 2009 +--- sepgsql/src/backend/commands/dbcommands.c Thu Sep 17 17:04:16 2009 *************** *** 33,38 **** --- 33,39 ---- @@ -3553,7 +3707,7 @@ diff -Nrpc base/src/backend/commands/dbcommands.c sepgsql/src/backend/commands/d check_is_member_of_role(GetUserId(), datdba); + /* SELinux checks db_database:{create} */ -+ datsecid = sepgsqlCheckDatabaseCreate(dbname, dseclabel); ++ datsecid = sepgsql_database_create(dbname, dseclabel); + /* * Lookup database (template) to be cloned, and obtain share lock on it. @@ -3588,7 +3742,7 @@ diff -Nrpc base/src/backend/commands/dbcommands.c sepgsql/src/backend/commands/d dbname); + /* SELinux checks db_database:{drop} permission */ -+ sepgsqlCheckDatabaseDrop(db_id); ++ sepgsql_database_drop(db_id); + /* * Disallow dropping a DB that is marked istemplate. This is just to @@ -3614,7 +3768,7 @@ diff -Nrpc base/src/backend/commands/dbcommands.c sepgsql/src/backend/commands/d errmsg("permission denied to rename database"))); + /* SELinux: check db_database:{setattr} */ -+ sepgsqlCheckDatabaseSetattr(db_id); ++ sepgsql_database_alter(db_id); + /* * Make sure the new name doesn't exist. See notes for same error in @@ -3626,7 +3780,7 @@ diff -Nrpc base/src/backend/commands/dbcommands.c sepgsql/src/backend/commands/d dbname); + /* SELinux checks db_database:{setattr} */ -+ sepgsqlCheckDatabaseSetattr(db_id); ++ sepgsql_database_alter(db_id); + /* * Obviously can't move the tables of my own database @@ -3638,7 +3792,7 @@ diff -Nrpc base/src/backend/commands/dbcommands.c sepgsql/src/backend/commands/d stmt->dbname); + /* SELinux checks db_database:{setattr} */ -+ sepgsqlCheckDatabaseSetattr(HeapTupleGetOid(tuple)); ++ sepgsql_database_alter(HeapTupleGetOid(tuple)); + /* * Build an updated tuple, perusing the information just obtained @@ -3650,7 +3804,7 @@ diff -Nrpc base/src/backend/commands/dbcommands.c sepgsql/src/backend/commands/d stmt->dbname); + /* SELinux checks db_database:{setattr} */ -+ sepgsqlCheckDatabaseSetattr(HeapTupleGetOid(tuple)); ++ sepgsql_database_alter(HeapTupleGetOid(tuple)); + memset(repl_repl, false, sizeof(repl_repl)); repl_repl[Anum_pg_database_datconfig - 1] = true; @@ -3662,7 +3816,7 @@ diff -Nrpc base/src/backend/commands/dbcommands.c sepgsql/src/backend/commands/d errmsg("permission denied to change owner of database"))); + /* SELinux checks db_database:{setattr} */ -+ sepgsqlCheckDatabaseSetattr(HeapTupleGetOid(tuple)); ++ sepgsql_database_alter(HeapTupleGetOid(tuple)); + memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); @@ -3704,6 +3858,10 @@ diff -Nrpc base/src/backend/commands/dbcommands.c sepgsql/src/backend/commands/d + memset(replaces, false, sizeof(replaces)); + newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel), + NULL, NULL, replaces); ++ if (!HeapTupleHasSecid(newtup)) ++ ereport(ERROR, ++ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), ++ errmsg("Unable to set security label on \"%s\"", dbname))); + systable_endscan(scan); + + /* check DAC permission */ @@ -3711,11 +3869,7 @@ diff -Nrpc base/src/backend/commands/dbcommands.c sepgsql/src/backend/commands/d + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE, dbname); + + /* SELinux checks db_database:{setattr relabelfrom relabelto} */ -+ secid = sepgsqlCheckDatabaseRelabel(HeapTupleGetOid(newtup), seclabel); -+ if (!HeapTupleHasSecid(newtup)) -+ ereport(ERROR, -+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), -+ errmsg("Unable to set security label on \"%s\"", dbname))); ++ secid = sepgsql_database_relabel(HeapTupleGetOid(newtup), seclabel); + HeapTupleSetSecid(newtup, secid); + + simple_heap_update(rel, &newtup->t_self, newtup); @@ -3730,7 +3884,7 @@ diff -Nrpc base/src/backend/commands/dbcommands.c sepgsql/src/backend/commands/d * Helper functions diff -Nrpc base/src/backend/commands/foreigncmds.c sepgsql/src/backend/commands/foreigncmds.c *** base/src/backend/commands/foreigncmds.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/commands/foreigncmds.c Wed Jul 15 19:48:58 2009 +--- sepgsql/src/backend/commands/foreigncmds.c Thu Sep 17 22:10:19 2009 *************** *** 27,32 **** --- 27,33 ---- @@ -3741,33 +3895,121 @@ diff -Nrpc base/src/backend/commands/foreigncmds.c sepgsql/src/backend/commands/ #include "utils/acl.h" #include "utils/builtins.h" #include "utils/lsyscache.h" +*************** AlterForeignDataWrapperOwner(const char +*** 233,238 **** +--- 234,242 ---- + + if (form->fdwowner != newOwnerId) + { ++ /* SELinux permission check */ ++ sepgsql_fdw_alter(fdwId, InvalidOid); ++ + form->fdwowner = newOwnerId; + + simple_heap_update(rel, &tup->t_self, tup); +*************** AlterForeignServerOwner(const char *name +*** 297,302 **** +--- 301,308 ---- + aclcheck_error(aclresult, ACL_KIND_FDW, fdw->fdwname); + } + } ++ /* SELinux permission checks */ ++ sepgsql_foreign_server_alter(srvId); + + form->srvowner = newOwnerId; + +*************** CreateForeignDataWrapper(CreateFdwStmt * +*** 342,347 **** +--- 348,354 ---- + Oid fdwvalidator; + Datum fdwoptions; + Oid ownerId; ++ Oid secid; + + /* Must be super user */ + if (!superuser()) *************** CreateForeignDataWrapper(CreateFdwStmt * *** 380,385 **** ---- 381,389 ---- +--- 387,395 ---- else fdwvalidator = InvalidOid; -+ /* SELinux checks db_procedure:{install} */ -+ sepgsqlCheckProcedureInstall(fdwvalidator); ++ /* SELinux permission checks */ ++ secid = sepgsql_fdw_create(stmt->fdwname, fdwvalidator); + values[Anum_pg_foreign_data_wrapper_fdwvalidator - 1] = fdwvalidator; nulls[Anum_pg_foreign_data_wrapper_fdwacl - 1] = true; +*************** CreateForeignDataWrapper(CreateFdwStmt * +*** 393,398 **** +--- 403,410 ---- + nulls[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = true; + + tuple = heap_form_tuple(rel->rd_att, values, nulls); ++ if (HeapTupleHasSecid(tuple)) ++ HeapTupleSetSecid(tuple, secid); + + fdwId = simple_heap_insert(rel, tuple); + CatalogUpdateIndexes(rel, tuple); *************** AlterForeignDataWrapper(AlterFdwStmt *st -*** 473,478 **** ---- 477,485 ---- - ereport(WARNING, - (errmsg("changing the foreign-data wrapper validator can cause " - "the options for dependent objects to become invalid"))); -+ -+ /* SELinux checks db_procedure:{install} */ -+ sepgsqlCheckProcedureInstall(fdwvalidator); +*** 487,492 **** +--- 499,507 ---- + fdwvalidator = DatumGetObjectId(datum); } - else - { + ++ /* SELinux permission checks */ ++ sepgsql_fdw_alter(fdwId, fdwvalidator); ++ + /* + * Options specified, validate and update. + */ +*************** CreateForeignServer(CreateForeignServerS +*** 609,614 **** +--- 624,630 ---- + HeapTuple tuple; + Oid srvId; + Oid ownerId; ++ Oid secid; + AclResult aclresult; + ObjectAddress myself; + ObjectAddress referenced; +*************** CreateForeignServer(CreateForeignServerS +*** 636,641 **** +--- 652,659 ---- + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_FDW, fdw->fdwname); + ++ secid = sepgsql_foreign_server_create(stmt->fdwname); ++ + /* + * Insert tuple into pg_foreign_server. + */ +*************** CreateForeignServer(CreateForeignServerS +*** 676,681 **** +--- 694,701 ---- + nulls[Anum_pg_foreign_server_srvoptions - 1] = true; + + tuple = heap_form_tuple(rel->rd_att, values, nulls); ++ if (HeapTupleHasSecid(tuple)) ++ HeapTupleSetSecid(tuple, secid); + + srvId = simple_heap_insert(rel, tuple); + +*************** AlterForeignServer(AlterForeignServerStm +*** 732,737 **** +--- 752,760 ---- + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER, + stmt->servername); + ++ /* SELinux permission checks */ ++ sepgsql_foreign_server_alter(srvId); ++ + memset(repl_val, 0, sizeof(repl_val)); + memset(repl_null, false, sizeof(repl_null)); + memset(repl_repl, false, sizeof(repl_repl)); diff -Nrpc base/src/backend/commands/functioncmds.c sepgsql/src/backend/commands/functioncmds.c *** base/src/backend/commands/functioncmds.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/commands/functioncmds.c Tue Sep 8 23:55:48 2009 +--- sepgsql/src/backend/commands/functioncmds.c Thu Sep 17 17:04:16 2009 *************** *** 53,58 **** --- 53,59 ---- @@ -3894,32 +4136,30 @@ diff -Nrpc base/src/backend/commands/functioncmds.c sepgsql/src/backend/commands *************** RenameFunction(List *name, List *argtype *** 1112,1117 **** ---- 1128,1138 ---- +--- 1128,1136 ---- aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(namespaceOid)); + /* SELinux permission checks */ -+ sepgsqlCheckProcedureSetattr(procOid); -+ sepgsqlCheckSchemaRemoveName(namespaceOid); -+ sepgsqlCheckSchemaAddName(namespaceOid); ++ sepgsql_proc_alter(procOid, newname, InvalidOid); + /* rename */ namestrcpy(&(procForm->proname), newname); simple_heap_update(rel, &tup->t_self, tup); *************** AlterFunctionOwner_internal(Relation rel *** 1220,1225 **** ---- 1241,1248 ---- +--- 1239,1246 ---- aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(procForm->pronamespace)); } + /* SELinux permission checks */ -+ sepgsqlCheckProcedureSetattr(procOid); ++ sepgsql_proc_alter(procOid, NULL, InvalidOid); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); *************** AlterFunctionOwner_internal(Relation rel *** 1258,1263 **** ---- 1281,1337 ---- +--- 1279,1337 ---- } /* @@ -3949,6 +4189,13 @@ diff -Nrpc base/src/backend/commands/functioncmds.c sepgsql/src/backend/commands + memset(replaces, false, sizeof(replaces)); + newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel), + NULL, NULL, replaces); ++ ++ if (!HeapTupleHasSecid(newtup)) ++ ereport(ERROR, ++ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), ++ errmsg("Unable to set security label on \"%s\"", ++ get_func_name(procOid)))); ++ + ReleaseSysCache(oldtup); + + /* DAC permission checks */ @@ -3957,12 +4204,7 @@ diff -Nrpc base/src/backend/commands/functioncmds.c sepgsql/src/backend/commands + get_func_name(HeapTupleGetOid(newtup))); + + /* SELinux permission checks */ -+ secid = sepgsqlCheckProcedureRelabel(procOid, seclabel); -+ if (!HeapTupleHasSecid(newtup)) -+ ereport(ERROR, -+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), -+ errmsg("Unable to set security label on \"%s\"", -+ get_func_name(procOid)))); ++ secid = sepgsql_proc_relabel(procOid, seclabel); + HeapTupleSetSecid(newtup, secid); + + simple_heap_update(rel, &newtup->t_self, newtup); @@ -3984,40 +4226,84 @@ diff -Nrpc base/src/backend/commands/functioncmds.c sepgsql/src/backend/commands NameListToString(stmt->func->funcname)); + /* SELinux checks permissions */ -+ sepgsqlCheckProcedureSetattr(funcOid); ++ sepgsql_proc_alter(funcOid, NULL, InvalidOid); + if (procForm->proisagg) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), *************** CreateCast(CreateCastStmt *stmt) -*** 1580,1585 **** ---- 1657,1665 ---- - errmsg("cast function must not return a set"))); - - ReleaseSysCache(tuple); -+ -+ /* SELinux checks db_procedure:{install} */ -+ sepgsqlCheckProcedureInstall(funcid); +*** 1473,1478 **** +--- 1550,1556 ---- + char sourcetyptype; + char targettyptype; + Oid funcid; ++ Oid secid; + int nargs; + char castcontext; + char castmethod; +*************** CreateCast(CreateCastStmt *stmt) +*** 1674,1679 **** +--- 1752,1759 ---- + castcontext = 0; /* keep compiler quiet */ + break; } - else - { ++ /* SELinux permission check */ ++ secid = sepgsql_cast_create(sourcetypeid, targettypeid, funcid); + + relation = heap_open(CastRelationId, RowExclusiveLock); + +*************** CreateCast(CreateCastStmt *stmt) +*** 1704,1709 **** +--- 1784,1792 ---- + + tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls); + ++ if (HeapTupleHasSecid(tuple)) ++ HeapTupleSetSecid(tuple, secid); ++ + simple_heap_insert(relation, tuple); + + CatalogUpdateIndexes(relation, tuple); *************** AlterFunctionNamespace(List *name, List *** 1897,1902 **** ---- 1977,1987 ---- +--- 1980,1988 ---- NameStr(proc->proname), newschema))); + /* SELinux checks permissions */ -+ sepgsqlCheckProcedureSetattr(procOid); -+ sepgsqlCheckSchemaRemoveName(oldNspOid); -+ sepgsqlCheckSchemaAddName(nspOid); ++ sepgsql_proc_alter(procOid, NULL, nspOid); + /* OK, modify the pg_proc row */ /* tup is a copy, so we can scribble directly on it */ +diff -Nrpc base/src/backend/commands/indexcmds.c sepgsql/src/backend/commands/indexcmds.c +*** base/src/backend/commands/indexcmds.c Thu Jun 18 10:20:52 2009 +--- sepgsql/src/backend/commands/indexcmds.c Fri Sep 18 17:02:48 2009 +*************** +*** 37,42 **** +--- 37,43 ---- + #include "parser/parse_coerce.h" + #include "parser/parse_func.h" + #include "parser/parsetree.h" ++ #include "security/sepgsql.h" + #include "storage/lmgr.h" + #include "storage/proc.h" + #include "storage/procarray.h" +*************** DefineIndex(RangeVar *heapRelation, +*** 258,263 **** +--- 259,267 ---- + } + } + ++ /* SELinux checks */ ++ sepgsql_index_create(relationId, namespaceId, check_rights); ++ + /* + * look up the access method, verify it can handle the requested features + */ diff -Nrpc base/src/backend/commands/lockcmds.c sepgsql/src/backend/commands/lockcmds.c *** base/src/backend/commands/lockcmds.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/commands/lockcmds.c Wed Jul 15 19:35:52 2009 +--- sepgsql/src/backend/commands/lockcmds.c Fri Sep 18 14:51:00 2009 *************** *** 20,25 **** --- 20,26 ---- @@ -4035,14 +4321,274 @@ diff -Nrpc base/src/backend/commands/lockcmds.c sepgsql/src/backend/commands/loc RelationGetRelationName(rel)))); + /* SELinux: check db_table:{lock} permission */ -+ sepgsqlCheckTableLock(reloid); ++ sepgsql_relation_lock(reloid); + /* * If requested, recurse to children. We use find_inheritance_children * not find_all_inheritors to avoid taking locks far in advance of +diff -Nrpc base/src/backend/commands/opclasscmds.c sepgsql/src/backend/commands/opclasscmds.c +*** base/src/backend/commands/opclasscmds.c Sat Jan 3 13:01:35 2009 +--- sepgsql/src/backend/commands/opclasscmds.c Thu Sep 17 17:04:16 2009 +*************** +*** 35,40 **** +--- 35,41 ---- + #include "parser/parse_func.h" + #include "parser/parse_oper.h" + #include "parser/parse_type.h" ++ #include "security/sepgsql.h" + #include "utils/acl.h" + #include "utils/builtins.h" + #include "utils/fmgroids.h" +*************** CreateOpFamily(char *amname, char *opfna +*** 177,182 **** +--- 178,184 ---- + HeapTuple tup; + Datum values[Natts_pg_opfamily]; + bool nulls[Natts_pg_opfamily]; ++ Oid opfSecid; + NameData opfName; + ObjectAddress myself, + referenced; +*************** CreateOpFamily(char *amname, char *opfna +*** 197,202 **** +--- 199,207 ---- + errmsg("operator family \"%s\" for access method \"%s\" already exists", + opfname, amname))); + ++ /* SELinux check permission */ ++ opfSecid = sepgsql_opfamily_create(opfname, namespaceoid); ++ + /* + * Okay, let's create the pg_opfamily entry. + */ +*************** CreateOpFamily(char *amname, char *opfna +*** 210,215 **** +--- 215,222 ---- + values[Anum_pg_opfamily_opfowner - 1] = ObjectIdGetDatum(GetUserId()); + + tup = heap_form_tuple(rel->rd_att, values, nulls); ++ if (HeapTupleHasSecid(tup)) ++ HeapTupleSetSecid(tup, opfSecid); + + opfamilyoid = simple_heap_insert(rel, tup); + +*************** DefineOpClass(CreateOpClassStmt *stmt) +*** 265,270 **** +--- 272,278 ---- + Form_pg_am pg_am; + Datum values[Natts_pg_opclass]; + bool nulls[Natts_pg_opclass]; ++ Oid opcSecid; + AclResult aclresult; + NameData opcName; + ObjectAddress myself, +*************** DefineOpClass(CreateOpClassStmt *stmt) +*** 353,358 **** +--- 361,369 ---- + NameListToString(stmt->opfamilyname), stmt->amname))); + opfamilyoid = HeapTupleGetOid(tup); + ++ /* SELinux checks permission */ ++ sepgsql_opfamily_alter(opfamilyoid, NULL); ++ + /* + * XXX given the superuser check above, there's no need for an + * ownership check here +*************** DefineOpClass(CreateOpClassStmt *stmt) +*** 371,376 **** +--- 382,390 ---- + { + opfamilyoid = HeapTupleGetOid(tup); + ++ /* SELinux checks permission */ ++ sepgsql_opfamily_alter(opfamilyoid, NULL); ++ + /* + * XXX given the superuser check above, there's no need for an + * ownership check here +*************** DefineOpClass(CreateOpClassStmt *stmt) +*** 441,446 **** +--- 455,462 ---- + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, + get_func_name(funcOid)); + #endif ++ /* SELinux check permission */ ++ sepgsql_opfamily_add_operator(opfamilyoid, operOid); + + /* Save the info */ + member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember)); +*************** DefineOpClass(CreateOpClassStmt *stmt) +*** 465,470 **** +--- 481,488 ---- + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, + get_func_name(funcOid)); + #endif ++ /* SELinux check permission */ ++ sepgsql_opfamily_add_procedure(opfamilyoid, funcOid); + + /* Save the info */ + member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember)); +*************** DefineOpClass(CreateOpClassStmt *stmt) +*** 531,536 **** +--- 549,557 ---- + errmsg("operator class \"%s\" for access method \"%s\" already exists", + opcname, stmt->amname))); + ++ /* SELinux permission check */ ++ opcSecid = sepgsql_opclass_create(opcname, namespaceoid); ++ + /* + * If we are creating a default opclass, check there isn't one already. + * (Note we do not restrict this test to visible opclasses; this ensures +*************** DefineOpFamily(CreateOpFamilyStmt *stmt) +*** 657,662 **** +--- 678,684 ---- + HeapTuple tup; + Datum values[Natts_pg_opfamily]; + bool nulls[Natts_pg_opfamily]; ++ Oid opfSecid; + AclResult aclresult; + NameData opfName; + ObjectAddress myself, +*************** DefineOpFamily(CreateOpFamilyStmt *stmt) +*** 699,704 **** +--- 721,729 ---- + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to create an operator family"))); + ++ /* SELinux permission check */ ++ opfSecid = sepgsql_opfamily_create(opfname, namespaceoid); ++ + rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock); + + /* +*************** AlterOpFamily(AlterOpFamilyStmt *stmt) +*** 773,778 **** +--- 798,804 ---- + int maxOpNumber, /* amstrategies value */ + maxProcNumber; /* amsupport value */ + HeapTuple tup; ++ Oid opfSecid; + Form_pg_am pg_am; + + /* Get necessary info about access method */ +*************** AlterOpFamily(AlterOpFamilyStmt *stmt) +*** 805,810 **** +--- 831,837 ---- + errmsg("operator family \"%s\" does not exist for access method \"%s\"", + NameListToString(stmt->opfamilyname), stmt->amname))); + opfamilyoid = HeapTupleGetOid(tup); ++ opfSecid = HeapTupleGetSecid(tup); + ReleaseSysCache(tup); + + /* +*************** AlterOpFamily(AlterOpFamilyStmt *stmt) +*** 817,822 **** +--- 844,852 ---- + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to alter an operator family"))); + ++ /* SELinux permission checks */ ++ sepgsql_opfamily_alter(opfamilyoid, NULL); ++ + /* + * ADD and DROP cases need separate code from here on down. + */ +*************** AlterOpFamilyAdd(List *opfamilyname, Oid +*** 893,898 **** +--- 923,930 ---- + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, + get_func_name(funcOid)); + #endif ++ /* SELinux permission check */ ++ sepgsql_opfamily_add_operator(opfamilyoid, operOid); + + /* Save the info */ + member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember)); +*************** AlterOpFamilyAdd(List *opfamilyname, Oid +*** 917,922 **** +--- 949,956 ---- + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, + get_func_name(funcOid)); + #endif ++ /* SELinux permission check */ ++ sepgsql_opfamily_add_procedure(opfamilyoid, funcOid); + + /* Save the info */ + member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember)); +*************** RenameOpClass(List *name, const char *ac +*** 1815,1820 **** +--- 1849,1857 ---- + aclcheck_error(aclresult, ACL_KIND_NAMESPACE, + get_namespace_name(namespaceOid)); + ++ /* SELinux permission checks */ ++ sepgsql_opclass_alter(opcOid, newname); ++ + /* rename */ + namestrcpy(&(((Form_pg_opclass) GETSTRUCT(tup))->opcname), newname); + simple_heap_update(rel, &tup->t_self, tup); +*************** RenameOpFamily(List *name, const char *a +*** 1915,1920 **** +--- 1952,1960 ---- + aclcheck_error(aclresult, ACL_KIND_NAMESPACE, + get_namespace_name(namespaceOid)); + ++ /* SELinux check permissions */ ++ sepgsql_opfamily_alter(opfOid, newname); ++ + /* rename */ + namestrcpy(&(((Form_pg_opfamily) GETSTRUCT(tup))->opfname), newname); + simple_heap_update(rel, &tup->t_self, tup); +*************** AlterOpClassOwner_internal(Relation rel, +*** 2035,2040 **** +--- 2075,2082 ---- + aclcheck_error(aclresult, ACL_KIND_NAMESPACE, + get_namespace_name(namespaceOid)); + } ++ /* SELinux permission check */ ++ sepgsql_opclass_alter(HeapTupleGetOid(tup), NULL); + + /* + * Modify the owner --- okay to scribble on tup because it's a copy +*************** AlterOpFamilyOwner_internal(Relation rel +*** 2162,2167 **** +--- 2204,2211 ---- + aclcheck_error(aclresult, ACL_KIND_NAMESPACE, + get_namespace_name(namespaceOid)); + } ++ /* SELinux permission checks */ ++ sepgsql_opfamily_alter(HeapTupleGetOid(tup), NULL); + + /* + * Modify the owner --- okay to scribble on tup because it's a copy +diff -Nrpc base/src/backend/commands/operatorcmds.c sepgsql/src/backend/commands/operatorcmds.c +*** base/src/backend/commands/operatorcmds.c Thu Jun 18 10:20:52 2009 +--- sepgsql/src/backend/commands/operatorcmds.c Thu Sep 17 22:10:19 2009 +*************** +*** 45,50 **** +--- 45,51 ---- + #include "parser/parse_func.h" + #include "parser/parse_oper.h" + #include "parser/parse_type.h" ++ #include "security/sepgsql.h" + #include "utils/acl.h" + #include "utils/lsyscache.h" + #include "utils/rel.h" +*************** AlterOperatorOwner_internal(Relation rel +*** 432,437 **** +--- 433,440 ---- + aclcheck_error(aclresult, ACL_KIND_NAMESPACE, + get_namespace_name(oprForm->oprnamespace)); + } ++ /* SELinux permission check */ ++ sepgsql_operator_alter(operOid); + + /* + * Modify the owner --- okay to scribble on tup because it's a copy diff -Nrpc base/src/backend/commands/proclang.c sepgsql/src/backend/commands/proclang.c *** base/src/backend/commands/proclang.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/commands/proclang.c Wed Jul 15 19:48:58 2009 +--- sepgsql/src/backend/commands/proclang.c Thu Sep 17 22:10:19 2009 *************** *** 30,35 **** --- 30,36 ---- @@ -4072,7 +4618,7 @@ diff -Nrpc base/src/backend/commands/proclang.c sepgsql/src/backend/commands/pro /* *************** CreateProceduralLanguage(CreatePLangStmt -*** 186,197 **** +*** 186,192 **** NIL, PointerGetDatum(NULL), 1, @@ -4080,12 +4626,7 @@ diff -Nrpc base/src/backend/commands/proclang.c sepgsql/src/backend/commands/pro } } else - valOid = InvalidOid; - - /* ok, create it */ - create_proc_lang(languageName, GetUserId(), handlerOid, valOid, - pltemplate->tmpltrusted); ---- 188,204 ---- +--- 188,195 ---- NIL, PointerGetDatum(NULL), 1, @@ -4094,31 +4635,63 @@ diff -Nrpc base/src/backend/commands/proclang.c sepgsql/src/backend/commands/pro } } else - valOid = InvalidOid; +*************** create_proc_lang(const char *languageNam +*** 275,284 **** +--- 278,293 ---- + bool nulls[Natts_pg_language]; + NameData langname; + HeapTuple tup; ++ Oid langSecid; + ObjectAddress myself, + referenced; -+ /* SELinux checks db_procedure:{install} */ -+ sepgsqlCheckProcedureInstall(handlerOid); -+ sepgsqlCheckProcedureInstall(valOid); + /* ++ * SELinux permission checks ++ */ ++ langSecid = sepgsql_language_create(languageName, handlerOid, valOid); + - /* ok, create it */ - create_proc_lang(languageName, GetUserId(), handlerOid, valOid, - pltemplate->tmpltrusted); -*************** CreateProceduralLanguage(CreatePLangStmt -*** 256,261 **** ---- 263,272 ---- - else - valOid = InvalidOid; ++ /* + * Insert the new language into pg_language + */ + rel = heap_open(LanguageRelationId, RowExclusiveLock); +*************** create_proc_lang(const char *languageNam +*** 297,302 **** +--- 306,313 ---- + nulls[Anum_pg_language_lanacl - 1] = true; -+ /* SELinux checks db_procedure:{install} */ -+ sepgsqlCheckProcedureInstall(handlerOid); -+ sepgsqlCheckProcedureInstall(valOid); + tup = heap_form_tuple(tupDesc, values, nulls); ++ if (HeapTupleHasSecid(tup)) ++ HeapTupleSetSecid(tup, langSecid); + + simple_heap_insert(rel, tup); + +*************** RenameLanguage(const char *oldname, cons +*** 518,523 **** +--- 529,537 ---- + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE, + oldname); + ++ /* SELinux permission checks */ ++ sepgsql_language_alter(HeapTupleGetOid(tup)); + - /* ok, create it */ - create_proc_lang(languageName, GetUserId(), handlerOid, valOid, - stmt->pltrusted); + /* rename */ + namestrcpy(&(((Form_pg_language) GETSTRUCT(tup))->lanname), newname); + simple_heap_update(rel, &tup->t_self, tup); +*************** AlterLanguageOwner_internal(HeapTuple tu +*** 613,618 **** +--- 627,635 ---- + /* Must be able to become new owner */ + check_is_member_of_role(GetUserId(), newOwnerId); + ++ /* SELinux permission checks */ ++ sepgsql_language_alter(HeapTupleGetOid(tup)); ++ + memset(repl_null, false, sizeof(repl_null)); + memset(repl_repl, false, sizeof(repl_repl)); + diff -Nrpc base/src/backend/commands/schemacmds.c sepgsql/src/backend/commands/schemacmds.c *** base/src/backend/commands/schemacmds.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/commands/schemacmds.c Tue Sep 8 23:55:48 2009 +--- sepgsql/src/backend/commands/schemacmds.c Thu Sep 17 17:04:16 2009 *************** *** 25,30 **** --- 25,31 ---- @@ -4141,12 +4714,13 @@ diff -Nrpc base/src/backend/commands/schemacmds.c sepgsql/src/backend/commands/s *************** CreateSchemaCommand(CreateSchemaStmt *st *** 75,80 **** ---- 77,85 ---- +--- 77,86 ---- check_is_member_of_role(saved_uid, owner_uid); + /* SELinux checks db_schema:{create} */ -+ nspsecid = sepgsqlCheckSchemaCreate(schemaName, (DefElem *)stmt->secLabel, false); ++ nspsecid = sepgsql_schema_create(schemaName, false, ++ (DefElem *)stmt->secLabel); + /* Additional check to protect reserved schema names */ if (!allowSystemTableMods && IsReservedName(schemaName)) @@ -4160,7 +4734,7 @@ diff -Nrpc base/src/backend/commands/schemacmds.c sepgsql/src/backend/commands/s /* Advance cmd counter to make the namespace visible */ CommandCounterIncrement(); ---- 99,105 ---- +--- 100,106 ---- SetUserIdAndContext(owner_uid, true); /* Create the schema's namespace */ @@ -4178,7 +4752,7 @@ diff -Nrpc base/src/backend/commands/schemacmds.c sepgsql/src/backend/commands/s CStringGetDatum(newname), 0, 0, 0))) ereport(ERROR, ---- 272,278 ---- +--- 273,279 ---- errmsg("schema \"%s\" does not exist", oldname))); /* make sure the new name doesn't exist */ @@ -4188,31 +4762,31 @@ diff -Nrpc base/src/backend/commands/schemacmds.c sepgsql/src/backend/commands/s ereport(ERROR, *************** RenameSchema(const char *oldname, const *** 286,291 **** ---- 290,298 ---- +--- 291,299 ---- aclcheck_error(aclresult, ACL_KIND_DATABASE, get_database_name(MyDatabaseId)); + /* SELinux checks db_schema:{setattr} */ -+ sepgsqlCheckSchemaSetattr(HeapTupleGetOid(tup)); ++ sepgsql_schema_alter(HeapTupleGetOid(tup)); + if (!allowSystemTableMods && IsReservedName(newname)) ereport(ERROR, (errcode(ERRCODE_RESERVED_NAME), *************** AlterSchemaOwner_internal(HeapTuple tup, *** 397,402 **** ---- 404,412 ---- +--- 405,413 ---- aclcheck_error(aclresult, ACL_KIND_DATABASE, get_database_name(MyDatabaseId)); + /* SELinux checks db_schema:{setattr} */ -+ sepgsqlCheckSchemaSetattr(HeapTupleGetOid(tup)); ++ sepgsql_schema_alter(HeapTupleGetOid(tup)); + memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); *************** AlterSchemaOwner_internal(HeapTuple tup, *** 431,433 **** ---- 441,489 ---- +--- 442,492 ---- } } @@ -4242,20 +4816,22 @@ diff -Nrpc base/src/backend/commands/schemacmds.c sepgsql/src/backend/commands/s + memset(replaces, false, sizeof(replaces)); + newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel), + NULL, NULL, replaces); ++ if (!HeapTupleHasSecid(newtup)) ++ ereport(ERROR, ++ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), ++ errmsg("Unable to set security label on \"%s\"", name))); ++ + ReleaseSysCache(oldtup); + + /* DAC permission check */ + if (!pg_namespace_ownercheck(HeapTupleGetOid(newtup), GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_NAMESPACE, name); + /* SELinux checks db_schema:{setattr relabelfrom relabelto} */ -+ secid = sepgsqlCheckSchemaRelabel(HeapTupleGetOid(newtup), secLabel); -+ if (!HeapTupleHasSecid(newtup)) -+ ereport(ERROR, -+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), -+ errmsg("Unable to set security label on \"%s\"", name))); ++ secid = sepgsql_schema_relabel(HeapTupleGetOid(newtup), secLabel); + HeapTupleSetSecid(newtup, secid); + + simple_heap_update(rel, &newtup->t_self, newtup); ++ + CatalogUpdateIndexes(rel, newtup); + + heap_freetuple(newtup); @@ -4264,7 +4840,7 @@ diff -Nrpc base/src/backend/commands/schemacmds.c sepgsql/src/backend/commands/s + } diff -Nrpc base/src/backend/commands/sequence.c sepgsql/src/backend/commands/sequence.c *** base/src/backend/commands/sequence.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/commands/sequence.c Wed Jul 15 19:37:35 2009 +--- sepgsql/src/backend/commands/sequence.c Fri Sep 18 14:51:00 2009 *************** *** 26,31 **** --- 26,32 ---- @@ -4292,7 +4868,7 @@ diff -Nrpc base/src/backend/commands/sequence.c sepgsql/src/backend/commands/seq aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, stmt->sequence->relname); + /* SELinux checks db_sequence:{setattr} */ -+ sepgsqlCheckTableSetattr(relid); ++ sepgsql_relation_alter(relid, NULL, InvalidOid); /* do the work */ AlterSequenceInternal(relid, stmt->options); @@ -4303,7 +4879,7 @@ diff -Nrpc base/src/backend/commands/sequence.c sepgsql/src/backend/commands/seq RelationGetRelationName(seqrel)))); + /* SELinux check db_sequence:{next_value} */ -+ sepgsqlCheckSequenceNextValue(elm->relid); ++ sepgsql_sequence_next_value(elm->relid); + if (elm->last != elm->cached) /* some numbers were cached */ { @@ -4315,7 +4891,7 @@ diff -Nrpc base/src/backend/commands/sequence.c sepgsql/src/backend/commands/seq RelationGetRelationName(seqrel)))); + /* SELinux check db_sequence:{get_value} */ -+ sepgsqlCheckSequenceGetValue(elm->relid); ++ sepgsql_sequence_get_value(elm->relid); + if (!elm->last_valid) ereport(ERROR, @@ -4327,7 +4903,7 @@ diff -Nrpc base/src/backend/commands/sequence.c sepgsql/src/backend/commands/seq RelationGetRelationName(seqrel)))); + /* SELinux check db_sequence:{get_value} */ -+ sepgsqlCheckSequenceGetValue(last_used_seq->relid); ++ sepgsql_sequence_get_value(last_used_seq->relid); + result = last_used_seq->last; relation_close(seqrel, NoLock); @@ -4339,14 +4915,14 @@ diff -Nrpc base/src/backend/commands/sequence.c sepgsql/src/backend/commands/seq RelationGetRelationName(seqrel)))); + /* SELinux check db_sequence:{set_value} */ -+ sepgsqlCheckSequenceSetValue(elm->relid); ++ sepgsql_sequence_set_value(elm->relid); + /* lock page' buffer and read tuple */ seq = read_info(elm, seqrel, &buf); diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/tablecmds.c *** base/src/backend/commands/tablecmds.c Sun Sep 6 19:40:49 2009 ---- sepgsql/src/backend/commands/tablecmds.c Tue Sep 8 23:55:48 2009 +--- sepgsql/src/backend/commands/tablecmds.c Thu Oct 8 09:29:32 2009 *************** *** 62,67 **** --- 62,68 ---- @@ -4357,6 +4933,25 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta #include "storage/bufmgr.h" #include "storage/lmgr.h" #include "storage/smgr.h" +*************** static void ATExecCmd(List **wqueue, Alt +*** 260,267 **** + static void ATRewriteTables(List **wqueue); + static void ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap); + static AlteredTableInfo *ATGetQueueEntry(List **wqueue, Relation rel); +! static void ATSimplePermissions(Relation rel, bool allowView); +! static void ATSimplePermissionsRelationOrIndex(Relation rel); + static void ATSimpleRecursion(List **wqueue, Relation rel, + AlterTableCmd *cmd, bool recurse); + static void ATOneLevelRecursion(List **wqueue, Relation rel, +--- 261,268 ---- + static void ATRewriteTables(List **wqueue); + static void ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap); + static AlteredTableInfo *ATGetQueueEntry(List **wqueue, Relation rel); +! static void ATSimplePermissions(Relation rel, const char *colname, bool allowView); +! static void ATSimplePermissionsRelationOrIndex(Relation rel, const char *colname); + static void ATSimpleRecursion(List **wqueue, Relation rel, + AlterTableCmd *cmd, bool recurse); + static void ATOneLevelRecursion(List **wqueue, Relation rel, *************** DefineRelation(CreateStmt *stmt, char re *** 351,356 **** --- 352,358 ---- @@ -4369,13 +4964,19 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta static char *validnsps[] = HEAP_RELOPT_NAMESPACES; *************** DefineRelation(CreateStmt *stmt, char re *** 444,449 **** ---- 446,455 ---- +--- 446,461 ---- localHasOids = interpretOidsOption(stmt->options); descriptor->tdhasoid = (localHasOids || parentOidCount > 0); + /* SELinux checks db_table:{create} and db_column:{create} */ -+ secLabels = sepgsqlCreateTableColumns(stmt, relname, namespaceId, -+ descriptor, relkind); ++ secLabels = sepgsql_relation_create(relname, ++ relkind, ++ descriptor, ++ namespaceId, ++ (DefElem *)stmt->secLabel, ++ schema, ++ false, ++ true); + /* * Find columns with default values and prepare for insertion of the @@ -4389,7 +4990,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta StoreCatalogInheritance(relationId, inheritOids); ---- 519,526 ---- +--- 525,532 ---- parentOidCount, stmt->oncommit, reloptions, @@ -4398,30 +4999,319 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta StoreCatalogInheritance(relationId, inheritOids); +*************** ExecuteTruncate(TruncateStmt *stmt) +*** 887,892 **** +--- 900,907 ---- + if (!pg_class_ownercheck(seq_relid, GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, + RelationGetRelationName(seq_rel)); ++ /* SELinux checks */ ++ sepgsql_relation_alter(seq_relid, NULL, InvalidOid); + + seq_relids = lappend_oid(seq_relids, seq_relid); + *************** truncate_check_rel(Relation rel) *** 1042,1047 **** ---- 1049,1057 ---- +--- 1057,1065 ---- errmsg("permission denied: \"%s\" is a system catalog", RelationGetRelationName(rel)))); + /* SELinux: check db_table:{delete} permission */ -+ sepgsqlCheckTableTruncate(rel); ++ sepgsql_relation_truncate(rel); + /* * We can never allow truncation of shared or nailed-in-cache relations, * because we can't support changing their relfilenode values. +*************** MergeAttributes(List *schema, List *supe +*** 1216,1221 **** +--- 1234,1241 ---- + if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, + RelationGetRelationName(relation)); ++ /* SELinux checks db_table:{setattr} */ ++ sepgsql_relation_alter(RelationGetRelid(relation), NULL, InvalidOid); + + /* + * Reject duplications in the list of parents. *************** renameatt(Oid myrelid, *** 1921,1926 **** ---- 1931,1939 ---- +--- 1941,1949 ---- errmsg("cannot rename system column \"%s\"", oldattname))); + /* SELinux checks db_column:{setattr} */ -+ sepgsqlCheckColumnSetattr(myrelid, attnum); ++ sepgsql_attribute_alter(myrelid, oldattname); + /* * if the attribute is inherited, forbid the renaming, unless we are * already inside a recursive rename. +*************** RenameRelation(Oid myrelid, const char * +*** 2026,2031 **** +--- 2049,2057 ---- + Oid namespaceId; + char relkind; + ++ /* SELinux checks */ ++ sepgsql_relation_alter(myrelid, newrelname, InvalidOid); ++ + /* + * Grab an exclusive lock on the target table, index, sequence or view, + * which we will NOT release until end of transaction. +*************** ATPrepCmd(List **wqueue, Relation rel, A +*** 2359,2372 **** + switch (cmd->subtype) + { + case AT_AddColumn: /* ADD COLUMN */ +! ATSimplePermissions(rel, false); + /* Performs own recursion */ + ATPrepAddColumn(wqueue, rel, recurse, cmd); + pass = AT_PASS_ADD_COL; + break; + case AT_AddColumnToView: /* add column via CREATE OR REPLACE + * VIEW */ +! ATSimplePermissions(rel, true); + /* Performs own recursion */ + ATPrepAddColumn(wqueue, rel, recurse, cmd); + pass = AT_PASS_ADD_COL; +--- 2385,2398 ---- + switch (cmd->subtype) + { + case AT_AddColumn: /* ADD COLUMN */ +! ATSimplePermissions(rel, NULL, false); + /* Performs own recursion */ + ATPrepAddColumn(wqueue, rel, recurse, cmd); + pass = AT_PASS_ADD_COL; + break; + case AT_AddColumnToView: /* add column via CREATE OR REPLACE + * VIEW */ +! ATSimplePermissions(rel, NULL, true); + /* Performs own recursion */ + ATPrepAddColumn(wqueue, rel, recurse, cmd); + pass = AT_PASS_ADD_COL; +*************** ATPrepCmd(List **wqueue, Relation rel, A +*** 2379,2397 **** + * substitutes default values into INSERTs before it expands + * rules. + */ +! ATSimplePermissions(rel, true); + ATSimpleRecursion(wqueue, rel, cmd, recurse); + /* No command-specific prep needed */ + pass = cmd->def ? AT_PASS_ADD_CONSTR : AT_PASS_DROP; + break; + case AT_DropNotNull: /* ALTER COLUMN DROP NOT NULL */ +! ATSimplePermissions(rel, false); + ATSimpleRecursion(wqueue, rel, cmd, recurse); + /* No command-specific prep needed */ + pass = AT_PASS_DROP; + break; + case AT_SetNotNull: /* ALTER COLUMN SET NOT NULL */ +! ATSimplePermissions(rel, false); + ATSimpleRecursion(wqueue, rel, cmd, recurse); + /* No command-specific prep needed */ + pass = AT_PASS_ADD_CONSTR; +--- 2405,2423 ---- + * substitutes default values into INSERTs before it expands + * rules. + */ +! ATSimplePermissions(rel, cmd->name, true); + ATSimpleRecursion(wqueue, rel, cmd, recurse); + /* No command-specific prep needed */ + pass = cmd->def ? AT_PASS_ADD_CONSTR : AT_PASS_DROP; + break; + case AT_DropNotNull: /* ALTER COLUMN DROP NOT NULL */ +! ATSimplePermissions(rel, cmd->name, false); + ATSimpleRecursion(wqueue, rel, cmd, recurse); + /* No command-specific prep needed */ + pass = AT_PASS_DROP; + break; + case AT_SetNotNull: /* ALTER COLUMN SET NOT NULL */ +! ATSimplePermissions(rel, cmd->name, false); + ATSimpleRecursion(wqueue, rel, cmd, recurse); + /* No command-specific prep needed */ + pass = AT_PASS_ADD_CONSTR; +*************** ATPrepCmd(List **wqueue, Relation rel, A +*** 2403,2415 **** + pass = AT_PASS_COL_ATTRS; + break; + case AT_SetStorage: /* ALTER COLUMN STORAGE */ +! ATSimplePermissions(rel, false); + ATSimpleRecursion(wqueue, rel, cmd, recurse); + /* No command-specific prep needed */ + pass = AT_PASS_COL_ATTRS; + break; + case AT_DropColumn: /* DROP COLUMN */ +! ATSimplePermissions(rel, false); + /* Recursion occurs during execution phase */ + /* No command-specific prep needed except saving recurse flag */ + if (recurse) +--- 2429,2441 ---- + pass = AT_PASS_COL_ATTRS; + break; + case AT_SetStorage: /* ALTER COLUMN STORAGE */ +! ATSimplePermissions(rel, cmd->name, false); + ATSimpleRecursion(wqueue, rel, cmd, recurse); + /* No command-specific prep needed */ + pass = AT_PASS_COL_ATTRS; + break; + case AT_DropColumn: /* DROP COLUMN */ +! ATSimplePermissions(rel, NULL, false); + /* Recursion occurs during execution phase */ + /* No command-specific prep needed except saving recurse flag */ + if (recurse) +*************** ATPrepCmd(List **wqueue, Relation rel, A +*** 2417,2429 **** + pass = AT_PASS_DROP; + break; + case AT_AddIndex: /* ADD INDEX */ +! ATSimplePermissions(rel, false); + /* This command never recurses */ + /* No command-specific prep needed */ + pass = AT_PASS_ADD_INDEX; + break; + case AT_AddConstraint: /* ADD CONSTRAINT */ +! ATSimplePermissions(rel, false); + /* Recursion occurs during execution phase */ + /* No command-specific prep needed except saving recurse flag */ + if (recurse) +--- 2443,2455 ---- + pass = AT_PASS_DROP; + break; + case AT_AddIndex: /* ADD INDEX */ +! ATSimplePermissions(rel, NULL, false); + /* This command never recurses */ + /* No command-specific prep needed */ + pass = AT_PASS_ADD_INDEX; + break; + case AT_AddConstraint: /* ADD CONSTRAINT */ +! ATSimplePermissions(rel, NULL, false); + /* Recursion occurs during execution phase */ + /* No command-specific prep needed except saving recurse flag */ + if (recurse) +*************** ATPrepCmd(List **wqueue, Relation rel, A +*** 2431,2437 **** + pass = AT_PASS_ADD_CONSTR; + break; + case AT_DropConstraint: /* DROP CONSTRAINT */ +! ATSimplePermissions(rel, false); + /* Recursion occurs during execution phase */ + /* No command-specific prep needed except saving recurse flag */ + if (recurse) +--- 2457,2463 ---- + pass = AT_PASS_ADD_CONSTR; + break; + case AT_DropConstraint: /* DROP CONSTRAINT */ +! ATSimplePermissions(rel, NULL, false); + /* Recursion occurs during execution phase */ + /* No command-specific prep needed except saving recurse flag */ + if (recurse) +*************** ATPrepCmd(List **wqueue, Relation rel, A +*** 2439,2445 **** + pass = AT_PASS_DROP; + break; + case AT_AlterColumnType: /* ALTER COLUMN TYPE */ +! ATSimplePermissions(rel, false); + /* Performs own recursion */ + ATPrepAlterColumnType(wqueue, tab, rel, recurse, recursing, cmd); + pass = AT_PASS_ALTER_TYPE; +--- 2465,2471 ---- + pass = AT_PASS_DROP; + break; + case AT_AlterColumnType: /* ALTER COLUMN TYPE */ +! ATSimplePermissions(rel, cmd->name, false); + /* Performs own recursion */ + ATPrepAlterColumnType(wqueue, tab, rel, recurse, recursing, cmd); + pass = AT_PASS_ALTER_TYPE; +*************** ATPrepCmd(List **wqueue, Relation rel, A +*** 2451,2470 **** + break; + case AT_ClusterOn: /* CLUSTER ON */ + case AT_DropCluster: /* SET WITHOUT CLUSTER */ +! ATSimplePermissions(rel, false); + /* These commands never recurse */ + /* No command-specific prep needed */ + pass = AT_PASS_MISC; + break; + case AT_AddOids: /* SET WITH OIDS */ +! ATSimplePermissions(rel, false); + /* Performs own recursion */ + if (!rel->rd_rel->relhasoids || recursing) + ATPrepAddOids(wqueue, rel, recurse, cmd); + pass = AT_PASS_ADD_COL; + break; + case AT_DropOids: /* SET WITHOUT OIDS */ +! ATSimplePermissions(rel, false); + /* Performs own recursion */ + if (rel->rd_rel->relhasoids) + { +--- 2477,2496 ---- + break; + case AT_ClusterOn: /* CLUSTER ON */ + case AT_DropCluster: /* SET WITHOUT CLUSTER */ +! ATSimplePermissions(rel, NULL, false); + /* These commands never recurse */ + /* No command-specific prep needed */ + pass = AT_PASS_MISC; + break; + case AT_AddOids: /* SET WITH OIDS */ +! ATSimplePermissions(rel, NULL, false); + /* Performs own recursion */ + if (!rel->rd_rel->relhasoids || recursing) + ATPrepAddOids(wqueue, rel, recurse, cmd); + pass = AT_PASS_ADD_COL; + break; + case AT_DropOids: /* SET WITHOUT OIDS */ +! ATSimplePermissions(rel, NULL, false); + /* Performs own recursion */ + if (rel->rd_rel->relhasoids) + { +*************** ATPrepCmd(List **wqueue, Relation rel, A +*** 2478,2491 **** + pass = AT_PASS_DROP; + break; + case AT_SetTableSpace: /* SET TABLESPACE */ +! ATSimplePermissionsRelationOrIndex(rel); + /* This command never recurses */ + ATPrepSetTableSpace(tab, rel, cmd->name); + pass = AT_PASS_MISC; /* doesn't actually matter */ + break; + case AT_SetRelOptions: /* SET (...) */ + case AT_ResetRelOptions: /* RESET (...) */ +! ATSimplePermissionsRelationOrIndex(rel); + /* This command never recurses */ + /* No command-specific prep needed */ + pass = AT_PASS_MISC; +--- 2504,2517 ---- + pass = AT_PASS_DROP; + break; + case AT_SetTableSpace: /* SET TABLESPACE */ +! ATSimplePermissionsRelationOrIndex(rel, NULL); + /* This command never recurses */ + ATPrepSetTableSpace(tab, rel, cmd->name); + pass = AT_PASS_MISC; /* doesn't actually matter */ + break; + case AT_SetRelOptions: /* SET (...) */ + case AT_ResetRelOptions: /* RESET (...) */ +! ATSimplePermissionsRelationOrIndex(rel, NULL); + /* This command never recurses */ + /* No command-specific prep needed */ + pass = AT_PASS_MISC; +*************** ATPrepCmd(List **wqueue, Relation rel, A +*** 2504,2510 **** + case AT_DisableRule: + case AT_AddInherit: /* INHERIT / NO INHERIT */ + case AT_DropInherit: +! ATSimplePermissions(rel, false); + /* These commands never recurse */ + /* No command-specific prep needed */ + pass = AT_PASS_MISC; +--- 2530,2536 ---- + case AT_DisableRule: + case AT_AddInherit: /* INHERIT / NO INHERIT */ + case AT_DropInherit: +! ATSimplePermissions(rel, NULL, false); + /* These commands never recurse */ + /* No command-specific prep needed */ + pass = AT_PASS_MISC; *************** ATRewriteTables(List **wqueue) *** 2850,2857 **** /* @@ -4432,7 +5322,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* performDeletion does CommandCounterIncrement at end */ /* ---- 2863,2871 ---- +--- 2876,2884 ---- /* * The new relation is local to our transaction and we know * nothing depends on it, so DROP_RESTRICT should be OK. @@ -4444,7 +5334,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* *************** ATRewriteTable(AlteredTableInfo *tab, Oi *** 3076,3086 **** ---- 3090,3103 ---- +--- 3103,3116 ---- if (newrel) { Oid tupOid = InvalidOid; @@ -4461,7 +5351,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta foreach(lc, dropped_attrs) *************** ATRewriteTable(AlteredTableInfo *tab, Oi *** 3112,3117 **** ---- 3129,3137 ---- +--- 3142,3150 ---- /* Preserve OID, if any */ if (newTupDesc->tdhasoid) HeapTupleSetOid(tuple, tupOid); @@ -4471,33 +5361,73 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta } /* Now check any constraints on the possibly-changed tuple */ +*************** ATGetQueueEntry(List **wqueue, Relation +*** 3213,3219 **** + * - Ensure that it is not a system table + */ + static void +! ATSimplePermissions(Relation rel, bool allowView) + { + if (rel->rd_rel->relkind != RELKIND_RELATION) + { +--- 3246,3252 ---- + * - Ensure that it is not a system table + */ + static void +! ATSimplePermissions(Relation rel, const char *colName, bool allowView) + { + if (rel->rd_rel->relkind != RELKIND_RELATION) + { *************** ATSimplePermissions(Relation rel, bool a -*** 3242,3247 **** ---- 3262,3270 ---- - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - RelationGetRelationName(rel)))); -+ -+ /* SELinux checks db_table:{setattr} */ -+ sepgsqlCheckTableSetattr(RelationGetRelid(rel)); - } +*** 3237,3242 **** +--- 3270,3281 ---- + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, + RelationGetRelationName(rel)); - /* ++ /* SELinux checks */ ++ if (!colName) ++ sepgsql_relation_alter(RelationGetRelid(rel), NULL, InvalidOid); ++ else ++ sepgsql_attribute_alter(RelationGetRelid(rel), colName); ++ + if (!allowSystemTableMods && IsSystemRelation(rel)) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), +*************** ATSimplePermissions(Relation rel, bool a +*** 3252,3258 **** + * - Ensure that it is not a system table + */ + static void +! ATSimplePermissionsRelationOrIndex(Relation rel) + { + if (rel->rd_rel->relkind != RELKIND_RELATION && + rel->rd_rel->relkind != RELKIND_INDEX) +--- 3291,3297 ---- + * - Ensure that it is not a system table + */ + static void +! ATSimplePermissionsRelationOrIndex(Relation rel, const char *colName) + { + if (rel->rd_rel->relkind != RELKIND_RELATION && + rel->rd_rel->relkind != RELKIND_INDEX) *************** ATSimplePermissionsRelationOrIndex(Relat -*** 3271,3276 **** ---- 3294,3302 ---- - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - RelationGetRelationName(rel)))); -+ -+ /* SELinux checks db_table:{setattr} */ -+ sepgsqlCheckTableSetattr(RelationGetRelid(rel)); - } +*** 3266,3271 **** +--- 3305,3316 ---- + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, + RelationGetRelationName(rel)); - /* ++ /* SELinux checks */ ++ if (!colName) ++ sepgsql_relation_alter(RelationGetRelid(rel), NULL, InvalidOid); ++ else ++ sepgsql_attribute_alter(RelationGetRelid(rel), colName); ++ + if (!allowSystemTableMods && IsSystemRelation(rel)) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), *************** ATExecAddColumn(AlteredTableInfo *tab, R *** 3509,3514 **** ---- 3535,3541 ---- +--- 3554,3560 ---- HeapTuple typeTuple; Oid typeOid; int32 typmod; @@ -4507,25 +5437,24 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta *************** ATExecAddColumn(AlteredTableInfo *tab, R *** 3546,3551 **** ---- 3573,3581 ---- +--- 3592,3600 ---- errmsg("child table \"%s\" has a conflicting \"%s\" column", RelationGetRelationName(rel), colDef->colname))); + /* SELinux checks db_column:{setattr} */ -+ sepgsqlCheckColumnSetattr(myrelid, childatt->attnum); ++ sepgsql_attribute_alter(myrelid, colDef->colname); + /* Bump the existing child att's inhcount */ childatt->attinhcount++; simple_heap_update(attrdesc, &tuple->t_self, tuple); *************** ATExecAddColumn(AlteredTableInfo *tab, R *** 3585,3590 **** ---- 3615,3624 ---- +--- 3634,3642 ---- errmsg("column \"%s\" of relation \"%s\" already exists", colDef->colname, RelationGetRelationName(rel)))); + /* SELinux checks db_column:{create} */ -+ attsecid = sepgsqlCheckColumnCreate(myrelid, colDef->colname, -+ (DefElem *)colDef->secLabel); ++ attsecid = sepgsql_attribute_create(myrelid, colDef); + /* Determine the new attribute's number */ if (isOid) @@ -4539,7 +5468,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta heap_close(attrdesc, RowExclusiveLock); ---- 3661,3667 ---- +--- 3679,3685 ---- ReleaseSysCache(typeTuple); @@ -4547,89 +5476,51 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta heap_close(attrdesc, RowExclusiveLock); -*************** ATExecDropNotNull(Relation rel, const ch -*** 3832,3837 **** ---- 3866,3874 ---- - errmsg("cannot alter system column \"%s\"", - colName))); - -+ /* SELinux checks db_column:{setattr} */ -+ sepgsqlCheckColumnSetattr(RelationGetRelid(rel), attnum); -+ - /* - * Check that the attribute is not in a primary key - */ -*************** ATExecSetNotNull(AlteredTableInfo *tab, -*** 3924,3929 **** ---- 3961,3969 ---- - errmsg("cannot alter system column \"%s\"", - colName))); - -+ /* SELinux checks db_column:{setattr} */ -+ sepgsqlCheckColumnSetattr(RelationGetRelid(rel), attnum); -+ - /* - * Okay, actually perform the catalog change ... if needed - */ -*************** ATExecColumnDefault(Relation rel, const -*** 3969,3974 **** ---- 4009,4017 ---- - errmsg("cannot alter system column \"%s\"", - colName))); - -+ /* SELinux checks db_column:{setattr} */ -+ sepgsqlCheckColumnSetattr(RelationGetRelid(rel), attnum); -+ - /* - * Remove any old default for the column. We use RESTRICT here for - * safety, but at present we do not expect anything to depend on the *************** ATPrepSetStatistics(Relation rel, const *** 4016,4021 **** ---- 4059,4066 ---- +--- 4068,4075 ---- if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, RelationGetRelationName(rel)); -+ /* SELinux checks db_table:{setatr} */ -+ sepgsqlCheckTableSetattr(RelationGetRelid(rel)); ++ /* SELinux checks */ ++ sepgsql_attribute_alter(RelationGetRelid(rel), colName); } static void -*************** ATExecSetStatistics(Relation rel, const -*** 4065,4070 **** ---- 4110,4118 ---- - errmsg("cannot alter system column \"%s\"", - colName))); - -+ /* SELinux checks db_column:{setattr} */ -+ sepgsqlCheckColumnSetattr(RelationGetRelid(rel), attrtuple->attnum); -+ - attrtuple->attstattarget = newtarget; - - simple_heap_update(attrelation, &tuple->t_self, tuple); -*************** ATExecSetStorage(Relation rel, const cha -*** 4126,4131 **** ---- 4174,4182 ---- - errmsg("cannot alter system column \"%s\"", - colName))); - -+ /* SELinux checks db_column:{setattr} */ -+ sepgsqlCheckColumnSetattr(RelationGetRelid(rel), attrtuple->attnum); -+ - /* - * safety check: do not allow toasted storage modes unless column datatype - * is TOAST-aware. *************** ATExecDropColumn(List **wqueue, Relation -*** 4202,4207 **** ---- 4253,4261 ---- +*** 4171,4177 **** - ReleaseSysCache(tuple); + /* At top level, permission check was done in ATPrepCmd, else do it */ + if (recursing) +! ATSimplePermissions(rel, false); -+ /* SELinux checks db_column:{drop} */ -+ sepgsqlCheckColumnDrop(RelationGetRelid(rel), attnum); -+ /* - * Propagate to children as appropriate. Unlike most other ALTER - * routines, we have to do this one level of recursion at a time; we can't + * get the number of the attribute +--- 4225,4231 ---- + + /* At top level, permission check was done in ATPrepCmd, else do it */ + if (recursing) +! ATSimplePermissions(rel, NULL, false); + + /* + * get the number of the attribute +*************** ATAddCheckConstraint(List **wqueue, Alte +*** 4473,4479 **** + + /* At top level, permission check was done in ATPrepCmd, else do it */ + if (recursing) +! ATSimplePermissions(rel, false); + + /* + * Call AddRelationNewConstraints to do the work, making sure it works on +--- 4527,4533 ---- + + /* At top level, permission check was done in ATPrepCmd, else do it */ + if (recursing) +! ATSimplePermissions(rel, NULL, false); + + /* + * Call AddRelationNewConstraints to do the work, making sure it works on *************** checkFkeyPermissions(Relation rel, int16 *** 5102,5108 **** aclresult = pg_class_aclcheck(RelationGetRelid(rel), roleid, @@ -4655,36 +5546,70 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta } + ok: + /* SELinux: check db_table/db_column:{reference} */ -+ sepgsqlCheckTableReference(rel, attnums, natts); ++ sepgsql_relation_references(rel, attnums, natts); } /* -*************** ATExecAlterColumnType(AlteredTableInfo * -*** 5715,5720 **** ---- 5772,5780 ---- - errmsg("cannot alter type of column \"%s\" twice", - colName))); +*************** ATExecDropConstraint(Relation rel, const +*** 5375,5381 **** + + /* At top level, permission check was done in ATPrepCmd, else do it */ + if (recursing) +! ATSimplePermissions(rel, false); + + conrel = heap_open(ConstraintRelationId, RowExclusiveLock); + +--- 5432,5438 ---- + + /* At top level, permission check was done in ATPrepCmd, else do it */ + if (recursing) +! ATSimplePermissions(rel, NULL, false); + + conrel = heap_open(ConstraintRelationId, RowExclusiveLock); -+ /* SELinux checks db_column:{setattr} */ -+ sepgsqlCheckColumnSetattr(RelationGetRelid(rel), attnum); -+ - /* Look up the target type (should not fail, since prep found it) */ - typeTuple = typenameType(NULL, typename, &targettypmod); - tform = (Form_pg_type) GETSTRUCT(typeTuple); *************** ATExecChangeOwner(Oid relationOid, Oid n *** 6308,6313 **** ---- 6368,6375 ---- +--- 6365,6372 ---- aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(namespaceOid)); } + /* SELinux checks db_table:{setattr} */ -+ sepgsqlCheckTableSetattr(relationOid); ++ sepgsql_relation_alter(relationOid, NULL, InvalidOid); } memset(repl_null, false, sizeof(repl_null)); +*************** ATExecAddInherit(Relation child_rel, Ran +*** 6912,6918 **** + * Must be owner of both parent and child -- child was checked by + * ATSimplePermissions call in ATPrepCmd + */ +! ATSimplePermissions(parent_rel, false); + + /* Permanent rels cannot inherit from temporary ones */ + if (parent_rel->rd_istemp && !child_rel->rd_istemp) +--- 6971,6977 ---- + * Must be owner of both parent and child -- child was checked by + * ATSimplePermissions call in ATPrepCmd + */ +! ATSimplePermissions(parent_rel, NULL, false); + + /* Permanent rels cannot inherit from temporary ones */ + if (parent_rel->rd_istemp && !child_rel->rd_istemp) +*************** AlterTableNamespace(RangeVar *relation, +*** 7570,7575 **** +--- 7629,7637 ---- + RelationGetRelationName(rel), + newschema))); + ++ /* SELinux checks */ ++ sepgsql_relation_alter(relid, NULL, nspOid); ++ + /* disallow renaming into or out of temp schemas */ + if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid)) + ereport(ERROR, *************** AlterSeqNamespaces(Relation classRel, Re *** 7762,7767 **** ---- 7824,7951 ---- +--- 7824,7957 ---- relation_close(depRel, AccessShareLock); } @@ -4711,18 +5636,21 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta + memset(replaces, false, sizeof(replaces)); + newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel), + NULL, NULL, replaces); -+ ReleaseSysCache(oldtup); -+ -+ /* SELinux checks db_table:{setattr relabelfrom relabelto} */ -+ secid = sepgsqlCheckTableRelabel(relid, seclabel); + if (!HeapTupleHasSecid(newtup)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("Unable to set security label on \"%s\"", + get_rel_name(relid)))); ++ ++ ReleaseSysCache(oldtup); ++ ++ /* SELinux checks db_table:{setattr relabelfrom relabelto} */ ++ secid = sepgsql_relation_relabel(relid, seclabel); ++ + HeapTupleSetSecid(newtup, secid); + + simple_heap_update(rel, &newtup->t_self, newtup); ++ + CatalogUpdateIndexes(rel, newtup); + + heap_freetuple(newtup); @@ -4752,18 +5680,21 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta + memset(replaces, false, sizeof(replaces)); + newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel), + NULL, NULL, replaces); ++ if (!HeapTupleHasSecid(newtup)) ++ ereport(ERROR, ++ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), ++ errmsg("Unable to set security context on \"%s.%s\"", ++ get_rel_name(relid), attname))); ++ + ReleaseSysCache(oldtup); + + /* SELinux checks db_column:{setattr relabelfrom relabelto} */ -+ secid = sepgsqlCheckColumnRelabel(relid, attnum, seclabel); -+ if (!HeapTupleHasSecid(newtup)) -+ ereport(ERROR, -+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), -+ errmsg("Unable to set security label on \"%s.%s\"", -+ get_rel_name(relid), attname))); ++ secid = sepgsql_attribute_relabel(relid, attnum, seclabel); ++ + HeapTupleSetSecid(newtup, secid); + + simple_heap_update(rel, &newtup->t_self, newtup); ++ + CatalogUpdateIndexes(rel, newtup); + + heap_freetuple(newtup); @@ -4815,7 +5746,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta * This code supports diff -Nrpc base/src/backend/commands/trigger.c sepgsql/src/backend/commands/trigger.c *** base/src/backend/commands/trigger.c Fri Jun 19 13:40:37 2009 ---- sepgsql/src/backend/commands/trigger.c Thu Jul 16 17:22:29 2009 +--- sepgsql/src/backend/commands/trigger.c Thu Sep 17 22:10:19 2009 *************** *** 33,38 **** --- 33,39 ---- @@ -4828,19 +5759,42 @@ diff -Nrpc base/src/backend/commands/trigger.c sepgsql/src/backend/commands/trig #include "utils/acl.h" *************** CreateTrigger(CreateTrigStmt *stmt, Oid *** 182,187 **** ---- 183,191 ---- +--- 183,192 ---- NameListToString(stmt->funcname)))); } -+ /* SELinux checks db_procedure:{install} */ -+ sepgsqlCheckProcedureInstall(funcoid); ++ /* SELinux checks */ ++ if (checkPermissions) ++ sepgsql_trigger_create(RelationGetRelid(rel), stmt->trigname, funcoid); + /* * If the command is a user-entered CREATE CONSTRAINT TRIGGER command that * references one of the built-in RI_FKey trigger functions, assume it is +*************** DropTrigger(Oid relid, const char *trign +*** 746,751 **** +--- 751,757 ---- + if (!pg_class_ownercheck(relid, GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, + get_rel_name(relid)); ++ sepgsql_trigger_drop(relid, trigname); + + object.classId = TriggerRelationId; + object.objectId = HeapTupleGetOid(tup); +*************** renametrig(Oid relid, +*** 862,867 **** +--- 868,876 ---- + */ + targetrel = heap_open(relid, AccessExclusiveLock); + ++ /* SELinux checks */ ++ sepgsql_trigger_alter(relid, oldname); ++ + /* + * Scan pg_trigger twice for existing triggers on relation. We do this in + * order to ensure a trigger does not exist with newname (The unique index diff -Nrpc base/src/backend/commands/tsearchcmds.c sepgsql/src/backend/commands/tsearchcmds.c *** base/src/backend/commands/tsearchcmds.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/commands/tsearchcmds.c Wed Jul 15 19:48:58 2009 +--- sepgsql/src/backend/commands/tsearchcmds.c Thu Sep 17 23:44:07 2009 *************** *** 35,40 **** --- 35,41 ---- @@ -4851,33 +5805,239 @@ diff -Nrpc base/src/backend/commands/tsearchcmds.c sepgsql/src/backend/commands/ #include "tsearch/ts_cache.h" #include "tsearch/ts_public.h" #include "tsearch/ts_utils.h" -*************** get_ts_parser_func(DefElem *defel, int a -*** 110,115 **** ---- 111,119 ---- - func_signature_string(funcName, nargs, typeId), - format_type_be(retTypeId)))); +*************** DefineTSParser(List *names, List *parame +*** 171,176 **** +--- 172,178 ---- + NameData pname; + Oid prsOid; + Oid namespaceoid; ++ Oid secid; -+ /* SELinux checks db_procedure:{install} */ -+ sepgsqlCheckProcedureInstall(procOid); + if (!superuser()) + ereport(ERROR, +*************** DefineTSParser(List *names, List *parame +*** 250,261 **** +--- 252,273 ---- + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("text search parser lextypes method is required"))); + ++ /* Permission checks */ ++ secid = sepgsql_ts_parser_create(prsname, namespaceoid, ++ DatumGetObjectId(values[Anum_pg_ts_parser_prsstart - 1]), ++ DatumGetObjectId(values[Anum_pg_ts_parser_prstoken - 1]), ++ DatumGetObjectId(values[Anum_pg_ts_parser_prsend - 1]), ++ DatumGetObjectId(values[Anum_pg_ts_parser_prsheadline - 1]), ++ DatumGetObjectId(values[Anum_pg_ts_parser_prslextype - 1])); + - return ObjectIdGetDatum(procOid); - } + /* + * Looks good, insert + */ + prsRel = heap_open(TSParserRelationId, RowExclusiveLock); -*************** get_ts_template_func(DefElem *defel, int -*** 948,953 **** ---- 952,960 ---- - func_signature_string(funcName, nargs, typeId), - format_type_be(retTypeId)))); + tup = heap_form_tuple(prsRel->rd_att, values, nulls); ++ if (HeapTupleHasSecid(tup)) ++ HeapTupleSetSecid(tup, secid); -+ /* SELinux checks db_procedure:{install} */ -+ sepgsqlCheckProcedureInstall(procOid); + prsOid = simple_heap_insert(prsRel, tup); + +*************** RenameTSParser(List *oldname, const char +*** 372,377 **** +--- 384,392 ---- + + prsId = TSParserGetPrsid(oldname, false); + ++ /* SELinux checks */ ++ sepgsql_ts_parser_alter(prsId, newname); + - return ObjectIdGetDatum(procOid); - } + tup = SearchSysCacheCopy(TSPARSEROID, + ObjectIdGetDatum(prsId), + 0, 0, 0); +*************** DefineTSDictionary(List *names, List *pa +*** 503,508 **** +--- 518,524 ---- + List *dictoptions = NIL; + Oid dictOid; + Oid namespaceoid; ++ Oid secid; + AclResult aclresult; + char *dictname; +*************** DefineTSDictionary(List *names, List *pa +*** 515,520 **** +--- 531,539 ---- + aclcheck_error(aclresult, ACL_KIND_NAMESPACE, + get_namespace_name(namespaceoid)); + ++ /* SELinux check */ ++ secid = sepgsql_ts_dict_create(dictname, namespaceoid); ++ + /* + * loop over the definition list and extract the information we need. + */ +*************** DefineTSDictionary(List *names, List *pa +*** 563,568 **** +--- 582,589 ---- + dictRel = heap_open(TSDictionaryRelationId, RowExclusiveLock); + + tup = heap_form_tuple(dictRel->rd_att, values, nulls); ++ if (HeapTupleHasSecid(tup)) ++ HeapTupleSetSecid(tup, secid); + + dictOid = simple_heap_insert(dictRel, tup); + +*************** RenameTSDictionary(List *oldname, const +*** 621,626 **** +--- 642,650 ---- + aclcheck_error(aclresult, ACL_KIND_NAMESPACE, + get_namespace_name(namespaceOid)); + ++ /* SELinux checks */ ++ sepgsql_ts_dict_alter(dictId, newname); ++ + namestrcpy(&(((Form_pg_ts_dict) GETSTRUCT(tup))->dictname), newname); + simple_heap_update(rel, &tup->t_self, tup); + CatalogUpdateIndexes(rel, tup); +*************** AlterTSDictionary(AlterTSDictionaryStmt +*** 762,767 **** +--- 786,794 ---- + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY, + NameListToString(stmt->dictname)); + ++ /* SELinux checks */ ++ sepgsql_ts_dict_alter(dictId, NULL); ++ + /* deserialize the existing set of options */ + opt = SysCacheGetAttr(TSDICTOID, tup, + Anum_pg_ts_dict_dictinitoption, +*************** AlterTSDictionaryOwner(List *name, Oid n +*** 889,894 **** +--- 916,923 ---- + aclcheck_error(aclresult, ACL_KIND_NAMESPACE, + get_namespace_name(namespaceOid)); + } ++ /* SELinux checks */ ++ sepgsql_ts_dict_alter(dictId, NULL); + + form->dictowner = newOwnerId; + +*************** DefineTSTemplate(List *names, List *para +*** 999,1004 **** +--- 1028,1034 ---- + NameData dname; + int i; + Oid dictOid; ++ Oid dictSecid; + Oid namespaceoid; + char *tmplname; + +*************** DefineTSTemplate(List *names, List *para +*** 1054,1059 **** +--- 1084,1094 ---- + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("text search template lexize method is required"))); + ++ /* SELinux checks */ ++ dictSecid = sepgsql_ts_template_create(tmplname, namespaceoid, ++ DatumGetObjectId(values[Anum_pg_ts_template_tmplinit - 1]), ++ DatumGetObjectId(values[Anum_pg_ts_template_tmpllexize - 1])); ++ + /* + * Looks good, insert + */ +*************** DefineTSTemplate(List *names, List *para +*** 1061,1066 **** +--- 1096,1103 ---- + tmplRel = heap_open(TSTemplateRelationId, RowExclusiveLock); + + tup = heap_form_tuple(tmplRel->rd_att, values, nulls); ++ if (HeapTupleHasSecid(tup)) ++ HeapTupleSetSecid(tup, dictSecid); + + dictOid = simple_heap_insert(tmplRel, tup); + +*************** RenameTSTemplate(List *oldname, const ch +*** 1093,1098 **** +--- 1130,1138 ---- + + tmplId = TSTemplateGetTmplid(oldname, false); + ++ /* Permission checks */ ++ sepgsql_ts_template_alter(tmplId, newname); ++ + tup = SearchSysCacheCopy(TSTEMPLATEOID, + ObjectIdGetDatum(tmplId), + 0, 0, 0); +*************** DefineTSConfiguration(List *names, List +*** 1335,1340 **** +--- 1375,1381 ---- + Oid sourceOid = InvalidOid; + Oid prsOid = InvalidOid; + Oid cfgOid; ++ Oid cfgSecid; + ListCell *pl; + + /* Convert list of names to a name and namespace */ +*************** DefineTSConfiguration(List *names, List +*** 1399,1404 **** +--- 1440,1448 ---- + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("text search parser is required"))); + ++ /* SELinux checks */ ++ cfgSecid = sepgsql_ts_config_create(cfgname, namespaceoid); ++ + /* + * Looks good, build tuple and insert + */ +*************** DefineTSConfiguration(List *names, List +*** 1414,1419 **** +--- 1458,1465 ---- + cfgRel = heap_open(TSConfigRelationId, RowExclusiveLock); + + tup = heap_form_tuple(cfgRel->rd_att, values, nulls); ++ if (HeapTupleHasSecid(tup)) ++ HeapTupleSetSecid(tup, cfgSecid); + + cfgOid = simple_heap_insert(cfgRel, tup); + +*************** RenameTSConfiguration(List *oldname, con +*** 1519,1524 **** +--- 1565,1573 ---- + aclcheck_error(aclresult, ACL_KIND_NAMESPACE, + get_namespace_name(namespaceOid)); + ++ /* permission checks */ ++ sepgsql_ts_config_alter(cfgId, newname); ++ + namestrcpy(&(((Form_pg_ts_config) GETSTRUCT(tup))->cfgname), newname); + simple_heap_update(rel, &tup->t_self, tup); + CatalogUpdateIndexes(rel, tup); +*************** AlterTSConfigurationOwner(List *name, Oi +*** 1690,1695 **** +--- 1739,1746 ---- + aclcheck_error(aclresult, ACL_KIND_NAMESPACE, + get_namespace_name(namespaceOid)); + } ++ /* SELinux checks */ ++ sepgsql_ts_config_alter(cfgId, NULL); + + form->cfgowner = newOwnerId; + +*************** AlterTSConfiguration(AlterTSConfiguratio +*** 1727,1732 **** +--- 1778,1786 ---- + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION, + NameListToString(stmt->cfgname)); + ++ /* SELinux checks */ ++ sepgsql_ts_config_alter(HeapTupleGetOid(tup), NULL); ++ + relMap = heap_open(TSConfigMapRelationId, RowExclusiveLock); + + /* Add or drop mappings */ diff -Nrpc base/src/backend/commands/typecmds.c sepgsql/src/backend/commands/typecmds.c *** base/src/backend/commands/typecmds.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/commands/typecmds.c Tue Sep 8 23:55:48 2009 +--- sepgsql/src/backend/commands/typecmds.c Thu Sep 17 22:10:19 2009 *************** *** 56,61 **** --- 56,62 ---- @@ -4890,106 +6050,104 @@ diff -Nrpc base/src/backend/commands/typecmds.c sepgsql/src/backend/commands/typ #include "utils/fmgroids.h" *************** AlterDomainDefault(List *names, Node *de *** 1543,1548 **** ---- 1544,1551 ---- +--- 1544,1550 ---- /* Check it's a domain and check user has permission for ALTER DOMAIN */ checkDomainOwner(tup, typename); -+ sepgsqlCheckSysobjSetattr(TypeRelationId, HeapTupleGetSecid(tup), -+ format_type_be(domainoid)); ++ sepgsql_type_alter(domainoid, NULL, InvalidOid); /* Setup new tuple */ MemSet(new_record, (Datum) 0, sizeof(new_record)); *************** AlterDomainNotNull(List *names, bool not *** 1671,1676 **** ---- 1674,1681 ---- +--- 1673,1679 ---- /* Check it's a domain and check user has permission for ALTER DOMAIN */ checkDomainOwner(tup, typename); -+ sepgsqlCheckSysobjSetattr(TypeRelationId, HeapTupleGetSecid(tup), -+ format_type_be(domainoid)); ++ sepgsql_type_alter(domainoid, NULL, InvalidOid); /* Is the domain already set to the desired constraint? */ if (typTup->typnotnull == notNull) *************** AlterDomainDropConstraint(List *names, c *** 1772,1777 **** ---- 1777,1784 ---- +--- 1775,1781 ---- /* Check it's a domain and check user has permission for ALTER DOMAIN */ checkDomainOwner(tup, typename); -+ sepgsqlCheckSysobjSetattr(TypeRelationId, HeapTupleGetSecid(tup), -+ format_type_be(domainoid)); ++ sepgsql_type_alter(domainoid, NULL, InvalidOid); /* Grab an appropriate lock on the pg_constraint relation */ conrel = heap_open(ConstraintRelationId, RowExclusiveLock); *************** AlterDomainAddConstraint(List *names, No *** 1848,1853 **** ---- 1855,1862 ---- +--- 1852,1858 ---- /* Check it's a domain and check user has permission for ALTER DOMAIN */ checkDomainOwner(tup, typename); -+ sepgsqlCheckSysobjSetattr(TypeRelationId, HeapTupleGetSecid(tup), -+ format_type_be(domainoid)); ++ sepgsql_type_alter(domainoid, NULL, InvalidOid); /* Check for unsupported constraint types */ if (IsA(newConstraint, FkConstraint)) *************** RenameType(List *names, const char *newT *** 2470,2475 **** ---- 2479,2490 ---- +--- 2475,2483 ---- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, format_type_be(typeOid)); + /* SELinux check permission */ -+ sepgsqlCheckSysobjSetattr(TypeRelationId, HeapTupleGetSecid(tup), -+ format_type_be(typeOid)); -+ sepgsqlCheckSchemaRemoveName(typTup->typnamespace); -+ sepgsqlCheckSchemaAddName(typTup->typnamespace); ++ sepgsql_type_alter(typeOid, newTypeName, InvalidOid); + /* * If it's a composite type, we need to check that it really is a * free-standing composite type, and not a table's rowtype. We want people *************** AlterTypeOwner(List *names, Oid newOwner *** 2590,2595 **** ---- 2605,2613 ---- +--- 2598,2605 ---- aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(typTup->typnamespace)); } + /* SELinux checks permissions */ -+ sepgsqlCheckSysobjSetattr(TypeRelationId, HeapTupleGetSecid(tup), -+ format_type_be(HeapTupleGetOid(tup))); ++ sepgsql_type_alter(HeapTupleGetOid(tup), NULL, InvalidOid); /* * If it's a composite type, invoke ATExecChangeOwner so that we fix -*************** void -*** 2680,2685 **** ---- 2698,2704 ---- - AlterTypeNamespace(List *names, const char *newschema) - { - TypeName *typename; -+ HeapTuple typtup; - Oid typeOid; - Oid nspOid; - Oid elemOid; *************** AlterTypeNamespace(List *names, const ch *** 2706,2711 **** ---- 2725,2742 ---- +--- 2716,2724 ---- errhint("You can alter type %s, which will alter the array type as well.", format_type_be(elemOid)))); + /* SELinux checks permissions */ -+ typtup = SearchSysCache(TYPEOID, -+ ObjectIdGetDatum(typeOid), -+ 0, 0, 0); -+ if (!HeapTupleIsValid(typtup)) -+ elog(ERROR, "cache lookup failed for type: %u", typeOid); -+ sepgsqlCheckSysobjSetattr(TypeRelationId, HeapTupleGetSecid(typtup), -+ format_type_be(typeOid)); -+ sepgsqlCheckSchemaRemoveName(((Form_pg_type) GETSTRUCT(typtup))->typnamespace); -+ sepgsqlCheckSchemaAddName(nspOid); -+ ReleaseSysCache(typtup); ++ sepgsql_type_alter(typeOid, NULL, nspOid); + /* and do the work */ AlterTypeNamespaceInternal(typeOid, nspOid, false, true); } +diff -Nrpc base/src/backend/commands/view.c sepgsql/src/backend/commands/view.c +*** base/src/backend/commands/view.c Thu Jun 18 10:20:52 2009 +--- sepgsql/src/backend/commands/view.c Fri Sep 18 14:51:00 2009 +*************** +*** 28,33 **** +--- 28,34 ---- + #include "rewrite/rewriteDefine.h" + #include "rewrite/rewriteManip.h" + #include "rewrite/rewriteSupport.h" ++ #include "security/sepgsql.h" + #include "utils/acl.h" + #include "utils/builtins.h" + #include "utils/lsyscache.h" +*************** DefineVirtualRelation(const RangeVar *re +*** 166,171 **** +--- 167,175 ---- + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, + RelationGetRelationName(rel)); + ++ /* SELinux checks */ ++ sepgsql_view_replace(viewOid); ++ + /* Also check it's not in use already */ + CheckTableNotInUse(rel, "CREATE OR REPLACE VIEW"); + diff -Nrpc base/src/backend/executor/execJunk.c sepgsql/src/backend/executor/execJunk.c *** base/src/backend/executor/execJunk.c Sat Jan 3 13:01:35 2009 --- sepgsql/src/backend/executor/execJunk.c Wed Jul 15 19:30:50 2009 @@ -5030,7 +6188,7 @@ diff -Nrpc base/src/backend/executor/execJunk.c sepgsql/src/backend/executor/exe * Use the given slot, or make a new slot if we weren't given one. diff -Nrpc base/src/backend/executor/execMain.c sepgsql/src/backend/executor/execMain.c *** base/src/backend/executor/execMain.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/executor/execMain.c Wed Sep 9 16:47:01 2009 +--- sepgsql/src/backend/executor/execMain.c Thu Oct 8 09:29:32 2009 *************** *** 39,44 **** --- 39,45 ---- @@ -5330,13 +6488,17 @@ diff -Nrpc base/src/backend/executor/execMain.c sepgsql/src/backend/executor/exe TupleDesc tupdesc; *************** OpenIntoRel(QueryDesc *queryDesc) *** 2871,2876 **** ---- 2982,2991 ---- +--- 2982,2995 ---- aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(namespaceId)); -+ /* SELinux checks db_table:{create} and db_column:{create} */ -+ secLabels = sepgsqlCreateTableColumns(NULL, intoName, namespaceId, -+ queryDesc->tupDesc, RELKIND_RELATION); ++ /* SELinux checks */ ++ secLabels = sepgsql_relation_create(intoName, ++ RELKIND_RELATION, ++ queryDesc->tupDesc, ++ namespaceId, ++ NULL, NIL, ++ true, true); + /* * Select tablespace to use. If not specified, use default tablespace @@ -5350,7 +6512,7 @@ diff -Nrpc base/src/backend/executor/execMain.c sepgsql/src/backend/executor/exe FreeTupleDesc(tupdesc); ---- 3044,3051 ---- +--- 3048,3055 ---- 0, into->onCommit, reloptions, @@ -5359,23 +6521,9 @@ diff -Nrpc base/src/backend/executor/execMain.c sepgsql/src/backend/executor/exe FreeTupleDesc(tupdesc); -*************** OpenIntoRel(QueryDesc *queryDesc) -*** 2956,2961 **** ---- 3072,3082 ---- - AlterTableCreateToastTable(intoRelationId, InvalidOid, reloptions, false); - - /* -+ * SELinux: checks db_table/column:{insert} permission -+ */ -+ sepgsqlCheckSelectInto(intoRelationId); -+ -+ /* - * And open the constructed table for writing. - */ - intoRelationDesc = heap_open(intoRelationId, AccessExclusiveLock); *************** intorel_receive(TupleTableSlot *slot, De *** 3054,3059 **** ---- 3175,3184 ---- +--- 3174,3183 ---- if (myState->rel->rd_rel->relhasoids) HeapTupleSetOid(tuple, InvalidOid); @@ -5388,7 +6536,7 @@ diff -Nrpc base/src/backend/executor/execMain.c sepgsql/src/backend/executor/exe myState->estate->es_output_cid, diff -Nrpc base/src/backend/executor/execQual.c sepgsql/src/backend/executor/execQual.c *** base/src/backend/executor/execQual.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/executor/execQual.c Tue Sep 8 17:13:41 2009 +--- sepgsql/src/backend/executor/execQual.c Thu Sep 17 17:04:16 2009 *************** *** 47,52 **** --- 47,53 ---- @@ -5405,7 +6553,7 @@ diff -Nrpc base/src/backend/executor/execQual.c sepgsql/src/backend/executor/exe aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(foid)); -+ sepgsqlCheckProcedureExecute(foid); ++ sepgsql_proc_execute(foid); /* * Safety check on nargs. Under normal circumstances this should never @@ -5415,7 +6563,7 @@ diff -Nrpc base/src/backend/executor/execQual.c sepgsql/src/backend/executor/exe if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(acoerce->elemfuncid)); -+ sepgsqlCheckProcedureExecute(acoerce->elemfuncid); ++ sepgsql_proc_execute(acoerce->elemfuncid); /* Set up the primary fmgr lookup information */ fmgr_info_cxt(acoerce->elemfuncid, &(astate->elemfunc), @@ -5710,7 +6858,7 @@ diff -Nrpc base/src/backend/executor/functions.c sepgsql/src/backend/executor/fu Assert(tupdesc); diff -Nrpc base/src/backend/executor/nodeAgg.c sepgsql/src/backend/executor/nodeAgg.c *** base/src/backend/executor/nodeAgg.c Sun Sep 6 19:40:49 2009 ---- sepgsql/src/backend/executor/nodeAgg.c Mon Sep 7 00:55:45 2009 +--- sepgsql/src/backend/executor/nodeAgg.c Thu Sep 17 17:04:16 2009 *************** *** 81,86 **** --- 81,87 ---- @@ -5727,7 +6875,7 @@ diff -Nrpc base/src/backend/executor/nodeAgg.c sepgsql/src/backend/executor/node if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(aggref->aggfnoid)); -+ sepgsqlCheckProcedureExecute(aggref->aggfnoid); ++ sepgsql_proc_execute(aggref->aggfnoid); peraggstate->transfn_oid = transfn_oid = aggform->aggtransfn; peraggstate->finalfn_oid = finalfn_oid = aggform->aggfinalfn; @@ -5737,7 +6885,7 @@ diff -Nrpc base/src/backend/executor/nodeAgg.c sepgsql/src/backend/executor/node if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(transfn_oid)); -+ sepgsqlCheckProcedureExecute(transfn_oid); ++ sepgsql_proc_execute(transfn_oid); if (OidIsValid(finalfn_oid)) { aclresult = pg_proc_aclcheck(finalfn_oid, aggOwner, @@ -5747,13 +6895,13 @@ diff -Nrpc base/src/backend/executor/nodeAgg.c sepgsql/src/backend/executor/node if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(finalfn_oid)); -+ sepgsqlCheckProcedureExecute(finalfn_oid); ++ sepgsql_proc_execute(finalfn_oid); } } diff -Nrpc base/src/backend/executor/nodeMergejoin.c sepgsql/src/backend/executor/nodeMergejoin.c *** base/src/backend/executor/nodeMergejoin.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/executor/nodeMergejoin.c Mon Sep 7 00:55:45 2009 +--- sepgsql/src/backend/executor/nodeMergejoin.c Thu Sep 17 17:04:16 2009 *************** *** 98,103 **** --- 98,104 ---- @@ -5770,7 +6918,7 @@ diff -Nrpc base/src/backend/executor/nodeMergejoin.c sepgsql/src/backend/executo if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(cmpproc)); -+ sepgsqlCheckProcedureExecute(cmpproc); ++ sepgsql_proc_execute(cmpproc); /* Set up the fmgr lookup information */ fmgr_info(cmpproc, &(clause->cmpfinfo)); @@ -5813,7 +6961,7 @@ diff -Nrpc base/src/backend/executor/nodeSubplan.c sepgsql/src/backend/executor/ sstate->projRight = ExecBuildProjectionInfo(righttlist, diff -Nrpc base/src/backend/executor/nodeWindowAgg.c sepgsql/src/backend/executor/nodeWindowAgg.c *** base/src/backend/executor/nodeWindowAgg.c Tue Jun 23 11:09:47 2009 ---- sepgsql/src/backend/executor/nodeWindowAgg.c Mon Sep 7 00:55:45 2009 +--- sepgsql/src/backend/executor/nodeWindowAgg.c Thu Sep 17 17:04:16 2009 *************** *** 43,48 **** --- 43,49 ---- @@ -5830,7 +6978,7 @@ diff -Nrpc base/src/backend/executor/nodeWindowAgg.c sepgsql/src/backend/executo if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(wfunc->winfnoid)); -+ sepgsqlCheckProcedureExecute(wfunc->winfnoid); ++ sepgsql_proc_execute(wfunc->winfnoid); /* Fill in the perfuncstate data */ perfuncstate->wfuncstate = wfuncstate; @@ -5840,7 +6988,7 @@ diff -Nrpc base/src/backend/executor/nodeWindowAgg.c sepgsql/src/backend/executo if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(transfn_oid)); -+ sepgsqlCheckProcedureExecute(transfn_oid); ++ sepgsql_proc_execute(transfn_oid); if (OidIsValid(finalfn_oid)) { aclresult = pg_proc_aclcheck(finalfn_oid, aggOwner, @@ -5850,7 +6998,7 @@ diff -Nrpc base/src/backend/executor/nodeWindowAgg.c sepgsql/src/backend/executo if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(finalfn_oid)); -+ sepgsqlCheckProcedureExecute(finalfn_oid); ++ sepgsql_proc_execute(finalfn_oid); } } @@ -5870,7 +7018,7 @@ diff -Nrpc base/src/backend/executor/spi.c sepgsql/src/backend/executor/spi.c { diff -Nrpc base/src/backend/libpq/be-fsstubs.c sepgsql/src/backend/libpq/be-fsstubs.c *** base/src/backend/libpq/be-fsstubs.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/libpq/be-fsstubs.c Wed Jul 15 19:48:58 2009 +--- sepgsql/src/backend/libpq/be-fsstubs.c Mon Sep 28 10:07:19 2009 *************** *** 42,50 **** --- 42,53 ---- @@ -5911,32 +7059,42 @@ diff -Nrpc base/src/backend/libpq/be-fsstubs.c sepgsql/src/backend/libpq/be-fsst return status; *************** lo_import_internal(text *filename, Oid l -*** 381,386 **** ---- 390,398 ---- +*** 364,369 **** +--- 373,381 ---- + * open the file to be read in */ - lobj = inv_open(oid, INV_WRITE, fscxt); - -+ /* SELinux checks db_blob:{write import} and file:{read} */ -+ sepgsqlCheckBlobImport(lobj, FileRawDescriptor(fd), fnamebuf); + text_to_cstring_buffer(filename, fnamebuf, sizeof(fnamebuf)); ++ /* SELinux checks db_blob:{write import} and file:{read} */ ++ //sepgsqlCheckBlobImport(lobj, fnamebuf); + - while ((nbytes = FileRead(fd, buf, BUFSIZE)) > 0) - { - tmp = inv_write(lobj, buf, nbytes); + fd = PathNameOpenFile(fnamebuf, O_RDONLY | PG_BINARY, 0666); + if (fd < 0) + ereport(ERROR, *************** lo_export(PG_FUNCTION_ARGS) -*** 448,453 **** ---- 460,468 ---- +*** 439,444 **** +--- 451,459 ---- + * world-writable export files doesn't seem wise. + */ + text_to_cstring_buffer(filename, fnamebuf, sizeof(fnamebuf)); ++ /* SELinux checks db_blob:{read export} and file:{write} */ ++ //sepgsqlCheckBlobExport(lobj, fnamebuf); ++ + oumask = umask((mode_t) 0022); + fd = PathNameOpenFile(fnamebuf, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666); + umask(oumask); +*************** lo_export(PG_FUNCTION_ARGS) +*** 447,453 **** + (errcode_for_file_access(), errmsg("could not create server file \"%s\": %m", fnamebuf))); - -+ /* SELinux checks db_blob:{read export} and file:{write} */ -+ sepgsqlCheckBlobExport(lobj, FileRawDescriptor(fd), fnamebuf); -+ +- /* * read in from the inversion file and write to the filesystem */ +--- 462,467 ---- *************** lo_truncate(PG_FUNCTION_ARGS) *** 482,493 **** ---- 497,560 ---- +--- 496,559 ---- (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("invalid large-object descriptor: %d", fd))); @@ -6207,7 +7365,7 @@ diff -Nrpc base/src/backend/optimizer/plan/createplan.c sepgsql/src/backend/opti * gating Result node that evaluates the pseudoconstants as one-time diff -Nrpc base/src/backend/optimizer/util/clauses.c sepgsql/src/backend/optimizer/util/clauses.c *** base/src/backend/optimizer/util/clauses.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/optimizer/util/clauses.c Mon Sep 7 00:55:45 2009 +--- sepgsql/src/backend/optimizer/util/clauses.c Thu Sep 17 17:04:16 2009 *************** *** 38,43 **** --- 38,44 ---- @@ -6224,7 +7382,7 @@ diff -Nrpc base/src/backend/optimizer/util/clauses.c sepgsql/src/backend/optimiz funcform->prosecdef || funcform->proretset || !heap_attisnull(func_tuple, Anum_pg_proc_proconfig) || -+ !sepgsqlHintProcedureInlined(func_tuple) || ++ !sepgsql_proc_hint_inlined(func_tuple) || funcform->pronargs != list_length(args)) return NULL; @@ -6234,7 +7392,7 @@ diff -Nrpc base/src/backend/optimizer/util/clauses.c sepgsql/src/backend/optimiz funcform->prosecdef || !funcform->proretset || !heap_attisnull(func_tuple, Anum_pg_proc_proconfig) || -+ !sepgsqlHintProcedureInlined(func_tuple) || ++ !sepgsql_proc_hint_inlined(func_tuple) || funcform->pronargs != list_length(fexpr->args)) { ReleaseSysCache(func_tuple); @@ -6812,6 +7970,30 @@ diff -Nrpc base/src/backend/parser/parse_target.c sepgsql/src/backend/parser/par /* * Check for duplicates, but only of whole columns --- we allow +diff -Nrpc base/src/backend/parser/parse_utilcmd.c sepgsql/src/backend/parser/parse_utilcmd.c +*** base/src/backend/parser/parse_utilcmd.c Thu Jun 18 10:20:52 2009 +--- sepgsql/src/backend/parser/parse_utilcmd.c Fri Sep 18 14:51:00 2009 +*************** +*** 49,54 **** +--- 49,55 ---- + #include "parser/parse_type.h" + #include "parser/parse_utilcmd.h" + #include "rewrite/rewriteManip.h" ++ #include "security/sepgsql.h" + #include "utils/acl.h" + #include "utils/builtins.h" + #include "utils/lsyscache.h" +*************** transformInhRelation(ParseState *pstate, +*** 565,570 **** +--- 566,573 ---- + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_CLASS, + RelationGetRelationName(relation)); ++ /* SELinux checks */ ++ sepgsql_relation_copy_definition(RelationGetRelid(relation)); + + tupleDesc = RelationGetDescr(relation); + constr = tupleDesc->constr; diff -Nrpc base/src/backend/postmaster/autovacuum.c sepgsql/src/backend/postmaster/autovacuum.c *** base/src/backend/postmaster/autovacuum.c Sun Sep 6 19:40:49 2009 --- sepgsql/src/backend/postmaster/autovacuum.c Sun Sep 6 19:53:10 2009 @@ -6834,7 +8016,7 @@ diff -Nrpc base/src/backend/postmaster/autovacuum.c sepgsql/src/backend/postmast { diff -Nrpc base/src/backend/postmaster/postmaster.c sepgsql/src/backend/postmaster/postmaster.c *** base/src/backend/postmaster/postmaster.c Sun Sep 6 19:40:49 2009 ---- sepgsql/src/backend/postmaster/postmaster.c Sun Sep 6 19:53:10 2009 +--- sepgsql/src/backend/postmaster/postmaster.c Tue Dec 8 14:04:25 2009 *************** *** 108,113 **** --- 108,114 ---- @@ -6859,81 +8041,92 @@ diff -Nrpc base/src/backend/postmaster/postmaster.c sepgsql/src/backend/postmast PgArchPID = 0, PgStatPID = 0, ! SysLoggerPID = 0, -! sepgsqlWorkerPID = 0; +! sepgsqlReceiverPID = 0; /* Startup/shutdown state */ #define NoShutdown 0 +*************** static void ShmemBackendArrayRemove(Back +*** 445,450 **** +--- 447,453 ---- + #define StartupDataBase() StartChildProcess(StartupProcess) + #define StartBackgroundWriter() StartChildProcess(BgWriterProcess) + #define StartWalWriter() StartChildProcess(WalWriterProcess) ++ #define StartSELinuxReceiver() StartChildProcess(SelinuxReceiverProcess) + + /* Macros to check exit status of a child process */ + #define EXIT_STATUS_0(st) ((st) == 0) *************** ServerLoop(void) *** 1436,1441 **** ---- 1438,1447 ---- +--- 1439,1449 ---- if (PgStatPID == 0 && pmState == PM_RUN) PgStatPID = pgstat_start(); -+ /* If we have lost the sepgsql worker (if needed), try to start a new one */ -+ if (sepgsqlWorkerPID == 0 && pmState == PM_RUN) -+ sepgsqlWorkerPID = sepgsqlStartupWorkerProcess(); ++ /* if we have lost the selinux netlink receiver, try to start */ ++ if (sepgsqlIsEnabled() && ++ sepgsqlReceiverPID == 0 && pmState == PM_RUN) ++ sepgsqlReceiverPID = StartSELinuxReceiver(); + /* If we need to signal the autovacuum launcher, do so now */ if (avlauncher_needs_signal) { *************** SIGHUP_handler(SIGNAL_ARGS) *** 2053,2058 **** ---- 2059,2066 ---- +--- 2061,2068 ---- signal_child(SysLoggerPID, SIGHUP); if (PgStatPID != 0) signal_child(PgStatPID, SIGHUP); -+ if (sepgsqlWorkerPID != 0) -+ signal_child(sepgsqlWorkerPID, SIGHUP); ++ if (sepgsqlReceiverPID != 0) ++ signal_child(sepgsqlReceiverPID, SIGHUP); /* Reload authentication config files too */ if (!load_hba()) *************** pmdie(SIGNAL_ARGS) *** 2113,2118 **** ---- 2121,2129 ---- +--- 2123,2131 ---- /* and the walwriter too */ if (WalWriterPID != 0) signal_child(WalWriterPID, SIGTERM); -+ /* and the sepgsql worker too */ -+ if (sepgsqlWorkerPID != 0) -+ signal_child(sepgsqlWorkerPID, SIGTERM); ++ /* and the selinux netlink receiver too */ ++ if (sepgsqlReceiverPID != 0) ++ signal_child(sepgsqlReceiverPID, SIGTERM); pmState = PM_WAIT_BACKUP; } *************** pmdie(SIGNAL_ARGS) *** 2160,2165 **** ---- 2171,2179 ---- +--- 2173,2181 ---- /* and the walwriter too */ if (WalWriterPID != 0) signal_child(WalWriterPID, SIGTERM); -+ /* and the sepgsqlWorker too */ -+ if (sepgsqlWorkerPID != 0) -+ signal_child(sepgsqlWorkerPID, SIGTERM); ++ /* and the selinux netlink receiver too */ ++ if (sepgsqlReceiverPID != 0) ++ signal_child(sepgsqlReceiverPID, SIGTERM); pmState = PM_WAIT_BACKENDS; } *************** pmdie(SIGNAL_ARGS) *** 2193,2198 **** ---- 2207,2214 ---- +--- 2209,2216 ---- signal_child(PgArchPID, SIGQUIT); if (PgStatPID != 0) signal_child(PgStatPID, SIGQUIT); -+ if (sepgsqlWorkerPID != 0) -+ signal_child(sepgsqlWorkerPID, SIGQUIT); ++ if (sepgsqlReceiverPID != 0) ++ signal_child(sepgsqlReceiverPID, SIGQUIT); ExitPostmaster(0); break; } *************** reaper(SIGNAL_ARGS) *** 2455,2460 **** ---- 2471,2486 ---- +--- 2473,2488 ---- continue; } -+ /* Was it the sepgsql worker process? */ -+ if (pid == sepgsqlWorkerPID) ++ /* Was it the selinux netlink receiver process? */ ++ if (pid == sepgsqlReceiverPID) + { -+ sepgsqlWorkerPID = 0; ++ sepgsqlReceiverPID = 0; + if (!EXIT_STATUS_0(exitstatus)) -+ LogChildExit(LOG, _("SE-PostgreSQL worker process"), ++ LogChildExit(LOG, _("SELinux netlink receiver process"), + pid, exitstatus); + continue; + } @@ -6943,20 +8136,20 @@ diff -Nrpc base/src/backend/postmaster/postmaster.c sepgsql/src/backend/postmast */ *************** HandleChildCrash(int pid, int exitstatus *** 2646,2651 **** ---- 2672,2689 ---- +--- 2674,2691 ---- signal_child(AutoVacPID, (SendStop ? SIGSTOP : SIGQUIT)); } -+ /* Take care of the sepgsql worker too */ -+ if (pid == sepgsqlWorkerPID) -+ sepgsqlWorkerPID = 0; -+ else if (sepgsqlWorkerPID != 0 && !FatalError) ++ /* Take care of the selinux netlink receiver too */ ++ if (pid == sepgsqlReceiverPID) ++ sepgsqlReceiverPID = 0; ++ else if (sepgsqlReceiverPID != 0 && !FatalError) + { + ereport(DEBUG2, + (errmsg_internal("sending %s to process %d", + (SendStop ? "SIGSTOP" : "SIGQUIT"), -+ (int) sepgsqlWorkerPID))); -+ signal_child(sepgsqlWorkerPID, (SendStop ? SIGSTOP : SIGQUIT)); ++ (int) sepgsqlReceiverPID))); ++ signal_child(sepgsqlReceiverPID, (SendStop ? SIGSTOP : SIGQUIT)); + } + /* @@ -6971,15 +8164,80 @@ diff -Nrpc base/src/backend/postmaster/postmaster.c sepgsql/src/backend/postmast { if (FatalError) { ---- 2816,2823 ---- +--- 2818,2825 ---- StartupPID == 0 && (BgWriterPID == 0 || !FatalError) && WalWriterPID == 0 && ! AutoVacPID == 0 && -! sepgsqlWorkerPID == 0) +! sepgsqlReceiverPID == 0) { if (FatalError) { +*************** StartChildProcess(AuxProcType type) +*** 4321,4326 **** +--- 4362,4373 ---- + ereport(LOG, + (errmsg("could not fork WAL writer process: %m"))); + break; ++ #ifdef HAVE_SELINUX ++ case SelinuxReceiverProcess: ++ ereport(LOG, ++ (errmsg("could not fork selinux receiver process: %m"))); ++ break; ++ #endif + default: + ereport(LOG, + (errmsg("could not fork process: %m"))); +diff -Nrpc base/src/backend/rewrite/rewriteDefine.c sepgsql/src/backend/rewrite/rewriteDefine.c +*** base/src/backend/rewrite/rewriteDefine.c Thu Jun 18 10:20:52 2009 +--- sepgsql/src/backend/rewrite/rewriteDefine.c Fri Sep 18 14:51:00 2009 +*************** +*** 27,32 **** +--- 27,33 ---- + #include "rewrite/rewriteDefine.h" + #include "rewrite/rewriteManip.h" + #include "rewrite/rewriteSupport.h" ++ #include "security/sepgsql.h" + #include "utils/acl.h" + #include "utils/builtins.h" + #include "utils/inval.h" +*************** DefineQueryRewrite(char *rulename, +*** 266,271 **** +--- 267,275 ---- + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, + RelationGetRelationName(event_relation)); + ++ /* SELinux checks */ ++ sepgsql_rule_create(event_relid, rulename); ++ + /* + * No rule actions that modify OLD or NEW + */ +diff -Nrpc base/src/backend/rewrite/rewriteRemove.c sepgsql/src/backend/rewrite/rewriteRemove.c +*** base/src/backend/rewrite/rewriteRemove.c Thu Jun 18 10:20:52 2009 +--- sepgsql/src/backend/rewrite/rewriteRemove.c Fri Sep 18 14:51:00 2009 +*************** +*** 22,27 **** +--- 22,28 ---- + #include "catalog/pg_rewrite.h" + #include "miscadmin.h" + #include "rewrite/rewriteRemove.h" ++ #include "security/sepgsql.h" + #include "utils/acl.h" + #include "utils/fmgroids.h" + #include "utils/inval.h" +*************** RemoveRewriteRule(Oid owningRel, const c +*** 78,83 **** +--- 79,87 ---- + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, + get_rel_name(eventRelationOid)); + ++ /* SELinux checks */ ++ sepgsql_rule_drop(eventRelationOid, ruleName); ++ + /* + * Do the deletion + */ diff -Nrpc base/src/backend/security/Makefile sepgsql/src/backend/security/Makefile *** base/src/backend/security/Makefile Thu Jan 1 09:00:00 1970 --- sepgsql/src/backend/security/Makefile Wed Jul 15 19:39:56 2009 @@ -7128,7 +8386,7 @@ diff -Nrpc base/src/backend/security/rowlevel.c sepgsql/src/backend/security/row + } diff -Nrpc base/src/backend/security/sepgsql/Makefile sepgsql/src/backend/security/sepgsql/Makefile *** base/src/backend/security/sepgsql/Makefile Thu Jan 1 09:00:00 1970 ---- sepgsql/src/backend/security/sepgsql/Makefile Thu Jul 16 17:22:29 2009 +--- sepgsql/src/backend/security/sepgsql/Makefile Thu Sep 17 17:04:16 2009 *************** *** 0 **** --- 1,16 ---- @@ -7142,7 +8400,7 @@ diff -Nrpc base/src/backend/security/sepgsql/Makefile sepgsql/src/backend/securi + include $(top_builddir)/src/Makefile.global + + ifeq ($(enable_selinux), yes) -+ OBJS = avc.o checker.o hooks.o label.o misc.o perms.o ++ OBJS = avc.o checker.o bridge.o hooks.o label.o misc.o perms.o + else + OBJS = dummy.o + endif @@ -7150,10 +8408,10 @@ diff -Nrpc base/src/backend/security/sepgsql/Makefile sepgsql/src/backend/securi + include $(top_srcdir)/src/backend/common.mk diff -Nrpc base/src/backend/security/sepgsql/avc.c sepgsql/src/backend/security/sepgsql/avc.c *** base/src/backend/security/sepgsql/avc.c Thu Jan 1 09:00:00 1970 ---- sepgsql/src/backend/security/sepgsql/avc.c Wed Sep 9 17:45:12 2009 +--- sepgsql/src/backend/security/sepgsql/avc.c Tue Dec 8 14:16:15 2009 *************** *** 0 **** ---- 1,894 ---- +--- 1,880 ---- + /* + * src/backend/security/sepgsql/avc.c + * SE-PostgreSQL userspace access vector cache @@ -7952,7 +9210,7 @@ diff -Nrpc base/src/backend/security/sepgsql/avc.c sepgsql/src/backend/security/ + if (c) + *c = '\0'; + -+ ereport(LOG, ++ ereport(LOG, + (errcode(ERRCODE_SELINUX_INFO), + errmsg("%s", buffer))); + @@ -7964,8 +9222,8 @@ diff -Nrpc base/src/backend/security/sepgsql/avc.c sepgsql/src/backend/security/ + { + /* switch enforcing/permissive */ + LWLockAcquire(SepgsqlAvcLock, LW_EXCLUSIVE); -+ selinux_state->version = selinux_state->version + 1; + selinux_state->enforcing = (enforce ? true : false); ++ selinux_state->version++; + LWLockRelease(SepgsqlAvcLock); + + return 0; @@ -7976,25 +9234,23 @@ diff -Nrpc base/src/backend/security/sepgsql/avc.c sepgsql/src/backend/security/ + { + /* invalidate local avc */ + LWLockAcquire(SepgsqlAvcLock, LW_EXCLUSIVE); -+ selinux_state->version = selinux_state->version + 1; ++ selinux_state->version++; + LWLockRelease(SepgsqlAvcLock); + + return 0; + } + -+ static int -+ sepgsqlWorkerMain(void) ++ void ++ sepgsqlReceiverMain(void) + { + union selinux_callback cb; + -+ ClosePostmasterPorts(false); ++ Assert(sepgsqlIsEnabled()); + -+ on_exit_reset(); -+ -+ /* -+ * map shared memory segment -+ */ -+ sepgsqlShmemInit(); ++ #ifdef HAVE_SETSID ++ if (setsid() < 0) ++ elog(FATAL, "setsid() failed: %m"); ++ #endif + + /* + * setup the signal handler @@ -8009,6 +9265,11 @@ diff -Nrpc base/src/backend/security/sepgsql/avc.c sepgsql/src/backend/security/ + pqsignal(SIGCHLD, SIG_DFL); + PG_SETMASK(&UnBlockSig); + ++ /* ++ * map shared memory segment ++ */ ++ sepgsqlShmemInit(); ++ + ereport(LOG, + (errcode(ERRCODE_SELINUX_INFO), + errmsg("SELinux: security policy monitor (pid=%u)", getpid()))); @@ -8029,31 +9290,2896 @@ diff -Nrpc base/src/backend/security/sepgsql/avc.c sepgsql/src/backend/security/ + + avc_netlink_loop(); + -+ return 0; ++ exit(0); + } -+ -+ pid_t -+ sepgsqlStartupWorkerProcess(void) -+ { -+ pid_t chld; -+ -+ if (!sepgsqlIsEnabled()) -+ return (pid_t) 0; -+ -+ chld = fork(); -+ if (chld == 0) -+ exit(sepgsqlWorkerMain()); -+ else if (chld > 0) -+ return chld; -+ -+ return (pid_t) 0; -+ } -diff -Nrpc base/src/backend/security/sepgsql/checker.c sepgsql/src/backend/security/sepgsql/checker.c -*** base/src/backend/security/sepgsql/checker.c Thu Jan 1 09:00:00 1970 ---- sepgsql/src/backend/security/sepgsql/checker.c Thu Sep 10 00:06:47 2009 +diff -Nrpc base/src/backend/security/sepgsql/bridge.c sepgsql/src/backend/security/sepgsql/bridge.c +*** base/src/backend/security/sepgsql/bridge.c Thu Jan 1 09:00:00 1970 +--- sepgsql/src/backend/security/sepgsql/bridge.c Tue Dec 1 17:11:40 2009 *************** *** 0 **** ---- 1,443 ---- +--- 1,2876 ---- ++ /* ++ * src/backend/security/sepgsql/bridge.c ++ * ++ * New style security hooks for SE-PostgreSQL ++ * ++ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group ++ * Portions Copyright (c) 1994, Regents of the University of California ++ */ ++ #include "postgres.h" ++ ++ #include "access/sysattr.h" ++ #include "catalog/heap.h" ++ #include "catalog/indexing.h" ++ #include "catalog/pg_authid.h" ++ #include "catalog/pg_cast.h" ++ #include "catalog/pg_conversion.h" ++ #include "catalog/pg_database.h" ++ #include "catalog/pg_foreign_data_wrapper.h" ++ #include "catalog/pg_foreign_server.h" ++ #include "catalog/pg_language.h" ++ #include "catalog/pg_namespace.h" ++ #include "catalog/pg_operator.h" ++ #include "catalog/pg_opclass.h" ++ #include "catalog/pg_opfamily.h" ++ #include "catalog/pg_proc.h" ++ #include "catalog/pg_rewrite.h" ++ #include "catalog/pg_security.h" ++ #include "catalog/pg_tablespace.h" ++ #include "catalog/pg_ts_parser.h" ++ #include "catalog/pg_ts_dict.h" ++ #include "catalog/pg_ts_template.h" ++ #include "catalog/pg_ts_config.h" ++ #include "catalog/pg_type.h" ++ #include "catalog/pg_user_mapping.h" ++ #include "commands/dbcommands.h" ++ #include "miscadmin.h" ++ #include "security/sepgsql.h" ++ #include "utils/builtins.h" ++ #include "utils/fmgroids.h" ++ #include "utils/lsyscache.h" ++ #include "utils/syscache.h" ++ #include "utils/tqual.h" ++ ++ #include ++ ++ /* ------------------------------------------------------------ * ++ * Common Helper Routines ++ * ------------------------------------------------------------ */ ++ static bool sepgsql_database_common(Oid datOid, uint32 required, bool abort); ++ static bool sepgsql_schema_common(Oid nspOid, uint32 required, bool abort); ++ static bool sepgsql_attribute_common(Oid relOid, AttrNumber attnum, ++ uint32 required, bool abort); ++ static bool sepgsql_relation_common(Oid relOid, uint32 required, bool abort); ++ static bool sepgsql_proc_common(Oid procOid, uint32 required, bool abort); ++ static bool sepgsql_fdw_common(Oid fdwOid, uint32 required, bool abort); ++ static bool sepgsql_foreign_server_common(Oid fsrvOid, uint32 required, bool abort); ++ static bool sepgsql_language_common(Oid langOid, uint32 required, bool abort); ++ static bool sepgsql_operator_common(Oid oprOid, uint32 required, bool abort); ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_database related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ static bool ++ sepgsql_database_common(Oid datOid, uint32 required, bool abort) ++ { ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ const char *auname; ++ bool rc; ++ ++ tuple = SearchSysCache(DATABASEOID, ++ ObjectIdGetDatum(datOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for database: %u", datOid); ++ ++ auname = NameStr(((Form_pg_database) GETSTRUCT(tuple))->datname); ++ ++ sid = sepgsqlGetTupleSecid(DatabaseRelationId, tuple, &tclass); ++ ++ rc = sepgsqlClientHasPerms(sid, tclass, required, auname, abort); ++ ++ ReleaseSysCache(tuple); ++ ++ return rc; ++ } ++ ++ Oid ++ sepgsql_database_create(const char *datName, DefElem *newLabel) ++ { ++ sepgsql_sid_t sid; ++ ++ if (!sepgsqlIsEnabled()) ++ return InvalidOid; ++ ++ if (!newLabel) ++ sid = sepgsqlGetDefaultDatabaseSecid(); ++ else ++ { ++ sid.relid = DatabaseRelationId; ++ sid.secid = securityTransSecLabelIn(sid.relid, ++ strVal(newLabel->arg)); ++ } ++ ++ sepgsqlClientHasPerms(sid, SEPG_CLASS_DB_DATABASE, ++ SEPG_DB_DATABASE__CREATE, ++ datName, true); ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_database_alter(Oid datOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_database_common(datOid, SEPG_DB_DATABASE__SETATTR, true); ++ } ++ ++ void ++ sepgsql_database_drop(Oid datOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_database_common(datOid, SEPG_DB_DATABASE__DROP, true); ++ } ++ ++ Oid ++ sepgsql_database_relabel(Oid datOid, DefElem *newLabel) ++ { ++ sepgsql_sid_t sid; ++ ++ if (!sepgsqlIsEnabled()) ++ { ++ if (newLabel) ++ ereport(ERROR, ++ (errcode(ERRCODE_SELINUX_ERROR), ++ errmsg("SELinux is disabled now"))); ++ ++ return InvalidOid; ++ } ++ sid.relid = DatabaseRelationId; ++ sid.secid = securityTransSecLabelIn(sid.relid, strVal(newLabel->arg)); ++ ++ /* db_database:{setattr relabelfrom} to older seclabel */ ++ sepgsql_database_common(datOid, ++ SEPG_DB_DATABASE__SETATTR | ++ SEPG_DB_DATABASE__RELABELFROM, true); ++ ++ /* db_database:{relabelto} to newer seclabel */ ++ sepgsqlClientHasPerms(sid, ++ SEPG_CLASS_DB_DATABASE, ++ SEPG_DB_DATABASE__RELABELTO, ++ get_database_name(datOid), true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_database_grant(Oid datOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_database_common(datOid, SEPG_DB_DATABASE__SETATTR, true); ++ } ++ ++ void ++ sepgsql_database_access(Oid datOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_database_common(datOid, SEPG_DB_DATABASE__ACCESS, true); ++ } ++ ++ bool ++ sepgsql_database_superuser(Oid datOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return true; ++ ++ return sepgsql_database_common(datOid, SEPG_DB_DATABASE__SUPERUSER, false); ++ } ++ ++ void ++ sepgsql_database_load_module(Oid datOid, const char *filename) ++ { ++ HeapTuple tuple; ++ security_context_t filecon; ++ security_context_t datcon; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ /* ++ * It assumes preloaded libraries are secure, ++ * because it can be set up using guc variable ++ * not any SQL statements. ++ */ ++ if (GetProcessingMode() == InitProcessing) ++ return; ++ ++ /* Get database context */ ++ tuple = SearchSysCache(DATABASEOID, ++ ObjectIdGetDatum(datOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for database: %u", datOid); ++ ++ datcon = securityRawSecLabelOut(DatabaseRelationId, ++ HeapTupleGetSecid(tuple)); ++ ReleaseSysCache(tuple); ++ ++ /* Get library context */ ++ if (getfilecon_raw(filename, &filecon) < 0) ++ ereport(ERROR, ++ (errcode_for_file_access(), ++ errmsg("could not access file \"%s\": %m", filename))); ++ PG_TRY(); ++ { ++ sepgsqlComputePerms(datcon, ++ filecon, ++ SEPG_CLASS_DB_DATABASE, ++ SEPG_DB_DATABASE__LOAD_MODULE, ++ filename, true); ++ } ++ PG_CATCH(); ++ { ++ freecon(filecon); ++ PG_RE_THROW(); ++ } ++ PG_END_TRY(); ++ freecon(filecon); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_namespace related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ static bool ++ sepgsql_schema_common(Oid nspOid, uint32 required, bool abort) ++ { ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ const char *auname; ++ bool rc; ++ ++ tuple = SearchSysCache(NAMESPACEOID, ++ ObjectIdGetDatum(nspOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for namespace: %u", nspOid); ++ ++ sid = sepgsqlGetTupleSecid(NamespaceRelationId, tuple, &tclass); ++ ++ auname = NameStr(((Form_pg_namespace) GETSTRUCT(tuple))->nspname); ++ ++ rc = sepgsqlClientHasPerms(sid, tclass, required, auname, abort); ++ ++ ReleaseSysCache(tuple); ++ ++ return rc; ++ } ++ ++ Oid ++ sepgsql_schema_create(const char *nspName, bool isTemp, DefElem *newLabel) ++ { ++ sepgsql_sid_t sid; ++ ++ if (!sepgsqlIsEnabled()) ++ return InvalidOid; ++ ++ if (!newLabel) ++ sid = sepgsqlGetDefaultSchemaSecid(MyDatabaseId); ++ else ++ { ++ sid.relid = NamespaceRelationId; ++ sid.secid = securityTransSecLabelIn(sid.relid, strVal(newLabel->arg)); ++ } ++ ++ sepgsqlClientHasPerms(sid, ++ SEPG_CLASS_DB_SCHEMA, ++ SEPG_DB_SCHEMA__CREATE, ++ nspName, true); ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_schema_alter(Oid nspOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_schema_common(nspOid, SEPG_DB_SCHEMA__SETATTR, true); ++ } ++ ++ void ++ sepgsql_schema_drop(Oid nspOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_schema_common(nspOid, SEPG_DB_SCHEMA__DROP, true); ++ } ++ ++ Oid ++ sepgsql_schema_relabel(Oid nspOid, DefElem *newLabel) ++ { ++ sepgsql_sid_t sid; ++ ++ if (!sepgsqlIsEnabled()) ++ { ++ if (newLabel) ++ ereport(ERROR, ++ (errcode(ERRCODE_SELINUX_ERROR), ++ errmsg("SELinux is disabled now"))); ++ return InvalidOid; ++ } ++ sid.relid = NamespaceRelationId; ++ sid.secid = securityTransSecLabelIn(sid.relid, strVal(newLabel->arg)); ++ ++ /* db_schema:{setattr relabelfrom} for older seclabel */ ++ sepgsql_schema_common(nspOid, ++ SEPG_DB_SCHEMA__SETATTR | ++ SEPG_DB_SCHEMA__RELABELFROM, true); ++ ++ /* db_schema:{relabelto} for newer seclabel */ ++ sepgsqlClientHasPerms(sid, ++ SEPG_CLASS_DB_SCHEMA, ++ SEPG_DB_SCHEMA__RELABELTO, ++ get_namespace_name(nspOid), true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_schema_grant(Oid nspOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_schema_common(nspOid, SEPG_DB_SCHEMA__SETATTR, true); ++ } ++ ++ bool ++ sepgsql_schema_search(Oid nspOid, bool abort) ++ { ++ if (!sepgsqlIsEnabled()) ++ return true; ++ ++ return sepgsql_schema_common(nspOid, SEPG_DB_SCHEMA__SEARCH, abort); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_attribute related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ static bool ++ sepgsql_attribute_common(Oid relOid, AttrNumber attnum, ++ uint32 required, bool abort) ++ { ++ Form_pg_attribute attForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ char auname[NAMEDATALEN * 2 + 3]; ++ bool rc = true; ++ ++ /* Caller prevent case when relkind != RELKIND_RELATION */ ++ Assert(get_rel_relkind(relOid) == RELKIND_RELATION); ++ ++ tuple = SearchSysCache(ATTNUM, ++ ObjectIdGetDatum(relOid), ++ Int16GetDatum(attnum), ++ 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for attribute %d of relation %u", ++ attnum, relOid); ++ attForm = (Form_pg_attribute) GETSTRUCT(tuple); ++ ++ /* ++ * NOTE: when a table to be dropped, corresponding attributes ++ * are also removed. Some of them can be already logically ++ * dropped using ALTER TABLE ... DROP statement. ++ * In this case, SE-PostgreSQL does not check anything. ++ * If any other situation touches dropped column, it is a bug. ++ */ ++ if (attForm->attisdropped) ++ goto skip; ++ ++ sprintf(auname, "%s.%s", get_rel_name(relOid), NameStr(attForm->attname)); ++ ++ sid = sepgsqlGetTupleSecid(AttributeRelationId, tuple, &tclass); ++ ++ rc = sepgsqlClientHasPerms(sid, tclass, required, auname, abort); ++ ++ skip: ++ ReleaseSysCache(tuple); ++ ++ return rc; ++ } ++ ++ Oid ++ sepgsql_attribute_create(Oid relOid, ColumnDef *cdef) ++ { ++ sepgsql_sid_t sid; ++ char relkind; ++ ++ if (!sepgsqlIsEnabled()) ++ { ++ if (cdef->secLabel) ++ ereport(ERROR, ++ (errcode(ERRCODE_SELINUX_ERROR), ++ errmsg("SELinux is disabled now"))); ++ return InvalidOid; ++ } ++ ++ relkind = get_rel_relkind(relOid); ++ if (relkind == RELKIND_RELATION) ++ { ++ char auname[NAMEDATALEN * 2 + 3]; ++ ++ if (!cdef->secLabel) ++ sid = sepgsqlGetDefaultColumnSecid(relOid); ++ else ++ { ++ char *label = strVal(((DefElem *)cdef->secLabel)->arg); ++ ++ sid.relid = AttributeRelationId; ++ sid.secid = securityTransSecLabelIn(sid.relid, label); ++ } ++ ++ sprintf(auname, "%s.%s", get_rel_name(relOid), cdef->colname); ++ sepgsqlClientHasPerms(sid, ++ SEPG_CLASS_DB_COLUMN, ++ SEPG_DB_COLUMN__CREATE, ++ auname, true); ++ } ++ else ++ { ++ /* no need to check for toast relation */ ++ if (relkind != RELKIND_TOASTVALUE) ++ sepgsql_relation_common(relOid, SEPG_DB_TABLE__SETATTR, true); ++ return InvalidOid; ++ } ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_attribute_alter(Oid relOid, const char *attname) ++ { ++ AttrNumber attno; ++ char relkind; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ /* ++ * If the target attribute does not exist, an error ++ * shall be raised later. ++ */ ++ attno = get_attnum(relOid, attname); ++ if (attno == InvalidAttrNumber) ++ return; ++ ++ relkind = get_rel_relkind(relOid); ++ if (relkind == RELKIND_RELATION) ++ { ++ sepgsql_attribute_common(relOid, attno, SEPG_DB_COLUMN__SETATTR, true); ++ } ++ else if (relkind != RELKIND_TOASTVALUE) ++ { ++ sepgsql_relation_common(relOid, SEPG_DB_TABLE__SETATTR, true); ++ } ++ } ++ ++ void ++ sepgsql_attribute_drop(Oid relOid, AttrNumber attnum) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ /* ++ * We only need to check db_column:{drop} when relkind equals ++ * RELKIND_RELATION, because db_xxx:{drop} permission is already ++ * checked in other cases. (e.g DROP SEQUENCE, ...) ++ */ ++ if (get_rel_relkind(relOid) == RELKIND_RELATION) ++ sepgsql_attribute_common(relOid, attnum, ++ SEPG_DB_COLUMN__DROP, true); ++ } ++ ++ void ++ sepgsql_attribute_grant(Oid relOid, AttrNumber attnum) ++ { ++ char relkind; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ relkind = get_rel_relkind(relOid); ++ if (relkind == RELKIND_RELATION) ++ { ++ sepgsql_attribute_common(relOid, attnum, SEPG_DB_COLUMN__SETATTR, true); ++ } ++ else if (relkind != RELKIND_TOASTVALUE) ++ { ++ sepgsql_relation_common(relOid, SEPG_DB_TABLE__SETATTR, true); ++ } ++ } ++ ++ Oid ++ sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum, DefElem *newLabel) ++ { ++ sepgsql_sid_t sid; ++ char auname[NAMEDATALEN * 2 + 3]; ++ ++ if (!sepgsqlIsEnabled()) ++ { ++ if (!newLabel) ++ ereport(ERROR, ++ (errcode(ERRCODE_SELINUX_ERROR), ++ errmsg("SELinux is disabled now"))); ++ return InvalidOid; ++ } ++ ++ Assert(get_rel_relkind(relOid) == RELKIND_RELATION); ++ ++ sid.relid = AttributeRelationId; ++ sid.secid = securityTransSecLabelIn(sid.relid, strVal(newLabel->arg)); ++ ++ /* db_column:{setattr relabelfrom} */ ++ sepgsql_attribute_common(relOid, attnum, ++ SEPG_DB_COLUMN__SETATTR | ++ SEPG_DB_COLUMN__RELABELFROM, true); ++ ++ /* db_column:{relabelto} */ ++ sprintf(auname, "%s.%s", ++ get_rel_name(relOid), ++ get_attname(relOid, attnum)); ++ sepgsqlClientHasPerms(sid, ++ SEPG_CLASS_DB_COLUMN, ++ SEPG_DB_COLUMN__RELABELTO, ++ auname, true); ++ ++ return sid.secid; ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_class related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ static bool ++ sepgsql_relation_common(Oid relOid, uint32 required, bool abort) ++ { ++ Form_pg_class relForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ bool rc; ++ ++ tuple = SearchSysCache(RELOID, ++ ObjectIdGetDatum(relOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for relation %u", relOid); ++ relForm = (Form_pg_class) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(RelationRelationId, tuple, &tclass); ++ rc = sepgsqlClientHasPerms(sid, tclass, required, ++ NameStr(relForm->relname), abort); ++ ++ ReleaseSysCache(tuple); ++ ++ return rc; ++ } ++ ++ /* ++ * sepgsql_relation_create ++ * It returns an array of security identifier for the new table ++ * and columns to be assigned. The corresponding security labels ++ * are already checked for db_table/db_sequence/db_column:{create} ++ * permission. ++ * In the default labeling rule, a column inherits the security ++ * label of its table, but we cannot refer it using system caches, ++ * because the command counter is not incremented under the ++ * heap_create_with_catalog(). Thus, we need to compute and check ++ * them prior to the actual creation of table and columns. ++ */ ++ Oid * ++ sepgsql_relation_create(const char *relName, ++ char relkind, ++ TupleDesc tupDesc, ++ Oid nspOid, ++ DefElem *relLabel, ++ List *colList, ++ bool createAs, ++ bool permission) ++ { ++ Oid *secLabels; ++ sepgsql_sid_t relsid; ++ uint16 tclass; ++ uint32 required; ++ int index; ++ ++ if (!sepgsqlIsEnabled()) ++ return NULL; ++ ++ switch (relkind) ++ { ++ case RELKIND_RELATION: ++ if (!relLabel) ++ relsid = sepgsqlGetDefaultTableSecid(nspOid); ++ else ++ { ++ relsid.relid = RelationRelationId; ++ relsid.secid = securityTransSecLabelIn(relsid.relid, ++ strVal(relLabel->arg)); ++ } ++ tclass = SEPG_CLASS_DB_TABLE; ++ required = SEPG_DB_TABLE__CREATE; ++ if (createAs) ++ required |= SEPG_DB_TABLE__INSERT; ++ break; ++ ++ case RELKIND_SEQUENCE: ++ if (!relLabel) ++ relsid = sepgsqlGetDefaultSequenceSecid(nspOid); ++ else ++ { ++ relsid.relid = RelationRelationId; ++ relsid.secid = securityTransSecLabelIn(relsid.relid, ++ strVal(relLabel->arg)); ++ } ++ tclass = SEPG_CLASS_DB_SEQUENCE; ++ required = SEPG_DB_SEQUENCE__CREATE; ++ break; ++ ++ default: ++ if (!relLabel) ++ relsid = sepgsqlGetDefaultTupleSecid(RelationRelationId); ++ else ++ { ++ /* should not be happen */ ++ relsid.relid = RelationRelationId; ++ relsid.secid = securityTransSecLabelIn(relsid.relid, ++ strVal(relLabel->arg)); ++ } ++ tclass = SEPG_CLASS_DB_TUPLE; ++ required = SEPG_DB_TUPLE__INSERT; ++ break; ++ } ++ ++ /* ++ * The secLabeld array stores security identifiers to be assigned ++ * on the new table and columns. ++ * ++ * secLabels[0] is security identifier of the table. ++ * secLabels[attnum - FirstLowInvalidHeapAttributeNumber] ++ * is security identifier of columns (if necessary). ++ */ ++ secLabels = palloc0(sizeof(Oid) * (tupDesc->natts ++ - FirstLowInvalidHeapAttributeNumber)); ++ ++ /* relation's security identifier to be assigned on */ ++ secLabels[0] = relsid.secid; ++ ++ /* ++ * Note that this hook can be called during initdb processes. ++ * It is an exception of access controls, so we skip any checks. ++ * ++ * And, we don't need any checks for toast relations, because ++ * it is a quite internal stuff. ++ */ ++ if (permission) ++ { ++ /* db_schema:{add_name} */ ++ sepgsql_schema_common(nspOid, SEPG_DB_SCHEMA__ADD_NAME, true); ++ ++ /* db_table:{create}, db_sequence:{create} or db_tuple:{insert} */ ++ sepgsqlClientHasPerms(relsid, tclass, required, relName, true); ++ } ++ ++ /* no individual security context expect for RELKIND_RELATION */ ++ if (relkind != RELKIND_RELATION) ++ return secLabels; ++ ++ /* ++ * db_column:{create} permission ++ */ ++ for (index = FirstLowInvalidHeapAttributeNumber + 1; ++ index < tupDesc->natts; ++ index++) ++ { ++ Form_pg_attribute attr; ++ sepgsql_sid_t attsid = { InvalidOid, InvalidOid }; ++ char attname[NAMEDATALEN * 2 + 3]; ++ ListCell *l; ++ ++ /* skip unnecessary attributes */ ++ if (index == ObjectIdAttributeNumber && !tupDesc->tdhasoid) ++ continue; ++ ++ if (index < 0) ++ attr = SystemAttributeDefinition(index, tupDesc->tdhasoid); ++ else ++ attr = tupDesc->attrs[index]; ++ ++ /* Is there any given security context? */ ++ foreach (l, colList) ++ { ++ ColumnDef *cdef = lfirst(l); ++ ++ if (cdef->secLabel && ++ strcmp(cdef->colname, NameStr(attr->attname)) == 0) ++ { ++ attsid.relid = AttributeRelationId; ++ attsid.secid = securityTransSecLabelIn(attsid.relid, ++ strVal(((DefElem *)cdef->secLabel)->arg)); ++ break; ++ } ++ } ++ ++ /* default security context, if not given */ ++ if (!SidIsValid(attsid)) ++ attsid = sepgsqlClientCreateSecid(relsid, ++ SEPG_CLASS_DB_COLUMN, ++ AttributeRelationId); ++ if (permission) ++ { ++ required = SEPG_DB_COLUMN__CREATE; ++ ++ if (createAs) ++ required |= SEPG_DB_COLUMN__INSERT; ++ ++ /* db_column:{create (insert)} */ ++ sprintf(attname, "%s.%s", relName, NameStr(attr->attname)); ++ sepgsqlClientHasPerms(attsid, ++ SEPG_CLASS_DB_COLUMN, ++ required, attname, true); ++ } ++ /* column's security identifier to be assigend on */ ++ secLabels[index - FirstLowInvalidHeapAttributeNumber] = attsid.secid; ++ } ++ ++ return secLabels; ++ } ++ ++ /* ++ * sepgsql_relation_copy ++ * It returns an array of security identifier of table and columns ++ * to be copied on make_new_heap(). It actually create a new temporary ++ * relation and insert all the tuples within original one into the ++ * temporary one, but swap_relation_files() swaps their file nodes. ++ * Thus, there are no changes from the viewpoint of users. ++ * SE-PostgreSQL also does not check and change anything. It simply ++ * copies security identifier of the source relation to the destination ++ * relation. ++ */ ++ Oid * ++ sepgsql_relation_copy(Relation src) ++ { ++ Oid *secLabels; ++ HeapTuple tuple; ++ Oid relOid = RelationGetRelid(src); ++ int index; ++ ++ if (!sepgsqlIsEnabled()) ++ return NULL; ++ ++ /* see the comment at sepgsqlCreateTableColumn*/ ++ secLabels = palloc0(sizeof(Oid) * (RelationGetDescr(src)->natts ++ - FirstLowInvalidHeapAttributeNumber)); ++ ++ /* copy table's security identifier */ ++ tuple = SearchSysCache(RELOID, ++ ObjectIdGetDatum(relOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for relation \"%s\"", ++ RelationGetRelationName(src)); ++ ++ secLabels[0] = HeapTupleGetSecid(tuple); ++ ++ ReleaseSysCache(tuple); ++ ++ /* copy column's security identifier */ ++ for (index = FirstLowInvalidHeapAttributeNumber + 1; ++ index < RelationGetDescr(src)->natts; ++ index++) ++ { ++ Form_pg_attribute attr; ++ ++ if (index < 0) ++ attr = SystemAttributeDefinition(index, true); ++ else ++ attr = RelationGetDescr(src)->attrs[index]; ++ ++ tuple = SearchSysCache(ATTNUM, ++ ObjectIdGetDatum(relOid), ++ Int16GetDatum(attr->attnum), ++ 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ continue; ++ ++ secLabels[index - FirstLowInvalidHeapAttributeNumber] ++ = HeapTupleGetSecid(tuple); ++ ++ ReleaseSysCache(tuple); ++ } ++ ++ return secLabels; ++ } ++ ++ void ++ sepgsql_relation_alter(Oid relOid, const char *newName, Oid newNsp) ++ { ++ Form_pg_class relForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(RELOID, ++ ObjectIdGetDatum(relOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for relation %u", relOid); ++ relForm = (Form_pg_class) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(RelationRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TABLE__SETATTR, ++ NameStr(relForm->relname), true); ++ ++ /* db_schema:{add_name remove_name}, if necessary */ ++ if (newName || OidIsValid(newNsp)) ++ { ++ if (!OidIsValid(newNsp)) ++ sepgsql_schema_common(relForm->relnamespace, ++ SEPG_DB_SCHEMA__ADD_NAME | ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ else ++ { ++ sepgsql_schema_common(relForm->relnamespace, ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ sepgsql_schema_common(newNsp, SEPG_DB_SCHEMA__ADD_NAME, true); ++ } ++ } ++ ReleaseSysCache(tuple); ++ } ++ ++ void ++ sepgsql_relation_drop(Oid relOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ if (get_rel_relkind(relOid) == RELKIND_TOASTVALUE) ++ return; ++ ++ sepgsql_relation_common(relOid, SEPG_DB_TABLE__DROP, true); ++ } ++ ++ void ++ sepgsql_relation_grant(Oid relOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_relation_common(relOid, SEPG_DB_TABLE__SETATTR, true); ++ } ++ ++ Oid ++ sepgsql_relation_relabel(Oid relOid, DefElem *newLabel) ++ { ++ sepgsql_sid_t sid; ++ char relkind; ++ ++ if (!sepgsqlIsEnabled()) ++ { ++ if (newLabel) ++ ereport(ERROR, ++ (errcode(ERRCODE_SELINUX_ERROR), ++ errmsg("SELinux is disabled now"))); ++ return InvalidOid; ++ } ++ ++ relkind = get_rel_relkind(relOid); ++ if (relkind != RELKIND_RELATION && relkind != RELKIND_SEQUENCE) ++ ereport(ERROR, ++ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), ++ errmsg("Unable to set security label on \"%s\"", ++ get_rel_name(relOid)))); ++ ++ /* input security context */ ++ sid.relid = RelationRelationId; ++ sid.secid = securityTransSecLabelIn(sid.relid, strVal(newLabel->arg)); ++ ++ /* db_table/db_sequence:{setattr relabelfrom} */ ++ sepgsql_relation_common(relOid, ++ SEPG_DB_TABLE__SETATTR | ++ SEPG_DB_TABLE__RELABELFROM, true); ++ ++ /* db_table/db_sequence:{relabelto} */ ++ sepgsqlClientHasPerms(sid, ++ (relkind == RELKIND_RELATION ++ ? SEPG_CLASS_DB_TABLE ++ : SEPG_CLASS_DB_SEQUENCE), ++ SEPG_DB_TABLE__RELABELTO, ++ get_rel_name(relOid), true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_relation_get_transaction_id(Oid relOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_relation_common(relOid, SEPG_DB_TABLE__GETATTR, true); ++ } ++ ++ void ++ sepgsql_relation_copy_definition(Oid relOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_relation_common(relOid, SEPG_DB_TABLE__GETATTR, true); ++ } ++ ++ void ++ sepgsql_relation_truncate(Relation rel) ++ { ++ HeapScanDesc scan; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ Assert(RelationGetForm(rel)->relkind == RELKIND_RELATION); ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ /* check db_table:{delete} permission */ ++ sepgsql_relation_common(RelationGetRelid(rel), ++ SEPG_DB_TABLE__DELETE, true); ++ ++ /* row-level access control is enabled? */ ++ if (!sepostgresql_row_level) ++ return; ++ ++ /* check db_tuple:{delete} permission */ ++ scan = heap_beginscan(rel, SnapshotNow, 0, NULL); ++ ++ while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) ++ { ++ sid = sepgsqlGetTupleSecid(RelationGetRelid(rel), tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__DELETE, ++ NULL, true); ++ } ++ heap_endscan(scan); ++ } ++ ++ void ++ sepgsql_relation_references(Relation rel, int16 *attnums, int natts) ++ { ++ Oid relOid = RelationGetRelid(rel); ++ int i; ++ ++ Assert(RelationGetForm(rel)->relkind == RELKIND_RELATION); ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ /* db_table:{reference} */ ++ sepgsql_relation_common(relOid, SEPG_DB_TABLE__REFERENCE, true); ++ ++ for (i=0; i < natts; i++) ++ sepgsql_attribute_common(relOid, attnums[i], ++ SEPG_DB_COLUMN__REFERENCE, true); ++ } ++ ++ void ++ sepgsql_relation_lock(Oid relOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ if (get_rel_relkind(relOid) != RELKIND_RELATION) ++ return; ++ ++ sepgsql_relation_common(relOid, SEPG_DB_TABLE__LOCK, true); ++ } ++ ++ void ++ sepgsql_view_replace(Oid viewOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ Assert(get_rel_relkind(viewOid) == RELKIND_VIEW); ++ ++ sepgsql_relation_common(viewOid, SEPG_DB_TABLE__SETATTR, true); ++ } ++ ++ void ++ sepgsql_index_create(Oid relOid, Oid nspOid, bool check_rights) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ if (check_rights) ++ { ++ /* db_table:{setattr} */ ++ sepgsql_relation_common(relOid, SEPG_DB_TABLE__SETATTR, true); ++ ++ /* db_schema:{add_name} */ ++ sepgsql_schema_common(nspOid, SEPG_DB_SCHEMA__ADD_NAME, true); ++ } ++ } ++ ++ void ++ sepgsql_sequence_get_value(Oid seqOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ Assert(get_rel_relkind(seqOid) == RELKIND_SEQUENCE); ++ ++ sepgsql_relation_common(seqOid, SEPG_DB_SEQUENCE__GET_VALUE, true); ++ } ++ ++ void ++ sepgsql_sequence_next_value(Oid seqOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ Assert(get_rel_relkind(seqOid) == RELKIND_SEQUENCE); ++ ++ sepgsql_relation_common(seqOid, SEPG_DB_SEQUENCE__NEXT_VALUE, true); ++ } ++ ++ void ++ sepgsql_sequence_set_value(Oid seqOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ Assert(get_rel_relkind(seqOid) == RELKIND_SEQUENCE); ++ ++ sepgsql_relation_common(seqOid, SEPG_DB_SEQUENCE__SET_VALUE, true); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_proc related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ static bool ++ sepgsql_proc_common(Oid procOid, uint32 required, bool abort) ++ { ++ sepgsql_sid_t sid; ++ HeapTuple tuple; ++ uint16 tclass; ++ const char *auname; ++ bool rc; ++ ++ tuple = SearchSysCache(PROCOID, ++ ObjectIdGetDatum(procOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for procedure: %u", procOid); ++ ++ auname = NameStr(((Form_pg_proc) GETSTRUCT(tuple))->proname); ++ sid = sepgsqlGetTupleSecid(ProcedureRelationId, tuple, &tclass); ++ ++ rc = sepgsqlClientHasPerms(sid, tclass, required, auname, abort); ++ ++ ReleaseSysCache(tuple); ++ ++ return rc; ++ } ++ ++ Oid ++ sepgsql_proc_create(const char *procName, HeapTuple oldTup, ++ Oid nspOid, Oid langOid, DefElem *newLabel) ++ { ++ sepgsql_sid_t sid; ++ HeapTuple tuple; ++ uint32 required; ++ bool trusted; ++ ++ if (!sepgsqlIsEnabled()) ++ return InvalidOid; ++ ++ if (!HeapTupleIsValid(oldTup)) ++ { ++ /* create a new function */ ++ required = SEPG_DB_PROCEDURE__CREATE; ++ if (!newLabel) ++ sid = sepgsqlGetDefaultProcedureSecid(nspOid); ++ else ++ { ++ sid.relid = ProcedureRelationId; ++ sid.secid = securityTransSecLabelIn(sid.relid, strVal(newLabel->arg)); ++ } ++ } ++ else if (!newLabel) ++ { ++ /* replace an existing function, without any label */ ++ required = SEPG_DB_PROCEDURE__SETATTR; ++ sid = sepgsqlGetTupleSecid(ProcedureRelationId, oldTup, NULL); ++ } ++ else ++ { ++ /* replace an existing function, with relabeling */ ++ sepgsql_proc_common(HeapTupleGetOid(oldTup), ++ SEPG_DB_PROCEDURE__SETATTR | ++ SEPG_DB_PROCEDURE__RELABELFROM, true); ++ ++ required = SEPG_DB_PROCEDURE__RELABELTO; ++ sid = sepgsqlGetTupleSecid(ProcedureRelationId, oldTup, NULL); ++ } ++ ++ /* Procedural language is trusted? */ ++ tuple = SearchSysCache(LANGOID, ++ ObjectIdGetDatum(langOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for procedural langugage: %u", langOid); ++ ++ trusted = ((Form_pg_language) GETSTRUCT(tuple))->lanpltrusted; ++ if (!trusted) ++ required |= SEPG_DB_PROCEDURE__UNTRUSTED; ++ ++ ReleaseSysCache(tuple); ++ ++ /* check it */ ++ sepgsqlClientHasPerms(sid, SEPG_CLASS_DB_PROCEDURE, ++ required, procName, true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_proc_alter(Oid procOid, const char *newName, Oid newNsp) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_proc_common(procOid, SEPG_DB_PROCEDURE__SETATTR, true); ++ if (newName || OidIsValid(newNsp)) ++ { ++ HeapTuple tuple; ++ Oid oldNsp; ++ ++ tuple = SearchSysCache(PROCOID, ++ ObjectIdGetDatum(procOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for function %u", procOid); ++ ++ oldNsp = ((Form_pg_proc) GETSTRUCT(tuple))->pronamespace; ++ ++ ReleaseSysCache(tuple); ++ ++ if (!OidIsValid(newNsp)) ++ { ++ sepgsql_schema_common(oldNsp, ++ SEPG_DB_SCHEMA__ADD_NAME | ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ } ++ else ++ { ++ sepgsql_schema_common(oldNsp, SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ sepgsql_schema_common(newNsp, SEPG_DB_SCHEMA__ADD_NAME, true); ++ } ++ } ++ } ++ ++ void ++ sepgsql_proc_drop(Oid procOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_proc_common(procOid, SEPG_DB_PROCEDURE__DROP, true); ++ } ++ ++ void ++ sepgsql_proc_grant(Oid procOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_proc_common(procOid, SEPG_DB_PROCEDURE__SETATTR, true); ++ } ++ ++ Oid ++ sepgsql_proc_relabel(Oid procOid, DefElem *newLabel) ++ { ++ sepgsql_sid_t sid; ++ ++ if (!sepgsqlIsEnabled()) ++ { ++ if (newLabel) ++ ereport(ERROR, ++ (errcode(ERRCODE_SELINUX_ERROR), ++ errmsg("SELinux is disabled now"))); ++ return InvalidOid; ++ } ++ ++ sid.relid = ProcedureRelationId; ++ sid.secid = securityTransSecLabelIn(sid.relid, strVal(newLabel->arg)); ++ ++ /* db_procedure:{setattr relabelfrom} for older seclabel */ ++ sepgsql_proc_common(procOid, ++ SEPG_DB_PROCEDURE__SETATTR | ++ SEPG_DB_PROCEDURE__RELABELFROM, true); ++ /* db_procedure:{relabelto} for newer seclabel */ ++ sepgsqlClientHasPerms(sid, ++ SEPG_CLASS_DB_PROCEDURE, ++ SEPG_DB_PROCEDURE__RELABELTO, ++ get_func_name(procOid), true); ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_proc_execute(Oid procOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_proc_common(procOid, SEPG_DB_PROCEDURE__EXECUTE, true); ++ } ++ ++ bool ++ sepgsql_proc_hint_inlined(HeapTuple protup) ++ { ++ security_context_t newcon; ++ sepgsql_sid_t sid; ++ ++ if (!sepgsqlIsEnabled()) ++ return true; ++ ++ if (!sepgsql_proc_common(HeapTupleGetOid(protup), ++ SEPG_DB_PROCEDURE__EXECUTE, false)) ++ return false; ++ /* ++ * If the security context of client is unchange ++ * before or after invocation of the functions, ++ * it is not a trusted procedure, so it can be ++ * inlined due to performance purpose. ++ */ ++ sid = sepgsqlGetTupleSecid(ProcedureRelationId, protup, NULL); ++ ++ newcon = sepgsqlClientCreateLabel(sid, SEPG_CLASS_PROCESS); ++ ++ if (strcmp(sepgsqlGetClientLabel(), newcon) == 0) ++ return true; ++ ++ return false; ++ } ++ ++ /* ++ * sepgsqlCheckProcedureEntrypoint ++ * checks whether the given function call causes domain transition, ++ * or not. If it needs a domain transition, it injects a wrapper ++ * function to invoke it under new domain. ++ */ ++ struct TrustedProcedureCache ++ { ++ FmgrInfo flinfo; ++ char newcon[1]; ++ }; ++ ++ static Datum ++ sepgsqlTrustedProcedure(PG_FUNCTION_ARGS) ++ { ++ struct TrustedProcedureCache *tcache; ++ security_context_t save_context; ++ FmgrInfo *save_flinfo; ++ Datum result; ++ ++ tcache = fcinfo->flinfo->fn_extra; ++ Assert(tcache != NULL); ++ ++ save_context = sepgsqlSwitchClient(tcache->newcon); ++ save_flinfo = fcinfo->flinfo; ++ fcinfo->flinfo = &tcache->flinfo; ++ ++ PG_TRY(); ++ { ++ result = FunctionCallInvoke(fcinfo); ++ } ++ PG_CATCH(); ++ { ++ sepgsqlSwitchClient(save_context); ++ fcinfo->flinfo = save_flinfo; ++ PG_RE_THROW(); ++ } ++ PG_END_TRY(); ++ sepgsqlSwitchClient(save_context); ++ fcinfo->flinfo = save_flinfo; ++ ++ return result; ++ } ++ ++ void ++ sepgsql_proc_entrypoint(FmgrInfo *flinfo, HeapTuple protup) ++ { ++ struct TrustedProcedureCache *tcache; ++ security_context_t newcon; ++ sepgsql_sid_t proSid; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ proSid = sepgsqlGetTupleSecid(ProcedureRelationId, ++ protup, NULL); ++ ++ newcon = sepgsqlClientCreateLabel(proSid, SEPG_CLASS_PROCESS); ++ ++ /* Do nothing, if it is not a trusted procedure */ ++ if (strcmp(newcon, sepgsqlGetClientLabel()) == 0) ++ return; ++ ++ /* check db_procedure:{entrypoint} */ ++ sepgsqlClientHasPerms(proSid, ++ SEPG_CLASS_DB_PROCEDURE, ++ SEPG_DB_PROCEDURE__ENTRYPOINT, ++ NULL, true); ++ ++ /* check process:{transition} */ ++ sepgsqlComputePerms(sepgsqlGetClientLabel(), ++ newcon, ++ SEPG_CLASS_PROCESS, ++ SEPG_PROCESS__TRANSITION, ++ NULL, true); ++ ++ /* setup trusted procedure */ ++ tcache = MemoryContextAllocZero(flinfo->fn_mcxt, ++ sizeof(*tcache) + strlen(newcon)); ++ memcpy(&tcache->flinfo, flinfo, sizeof(*flinfo)); ++ strcpy(tcache->newcon, newcon); ++ flinfo->fn_addr = sepgsqlTrustedProcedure; ++ flinfo->fn_extra = tcache; ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_cast related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ Oid ++ sepgsql_cast_create(Oid sourceTypOid, Oid targetTypOid, Oid funcOid) ++ { ++ sepgsql_sid_t sid; ++ char audit_buffer[2*NAMEDATALEN+10]; ++ ++ if (!sepgsqlIsEnabled()) ++ return InvalidOid; ++ ++ sid = sepgsqlGetDefaultTupleSecid(CastRelationId); ++ ++ snprintf(audit_buffer, sizeof(audit_buffer), "%s::%s", ++ format_type_be(sourceTypOid), format_type_be(targetTypOid)); ++ ++ sepgsqlClientHasPerms(sid, SEPG_CLASS_DB_TUPLE, ++ SEPG_DB_TUPLE__INSERT, ++ audit_buffer, true); ++ ++ if (OidIsValid(funcOid)) ++ sepgsql_proc_common(funcOid, SEPG_DB_PROCEDURE__INSTALL, true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_cast_drop(Oid castOid) ++ { ++ Form_pg_cast castForm; ++ Relation rel; ++ HeapTuple tuple; ++ ScanKeyData skey; ++ SysScanDesc scan; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ char audit_buffer[2*NAMEDATALEN+10]; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ rel = heap_open(CastRelationId, AccessShareLock); ++ ++ ScanKeyInit(&skey, ++ ObjectIdAttributeNumber, ++ BTEqualStrategyNumber, F_OIDEQ, ++ ObjectIdGetDatum(castOid)); ++ ++ scan = systable_beginscan(rel, CastOidIndexId, true, ++ SnapshotNow, 1, &skey); ++ tuple = systable_getnext(scan); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "could not find tuple for cast: %u", castOid); ++ ++ castForm = (Form_pg_cast) GETSTRUCT(tuple); ++ ++ snprintf(audit_buffer, sizeof(audit_buffer), "%s::%s", ++ format_type_be(castForm->castsource), ++ format_type_be(castForm->casttarget)); ++ ++ sid = sepgsqlGetTupleSecid(CastRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__DELETE, ++ audit_buffer, true); ++ ++ systable_endscan(scan); ++ ++ heap_close(rel, AccessShareLock); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_conversion related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ Oid ++ sepgsql_conversion_create(const char *convName, Oid nspOid, Oid procOid) ++ { ++ sepgsql_sid_t sid; ++ ++ if (!sepgsqlIsEnabled()) ++ return InvalidOid; ++ ++ sid = sepgsqlGetDefaultTupleSecid(ConversionRelationId); ++ sepgsqlClientHasPerms(sid, SEPG_CLASS_DB_TUPLE, ++ SEPG_DB_TUPLE__INSERT, ++ convName, true); ++ ++ /* db_schema:{add_name} */ ++ sepgsql_schema_common(nspOid, SEPG_DB_SCHEMA__ADD_NAME, true); ++ ++ /* db_procedure:{install} */ ++ sepgsql_proc_common(procOid, SEPG_DB_PROCEDURE__INSTALL, true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_conversion_alter(Oid convOid, const char *newName) ++ { ++ Form_pg_conversion convForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(CONVOID, ++ ObjectIdGetDatum(convOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for conversion %u", convOid); ++ convForm = (Form_pg_conversion) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(ConversionRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__UPDATE, ++ NameStr(convForm->conname), true); ++ if (newName) ++ { ++ Oid nspOid = convForm->connamespace; ++ ++ sepgsql_schema_common(nspOid, ++ SEPG_DB_SCHEMA__ADD_NAME | ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ } ++ ReleaseSysCache(tuple); ++ } ++ ++ void ++ sepgsql_conversion_drop(Oid convOid) ++ { ++ Form_pg_conversion convForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(CONVOID, ++ ObjectIdGetDatum(convOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for conversion %u", convOid); ++ convForm = (Form_pg_conversion) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(ConversionRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__UPDATE, ++ NameStr(convForm->conname), true); ++ ++ /* db_schema:{remove_name} */ ++ sepgsql_schema_common(convForm->connamespace, ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ ++ ReleaseSysCache(tuple); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_foreign_data_wrapper related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ static bool ++ sepgsql_fdw_common(Oid fdwOid, uint32 required, bool abort) ++ { ++ Form_pg_foreign_data_wrapper fdwForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ bool rc; ++ ++ tuple = SearchSysCache(FOREIGNDATAWRAPPEROID, ++ ObjectIdGetDatum(fdwOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for FDW: %u", fdwOid); ++ fdwForm = (Form_pg_foreign_data_wrapper) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(ForeignDataWrapperRelationId, tuple, &tclass); ++ rc = sepgsqlClientHasPerms(sid, tclass, required, ++ NameStr(fdwForm->fdwname), abort); ++ ReleaseSysCache(tuple); ++ ++ return rc; ++ } ++ ++ Oid ++ sepgsql_fdw_create(const char *fdwName, Oid fdwValidator) ++ { ++ sepgsql_sid_t sid; ++ ++ if (!sepgsqlIsEnabled()) ++ return InvalidOid; ++ ++ sid = sepgsqlGetDefaultTupleSecid(ForeignDataWrapperRelationId); ++ sepgsqlClientHasPerms(sid, SEPG_CLASS_DB_TUPLE, ++ SEPG_DB_TUPLE__INSERT, ++ fdwName, true); ++ ++ /* db_procedure:{install} */ ++ if (OidIsValid(fdwValidator)) ++ sepgsql_proc_common(fdwValidator, SEPG_DB_PROCEDURE__INSTALL, true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_fdw_alter(Oid fdwOid, Oid newValidator) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_fdw_common(fdwOid, SEPG_DB_TUPLE__UPDATE, true); ++ ++ /* db_procedure:{install} */ ++ if (OidIsValid(newValidator)) ++ sepgsql_proc_common(newValidator, SEPG_DB_PROCEDURE__INSTALL, true); ++ } ++ ++ void ++ sepgsql_fdw_drop(Oid fdwOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_fdw_common(fdwOid, SEPG_DB_TUPLE__DELETE, true); ++ } ++ ++ void ++ sepgsql_fdw_grant(Oid fdwOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_fdw_common(fdwOid, SEPG_DB_TUPLE__UPDATE, true); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_foreign_server related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ static bool ++ sepgsql_foreign_server_common(Oid fsrvOid, uint32 required, bool abort) ++ { ++ Form_pg_foreign_server fsrvForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ bool rc; ++ ++ tuple = SearchSysCache(FOREIGNSERVEROID, ++ ObjectIdGetDatum(fsrvOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for foreign server %u", fsrvOid); ++ fsrvForm = (Form_pg_foreign_server) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(ForeignServerRelationId, tuple, &tclass); ++ rc = sepgsqlClientHasPerms(sid, tclass, required, ++ NameStr(fsrvForm->srvname), abort); ++ ReleaseSysCache(tuple); ++ ++ return rc; ++ } ++ ++ Oid ++ sepgsql_foreign_server_create(const char *fsrvName) ++ { ++ sepgsql_sid_t sid; ++ ++ if (!sepgsqlIsEnabled()) ++ return InvalidOid; ++ ++ sid = sepgsqlGetDefaultTupleSecid(ForeignServerRelationId); ++ sepgsqlClientHasPerms(sid, SEPG_CLASS_DB_TUPLE, ++ SEPG_DB_TUPLE__INSERT, ++ fsrvName, true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_foreign_server_alter(Oid fsrvOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_foreign_server_common(fsrvOid, SEPG_DB_TUPLE__UPDATE, true); ++ } ++ ++ void ++ sepgsql_foreign_server_drop(Oid fsrvOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_foreign_server_common(fsrvOid, SEPG_DB_TUPLE__DELETE, true); ++ } ++ ++ void ++ sepgsql_foreign_server_grant(Oid fsrvOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_foreign_server_common(fsrvOid, SEPG_DB_TUPLE__UPDATE, true); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_language related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ static bool ++ sepgsql_language_common(Oid langOid, uint32 required, bool abort) ++ { ++ Form_pg_language langForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ bool rc; ++ ++ tuple = SearchSysCache(LANGOID, ++ ObjectIdGetDatum(langOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for language %u", langOid); ++ langForm = (Form_pg_language) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(LanguageRelationId, tuple, &tclass); ++ rc = sepgsqlClientHasPerms(sid, tclass, required, ++ NameStr(langForm->lanname), abort); ++ ++ ReleaseSysCache(tuple); ++ ++ return rc; ++ } ++ ++ Oid ++ sepgsql_language_create(const char *langName, Oid handlerOid, Oid validatorOid) ++ { ++ sepgsql_sid_t sid; ++ ++ if (!sepgsqlIsEnabled()) ++ return InvalidOid; ++ ++ sid = sepgsqlGetDefaultTupleSecid(LanguageRelationId); ++ sepgsqlClientHasPerms(sid, SEPG_CLASS_DB_TUPLE, ++ SEPG_DB_TUPLE__INSERT, langName, true); ++ ++ /* db_procedure:{install} */ ++ if (OidIsValid(handlerOid)) ++ sepgsql_proc_common(handlerOid, SEPG_DB_PROCEDURE__INSTALL, true); ++ if (OidIsValid(validatorOid)) ++ sepgsql_proc_common(validatorOid, SEPG_DB_PROCEDURE__INSTALL, true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_language_alter(Oid langOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_language_common(langOid, SEPG_DB_TUPLE__UPDATE, true); ++ } ++ ++ void ++ sepgsql_language_drop(Oid langOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_language_common(langOid, SEPG_DB_TUPLE__DELETE, true); ++ } ++ ++ void ++ sepgsql_language_grant(Oid langOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_language_common(langOid, SEPG_DB_TUPLE__UPDATE, true); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_largeobject related security hooks ++ * (need to backport v8.5 feature) ++ * ------------------------------------------------------------ */ ++ Oid ++ sepgsql_largeobject_create(Oid loid, DefElem *newLabel) ++ { ++ return InvalidOid; ++ } ++ ++ void ++ sepgsql_largeobject_alter(Oid loid, Oid newOwner) ++ {} ++ ++ void ++ sepgsql_largeobject_drop(Oid loid, bool dacSkip) ++ {} ++ ++ void ++ sepgsql_largeobject_read(Oid loid) ++ {} ++ ++ void ++ sepgsql_largeobject_write(Oid loid) ++ {} ++ ++ void ++ sepgsql_largeobject_export(Oid loid, const char *filename) ++ {} ++ ++ Oid ++ sepgsql_largeobject_import(Oid loid, const char *filename, DefElem *newLabel) ++ {} ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_opclass related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ Oid ++ sepgsql_opclass_create(const char *opcName, Oid nspOid) ++ { ++ sepgsql_sid_t sid; ++ ++ if (!sepgsqlIsEnabled()) ++ return InvalidOid; ++ ++ sid = sepgsqlGetDefaultTupleSecid(OperatorClassRelationId); ++ sepgsqlClientHasPerms(sid, SEPG_CLASS_DB_TUPLE, ++ SEPG_DB_TUPLE__INSERT, ++ opcName, true); ++ ++ /* db_schema:{add_name} */ ++ sepgsql_schema_common(nspOid, SEPG_DB_SCHEMA__ADD_NAME, true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_opclass_alter(Oid opcOid, const char *newName) ++ { ++ Form_pg_opclass opcForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(CLAOID, ++ ObjectIdGetDatum(opcOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for opclass %u", opcOid); ++ opcForm = (Form_pg_opclass) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(OperatorClassRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__UPDATE, ++ NameStr(opcForm->opcname), true); ++ ++ /* db_schema:{add_name remove_name} */ ++ if (newName) ++ { ++ sepgsql_schema_common(opcForm->opcnamespace, ++ SEPG_DB_SCHEMA__ADD_NAME | ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ } ++ ReleaseSysCache(tuple); ++ } ++ ++ void ++ sepgsql_opclass_drop(Oid opcOid) ++ { ++ Form_pg_opclass opcForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(CLAOID, ++ ObjectIdGetDatum(opcOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for opclass %u", opcOid); ++ opcForm = (Form_pg_opclass) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(OperatorClassRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__UPDATE, ++ NameStr(opcForm->opcname), true); ++ ++ /* db_schema:{remove_name} */ ++ sepgsql_schema_common(opcForm->opcnamespace, ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ ++ ReleaseSysCache(tuple); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_opfamily related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ Oid ++ sepgsql_opfamily_create(const char *opfName, Oid nspOid) ++ { ++ sepgsql_sid_t sid; ++ ++ if (!sepgsqlIsEnabled()) ++ return InvalidOid; ++ ++ sid = sepgsqlGetDefaultTupleSecid(OperatorFamilyRelationId); ++ sepgsqlClientHasPerms(sid, SEPG_CLASS_DB_TUPLE, ++ SEPG_DB_TUPLE__INSERT, ++ opfName, true); ++ ++ /* db_schema:{add_name} */ ++ sepgsql_schema_common(nspOid, SEPG_DB_SCHEMA__ADD_NAME, true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_opfamily_alter(Oid opfOid, const char *newName) ++ { ++ Form_pg_opfamily opfForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(OPFAMILYOID, ++ ObjectIdGetDatum(opfOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for operator family: %u", opfOid); ++ opfForm = (Form_pg_opfamily) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(OperatorFamilyRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__UPDATE, ++ NameStr(opfForm->opfname), true); ++ if (newName) ++ { ++ sepgsql_schema_common(opfForm->opfnamespace, ++ SEPG_DB_SCHEMA__ADD_NAME | ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ } ++ ReleaseSysCache(tuple); ++ } ++ ++ void ++ sepgsql_opfamily_drop(Oid opfOid) ++ { ++ Form_pg_opfamily opfForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(OPFAMILYOID, ++ ObjectIdGetDatum(opfOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for operator family: %u", opfOid); ++ opfForm = (Form_pg_opfamily) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(OperatorFamilyRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__DELETE, ++ NameStr(opfForm->opfname), true); ++ ++ /* db_schema:{remove_name} */ ++ sepgsql_schema_common(opfForm->opfnamespace, ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ ++ ReleaseSysCache(tuple); ++ } ++ ++ void ++ sepgsql_opfamily_add_operator(Oid opfOid, Oid operOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ /* currently, do nothing here */ ++ } ++ ++ void ++ sepgsql_opfamily_add_procedure(Oid opfOid, Oid procOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ /* ++ * Note that db_tuple:{setattr} is already checked at the ++ * earlier phase, so db_procedure:{install} is only needed. ++ */ ++ if (OidIsValid(procOid)) ++ sepgsql_proc_common(procOid, SEPG_DB_PROCEDURE__INSTALL, true); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_operator related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ static bool ++ sepgsql_operator_common(Oid oprOid, uint32 required, bool abort) ++ { ++ Form_pg_operator oprForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ bool rc; ++ ++ tuple = SearchSysCache(OPEROID, ++ ObjectIdGetDatum(oprOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for operator: %u", oprOid); ++ oprForm = (Form_pg_operator) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(OperatorRelationId, tuple, &tclass); ++ rc = sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__DELETE, ++ NameStr(oprForm->oprname), abort); ++ ++ ReleaseSysCache(tuple); ++ ++ return rc; ++ } ++ ++ Oid ++ sepgsql_operator_create(const char *oprName, Oid oprOid, Oid nspOid, ++ Oid codeFn, Oid restFn, Oid joinFn) ++ { ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint32 required; ++ ++ if (!sepgsqlIsEnabled()) ++ return InvalidOid; ++ ++ if (!OidIsValid(oprOid)) ++ { ++ sid = sepgsqlGetDefaultTupleSecid(OperatorRelationId); ++ required = SEPG_DB_TUPLE__INSERT; ++ } ++ else ++ { ++ tuple = SearchSysCache(OPEROID, ++ ObjectIdGetDatum(oprOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for operator %u", oprOid); ++ ++ sid = sepgsqlGetTupleSecid(OperatorRelationId, tuple, NULL); ++ ++ ReleaseSysCache(tuple); ++ ++ required = SEPG_DB_TUPLE__UPDATE; ++ } ++ ++ sepgsqlClientHasPerms(sid, SEPG_CLASS_DB_TUPLE, ++ required, oprName, true); ++ ++ /* db_schema:{add_name} checks */ ++ if (!OidIsValid(oprOid)) ++ sepgsql_schema_common(nspOid, SEPG_DB_SCHEMA__ADD_NAME, true); ++ ++ /* db_procedure:{install} checks */ ++ if (OidIsValid(codeFn)) ++ sepgsql_proc_common(codeFn, SEPG_DB_PROCEDURE__INSTALL, true); ++ if (OidIsValid(restFn)) ++ sepgsql_proc_common(restFn, SEPG_DB_PROCEDURE__INSTALL, true); ++ if (OidIsValid(joinFn)) ++ sepgsql_proc_common(joinFn, SEPG_DB_PROCEDURE__INSTALL, true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_operator_alter(Oid oprOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_operator_common(oprOid, SEPG_DB_TUPLE__UPDATE, true); ++ } ++ ++ void ++ sepgsql_operator_drop(Oid oprOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_operator_common(oprOid, SEPG_DB_TUPLE__DELETE, true); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_rewrite related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ void ++ sepgsql_rule_create(Oid relOid, const char *ruleName) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_relation_common(relOid, SEPG_DB_TABLE__SETATTR, true); ++ } ++ ++ void ++ sepgsql_rule_drop(Oid relOid, const char *ruleName) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_relation_common(relOid, SEPG_DB_TABLE__SETATTR, true); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_trigger related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ void ++ sepgsql_trigger_create(Oid relOid, const char *trigName, Oid procOid) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ /* db_table:{setattr} */ ++ sepgsql_relation_common(relOid, SEPG_DB_TABLE__SETATTR, true); ++ ++ /* db_procedure:{install} */ ++ sepgsql_proc_common(procOid, SEPG_DB_PROCEDURE__INSTALL, true); ++ } ++ ++ void ++ sepgsql_trigger_alter(Oid relOid, const char *trigName) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ /* db_table:{setattr} */ ++ sepgsql_relation_common(relOid, SEPG_DB_TABLE__SETATTR, true); ++ } ++ ++ void ++ sepgsql_trigger_drop(Oid relOid, const char *trigName) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ /* db_table:{setattr} */ ++ sepgsql_relation_common(relOid, SEPG_DB_TABLE__SETATTR, true); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_type related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ Oid ++ sepgsql_ts_config_create(const char *cfgName, Oid nspOid) ++ { ++ sepgsql_sid_t sid; ++ ++ if (!sepgsqlIsEnabled()) ++ return InvalidOid; ++ ++ sid = sepgsqlGetDefaultTupleSecid(TSConfigRelationId); ++ sepgsqlClientHasPerms(sid, SEPG_CLASS_DB_TUPLE, ++ SEPG_DB_TUPLE__INSERT, ++ cfgName, true); ++ ++ /* db_schema:{add_name} */ ++ sepgsql_schema_common(nspOid, SEPG_DB_SCHEMA__ADD_NAME, true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_ts_config_alter(Oid cfgOid, const char *newName) ++ { ++ Form_pg_ts_config cfgForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(TSCONFIGOID, ++ ObjectIdGetDatum(cfgOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for text search dictionary %u", cfgOid); ++ cfgForm = (Form_pg_ts_config) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(TSConfigRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__UPDATE, ++ NameStr(cfgForm->cfgname), true); ++ if (newName) ++ { ++ sepgsql_schema_common(cfgForm->cfgnamespace, ++ SEPG_DB_SCHEMA__ADD_NAME | ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ } ++ ReleaseSysCache(tuple); ++ } ++ ++ void ++ sepgsql_ts_config_drop(Oid cfgOid) ++ { ++ Form_pg_ts_config cfgForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(TSCONFIGOID, ++ ObjectIdGetDatum(cfgOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for text search dictionary %u", cfgOid); ++ cfgForm = (Form_pg_ts_config) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(TSConfigRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__DELETE, ++ NameStr(cfgForm->cfgname), true); ++ ++ /* db_schema:{remove_name} */ ++ sepgsql_schema_common(cfgForm->cfgnamespace, ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ ++ ReleaseSysCache(tuple); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_type related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ Oid ++ sepgsql_ts_dict_create(const char *dictName, Oid nspOid) ++ { ++ sepgsql_sid_t sid; ++ ++ if (!sepgsqlIsEnabled()) ++ return InvalidOid; ++ ++ sid = sepgsqlGetDefaultTupleSecid(TSDictionaryRelationId); ++ sepgsqlClientHasPerms(sid, SEPG_CLASS_DB_TUPLE, ++ SEPG_DB_TUPLE__INSERT, ++ dictName, true); ++ ++ /* db_schema:{add_name} */ ++ sepgsql_schema_common(nspOid, SEPG_DB_SCHEMA__ADD_NAME, true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_ts_dict_alter(Oid dictOid, const char *newName) ++ { ++ Form_pg_ts_dict dictForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(TSDICTOID, ++ ObjectIdGetDatum(dictOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for text search dictionary %u", dictOid); ++ dictForm = (Form_pg_ts_dict) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(TSDictionaryRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__UPDATE, ++ NameStr(dictForm->dictname), true); ++ ++ /* db_schema:{add_name remove_name} */ ++ if (newName) ++ { ++ sepgsql_schema_common(dictForm->dictnamespace, ++ SEPG_DB_SCHEMA__ADD_NAME | ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ } ++ ReleaseSysCache(tuple); ++ } ++ ++ void ++ sepgsql_ts_dict_drop(Oid dictOid) ++ { ++ Form_pg_ts_dict dictForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(TSDICTOID, ++ ObjectIdGetDatum(dictOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for text search dictionary %u", dictOid); ++ dictForm = (Form_pg_ts_dict) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(TSDictionaryRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__DELETE, ++ NameStr(dictForm->dictname), true); ++ ++ /* db_schema:{remove_name} */ ++ sepgsql_schema_common(dictForm->dictnamespace, ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ ++ ReleaseSysCache(tuple); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_type related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ Oid ++ sepgsql_ts_parser_create(const char *prsName, Oid nspOid, ++ Oid startFn, Oid tokenFn, Oid sendFn, ++ Oid headlineFn, Oid lextypeFn) ++ { ++ sepgsql_sid_t sid; ++ ++ if (!sepgsqlIsEnabled()) ++ return InvalidOid; ++ ++ sid = sepgsqlGetDefaultTupleSecid(TSParserRelationId); ++ sepgsqlClientHasPerms(sid, SEPG_CLASS_DB_TUPLE, ++ SEPG_DB_TUPLE__INSERT, ++ prsName, true); ++ ++ /* db_schema:{add_name} */ ++ sepgsql_schema_common(nspOid, SEPG_DB_SCHEMA__ADD_NAME, true); ++ ++ /* db_procedure:{install} */ ++ if (OidIsValid(startFn)) ++ sepgsql_proc_common(startFn, SEPG_DB_PROCEDURE__INSTALL, true); ++ if (OidIsValid(tokenFn)) ++ sepgsql_proc_common(tokenFn, SEPG_DB_PROCEDURE__INSTALL, true); ++ if (OidIsValid(sendFn)) ++ sepgsql_proc_common(sendFn, SEPG_DB_PROCEDURE__INSTALL, true); ++ if (OidIsValid(headlineFn)) ++ sepgsql_proc_common(headlineFn, SEPG_DB_PROCEDURE__INSTALL, true); ++ if (OidIsValid(lextypeFn)) ++ sepgsql_proc_common(lextypeFn, SEPG_DB_PROCEDURE__INSTALL, true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_ts_parser_alter(Oid prsOid, const char *newName) ++ { ++ Form_pg_ts_parser prsForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(TSPARSEROID, ++ ObjectIdGetDatum(prsOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for text search parser %u", prsOid); ++ ++ prsForm = (Form_pg_ts_parser) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(TSParserRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__UPDATE, ++ NameStr(prsForm->prsname), true); ++ if (newName) ++ { ++ sepgsql_schema_common(prsForm->prsnamespace, ++ SEPG_DB_SCHEMA__ADD_NAME | ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ } ++ ReleaseSysCache(tuple); ++ } ++ ++ void ++ sepgsql_ts_parser_drop(Oid prsOid) ++ { ++ Form_pg_ts_parser prsForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(TSPARSEROID, ++ ObjectIdGetDatum(prsOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for text search parser %u", prsOid); ++ ++ prsForm = (Form_pg_ts_parser) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(TSParserRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__DELETE, ++ NameStr(prsForm->prsname), true); ++ ++ /* db_schema:{remove_name} */ ++ sepgsql_schema_common(prsForm->prsnamespace, ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ ++ ReleaseSysCache(tuple); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_type related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ Oid ++ sepgsql_ts_template_create(const char *tmplName, Oid nspOid, ++ Oid initFn, Oid lexizeFn) ++ { ++ sepgsql_sid_t sid; ++ ++ if (!sepgsqlIsEnabled()) ++ return InvalidOid; ++ ++ sid = sepgsqlGetDefaultTupleSecid(TSTemplateRelationId); ++ sepgsqlClientHasPerms(sid, SEPG_CLASS_DB_TUPLE, ++ SEPG_DB_TUPLE__INSERT, ++ tmplName, true); ++ ++ /* db_schema:{add_name} */ ++ sepgsql_schema_common(nspOid, SEPG_DB_SCHEMA__ADD_NAME, true); ++ ++ /* db_procedure:{install} */ ++ if (OidIsValid(initFn)) ++ sepgsql_proc_common(initFn, SEPG_DB_PROCEDURE__INSTALL, true); ++ if (OidIsValid(lexizeFn)) ++ sepgsql_proc_common(lexizeFn, SEPG_DB_PROCEDURE__INSTALL, true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_ts_template_alter(Oid tmplOid, const char *newName) ++ { ++ Form_pg_ts_template tmplForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(TSTEMPLATEOID, ++ ObjectIdGetDatum(tmplOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for text search template %u", tmplOid); ++ tmplForm = (Form_pg_ts_template) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(TSTemplateRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__UPDATE, ++ NameStr(tmplForm->tmplname), true); ++ if (newName) ++ { ++ sepgsql_schema_common(tmplForm->tmplnamespace, ++ SEPG_DB_SCHEMA__ADD_NAME | ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ } ++ ReleaseSysCache(tuple); ++ } ++ ++ void ++ sepgsql_ts_template_drop(Oid tmplOid) ++ { ++ Form_pg_ts_template tmplForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(TSTEMPLATEOID, ++ ObjectIdGetDatum(tmplOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for text search template %u", tmplOid); ++ tmplForm = (Form_pg_ts_template) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(TSTemplateRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__DELETE, ++ NameStr(tmplForm->tmplname), true); ++ ++ /* db_schema:{remove_name} */ ++ sepgsql_schema_common(tmplForm->tmplnamespace, ++ SEPG_DB_SCHEMA__ADD_NAME | ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ ++ ReleaseSysCache(tuple); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Pg_type related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ Oid ++ sepgsql_type_create(const char *typName, HeapTuple oldTup, Oid nspOid, ++ Oid inputProc, Oid outputProc, Oid recvProc, Oid sendProc, ++ Oid modinProc, Oid modoutProc, Oid analyzeProc) ++ { ++ sepgsql_sid_t sid; ++ uint32 required; ++ ++ if (!sepgsqlIsEnabled()) ++ return InvalidOid; ++ ++ if (!HeapTupleIsValid(oldTup)) ++ { ++ sid = sepgsqlGetDefaultTupleSecid(TypeRelationId); ++ required = SEPG_DB_TUPLE__INSERT; ++ } ++ else ++ { ++ sid = sepgsqlGetTupleSecid(TypeRelationId, oldTup, NULL); ++ required = SEPG_DB_TUPLE__UPDATE; ++ } ++ sepgsqlClientHasPerms(sid, SEPG_CLASS_DB_TUPLE, ++ required, typName, true); ++ /* db_schema:{add_name} */ ++ sepgsql_schema_common(nspOid, SEPG_DB_SCHEMA__ADD_NAME, true); ++ ++ /* db_procedure:{install} */ ++ if (OidIsValid(inputProc)) ++ sepgsql_proc_common(inputProc, SEPG_DB_PROCEDURE__INSTALL, true); ++ if (OidIsValid(outputProc)) ++ sepgsql_proc_common(outputProc, SEPG_DB_PROCEDURE__INSTALL, true); ++ if (OidIsValid(recvProc)) ++ sepgsql_proc_common(recvProc, SEPG_DB_PROCEDURE__INSTALL, true); ++ if (OidIsValid(sendProc)) ++ sepgsql_proc_common(sendProc, SEPG_DB_PROCEDURE__INSTALL, true); ++ if (OidIsValid(modinProc)) ++ sepgsql_proc_common(modinProc, SEPG_DB_PROCEDURE__INSTALL, true); ++ if (OidIsValid(modoutProc)) ++ sepgsql_proc_common(modoutProc, SEPG_DB_PROCEDURE__INSTALL, true); ++ if (OidIsValid(analyzeProc)) ++ sepgsql_proc_common(analyzeProc, SEPG_DB_PROCEDURE__INSTALL, true); ++ ++ return sid.secid; ++ } ++ ++ void ++ sepgsql_type_alter(Oid typOid, const char *newName, Oid newNsp) ++ { ++ Form_pg_type typForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(TYPEOID, ++ ObjectIdGetDatum(typOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for type: %u", typOid); ++ typForm = (Form_pg_type) GETSTRUCT(tuple); ++ ++ sid = sepgsqlGetTupleSecid(TypeRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__UPDATE, ++ NameStr(typForm->typname), true); ++ ++ if (newName || OidIsValid(newNsp)) ++ { ++ Oid oldNsp = typForm->typnamespace; ++ ++ if (!OidIsValid(newNsp)) ++ { ++ sepgsql_schema_common(oldNsp, ++ SEPG_DB_SCHEMA__ADD_NAME | ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ } ++ else ++ { ++ sepgsql_schema_common(oldNsp, SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ sepgsql_schema_common(newNsp, SEPG_DB_SCHEMA__ADD_NAME, true); ++ } ++ } ++ ReleaseSysCache(tuple); ++ } ++ ++ void ++ sepgsql_type_drop(Oid typOid) ++ { ++ Form_pg_type typForm; ++ HeapTuple tuple; ++ sepgsql_sid_t sid; ++ uint16 tclass; ++ ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ tuple = SearchSysCache(TYPEOID, ++ ObjectIdGetDatum(typOid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for type: %u", typOid); ++ typForm = (Form_pg_type) GETSTRUCT(tuple); ++ ++ if (typForm->typtype == TYPTYPE_COMPOSITE || ++ (typForm->typtype == TYPTYPE_BASE && OidIsValid(typForm->typarray))) ++ { ++ /* ++ * No need to check for composite type and implicitly ++ * declared array type here. ++ */ ++ ReleaseSysCache(tuple); ++ return; ++ } ++ ++ sid = sepgsqlGetTupleSecid(TypeRelationId, tuple, &tclass); ++ sepgsqlClientHasPerms(sid, tclass, ++ SEPG_DB_TUPLE__DELETE, ++ NameStr(typForm->typname), true); ++ ++ /* db_schema:{remove_name} */ ++ sepgsql_schema_common(typForm->typnamespace, ++ SEPG_DB_SCHEMA__REMOVE_NAME, true); ++ ++ ReleaseSysCache(tuple); ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Misc system object related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ ++ void ++ sepgsql_sysobj_drop(const ObjectAddress *object) ++ { ++ switch (object->classId) ++ { ++ case RelationRelationId: ++ if (object->objectSubId == 0) ++ sepgsql_relation_drop(object->objectId); ++ else ++ sepgsql_attribute_drop(object->objectId, ++ object->objectSubId); ++ break; ++ ++ case ProcedureRelationId: ++ sepgsql_proc_drop(object->objectId); ++ break; ++ ++ case TypeRelationId: ++ sepgsql_type_drop(object->objectId); ++ break; ++ ++ case CastRelationId: ++ sepgsql_cast_drop(object->objectId); ++ break; ++ ++ case ConversionRelationId: ++ sepgsql_conversion_drop(object->objectId); ++ break; ++ ++ case LanguageRelationId: ++ sepgsql_language_drop(object->objectId); ++ break; ++ ++ case OperatorRelationId: ++ sepgsql_operator_drop(object->objectId); ++ break; ++ ++ case OperatorClassRelationId: ++ sepgsql_opclass_drop(object->objectId); ++ break; ++ ++ case OperatorFamilyRelationId: ++ sepgsql_opfamily_drop(object->objectId); ++ break; ++ ++ case NamespaceRelationId: ++ sepgsql_schema_drop(object->objectId); ++ break; ++ ++ case TSParserRelationId: ++ sepgsql_ts_parser_drop(object->objectId); ++ break; ++ ++ case TSDictionaryRelationId: ++ sepgsql_ts_dict_drop(object->objectId); ++ break; ++ ++ case TSTemplateRelationId: ++ sepgsql_ts_template_drop(object->objectId); ++ break; ++ ++ case TSConfigRelationId: ++ sepgsql_ts_config_drop(object->objectId); ++ break; ++ ++ case AuthIdRelationId: ++ break; ++ ++ case DatabaseRelationId: ++ sepgsql_database_drop(object->objectId); ++ break; ++ ++ case TableSpaceRelationId: ++ break; ++ ++ case ForeignDataWrapperRelationId: ++ sepgsql_fdw_drop(object->objectId); ++ break; ++ ++ case ForeignServerRelationId: ++ sepgsql_foreign_server_drop(object->objectId); ++ break; ++ ++ case UserMappingRelationId: ++ break; ++ ++ default: ++ /* do nothing */ ++ break; ++ } ++ } ++ ++ /* ------------------------------------------------------------ * ++ * ++ * Filesystem object related security hooks ++ * ++ * ------------------------------------------------------------ */ ++ static char * ++ sepgsql_getfilecon(const char *path) ++ { ++ security_context_t context; ++ char *result; ++ ++ if (getfilecon_raw(path, &context) < 0) ++ ereport(ERROR, ++ (errcode_for_file_access(), ++ errmsg("could not get context of \"%s\": %m", path))); ++ ++ PG_TRY(); ++ { ++ result = pstrdup(context); ++ } ++ PG_CATCH(); ++ { ++ freecon(context); ++ PG_RE_THROW(); ++ } ++ PG_END_TRY(); ++ freecon(context); ++ ++ return result; ++ } ++ ++ static void ++ sepgsql_file_common(const char *filename, uint32 required, bool may_create) ++ { ++ struct stat stbuf; ++ ++ if (stat(filename, &stbuf) == 0) ++ { ++ uint16 tclass; ++ ++ /* ++ * Get file object class ++ */ ++ if (S_ISDIR(stbuf.st_mode)) ++ tclass = SEPG_CLASS_DIR; ++ else if (S_ISCHR(stbuf.st_mode)) ++ tclass = SEPG_CLASS_CHR_FILE; ++ else if (S_ISBLK(stbuf.st_mode)) ++ tclass = SEPG_CLASS_BLK_FILE; ++ else if (S_ISFIFO(stbuf.st_mode)) ++ tclass = SEPG_CLASS_FIFO_FILE; ++ else if (S_ISLNK(stbuf.st_mode)) ++ tclass = SEPG_CLASS_LNK_FILE; ++ else if (S_ISSOCK(stbuf.st_mode)) ++ tclass = SEPG_CLASS_SOCK_FILE; ++ else ++ tclass = SEPG_CLASS_FILE; ++ ++ /* ++ * Check permission (no cached operation) ++ */ ++ sepgsqlComputePerms(sepgsqlGetClientLabel(), ++ sepgsql_getfilecon(filename), ++ tclass, required, ++ filename, true); ++ } ++ else if (may_create) ++ { ++ /* ++ * If the required file is not found, we check permission to ++ * create a new file and required permission on the new file. ++ */ ++ security_context_t dcontext; ++ security_context_t ncontext; ++ char *copy = pstrdup(filename); ++ ++ /* ++ * Compute a security context for the new file ++ */ ++ dcontext = sepgsql_getfilecon(dirname(copy)); ++ ++ ncontext = sepgsqlComputeCreate(sepgsqlGetServerLabel(), ++ dcontext, ++ SEPG_CLASS_FILE); ++ /* ++ * Check permission (no cached operation) ++ */ ++ required |= SEPG_FILE__CREATE; ++ ++ sepgsqlComputePerms(sepgsqlGetClientLabel(), ++ sepgsql_getfilecon(filename), ++ SEPG_CLASS_FILE, ++ required, filename, true); ++ } ++ else ++ { ++ ereport(ERROR, ++ (errcode_for_file_access(), ++ errmsg("could not stat file \"%s\": %m", filename))); ++ } ++ } ++ ++ void ++ sepgsql_file_stat(const char *filename) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_file_common(filename, SEPG_FILE__GETATTR, false); ++ } ++ ++ void ++ sepgsql_file_read(const char *filename) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_file_common(filename, SEPG_FILE__READ, false); ++ } ++ ++ void ++ sepgsql_file_write(const char *filename) ++ { ++ if (!sepgsqlIsEnabled()) ++ return; ++ ++ sepgsql_file_common(filename, SEPG_FILE__WRITE, true); ++ } ++ ++ /* ++ * TODO: add check for pg_ls_dir() ++ */ +diff -Nrpc base/src/backend/security/sepgsql/checker.c sepgsql/src/backend/security/sepgsql/checker.c +*** base/src/backend/security/sepgsql/checker.c Thu Jan 1 09:00:00 1970 +--- sepgsql/src/backend/security/sepgsql/checker.c Thu Oct 8 09:29:32 2009 +*************** +*** 0 **** +--- 1,424 ---- + /* + * src/backend/security/sepgsql/checker.c + * walks on given Query tree and applies checks @@ -8170,7 +12296,7 @@ diff -Nrpc base/src/backend/security/sepgsql/checker.c sepgsql/src/backend/secur + + relForm = (Form_pg_class) GETSTRUCT(reltup); + -+ relsid = sepgsqlGetTupleContext(RelationRelationId, reltup, &tclass); ++ relsid = sepgsqlGetTupleSecid(RelationRelationId, reltup, &tclass); + + if (tclass != SEPG_CLASS_DB_TABLE) + { @@ -8234,8 +12360,8 @@ diff -Nrpc base/src/backend/security/sepgsql/checker.c sepgsql/src/backend/secur + snprintf(auname, sizeof(auname), "%s.%s", + NameStr(relForm->relname), + NameStr(attForm->attname)); -+ attsid = sepgsqlGetTupleContext(AttributeRelationId, -+ atttup, &tclass); ++ attsid = sepgsqlGetTupleSecid(AttributeRelationId, ++ atttup, &tclass); + sepgsqlClientHasPerms(attsid, tclass, attperms, auname, true); + + ReleaseSysCache(atttup); @@ -8334,25 +12460,6 @@ diff -Nrpc base/src/backend/security/sepgsql/checker.c sepgsql/src/backend/secur + } + + /* -+ * sepgsqlCheckSelectInto -+ * It checks db_table/db_column:{insert} on the table newly created -+ */ -+ void -+ sepgsqlCheckSelectInto(Oid relationId) -+ { -+ Bitmapset *modified = NULL; -+ -+ if (!sepgsqlIsEnabled()) -+ return; -+ -+ modified = bms_add_member(modified, InvalidAttrNumber -+ - FirstLowInvalidHeapAttributeNumber); -+ -+ checkTabelColumnPerms(relationId, NULL, modified, -+ SEPG_DB_TABLE__INSERT); -+ } -+ -+ /* + * sepgsqlExecScan + * makes a decision on the given tuple. + */ @@ -8368,7 +12475,7 @@ diff -Nrpc base/src/backend/security/sepgsql/checker.c sepgsql/src/backend/secur + RelationGetRelid(rel) == SecurityRelationId) + return true; + -+ sid = sepgsqlGetTupleContext(RelationGetRelid(rel), tuple, &tclass); ++ sid = sepgsqlGetTupleSecid(RelationGetRelid(rel), tuple, &tclass); + /* + * Insert/Delete to an external attribute is equivalent to + * the set-attribute on the master @@ -8436,8 +12543,8 @@ diff -Nrpc base/src/backend/security/sepgsql/checker.c sepgsql/src/backend/secur + if (internal) + return; + -+ sid = sepgsqlGetTupleContext(RelationGetRelid(rel), -+ newtup, &tclass); ++ sid = sepgsqlGetTupleSecid(RelationGetRelid(rel), ++ newtup, &tclass); + sepgsqlClientHasPerms(sid, tclass, SEPG_DB_TUPLE__INSERT, NULL, true); + } + @@ -8482,15 +12589,15 @@ diff -Nrpc base/src/backend/security/sepgsql/checker.c sepgsql/src/backend/secur + uint16 tclass; + + /* db_tuple:{relabelfrom} for older security context */ -+ sid = sepgsqlGetTupleContext(RelationGetRelid(rel), -+ &oldtup, &tclass); ++ sid = sepgsqlGetTupleSecid(RelationGetRelid(rel), ++ &oldtup, &tclass); + sepgsqlClientHasPerms(sid, tclass, + SEPG_DB_TUPLE__RELABELFROM, + NULL, true); + + /* db_tuple:{relabelto} for newer security label */ -+ sid = sepgsqlGetTupleContext(RelationGetRelid(rel), -+ newtup, &tclass); ++ sid = sepgsqlGetTupleSecid(RelationGetRelid(rel), ++ newtup, &tclass); + sepgsqlClientHasPerms(sid, tclass, + SEPG_DB_TUPLE__RELABELTO, + NULL, true); @@ -8584,10 +12691,10 @@ diff -Nrpc base/src/backend/security/sepgsql/dummy.c sepgsql/src/backend/securit + } diff -Nrpc base/src/backend/security/sepgsql/hooks.c sepgsql/src/backend/security/sepgsql/hooks.c *** base/src/backend/security/sepgsql/hooks.c Thu Jan 1 09:00:00 1970 ---- sepgsql/src/backend/security/sepgsql/hooks.c Thu Sep 10 00:06:47 2009 +--- sepgsql/src/backend/security/sepgsql/hooks.c Mon Sep 28 10:07:19 2009 *************** *** 0 **** ---- 1,1273 ---- +--- 1,239 ---- + /* + * src/backend/security/sepgsql/hooks.c + * SE-PostgreSQL security hooks @@ -8624,897 +12731,11 @@ diff -Nrpc base/src/backend/security/sepgsql/hooks.c sepgsql/src/backend/securit + #include "utils/syscache.h" + #include "utils/tqual.h" + -+ /* -+ * ------------------------------------------------------------ -+ * Hooks corresponding to db_database object class -+ * ------------------------------------------------------------ -+ * -+ * sepgsqlCheckDatabaseInstallModule -+ * checks db_database:{install_module} permission when the client -+ * tries to install a dynamic link library on the current databse. -+ * -+ * sepgsqlCheckDatabaseLoadModule -+ * checks capability of the database when it loads a certain DLL -+ * into its process address space. -+ */ -+ Oid -+ sepgsqlCheckDatabaseCreate(const char *datname, DefElem *newLabel) -+ { -+ sepgsql_sid_t datSid; -+ -+ if (!sepgsqlIsEnabled()) -+ return InvalidOid; -+ -+ if (!newLabel) -+ datSid = sepgsqlGetDefaultDatabaseSecid(); -+ else -+ { -+ datSid.relid = DatabaseRelationId; -+ datSid.secid = securityTransSecLabelIn(datSid.relid, -+ strVal(newLabel->arg)); -+ } -+ -+ sepgsqlClientHasPerms(datSid, -+ SEPG_CLASS_DB_DATABASE, -+ SEPG_DB_DATABASE__CREATE, -+ datname, true); -+ return datSid.secid; -+ } -+ -+ static bool -+ checkDatabaseCommon(Oid datOid, uint32 required, bool abort) -+ { -+ HeapTuple tuple; -+ sepgsql_sid_t datSid; -+ uint16 tclass; -+ const char *auname; -+ bool rc; -+ -+ if (!sepgsqlIsEnabled()) -+ return true; -+ -+ tuple = SearchSysCache(DATABASEOID, -+ ObjectIdGetDatum(datOid), -+ 0, 0, 0); -+ if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "cache lookup failed for database: %u", datOid); -+ -+ auname = NameStr(((Form_pg_database) GETSTRUCT(tuple))->datname); -+ datSid = sepgsqlGetTupleContext(DatabaseRelationId, -+ tuple, &tclass); -+ rc = sepgsqlClientHasPerms(datSid, -+ tclass, required, -+ auname, abort); -+ -+ ReleaseSysCache(tuple); -+ -+ return rc; -+ } -+ -+ void -+ sepgsqlCheckDatabaseDrop(Oid datOid) -+ { -+ checkDatabaseCommon(datOid, SEPG_DB_DATABASE__DROP, true); -+ } -+ -+ void -+ sepgsqlCheckDatabaseSetattr(Oid datOid) -+ { -+ checkDatabaseCommon(datOid, SEPG_DB_DATABASE__SETATTR, true); -+ } -+ -+ Oid -+ sepgsqlCheckDatabaseRelabel(Oid datOid, DefElem *newLabel) -+ { -+ sepgsql_sid_t datSid; -+ -+ if (!sepgsqlIsEnabled()) -+ { -+ if (newLabel) -+ ereport(ERROR, -+ (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("SELinux is disabled now"))); -+ return InvalidOid; -+ } -+ datSid.relid = DatabaseRelationId; -+ datSid.secid = securityTransSecLabelIn(datSid.relid, -+ strVal(newLabel->arg)); -+ /* db_database:{setattr relabelfrom} for older seclabel */ -+ checkDatabaseCommon(datOid, -+ SEPG_DB_DATABASE__SETATTR | -+ SEPG_DB_DATABASE__RELABELFROM, true); -+ /* db_database:{relabelto} for newer seclabel */ -+ sepgsqlClientHasPerms(datSid, -+ SEPG_CLASS_DB_DATABASE, -+ SEPG_DB_DATABASE__RELABELTO, -+ get_database_name(datOid), true); -+ return datSid.secid; -+ } -+ -+ void -+ sepgsqlCheckDatabaseAccess(Oid datOid) -+ { -+ if (!checkDatabaseCommon(datOid, SEPG_DB_DATABASE__ACCESS, false)) -+ ereport(FATAL, -+ (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("SELinux: security policy violation"))); -+ } -+ -+ bool -+ sepgsqlCheckDatabaseSuperuser(void) -+ { -+ return checkDatabaseCommon(MyDatabaseId, -+ SEPG_DB_DATABASE__SUPERUSER, false); -+ } -+ -+ void -+ sepgsqlCheckDatabaseLoadModule(const char *filename) -+ { -+ HeapTuple tuple; -+ security_context_t filecon; -+ security_context_t dbcon; -+ -+ if (!sepgsqlIsEnabled()) -+ return; -+ /* -+ * It assumes preloaded libraries are secure, -+ * because it can be set up using guc variable -+ * not any SQL statements. -+ */ -+ if (GetProcessingMode() == InitProcessing) -+ return; -+ -+ /* Get database context */ -+ tuple = SearchSysCache(DATABASEOID, -+ ObjectIdGetDatum(MyDatabaseId), -+ 0, 0, 0); -+ if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "cache lookup failed for database: %u", MyDatabaseId); -+ -+ dbcon = securityRawSecLabelOut(DatabaseRelationId, -+ HeapTupleGetSecid(tuple)); -+ ReleaseSysCache(tuple); -+ -+ /* Get library context */ -+ if (getfilecon_raw(filename, &filecon) < 0) -+ ereport(ERROR, -+ (errcode_for_file_access(), -+ errmsg("could not access file \"%s\": %m", filename))); -+ PG_TRY(); -+ { -+ sepgsqlComputePerms(dbcon, -+ filecon, -+ SEPG_CLASS_DB_DATABASE, -+ SEPG_DB_DATABASE__LOAD_MODULE, -+ filename, true); -+ } -+ PG_CATCH(); -+ { -+ freecon(filecon); -+ PG_RE_THROW(); -+ } -+ PG_END_TRY(); -+ freecon(filecon); -+ } -+ -+ /* -+ * ------------------------------------------------------------ -+ * Hooks corresponding to db_schema object class -+ * ------------------------------------------------------------ -+ */ -+ -+ Oid -+ sepgsqlCheckSchemaCreate(const char *nspName, DefElem *newLabel, bool isTemp) -+ { -+ sepgsql_sid_t nspSid; -+ -+ if (!sepgsqlIsEnabled()) -+ return InvalidOid; -+ -+ if (!newLabel) -+ { -+ nspSid = (!isTemp -+ ? sepgsqlGetDefaultSchemaSecid(MyDatabaseId) -+ : sepgsqlGetDefaultSchemaTempSecid(MyDatabaseId)); -+ } -+ else -+ { -+ nspSid.relid = NamespaceRelationId; -+ nspSid.secid = securityTransSecLabelIn(nspSid.relid, -+ strVal(newLabel->arg)); -+ } -+ sepgsqlClientHasPerms(nspSid, -+ (!isTemp -+ ? SEPG_CLASS_DB_SCHEMA -+ : SEPG_CLASS_DB_SCHEMA_TEMP), -+ SEPG_DB_SCHEMA__CREATE, -+ nspName, true); -+ return nspSid.secid; -+ } -+ -+ static bool -+ checkSchemaCommon(Oid nspOid, uint32 required, bool abort) -+ { -+ HeapTuple tuple; -+ sepgsql_sid_t nspSid; -+ uint16 tclass; -+ const char *auname; -+ bool rc; -+ -+ if (!sepgsqlIsEnabled()) -+ return true; -+ -+ tuple = SearchSysCache(NAMESPACEOID, -+ ObjectIdGetDatum(nspOid), -+ 0, 0, 0); -+ if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "cache lookup failed for namespace: %u", nspOid); -+ -+ nspSid = sepgsqlGetTupleContext(NamespaceRelationId, -+ tuple, &tclass); -+ -+ auname = NameStr(((Form_pg_namespace) GETSTRUCT(tuple))->nspname); -+ rc = sepgsqlClientHasPerms(nspSid, tclass, required, -+ auname, abort); -+ -+ ReleaseSysCache(tuple); -+ -+ return rc; -+ } -+ -+ void -+ sepgsqlCheckSchemaDrop(Oid nspOid) -+ { -+ checkSchemaCommon(nspOid, SEPG_DB_SCHEMA__DROP, true); -+ } -+ -+ void -+ sepgsqlCheckSchemaSetattr(Oid nspOid) -+ { -+ checkSchemaCommon(nspOid, SEPG_DB_SCHEMA__SETATTR, true); -+ } -+ -+ Oid -+ sepgsqlCheckSchemaRelabel(Oid nspOid, DefElem *newLabel) -+ { -+ sepgsql_sid_t nspSid; -+ -+ if (!sepgsqlIsEnabled()) -+ { -+ if (newLabel) -+ ereport(ERROR, -+ (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("SELinux is disabled now"))); -+ return InvalidOid; -+ } -+ nspSid.relid = NamespaceRelationId; -+ nspSid.secid = securityTransSecLabelIn(nspSid.relid, -+ strVal(newLabel->arg)); -+ -+ /* db_schema:{setattr relabelfrom} for older seclabel */ -+ checkSchemaCommon(nspOid, -+ SEPG_DB_SCHEMA__SETATTR | -+ SEPG_DB_SCHEMA__RELABELFROM, true); -+ /* db_schema:{relabelto} for newer seclabel */ -+ sepgsqlClientHasPerms(nspSid, -+ !isAnyTempNamespace(nspOid) -+ ? SEPG_CLASS_DB_SCHEMA -+ : SEPG_CLASS_DB_SCHEMA_TEMP, -+ SEPG_DB_SCHEMA__RELABELTO, -+ get_namespace_name(nspOid), true); -+ return nspSid.secid; -+ } -+ -+ void -+ sepgsqlCheckSchemaAddName(Oid nspOid) -+ { -+ checkSchemaCommon(nspOid, SEPG_DB_SCHEMA__ADD_NAME, true); -+ } -+ -+ void -+ sepgsqlCheckSchemaRemoveName(Oid nspOid) -+ { -+ checkSchemaCommon(nspOid, SEPG_DB_SCHEMA__REMOVE_NAME, true); -+ } -+ -+ bool -+ sepgsqlCheckSchemaSearch(Oid nspOid, bool abort) -+ { -+ return checkSchemaCommon(nspOid, SEPG_DB_SCHEMA__SEARCH, abort); -+ } -+ + /* ------------------------------------------------------------ * -+ * Hooks corresponding to db_column object class ++ * Hooks corresponding to db_blob object class + * ------------------------------------------------------------ */ + + /* -+ * NOTE: db_column:{create} is checked on sepgsqlCreateTableColumns() -+ * which is invoked on CREATE TABLE statement. -+ * The sepgsqlCheckColumnCreate() is called on the ALTER TABLE -+ * ... ADD COLUMN path. -+ */ -+ Oid -+ sepgsqlCheckColumnCreate(Oid table_oid, const char *attname, DefElem *newLabel) -+ { -+ sepgsql_sid_t attSid; -+ char relkind; -+ char auname[NAMEDATALEN * 2 + 3]; -+ -+ if (!sepgsqlIsEnabled()) -+ { -+ if (newLabel) -+ ereport(ERROR, -+ (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("SELinux is disabled now"))); -+ return InvalidOid; -+ } -+ -+ relkind = get_rel_relkind(table_oid); -+ if (relkind != RELKIND_RELATION) -+ { -+ if (newLabel) -+ ereport(ERROR, -+ (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("Unable to assign security label"))); -+ return InvalidOid; -+ } -+ -+ if (!newLabel) -+ attSid = sepgsqlGetDefaultColumnSecid(table_oid); -+ else -+ { -+ attSid.relid = AttributeRelationId; -+ attSid.secid = securityTransSecLabelIn(attSid.relid, -+ strVal(newLabel->arg)); -+ } -+ -+ sprintf(auname, "%s.%s", get_rel_name(table_oid), attname); -+ sepgsqlClientHasPerms(attSid, -+ SEPG_CLASS_DB_COLUMN, -+ SEPG_DB_COLUMN__CREATE, -+ auname, true); -+ return attSid.secid; -+ } -+ -+ static void -+ checkColumnCommon(Oid relOid, AttrNumber attno, uint32 required) -+ { -+ Form_pg_attribute attr; -+ sepgsql_sid_t attSid; -+ HeapTuple tuple; -+ uint16 tclass; -+ char auname[2 * NAMEDATALEN + 3]; -+ char relkind; -+ -+ if (!sepgsqlIsEnabled()) -+ return; -+ -+ relkind = get_rel_relkind(relOid); -+ if (relkind != RELKIND_RELATION) -+ return; -+ -+ tuple = SearchSysCache(ATTNUM, -+ ObjectIdGetDatum(relOid), -+ Int16GetDatum(attno), -+ 0, 0); -+ if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "cache lookup failed for attribute %d of relation %u", -+ attno, relOid); -+ -+ attr = (Form_pg_attribute) GETSTRUCT(tuple); -+ if (!attr->attisdropped) -+ { -+ sprintf(auname, "%s.%s", -+ get_rel_name(relOid), -+ NameStr(attr->attname)); -+ attSid = sepgsqlGetTupleContext(AttributeRelationId, -+ tuple, &tclass); -+ sepgsqlClientHasPerms(attSid, tclass, required, -+ auname, true); -+ } -+ -+ ReleaseSysCache(tuple); -+ } -+ -+ void -+ sepgsqlCheckColumnDrop(Oid relOid, AttrNumber attno) -+ { -+ checkColumnCommon(relOid, attno, SEPG_DB_COLUMN__DROP); -+ } -+ -+ void -+ sepgsqlCheckColumnSetattr(Oid relOid, AttrNumber attno) -+ { -+ checkColumnCommon(relOid, attno, SEPG_DB_COLUMN__SETATTR); -+ } -+ -+ Oid -+ sepgsqlCheckColumnRelabel(Oid relOid, AttrNumber attno, DefElem *newLabel) -+ { -+ sepgsql_sid_t attSid; -+ char relkind; -+ -+ if (!sepgsqlIsEnabled()) -+ { -+ if (newLabel) -+ ereport(ERROR, -+ (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("SELinux is disabled now"))); -+ return InvalidOid; -+ } -+ -+ relkind = get_rel_relkind(relOid); -+ if (relkind != RELKIND_RELATION) -+ ereport(ERROR, -+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), -+ errmsg("Unable to set security label on \"%s.%s\"", -+ get_rel_name(relOid), -+ get_attname(relOid, attno)))); -+ -+ attSid.relid = AttributeRelationId; -+ attSid.secid = securityTransSecLabelIn(attSid.relid, -+ strVal(newLabel->arg)); -+ -+ /* db_column:{setattr relabelfrom} for older seclabel */ -+ checkColumnCommon(relOid, attno, -+ SEPG_DB_COLUMN__SETATTR | -+ SEPG_DB_COLUMN__RELABELFROM); -+ -+ /* db_column:{relabelto} for newer seclabel */ -+ sepgsqlClientHasPerms(attSid, -+ SEPG_CLASS_DB_COLUMN, -+ SEPG_DB_COLUMN__RELABELTO, -+ get_attname(relOid, attno), true); -+ return attSid.secid; -+ } -+ -+ /* ------------------------------------------------------------ * -+ * Hooks corresponding to db_table object class -+ * ------------------------------------------------------------ */ -+ -+ /* -+ * NOTE: db_table/db_sequence:{create} permission is checked -+ * at sepgsqlCreateTableColumns() due to the reason -+ * for implementation. -+ * -+ * sepgsqlCheckTableReference -+ * checks db_table:{reference} and db_column:{reference} permission -+ * when the client tries to set up a foreign key constraint on the -+ * certain tables and columns. -+ */ -+ -+ static void -+ checkTableCommon(Oid table_oid, access_vector_t required) -+ { -+ HeapTuple tuple; -+ sepgsql_sid_t relSid; -+ uint16 tclass; -+ const char *auname; -+ -+ if (!sepgsqlIsEnabled()) -+ return; -+ -+ tuple = SearchSysCache(RELOID, -+ ObjectIdGetDatum(table_oid), -+ 0, 0, 0); -+ if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "cache lookup failed for relation %u", table_oid); -+ -+ auname = NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname); -+ relSid = sepgsqlGetTupleContext(RelationRelationId, -+ tuple, &tclass); -+ sepgsqlClientHasPerms(relSid, tclass, required, -+ auname, true); -+ ReleaseSysCache(tuple); -+ } -+ -+ void -+ sepgsqlCheckTableDrop(Oid table_oid) -+ { -+ checkTableCommon(table_oid, SEPG_DB_TABLE__DROP); -+ } -+ -+ void -+ sepgsqlCheckTableSetattr(Oid table_oid) -+ { -+ checkTableCommon(table_oid, SEPG_DB_TABLE__SETATTR); -+ } -+ -+ Oid -+ sepgsqlCheckTableRelabel(Oid table_oid, DefElem *newLabel) -+ { -+ sepgsql_sid_t relSid; -+ char relkind; -+ -+ if (!sepgsqlIsEnabled()) -+ { -+ if (newLabel) -+ ereport(ERROR, -+ (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("SELinux is disabled now"))); -+ return InvalidOid; -+ } -+ -+ relkind = get_rel_relkind(table_oid); -+ if (relkind != RELKIND_RELATION && relkind != RELKIND_SEQUENCE) -+ ereport(ERROR, -+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), -+ errmsg("Unable to set security label on \"%s\"", -+ get_rel_name(table_oid)))); -+ -+ relSid.relid = RelationRelationId; -+ relSid.secid = securityTransSecLabelIn(relSid.relid, -+ strVal(newLabel->arg)); -+ -+ /* db_table/db_sequence:{setattr relabelfrom} for older seclabel */ -+ checkTableCommon(table_oid, -+ SEPG_DB_TABLE__SETATTR | -+ SEPG_DB_TABLE__RELABELFROM); -+ -+ /* db_table/db_sequence:{relabelto} for newer seclabel */ -+ sepgsqlClientHasPerms(relSid, -+ (relkind == RELKIND_RELATION -+ ? SEPG_CLASS_DB_TABLE -+ : SEPG_CLASS_DB_SEQUENCE), -+ SEPG_DB_TABLE__RELABELTO, -+ get_rel_name(table_oid), true); -+ return relSid.secid; -+ } -+ -+ void -+ sepgsqlCheckTableLock(Oid table_oid) -+ { -+ checkTableCommon(table_oid, SEPG_DB_TABLE__LOCK); -+ } -+ -+ void -+ sepgsqlCheckTableTruncate(Relation rel) -+ { -+ HeapScanDesc scan; -+ HeapTuple tuple; -+ sepgsql_sid_t tupSid; -+ uint16 tclass; -+ -+ if (!sepgsqlIsEnabled()) -+ return; -+ -+ /* check db_table:{delete} permission */ -+ checkTableCommon(RelationGetRelid(rel), SEPG_DB_TABLE__DELETE); -+ -+ /* row-level access control is enabled? */ -+ if (!sepostgresql_row_level) -+ return; -+ -+ /* check db_tuple:{delete} permission */ -+ scan = heap_beginscan(rel, SnapshotNow, 0, NULL); -+ -+ while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) -+ { -+ tupSid = sepgsqlGetTupleContext(RelationGetRelid(rel), -+ tuple, &tclass); -+ sepgsqlClientHasPerms(tupSid, -+ tclass, SEPG_DB_TUPLE__DELETE, -+ NULL, true); -+ } -+ heap_endscan(scan); -+ } -+ -+ void -+ sepgsqlCheckTableReference(Relation rel, int16 *attnums, int natts) -+ { -+ int i; -+ -+ checkTableCommon(RelationGetRelid(rel), SEPG_DB_TABLE__REFERENCE); -+ -+ for (i=0; i < natts; i++) -+ { -+ checkColumnCommon(RelationGetRelid(rel), -+ attnums[i], SEPG_DB_COLUMN__REFERENCE); -+ } -+ } -+ -+ /* ------------------------------------------------------------ * -+ * Hooks corresponding to db_sequence object class -+ * ------------------------------------------------------------ */ -+ void sepgsqlCheckSequenceGetValue(Oid seqOid) -+ { -+ checkTableCommon(seqOid, SEPG_DB_SEQUENCE__GET_VALUE); -+ } -+ -+ void sepgsqlCheckSequenceNextValue(Oid seqOid) -+ { -+ checkTableCommon(seqOid, SEPG_DB_SEQUENCE__NEXT_VALUE); -+ } -+ -+ void sepgsqlCheckSequenceSetValue(Oid seqOid) -+ { -+ checkTableCommon(seqOid, SEPG_DB_SEQUENCE__SET_VALUE); -+ } -+ -+ /* ------------------------------------------------------------ * -+ * Hooks corresponding to db_procedure object class -+ * ------------------------------------------------------------ */ -+ static bool -+ checkProcedureCommon(Oid procOid, uint32 required, bool abort) -+ { -+ sepgsql_sid_t proSid; -+ HeapTuple tuple; -+ uint16 tclass; -+ const char *auname; -+ bool rc; -+ -+ if (!sepgsqlIsEnabled()) -+ return true; -+ -+ tuple = SearchSysCache(PROCOID, -+ ObjectIdGetDatum(procOid), -+ 0, 0, 0); -+ if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "cache lookup failed for procedure: %u", procOid); -+ -+ auname = NameStr(((Form_pg_proc) GETSTRUCT(tuple))->proname); -+ proSid = sepgsqlGetTupleContext(ProcedureRelationId, -+ tuple, &tclass); -+ rc = sepgsqlClientHasPerms(proSid, tclass, required, -+ auname, abort); -+ -+ ReleaseSysCache(tuple); -+ -+ return rc; -+ } -+ -+ Oid -+ sepgsqlCheckProcedureCreate(const char *procName, Oid procOid, -+ Oid procNsp, Oid procLang, DefElem *newLabel) -+ { -+ sepgsql_sid_t proSid; -+ HeapTuple tuple; -+ uint32 required; -+ -+ if (!sepgsqlIsEnabled()) -+ return InvalidOid; -+ -+ if (!OidIsValid(procOid)) -+ { -+ /* create a new function */ -+ required = SEPG_DB_PROCEDURE__CREATE; -+ if (!newLabel) -+ proSid = sepgsqlGetDefaultProcedureSecid(procNsp); -+ else -+ { -+ proSid.relid = ProcedureRelationId; -+ proSid.secid = securityTransSecLabelIn(proSid.relid, -+ strVal(newLabel->arg)); -+ } -+ } -+ else if (!newLabel) -+ { -+ /* replace an existing function, without any label */ -+ required = SEPG_DB_PROCEDURE__SETATTR; -+ tuple = SearchSysCache(PROCOID, -+ ObjectIdGetDatum(procOid), -+ 0, 0, 0); -+ if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "cache lookup failed for procedure: %u", procOid); -+ -+ proSid = sepgsqlGetTupleContext(ProcedureRelationId, -+ tuple, NULL); -+ ReleaseSysCache(tuple); -+ } -+ else -+ { -+ /* replace an existing function, with relabeling */ -+ checkProcedureCommon(procOid, -+ SEPG_DB_PROCEDURE__SETATTR | -+ SEPG_DB_PROCEDURE__RELABELFROM, true); -+ -+ required = SEPG_DB_PROCEDURE__RELABELTO; -+ proSid.relid = ProcedureRelationId; -+ proSid.secid = securityTransSecLabelIn(proSid.relid, -+ strVal(newLabel->arg)); -+ } -+ -+ /* Procedural language is trusted? */ -+ tuple = SearchSysCache(LANGOID, -+ ObjectIdGetDatum(procLang), -+ 0, 0, 0); -+ if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "cache lookup failed for procedural langugage: %u", procLang); -+ -+ if (!((Form_pg_language) GETSTRUCT(tuple))->lanpltrusted) -+ required |= SEPG_DB_PROCEDURE__UNTRUSTED; -+ -+ ReleaseSysCache(tuple); -+ -+ /* check it */ -+ sepgsqlClientHasPerms(proSid, -+ SEPG_CLASS_DB_PROCEDURE, required, -+ procName, true); -+ -+ return proSid.secid; -+ } -+ -+ void -+ sepgsqlCheckProcedureDrop(Oid procOid) -+ { -+ checkProcedureCommon(procOid, SEPG_DB_PROCEDURE__DROP, true); -+ } -+ -+ void -+ sepgsqlCheckProcedureSetattr(Oid procOid) -+ { -+ checkProcedureCommon(procOid, SEPG_DB_PROCEDURE__SETATTR, true); -+ } -+ -+ Oid -+ sepgsqlCheckProcedureRelabel(Oid procOid, DefElem *newLabel) -+ { -+ sepgsql_sid_t proSid; -+ -+ if (!sepgsqlIsEnabled()) -+ { -+ if (newLabel) -+ ereport(ERROR, -+ (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("SELinux is disabled now"))); -+ return InvalidOid; -+ } -+ -+ proSid.relid = ProcedureRelationId; -+ proSid.secid = securityTransSecLabelIn(proSid.relid, -+ strVal(newLabel->arg)); -+ -+ /* db_procedure:{setattr relabelfrom} for older seclabel */ -+ checkProcedureCommon(procOid, -+ SEPG_DB_PROCEDURE__SETATTR | -+ SEPG_DB_PROCEDURE__RELABELFROM, true); -+ /* db_procedure:{relabelto} for newer seclabel */ -+ sepgsqlClientHasPerms(proSid, -+ SEPG_CLASS_DB_PROCEDURE, -+ SEPG_DB_PROCEDURE__RELABELTO, -+ get_func_name(procOid), true); -+ return proSid.secid; -+ } -+ -+ void -+ sepgsqlCheckProcedureExecute(Oid procOid) -+ { -+ checkProcedureCommon(procOid, SEPG_DB_PROCEDURE__EXECUTE, true); -+ } -+ -+ /* -+ * sepgsqlCheckProcedureInstall -+ * -+ * It should be checked when a procedure is installed as a part of system -+ * internal stuff. -+ */ -+ void -+ sepgsqlCheckProcedureInstall(Oid procOid) -+ { -+ if (OidIsValid(procOid)) -+ checkProcedureCommon(procOid, SEPG_DB_PROCEDURE__INSTALL, true); -+ } -+ -+ /* -+ * sepgsqlHintProcedureInlined -+ * -+ * It provides a hint whether the given sql procedure can be inlined, or not. -+ */ -+ bool -+ sepgsqlHintProcedureInlined(HeapTuple protup) -+ { -+ security_context_t newcon; -+ sepgsql_sid_t proSid; -+ -+ if (!sepgsqlIsEnabled()) -+ return true; -+ -+ if (!checkProcedureCommon(HeapTupleGetOid(protup), -+ SEPG_DB_PROCEDURE__EXECUTE, false)) -+ return false; -+ /* -+ * If the security context of client is unchange -+ * before or after invocation of the functions, -+ * it is not a trusted procedure, so it can be -+ * inlined due to performance purpose. -+ */ -+ proSid = sepgsqlGetTupleContext(ProcedureRelationId, -+ protup, NULL); -+ -+ newcon = sepgsqlClientCreateLabel(proSid, SEPG_CLASS_PROCESS); -+ -+ if (strcmp(sepgsqlGetClientLabel(), newcon) == 0) -+ return true; -+ -+ return false; -+ } -+ -+ /* -+ * sepgsqlCheckProcedureEntrypoint -+ * checks whether the given function call causes domain transition, -+ * or not. If it needs a domain transition, it injects a wrapper -+ * function to invoke it under new domain. -+ */ -+ struct TrustedProcedureCache -+ { -+ FmgrInfo flinfo; -+ char newcon[1]; -+ }; -+ -+ static Datum -+ sepgsqlTrustedProcedure(PG_FUNCTION_ARGS) -+ { -+ struct TrustedProcedureCache *tcache; -+ security_context_t save_context; -+ FmgrInfo *save_flinfo; -+ Datum result; -+ -+ tcache = fcinfo->flinfo->fn_extra; -+ Assert(tcache != NULL); -+ -+ save_context = sepgsqlSwitchClient(tcache->newcon); -+ save_flinfo = fcinfo->flinfo; -+ fcinfo->flinfo = &tcache->flinfo; -+ -+ PG_TRY(); -+ { -+ result = FunctionCallInvoke(fcinfo); -+ } -+ PG_CATCH(); -+ { -+ sepgsqlSwitchClient(save_context); -+ fcinfo->flinfo = save_flinfo; -+ PG_RE_THROW(); -+ } -+ PG_END_TRY(); -+ sepgsqlSwitchClient(save_context); -+ fcinfo->flinfo = save_flinfo; -+ -+ return result; -+ } -+ -+ void -+ sepgsqlCheckProcedureEntrypoint(FmgrInfo *flinfo, HeapTuple protup) -+ { -+ struct TrustedProcedureCache *tcache; -+ security_context_t newcon; -+ sepgsql_sid_t proSid; -+ -+ if (!sepgsqlIsEnabled()) -+ return; -+ -+ proSid = sepgsqlGetTupleContext(ProcedureRelationId, -+ protup, NULL); -+ -+ newcon = sepgsqlClientCreateLabel(proSid, SEPG_CLASS_PROCESS); -+ -+ /* Do nothing, if it is not a trusted procedure */ -+ if (strcmp(newcon, sepgsqlGetClientLabel()) == 0) -+ return; -+ -+ /* check db_procedure:{entrypoint} */ -+ sepgsqlClientHasPerms(proSid, -+ SEPG_CLASS_DB_PROCEDURE, -+ SEPG_DB_PROCEDURE__ENTRYPOINT, -+ NULL, true); -+ -+ /* check process:{transition} */ -+ sepgsqlComputePerms(sepgsqlGetClientLabel(), -+ newcon, -+ SEPG_CLASS_PROCESS, -+ SEPG_PROCESS__TRANSITION, -+ NULL, true); -+ -+ /* setup trusted procedure */ -+ tcache = MemoryContextAllocZero(flinfo->fn_mcxt, -+ sizeof(*tcache) + strlen(newcon)); -+ memcpy(&tcache->flinfo, flinfo, sizeof(*flinfo)); -+ strcpy(tcache->newcon, newcon); -+ flinfo->fn_addr = sepgsqlTrustedProcedure; -+ flinfo->fn_extra = tcache; -+ } -+ -+ /* + * sepgsqlCheckBlobCreate + * assigns a default security label and checks db_blob:{create} + */ @@ -9530,7 +12751,7 @@ diff -Nrpc base/src/backend/security/sepgsql/hooks.c sepgsql/src/backend/securit + /* set a default security context */ + sepgsqlSetDefaultSecid(rel, lotup); + -+ loSid = sepgsqlGetTupleContext(relid, lotup, NULL); ++ loSid = sepgsqlGetTupleSecid(relid, lotup, NULL); + sepgsqlClientHasPerms(loSid, + SEPG_CLASS_DB_BLOB, + SEPG_DB_BLOB__CREATE, @@ -9550,7 +12771,7 @@ diff -Nrpc base/src/backend/security/sepgsql/hooks.c sepgsql/src/backend/securit + if (!sepgsqlIsEnabled()) + return; + -+ loSid = sepgsqlGetTupleContext(relid, lotup, NULL); ++ loSid = sepgsqlGetTupleSecid(relid, lotup, NULL); + sepgsqlClientHasPerms(loSid, + SEPG_CLASS_DB_BLOB, + SEPG_DB_BLOB__DROP, @@ -9642,8 +12863,7 @@ diff -Nrpc base/src/backend/security/sepgsql/hooks.c sepgsql/src/backend/securit + * check db_blob:{read export} and file:{write} permission + */ + void -+ sepgsqlCheckBlobExport(LargeObjectDesc *lobj, -+ int fdesc, const char *filename) ++ sepgsqlCheckBlobExport(LargeObjectDesc *lobj, const char *filename) + { + sepgsql_sid_t loSid; + @@ -9658,7 +12878,7 @@ diff -Nrpc base/src/backend/security/sepgsql/hooks.c sepgsql/src/backend/securit + SEPG_DB_BLOB__READ | SEPG_DB_BLOB__EXPORT, + NULL, true); + /* file:{write} */ -+ sepgsqlCheckFileWrite(fdesc, filename); ++ sepgsql_file_write(filename); + } + + /* @@ -9666,8 +12886,7 @@ diff -Nrpc base/src/backend/security/sepgsql/hooks.c sepgsql/src/backend/securit + * check db_blob:{write import} and file:{read} permission + */ + void -+ sepgsqlCheckBlobImport(LargeObjectDesc *lobj, -+ int fdesc, const char *filename) ++ sepgsqlCheckBlobImport(LargeObjectDesc *lobj, const char *filename) + { + sepgsql_sid_t loSid; + @@ -9682,7 +12901,7 @@ diff -Nrpc base/src/backend/security/sepgsql/hooks.c sepgsql/src/backend/securit + SEPG_DB_BLOB__WRITE | SEPG_DB_BLOB__IMPORT, + NULL, true); + /* file:{read} */ -+ sepgsqlCheckFileRead(fdesc, filename); ++ sepgsql_file_read(filename); + } + + /* @@ -9699,7 +12918,7 @@ diff -Nrpc base/src/backend/security/sepgsql/hooks.c sepgsql/src/backend/securit + required |= SEPG_DB_BLOB__RELABELFROM; + + /* db_blob:{setattr relabelfrom} */ -+ loSid = sepgsqlGetTupleContext(LargeObjectRelationId, oldtup, NULL); ++ loSid = sepgsqlGetTupleSecid(LargeObjectRelationId, oldtup, NULL); + sepgsqlClientHasPerms(loSid, + SEPG_CLASS_DB_BLOB, + required, @@ -9709,164 +12928,18 @@ diff -Nrpc base/src/backend/security/sepgsql/hooks.c sepgsql/src/backend/securit + return; + + /* db_blob:{relabelto} */ -+ loSid = sepgsqlGetTupleContext(LargeObjectRelationId, newtup, NULL); ++ loSid = sepgsqlGetTupleSecid(LargeObjectRelationId, newtup, NULL); + sepgsqlClientHasPerms(loSid, + SEPG_CLASS_DB_BLOB, + SEPG_DB_BLOB__RELABELTO, + NULL, true); + } -+ -+ /* -+ * sepgsqlCheckSysobjCreate -+ * -+ * It checks db_tuple:{insert} for system catalog -+ */ -+ Oid -+ sepgsqlCheckSysobjCreate(Oid relid, const char *auditName) -+ { -+ sepgsql_sid_t sysSid; -+ -+ if (!sepgsqlIsEnabled()) -+ return InvalidOid; -+ -+ sysSid = sepgsqlGetDefaultTupleSecid(relid); -+ -+ sepgsqlClientHasPerms(sysSid, -+ SEPG_CLASS_DB_TUPLE, -+ SEPG_DB_TUPLE__INSERT, -+ auditName, true); -+ -+ return sysSid.secid; -+ } -+ -+ /* -+ * sepgsqlCheckSysobjGetattr -+ * -+ * It checks db_tuple:{select} for system catalog -+ */ -+ void -+ sepgsqlCheckSysobjGetattr(Oid relid, Oid secid, const char *auditName) -+ { -+ sepgsql_sid_t sysSid; -+ -+ if (!sepgsqlIsEnabled()) -+ return; -+ -+ sysSid.relid = relid; -+ sysSid.secid = secid; -+ sepgsqlClientHasPerms(sysSid, -+ SEPG_CLASS_DB_TUPLE, -+ SEPG_DB_TUPLE__SELECT, -+ auditName, true); -+ } -+ -+ /* -+ * sepgsqlCheckSysobjSetattr -+ * -+ * It checks db_tuple:{update} for system catalog -+ */ -+ void -+ sepgsqlCheckSysobjSetattr(Oid relid, Oid secid, const char *auditName) -+ { -+ sepgsql_sid_t sysSid; -+ -+ if (!sepgsqlIsEnabled()) -+ return; -+ -+ sysSid.relid = relid; -+ sysSid.secid = secid; -+ sepgsqlClientHasPerms(sysSid, -+ SEPG_CLASS_DB_TUPLE, -+ SEPG_DB_TUPLE__UPDATE, -+ auditName, true); -+ } -+ -+ /* -+ * sepgsqlCheckSysobjDrop -+ * It checks db_xxx:{drop} permission on the given opaque -+ * object, invoked from deleteOneObject() -+ */ -+ void -+ sepgsqlCheckSysobjDrop(const ObjectAddress *object) -+ { -+ switch (object->classId) -+ { -+ case NamespaceRelationId: -+ sepgsqlCheckSchemaDrop(object->objectId); -+ break; -+ -+ case RelationRelationId: -+ if (!object->objectSubId) -+ sepgsqlCheckTableDrop(object->objectId); -+ else -+ sepgsqlCheckColumnDrop(object->objectId, object->objectSubId); -+ break; -+ -+ case ProcedureRelationId: -+ sepgsqlCheckProcedureDrop(object->objectId); -+ break; -+ -+ default: -+ /* do nothing in this version */ -+ break; -+ } -+ } -+ -+ /* -+ * sepgsqlCheckFileRead -+ * sepgsqlCheckFileWrite -+ * check file:{read} or file:{write} permission on the given file, -+ * and raises an error if violated. -+ */ -+ static void -+ checkFileCommon(int fdesc, const char *filename, access_vector_t perms) -+ { -+ security_context_t context; -+ security_class_t tclass; -+ -+ if (!sepgsqlIsEnabled()) -+ return; -+ -+ tclass = sepgsqlFileObjectClass(fdesc); -+ -+ if (fgetfilecon_raw(fdesc, &context) < 0) -+ ereport(ERROR, -+ (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("SELinux: could not get context of %s", filename))); -+ PG_TRY(); -+ { -+ sepgsqlComputePerms(sepgsqlGetClientLabel(), -+ context, -+ tclass, -+ perms, -+ filename, true); -+ } -+ PG_CATCH(); -+ { -+ freecon(context); -+ PG_RE_THROW(); -+ } -+ PG_END_TRY(); -+ freecon(context); -+ } -+ -+ void -+ sepgsqlCheckFileRead(int fdesc, const char *filename) -+ { -+ checkFileCommon(fdesc, filename, SEPG_FILE__READ); -+ } -+ -+ void -+ sepgsqlCheckFileWrite(int fdesc, const char *filename) -+ { -+ checkFileCommon(fdesc, filename, SEPG_FILE__WRITE); -+ } diff -Nrpc base/src/backend/security/sepgsql/label.c sepgsql/src/backend/security/sepgsql/label.c *** base/src/backend/security/sepgsql/label.c Thu Jan 1 09:00:00 1970 ---- sepgsql/src/backend/security/sepgsql/label.c Thu Sep 10 15:18:03 2009 +--- sepgsql/src/backend/security/sepgsql/label.c Fri Sep 25 17:27:05 2009 *************** *** 0 **** ---- 1,1151 ---- +--- 1,1140 ---- + /* + * src/backend/security/sepgsql/label.c + * SE-PostgreSQL security label management @@ -9913,6 +12986,7 @@ diff -Nrpc base/src/backend/security/sepgsql/label.c sepgsql/src/backend/securit + #include "catalog/pg_tablespace.h" + #include "catalog/pg_trigger.h" + #include "catalog/pg_ts_config.h" ++ #include "catalog/pg_ts_config_map.h" + #include "catalog/pg_ts_dict.h" + #include "catalog/pg_ts_parser.h" + #include "catalog/pg_ts_template.h" @@ -10073,14 +13147,6 @@ diff -Nrpc base/src/backend/security/sepgsql/label.c sepgsql/src/backend/securit + SEPG_CLASS_DB_SCHEMA); + } + -+ sepgsql_sid_t -+ sepgsqlGetDefaultSchemaTempSecid(Oid database_oid) -+ { -+ return defaultSecidWithDatabase(NamespaceRelationId, -+ database_oid, -+ SEPG_CLASS_DB_SCHEMA_TEMP); -+ } -+ + static sepgsql_sid_t + defaultSecidWithSchema(Oid relid, Oid nspoid, uint16 tclass) + { @@ -10196,9 +13262,10 @@ diff -Nrpc base/src/backend/security/sepgsql/label.c sepgsql/src/backend/securit + void + sepgsqlSetDefaultSecid(Relation rel, HeapTuple tuple) + { -+ Oid relOid = RelationGetRelid(rel); -+ Oid nspOid, tblOid; + sepgsql_sid_t newSid; ++ Oid relOid = RelationGetRelid(rel); ++ Oid nspOid, tblOid; ++ char relkind; + + if (!sepgsqlIsEnabled()) + return; @@ -10206,282 +13273,85 @@ diff -Nrpc base/src/backend/security/sepgsql/label.c sepgsql/src/backend/securit + if (!HeapTupleHasSecid(tuple)) + return; + -+ switch (sepgsqlTupleObjectClass(relOid, tuple)) ++ /* initialize */ ++ newSid.relid = relOid; ++ newSid.secid = InvalidOid; ++ ++ switch (relOid) + { -+ case SEPG_CLASS_DB_DATABASE: ++ case DatabaseRelationId: + newSid = sepgsqlGetDefaultDatabaseSecid(); + break; -+ case SEPG_CLASS_DB_SCHEMA: ++ ++ case NamespaceRelationId: + newSid = sepgsqlGetDefaultSchemaSecid(MyDatabaseId); + break; -+ case SEPG_CLASS_DB_SCHEMA_TEMP: -+ newSid = sepgsqlGetDefaultSchemaTempSecid(MyDatabaseId); -+ break; -+ case SEPG_CLASS_DB_TABLE: ++ ++ case RelationRelationId: + nspOid = ((Form_pg_class) GETSTRUCT(tuple))->relnamespace; -+ newSid = sepgsqlGetDefaultTableSecid(nspOid); ++ relkind = ((Form_pg_class) GETSTRUCT(tuple))->relkind; ++ ++ switch (relkind) ++ { ++ case RELKIND_RELATION: ++ newSid = sepgsqlGetDefaultTableSecid(nspOid); ++ break; ++ ++ case RELKIND_SEQUENCE: ++ newSid = sepgsqlGetDefaultSequenceSecid(nspOid); ++ break; ++ ++ default: ++ newSid = sepgsqlGetDefaultTupleSecid(relOid); ++ break; ++ } + break; -+ case SEPG_CLASS_DB_SEQUENCE: -+ nspOid = ((Form_pg_class) GETSTRUCT(tuple))->relnamespace; -+ newSid = sepgsqlGetDefaultSequenceSecid(nspOid); -+ break; -+ case SEPG_CLASS_DB_PROCEDURE: ++ ++ case ProcedureRelationId: + nspOid = ((Form_pg_proc) GETSTRUCT(tuple))->pronamespace; + newSid = sepgsqlGetDefaultProcedureSecid(nspOid); + break; -+ case SEPG_CLASS_DB_COLUMN: ++ ++ case AttributeRelationId: + tblOid = ((Form_pg_attribute) GETSTRUCT(tuple))->attrelid; -+ newSid = sepgsqlGetDefaultColumnSecid(tblOid); ++ ++ /* ++ * We cannot refer system cache in the very early initdb ++ * phase, because pg_class is not constructed yet. ++ */ ++ if ((IsBootstrapProcessingMode() && ++ (tblOid == TypeRelationId || ++ tblOid == ProcedureRelationId || ++ tblOid == AttributeRelationId || ++ tblOid == RelationRelationId)) ++ || get_rel_relkind(tblOid) == RELKIND_RELATION) ++ { ++ newSid = sepgsqlGetDefaultColumnSecid(tblOid); ++ } ++ /* otherwise, it does not have individual security context */ + break; -+ case SEPG_CLASS_DB_BLOB: ++ ++ case LargeObjectRelationId: + newSid = sepgsqlGetDefaultBlobSecid(MyDatabaseId); + break; ++ + default: + newSid = sepgsqlGetDefaultTupleSecid(relOid); + break; + } + -+ Assert(newSid.relid == relOid); + HeapTupleSetSecid(tuple, newSid.secid); + } + + /* -+ * sepgsqlCreateTableColumn -+ * It returns an array of security identifier for the new table -+ * and columns to be assigned. The corresponding security labels -+ * are already checked for db_table/db_sequence/db_column:{create} -+ * permission. -+ * In the default labeling rule, a column inherits the security -+ * label of its table, but we cannot refer it using system caches, -+ * because the command counter is not incremented under the -+ * heap_create_with_catalog(). Thus, we need to compute and check -+ * them prior to the actual creation of table and columns. -+ */ -+ Oid * -+ sepgsqlCreateTableColumns(CreateStmt *stmt, -+ const char *relname, Oid namespace_oid, -+ TupleDesc tupdesc, char relkind) -+ { -+ sepgsql_sid_t relsid; -+ Oid *secLabels = NULL; -+ int index; -+ -+ if (!sepgsqlIsEnabled()) -+ return NULL; -+ -+ /* -+ * In the current version, we don't assign any certain security -+ * labels on relations except for tables/sequences. -+ */ -+ if (relkind != RELKIND_RELATION && relkind != RELKIND_SEQUENCE) -+ return NULL; -+ -+ /* -+ * The secLabels array stores security identifiers to be assigned -+ * on the new table and columns. -+ * -+ * secLabels[0] is security identifier of the table. -+ * secLabels[attnum - FirstLowInvalidHeapAttributeNumber] -+ * is security identifier of columns. -+ */ -+ secLabels = palloc0(sizeof(Oid) * (tupdesc->natts -+ - FirstLowInvalidHeapAttributeNumber)); -+ -+ /* -+ * SELinux checks db_table/db_sequence:{create} -+ */ -+ switch (relkind) -+ { -+ case RELKIND_RELATION: -+ if (!stmt || !stmt->secLabel) -+ relsid = sepgsqlGetDefaultTableSecid(namespace_oid); -+ else -+ { -+ relsid.relid = RelationRelationId; -+ relsid.secid = securityTransSecLabelIn(relsid.relid, -+ strVal(((DefElem *)stmt->secLabel)->arg)); -+ } -+ sepgsqlClientHasPerms(relsid, -+ SEPG_CLASS_DB_TABLE, -+ SEPG_DB_TABLE__CREATE, -+ relname, true); -+ break; -+ -+ case RELKIND_SEQUENCE: -+ if (!stmt || !stmt->secLabel) -+ relsid = sepgsqlGetDefaultSequenceSecid(namespace_oid); -+ else -+ { -+ relsid.relid = RelationRelationId; -+ relsid.secid = securityTransSecLabelIn(relsid.relid, -+ strVal(((DefElem *)stmt->secLabel)->arg)); -+ } -+ sepgsqlClientHasPerms(relsid, -+ SEPG_CLASS_DB_SEQUENCE, -+ SEPG_DB_SEQUENCE__CREATE, -+ relname, true); -+ break; -+ -+ default: -+ if (stmt && stmt->secLabel) -+ ereport(ERROR, -+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), -+ errmsg("Unable to set security label on \"%s\"", relname))); -+ relsid = sepgsqlGetDefaultTupleSecid(RelationRelationId); -+ break; -+ } -+ /* table's security identifier to be assigned on */ -+ secLabels[0] = relsid.secid; -+ -+ /* -+ * SELinux checks db_column:{create} -+ */ -+ for (index = FirstLowInvalidHeapAttributeNumber + 1; -+ index < tupdesc->natts; -+ index++) -+ { -+ Form_pg_attribute attr; -+ sepgsql_sid_t attsid = { InvalidOid, InvalidOid }; -+ char attname[NAMEDATALEN * 2 + 3]; -+ -+ /* skip unnecessary attributes */ -+ if (index < 0 && (relkind == RELKIND_VIEW || -+ relkind == RELKIND_COMPOSITE_TYPE)) -+ continue; -+ if (index == ObjectIdAttributeNumber && !tupdesc->tdhasoid) -+ continue; -+ -+ if (index < 0) -+ attr = SystemAttributeDefinition(index, tupdesc->tdhasoid); -+ else -+ attr = tupdesc->attrs[index]; -+ -+ /* Is there any given security label? */ -+ if (stmt) -+ { -+ ListCell *l; -+ -+ foreach (l, stmt->tableElts) -+ { -+ ColumnDef *colDef = lfirst(l); -+ -+ if (colDef->secLabel && -+ strcmp(colDef->colname, NameStr(attr->attname)) == 0) -+ { -+ attsid.relid = AttributeRelationId; -+ attsid.secid = securityTransSecLabelIn(attsid.relid, -+ strVal(((DefElem *)colDef->secLabel)->arg)); -+ break; -+ } -+ } -+ } -+ -+ switch (relkind) -+ { -+ case RELKIND_RELATION: -+ /* compute default column's label if necessary */ -+ if (!SidIsValid(attsid)) -+ attsid = sepgsqlClientCreateSecid(relsid, -+ SEPG_CLASS_DB_COLUMN, -+ AttributeRelationId); -+ -+ sprintf(attname, "%s.%s", relname, NameStr(attr->attname)); -+ sepgsqlClientHasPerms(attsid, -+ SEPG_CLASS_DB_COLUMN, -+ SEPG_DB_COLUMN__CREATE, -+ attname, true); -+ break; -+ -+ default: -+ if (SidIsValid(attsid)) -+ ereport(ERROR, -+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), -+ errmsg("Unable to set security label on \"%s.%s\"", -+ relname, NameStr(attr->attname)))); -+ attsid = sepgsqlGetDefaultTupleSecid(AttributeRelationId); -+ break; -+ } -+ /* column's security identifier to be assigend on */ -+ secLabels[index - FirstLowInvalidHeapAttributeNumber] = attsid.secid; -+ } -+ return secLabels; -+ } -+ -+ /* -+ * sepgsqlCopyTableColumns -+ * It returns an array of security identifier of table and columns -+ * to be copied on make_new_heap(). It actually create a new temporary -+ * relation and insert all the tuples within original one into the -+ * temporary one, but swap_relation_files() swaps their file nodes. -+ * Thus, there are no changes from the viewpoint of users. -+ * SE-PostgreSQL also does not check and change anything. It simply -+ * copies security identifier of the source relation to the destination -+ * relation. -+ */ -+ Oid * -+ sepgsqlCopyTableColumns(Relation source) -+ { -+ HeapTuple tuple; -+ Oid *secLabels; -+ Oid relid = RelationGetRelid(source); -+ int index; -+ -+ if (!sepgsqlIsEnabled()) -+ return PointerGetDatum(NULL); -+ -+ /* see the comment at sepgsqlCreateTableColumn*/ -+ secLabels = palloc0(sizeof(Oid) * (RelationGetDescr(source)->natts -+ - FirstLowInvalidHeapAttributeNumber)); -+ -+ /* copy table's security identifier */ -+ tuple = SearchSysCache(RELOID, -+ ObjectIdGetDatum(relid), -+ 0, 0, 0); -+ if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "cache lookup failed for relation \"%s\"", -+ RelationGetRelationName(source)); -+ -+ secLabels[0] = HeapTupleGetSecid(tuple); -+ -+ ReleaseSysCache(tuple); -+ -+ /* copy column's security identifier */ -+ for (index = FirstLowInvalidHeapAttributeNumber + 1; -+ index < RelationGetDescr(source)->natts; -+ index++) -+ { -+ Form_pg_attribute attr; -+ -+ if (index < 0) -+ attr = SystemAttributeDefinition(index, true); -+ else -+ attr = RelationGetDescr(source)->attrs[index]; -+ -+ tuple = SearchSysCache(ATTNUM, -+ ObjectIdGetDatum(relid), -+ Int16GetDatum(attr->attnum), -+ 0, 0); -+ if (!HeapTupleIsValid(tuple)) -+ continue; -+ -+ secLabels[index - FirstLowInvalidHeapAttributeNumber] -+ = HeapTupleGetSecid(tuple); -+ -+ ReleaseSysCache(tuple); -+ } -+ -+ return secLabels; -+ } -+ -+ /* -+ * sepgsqlGetSysobjContext ++ * sepgsqlGetSysobjSecid + * + * It returns a pair of relid/secid for the given OID. + */ + static sepgsql_sid_t -+ getSysobjContextDirect(Oid classOid, Oid indexOid, Oid objectId, uint16 *tclass) ++ getSysobjSecidDirect(Oid classOid, Oid indexOid, Oid objectId, uint16 *tclass) + { -+ sepgsql_sid_t sid = { InvalidOid, InvalidOid }; ++ sepgsql_sid_t sid; + Relation rel; + HeapTuple tup; + ScanKeyData skey; @@ -10498,8 +13368,11 @@ diff -Nrpc base/src/backend/security/sepgsql/label.c sepgsql/src/backend/securit + SnapshotNow, 1, &skey); + tup = systable_getnext(scan); + -+ if (HeapTupleIsValid(tup)) -+ sid = sepgsqlGetTupleContext(classOid, tup, tclass); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "system object lookup failed for oid %u on relation %u", ++ objectId, classOid); ++ ++ sid = sepgsqlGetTupleSecid(classOid, tup, tclass); + + systable_endscan(scan); + @@ -10509,10 +13382,10 @@ diff -Nrpc base/src/backend/security/sepgsql/label.c sepgsql/src/backend/securit + } + + sepgsql_sid_t -+ sepgsqlGetSysobjContext(Oid classOid, Oid objectId, int32 objsubId, uint16 *tclass) ++ sepgsqlGetSysobjSecid(Oid classOid, Oid objectId, int32 objsubId, uint16 *tclass) + { -+ sepgsql_sid_t sid = { InvalidOid, InvalidOid }; -+ HeapTuple tup = NULL; ++ sepgsql_sid_t sid; ++ HeapTuple tup; + + switch (classOid) + { @@ -10520,57 +13393,71 @@ diff -Nrpc base/src/backend/security/sepgsql/label.c sepgsql/src/backend/securit + tup = SearchSysCache(AMOID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for access method: %u", objectId); + break; + + case AccessMethodOperatorRelationId: -+ return getSysobjContextDirect(AccessMethodOperatorRelationId, -+ AccessMethodOperatorOidIndexId, -+ objectId, tclass); ++ return getSysobjSecidDirect(AccessMethodOperatorRelationId, ++ AccessMethodOperatorOidIndexId, ++ objectId, tclass); + + case AccessMethodProcedureRelationId: -+ return getSysobjContextDirect(AccessMethodProcedureRelationId, -+ AccessMethodProcedureOidIndexId, -+ objectId, tclass); ++ return getSysobjSecidDirect(AccessMethodProcedureRelationId, ++ AccessMethodProcedureOidIndexId, ++ objectId, tclass); + + case AuthIdRelationId: + tup = SearchSysCache(AUTHOID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for role: %u", objectId); + break; + + case CastRelationId: -+ return getSysobjContextDirect(CastRelationId, -+ CastOidIndexId, -+ objectId, tclass); ++ return getSysobjSecidDirect(CastRelationId, ++ CastOidIndexId, ++ objectId, tclass); + + case ConstraintRelationId: + tup = SearchSysCache(CONSTROID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for constraint: %u", objectId); + break; + + case ConversionRelationId: + tup = SearchSysCache(CONVOID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for conversion: %u", objectId); + break; + + case DatabaseRelationId: + tup = SearchSysCache(DATABASEOID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for database: %u", objectId); + break; + + case ForeignDataWrapperRelationId: + tup = SearchSysCache(FOREIGNDATAWRAPPEROID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for FDW: %u", objectId); + break; + + case ForeignServerRelationId: + tup = SearchSysCache(FOREIGNSERVEROID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for foreign server: %u", objectId); + break; + + case LanguageRelationId: @@ -10598,9 +13485,10 @@ diff -Nrpc base/src/backend/security/sepgsql/label.c sepgsql/src/backend/securit + + tup = systable_getnext(scan); + -+ if (HeapTupleIsValid(tup)) -+ sid = sepgsqlGetTupleContext(classOid, tup, tclass); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "largeobject %u lookup failed", objectId); + ++ sid = sepgsqlGetTupleSecid(classOid, tup, tclass); + systable_endscan(scan); + + heap_close(rel, AccessShareLock); @@ -10615,6 +13503,9 @@ diff -Nrpc base/src/backend/security/sepgsql/label.c sepgsql/src/backend/securit + ObjectIdGetDatum(objectId), + Int16GetDatum(objsubId), + 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for attribute %d of relation %u", ++ objsubId, objectId); + } + else + { @@ -10622,6 +13513,8 @@ diff -Nrpc base/src/backend/security/sepgsql/label.c sepgsql/src/backend/securit + tup = SearchSysCache(RELOID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for relation %u", objectId); + } + break; + @@ -10629,99 +13522,122 @@ diff -Nrpc base/src/backend/security/sepgsql/label.c sepgsql/src/backend/securit + tup = SearchSysCache(NAMESPACEOID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for schema %u", objectId); + break; + + case OperatorClassRelationId: + tup = SearchSysCache(CLAOID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for opclass %u", objectId); + break; + + case OperatorFamilyRelationId: + tup = SearchSysCache(OPFAMILYOID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for opfamily %u", objectId); + break; + + case OperatorRelationId: + tup = SearchSysCache(OPEROID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for operator %u", objectId); + break; + + case ProcedureRelationId: + tup = SearchSysCache(PROCOID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for procedure %u", objectId); + break; + + case RewriteRelationId: -+ return getSysobjContextDirect(RewriteRelationId, -+ RewriteOidIndexId, -+ objectId, tclass); ++ return getSysobjSecidDirect(RewriteRelationId, ++ RewriteOidIndexId, ++ objectId, tclass); + + case TableSpaceRelationId: -+ return getSysobjContextDirect(TableSpaceRelationId, -+ TablespaceOidIndexId, -+ objectId, tclass); ++ return getSysobjSecidDirect(TableSpaceRelationId, ++ TablespaceOidIndexId, ++ objectId, tclass); + + case TriggerRelationId: -+ return getSysobjContextDirect(TriggerRelationId, -+ TriggerOidIndexId, -+ objectId, tclass); ++ return getSysobjSecidDirect(TriggerRelationId, ++ TriggerOidIndexId, ++ objectId, tclass); + + case TSConfigRelationId: + tup = SearchSysCache(TSCONFIGOID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for text search configuration %u", objectId); + break; + + case TSDictionaryRelationId: + tup = SearchSysCache(TSDICTOID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for text search dictionary %u", objectId); + break; + + case TSParserRelationId: + tup = SearchSysCache(TSPARSEROID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for text search parser %u", objectId); + break; + + case TSTemplateRelationId: + tup = SearchSysCache(TSTEMPLATEOID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for text search template %u", objectId); + break; + + case TypeRelationId: + tup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for type %u", objectId); + break; + + case UserMappingRelationId: + tup = SearchSysCache(USERMAPPINGOID, + ObjectIdGetDatum(objectId), + 0, 0, 0); ++ if (!HeapTupleIsValid(tup)) ++ elog(ERROR, "cache lookup failed for user mapping %u", objectId); + break; + + default: + elog(ERROR, "unexpected class OID: %u", classOid); ++ tup = NULL; /* for compiler quiet */ + break; + } -+ -+ if (HeapTupleIsValid(tup)) -+ { -+ sid = sepgsqlGetTupleContext(classOid, tup, tclass); -+ ReleaseSysCache(tup); -+ } ++ ++ Assert(HeapTupleIsValid(tup)); ++ ++ sid = sepgsqlGetTupleSecid(classOid, tup, tclass); ++ ++ ReleaseSysCache(tup); + + return sid; + } + + /* -+ * sepgsqlGetTupleContext ++ * sepgsqlGetTupleSecid + * + * It returns a pair of relid/secid for the given HeapTuple. + * A few system catalogs is handled as an attribute of other @@ -10729,59 +13645,109 @@ diff -Nrpc base/src/backend/security/sepgsql/label.c sepgsql/src/backend/securit + * E.g) pg_attrdef is an attribute of a certain pg_attribute + */ + sepgsql_sid_t -+ sepgsqlGetTupleContext(Oid tableOid, HeapTuple tuple, uint16 *tclass) ++ sepgsqlGetTupleSecid(Oid tableOid, HeapTuple tuple, uint16 *tclass) + { -+ sepgsql_sid_t sid = { InvalidOid, InvalidOid }; ++ sepgsql_sid_t sid; + HeapTuple exttup; + Oid extid; + Oid extcls; + AttrNumber extsub; + ++ /* initialize (unlabeled security context) */ ++ sid.relid = tableOid; ++ sid.secid = InvalidOid; + if (tclass) + *tclass = SEPG_CLASS_DB_TUPLE; + + switch (tableOid) + { + case AggregateRelationId: -+ sid.relid = ProcedureRelationId; + extid = ((Form_pg_aggregate) GETSTRUCT(tuple))->aggfnoid; + exttup = SearchSysCache(PROCOID, + ObjectIdGetDatum(extid), + 0, 0, 0); ++ if (HeapTupleIsValid(exttup)) ++ { ++ sid = sepgsqlGetTupleSecid(ProcedureRelationId, ++ exttup, tclass); ++ ReleaseSysCache(exttup); ++ } + break; + + case AccessMethodOperatorRelationId: -+ sid.relid = OperatorFamilyRelationId; + extid = ((Form_pg_amop) GETSTRUCT(tuple))->amopfamily; + exttup = SearchSysCache(OPFAMILYOID, + ObjectIdGetDatum(extid), + 0, 0, 0); ++ if (HeapTupleIsValid(exttup)) ++ { ++ sid = sepgsqlGetTupleSecid(OperatorFamilyRelationId, ++ exttup, tclass); ++ ReleaseSysCache(exttup); ++ } + break; + + case AccessMethodProcedureRelationId: -+ sid.relid = OperatorFamilyRelationId; + extid = ((Form_pg_amproc) GETSTRUCT(tuple))->amprocfamily; + exttup = SearchSysCache(OPFAMILYOID, + ObjectIdGetDatum(extid), + 0, 0, 0); ++ if (HeapTupleIsValid(exttup)) ++ { ++ sid = sepgsqlGetTupleSecid(OperatorFamilyRelationId, ++ exttup, tclass); ++ ReleaseSysCache(exttup); ++ } + break; + + case AttrDefaultRelationId: -+ sid.relid = AttributeRelationId; + extid = ((Form_pg_attrdef) GETSTRUCT(tuple))->adrelid; + extsub = ((Form_pg_attrdef) GETSTRUCT(tuple))->adnum; + exttup = SearchSysCache(ATTNUM, + ObjectIdGetDatum(extid), + Int16GetDatum(extsub), + 0, 0); ++ if (HeapTupleIsValid(exttup)) ++ { ++ sid = sepgsqlGetTupleSecid(AttributeRelationId, ++ exttup, tclass); ++ ReleaseSysCache(exttup); ++ } ++ break; ++ ++ case AttributeRelationId: ++ extid = ((Form_pg_attribute) GETSTRUCT(tuple))->attrelid; ++ exttup = SearchSysCache(RELOID, ++ ObjectIdGetDatum(extid), ++ 0, 0, 0); ++ if (HeapTupleIsValid(exttup)) ++ { ++ char relkind = ((Form_pg_class) GETSTRUCT(exttup))->relkind; ++ ++ if (relkind == RELKIND_RELATION) ++ { ++ if (tclass) ++ *tclass = SEPG_CLASS_DB_COLUMN; ++ sid.secid = HeapTupleGetSecid(tuple); ++ } ++ else ++ sid = sepgsqlGetTupleSecid(RelationRelationId, ++ exttup, tclass); ++ ReleaseSysCache(exttup); ++ } + break; + + case AuthMemRelationId: -+ sid.relid = AuthIdRelationId; + extid = ((Form_pg_auth_members) GETSTRUCT(tuple))->roleid; + exttup = SearchSysCache(AUTHOID, + ObjectIdGetDatum(extid), + 0, 0, 0); ++ if (HeapTupleIsValid(exttup)) ++ { ++ sid = sepgsqlGetTupleSecid(AuthIdRelationId, ++ exttup, tclass); ++ ReleaseSysCache(exttup); ++ } + break; + + case ConstraintRelationId: @@ -10789,10 +13755,15 @@ diff -Nrpc base/src/backend/security/sepgsql/label.c sepgsql/src/backend/securit + extid = ((Form_pg_constraint) GETSTRUCT(tuple))->conrelid; + if (OidIsValid(extid)) + { -+ sid.relid = RelationRelationId; + exttup = SearchSysCache(RELOID, + ObjectIdGetDatum(extid), + 0, 0, 0); ++ if (HeapTupleIsValid(exttup)) ++ { ++ sid = sepgsqlGetTupleSecid(RelationRelationId, ++ exttup, tclass); ++ ReleaseSysCache(exttup); ++ } + break; + } + /* DOMAIN constraint is an attribute of the domain type */ @@ -10803,93 +13774,184 @@ diff -Nrpc base/src/backend/security/sepgsql/label.c sepgsql/src/backend/securit + exttup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(extid), + 0, 0, 0); ++ if (HeapTupleIsValid(exttup)) ++ { ++ sid = sepgsqlGetTupleSecid(TypeRelationId, ++ exttup, tclass); ++ ReleaseSysCache(exttup); ++ } + break; + } + /* Database's context for global assertion */ -+ sid.relid = DatabaseRelationId; + exttup = SearchSysCache(DATABASEOID, + ObjectIdGetDatum(MyDatabaseId), + 0, 0, 0); ++ if (HeapTupleIsValid(exttup)) ++ { ++ sid = sepgsqlGetTupleSecid(DatabaseRelationId, ++ exttup, tclass); ++ ReleaseSysCache(exttup); ++ } ++ break; ++ ++ case DatabaseRelationId: ++ sid.secid = HeapTupleGetSecid(tuple); ++ if (tclass) ++ *tclass = SEPG_CLASS_DB_DATABASE; + break; + + case DescriptionRelationId: + /* recursive call */ + extid = ((Form_pg_description) GETSTRUCT(tuple))->objoid; + extcls = ((Form_pg_description) GETSTRUCT(tuple))->classoid; -+ return sepgsqlGetSysobjContext(extcls, extid, 0, tclass); ++ return sepgsqlGetSysobjSecid(extcls, extid, 0, tclass); + + case EnumRelationId: -+ sid.relid = TypeRelationId; + extid = ((Form_pg_enum) GETSTRUCT(tuple))->enumtypid; + exttup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(extid), + 0, 0, 0); ++ if (HeapTupleIsValid(exttup)) ++ { ++ sid = sepgsqlGetTupleSecid(TypeRelationId, ++ exttup, tclass); ++ ReleaseSysCache(exttup); ++ } + break; + + case IndexRelationId: -+ sid.relid = RelationRelationId; -+ extid = ((Form_pg_index) GETSTRUCT(tuple))->indexrelid; ++ extid = ((Form_pg_index) GETSTRUCT(tuple))->indrelid; + exttup = SearchSysCache(RELOID, + ObjectIdGetDatum(extid), + 0, 0, 0); ++ if (HeapTupleIsValid(exttup)) ++ { ++ sid = sepgsqlGetTupleSecid(RelationRelationId, ++ exttup, tclass); ++ ReleaseSysCache(exttup); ++ } + break; + + case InheritsRelationId: -+ sid.relid = RelationRelationId; + extid = ((Form_pg_inherits) GETSTRUCT(tuple))->inhrelid; + exttup = SearchSysCache(RELOID, + ObjectIdGetDatum(extid), + 0, 0, 0); ++ if (HeapTupleIsValid(exttup)) ++ { ++ sid = sepgsqlGetTupleSecid(RelationRelationId, ++ exttup, tclass); ++ ReleaseSysCache(exttup); ++ } ++ break; ++ ++ case LargeObjectRelationId: ++ sid.secid = HeapTupleGetSecid(tuple); ++ if (tclass) ++ *tclass = SEPG_CLASS_DB_BLOB; ++ break; ++ ++ case NamespaceRelationId: ++ sid.secid = HeapTupleGetSecid(tuple); ++ if (tclass) ++ *tclass = SEPG_CLASS_DB_SCHEMA; ++ break; ++ ++ case ProcedureRelationId: ++ sid.secid = HeapTupleGetSecid(tuple); ++ if (tclass) ++ *tclass = SEPG_CLASS_DB_PROCEDURE; ++ break; ++ ++ case RelationRelationId: ++ sid.secid = HeapTupleGetSecid(tuple); ++ if (tclass) ++ { ++ char relkind = ((Form_pg_class) GETSTRUCT(tuple))->relkind; ++ ++ switch (relkind) ++ { ++ case RELKIND_RELATION: ++ *tclass = SEPG_CLASS_DB_TABLE; ++ break; ++ ++ case RELKIND_SEQUENCE: ++ *tclass = SEPG_CLASS_DB_SEQUENCE; ++ break; ++ ++ default: ++ *tclass = SEPG_CLASS_DB_TUPLE; ++ break; ++ } ++ } + break; + + case RewriteRelationId: -+ sid.relid = RelationRelationId; + extid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class; + exttup = SearchSysCache(RELOID, + ObjectIdGetDatum(extid), + 0, 0, 0); ++ if (HeapTupleIsValid(exttup)) ++ { ++ sid = sepgsqlGetTupleSecid(RelationRelationId, ++ exttup, tclass); ++ ReleaseSysCache(exttup); ++ } + break; + + case SharedDescriptionRelationId: + /* recursive invocation */ + extid = ((Form_pg_shdescription) GETSTRUCT(tuple))->objoid; + extcls = ((Form_pg_shdescription) GETSTRUCT(tuple))->classoid; -+ return sepgsqlGetSysobjContext(extcls, extid, 0, tclass); ++ return sepgsqlGetSysobjSecid(extcls, extid, 0, tclass); + + case StatisticRelationId: -+ sid.relid = AttributeRelationId; + extid = ((Form_pg_statistic) GETSTRUCT(tuple))->starelid; + extsub = ((Form_pg_statistic) GETSTRUCT(tuple))->staattnum; + exttup = SearchSysCache(ATTNUM, + ObjectIdGetDatum(extid), + Int16GetDatum(extsub), + 0, 0); ++ if (HeapTupleIsValid(exttup)) ++ { ++ sid = sepgsqlGetTupleSecid(AttributeRelationId, ++ exttup, tclass); ++ ReleaseSysCache(exttup); ++ } + break; + + case TriggerRelationId: -+ sid.relid = RelationRelationId; + extid = ((Form_pg_trigger) GETSTRUCT(tuple))->tgrelid; + exttup = SearchSysCache(RELOID, + ObjectIdGetDatum(extid), + 0, 0, 0); ++ if (HeapTupleIsValid(exttup)) ++ { ++ sid = sepgsqlGetTupleSecid(RelationRelationId, ++ exttup, tclass); ++ ReleaseSysCache(exttup); ++ } ++ break; ++ ++ case TSConfigMapRelationId: ++ extid = ((Form_pg_ts_config_map) GETSTRUCT(tuple))->mapcfg; ++ exttup = SearchSysCache(TSCONFIGOID, ++ ObjectIdGetDatum(extid), ++ 0, 0, 0); ++ if (HeapTupleIsValid(exttup)) ++ { ++ sid = sepgsqlGetTupleSecid(TSConfigRelationId, ++ exttup, tclass); ++ ReleaseSysCache(exttup); ++ } + break; + + default: -+ exttup = tuple; -+ sid.relid = tableOid; ++ /* No external lookups (normal case) */ ++ sid.secid = HeapTupleGetSecid(tuple); + break; + } + -+ if (HeapTupleIsValid(exttup)) -+ { -+ sid.secid = HeapTupleGetSecid(exttup); -+ -+ if (tclass) -+ *tclass = sepgsqlTupleObjectClass(sid.relid, exttup); -+ -+ if (exttup != tuple) -+ ReleaseSysCache(exttup); -+ } + return sid; + } + @@ -11014,7 +14076,7 @@ diff -Nrpc base/src/backend/security/sepgsql/label.c sepgsql/src/backend/securit + { + sepgsql_sid_t sid; + -+ sid = sepgsqlGetTupleContext(relid, tuple, NULL); ++ sid = sepgsqlGetTupleSecid(relid, tuple, NULL); + + return securityTransSecLabelOut(sid.relid, sid.secid); + } @@ -11330,10 +14392,10 @@ diff -Nrpc base/src/backend/security/sepgsql/misc.c sepgsql/src/backend/security + } diff -Nrpc base/src/backend/security/sepgsql/perms.c sepgsql/src/backend/security/sepgsql/perms.c *** base/src/backend/security/sepgsql/perms.c Thu Jan 1 09:00:00 1970 ---- sepgsql/src/backend/security/sepgsql/perms.c Sun Sep 6 19:31:39 2009 +--- sepgsql/src/backend/security/sepgsql/perms.c Mon Sep 28 09:29:32 2009 *************** *** 0 **** ---- 1,464 ---- +--- 1,597 ---- + /* + * src/backend/utils/sepgsql/perms.c + * SE-PostgreSQL permission checks @@ -11381,6 +14443,8 @@ diff -Nrpc base/src/backend/security/sepgsql/perms.c sepgsql/src/backend/securit + { + {"read", SEPG_FILE__READ }, + {"write", SEPG_FILE__WRITE }, ++ {"create", SEPG_FILE__CREATE }, ++ {"getattr", SEPG_FILE__GETATTR }, + {NULL, 0} + } + }, @@ -11389,6 +14453,8 @@ diff -Nrpc base/src/backend/security/sepgsql/perms.c sepgsql/src/backend/securit + { + {"read", SEPG_DIR__READ }, + {"write", SEPG_DIR__WRITE }, ++ {"create", SEPG_DIR__CREATE }, ++ {"getattr", SEPG_DIR__GETATTR }, + {NULL,0} + } + }, @@ -11397,6 +14463,8 @@ diff -Nrpc base/src/backend/security/sepgsql/perms.c sepgsql/src/backend/securit + { + {"read", SEPG_LNK_FILE__READ }, + {"write", SEPG_LNK_FILE__WRITE }, ++ {"create", SEPG_LNK_FILE__CREATE }, ++ {"getattr", SEPG_LNK_FILE__GETATTR }, + {NULL,0} + } + }, @@ -11405,6 +14473,8 @@ diff -Nrpc base/src/backend/security/sepgsql/perms.c sepgsql/src/backend/securit + { + {"read", SEPG_CHR_FILE__READ }, + {"write", SEPG_CHR_FILE__WRITE }, ++ {"create", SEPG_CHR_FILE__CREATE }, ++ {"getattr", SEPG_CHR_FILE__GETATTR }, + {NULL,0} + } + }, @@ -11413,6 +14483,8 @@ diff -Nrpc base/src/backend/security/sepgsql/perms.c sepgsql/src/backend/securit + { + {"read", SEPG_BLK_FILE__READ }, + {"write", SEPG_BLK_FILE__WRITE }, ++ {"create", SEPG_BLK_FILE__CREATE }, ++ {"getattr", SEPG_BLK_FILE__GETATTR }, + {NULL,0} + } + }, @@ -11421,6 +14493,8 @@ diff -Nrpc base/src/backend/security/sepgsql/perms.c sepgsql/src/backend/securit + { + {"read", SEPG_SOCK_FILE__READ }, + {"write", SEPG_SOCK_FILE__WRITE }, ++ {"create", SEPG_SOCK_FILE__CREATE }, ++ {"getattr", SEPG_SOCK_FILE__GETATTR }, + {NULL,0} + } + }, @@ -11429,6 +14503,8 @@ diff -Nrpc base/src/backend/security/sepgsql/perms.c sepgsql/src/backend/securit + { + {"read", SEPG_FIFO_FILE__READ }, + {"write", SEPG_FIFO_FILE__WRITE }, ++ {"create", SEPG_FIFO_FILE__CREATE }, ++ {"getattr", SEPG_FIFO_FILE__GETATTR }, + {NULL, 0UL } + } + }, @@ -11464,21 +14540,6 @@ diff -Nrpc base/src/backend/security/sepgsql/perms.c sepgsql/src/backend/securit + } + }, + { -+ "db_schema_temp", SEPG_CLASS_DB_SCHEMA_TEMP, -+ { -+ { "create", SEPG_DB_SCHEMA_TEMP__CREATE }, -+ { "drop", SEPG_DB_SCHEMA_TEMP__DROP}, -+ { "getattr", SEPG_DB_SCHEMA_TEMP__GETATTR }, -+ { "setattr", SEPG_DB_SCHEMA_TEMP__SETATTR }, -+ { "relabelfrom", SEPG_DB_SCHEMA_TEMP__RELABELFROM }, -+ { "relabelto", SEPG_DB_SCHEMA_TEMP__RELABELTO }, -+ { "search", SEPG_DB_SCHEMA_TEMP__SEARCH }, -+ { "add_name", SEPG_DB_SCHEMA_TEMP__ADD_NAME }, -+ { "remove_name", SEPG_DB_SCHEMA_TEMP__REMOVE_NAME }, -+ { NULL, 0UL }, -+ } -+ }, -+ { + "db_table", SEPG_CLASS_DB_TABLE, + { + { "create", SEPG_DB_TABLE__CREATE }, @@ -11579,7 +14640,7 @@ diff -Nrpc base/src/backend/security/sepgsql/perms.c sepgsql/src/backend/securit + * external code which is necessary to communicate in-kernel SELinux + */ + extern security_class_t -+ sepgsqlTransToExternalClass(security_class_t tclass) ++ sepgsqlTransToExternalClass(uint16 tclass) + { + Assert(tclass < SEPG_CLASS_MAX); + @@ -11666,52 +14727,7 @@ diff -Nrpc base/src/backend/security/sepgsql/perms.c sepgsql/src/backend/securit + return NULL; + } + -+ /* -+ * sepgsqlAuditName -+ * returns an identifier string to generate audit record for -+ * the given tuple. Please note that its results can indicate -+ * an address within the given tuple, so we should not refer -+ * the returned pointer after HeapTuple is released. -+ */ -+ const char * -+ sepgsqlAuditName(Oid relid, HeapTuple tuple) -+ { -+ static char buffer[NAMEDATALEN * 2 + 10]; -+ -+ switch (relid) -+ { -+ case DatabaseRelationId: -+ return NameStr(((Form_pg_database) GETSTRUCT(tuple))->datname); -+ -+ case NamespaceRelationId: -+ return NameStr(((Form_pg_namespace) GETSTRUCT(tuple))->nspname); -+ -+ case RelationRelationId: -+ return NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname); -+ -+ case AttributeRelationId: -+ if (!IsBootstrapProcessingMode()) -+ { -+ Form_pg_attribute attForm -+ = (Form_pg_attribute) GETSTRUCT(tuple); -+ char *relname -+ = get_rel_name(attForm->attrelid); -+ -+ if (relname) -+ { -+ snprintf(buffer, sizeof(buffer), "%s.%s", -+ relname, NameStr(attForm->attname)); -+ pfree(relname); -+ return buffer; -+ } -+ } -+ return NameStr(((Form_pg_attribute) GETSTRUCT(tuple))->attname); -+ -+ case ProcedureRelationId: -+ return NameStr(((Form_pg_proc) GETSTRUCT(tuple))->proname); -+ } -+ return NULL; -+ } ++ #if 0 + + /* + * sepgsqlFileObjectClass @@ -11719,7 +14735,7 @@ diff -Nrpc base/src/backend/security/sepgsql/perms.c sepgsql/src/backend/securit + * It returns proper object class of filesystem object already opened. + * It is necessary to check privileges voluntarily. + */ -+ security_class_t ++ uint16 + sepgsqlFileObjectClass(int fdesc) + { + struct stat stbuf; @@ -11750,10 +14766,9 @@ diff -Nrpc base/src/backend/security/sepgsql/perms.c sepgsql/src/backend/securit + * + * It returns correct object class of given tuple + */ -+ security_class_t ++ uint16 + sepgsqlTupleObjectClass(Oid relid, HeapTuple tuple) + { -+ Form_pg_namespace nspForm; + Form_pg_class clsForm; + Form_pg_attribute attForm; + @@ -11763,10 +14778,6 @@ diff -Nrpc base/src/backend/security/sepgsql/perms.c sepgsql/src/backend/securit + return SEPG_CLASS_DB_DATABASE; + + case NamespaceRelationId: -+ nspForm = (Form_pg_namespace) GETSTRUCT(tuple); -+ if (strncmp(NameStr(nspForm->nspname), "pg_temp_", 8) == 0 || -+ strncmp(NameStr(nspForm->nspname), "pg_toast_temp_", 14) == 0) -+ return SEPG_CLASS_DB_SCHEMA_TEMP; + return SEPG_CLASS_DB_SCHEMA; + + case RelationRelationId: @@ -11798,6 +14809,190 @@ diff -Nrpc base/src/backend/security/sepgsql/perms.c sepgsql/src/backend/securit + } + return SEPG_CLASS_DB_TUPLE; + } ++ ++ /* ++ * sepgsqlTupleNamespace ++ * ++ * It returns an OID of the namespace, if the given system object is ++ * deployed under a certain namespace. ++ */ ++ Oid ++ sepgsqlTupleNamespace(Oid relOid, HeapTuple tuple) ++ { ++ Oid nspOid; ++ ++ switch (relOid) ++ { ++ case RelationRelationId: ++ nspOid = ((Form_pg_class) GETSTRUCT(tuple))->relnamespace; ++ break; ++ ++ case ConstraintRelationId: ++ nspOid = ((Form_pg_constraint) GETSTRUCT(tuple))->connamespace; ++ break; ++ ++ case ConversionRelationId: ++ nspOid = ((Form_pg_conversion) GETSTRUCT(tuple))->connamespace; ++ break; ++ ++ case OperatorClassRelationId: ++ nspOid = ((Form_pg_opclass) GETSTRUCT(tuple))->opcnamespace; ++ break; ++ ++ case OperatorRelationId: ++ nspOid = ((Form_pg_operator) GETSTRUCT(tuple))->oprnamespace; ++ break; ++ ++ case OperatorFamilyRelationId: ++ nspOid = ((Form_pg_opfamily) GETSTRUCT(tuple))->opfnamespace; ++ break; ++ ++ case ProcedureRelationId: ++ nspOid = ((Form_pg_proc) GETSTRUCT(tuple))->pronamespace; ++ break; ++ ++ case TSConfigRelationId: ++ nspOid = ((Form_pg_ts_config) GETSTRUCT(tuple))->cfgnamespace; ++ break; ++ ++ case TSDictionaryRelationId: ++ nspOid = ((Form_pg_ts_dict) GETSTRUCT(tuple))->dictnamespace; ++ break; ++ ++ case TSParserRelationId: ++ nspOid = ((Form_pg_ts_parser) GETSTRUCT(tuple))->prsnamespace; ++ break; ++ ++ case TSTemplateRelationId: ++ nspOid = ((Form_pg_ts_template) GETSTRUCT(tuple))->tmplnamespace; ++ break; ++ ++ default: ++ /* no specific namespace */ ++ nspOid = InvalidOid; ++ break; ++ } ++ ++ return nspOid; ++ } ++ ++ /* ++ * sepgsqlTupleAuditName ++ * ++ * It returns an OID of the namespace, if the given system object is ++ * deployed under a certain namespace. ++ */ ++ void ++ sepgsqlTupleAuditName(Oid relid, HeapTuple tuple, char *auname_buf) ++ { ++ char *name; ++ Oid extid; ++ ++ switch (relid) ++ { ++ case AccessMethodRelationId: ++ name = NameStr(((Form_pg_am) GETSTRUCT(tuple))->amname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case AttributeRelationId: ++ name = NameStr(((Form_pg_attribute) GETSTRUCT(tuple))->attname); ++ extid = ((Form_pg_attribute) GETSTRUCT(tuple))->attrelid; ++ sprintf(audit_name, "%s.%s", name, extid); ++ return; ++ ++ case AuthIdRelationId: ++ name = NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case ConversionRelationId: ++ name = NameStr(((Form_pg_conversion) GETSTRUCT(tuple))->conname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case DatabaseRelationId: ++ name = NameStr(((Form_pg_database) GETSTRUCT(tuple))->datname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case ForeignDataWrapperRelationId: ++ name = NameStr(((Form_pg_foreign_data_wrapper) GETSTRUCT(tuple))->fdwname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case ForeignServerRelationId: ++ name = NameStr(((Form_pg_foreign_server) GETSTRUCT(tuple))->srvname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case LanguageRelationId: ++ name = NameStr(((Form_pg_language) GETSTRUCT(tuple))->lanname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case NamespaceRelationId: ++ name = NameStr(((Form_pg_namespace) GETSTRUCT(tuple))->nspname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case OperatorClassRelationId: ++ name = NameStr(((Form_pg_opclass) GETSTRUCT(tuple))->opcname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case OperatorRelationId: ++ name = NameStr(((Form_pg_operator) GETSTRUCT(tuple))->oprname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case OperatorFamilyRelationId: ++ name = NameStr(((Form_pg_opfamily) GETSTRUCT(tuple))->opfname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case ProcedureRelationId: ++ name = NameStr(((Form_pg_proc) GETSTRUCT(tuple))->proname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case RelationRelationId: ++ name = NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case TableSpaceRelationId: ++ name = NameStr(((Form_pg_tablespace) GETSTRUCT(tuple))->spcname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case TSConfigRelationId: ++ name = NameStr(((Form_pg_ts_config) GETSTRUCT(tuple))->cfgname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case TSDictionaryRelationId: ++ name = NameStr(((Form_pg_ts_dict) GETSTRUCT(tuple))->dictname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case TSParserRelationId: ++ name = NameStr(((Form_pg_ts_parser) GETSTRUCT(tuple))->prsname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ case TSTemplateRelationId: ++ name = NameStr(((Form_pg_templace) GETSTRUCT(tuple))->tmplname); ++ strncpy(auname_buf, name, NAMEDATALEN); ++ break; ++ ++ default: ++ /* no auditable name */ ++ auname_buf[0] = '\0'; ++ break; ++ } ++ } ++ #endif diff -Nrpc base/src/backend/security/sepgsql/policy/Makefile sepgsql/src/backend/security/sepgsql/policy/Makefile *** base/src/backend/security/sepgsql/policy/Makefile Thu Jan 1 09:00:00 1970 --- sepgsql/src/backend/security/sepgsql/policy/Makefile Wed Jul 15 19:35:52 2009 @@ -11852,11 +15047,11 @@ diff -Nrpc base/src/backend/security/sepgsql/policy/sepostgresql-devel.fc.templa + diff -Nrpc base/src/backend/security/sepgsql/policy/sepostgresql-devel.te sepgsql/src/backend/security/sepgsql/policy/sepostgresql-devel.te *** base/src/backend/security/sepgsql/policy/sepostgresql-devel.te Thu Jan 1 09:00:00 1970 ---- sepgsql/src/backend/security/sepgsql/policy/sepostgresql-devel.te Thu Sep 10 15:43:44 2009 +--- sepgsql/src/backend/security/sepgsql/policy/sepostgresql-devel.te Tue Dec 1 17:11:40 2009 *************** *** 0 **** ---- 1,121 ---- -+ policy_module(sepostgresql-devel, 3.28) +--- 1,123 ---- ++ policy_module(sepostgresql-devel, 3.29) + + gen_require(` + class db_database all_db_database_perms; @@ -11879,10 +15074,9 @@ diff -Nrpc base/src/backend/security/sepgsql/policy/sepostgresql-devel.te sepgsq + # for regression test + type bin_t; + type user_home_t; -+ type sepgsql_trusted_proc_t; ++ type sepgsql_trusted_proc_exec_t; + + attribute tmpfile; -+ attribute ptynode; + ') + + ################################# @@ -11897,7 +15091,10 @@ diff -Nrpc base/src/backend/security/sepgsql/policy/sepostgresql-devel.te sepgsq + + allow sepgsql_test_t tmpfile : dir search_dir_perms; + allow sepgsql_test_t tmpfile : file rw_file_perms; -+ allow sepgsql_test_t ptynode : chr_file rw_file_perms; ++ ++ optional_policy(` ++ term_write_all_terms(sepgsql_test_t) ++ ') + + optional_policy(` + gen_require(` @@ -11908,7 +15105,7 @@ diff -Nrpc base/src/backend/security/sepgsql/policy/sepostgresql-devel.te sepgsq + tunable_policy(`sepgsql_regression_test_mode',` + allow unconfined_t sepgsql_test_t : process transition; + ') -+ allow sepgsql_test_t unconfined_t : fifo_file read_file_perms; ++ unconfined_rw_pipes(sepgsql_test_t) + role unconfined_r types sepgsql_test_t; + role unconfined_r types sepgsql_trusted_proc_t; + ') @@ -12251,7 +15448,7 @@ diff -Nrpc base/src/backend/storage/large_object/inv_api.c sepgsql/src/backend/s + } diff -Nrpc base/src/backend/tcop/fastpath.c sepgsql/src/backend/tcop/fastpath.c *** base/src/backend/tcop/fastpath.c Sat Jan 3 13:01:35 2009 ---- sepgsql/src/backend/tcop/fastpath.c Mon Sep 7 00:55:45 2009 +--- sepgsql/src/backend/tcop/fastpath.c Thu Sep 17 17:04:16 2009 *************** *** 26,31 **** --- 26,32 ---- @@ -12268,13 +15465,13 @@ diff -Nrpc base/src/backend/tcop/fastpath.c sepgsql/src/backend/tcop/fastpath.c if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(fip->namespace)); -+ sepgsqlCheckSchemaSearch(fip->namespace, true); ++ sepgsql_schema_search(fip->namespace, true); aclresult = pg_proc_aclcheck(fid, GetUserId(), ACL_EXECUTE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(fid)); -+ sepgsqlCheckProcedureExecute(fid); ++ sepgsql_proc_execute(fid); /* * Prepare function call info block and insert arguments. @@ -12393,7 +15590,7 @@ diff -Nrpc base/src/backend/tcop/utility.c sepgsql/src/backend/tcop/utility.c break; diff -Nrpc base/src/backend/utils/adt/genfile.c sepgsql/src/backend/utils/adt/genfile.c *** base/src/backend/utils/adt/genfile.c Sat Jan 3 13:01:35 2009 ---- sepgsql/src/backend/utils/adt/genfile.c Wed Jul 15 19:48:58 2009 +--- sepgsql/src/backend/utils/adt/genfile.c Mon Sep 28 09:29:32 2009 *************** *** 24,29 **** --- 24,30 ---- @@ -12405,16 +15602,27 @@ diff -Nrpc base/src/backend/utils/adt/genfile.c sepgsql/src/backend/utils/adt/ge #include "utils/builtins.h" #include "utils/memutils.h" *************** pg_read_file(PG_FUNCTION_ARGS) -*** 105,110 **** ---- 106,114 ---- - errmsg("could not open file \"%s\" for reading: %m", - filename))); +*** 99,104 **** +--- 100,108 ---- + + filename = convert_and_check_filename(filename_t); + /* SELinux: check file:{read} permission */ -+ sepgsqlCheckFileRead(fileno(file), filename); ++ sepgsql_file_read(filename); + - if (fseeko(file, (off_t) seek_offset, - (seek_offset >= 0) ? SEEK_SET : SEEK_END) != 0) + if ((file = AllocateFile(filename, PG_BINARY_R)) == NULL) + ereport(ERROR, + (errcode_for_file_access(), +*************** pg_stat_file(PG_FUNCTION_ARGS) +*** 159,164 **** +--- 163,170 ---- + (errmsg("must be superuser to get file information")))); + + filename = convert_and_check_filename(filename_t); ++ /* SELinux: check file:{getattr} permission */ ++ sepgsql_file_stat(filename); + + if (stat(filename, &fst) < 0) ereport(ERROR, diff -Nrpc base/src/backend/utils/adt/ri_triggers.c sepgsql/src/backend/utils/adt/ri_triggers.c *** base/src/backend/utils/adt/ri_triggers.c Thu Jun 18 10:20:52 2009 @@ -12497,6 +15705,31 @@ diff -Nrpc base/src/backend/utils/adt/ri_triggers.c sepgsql/src/backend/utils/ad /* Restore UID */ SetUserIdAndContext(save_userid, save_secdefcxt); +diff -Nrpc base/src/backend/utils/adt/tid.c sepgsql/src/backend/utils/adt/tid.c +*** base/src/backend/utils/adt/tid.c Sat Jan 3 13:01:35 2009 +--- sepgsql/src/backend/utils/adt/tid.c Fri Sep 18 14:51:00 2009 +*************** currtid_byreloid(PG_FUNCTION_ARGS) +*** 347,352 **** +--- 347,354 ---- + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_CLASS, + RelationGetRelationName(rel)); ++ /* SELinux checks */ ++ sepgsql_relation_get_transaction_id(RelationGetRelid(rel)); + + if (rel->rd_rel->relkind == RELKIND_VIEW) + return currtid_for_view(rel, tid); +*************** currtid_byrelname(PG_FUNCTION_ARGS) +*** 377,382 **** +--- 379,386 ---- + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_CLASS, + RelationGetRelationName(rel)); ++ /* SELinux checks */ ++ sepgsql_relation_get_transaction_id(RelationGetRelid(rel)); + + if (rel->rd_rel->relkind == RELKIND_VIEW) + return currtid_for_view(rel, tid); diff -Nrpc base/src/backend/utils/adt/trigfuncs.c sepgsql/src/backend/utils/adt/trigfuncs.c *** base/src/backend/utils/adt/trigfuncs.c Thu Jun 18 10:20:52 2009 --- sepgsql/src/backend/utils/adt/trigfuncs.c Tue Sep 8 23:55:48 2009 @@ -12701,7 +15934,7 @@ diff -Nrpc base/src/backend/utils/cache/syscache.c sepgsql/src/backend/utils/cac --- 956,961 ---- diff -Nrpc base/src/backend/utils/fmgr/dfmgr.c sepgsql/src/backend/utils/fmgr/dfmgr.c *** base/src/backend/utils/fmgr/dfmgr.c Sun Sep 6 19:40:49 2009 ---- sepgsql/src/backend/utils/fmgr/dfmgr.c Sun Sep 6 19:53:10 2009 +--- sepgsql/src/backend/utils/fmgr/dfmgr.c Thu Sep 17 17:04:16 2009 *************** *** 23,28 **** --- 23,29 ---- @@ -12719,7 +15952,7 @@ diff -Nrpc base/src/backend/utils/fmgr/dfmgr.c sepgsql/src/backend/utils/fmgr/df fullname = expand_dynamic_library_name(filename); + /* SELinux checks db_database:{load_module} */ -+ sepgsqlCheckDatabaseLoadModule(fullname); ++ sepgsql_database_load_module(MyDatabaseId, fullname); + /* Load the shared library, unless we already did */ lib_handle = internal_load_library(fullname); @@ -12731,14 +15964,14 @@ diff -Nrpc base/src/backend/utils/fmgr/dfmgr.c sepgsql/src/backend/utils/fmgr/df fullname = expand_dynamic_library_name(filename); + /* SELinux checks db_database:{load_module} */ -+ sepgsqlCheckDatabaseLoadModule(fullname); ++ sepgsql_database_load_module(MyDatabaseId, fullname); + /* Unload the library if currently loaded */ internal_unload_library(fullname); diff -Nrpc base/src/backend/utils/fmgr/fmgr.c sepgsql/src/backend/utils/fmgr/fmgr.c *** base/src/backend/utils/fmgr/fmgr.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/utils/fmgr/fmgr.c Wed Jul 15 19:35:52 2009 +--- sepgsql/src/backend/utils/fmgr/fmgr.c Thu Sep 17 17:04:16 2009 *************** *** 24,29 **** --- 24,30 ---- @@ -12755,13 +15988,13 @@ diff -Nrpc base/src/backend/utils/fmgr/fmgr.c sepgsql/src/backend/utils/fmgr/fmg } finfo->fn_oid = functionId; -+ sepgsqlCheckProcedureEntrypoint(finfo, procedureTuple); ++ sepgsql_proc_entrypoint(finfo, procedureTuple); ReleaseSysCache(procedureTuple); } diff -Nrpc base/src/backend/utils/init/postinit.c sepgsql/src/backend/utils/init/postinit.c *** base/src/backend/utils/init/postinit.c Sun Sep 6 19:40:49 2009 ---- sepgsql/src/backend/utils/init/postinit.c Mon Sep 7 00:55:45 2009 +--- sepgsql/src/backend/utils/init/postinit.c Thu Sep 17 17:04:16 2009 *************** *** 32,37 **** --- 32,38 ---- @@ -12796,7 +16029,7 @@ diff -Nrpc base/src/backend/utils/init/postinit.c sepgsql/src/backend/utils/init errdetail("User does not have CONNECT privilege."))); + /* SELinux: db_database:{access} */ -+ sepgsqlCheckDatabaseAccess(MyDatabaseId); ++ sepgsql_database_access(MyDatabaseId); + /* * Check connection limit for this database. @@ -12863,7 +16096,7 @@ diff -Nrpc base/src/backend/utils/misc/guc.c sepgsql/src/backend/utils/misc/guc. { diff -Nrpc base/src/backend/utils/misc/postgresql.conf.sample sepgsql/src/backend/utils/misc/postgresql.conf.sample *** base/src/backend/utils/misc/postgresql.conf.sample Sun Sep 6 19:40:49 2009 ---- sepgsql/src/backend/utils/misc/postgresql.conf.sample Thu Sep 10 00:06:47 2009 +--- sepgsql/src/backend/utils/misc/postgresql.conf.sample Tue Dec 1 17:11:40 2009 *************** *** 51,57 **** @@ -12890,18 +16123,17 @@ diff -Nrpc base/src/backend/utils/misc/postgresql.conf.sample sepgsql/src/backen #------------------------------------------------------------------------------ # RESOURCE USAGE (except WAL) ---- 95,102 ---- +--- 95,101 ---- # 0 selects the system default #tcp_keepalives_count = 0 # TCP_KEEPCNT; # 0 selects the system default ! #sepostgresql = off # SE-PostgreSQL support -! sepostgresql = on #------------------------------------------------------------------------------ # RESOURCE USAGE (except WAL) diff -Nrpc base/src/backend/utils/misc/superuser.c sepgsql/src/backend/utils/misc/superuser.c *** base/src/backend/utils/misc/superuser.c Sat Jan 3 13:01:35 2009 ---- sepgsql/src/backend/utils/misc/superuser.c Wed Jul 15 19:35:52 2009 +--- sepgsql/src/backend/utils/misc/superuser.c Thu Sep 17 17:04:16 2009 *************** *** 21,26 **** --- 21,27 ---- @@ -12913,7 +16145,7 @@ diff -Nrpc base/src/backend/utils/misc/superuser.c sepgsql/src/backend/utils/mis #include "utils/syscache.h" #include "miscadmin.h" *************** superuser_arg(Oid roleid) -*** 60,70 **** +*** 60,66 **** /* Quick out for cache hit */ if (OidIsValid(last_roleid) && last_roleid == roleid) @@ -12921,11 +16153,7 @@ diff -Nrpc base/src/backend/utils/misc/superuser.c sepgsql/src/backend/utils/mis /* Special escape path in case you deleted all your users. */ if (!IsUnderPostmaster && roleid == BOOTSTRAP_SUPERUSERID) -! return true; - - /* OK, look up the information in pg_authid */ - rtup = SearchSysCache(AUTHOID, ---- 61,77 ---- +--- 61,70 ---- /* Quick out for cache hit */ if (OidIsValid(last_roleid) && last_roleid == roleid) @@ -12936,22 +16164,15 @@ diff -Nrpc base/src/backend/utils/misc/superuser.c sepgsql/src/backend/utils/mis /* Special escape path in case you deleted all your users. */ if (!IsUnderPostmaster && roleid == BOOTSTRAP_SUPERUSERID) -! { -! result = true; -! goto out; -! } - - /* OK, look up the information in pg_authid */ - rtup = SearchSysCache(AUTHOID, *************** superuser_arg(Oid roleid) *** 94,99 **** ---- 101,110 ---- +--- 98,107 ---- last_roleid = roleid; last_roleid_is_super = result; + out: + if (result) -+ result = sepgsqlCheckDatabaseSuperuser(); ++ result = sepgsql_database_superuser(MyDatabaseId); + return result; } @@ -14158,6 +17379,27 @@ diff -Nrpc base/src/include/access/tupdesc.h sepgsql/src/include/access/tupdesc. int tdrefcount; /* reference count, or -1 if not counting */ } *TupleDesc; +diff -Nrpc base/src/include/bootstrap/bootstrap.h sepgsql/src/include/bootstrap/bootstrap.h +*** base/src/include/bootstrap/bootstrap.h Sat Jan 3 12:25:21 2009 +--- sepgsql/src/include/bootstrap/bootstrap.h Tue Dec 8 14:04:25 2009 +*************** typedef enum +*** 70,76 **** + BootstrapProcess, + StartupProcess, + BgWriterProcess, +! WalWriterProcess + } AuxProcType; + + #endif /* BOOTSTRAP_H */ +--- 70,77 ---- + BootstrapProcess, + StartupProcess, + BgWriterProcess, +! WalWriterProcess, +! SelinuxReceiverProcess, + } AuxProcType; + + #endif /* BOOTSTRAP_H */ diff -Nrpc base/src/include/catalog/dependency.h sepgsql/src/include/catalog/dependency.h *** base/src/include/catalog/dependency.h Thu Jun 18 10:20:52 2009 --- sepgsql/src/include/catalog/dependency.h Thu Jul 16 17:22:29 2009 @@ -14294,6 +17536,26 @@ diff -Nrpc base/src/include/catalog/pg_attribute.h sepgsql/src/include/catalog/p /* ---------------- * pg_index +diff -Nrpc base/src/include/catalog/pg_conversion_fn.h sepgsql/src/include/catalog/pg_conversion_fn.h +*** base/src/include/catalog/pg_conversion_fn.h Thu Jun 18 10:20:52 2009 +--- sepgsql/src/include/catalog/pg_conversion_fn.h Thu Sep 17 22:10:19 2009 +*************** +*** 17,23 **** + extern Oid ConversionCreate(const char *conname, Oid connamespace, + Oid conowner, + int32 conforencoding, int32 contoencoding, +! Oid conproc, bool def); + extern void RemoveConversionById(Oid conversionOid); + extern Oid FindConversion(const char *conname, Oid connamespace); + extern Oid FindDefaultConversion(Oid connamespace, int32 for_encoding, int32 to_encoding); +--- 17,23 ---- + extern Oid ConversionCreate(const char *conname, Oid connamespace, + Oid conowner, + int32 conforencoding, int32 contoencoding, +! Oid conproc, Oid consecid, bool def); + extern void RemoveConversionById(Oid conversionOid); + extern Oid FindConversion(const char *conname, Oid connamespace); + extern Oid FindDefaultConversion(Oid connamespace, int32 for_encoding, int32 to_encoding); diff -Nrpc base/src/include/catalog/pg_namespace.h sepgsql/src/include/catalog/pg_namespace.h *** base/src/include/catalog/pg_namespace.h Sat Jan 3 12:25:21 2009 --- sepgsql/src/include/catalog/pg_namespace.h Wed Jul 15 19:35:52 2009 @@ -14833,10 +18095,10 @@ diff -Nrpc base/src/include/security/rowlevel.h sepgsql/src/include/security/row + #endif /* ROWLEVEL_H */ diff -Nrpc base/src/include/security/sepgsql.h sepgsql/src/include/security/sepgsql.h *** base/src/include/security/sepgsql.h Thu Jan 1 09:00:00 1970 ---- sepgsql/src/include/security/sepgsql.h Thu Sep 10 15:18:03 2009 +--- sepgsql/src/include/security/sepgsql.h Tue Dec 8 14:04:25 2009 *************** *** 0 **** ---- 1,534 ---- +--- 1,777 ---- + /* + * src/include/security/sepgsql.h + * Headers of SE-PostgreSQL @@ -14881,7 +18143,6 @@ diff -Nrpc base/src/include/security/sepgsql.h sepgsql/src/include/security/sepg + SEPG_CLASS_FIFO_FILE, + SEPG_CLASS_DB_DATABASE, + SEPG_CLASS_DB_SCHEMA, -+ SEPG_CLASS_DB_SCHEMA_TEMP, + SEPG_CLASS_DB_TABLE, + SEPG_CLASS_DB_SEQUENCE, + SEPG_CLASS_DB_PROCEDURE, @@ -14895,24 +18156,38 @@ diff -Nrpc base/src/include/security/sepgsql.h sepgsql/src/include/security/sepg + + #define SEPG_FILE__READ (1<<0) + #define SEPG_FILE__WRITE (1<<1) ++ #define SEPG_FILE__CREATE (1<<2) ++ #define SEPG_FILE__GETATTR (1<<3) + + #define SEPG_DIR__READ (SEPG_FILE__READ) + #define SEPG_DIR__WRITE (SEPG_FILE__WRITE) ++ #define SEPG_DIR__CREATE (SEPG_FILE__CREATE) ++ #define SEPG_DIR__GETATTR (SEPG_FILE__GETATTR) + + #define SEPG_LNK_FILE__READ (SEPG_FILE__READ) + #define SEPG_LNK_FILE__WRITE (SEPG_FILE__WRITE) ++ #define SEPG_LNK_FILE__CREATE (SEPG_FILE__CREATE) ++ #define SEPG_LNK_FILE__GETATTR (SEPG_FILE__GETATTR) + + #define SEPG_CHR_FILE__READ (SEPG_FILE__READ) + #define SEPG_CHR_FILE__WRITE (SEPG_FILE__WRITE) ++ #define SEPG_CHR_FILE__CREATE (SEPG_FILE__CREATE) ++ #define SEPG_CHR_FILE__GETATTR (SEPG_FILE__GETATTR) + + #define SEPG_BLK_FILE__READ (SEPG_FILE__READ) + #define SEPG_BLK_FILE__WRITE (SEPG_FILE__WRITE) ++ #define SEPG_BLK_FILE__CREATE (SEPG_FILE__CREATE) ++ #define SEPG_BLK_FILE__GETATTR (SEPG_FILE__GETATTR) + + #define SEPG_SOCK_FILE__READ (SEPG_FILE__READ) + #define SEPG_SOCK_FILE__WRITE (SEPG_FILE__WRITE) ++ #define SEPG_SOCK_FILE__CREATE (SEPG_FILE__CREATE) ++ #define SEPG_SOCK_FILE__GETATTR (SEPG_FILE__GETATTR) + + #define SEPG_FIFO_FILE__READ (SEPG_FILE__READ) + #define SEPG_FIFO_FILE__WRITE (SEPG_FILE__WRITE) ++ #define SEPG_FIFO_FILE__CREATE (SEPG_FILE__CREATE) ++ #define SEPG_FIFO_FILE__GETATTR (SEPG_FILE__GETATTR) + + #define SEPG_DB_DATABASE__CREATE (1<<0) + #define SEPG_DB_DATABASE__DROP (1<<1) @@ -14935,16 +18210,6 @@ diff -Nrpc base/src/include/security/sepgsql.h sepgsql/src/include/security/sepg + #define SEPG_DB_SCHEMA__ADD_NAME (1<<7) + #define SEPG_DB_SCHEMA__REMOVE_NAME (1<<8) + -+ #define SEPG_DB_SCHEMA_TEMP__CREATE (SEPG_DB_DATABASE__CREATE) -+ #define SEPG_DB_SCHEMA_TEMP__DROP (SEPG_DB_DATABASE__DROP) -+ #define SEPG_DB_SCHEMA_TEMP__GETATTR (SEPG_DB_DATABASE__GETATTR) -+ #define SEPG_DB_SCHEMA_TEMP__SETATTR (SEPG_DB_DATABASE__SETATTR) -+ #define SEPG_DB_SCHEMA_TEMP__RELABELFROM (SEPG_DB_DATABASE__RELABELFROM) -+ #define SEPG_DB_SCHEMA_TEMP__RELABELTO (SEPG_DB_DATABASE__RELABELTO) -+ #define SEPG_DB_SCHEMA_TEMP__SEARCH (SEPG_DB_SCHEMA__SEARCH) -+ #define SEPG_DB_SCHEMA_TEMP__ADD_NAME (SEPG_DB_SCHEMA__ADD_NAME) -+ #define SEPG_DB_SCHEMA_TEMP__REMOVE_NAME (SEPG_DB_SCHEMA__REMOVE_NAME) -+ + #define SEPG_DB_TABLE__CREATE (SEPG_DB_DATABASE__CREATE) + #define SEPG_DB_TABLE__DROP (SEPG_DB_DATABASE__DROP) + #define SEPG_DB_TABLE__GETATTR (SEPG_DB_DATABASE__GETATTR) @@ -15060,7 +18325,275 @@ diff -Nrpc base/src/include/security/sepgsql.h sepgsql/src/include/security/sepg + security_context_t tcontext, + uint16 tclass); + -+ extern pid_t sepgsqlStartupWorkerProcess(void); ++ extern void sepgsqlReceiverMain(void); ++ ++ /* ++ * bridge.c : new style security hooks ++ */ ++ ++ /* pg_attribute */ ++ extern Oid ++ sepgsql_attribute_create(Oid relOid, ColumnDef *cdef); ++ extern void ++ sepgsql_attribute_alter(Oid relOid, const char *attname); ++ extern void ++ sepgsql_attribute_drop(Oid relOid, AttrNumber attnum); ++ extern void ++ sepgsql_attribute_grant(Oid relOid, AttrNumber attnum); ++ extern Oid ++ sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum, DefElem *newLabel); ++ ++ /* pg_cast */ ++ extern Oid ++ sepgsql_cast_create(Oid sourceTypOid, Oid targetTypOid, Oid funcOid); ++ extern void ++ sepgsql_cast_drop(Oid castOid); ++ ++ /* pg_class */ ++ extern Oid * ++ sepgsql_relation_create(const char *relName, ++ char relkind, ++ TupleDesc tupDesc, ++ Oid nspOid, ++ DefElem *relLabel, ++ List *colList, ++ bool createAs, ++ bool permission); ++ extern Oid * ++ sepgsql_relation_copy(Relation src); ++ extern void ++ sepgsql_relation_alter(Oid relOid, const char *newName, Oid newNsp); ++ extern void ++ sepgsql_relation_drop(Oid relOid); ++ extern void ++ sepgsql_relation_grant(Oid relOid); ++ extern Oid ++ sepgsql_relation_relabel(Oid relOid, DefElem *newLabel); ++ extern void ++ sepgsql_relation_get_transaction_id(Oid relOid); ++ extern void ++ sepgsql_relation_copy_definition(Oid relOid); ++ extern void ++ sepgsql_relation_truncate(Relation rel); ++ extern void ++ sepgsql_relation_references(Relation rel, int16 *attnums, int natts); ++ extern void ++ sepgsql_relation_lock(Oid relOid); ++ extern void ++ sepgsql_view_replace(Oid viewOid); ++ extern void ++ sepgsql_index_create(Oid relOid, Oid nspOid, bool check_rights); ++ extern void ++ sepgsql_sequence_get_value(Oid seqOid); ++ extern void ++ sepgsql_sequence_next_value(Oid seqOid); ++ extern void ++ sepgsql_sequence_set_value(Oid seqOid); ++ ++ /* pg_conversion */ ++ extern Oid ++ sepgsql_conversion_create(const char *convName, Oid nspOid, Oid procOid); ++ extern void ++ sepgsql_conversion_alter(Oid convOid, const char *newName); ++ extern void ++ sepgsql_conversion_drop(Oid convOid); ++ ++ /* pg_database */ ++ extern Oid ++ sepgsql_database_create(const char *datName, DefElem *newLabel); ++ extern void ++ sepgsql_database_alter(Oid datOid); ++ extern void ++ sepgsql_database_drop(Oid datOid); ++ extern Oid ++ sepgsql_database_relabel(Oid datOid, DefElem *newLabel); ++ extern void ++ sepgsql_database_grant(Oid datOid); ++ extern void ++ sepgsql_database_access(Oid datOid); ++ extern bool ++ sepgsql_database_superuser(Oid datOid); ++ extern void ++ sepgsql_database_load_module(Oid datOid, const char *filename); ++ ++ /* pg_foreign_data_wrapper */ ++ extern Oid ++ sepgsql_fdw_create(const char *fdwName, Oid fdwValidator); ++ extern void ++ sepgsql_fdw_alter(Oid fdwOid, Oid newValidator); ++ extern void ++ sepgsql_fdw_drop(Oid fdwOid); ++ extern void ++ sepgsql_fdw_grant(Oid fdwOid); ++ ++ /* pg_foreign_server */ ++ extern Oid ++ sepgsql_foreign_server_create(const char *fsrvName); ++ extern void ++ sepgsql_foreign_server_alter(Oid fsrvOid); ++ extern void ++ sepgsql_foreign_server_drop(Oid fsrvOid); ++ extern void ++ sepgsql_foreign_server_grant(Oid fsrvOid); ++ ++ /* pg_language */ ++ extern Oid ++ sepgsql_language_create(const char *langName, Oid handlerOid, Oid validatorOid); ++ extern void ++ sepgsql_language_alter(Oid langOid); ++ extern void ++ sepgsql_language_drop(Oid langOid); ++ extern void ++ sepgsql_language_grant(Oid langOid); ++ ++ /* pg_largeobject */ ++ extern Oid ++ sepgsql_largeobject_create(Oid loid, DefElem *newLabel); ++ extern void ++ sepgsql_largeobject_alter(Oid loid, Oid newOwner); ++ extern void ++ sepgsql_largeobject_drop(Oid loid, bool dacSkip); ++ extern void ++ sepgsql_largeobject_read(Oid loid); ++ extern void ++ sepgsql_largeobject_write(Oid loid); ++ extern void ++ sepgsql_largeobject_export(Oid loid, const char *filename); ++ extern Oid ++ sepgsql_largeobject_import(Oid loid, const char *filename, DefElem *newLabel); ++ ++ /* pg_namespace */ ++ extern Oid ++ sepgsql_schema_create(const char *nspName, bool isTemp, DefElem *newLabel); ++ extern void ++ sepgsql_schema_alter(Oid nspOid); ++ extern void ++ sepgsql_schema_drop(Oid nspOid); ++ extern Oid ++ sepgsql_schema_relabel(Oid nspOid, DefElem *newLabel); ++ extern void ++ sepgsql_schema_grant(Oid nspOid); ++ extern bool ++ sepgsql_schema_search(Oid nspOid, bool abort); ++ ++ /* pg_opclass */ ++ extern Oid ++ sepgsql_opclass_create(const char *opcName, Oid nspOid); ++ extern void ++ sepgsql_opclass_alter(Oid opcOid, const char *newName); ++ extern void ++ sepgsql_opclass_drop(Oid opcOid); ++ ++ /* pg_opfamily */ ++ extern Oid ++ sepgsql_opfamily_create(const char *opfName, Oid nspOid); ++ extern void ++ sepgsql_opfamily_alter(Oid opfOid, const char *newName); ++ extern void ++ sepgsql_opfamily_drop(Oid opfOid); ++ extern void ++ sepgsql_opfamily_add_operator(Oid opfOid, Oid operOid); ++ extern void ++ sepgsql_opfamily_add_procedure(Oid opfOid, Oid procOid); ++ ++ /* pg_operator */ ++ extern Oid ++ sepgsql_operator_create(const char *oprName, Oid oprOid, Oid nspOid, ++ Oid codeFn, Oid restFn, Oid joinFn); ++ extern void ++ sepgsql_operator_alter(Oid oprOid); ++ extern void ++ sepgsql_operator_drop(Oid oprOid); ++ ++ /* pg_proc */ ++ extern Oid ++ sepgsql_proc_create(const char *procName, HeapTuple oldTup, ++ Oid nspOid, Oid langOid, DefElem *newLabel); ++ extern void ++ sepgsql_proc_alter(Oid procOid, const char *newName, Oid newNsp); ++ extern void ++ sepgsql_proc_drop(Oid procOid); ++ extern Oid ++ sepgsql_proc_relabel(Oid procOid, DefElem *newLabel); ++ extern void ++ sepgsql_proc_grant(Oid procOid); ++ extern void ++ sepgsql_proc_execute(Oid procOid); ++ extern bool ++ sepgsql_proc_hint_inlined(HeapTuple protup); ++ extern void ++ sepgsql_proc_entrypoint(FmgrInfo *flinfo, HeapTuple protup); ++ ++ /* pg_rewrite */ ++ extern void ++ sepgsql_rule_create(Oid relOid, const char *ruleName); ++ extern void ++ sepgsql_rule_drop(Oid relOid, const char *ruleName); ++ ++ /* pg_trigger */ ++ extern void ++ sepgsql_trigger_create(Oid relOid, const char *trigName, Oid procOid); ++ extern void ++ sepgsql_trigger_alter(Oid relOid, const char *trigName); ++ extern void ++ sepgsql_trigger_drop(Oid relOid, const char *trigName); ++ ++ /* pg_ts_config */ ++ extern Oid ++ sepgsql_ts_config_create(const char *cfgName, Oid nspOid); ++ extern void ++ sepgsql_ts_config_alter(Oid cfgOid, const char *newName); ++ extern void ++ sepgsql_ts_config_drop(Oid cfgOid); ++ ++ /* pg_ts_dict */ ++ extern Oid ++ sepgsql_ts_dict_create(const char *dictName, Oid nspOid); ++ extern void ++ sepgsql_ts_dict_alter(Oid dictOid, const char *newName); ++ extern void ++ sepgsql_ts_dict_drop(Oid dictOid); ++ ++ /* pg_ts_parser */ ++ extern Oid ++ sepgsql_ts_parser_create(const char *prsName, Oid nspOid, ++ Oid startFn, Oid tokenFn, Oid sendFn, ++ Oid headlineFn, Oid lextypeFn); ++ extern void ++ sepgsql_ts_parser_alter(Oid prsOid, const char *newName); ++ extern void ++ sepgsql_ts_parser_drop(Oid prsOid); ++ ++ /* pg_ts_templace */ ++ extern Oid ++ sepgsql_ts_template_create(const char *tmplName, Oid nspOid, ++ Oid initFn, Oid lexizeFn); ++ extern void ++ sepgsql_ts_template_alter(Oid tmplOid, const char *newName); ++ extern void ++ sepgsql_ts_template_drop(Oid tmplOid); ++ ++ /* pg_type */ ++ extern Oid ++ sepgsql_type_create(const char *typName, HeapTuple oldTup, Oid nspOid, ++ Oid inputProc, Oid outputProc, Oid recvProc, Oid sendProc, ++ Oid modinProc, Oid modoutProc, Oid analyzeProc); ++ extern void ++ sepgsql_type_alter(Oid typOid, const char *newName, Oid newNsp); ++ extern void ++ sepgsql_type_drop(Oid typOid); ++ ++ /* misc objects */ ++ extern void ++ sepgsql_sysobj_drop(const ObjectAddress *object); ++ ++ /* filesystem objects */ ++ void ++ sepgsql_file_stat(const char *filename); ++ void ++ sepgsql_file_read(const char *filename); ++ void ++ sepgsql_file_write(const char *filename); + + /* + * checker.c : check permission on given queries @@ -15107,83 +18640,6 @@ diff -Nrpc base/src/include/security/sepgsql.h sepgsql/src/include/security/sepg + /* + * hooks.c : routines to check certain permissions + */ -+ extern Oid -+ sepgsqlCheckDatabaseCreate(const char *datname, DefElem *newLabel); -+ extern void -+ sepgsqlCheckDatabaseDrop(Oid datOid); -+ extern void -+ sepgsqlCheckDatabaseSetattr(Oid datOid); -+ extern Oid -+ sepgsqlCheckDatabaseRelabel(Oid datOid, DefElem *newLlabel); -+ extern void -+ sepgsqlCheckDatabaseAccess(Oid datOid); -+ extern bool -+ sepgsqlCheckDatabaseSuperuser(void); -+ extern void -+ sepgsqlCheckDatabaseLoadModule(const char *filename); -+ -+ extern Oid -+ sepgsqlCheckSchemaCreate(const char *nspName, DefElem *new_label, bool isTemp); -+ extern void -+ sepgsqlCheckSchemaDrop(Oid nspOid); -+ extern void -+ sepgsqlCheckSchemaSetattr(Oid nspOid); -+ extern Oid -+ sepgsqlCheckSchemaRelabel(Oid nspOid, DefElem *new_label); -+ extern void -+ sepgsqlCheckSchemaAddName(Oid nspOid); -+ extern void -+ sepgsqlCheckSchemaRemoveName(Oid nspOid); -+ extern bool -+ sepgsqlCheckSchemaSearch(Oid nspOid, bool abort); -+ -+ extern void -+ sepgsqlCheckTableDrop(Oid table_oid); -+ extern void -+ sepgsqlCheckTableSetattr(Oid table_oid); -+ extern Oid -+ sepgsqlCheckTableRelabel(Oid table_oid, DefElem *new_label); -+ extern void -+ sepgsqlCheckTableLock(Oid table_oid); -+ extern void -+ sepgsqlCheckTableTruncate(Relation rel); -+ extern void -+ sepgsqlCheckTableReference(Relation rel, int16 *attnums, int natts); -+ -+ extern void -+ sepgsqlCheckSequenceGetValue(Oid seqOid); -+ extern void -+ sepgsqlCheckSequenceNextValue(Oid seqOid); -+ extern void -+ sepgsqlCheckSequenceSetValue(Oid seqOid); -+ -+ extern Oid -+ sepgsqlCheckColumnCreate(Oid relOid, const char *attname, DefElem *newLabel); -+ extern void -+ sepgsqlCheckColumnDrop(Oid relOid, AttrNumber attno); -+ extern void -+ sepgsqlCheckColumnSetattr(Oid relOid, AttrNumber attno); -+ extern Oid -+ sepgsqlCheckColumnRelabel(Oid relOid, AttrNumber attno, DefElem *newLabel); -+ -+ extern Oid -+ sepgsqlCheckProcedureCreate(const char *procName, Oid procOid, -+ Oid procNsp, Oid procLang, DefElem *newLabel); -+ extern void -+ sepgsqlCheckProcedureDrop(Oid procOid); -+ extern void -+ sepgsqlCheckProcedureSetattr(Oid procOid); -+ extern Oid -+ sepgsqlCheckProcedureRelabel(Oid procOid, DefElem *newLabel); -+ extern void -+ sepgsqlCheckProcedureExecute(Oid procOid); -+ extern void -+ sepgsqlCheckProcedureInstall(Oid procOid); -+ extern bool -+ sepgsqlHintProcedureInlined(HeapTuple protup); -+ extern void -+ sepgsqlCheckProcedureEntrypoint(FmgrInfo *flinfo, HeapTuple protup); -+ + extern void + sepgsqlCheckBlobCreate(Relation rel, HeapTuple lotup); + extern void @@ -15197,28 +18653,12 @@ diff -Nrpc base/src/include/security/sepgsql.h sepgsql/src/include/security/sepg + extern void + sepgsqlCheckBlobSetattr(HeapTuple tuple); + extern void -+ sepgsqlCheckBlobExport(LargeObjectDesc *lobj, -+ int fdesc, const char *filename); ++ sepgsqlCheckBlobExport(LargeObjectDesc *lobj, const char *filename); + extern void -+ sepgsqlCheckBlobImport(LargeObjectDesc *lobj, -+ int fdesc, const char *filename); ++ sepgsqlCheckBlobImport(LargeObjectDesc *lobj, const char *filename); + extern void + sepgsqlCheckBlobRelabel(HeapTuple oldtup, HeapTuple newtup); + -+ extern void -+ sepgsqlCheckFileRead(int fdesc, const char *filename); -+ extern void -+ sepgsqlCheckFileWrite(int fdesc, const char *filename); -+ -+ extern Oid -+ sepgsqlCheckSysobjCreate(Oid relid, const char *auditName); -+ extern void -+ sepgsqlCheckSysobjGetattr(Oid relid, Oid secid, const char *auditName); -+ extern void -+ sepgsqlCheckSysobjSetattr(Oid relid, Oid secid, const char *auditName); -+ extern void -+ sepgsqlCheckSysobjDrop(const ObjectAddress *object); -+ + /* + * label.c : security label management + */ @@ -15242,9 +18682,9 @@ diff -Nrpc base/src/include/security/sepgsql.h sepgsql/src/include/security/sepg + extern Oid *sepgsqlCopyTableColumns(Relation source); + + extern sepgsql_sid_t -+ sepgsqlGetTupleContext(Oid tableOid, HeapTuple tuple, uint16 *tclass); ++ sepgsqlGetTupleSecid(Oid tableOid, HeapTuple tuple, uint16 *tclass); + extern sepgsql_sid_t -+ sepgsqlGetSysobjContext(Oid tableOid, Oid objectId, int32 objsubId, uint16 *tclass); ++ sepgsqlGetSysobjSecid(Oid tableOid, Oid objectId, int32 objsubId, uint16 *tclass); + + extern char *sepgsqlTransSecLabelIn(char *seclabel); + extern char *sepgsqlTransSecLabelOut(char *seclabel); @@ -15255,13 +18695,11 @@ diff -Nrpc base/src/include/security/sepgsql.h sepgsql/src/include/security/sepg + /* + * perms.c : SELinux permission related stuff + */ -+ extern const char *sepgsqlAuditName(Oid relid, HeapTuple tuple); ++ extern uint16 sepgsqlFileObjectClass(int fdesc); + -+ extern security_class_t sepgsqlFileObjectClass(int fdesc); ++ extern uint16 sepgsqlTupleObjectClass(Oid relid, HeapTuple tuple); + -+ extern security_class_t sepgsqlTupleObjectClass(Oid relid, HeapTuple tuple); -+ -+ extern security_class_t sepgsqlTransToExternalClass(security_class_t tclass_in); ++ extern security_class_t sepgsqlTransToExternalClass(uint16 tclass_in); + + extern void sepgsqlTransToInternalPerms(security_class_t tclass_ex, + struct av_decision *avd); @@ -15272,7 +18710,6 @@ diff -Nrpc base/src/include/security/sepgsql.h sepgsql/src/include/security/sepg + + /* avc.c */ + #define sepgsqlShmemSize() (0) -+ #define sepgsqlStartupWorkerProcess() (0) + + /* checker.c */ + #define sepgsqlCheckRTEPerms(a) do {} while(0) @@ -15287,71 +18724,139 @@ diff -Nrpc base/src/include/security/sepgsql.h sepgsql/src/include/security/sepg + #define sepgsqlIsEnabled() (false) + #define sepgsqlInitialize() do {} while(0) + -+ /* hooks.c */ -+ #define sepgsqlCheckDatabaseCreate(a,b) (InvalidOid) -+ #define sepgsqlCheckDatabaseDrop(a) do {} while(0) -+ #define sepgsqlCheckDatabaseSetattr(a) do {} while(0) -+ #define sepgsqlCheckDatabaseRelabel(a,b) (InvalidOid) -+ #define sepgsqlCheckDatabaseAccess(a) (true) -+ #define sepgsqlCheckDatabaseSuperuser() (true) -+ #define sepgsqlCheckDatabaseLoadModule(a) do {} while(0) ++ /* bridge.c */ ++ #define sepgsql_attribute_create(a,b) (InvalidOid) ++ #define sepgsql_attribute_alter(a,b) do {} while(0) ++ #define sepgsql_attribute_drop(a,b) do {} while(0) ++ #define sepgsql_attribute_grant(a,b) do {} while(0) ++ #define sepgsql_attribute_relabel(a,b,c) (InvalidOid) + -+ #define sepgsqlCheckSchemaCreate(a,b,c) (InvalidOid) -+ #define sepgsqlCheckSchemaDrop(a) do {} while(0) -+ #define sepgsqlCheckSchemaSetattr(a) do {} while(0) -+ #define sepgsqlCheckSchemaRelabel(a,b) (InvalidOid) -+ #define sepgsqlCheckSchemaAddName(a) do {} while(0) -+ #define sepgsqlCheckSchemaRemoveName(a) do {} while(0) -+ #define sepgsqlCheckSchemaSearch(a,b) (true) ++ #define sepgsql_cast_create(a,b,c) (InvalidOid) ++ #define sepgsql_cast_drop(a) (InvalidOid) + -+ #define sepgsqlCheckTableDrop(a) do {} while(0) -+ #define sepgsqlCheckTableSetattr(a) do {} while(0) -+ #define sepgsqlCheckTableRelabel(a,b) (InvalidOid) -+ #define sepgsqlCheckTableLock(a) do {} while(0) -+ #define sepgsqlCheckTableTruncate(a) do {} while(0) -+ #define sepgsqlCheckTableReference(a,b,c) do {} while(0) ++ #define sepgsql_relation_create(a,b,c,d,e,f) (NULL) ++ #define sepgsql_relation_copy(a) (NULL) ++ #define sepgsql_relation_alter(a,b,c) do {} while(0) ++ #define sepgsql_relation_drop(a) do {} while(0) ++ #define sepgsql_relation_grant(a) do {} while(0) ++ #define sepgsql_relation_relabel(a,b) do {} while(0) ++ #define sepgsql_relation_get_transaction_id(a) do {} while(0) ++ #define sepgsql_relation_copy_definition(a) do {} while(0) ++ #define sepgsql_relation_truncate(a) do {} while(0) ++ #define sepgsql_relation_references(a,b,c) do {} while(0) ++ #define sepgsql_relation_lock(a) do {} while(0) ++ #define sepgsql_view_replace(a) do {} while(0) ++ #define sepgsql_index_create(a,b,c) do {} while(0) ++ #define sepgsql_sequence_get_value(a) do {} while(0) ++ #define sepgsql_sequence_next_value(a) do {} while(0) ++ #define sepgsql_sequence_set_value(a) do {} while(0) + -+ #define sepgsqlCheckSequenceGetValue(a) do {} while(0) -+ #define sepgsqlCheckSequenceNextValue(a) do {} while(0) -+ #define sepgsqlCheckSequenceSetValue(a) do {} while(0) ++ #define sepgsql_conversion_create(a,b,c) do {} while(0) ++ #define sepgsql_conversion_alter(a,b) do {} while(0) ++ #define sepgsql_conversion_drop(a) do {} while(0) + -+ #define sepgsqlCheckColumnCreate(a,b,c) (InvalidOid) -+ #define sepgsqlCheckColumnDrop(a,b) do {} while(0) -+ #define sepgsqlCheckColumnSetattr(a,b) do {} while(0) -+ #define sepgsqlCheckColumnRelabel(a,b,c) (InvalidOid) ++ #define sepgsql_database_create(a,b) (InvalidOid) ++ #define sepgsql_database_alter(a) do {} while(0) ++ #define sepgsql_database_drop(a) do {} while(0) ++ #define sepgsql_database_relabel(a,b) (InvalidOid) ++ #define sepgsql_database_grant(a) do {} while(0) ++ #define sepgsql_database_access(a) do {} while(0) ++ #define sepgsql_database_superuser(a) (true) ++ #define sepgsql_database_load_module(a,b) do {} while(0) + -+ #define sepgsqlCheckProcedureCreate(a,b,c,d) (InvalidOid) -+ #define sepgsqlCheckProcedureDrop(a) do {} while(0) -+ #define sepgsqlCheckProcedureSetattr(a) do {} while(0) -+ #define sepgsqlCheckProcedureRelabel(a,b) (InvalidOid) -+ #define sepgsqlCheckProcedureExecute(a) (true) -+ #define sepgsqlCheckProcedureInstall(a) do {} while(0) -+ #define sepgsqlHintProcedureInlined(a) (true) -+ #define sepgsqlCheckProcedureEntrypoint(a,b) do {} while(0) ++ #define sepgsql_fdw_create(a,b) (InvalidOid) ++ #define sepgsql_fdw_alter(a,b) do {} while(0) ++ #define sepgsql_fdw_drop(a) do {} while(0) ++ #define sepgsql_fdw_grant(a) do {} while(0) + -+ #define sepgsqlCheckBlobCreate(a,b) do {} while(0) -+ #define sepgsqlCheckBlobDrop(a,b) do {} while(0) -+ #define sepgsqlCheckBlobRead(a) do {} while(0) -+ #define sepgsqlCheckBlobWrite(a) do {} while(0) -+ #define sepgsqlCheckBlobGetattr(a) do {} while(0) -+ #define sepgsqlCheckBlobSetattr(a) do {} while(0) -+ #define sepgsqlCheckBlobExport(a,b,c) do {} while(0) -+ #define sepgsqlCheckBlobImport(a,b,c) do {} while(0) -+ #define sepgsqlCheckBlobRelabel(a,b) do {} while(0) -+ #define sepgsqlCheckFileRead(a,b) do {} while(0) -+ #define sepgsqlCheckFileWrite(a,b) do {} while(0) ++ #define sepgsql_foreign_server_create(a) (InvalidOid) ++ #define sepgsql_foreign_server_alter(a) do {} while(0) ++ #define sepgsql_foreign_server_drop(a) do {} while(0) ++ #define sepgsql_foreign_server_grant(a) do {} while(0) + -+ #define sepgsqlCheckSysobjCreate(a,b) (InvalidOid) -+ #define sepgsqlCheckSysobjGetattr(a,b,c) do {} while(0) -+ #define sepgsqlCheckSysobjSetattr(a,b,c) do {} while(0) -+ #define sepgsqlCheckSysobjDrop(a) do {} while(0) ++ #define sepgsql_language_create(a,b,c) (InvalidOid) ++ #define sepgsql_language_alter(a) do {} while(0) ++ #define sepgsql_language_drop(a) do {} while(0) ++ #define sepgsql_language_grant(a) do {} while(0) ++ ++ #define sepgsql_largeobject_create(a,b) (InvalidOid) ++ #define sepgsql_largeobject_alter(a,b) do {} while(0) ++ #define sepgsql_largeobject_drop(a) do {} while(0) ++ #define sepgsql_largeobject_read(a) do {} while(0) ++ #define sepgsql_largeobject_write(a) do {} while(0) ++ #define sepgsql_largeobject_export(a,b) do {} while(0) ++ #define sepgsql_largeobject_import(a,b) (InvalidOid) ++ ++ #define sepgsql_schema_create(a,b,c) (InvalidOid) ++ #define sepgsql_schema_alter(a) do {} while(0) ++ #define sepgsql_schema_drop(a) do {} while(0) ++ #define sepgsql_schema_relabel(a,b) (InvalidOid) ++ #define sepgsql_schema_grant(a) do {} while(0) ++ #define sepgsql_schema_search(a,b) (true) ++ ++ #define sepgsql_opclass_create(a,b) (InvalidOid) ++ #define sepgsql_opclass_alter(a,b) do {} while(0) ++ #define sepgsql_opclass_drop(a) do {} while(0) ++ ++ #define sepgsql_opfamily_create(a,b) (InvalidOid) ++ #define sepgsql_opfamily_alter(a,b) do {} while(0) ++ #define sepgsql_opfamily_drop(a) do {} while(0) ++ #define sepgsql_opfamily_add_operator(a,b) do {} while(0) ++ #define sepgsql_opfamily_add_procedure(a,b) do {} while(0) ++ ++ #define sepgsql_operator_create(a,b,c,d,e,f) (InvalidOid) ++ #define sepgsql_operator_alter(a) do {} while(0) ++ #define sepgsql_operator_drop(a) do {} while(0) ++ ++ #define sepgsql_proc_create(a,b,c,d,e) (InvalidOid) ++ #define sepgsql_proc_alter(a,b,c) do {} while(0) ++ #define sepgsql_proc_drop(a) do {} while(0) ++ #define sepgsql_proc_relabel(a,b) (InvalidOid) ++ #define sepgsql_proc_grant(a) do {} while(0) ++ #define sepgsql_proc_execute(a) do {} while(0) ++ #define sepgsql_proc_hint_inlined(a) (true) ++ #define sepgsql_proc_entrypoint(a,b) do {} while(0) ++ ++ #define sepgsql_rule_create(a,b) do {} while(0) ++ #define sepgsql_rule_drop(a,b) do {} while(0) ++ ++ #define sepgsql_trigger_create(a,b,c) do {} while(0) ++ #define sepgsql_trigger_alter(a,b) do {} while(0) ++ #define sepgsql_trigger_drop(a,b) do {} while(0) ++ ++ #define sepgsql_ts_config_create(a,b) (InvalidOid) ++ #define sepgsql_ts_config_alter(a,b) do {} while(0) ++ #define sepgsql_ts_config_drop(a) do {} while(0) ++ ++ #define sepgsql_ts_config_create(a,b) (InvalidOid) ++ #define sepgsql_ts_config_alter(a,b) do {} while(0) ++ #define sepgsql_ts_config_drop(a) do {} while(0) ++ ++ #define sepgsql_ts_dict_create(a,b) (InvalidOid) ++ #define sepgsql_ts_dict_alter(a,b) do {} while(0) ++ #define sepgsql_ts_dict_drop(a) do {} while(0) ++ ++ #define sepgsql_ts_parser_create(a,b,c,d,e,f,g) (InvalidOid) ++ #define sepgsql_ts_parser_alter(a,b) do {} while(0) ++ #define sepgsql_ts_parser_drop(a) do {} while(0) ++ ++ #define sepgsql_ts_template_create(a,b,c,d) (InvalidOid) ++ #define sepgsql_ts_template_alter(a,b) do {} while(0) ++ #define sepgsql_ts_template_drop(a) do {} while(0) ++ ++ #define sepgsql_type_create(a,b,c,d,e,f,g,h,i,j) (InvalidOid) ++ #define sepgsql_type_alter(a,b,c) do {} while(0) ++ #define sepgsql_type_drop(a) do {} while(0) ++ ++ #define sepgsql_sysobj_drop(a) do {} while(0) ++ ++ #define sepgsql_file_stat(a) do {} while(0) ++ #define sepgsql_file_read(a) do {} while(0) ++ #define sepgsql_file_write(a) do {} while(0) + + /* label.c */ + #define sepgsqlTupleDescHasSecLabel(a,b) (false) + #define sepgsqlSetDefaultSecLabel(a,b) do {} while(0) -+ #define sepgsqlCreateTableColumns(a,b,c,d,e) (NULL) -+ #define sepgsqlCopyTableColumns(a) (NULL) -+ #define sepgsqlMetaSecurityLabel() (NULL) + #define sepgsqlTransSecLabelIn(a) (a) + #define sepgsqlTransSecLabelOut(a) (a) + #define sepgsqlRawSecLabelIn(a) (a) @@ -15420,6 +18925,30 @@ diff -Nrpc base/src/include/storage/lwlock.h sepgsql/src/include/storage/lwlock. /* Individual lock IDs end here */ FirstBufMappingLock, FirstLockMgrLock = FirstBufMappingLock + NUM_BUFFER_PARTITIONS, +diff -Nrpc base/src/include/storage/proc.h sepgsql/src/include/storage/proc.h +*** base/src/include/storage/proc.h Thu Feb 26 10:18:55 2009 +--- sepgsql/src/include/storage/proc.h Tue Dec 8 14:04:25 2009 +*************** typedef struct PROC_HDR +*** 143,150 **** + * normal operation. Startup process also consumes one slot, but WAL + * writer and autovacuum launcher are launched only after it has + * exited. + */ +! #define NUM_AUXILIARY_PROCS 3 + + + /* configurable options */ +--- 143,152 ---- + * normal operation. Startup process also consumes one slot, but WAL + * writer and autovacuum launcher are launched only after it has + * exited. ++ * In addition, a netlink receiver process may be launched, if SELinux ++ * support is enabled. + */ +! #define NUM_AUXILIARY_PROCS 4 + + + /* configurable options */ diff -Nrpc base/src/include/utils/errcodes.h sepgsql/src/include/utils/errcodes.h *** base/src/include/utils/errcodes.h Fri Mar 6 09:45:33 2009 --- sepgsql/src/include/utils/errcodes.h Wed Jul 15 19:35:52 2009 @@ -15451,6 +18980,41 @@ diff -Nrpc base/src/include/utils/syscache.h sepgsql/src/include/utils/syscache. STATRELATT, TSCONFIGMAP, TSCONFIGNAMENSP, +diff -Nrpc base/src/test/regress/GNUmakefile sepgsql/src/test/regress/GNUmakefile +*** base/src/test/regress/GNUmakefile Sat Jan 3 13:01:35 2009 +--- sepgsql/src/test/regress/GNUmakefile Tue Dec 1 17:11:40 2009 +*************** ifdef NO_LOCALE +*** 38,43 **** +--- 38,49 ---- + NOLOCALE += --no-locale + endif + ++ # SELinux support ++ ENABLE_SELINUX = ++ ifdef SELINUX ++ ENABLE_SELINUX += --enable-selinux ++ endif ++ + # stuff to pass into build of pg_regress + EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \ + '-DMAKEPROG="$(MAKE)"' \ +*************** tablespace-setup: +*** 138,144 **** + ## Run tests + ## + +! pg_regress_call = ./pg_regress --inputdir=$(srcdir) --dlpath=. --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE) + + check: all + $(pg_regress_call) --temp-install=./tmp_check --top-builddir=$(top_builddir) --schedule=$(srcdir)/parallel_schedule $(MAXCONNOPT) $(TEMP_CONF) +--- 144,150 ---- + ## Run tests + ## + +! pg_regress_call = ./pg_regress --inputdir=$(srcdir) --dlpath=. --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE) $(ENABLE_SELINUX) + + check: all + $(pg_regress_call) --temp-install=./tmp_check --top-builddir=$(top_builddir) --schedule=$(srcdir)/parallel_schedule $(MAXCONNOPT) $(TEMP_CONF) diff -Nrpc base/src/test/regress/expected/sanity_check.out sepgsql/src/test/regress/expected/sanity_check.out *** base/src/test/regress/expected/sanity_check.out Tue Feb 10 10:10:02 2009 --- sepgsql/src/test/regress/expected/sanity_check.out Thu Jul 16 23:18:11 2009 @@ -15481,3 +19045,72 @@ diff -Nrpc base/src/test/regress/expected/sanity_check.out sepgsql/src/test/regr -- -- another sanity check: every system catalog that has OIDs should have +diff -Nrpc base/src/test/regress/pg_regress.c sepgsql/src/test/regress/pg_regress.c +*** base/src/test/regress/pg_regress.c Thu Jun 18 10:20:52 2009 +--- sepgsql/src/test/regress/pg_regress.c Tue Dec 1 17:11:40 2009 +*************** static _stringlist *schedulelist = NULL; +*** 82,87 **** +--- 82,88 ---- + static _stringlist *extra_tests = NULL; + static char *temp_install = NULL; + static char *temp_config = NULL; ++ static bool enable_selinux = false; + static char *top_builddir = NULL; + static bool nolocale = false; + static char *hostname = NULL; +*************** help(void) +*** 1863,1868 **** +--- 1864,1870 ---- + printf(_(" --top-builddir=DIR (relative) path to top level build directory\n")); + printf(_(" --port=PORT start postmaster on PORT\n")); + printf(_(" --temp-config=PATH append contents of PATH to temporary config\n")); ++ printf(_(" --enable-selinux enables SELinux support, if available\n")); + printf(_("\n")); + printf(_("Options for using an existing installation:\n")); + printf(_(" --host=HOST use postmaster running on HOST\n")); +*************** regression_main(int argc, char *argv[], +*** 1907,1912 **** +--- 1909,1915 ---- + {"dlpath", required_argument, NULL, 17}, + {"create-role", required_argument, NULL, 18}, + {"temp-config", required_argument, NULL, 19}, ++ {"enable-selinux", optional_argument, NULL, 20}, + {NULL, 0, NULL, 0} + }; + +*************** regression_main(int argc, char *argv[], +*** 1997,2002 **** +--- 2000,2008 ---- + case 19: + temp_config = strdup(optarg); + break; ++ case 20: ++ enable_selinux = true; ++ break; + default: + /* getopt_long already emitted a complaint */ + fprintf(stderr, _("\nTry \"%s -h\" for more information.\n"), +*************** regression_main(int argc, char *argv[], +*** 2086,2095 **** + /* initdb */ + header(_("initializing database system")); + snprintf(buf, sizeof(buf), +! SYSTEMQUOTE "\"%s/initdb\" -D \"%s/data\" -L \"%s\" --noclean%s%s > \"%s/log/initdb.log\" 2>&1" SYSTEMQUOTE, + bindir, temp_install, datadir, + debug ? " --debug" : "", + nolocale ? " --no-locale" : "", + outputdir); + if (system(buf)) + { +--- 2092,2102 ---- + /* initdb */ + header(_("initializing database system")); + snprintf(buf, sizeof(buf), +! SYSTEMQUOTE "\"%s/initdb\" -D \"%s/data\" -L \"%s\" --noclean%s%s%s > \"%s/log/initdb.log\" 2>&1" SYSTEMQUOTE, + bindir, temp_install, datadir, + debug ? " --debug" : "", + nolocale ? " --no-locale" : "", ++ enable_selinux ? " --enable-selinux" : "", + outputdir); + if (system(buf)) + { diff --git a/sepostgresql.spec b/sepostgresql.spec index ba07df7..7955ef9 100644 --- a/sepostgresql.spec +++ b/sepostgresql.spec @@ -12,7 +12,7 @@ Summary: Security Enhanced PostgreSQL Name: sepostgresql Version: 8.4.1 -Release: 2306%{?dist} +Release: 2464%{?dist} License: BSD Group: Applications/Databases Url: http://code.google.com/p/sepgsql/ @@ -192,6 +192,10 @@ fi %attr(700,sepgsql,sepgsql) %dir %{_localstatedir}/lib/sepgsql/backups %changelog +* Fri Dec 8 2009 KaiGai Kohei - 8.4.1-2464 +- rework: backport features from v8.5devel tree +- fixbug: selinux netlink receiver process didn't have correct ps display + * Mon Nov 16 2009 KaiGai Kohei - 8.4.1-2306 - rebild for ppc/ppc64 libraries From 543ac036a2d61620e355e83cde9fc6495d9d5c12 Mon Sep 17 00:00:00 2001 From: KaiGai Kohei Date: Wed, 16 Dec 2009 13:38:53 +0000 Subject: [PATCH 5/8] upgrade base version 8.4.1->8.4.2 --- .cvsignore | 2 +- sepostgresql-8.4.patch | 493 +++++++++++++++++++++-------------------- sepostgresql.spec | 7 +- sources | 2 +- 4 files changed, 254 insertions(+), 250 deletions(-) diff --git a/.cvsignore b/.cvsignore index 19279bd..227e30f 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -postgresql-8.4.1.tar.bz2 +postgresql-8.4.2.tar.bz2 diff --git a/sepostgresql-8.4.patch b/sepostgresql-8.4.patch index b703db3..0a1331d 100644 --- a/sepostgresql-8.4.patch +++ b/sepostgresql-8.4.patch @@ -1,6 +1,6 @@ diff -Nrpc base/configure sepgsql/configure -*** base/configure Sun Sep 6 19:40:49 2009 ---- sepgsql/configure Sun Sep 6 19:53:10 2009 +*** base/configure Tue Dec 15 17:16:51 2009 +--- sepgsql/configure Tue Dec 15 17:30:25 2009 *************** with_libxml *** 710,715 **** --- 710,716 ---- @@ -189,8 +189,8 @@ diff -Nrpc base/configure sepgsql/configure elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 diff -Nrpc base/configure.in sepgsql/configure.in -*** base/configure.in Sun Sep 6 19:40:49 2009 ---- sepgsql/configure.in Sun Sep 6 19:53:10 2009 +*** base/configure.in Tue Dec 15 17:16:51 2009 +--- sepgsql/configure.in Tue Dec 15 17:30:25 2009 *************** PGAC_ARG_BOOL(with, zlib, yes, *** 764,769 **** --- 764,782 ---- @@ -227,8 +227,8 @@ diff -Nrpc base/src/Makefile.global.in sepgsql/src/Makefile.global.in enable_thread_safety = @enable_thread_safety@ diff -Nrpc base/src/backend/Makefile sepgsql/src/backend/Makefile -*** base/src/backend/Makefile Sat Jan 3 13:01:35 2009 ---- sepgsql/src/backend/Makefile Wed Jul 15 19:35:52 2009 +*** base/src/backend/Makefile Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/Makefile Tue Dec 15 17:30:25 2009 *************** include $(top_builddir)/src/Makefile.glo *** 16,22 **** @@ -247,8 +247,8 @@ diff -Nrpc base/src/backend/Makefile sepgsql/src/backend/Makefile include $(srcdir)/common.mk *************** LIBS := $(filter-out -lpgport, $(LIBS)) -*** 34,39 **** ---- 34,44 ---- +*** 40,45 **** +--- 40,50 ---- # The backend doesn't need everything that's in LIBS, however LIBS := $(filter-out -lz -lreadline -ledit -ltermcap -lncurses -lcurses, $(LIBS)) @@ -498,8 +498,8 @@ diff -Nrpc base/src/backend/access/heap/tuptoaster.c sepgsql/src/backend/access/ /* diff -Nrpc base/src/backend/access/transam/xact.c sepgsql/src/backend/access/transam/xact.c -*** base/src/backend/access/transam/xact.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/access/transam/xact.c Sun Sep 6 19:31:39 2009 +*** base/src/backend/access/transam/xact.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/access/transam/xact.c Tue Dec 15 17:30:25 2009 *************** *** 36,41 **** --- 36,43 ---- @@ -515,7 +515,7 @@ diff -Nrpc base/src/backend/access/transam/xact.c sepgsql/src/backend/access/tra *** 140,145 **** --- 142,148 ---- Oid prevUser; /* previous CurrentUserId setting */ - bool prevSecDefCxt; /* previous SecurityDefinerContext setting */ + int prevSecContext; /* previous SecurityRestrictionContext */ bool prevXactReadOnly; /* entry-time xact r/o state */ + int prevRowlv; /* previous Row-level control behavior */ struct TransactionStateData *parent; /* back link to parent */ @@ -525,7 +525,7 @@ diff -Nrpc base/src/backend/access/transam/xact.c sepgsql/src/backend/access/tra *** 168,173 **** --- 171,177 ---- InvalidOid, /* previous CurrentUserId setting */ - false, /* previous SecurityDefinerContext setting */ + 0, /* previous SecurityRestrictionContext */ false, /* entry-time xact r/o state */ + ROWLV_FILTER_MODE, /* previous Row-level control behavior */ NULL /* link to parent state block */ @@ -536,15 +536,15 @@ diff -Nrpc base/src/backend/access/transam/xact.c sepgsql/src/backend/access/tra --- 1528,1534 ---- s->nChildXids = 0; s->maxChildXids = 0; - GetUserIdAndContext(&s->prevUser, &s->prevSecDefCxt); + GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext); + s->prevRowlv = rowlvGetPerformingMode(); - /* SecurityDefinerContext should never be set outside a transaction */ - Assert(!s->prevSecDefCxt); + /* SecurityRestrictionContext should never be set outside a transaction */ + Assert(s->prevSecContext == 0); *************** AbortTransaction(void) -*** 2030,2035 **** ---- 2035,2050 ---- - SetUserIdAndContext(s->prevUser, s->prevSecDefCxt); +*** 2031,2036 **** +--- 2036,2051 ---- + SetUserIdAndSecContext(s->prevUser, s->prevSecContext); /* + * Reset behavior of row-level access controls @@ -561,9 +561,9 @@ diff -Nrpc base/src/backend/access/transam/xact.c sepgsql/src/backend/access/tra */ AfterTriggerEndXact(false); *************** AbortSubTransaction(void) -*** 3873,3878 **** ---- 3888,3903 ---- - SetUserIdAndContext(s->prevUser, s->prevSecDefCxt); +*** 3874,3879 **** +--- 3889,3904 ---- + SetUserIdAndSecContext(s->prevUser, s->prevSecContext); /* + * Reset behavior of row-level access controls @@ -580,10 +580,10 @@ diff -Nrpc base/src/backend/access/transam/xact.c sepgsql/src/backend/access/tra * ResourceOwner... */ *************** PushTransaction(void) -*** 4014,4019 **** ---- 4039,4045 ---- +*** 4015,4020 **** +--- 4040,4046 ---- s->blockState = TBLOCK_SUBBEGIN; - GetUserIdAndContext(&s->prevUser, &s->prevSecDefCxt); + GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext); s->prevXactReadOnly = XactReadOnly; + s->prevRowlv = rowlvGetPerformingMode(); @@ -920,8 +920,8 @@ diff -Nrpc base/src/backend/catalog/catalog.c sepgsql/src/backend/catalog/catalo relationId == PgShdescriptionToastIndex) return true; diff -Nrpc base/src/backend/catalog/dependency.c sepgsql/src/backend/catalog/dependency.c -*** base/src/backend/catalog/dependency.c Sun Sep 6 19:40:49 2009 ---- sepgsql/src/backend/catalog/dependency.c Thu Sep 17 23:44:07 2009 +*** base/src/backend/catalog/dependency.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/catalog/dependency.c Tue Dec 15 17:30:25 2009 *************** *** 63,68 **** --- 63,69 ---- @@ -1045,7 +1045,7 @@ diff -Nrpc base/src/backend/catalog/dependency.c sepgsql/src/backend/catalog/dep /* And clean up */ *************** reportDependentObjects(const ObjectAddre -*** 942,954 **** +*** 943,955 **** * depRel is the already-open pg_depend relation. */ static void @@ -1059,7 +1059,7 @@ diff -Nrpc base/src/backend/catalog/dependency.c sepgsql/src/backend/catalog/dep /* * First remove any pg_depend records that link from this object to * others. (Any records linking to this object should be gone already.) ---- 957,973 ---- +--- 958,974 ---- * depRel is the already-open pg_depend relation. */ static void @@ -1435,8 +1435,8 @@ diff -Nrpc base/src/backend/catalog/heap.c sepgsql/src/backend/catalog/heap.c diff -Nrpc base/src/backend/catalog/index.c sepgsql/src/backend/catalog/index.c -*** base/src/backend/catalog/index.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/catalog/index.c Fri Sep 18 17:02:48 2009 +*** base/src/backend/catalog/index.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/catalog/index.c Tue Dec 15 17:30:25 2009 *************** *** 48,53 **** --- 48,54 ---- @@ -1448,7 +1448,7 @@ diff -Nrpc base/src/backend/catalog/index.c sepgsql/src/backend/catalog/index.c #include "storage/lmgr.h" #include "storage/procarray.h" *************** AppendAttributeTuples(Relation indexRela -*** 351,357 **** +*** 352,358 **** Assert(indexTupDesc->attrs[i]->attnum == i + 1); Assert(indexTupDesc->attrs[i]->attcacheoff == -1); @@ -1456,7 +1456,7 @@ diff -Nrpc base/src/backend/catalog/index.c sepgsql/src/backend/catalog/index.c } CatalogCloseIndexes(indstate); ---- 352,359 ---- +--- 353,360 ---- Assert(indexTupDesc->attrs[i]->attnum == i + 1); Assert(indexTupDesc->attrs[i]->attcacheoff == -1); @@ -1466,7 +1466,7 @@ diff -Nrpc base/src/backend/catalog/index.c sepgsql/src/backend/catalog/index.c CatalogCloseIndexes(indstate); *************** index_create(Oid heapRelationId, -*** 652,658 **** +*** 653,659 **** */ InsertPgClassTuple(pg_class, indexRelation, RelationGetRelid(indexRelation), @@ -1474,7 +1474,7 @@ diff -Nrpc base/src/backend/catalog/index.c sepgsql/src/backend/catalog/index.c /* done with pg_class */ heap_close(pg_class, RowExclusiveLock); ---- 654,660 ---- +--- 655,661 ---- */ InsertPgClassTuple(pg_class, indexRelation, RelationGetRelid(indexRelation), @@ -1861,8 +1861,8 @@ diff -Nrpc base/src/backend/catalog/pg_operator.c sepgsql/src/backend/catalog/pg operatorObjectId = simple_heap_insert(pg_operator_desc, tup); } diff -Nrpc base/src/backend/catalog/pg_proc.c sepgsql/src/backend/catalog/pg_proc.c -*** base/src/backend/catalog/pg_proc.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/catalog/pg_proc.c Fri Sep 18 17:39:46 2009 +*** base/src/backend/catalog/pg_proc.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/catalog/pg_proc.c Tue Dec 15 17:30:25 2009 *************** *** 29,34 **** --- 29,35 ---- @@ -1892,8 +1892,8 @@ diff -Nrpc base/src/backend/catalog/pg_proc.c sepgsql/src/backend/catalog/pg_pro Oid retval; int parameterCount; *************** ProcedureCreate(const char *procedureNam -*** 96,101 **** ---- 98,104 ---- +*** 97,102 **** +--- 99,105 ---- Datum values[Natts_pg_proc]; bool replaces[Natts_pg_proc]; Oid relid; @@ -1902,8 +1902,8 @@ diff -Nrpc base/src/backend/catalog/pg_proc.c sepgsql/src/backend/catalog/pg_pro TupleDesc tupDesc; bool is_update; *************** ProcedureCreate(const char *procedureNam -*** 343,348 **** ---- 346,356 ---- +*** 344,349 **** +--- 347,357 ---- ObjectIdGetDatum(procNamespace), 0); @@ -1916,8 +1916,8 @@ diff -Nrpc base/src/backend/catalog/pg_proc.c sepgsql/src/backend/catalog/pg_pro { /* There is one; okay to replace it? */ *************** ProcedureCreate(const char *procedureNam -*** 477,482 **** ---- 485,492 ---- +*** 481,486 **** +--- 489,496 ---- /* Okay, do it... */ tup = heap_modify_tuple(oldtup, tupDesc, values, nulls, replaces); @@ -1927,8 +1927,8 @@ diff -Nrpc base/src/backend/catalog/pg_proc.c sepgsql/src/backend/catalog/pg_pro ReleaseSysCache(oldtup); *************** ProcedureCreate(const char *procedureNam -*** 486,491 **** ---- 496,503 ---- +*** 490,495 **** +--- 500,507 ---- { /* Creating a new procedure */ tup = heap_form_tuple(tupDesc, values, nulls); @@ -4690,8 +4690,8 @@ diff -Nrpc base/src/backend/commands/proclang.c sepgsql/src/backend/commands/pro memset(repl_repl, false, sizeof(repl_repl)); diff -Nrpc base/src/backend/commands/schemacmds.c sepgsql/src/backend/commands/schemacmds.c -*** base/src/backend/commands/schemacmds.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/commands/schemacmds.c Thu Sep 17 17:04:16 2009 +*** base/src/backend/commands/schemacmds.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/commands/schemacmds.c Tue Dec 15 17:30:25 2009 *************** *** 25,30 **** --- 25,31 ---- @@ -4709,7 +4709,7 @@ diff -Nrpc base/src/backend/commands/schemacmds.c sepgsql/src/backend/commands/s Oid owner_uid; Oid saved_uid; + Oid nspsecid; - bool saved_secdefcxt; + int save_sec_context; AclResult aclresult; *************** CreateSchemaCommand(CreateSchemaStmt *st @@ -4726,16 +4726,16 @@ diff -Nrpc base/src/backend/commands/schemacmds.c sepgsql/src/backend/commands/s if (!allowSystemTableMods && IsReservedName(schemaName)) ereport(ERROR, *************** CreateSchemaCommand(CreateSchemaStmt *st -*** 94,100 **** - SetUserIdAndContext(owner_uid, true); +*** 95,101 **** + save_sec_context | SECURITY_LOCAL_USERID_CHANGE); /* Create the schema's namespace */ ! namespaceId = NamespaceCreate(schemaName, owner_uid); /* Advance cmd counter to make the namespace visible */ CommandCounterIncrement(); ---- 100,106 ---- - SetUserIdAndContext(owner_uid, true); +--- 101,107 ---- + save_sec_context | SECURITY_LOCAL_USERID_CHANGE); /* Create the schema's namespace */ ! namespaceId = NamespaceCreate(schemaName, owner_uid, nspsecid); @@ -4743,7 +4743,7 @@ diff -Nrpc base/src/backend/commands/schemacmds.c sepgsql/src/backend/commands/s /* Advance cmd counter to make the namespace visible */ CommandCounterIncrement(); *************** RenameSchema(const char *oldname, const -*** 267,274 **** +*** 268,275 **** errmsg("schema \"%s\" does not exist", oldname))); /* make sure the new name doesn't exist */ @@ -4752,7 +4752,7 @@ diff -Nrpc base/src/backend/commands/schemacmds.c sepgsql/src/backend/commands/s CStringGetDatum(newname), 0, 0, 0))) ereport(ERROR, ---- 273,279 ---- +--- 274,280 ---- errmsg("schema \"%s\" does not exist", oldname))); /* make sure the new name doesn't exist */ @@ -4761,8 +4761,8 @@ diff -Nrpc base/src/backend/commands/schemacmds.c sepgsql/src/backend/commands/s 0, 0, 0))) ereport(ERROR, *************** RenameSchema(const char *oldname, const -*** 286,291 **** ---- 291,299 ---- +*** 287,292 **** +--- 292,300 ---- aclcheck_error(aclresult, ACL_KIND_DATABASE, get_database_name(MyDatabaseId)); @@ -4773,8 +4773,8 @@ diff -Nrpc base/src/backend/commands/schemacmds.c sepgsql/src/backend/commands/s ereport(ERROR, (errcode(ERRCODE_RESERVED_NAME), *************** AlterSchemaOwner_internal(HeapTuple tup, -*** 397,402 **** ---- 405,413 ---- +*** 398,403 **** +--- 406,414 ---- aclcheck_error(aclresult, ACL_KIND_DATABASE, get_database_name(MyDatabaseId)); @@ -4785,8 +4785,8 @@ diff -Nrpc base/src/backend/commands/schemacmds.c sepgsql/src/backend/commands/s memset(repl_repl, false, sizeof(repl_repl)); *************** AlterSchemaOwner_internal(HeapTuple tup, -*** 431,433 **** ---- 442,492 ---- +*** 432,434 **** +--- 443,493 ---- } } @@ -4921,8 +4921,8 @@ diff -Nrpc base/src/backend/commands/sequence.c sepgsql/src/backend/commands/seq seq = read_info(elm, seqrel, &buf); diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/tablecmds.c -*** base/src/backend/commands/tablecmds.c Sun Sep 6 19:40:49 2009 ---- sepgsql/src/backend/commands/tablecmds.c Thu Oct 8 09:29:32 2009 +*** base/src/backend/commands/tablecmds.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/commands/tablecmds.c Tue Dec 15 17:30:25 2009 *************** *** 62,67 **** --- 62,68 ---- @@ -4963,8 +4963,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta AttrNumber attnum; static char *validnsps[] = HEAP_RELOPT_NAMESPACES; *************** DefineRelation(CreateStmt *stmt, char re -*** 444,449 **** ---- 446,461 ---- +*** 454,459 **** +--- 456,471 ---- localHasOids = interpretOidsOption(stmt->options); descriptor->tdhasoid = (localHasOids || parentOidCount > 0); @@ -4982,7 +4982,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta * Find columns with default values and prepare for insertion of the * defaults. Pre-cooked (that is, inherited) defaults go into a list of *************** DefineRelation(CreateStmt *stmt, char re -*** 513,519 **** +*** 523,529 **** parentOidCount, stmt->oncommit, reloptions, @@ -4990,7 +4990,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta StoreCatalogInheritance(relationId, inheritOids); ---- 525,532 ---- +--- 535,542 ---- parentOidCount, stmt->oncommit, reloptions, @@ -5000,8 +5000,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta StoreCatalogInheritance(relationId, inheritOids); *************** ExecuteTruncate(TruncateStmt *stmt) -*** 887,892 **** ---- 900,907 ---- +*** 897,902 **** +--- 910,917 ---- if (!pg_class_ownercheck(seq_relid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, RelationGetRelationName(seq_rel)); @@ -5011,8 +5011,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta seq_relids = lappend_oid(seq_relids, seq_relid); *************** truncate_check_rel(Relation rel) -*** 1042,1047 **** ---- 1057,1065 ---- +*** 1052,1057 **** +--- 1067,1075 ---- errmsg("permission denied: \"%s\" is a system catalog", RelationGetRelationName(rel)))); @@ -5023,8 +5023,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta * We can never allow truncation of shared or nailed-in-cache relations, * because we can't support changing their relfilenode values. *************** MergeAttributes(List *schema, List *supe -*** 1216,1221 **** ---- 1234,1241 ---- +*** 1226,1231 **** +--- 1244,1251 ---- if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, RelationGetRelationName(relation)); @@ -5034,8 +5034,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* * Reject duplications in the list of parents. *************** renameatt(Oid myrelid, -*** 1921,1926 **** ---- 1941,1949 ---- +*** 1931,1936 **** +--- 1951,1959 ---- errmsg("cannot rename system column \"%s\"", oldattname))); @@ -5046,8 +5046,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta * if the attribute is inherited, forbid the renaming, unless we are * already inside a recursive rename. *************** RenameRelation(Oid myrelid, const char * -*** 2026,2031 **** ---- 2049,2057 ---- +*** 2036,2041 **** +--- 2059,2067 ---- Oid namespaceId; char relkind; @@ -5058,7 +5058,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta * Grab an exclusive lock on the target table, index, sequence or view, * which we will NOT release until end of transaction. *************** ATPrepCmd(List **wqueue, Relation rel, A -*** 2359,2372 **** +*** 2369,2382 **** switch (cmd->subtype) { case AT_AddColumn: /* ADD COLUMN */ @@ -5073,7 +5073,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* Performs own recursion */ ATPrepAddColumn(wqueue, rel, recurse, cmd); pass = AT_PASS_ADD_COL; ---- 2385,2398 ---- +--- 2395,2408 ---- switch (cmd->subtype) { case AT_AddColumn: /* ADD COLUMN */ @@ -5089,7 +5089,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta ATPrepAddColumn(wqueue, rel, recurse, cmd); pass = AT_PASS_ADD_COL; *************** ATPrepCmd(List **wqueue, Relation rel, A -*** 2379,2397 **** +*** 2389,2407 **** * substitutes default values into INSERTs before it expands * rules. */ @@ -5109,7 +5109,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta ATSimpleRecursion(wqueue, rel, cmd, recurse); /* No command-specific prep needed */ pass = AT_PASS_ADD_CONSTR; ---- 2405,2423 ---- +--- 2415,2433 ---- * substitutes default values into INSERTs before it expands * rules. */ @@ -5130,7 +5130,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* No command-specific prep needed */ pass = AT_PASS_ADD_CONSTR; *************** ATPrepCmd(List **wqueue, Relation rel, A -*** 2403,2415 **** +*** 2413,2425 **** pass = AT_PASS_COL_ATTRS; break; case AT_SetStorage: /* ALTER COLUMN STORAGE */ @@ -5144,7 +5144,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* Recursion occurs during execution phase */ /* No command-specific prep needed except saving recurse flag */ if (recurse) ---- 2429,2441 ---- +--- 2439,2451 ---- pass = AT_PASS_COL_ATTRS; break; case AT_SetStorage: /* ALTER COLUMN STORAGE */ @@ -5159,7 +5159,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* No command-specific prep needed except saving recurse flag */ if (recurse) *************** ATPrepCmd(List **wqueue, Relation rel, A -*** 2417,2429 **** +*** 2427,2439 **** pass = AT_PASS_DROP; break; case AT_AddIndex: /* ADD INDEX */ @@ -5173,7 +5173,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* Recursion occurs during execution phase */ /* No command-specific prep needed except saving recurse flag */ if (recurse) ---- 2443,2455 ---- +--- 2453,2465 ---- pass = AT_PASS_DROP; break; case AT_AddIndex: /* ADD INDEX */ @@ -5188,7 +5188,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* No command-specific prep needed except saving recurse flag */ if (recurse) *************** ATPrepCmd(List **wqueue, Relation rel, A -*** 2431,2437 **** +*** 2441,2447 **** pass = AT_PASS_ADD_CONSTR; break; case AT_DropConstraint: /* DROP CONSTRAINT */ @@ -5196,7 +5196,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* Recursion occurs during execution phase */ /* No command-specific prep needed except saving recurse flag */ if (recurse) ---- 2457,2463 ---- +--- 2467,2473 ---- pass = AT_PASS_ADD_CONSTR; break; case AT_DropConstraint: /* DROP CONSTRAINT */ @@ -5205,7 +5205,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* No command-specific prep needed except saving recurse flag */ if (recurse) *************** ATPrepCmd(List **wqueue, Relation rel, A -*** 2439,2445 **** +*** 2449,2455 **** pass = AT_PASS_DROP; break; case AT_AlterColumnType: /* ALTER COLUMN TYPE */ @@ -5213,7 +5213,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* Performs own recursion */ ATPrepAlterColumnType(wqueue, tab, rel, recurse, recursing, cmd); pass = AT_PASS_ALTER_TYPE; ---- 2465,2471 ---- +--- 2475,2481 ---- pass = AT_PASS_DROP; break; case AT_AlterColumnType: /* ALTER COLUMN TYPE */ @@ -5222,7 +5222,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta ATPrepAlterColumnType(wqueue, tab, rel, recurse, recursing, cmd); pass = AT_PASS_ALTER_TYPE; *************** ATPrepCmd(List **wqueue, Relation rel, A -*** 2451,2470 **** +*** 2461,2480 **** break; case AT_ClusterOn: /* CLUSTER ON */ case AT_DropCluster: /* SET WITHOUT CLUSTER */ @@ -5243,7 +5243,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* Performs own recursion */ if (rel->rd_rel->relhasoids) { ---- 2477,2496 ---- +--- 2487,2506 ---- break; case AT_ClusterOn: /* CLUSTER ON */ case AT_DropCluster: /* SET WITHOUT CLUSTER */ @@ -5265,7 +5265,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta if (rel->rd_rel->relhasoids) { *************** ATPrepCmd(List **wqueue, Relation rel, A -*** 2478,2491 **** +*** 2488,2501 **** pass = AT_PASS_DROP; break; case AT_SetTableSpace: /* SET TABLESPACE */ @@ -5280,7 +5280,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* This command never recurses */ /* No command-specific prep needed */ pass = AT_PASS_MISC; ---- 2504,2517 ---- +--- 2514,2527 ---- pass = AT_PASS_DROP; break; case AT_SetTableSpace: /* SET TABLESPACE */ @@ -5296,7 +5296,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* No command-specific prep needed */ pass = AT_PASS_MISC; *************** ATPrepCmd(List **wqueue, Relation rel, A -*** 2504,2510 **** +*** 2514,2520 **** case AT_DisableRule: case AT_AddInherit: /* INHERIT / NO INHERIT */ case AT_DropInherit: @@ -5304,7 +5304,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* These commands never recurse */ /* No command-specific prep needed */ pass = AT_PASS_MISC; ---- 2530,2536 ---- +--- 2540,2546 ---- case AT_DisableRule: case AT_AddInherit: /* INHERIT / NO INHERIT */ case AT_DropInherit: @@ -5313,7 +5313,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* No command-specific prep needed */ pass = AT_PASS_MISC; *************** ATRewriteTables(List **wqueue) -*** 2850,2857 **** +*** 2860,2867 **** /* * The new relation is local to our transaction and we know * nothing depends on it, so DROP_RESTRICT should be OK. @@ -5322,7 +5322,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* performDeletion does CommandCounterIncrement at end */ /* ---- 2876,2884 ---- +--- 2886,2894 ---- /* * The new relation is local to our transaction and we know * nothing depends on it, so DROP_RESTRICT should be OK. @@ -5333,8 +5333,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* *************** ATRewriteTable(AlteredTableInfo *tab, Oi -*** 3076,3086 **** ---- 3103,3116 ---- +*** 3086,3096 **** +--- 3113,3126 ---- if (newrel) { Oid tupOid = InvalidOid; @@ -5350,8 +5350,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* Set dropped attributes to null in new tuple */ foreach(lc, dropped_attrs) *************** ATRewriteTable(AlteredTableInfo *tab, Oi -*** 3112,3117 **** ---- 3142,3150 ---- +*** 3122,3127 **** +--- 3152,3160 ---- /* Preserve OID, if any */ if (newTupDesc->tdhasoid) HeapTupleSetOid(tuple, tupOid); @@ -5362,7 +5362,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* Now check any constraints on the possibly-changed tuple */ *************** ATGetQueueEntry(List **wqueue, Relation -*** 3213,3219 **** +*** 3223,3229 **** * - Ensure that it is not a system table */ static void @@ -5370,7 +5370,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta { if (rel->rd_rel->relkind != RELKIND_RELATION) { ---- 3246,3252 ---- +--- 3256,3262 ---- * - Ensure that it is not a system table */ static void @@ -5379,8 +5379,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta if (rel->rd_rel->relkind != RELKIND_RELATION) { *************** ATSimplePermissions(Relation rel, bool a -*** 3237,3242 **** ---- 3270,3281 ---- +*** 3247,3252 **** +--- 3280,3291 ---- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, RelationGetRelationName(rel)); @@ -5394,7 +5394,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), *************** ATSimplePermissions(Relation rel, bool a -*** 3252,3258 **** +*** 3262,3268 **** * - Ensure that it is not a system table */ static void @@ -5402,7 +5402,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta { if (rel->rd_rel->relkind != RELKIND_RELATION && rel->rd_rel->relkind != RELKIND_INDEX) ---- 3291,3297 ---- +--- 3301,3307 ---- * - Ensure that it is not a system table */ static void @@ -5411,8 +5411,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta if (rel->rd_rel->relkind != RELKIND_RELATION && rel->rd_rel->relkind != RELKIND_INDEX) *************** ATSimplePermissionsRelationOrIndex(Relat -*** 3266,3271 **** ---- 3305,3316 ---- +*** 3276,3281 **** +--- 3315,3326 ---- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, RelationGetRelationName(rel)); @@ -5426,8 +5426,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), *************** ATExecAddColumn(AlteredTableInfo *tab, R -*** 3509,3514 **** ---- 3554,3560 ---- +*** 3519,3524 **** +--- 3564,3570 ---- HeapTuple typeTuple; Oid typeOid; int32 typmod; @@ -5436,8 +5436,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta Expr *defval; *************** ATExecAddColumn(AlteredTableInfo *tab, R -*** 3546,3551 **** ---- 3592,3600 ---- +*** 3556,3561 **** +--- 3602,3610 ---- errmsg("child table \"%s\" has a conflicting \"%s\" column", RelationGetRelationName(rel), colDef->colname))); @@ -5448,8 +5448,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta childatt->attinhcount++; simple_heap_update(attrdesc, &tuple->t_self, tuple); *************** ATExecAddColumn(AlteredTableInfo *tab, R -*** 3585,3590 **** ---- 3634,3642 ---- +*** 3595,3600 **** +--- 3644,3652 ---- errmsg("column \"%s\" of relation \"%s\" already exists", colDef->colname, RelationGetRelationName(rel)))); @@ -5460,7 +5460,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta if (isOid) newattnum = ObjectIdAttributeNumber; *************** ATExecAddColumn(AlteredTableInfo *tab, R -*** 3627,3633 **** +*** 3637,3643 **** ReleaseSysCache(typeTuple); @@ -5468,7 +5468,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta heap_close(attrdesc, RowExclusiveLock); ---- 3679,3685 ---- +--- 3689,3695 ---- ReleaseSysCache(typeTuple); @@ -5477,8 +5477,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta heap_close(attrdesc, RowExclusiveLock); *************** ATPrepSetStatistics(Relation rel, const -*** 4016,4021 **** ---- 4068,4075 ---- +*** 4026,4031 **** +--- 4078,4085 ---- if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, RelationGetRelationName(rel)); @@ -5488,7 +5488,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta static void *************** ATExecDropColumn(List **wqueue, Relation -*** 4171,4177 **** +*** 4181,4187 **** /* At top level, permission check was done in ATPrepCmd, else do it */ if (recursing) @@ -5496,7 +5496,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* * get the number of the attribute ---- 4225,4231 ---- +--- 4235,4241 ---- /* At top level, permission check was done in ATPrepCmd, else do it */ if (recursing) @@ -5505,7 +5505,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* * get the number of the attribute *************** ATAddCheckConstraint(List **wqueue, Alte -*** 4473,4479 **** +*** 4483,4489 **** /* At top level, permission check was done in ATPrepCmd, else do it */ if (recursing) @@ -5513,7 +5513,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* * Call AddRelationNewConstraints to do the work, making sure it works on ---- 4527,4533 ---- +--- 4537,4543 ---- /* At top level, permission check was done in ATPrepCmd, else do it */ if (recursing) @@ -5522,7 +5522,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* * Call AddRelationNewConstraints to do the work, making sure it works on *************** checkFkeyPermissions(Relation rel, int16 -*** 5102,5108 **** +*** 5112,5118 **** aclresult = pg_class_aclcheck(RelationGetRelid(rel), roleid, ACL_REFERENCES); if (aclresult == ACLCHECK_OK) @@ -5530,7 +5530,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* Else we must have REFERENCES on each column */ for (i = 0; i < natts; i++) { ---- 5156,5162 ---- +--- 5166,5172 ---- aclresult = pg_class_aclcheck(RelationGetRelid(rel), roleid, ACL_REFERENCES); if (aclresult == ACLCHECK_OK) @@ -5539,8 +5539,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta for (i = 0; i < natts; i++) { *************** checkFkeyPermissions(Relation rel, int16 -*** 5112,5117 **** ---- 5166,5174 ---- +*** 5122,5127 **** +--- 5176,5184 ---- aclcheck_error(aclresult, ACL_KIND_CLASS, RelationGetRelationName(rel)); } @@ -5551,7 +5551,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* *************** ATExecDropConstraint(Relation rel, const -*** 5375,5381 **** +*** 5385,5391 **** /* At top level, permission check was done in ATPrepCmd, else do it */ if (recursing) @@ -5559,7 +5559,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta conrel = heap_open(ConstraintRelationId, RowExclusiveLock); ---- 5432,5438 ---- +--- 5442,5448 ---- /* At top level, permission check was done in ATPrepCmd, else do it */ if (recursing) @@ -5568,8 +5568,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta conrel = heap_open(ConstraintRelationId, RowExclusiveLock); *************** ATExecChangeOwner(Oid relationOid, Oid n -*** 6308,6313 **** ---- 6365,6372 ---- +*** 6318,6323 **** +--- 6375,6382 ---- aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(namespaceOid)); } @@ -5579,7 +5579,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta memset(repl_null, false, sizeof(repl_null)); *************** ATExecAddInherit(Relation child_rel, Ran -*** 6912,6918 **** +*** 6922,6928 **** * Must be owner of both parent and child -- child was checked by * ATSimplePermissions call in ATPrepCmd */ @@ -5587,7 +5587,7 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* Permanent rels cannot inherit from temporary ones */ if (parent_rel->rd_istemp && !child_rel->rd_istemp) ---- 6971,6977 ---- +--- 6981,6987 ---- * Must be owner of both parent and child -- child was checked by * ATSimplePermissions call in ATPrepCmd */ @@ -5596,8 +5596,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* Permanent rels cannot inherit from temporary ones */ if (parent_rel->rd_istemp && !child_rel->rd_istemp) *************** AlterTableNamespace(RangeVar *relation, -*** 7570,7575 **** ---- 7629,7637 ---- +*** 7580,7585 **** +--- 7639,7647 ---- RelationGetRelationName(rel), newschema))); @@ -5608,8 +5608,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid)) ereport(ERROR, *************** AlterSeqNamespaces(Relation classRel, Re -*** 7762,7767 **** ---- 7824,7957 ---- +*** 7772,7777 **** +--- 7834,7967 ---- relation_close(depRel, AccessShareLock); } @@ -5745,8 +5745,8 @@ diff -Nrpc base/src/backend/commands/tablecmds.c sepgsql/src/backend/commands/ta /* * This code supports diff -Nrpc base/src/backend/commands/trigger.c sepgsql/src/backend/commands/trigger.c -*** base/src/backend/commands/trigger.c Fri Jun 19 13:40:37 2009 ---- sepgsql/src/backend/commands/trigger.c Thu Sep 17 22:10:19 2009 +*** base/src/backend/commands/trigger.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/commands/trigger.c Tue Dec 15 17:30:25 2009 *************** *** 33,38 **** --- 33,39 ---- @@ -6187,8 +6187,8 @@ diff -Nrpc base/src/backend/executor/execJunk.c sepgsql/src/backend/executor/exe /* * Use the given slot, or make a new slot if we weren't given one. diff -Nrpc base/src/backend/executor/execMain.c sepgsql/src/backend/executor/execMain.c -*** base/src/backend/executor/execMain.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/executor/execMain.c Thu Oct 8 09:29:32 2009 +*** base/src/backend/executor/execMain.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/executor/execMain.c Tue Dec 15 17:30:25 2009 *************** *** 39,44 **** --- 39,45 ---- @@ -6487,8 +6487,8 @@ diff -Nrpc base/src/backend/executor/execMain.c sepgsql/src/backend/executor/exe Oid intoRelationId; TupleDesc tupdesc; *************** OpenIntoRel(QueryDesc *queryDesc) -*** 2871,2876 **** ---- 2982,2995 ---- +*** 2886,2891 **** +--- 2997,3010 ---- aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(namespaceId)); @@ -6504,7 +6504,7 @@ diff -Nrpc base/src/backend/executor/execMain.c sepgsql/src/backend/executor/exe * Select tablespace to use. If not specified, use default tablespace * (which may in turn default to database's default). *************** OpenIntoRel(QueryDesc *queryDesc) -*** 2929,2935 **** +*** 2944,2950 **** 0, into->onCommit, reloptions, @@ -6512,7 +6512,7 @@ diff -Nrpc base/src/backend/executor/execMain.c sepgsql/src/backend/executor/exe FreeTupleDesc(tupdesc); ---- 3048,3055 ---- +--- 3063,3070 ---- 0, into->onCommit, reloptions, @@ -6522,8 +6522,8 @@ diff -Nrpc base/src/backend/executor/execMain.c sepgsql/src/backend/executor/exe FreeTupleDesc(tupdesc); *************** intorel_receive(TupleTableSlot *slot, De -*** 3054,3059 **** ---- 3174,3183 ---- +*** 3069,3074 **** +--- 3189,3198 ---- if (myState->rel->rd_rel->relhasoids) HeapTupleSetOid(tuple, InvalidOid); @@ -7003,8 +7003,8 @@ diff -Nrpc base/src/backend/executor/nodeWindowAgg.c sepgsql/src/backend/executo } diff -Nrpc base/src/backend/executor/spi.c sepgsql/src/backend/executor/spi.c -*** base/src/backend/executor/spi.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/executor/spi.c Tue Sep 8 23:55:48 2009 +*** base/src/backend/executor/spi.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/executor/spi.c Tue Dec 15 17:30:25 2009 *************** SPI_modifytuple(Relation rel, HeapTuple *** 705,710 **** --- 705,712 ---- @@ -7160,8 +7160,8 @@ diff -Nrpc base/src/backend/libpq/be-fsstubs.c sepgsql/src/backend/libpq/be-fsst * prepares large objects for transaction commit */ diff -Nrpc base/src/backend/nodes/copyfuncs.c sepgsql/src/backend/nodes/copyfuncs.c -*** base/src/backend/nodes/copyfuncs.c Fri Jun 19 13:40:37 2009 ---- sepgsql/src/backend/nodes/copyfuncs.c Wed Jul 15 19:39:56 2009 +*** base/src/backend/nodes/copyfuncs.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/nodes/copyfuncs.c Tue Dec 15 17:30:25 2009 *************** CopyScanFields(Scan *from, Scan *newnode *** 259,264 **** --- 259,265 ---- @@ -7176,7 +7176,7 @@ diff -Nrpc base/src/backend/nodes/copyfuncs.c sepgsql/src/backend/nodes/copyfunc *** 2075,2080 **** --- 2076,2082 ---- COPY_NODE_FIELD(raw_default); - COPY_STRING_FIELD(cooked_default); + COPY_NODE_FIELD(cooked_default); COPY_NODE_FIELD(constraints); + COPY_NODE_FIELD(secLabel); @@ -7239,8 +7239,8 @@ diff -Nrpc base/src/backend/nodes/copyfuncs.c sepgsql/src/backend/nodes/copyfunc retval = _copyRuleStmt(from); break; diff -Nrpc base/src/backend/nodes/equalfuncs.c sepgsql/src/backend/nodes/equalfuncs.c -*** base/src/backend/nodes/equalfuncs.c Fri Jun 19 13:40:37 2009 ---- sepgsql/src/backend/nodes/equalfuncs.c Wed Jul 15 19:37:35 2009 +*** base/src/backend/nodes/equalfuncs.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/nodes/equalfuncs.c Tue Dec 15 17:30:25 2009 *************** _equalCreateStmt(CreateStmt *a, CreateSt *** 1078,1083 **** --- 1078,1084 ---- @@ -7287,7 +7287,7 @@ diff -Nrpc base/src/backend/nodes/equalfuncs.c sepgsql/src/backend/nodes/equalfu *** 2054,2059 **** --- 2069,2075 ---- COMPARE_NODE_FIELD(raw_default); - COMPARE_STRING_FIELD(cooked_default); + COMPARE_NODE_FIELD(cooked_default); COMPARE_NODE_FIELD(constraints); + COMPARE_NODE_FIELD(secLabel); @@ -7306,8 +7306,8 @@ diff -Nrpc base/src/backend/nodes/equalfuncs.c sepgsql/src/backend/nodes/equalfu retval = _equalRuleStmt(a, b); break; diff -Nrpc base/src/backend/nodes/outfuncs.c sepgsql/src/backend/nodes/outfuncs.c -*** base/src/backend/nodes/outfuncs.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/nodes/outfuncs.c Wed Jul 15 19:39:56 2009 +*** base/src/backend/nodes/outfuncs.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/nodes/outfuncs.c Tue Dec 15 17:30:25 2009 *************** _outScanInfo(StringInfo str, Scan *node) *** 285,290 **** --- 285,291 ---- @@ -7342,7 +7342,7 @@ diff -Nrpc base/src/backend/nodes/outfuncs.c sepgsql/src/backend/nodes/outfuncs. *** 1839,1844 **** --- 1842,1848 ---- WRITE_NODE_FIELD(raw_default); - WRITE_STRING_FIELD(cooked_default); + WRITE_NODE_FIELD(cooked_default); WRITE_NODE_FIELD(constraints); + WRITE_NODE_FIELD(secLabel); } @@ -7420,8 +7420,8 @@ diff -Nrpc base/src/backend/optimizer/util/relnode.c sepgsql/src/backend/optimiz /* Check type of rtable entry */ switch (rte->rtekind) diff -Nrpc base/src/backend/parser/analyze.c sepgsql/src/backend/parser/analyze.c -*** base/src/backend/parser/analyze.c Sun Sep 6 19:40:49 2009 ---- sepgsql/src/backend/parser/analyze.c Sun Sep 6 19:53:10 2009 +*** base/src/backend/parser/analyze.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/parser/analyze.c Tue Dec 15 17:30:25 2009 *************** *** 25,30 **** --- 25,31 ---- @@ -7433,7 +7433,7 @@ diff -Nrpc base/src/backend/parser/analyze.c sepgsql/src/backend/parser/analyze. #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" *************** transformInsertStmt(ParseState *pstate, -*** 653,659 **** +*** 660,666 **** tle = makeTargetEntry(expr, attr_num, col->name, @@ -7441,7 +7441,7 @@ diff -Nrpc base/src/backend/parser/analyze.c sepgsql/src/backend/parser/analyze. qry->targetList = lappend(qry->targetList, tle); rte->modifiedCols = bms_add_member(rte->modifiedCols, ---- 654,660 ---- +--- 661,667 ---- tle = makeTargetEntry(expr, attr_num, col->name, @@ -7450,8 +7450,8 @@ diff -Nrpc base/src/backend/parser/analyze.c sepgsql/src/backend/parser/analyze. rte->modifiedCols = bms_add_member(rte->modifiedCols, *************** transformInsertRow(ParseState *pstate, L -*** 768,773 **** ---- 769,816 ---- +*** 775,780 **** +--- 776,823 ---- return result; } @@ -7501,8 +7501,8 @@ diff -Nrpc base/src/backend/parser/analyze.c sepgsql/src/backend/parser/analyze. /* * transformSelectStmt - *************** transformSelectStmt(ParseState *pstate, -*** 872,877 **** ---- 915,921 ---- +*** 879,884 **** +--- 922,928 ---- if (stmt->intoClause) { qry->intoClause = stmt->intoClause; @@ -7971,8 +7971,8 @@ diff -Nrpc base/src/backend/parser/parse_target.c sepgsql/src/backend/parser/par /* * Check for duplicates, but only of whole columns --- we allow diff -Nrpc base/src/backend/parser/parse_utilcmd.c sepgsql/src/backend/parser/parse_utilcmd.c -*** base/src/backend/parser/parse_utilcmd.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/parser/parse_utilcmd.c Fri Sep 18 14:51:00 2009 +*** base/src/backend/parser/parse_utilcmd.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/parser/parse_utilcmd.c Tue Dec 15 17:30:25 2009 *************** *** 49,54 **** --- 49,55 ---- @@ -8015,8 +8015,8 @@ diff -Nrpc base/src/backend/postmaster/autovacuum.c sepgsql/src/backend/postmast else { diff -Nrpc base/src/backend/postmaster/postmaster.c sepgsql/src/backend/postmaster/postmaster.c -*** base/src/backend/postmaster/postmaster.c Sun Sep 6 19:40:49 2009 ---- sepgsql/src/backend/postmaster/postmaster.c Tue Dec 8 14:04:25 2009 +*** base/src/backend/postmaster/postmaster.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/postmaster/postmaster.c Tue Dec 15 17:30:25 2009 *************** *** 108,113 **** --- 108,114 ---- @@ -8070,8 +8070,8 @@ diff -Nrpc base/src/backend/postmaster/postmaster.c sepgsql/src/backend/postmast if (avlauncher_needs_signal) { *************** SIGHUP_handler(SIGNAL_ARGS) -*** 2053,2058 **** ---- 2061,2068 ---- +*** 2055,2060 **** +--- 2063,2070 ---- signal_child(SysLoggerPID, SIGHUP); if (PgStatPID != 0) signal_child(PgStatPID, SIGHUP); @@ -8081,8 +8081,8 @@ diff -Nrpc base/src/backend/postmaster/postmaster.c sepgsql/src/backend/postmast /* Reload authentication config files too */ if (!load_hba()) *************** pmdie(SIGNAL_ARGS) -*** 2113,2118 **** ---- 2123,2131 ---- +*** 2115,2120 **** +--- 2125,2133 ---- /* and the walwriter too */ if (WalWriterPID != 0) signal_child(WalWriterPID, SIGTERM); @@ -8093,8 +8093,8 @@ diff -Nrpc base/src/backend/postmaster/postmaster.c sepgsql/src/backend/postmast } *************** pmdie(SIGNAL_ARGS) -*** 2160,2165 **** ---- 2173,2181 ---- +*** 2162,2167 **** +--- 2175,2183 ---- /* and the walwriter too */ if (WalWriterPID != 0) signal_child(WalWriterPID, SIGTERM); @@ -8105,8 +8105,8 @@ diff -Nrpc base/src/backend/postmaster/postmaster.c sepgsql/src/backend/postmast } *************** pmdie(SIGNAL_ARGS) -*** 2193,2198 **** ---- 2209,2216 ---- +*** 2195,2200 **** +--- 2211,2218 ---- signal_child(PgArchPID, SIGQUIT); if (PgStatPID != 0) signal_child(PgStatPID, SIGQUIT); @@ -8116,8 +8116,8 @@ diff -Nrpc base/src/backend/postmaster/postmaster.c sepgsql/src/backend/postmast break; } *************** reaper(SIGNAL_ARGS) -*** 2455,2460 **** ---- 2473,2488 ---- +*** 2457,2462 **** +--- 2475,2490 ---- continue; } @@ -8135,8 +8135,8 @@ diff -Nrpc base/src/backend/postmaster/postmaster.c sepgsql/src/backend/postmast * Else do standard backend child cleanup. */ *************** HandleChildCrash(int pid, int exitstatus -*** 2646,2651 **** ---- 2674,2691 ---- +*** 2648,2653 **** +--- 2676,2693 ---- signal_child(AutoVacPID, (SendStop ? SIGSTOP : SIGQUIT)); } @@ -8156,7 +8156,7 @@ diff -Nrpc base/src/backend/postmaster/postmaster.c sepgsql/src/backend/postmast * Force a power-cycle of the pgarch process too. (This isn't absolutely * necessary, but it seems like a good idea for robustness, and it *************** PostmasterStateMachine(void) -*** 2778,2784 **** +*** 2780,2786 **** StartupPID == 0 && (BgWriterPID == 0 || !FatalError) && WalWriterPID == 0 && @@ -8164,7 +8164,7 @@ diff -Nrpc base/src/backend/postmaster/postmaster.c sepgsql/src/backend/postmast { if (FatalError) { ---- 2818,2825 ---- +--- 2820,2827 ---- StartupPID == 0 && (BgWriterPID == 0 || !FatalError) && WalWriterPID == 0 && @@ -8174,8 +8174,8 @@ diff -Nrpc base/src/backend/postmaster/postmaster.c sepgsql/src/backend/postmast if (FatalError) { *************** StartChildProcess(AuxProcType type) -*** 4321,4326 **** ---- 4362,4373 ---- +*** 4323,4328 **** +--- 4364,4375 ---- ereport(LOG, (errmsg("could not fork WAL writer process: %m"))); break; @@ -8408,10 +8408,10 @@ diff -Nrpc base/src/backend/security/sepgsql/Makefile sepgsql/src/backend/securi + include $(top_srcdir)/src/backend/common.mk diff -Nrpc base/src/backend/security/sepgsql/avc.c sepgsql/src/backend/security/sepgsql/avc.c *** base/src/backend/security/sepgsql/avc.c Thu Jan 1 09:00:00 1970 ---- sepgsql/src/backend/security/sepgsql/avc.c Tue Dec 8 14:16:15 2009 +--- sepgsql/src/backend/security/sepgsql/avc.c Thu Dec 10 10:36:18 2009 *************** *** 0 **** ---- 1,880 ---- +--- 1,881 ---- + /* + * src/backend/security/sepgsql/avc.c + * SE-PostgreSQL userspace access vector cache @@ -8454,7 +8454,7 @@ diff -Nrpc base/src/backend/security/sepgsql/avc.c sepgsql/src/backend/security/ + * postmaster can receives the notification messages from the kernel + * space, and invalidate the current version of avc. + */ -+ static MemoryContext AvcMemCtx; ++ static MemoryContext AvcMemCtx = NULL; + + #define AVC_HASH_NUM_SLOTS 256 + #define AVC_HASH_NUM_NODES 180 @@ -8554,11 +8554,12 @@ diff -Nrpc base/src/backend/security/sepgsql/avc.c sepgsql/src/backend/security/ + * It invalidate access vector cache. It has to be called on errors, + * because avc entries for newly created context is uncertain whether + * it is still valid, or not. ++ * If error happens before avc initialization, we simply skip it. + */ + void + sepgsqlAvcReset(void) + { -+ if (!sepgsqlIsEnabled()) ++ if (!sepgsqlIsEnabled() || !AvcMemCtx) + return; + + MemoryContextReset(AvcMemCtx); @@ -15175,11 +15176,11 @@ diff -Nrpc base/src/backend/security/sepgsql/policy/sepostgresql-devel.te sepgsq + allow sepgsql_database_type user_home_t : db_database { load_module }; + ') diff -Nrpc base/src/backend/storage/file/fd.c sepgsql/src/backend/storage/file/fd.c -*** base/src/backend/storage/file/fd.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/storage/file/fd.c Wed Jul 15 19:48:58 2009 +*** base/src/backend/storage/file/fd.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/storage/file/fd.c Tue Dec 15 17:30:25 2009 *************** FileTruncate(File file, off_t offset) -*** 1319,1324 **** ---- 1319,1331 ---- +*** 1329,1334 **** +--- 1329,1341 ---- return returnCode; } @@ -15496,8 +15497,8 @@ diff -Nrpc base/src/backend/tcop/pquery.c sepgsql/src/backend/tcop/pquery.c /* diff -Nrpc base/src/backend/tcop/utility.c sepgsql/src/backend/tcop/utility.c -*** base/src/backend/tcop/utility.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/tcop/utility.c Wed Jul 15 21:17:18 2009 +*** base/src/backend/tcop/utility.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/tcop/utility.c Tue Dec 15 17:30:25 2009 *************** *** 50,55 **** --- 50,56 ---- @@ -15519,8 +15520,8 @@ diff -Nrpc base/src/backend/tcop/utility.c sepgsql/src/backend/tcop/utility.c case T_AlterTableStmt: case T_RenameStmt: *************** ProcessUtility(Node *parsetree, -*** 612,617 **** ---- 614,623 ---- +*** 634,639 **** +--- 636,645 ---- ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree); break; @@ -15532,8 +15533,8 @@ diff -Nrpc base/src/backend/tcop/utility.c sepgsql/src/backend/tcop/utility.c { List *stmts; *************** ProcessUtility(Node *parsetree, -*** 893,898 **** ---- 899,905 ---- +*** 917,922 **** +--- 923,929 ---- LoadStmt *stmt = (LoadStmt *) parsetree; closeAllVfds(); /* probably not necessary... */ @@ -15542,8 +15543,8 @@ diff -Nrpc base/src/backend/tcop/utility.c sepgsql/src/backend/tcop/utility.c load_file(stmt->filename, !superuser()); } *************** CreateCommandTag(Node *parsetree) -*** 1635,1640 **** ---- 1642,1672 ---- +*** 1661,1666 **** +--- 1668,1698 ---- } break; @@ -15576,8 +15577,8 @@ diff -Nrpc base/src/backend/tcop/utility.c sepgsql/src/backend/tcop/utility.c switch (((AlterTableStmt *) parsetree)->relkind) { *************** GetCommandLogLevel(Node *parsetree) -*** 2213,2218 **** ---- 2245,2254 ---- +*** 2239,2244 **** +--- 2271,2280 ---- lev = LOGSTMT_DDL; break; @@ -15625,8 +15626,8 @@ diff -Nrpc base/src/backend/utils/adt/genfile.c sepgsql/src/backend/utils/adt/ge if (stat(filename, &fst) < 0) ereport(ERROR, diff -Nrpc base/src/backend/utils/adt/ri_triggers.c sepgsql/src/backend/utils/adt/ri_triggers.c -*** base/src/backend/utils/adt/ri_triggers.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/utils/adt/ri_triggers.c Wed Jul 15 19:39:56 2009 +*** base/src/backend/utils/adt/ri_triggers.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/utils/adt/ri_triggers.c Tue Dec 15 17:30:25 2009 *************** *** 39,44 **** --- 39,45 ---- @@ -15674,20 +15675,20 @@ diff -Nrpc base/src/backend/utils/adt/ri_triggers.c sepgsql/src/backend/utils/ad if (spi_result != SPI_OK_SELECT) elog(ERROR, "SPI_execute_snapshot returned %d", spi_result); *************** ri_PerformCheck(RI_QueryKey *qkey, SPIPl -*** 3264,3269 **** ---- 3274,3280 ---- +*** 3265,3270 **** +--- 3275,3281 ---- int spi_result; Oid save_userid; - bool save_secdefcxt; + int save_sec_context; + int save_rowlv, temp_rowlv; Datum vals[RI_MAX_NUMKEYS * 2]; char nulls[RI_MAX_NUMKEYS * 2]; *************** ri_PerformCheck(RI_QueryKey *qkey, SPIPl -*** 3346,3357 **** ---- 3357,3375 ---- - GetUserIdAndContext(&save_userid, &save_secdefcxt); - SetUserIdAndContext(RelationGetForm(query_rel)->relowner, true); +*** 3348,3359 **** +--- 3359,3377 ---- + SetUserIdAndSecContext(RelationGetForm(query_rel)->relowner, + save_sec_context | SECURITY_LOCAL_USERID_CHANGE); + /* Switch Row-level stuff behavior on FK checks, if necessary */ + temp_rowlv = (detectNewRows ? ROWLV_ABORT_MODE : ROWLV_FILTER_MODE); @@ -15702,8 +15703,8 @@ diff -Nrpc base/src/backend/utils/adt/ri_triggers.c sepgsql/src/backend/utils/ad + /* Restore Row-level stuff behavior */ + rowlvSetPerformingMode(save_rowlv); + - /* Restore UID */ - SetUserIdAndContext(save_userid, save_secdefcxt); + /* Restore UID and security context */ + SetUserIdAndSecContext(save_userid, save_sec_context); diff -Nrpc base/src/backend/utils/adt/tid.c sepgsql/src/backend/utils/adt/tid.c *** base/src/backend/utils/adt/tid.c Sat Jan 3 13:01:35 2009 @@ -15807,8 +15808,8 @@ diff -Nrpc base/src/backend/utils/cache/plancache.c sepgsql/src/backend/utils/ca /* other cases shouldn't happen, but return NULL */ break; diff -Nrpc base/src/backend/utils/cache/relcache.c sepgsql/src/backend/utils/cache/relcache.c -*** base/src/backend/utils/cache/relcache.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/utils/cache/relcache.c Wed Sep 9 13:14:37 2009 +*** base/src/backend/utils/cache/relcache.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/utils/cache/relcache.c Tue Dec 15 17:30:25 2009 *************** *** 47,52 **** --- 47,53 ---- @@ -15833,8 +15834,8 @@ diff -Nrpc base/src/backend/utils/cache/relcache.c sepgsql/src/backend/utils/cac * initialize the relation lock manager information */ *************** formrdesc(const char *relationName, Oid -*** 1458,1463 **** ---- 1463,1473 ---- +*** 1460,1465 **** +--- 1465,1475 ---- RelationGetRelid(relation) = relation->rd_att->attrs[0]->attrelid; relation->rd_rel->relfilenode = RelationGetRelid(relation); @@ -15847,8 +15848,8 @@ diff -Nrpc base/src/backend/utils/cache/relcache.c sepgsql/src/backend/utils/cac * initialize the relation lock manager information */ *************** BuildHardcodedDescriptor(int natts, Form -*** 2699,2704 **** ---- 2709,2721 ---- +*** 2749,2754 **** +--- 2759,2771 ---- result = CreateTemplateTupleDesc(natts, hasoids); result->tdtypeid = RECORDOID; /* not right, but we don't care */ result->tdtypmod = -1; @@ -15863,8 +15864,8 @@ diff -Nrpc base/src/backend/utils/cache/relcache.c sepgsql/src/backend/utils/cac for (i = 0; i < natts; i++) { *************** load_relcache_init_file(void) -*** 3453,3458 **** ---- 3470,3480 ---- +*** 3503,3508 **** +--- 3520,3530 ---- rel->rd_options = NULL; } @@ -15970,8 +15971,8 @@ diff -Nrpc base/src/backend/utils/fmgr/dfmgr.c sepgsql/src/backend/utils/fmgr/df internal_unload_library(fullname); diff -Nrpc base/src/backend/utils/fmgr/fmgr.c sepgsql/src/backend/utils/fmgr/fmgr.c -*** base/src/backend/utils/fmgr/fmgr.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/backend/utils/fmgr/fmgr.c Thu Sep 17 17:04:16 2009 +*** base/src/backend/utils/fmgr/fmgr.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/utils/fmgr/fmgr.c Tue Dec 15 17:30:25 2009 *************** *** 24,29 **** --- 24,30 ---- @@ -16047,8 +16048,8 @@ diff -Nrpc base/src/backend/utils/init/postinit.c sepgsql/src/backend/utils/init * Figure out our postgres user id, and see if we are a superuser. * diff -Nrpc base/src/backend/utils/misc/guc.c sepgsql/src/backend/utils/misc/guc.c -*** base/src/backend/utils/misc/guc.c Sun Sep 6 19:40:49 2009 ---- sepgsql/src/backend/utils/misc/guc.c Sun Sep 6 19:53:10 2009 +*** base/src/backend/utils/misc/guc.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/backend/utils/misc/guc.c Tue Dec 15 17:30:25 2009 *************** *** 56,61 **** --- 56,62 ---- @@ -16178,8 +16179,8 @@ diff -Nrpc base/src/backend/utils/misc/superuser.c sepgsql/src/backend/utils/mis } diff -Nrpc base/src/bin/initdb/initdb.c sepgsql/src/bin/initdb/initdb.c -*** base/src/bin/initdb/initdb.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/bin/initdb/initdb.c Wed Jul 15 19:35:52 2009 +*** base/src/bin/initdb/initdb.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/bin/initdb/initdb.c Tue Dec 15 17:30:25 2009 *************** static bool debug = false; *** 87,92 **** --- 87,93 ---- @@ -16239,8 +16240,8 @@ diff -Nrpc base/src/bin/initdb/initdb.c sepgsql/src/bin/initdb/initdb.c show_setting = true; break; diff -Nrpc base/src/bin/pg_dump/pg_dump.c sepgsql/src/bin/pg_dump/pg_dump.c -*** base/src/bin/pg_dump/pg_dump.c Sun Sep 6 19:40:49 2009 ---- sepgsql/src/bin/pg_dump/pg_dump.c Tue Sep 8 17:13:41 2009 +*** base/src/bin/pg_dump/pg_dump.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/bin/pg_dump/pg_dump.c Tue Dec 15 17:30:25 2009 *************** static int disable_dollar_quoting = 0; *** 112,117 **** --- 112,119 ---- @@ -16967,8 +16968,8 @@ diff -Nrpc base/src/bin/pg_dump/pg_dump.c sepgsql/src/bin/pg_dump/pg_dump.c /* *************** fmtCopyColumnList(const TableInfo *ti) -*** 11508,11513 **** ---- 11595,11607 ---- +*** 11510,11515 **** +--- 11597,11609 ---- appendPQExpBuffer(q, "("); needComma = false; @@ -17914,21 +17915,21 @@ diff -Nrpc base/src/include/nodes/nodes.h sepgsql/src/include/nodes/nodes.h /* * TAGS FOR PARSE TREE NODES (parsenodes.h) diff -Nrpc base/src/include/nodes/parsenodes.h sepgsql/src/include/nodes/parsenodes.h -*** base/src/include/nodes/parsenodes.h Fri Jun 19 13:40:37 2009 ---- sepgsql/src/include/nodes/parsenodes.h Wed Jul 15 19:37:35 2009 +*** base/src/include/nodes/parsenodes.h Tue Dec 15 17:16:51 2009 +--- sepgsql/src/include/nodes/parsenodes.h Tue Dec 15 17:30:25 2009 *************** typedef struct ColumnDef -*** 464,469 **** ---- 464,470 ---- +*** 463,468 **** +--- 463,469 ---- Node *raw_default; /* default value (untransformed parse tree) */ - char *cooked_default; /* nodeToString representation */ + Node *cooked_default; /* default value (transformed expr tree) */ List *constraints; /* other constraints on column */ + Node *secLabel; /* security label of column */ } ColumnDef; /* *************** typedef struct CreateSchemaStmt -*** 1070,1075 **** ---- 1071,1077 ---- +*** 1069,1074 **** +--- 1070,1076 ---- NodeTag type; char *schemaname; /* the name of the schema to create */ char *authid; /* the owner of the created schema */ @@ -17937,8 +17938,8 @@ diff -Nrpc base/src/include/nodes/parsenodes.h sepgsql/src/include/nodes/parseno } CreateSchemaStmt; *************** typedef struct CreateStmt -*** 1335,1340 **** ---- 1337,1343 ---- +*** 1334,1339 **** +--- 1336,1342 ---- List *options; /* options from WITH clause */ OnCommitAction oncommit; /* what do we do at COMMIT? */ char *tablespacename; /* table space to use, or NULL */ @@ -17947,8 +17948,8 @@ diff -Nrpc base/src/include/nodes/parsenodes.h sepgsql/src/include/nodes/parseno /* ---------- *************** typedef struct CreateSeqStmt -*** 1639,1644 **** ---- 1642,1648 ---- +*** 1638,1643 **** +--- 1641,1647 ---- NodeTag type; RangeVar *sequence; /* the sequence to create */ List *options; @@ -17957,8 +17958,8 @@ diff -Nrpc base/src/include/nodes/parsenodes.h sepgsql/src/include/nodes/parseno typedef struct AlterSeqStmt *************** typedef struct AlterOwnerStmt -*** 1993,1998 **** ---- 1997,2016 ---- +*** 1992,1997 **** +--- 1996,2015 ---- char *newowner; /* the new owner */ } AlterOwnerStmt; @@ -19046,8 +19047,8 @@ diff -Nrpc base/src/test/regress/expected/sanity_check.out sepgsql/src/test/regr -- -- another sanity check: every system catalog that has OIDs should have diff -Nrpc base/src/test/regress/pg_regress.c sepgsql/src/test/regress/pg_regress.c -*** base/src/test/regress/pg_regress.c Thu Jun 18 10:20:52 2009 ---- sepgsql/src/test/regress/pg_regress.c Tue Dec 1 17:11:40 2009 +*** base/src/test/regress/pg_regress.c Tue Dec 15 17:16:51 2009 +--- sepgsql/src/test/regress/pg_regress.c Tue Dec 15 17:30:25 2009 *************** static _stringlist *schedulelist = NULL; *** 82,87 **** --- 82,88 ---- diff --git a/sepostgresql.spec b/sepostgresql.spec index 7955ef9..4c0cd85 100644 --- a/sepostgresql.spec +++ b/sepostgresql.spec @@ -11,8 +11,8 @@ Summary: Security Enhanced PostgreSQL Name: sepostgresql -Version: 8.4.1 -Release: 2464%{?dist} +Version: 8.4.2 +Release: 2487%{?dist} License: BSD Group: Applications/Databases Url: http://code.google.com/p/sepgsql/ @@ -192,6 +192,9 @@ fi %attr(700,sepgsql,sepgsql) %dir %{_localstatedir}/lib/sepgsql/backups %changelog +* Wed Dec 16 2009 KaiGai Kohei - 8.4.2-2487 +- upgrade base version 8.4.1->8.4.2 + * Fri Dec 8 2009 KaiGai Kohei - 8.4.1-2464 - rework: backport features from v8.5devel tree - fixbug: selinux netlink receiver process didn't have correct ps display diff --git a/sources b/sources index 91e78c6..0aef01a 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -f2015af17bacbbfe140daf0d1067f9c9 postgresql-8.4.1.tar.bz2 +d738227e2f1f742d2f2d4ab56496c5c6 postgresql-8.4.2.tar.bz2 From a926a7c3ca161044af3509c707399814b067348b Mon Sep 17 00:00:00 2001 From: KaiGai Kohei Date: Thu, 18 Mar 2010 01:18:22 +0000 Subject: [PATCH 6/8] detach dependency to minor updates --- sepostgresql.spec | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sepostgresql.spec b/sepostgresql.spec index 4c0cd85..6dea944 100644 --- a/sepostgresql.spec +++ b/sepostgresql.spec @@ -12,7 +12,7 @@ Summary: Security Enhanced PostgreSQL Name: sepostgresql Version: 8.4.2 -Release: 2487%{?dist} +Release: 2582%{?dist} License: BSD Group: Applications/Databases Url: http://code.google.com/p/sepgsql/ @@ -33,7 +33,8 @@ Requires(pre): shadow-utils Requires(post): policycoreutils /sbin/chkconfig Requires(preun): /sbin/chkconfig /sbin/service Requires(postun): policycoreutils -Requires: postgresql-server = %{version} +Requires: postgresql-server >= 8.4.0 +Conflicts: postgresql-server >= 8.5.0 Requires: policycoreutils >= 2.0.16 libselinux >= 2.0.80 Requires: selinux-policy >= 3.6.8 Requires: tzdata logrotate @@ -192,6 +193,9 @@ fi %attr(700,sepgsql,sepgsql) %dir %{_localstatedir}/lib/sepgsql/backups %changelog +* Thu Mar 18 2010 KaiGai Kohei - 8.4.3-2582 +- detach dependency to minor updates + * Wed Dec 16 2009 KaiGai Kohei - 8.4.2-2487 - upgrade base version 8.4.1->8.4.2 From b4f78eea007f89601d86042265dbec004ab67f47 Mon Sep 17 00:00:00 2001 From: KaiGai Kohei Date: Thu, 18 Mar 2010 01:36:21 +0000 Subject: [PATCH 7/8] incorrect release number --- sepostgresql.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sepostgresql.spec b/sepostgresql.spec index 6dea944..b4b410a 100644 --- a/sepostgresql.spec +++ b/sepostgresql.spec @@ -12,7 +12,7 @@ Summary: Security Enhanced PostgreSQL Name: sepostgresql Version: 8.4.2 -Release: 2582%{?dist} +Release: 2583%{?dist} License: BSD Group: Applications/Databases Url: http://code.google.com/p/sepgsql/ @@ -193,7 +193,7 @@ fi %attr(700,sepgsql,sepgsql) %dir %{_localstatedir}/lib/sepgsql/backups %changelog -* Thu Mar 18 2010 KaiGai Kohei - 8.4.3-2582 +* Thu Mar 18 2010 KaiGai Kohei - 8.4.3-2583 - detach dependency to minor updates * Wed Dec 16 2009 KaiGai Kohei - 8.4.2-2487 From 9df0019eac5a147aff9ef90deaea8f4570ae74d6 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 29 Jul 2010 12:35:28 +0000 Subject: [PATCH 8/8] dist-git conversion --- .cvsignore => .gitignore | 0 Makefile | 21 --------------------- branch | 1 - 3 files changed, 22 deletions(-) rename .cvsignore => .gitignore (100%) delete mode 100644 Makefile delete mode 100644 branch diff --git a/.cvsignore b/.gitignore similarity index 100% rename from .cvsignore rename to .gitignore diff --git a/Makefile b/Makefile deleted file mode 100644 index 59ecad3..0000000 --- a/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# Makefile for source rpm: sepostgresql -# $Id$ -NAME := sepostgresql -SPECFILE = $(firstword $(wildcard *.spec)) - -define find-makefile-common -for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$d/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done -endef - -MAKEFILE_COMMON := $(shell $(find-makefile-common)) - -ifeq ($(MAKEFILE_COMMON),) -# attept a checkout -define checkout-makefile-common -test -f CVS/Root && { cvs -Q -d $$(cat CVS/Root) checkout common && echo "common/Makefile.common" ; } || { echo "ERROR: I can't figure out how to checkout the 'common' module." ; exit -1 ; } >&2 -endef - -MAKEFILE_COMMON := $(shell $(checkout-makefile-common)) -endif - -include $(MAKEFILE_COMMON) diff --git a/branch b/branch deleted file mode 100644 index 06de2d2..0000000 --- a/branch +++ /dev/null @@ -1 +0,0 @@ -F-12