diff --git a/.cvsignore b/.cvsignore index e18d446..28f3a6b 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -postgresql-8.3.7.tar.bz2 +postgresql-8.3.8.tar.bz2 diff --git a/sepostgresql-core-8.3.patch b/sepostgresql-core-8.3.patch index 47685f3..e732e59 100644 --- a/sepostgresql-core-8.3.patch +++ b/sepostgresql-core-8.3.patch @@ -1,6 +1,6 @@ diff -rpNU3 base/configure sepgsql-new/configure ---- base/configure 2009-05-20 17:08:02.000000000 +0900 -+++ sepgsql-new/configure 2009-05-20 17:08:02.000000000 +0900 +--- base/configure 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/configure 2009-09-10 20:24:37.000000000 +0900 @@ -314,7 +314,7 @@ ac_includes_default="\ # include #endif" @@ -143,8 +143,8 @@ diff -rpNU3 base/configure sepgsql-new/configure s,@ELF_SYS@,$ELF_SYS,;t t s,@LDFLAGS_SL@,$LDFLAGS_SL,;t t diff -rpNU3 base/configure.in sepgsql-new/configure.in ---- base/configure.in 2009-03-15 17:47:25.000000000 +0900 -+++ sepgsql-new/configure.in 2009-03-15 17:58:10.000000000 +0900 +--- base/configure.in 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/configure.in 2009-09-10 20:24:37.000000000 +0900 @@ -626,6 +626,19 @@ PGAC_ARG_BOOL(with, zlib, yes, AC_SUBST(with_zlib) @@ -201,8 +201,8 @@ diff -rpNU3 base/src/backend/Makefile sepgsql-new/src/backend/Makefile all: submake-libpgport postgres $(POSTGRES_IMP) diff -rpNU3 base/src/backend/access/common/heaptuple.c sepgsql-new/src/backend/access/common/heaptuple.c ---- base/src/backend/access/common/heaptuple.c 2008-01-07 23:51:33.000000000 +0900 -+++ sepgsql-new/src/backend/access/common/heaptuple.c 2009-03-13 18:14:33.000000000 +0900 +--- base/src/backend/access/common/heaptuple.c 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/src/backend/access/common/heaptuple.c 2009-09-10 20:24:37.000000000 +0900 @@ -66,6 +66,7 @@ #include "access/heapam.h" @@ -372,8 +372,8 @@ diff -rpNU3 base/src/backend/access/common/tupdesc.c sepgsql-new/src/backend/acc for (i = 0; i < tupdesc1->natts; i++) { diff -rpNU3 base/src/backend/access/heap/heapam.c sepgsql-new/src/backend/access/heap/heapam.c ---- base/src/backend/access/heap/heapam.c 2009-02-02 11:47:17.000000000 +0900 -+++ sepgsql-new/src/backend/access/heap/heapam.c 2009-03-13 18:14:33.000000000 +0900 +--- base/src/backend/access/heap/heapam.c 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/src/backend/access/heap/heapam.c 2009-09-10 20:24:37.000000000 +0900 @@ -50,6 +50,7 @@ #include "catalog/namespace.h" #include "miscadmin.h" @@ -382,7 +382,7 @@ diff -rpNU3 base/src/backend/access/heap/heapam.c sepgsql-new/src/backend/access #include "storage/procarray.h" #include "storage/smgr.h" #include "utils/datum.h" -@@ -1949,6 +1950,8 @@ heap_insert(Relation relation, HeapTuple +@@ -1958,6 +1959,8 @@ heap_insert(Relation relation, HeapTuple Oid simple_heap_insert(Relation relation, HeapTuple tup) { @@ -391,7 +391,7 @@ diff -rpNU3 base/src/backend/access/heap/heapam.c sepgsql-new/src/backend/access return heap_insert(relation, tup, GetCurrentCommandId(true), true, true); } -@@ -2230,6 +2233,8 @@ simple_heap_delete(Relation relation, It +@@ -2239,6 +2242,8 @@ simple_heap_delete(Relation relation, It ItemPointerData update_ctid; TransactionId update_xmax; @@ -400,7 +400,7 @@ diff -rpNU3 base/src/backend/access/heap/heapam.c sepgsql-new/src/backend/access result = heap_delete(relation, tid, &update_ctid, &update_xmax, GetCurrentCommandId(true), InvalidSnapshot, -@@ -2874,6 +2879,8 @@ simple_heap_update(Relation relation, It +@@ -2883,6 +2888,8 @@ simple_heap_update(Relation relation, It ItemPointerData update_ctid; TransactionId update_xmax; @@ -701,7 +701,7 @@ diff -rpNU3 base/src/backend/catalog/catalog.c sepgsql-new/src/backend/catalog/c relationId == SharedDependReferenceIndexId || diff -rpNU3 base/src/backend/catalog/heap.c sepgsql-new/src/backend/catalog/heap.c --- base/src/backend/catalog/heap.c 2009-03-15 17:47:25.000000000 +0900 -+++ sepgsql-new/src/backend/catalog/heap.c 2009-03-15 17:58:10.000000000 +0900 ++++ sepgsql-new/src/backend/catalog/heap.c 2009-06-19 15:02:12.000000000 +0900 @@ -42,6 +42,7 @@ #include "catalog/pg_constraint.h" #include "catalog/pg_inherits.h" @@ -710,15 +710,7 @@ diff -rpNU3 base/src/backend/catalog/heap.c sepgsql-new/src/backend/catalog/heap #include "catalog/pg_statistic.h" #include "catalog/pg_tablespace.h" #include "catalog/pg_type.h" -@@ -53,6 +54,7 @@ - #include "parser/parse_coerce.h" - #include "parser/parse_expr.h" - #include "parser/parse_relation.h" -+#include "security/sepgsql.h" - #include "storage/smgr.h" - #include "utils/builtins.h" - #include "utils/fmgroids.h" -@@ -67,7 +69,8 @@ static void AddNewRelationTuple(Relation +@@ -67,7 +68,8 @@ static void AddNewRelationTuple(Relation Oid new_rel_oid, Oid new_type_oid, Oid relowner, char relkind, @@ -728,7 +720,7 @@ diff -rpNU3 base/src/backend/catalog/heap.c sepgsql-new/src/backend/catalog/heap static Oid AddNewRelationType(const char *typeName, Oid typeNamespace, Oid new_rel_oid, -@@ -145,7 +148,16 @@ static FormData_pg_attribute a7 = { +@@ -145,7 +147,16 @@ static FormData_pg_attribute a7 = { true, 'p', 'i', true, false, false, true, 0 }; @@ -746,7 +738,7 @@ diff -rpNU3 base/src/backend/catalog/heap.c sepgsql-new/src/backend/catalog/heap /* * This function returns a Form_pg_attribute pointer for a system attribute. -@@ -185,6 +197,18 @@ SystemAttributeByName(const char *attnam +@@ -185,6 +196,18 @@ SystemAttributeByName(const char *attnam return NULL; } @@ -765,7 +757,7 @@ diff -rpNU3 base/src/backend/catalog/heap.c sepgsql-new/src/backend/catalog/heap /* ---------------------------------------------------------------- * XXX END OF UGLY HARD CODED BADNESS XXX -@@ -468,7 +492,8 @@ AddNewAttributeTuples(Oid new_rel_oid, +@@ -468,7 +491,8 @@ AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, char relkind, bool oidislocal, @@ -775,12 +767,12 @@ diff -rpNU3 base/src/backend/catalog/heap.c sepgsql-new/src/backend/catalog/heap { const Form_pg_attribute *dpp; int i; -@@ -493,16 +518,40 @@ AddNewAttributeTuples(Oid new_rel_oid, +@@ -493,16 +517,40 @@ AddNewAttributeTuples(Oid new_rel_oid, dpp = tupdesc->attrs; for (i = 0; i < natts; i++) { + ListCell *l; -+ Oid attselabel = InvalidOid; ++ Oid attselabel = InvalidOid; + /* Fill in the correct relation OID */ (*dpp)->attrelid = new_rel_oid; @@ -796,7 +788,7 @@ diff -rpNU3 base/src/backend/catalog/heap.c sepgsql-new/src/backend/catalog/heap + if (defel->defname && + strcmp(defel->defname, NameStr((*dpp)->attname)) == 0) + { -+ attselabel = sepgsqlInputGivenSecLabel(defel); ++ attselabel = intVal(defel->arg); + break; + } + } @@ -816,7 +808,7 @@ diff -rpNU3 base/src/backend/catalog/heap.c sepgsql-new/src/backend/catalog/heap simple_heap_insert(rel, tup); -@@ -538,6 +587,7 @@ AddNewAttributeTuples(Oid new_rel_oid, +@@ -538,6 +586,7 @@ AddNewAttributeTuples(Oid new_rel_oid, tup = heap_addheader(Natts_pg_attribute, false, @@ -824,7 +816,7 @@ diff -rpNU3 base/src/backend/catalog/heap.c sepgsql-new/src/backend/catalog/heap ATTRIBUTE_TUPLE_SIZE, (void *) *dpp); attStruct = (Form_pg_attribute) GETSTRUCT(tup); -@@ -593,7 +643,8 @@ void +@@ -593,7 +642,8 @@ void InsertPgClassTuple(Relation pg_class_desc, Relation new_rel_desc, Oid new_rel_oid, @@ -834,7 +826,7 @@ diff -rpNU3 base/src/backend/catalog/heap.c sepgsql-new/src/backend/catalog/heap { Form_pg_class rd_rel = new_rel_desc->rd_rel; Datum values[Natts_pg_class]; -@@ -644,11 +695,23 @@ InsertPgClassTuple(Relation pg_class_des +@@ -644,11 +694,23 @@ InsertPgClassTuple(Relation pg_class_des */ HeapTupleSetOid(tup, new_rel_oid); @@ -858,7 +850,7 @@ diff -rpNU3 base/src/backend/catalog/heap.c sepgsql-new/src/backend/catalog/heap heap_freetuple(tup); } -@@ -666,9 +729,12 @@ AddNewRelationTuple(Relation pg_class_de +@@ -666,9 +728,12 @@ AddNewRelationTuple(Relation pg_class_de Oid new_type_oid, Oid relowner, char relkind, @@ -872,7 +864,7 @@ diff -rpNU3 base/src/backend/catalog/heap.c sepgsql-new/src/backend/catalog/heap /* * first we update some of the information in our uncataloged relation's -@@ -725,8 +791,21 @@ AddNewRelationTuple(Relation pg_class_de +@@ -725,8 +790,21 @@ AddNewRelationTuple(Relation pg_class_de new_rel_desc->rd_att->tdtypeid = new_type_oid; @@ -883,7 +875,7 @@ diff -rpNU3 base/src/backend/catalog/heap.c sepgsql-new/src/backend/catalog/heap + + if (!defel->defname) + { -+ relselabel = sepgsqlInputGivenSecLabel(defel); ++ relselabel = intVal(defel->arg); + break; + } + } @@ -895,7 +887,7 @@ diff -rpNU3 base/src/backend/catalog/heap.c sepgsql-new/src/backend/catalog/heap } -@@ -794,7 +873,8 @@ heap_create_with_catalog(const char *rel +@@ -794,7 +872,8 @@ heap_create_with_catalog(const char *rel int oidinhcount, OnCommitAction oncommit, Datum reloptions, @@ -905,7 +897,7 @@ diff -rpNU3 base/src/backend/catalog/heap.c sepgsql-new/src/backend/catalog/heap { Relation pg_class_desc; Relation new_rel_desc; -@@ -968,13 +1048,20 @@ heap_create_with_catalog(const char *rel +@@ -968,13 +1047,20 @@ heap_create_with_catalog(const char *rel new_type_oid, ownerid, relkind, @@ -971,7 +963,7 @@ diff -rpNU3 base/src/backend/catalog/index.c sepgsql-new/src/backend/catalog/ind heap_close(pg_class, RowExclusiveLock); diff -rpNU3 base/src/backend/catalog/namespace.c sepgsql-new/src/backend/catalog/namespace.c --- base/src/backend/catalog/namespace.c 2008-01-07 23:51:33.000000000 +0900 -+++ sepgsql-new/src/backend/catalog/namespace.c 2009-05-20 17:35:01.000000000 +0900 ++++ sepgsql-new/src/backend/catalog/namespace.c 2009-09-10 20:24:37.000000000 +0900 @@ -37,6 +37,7 @@ #include "commands/dbcommands.h" #include "miscadmin.h" @@ -980,7 +972,29 @@ diff -rpNU3 base/src/backend/catalog/namespace.c sepgsql-new/src/backend/catalog #include "storage/backendid.h" #include "storage/ipc.h" #include "utils/acl.h" -@@ -2797,6 +2798,7 @@ static void +@@ -2629,7 +2630,9 @@ InitTempTableNamespace(void) + * temp tables. This works because the places that access the temp + * namespace for my own backend skip permissions checks on it. + */ +- namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID); ++ namespaceId = NamespaceCreate(namespaceName, ++ BOOTSTRAP_SUPERUSERID, ++ InvalidOid); + /* Advance command counter to make namespace visible */ + CommandCounterIncrement(); + } +@@ -2655,7 +2658,9 @@ InitTempTableNamespace(void) + 0, 0, 0); + if (!OidIsValid(toastspaceId)) + { +- toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID); ++ toastspaceId = NamespaceCreate(namespaceName, ++ BOOTSTRAP_SUPERUSERID, ++ InvalidOid); + /* Advance command counter to make namespace visible */ + CommandCounterIncrement(); + } +@@ -2797,6 +2802,7 @@ static void RemoveTempRelations(Oid tempNamespaceId) { ObjectAddress object; @@ -988,7 +1002,7 @@ diff -rpNU3 base/src/backend/catalog/namespace.c sepgsql-new/src/backend/catalog /* * We want to get rid of everything in the target namespace, but not the -@@ -2808,7 +2810,22 @@ RemoveTempRelations(Oid tempNamespaceId) +@@ -2808,7 +2814,22 @@ RemoveTempRelations(Oid tempNamespaceId) object.objectId = tempNamespaceId; object.objectSubId = 0; @@ -1056,6 +1070,27 @@ diff -rpNU3 base/src/backend/catalog/pg_largeobject.c sepgsql-new/src/backend/ca simple_heap_delete(pg_largeobject, &tuple->t_self); found = true; } +diff -rpNU3 base/src/backend/catalog/pg_namespace.c sepgsql-new/src/backend/catalog/pg_namespace.c +--- base/src/backend/catalog/pg_namespace.c 2008-01-07 23:51:33.000000000 +0900 ++++ sepgsql-new/src/backend/catalog/pg_namespace.c 2009-06-19 15:02:12.000000000 +0900 +@@ -27,7 +27,7 @@ + * --------------- + */ + Oid +-NamespaceCreate(const char *nspName, Oid ownerId) ++NamespaceCreate(const char *nspName, Oid ownerId, Oid secid) + { + Relation nspdesc; + HeapTuple tup; +@@ -65,6 +65,8 @@ NamespaceCreate(const char *nspName, Oid + tupDesc = nspdesc->rd_att; + + tup = heap_formtuple(tupDesc, values, nulls); ++ if (HeapTupleHasSecLabel(tup)) ++ HeapTupleSetSecLabel(tup, secid); + + nspoid = simple_heap_insert(nspdesc, tup); + Assert(OidIsValid(nspoid)); diff -rpNU3 base/src/backend/catalog/pg_proc.c sepgsql-new/src/backend/catalog/pg_proc.c --- base/src/backend/catalog/pg_proc.c 2008-01-07 23:51:33.000000000 +0900 +++ sepgsql-new/src/backend/catalog/pg_proc.c 2009-03-13 18:14:33.000000000 +0900 @@ -1107,8 +1142,8 @@ diff -rpNU3 base/src/backend/catalog/pg_proc.c sepgsql-new/src/backend/catalog/p } diff -rpNU3 base/src/backend/catalog/pg_security.c sepgsql-new/src/backend/catalog/pg_security.c --- base/src/backend/catalog/pg_security.c 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/backend/catalog/pg_security.c 2009-05-20 17:08:02.000000000 +0900 -@@ -0,0 +1,283 @@ ++++ sepgsql-new/src/backend/catalog/pg_security.c 2009-06-10 17:43:08.000000000 +0900 +@@ -0,0 +1,299 @@ +/* + * src/backend/catalog/pg_security.c + * routines to support security label management @@ -1139,7 +1174,7 @@ diff -rpNU3 base/src/backend/catalog/pg_security.c sepgsql-new/src/backend/catal +static char * +securityMetaSecurityLabel(void) +{ -+ return sepgsqlMetaSecurityLabel(); ++ return sepgsqlMetaSecurityLabel(true); +} + +typedef struct earlySecLabel @@ -1152,32 +1187,31 @@ diff -rpNU3 base/src/backend/catalog/pg_security.c sepgsql-new/src/backend/catal +static earlySecLabel *earlySecLabelList = NULL; + +static Oid -+earlyLookupSecurityId(const char *seclabel) ++earlyInputSecurityAttr(const char *seclabel) +{ ++ static Oid dummySecid = SecurityRelationId; + earlySecLabel *es; -+ Oid minsecid = SecurityRelationId; + + for (es = earlySecLabelList; es; es = es->next) + { + if (strcmp(seclabel, es->seclabel) == 0) + return es->secid; -+ if (es->secid < minsecid) -+ minsecid = es->secid; + } + + /* not found */ -+ es = MemoryContextAllocZero(TopMemoryContext, -+ sizeof(*es) + strlen(seclabel)); -+ es->next = earlySecLabelList; -+ es->secid = minsecid - 1; ++ es = MemoryContextAlloc(TopMemoryContext, ++ sizeof(*es) + strlen(seclabel)); ++ es->secid = --dummySecid; + strcpy(es->seclabel, seclabel); ++ ++ es->next = earlySecLabelList; + earlySecLabelList = es; + + return es->secid; +} + +static char * -+earlyLookupSecurityLabel(Oid secid) ++earlyOutputSecurityAttr(Oid secid) +{ + earlySecLabel *es; + @@ -1186,8 +1220,7 @@ diff -rpNU3 base/src/backend/catalog/pg_security.c sepgsql-new/src/backend/catal + if (es->secid == secid) + return pstrdup(es->seclabel); + } -+ -+ return NULL; /* not found */ ++ return NULL; /* Not found */ +} + +void @@ -1197,7 +1230,7 @@ diff -rpNU3 base/src/backend/catalog/pg_security.c sepgsql-new/src/backend/catal + CatalogIndexState ind; + HeapTuple tuple; + earlySecLabel *es; -+ Oid labelSid; ++ Oid labelSid = InvalidOid; + Datum values[Natts_pg_security]; + bool nulls[Natts_pg_security]; + char *meta_label; @@ -1207,15 +1240,13 @@ diff -rpNU3 base/src/backend/catalog/pg_security.c sepgsql-new/src/backend/catal + + StartTransactionCommand(); + ++ meta_label = securityMetaSecurityLabel(); ++ if (meta_label) ++ labelSid = securityTransSecLabelIn(SecurityRelationId, meta_label); ++ + rel = heap_open(SecurityRelationId, RowExclusiveLock); + ind = CatalogOpenIndexes(rel); + -+ if (RelationGetDescr(rel)->tdhasseclabel && -+ (meta_label = securityMetaSecurityLabel()) != NULL) -+ labelSid = earlyLookupSecurityId(meta_label); -+ else -+ labelSid = InvalidOid; -+ + for (es = earlySecLabelList; es; es = es->next) + { + memset(nulls, false, sizeof(nulls)); @@ -1241,8 +1272,11 @@ diff -rpNU3 base/src/backend/catalog/pg_security.c sepgsql-new/src/backend/catal + CommitTransactionCommand(); +} + -+Oid -+securityLookupSecurityId(const char *seclabel) ++/* ++ * InputSecurityAttr ++ */ ++static Oid ++InputSecurityAttr(Oid relid, const char *seclabel) +{ + Relation rel; + CatalogIndexState ind; @@ -1254,7 +1288,7 @@ diff -rpNU3 base/src/backend/catalog/pg_security.c sepgsql-new/src/backend/catal + char *meta_label; + + if (IsBootstrapProcessingMode()) -+ return earlyLookupSecurityId(seclabel); ++ return earlyInputSecurityAttr(seclabel); + /* + * lookup syscache at first + */ @@ -1285,7 +1319,7 @@ diff -rpNU3 base/src/backend/catalog/pg_security.c sepgsql-new/src/backend/catal + else + { + labelOid = GetNewOid(rel); -+ labelSid = securityLookupSecurityId(meta_label); ++ labelSid = securityTransSecLabelIn(SecurityRelationId, meta_label); + } + } + else @@ -1331,19 +1365,16 @@ diff -rpNU3 base/src/backend/catalog/pg_security.c sepgsql-new/src/backend/catal + return labelOid; +} + -+char * -+securityLookupSecurityLabel(Oid secid) ++static char * ++OutputSecurityAttr(Oid relid, Oid secid) +{ + HeapTuple tuple; + Datum labelTxt; + char *label; + bool isnull; + -+ if (!OidIsValid(secid)) -+ return NULL; -+ + if (IsBootstrapProcessingMode()) -+ return earlyLookupSecurityLabel(secid); ++ return earlyOutputSecurityAttr(secid); + + tuple = SearchSysCache(SECURITYOID, + ObjectIdGetDatum(secid), @@ -1362,35 +1393,55 @@ diff -rpNU3 base/src/backend/catalog/pg_security.c sepgsql-new/src/backend/catal +} + +/* -+ * "security_label" system column related stuffs ++ * input/output handler + */ +Oid -+securityTransSecLabelIn(char *seclabel) ++securityRawSecLabelIn(Oid relid, char *seclabel) +{ -+ char *rawlabel = sepgsqlSecurityLabelTransIn(seclabel); ++ seclabel = sepgsqlRawSecLabelIn(seclabel); + -+ return securityLookupSecurityId(rawlabel); ++ return InputSecurityAttr(relid, seclabel); +} + +char * -+securityTransSecLabelOut(Oid secid) ++securityRawSecLabelOut(Oid relid, Oid secid) +{ -+ char *rawlabel = securityLookupSecurityLabel(secid); -+ char *seclabel; ++ char *seclabel = OutputSecurityAttr(relid, secid); + -+ seclabel = sepgsqlSecurityLabelTransOut(rawlabel); -+ if (!seclabel) -+ seclabel = pstrdup("unlabeled"); -+ -+ return seclabel; ++ return sepgsqlRawSecLabelOut(seclabel); +} + ++ ++Oid ++securityTransSecLabelIn(Oid relid, char *seclabel) ++{ ++ seclabel = sepgsqlTransSecLabelIn(seclabel); ++ ++ return securityRawSecLabelIn(relid, seclabel); ++} ++ ++char * ++securityTransSecLabelOut(Oid relid, Oid secid) ++{ ++ char *seclabel = securityRawSecLabelOut(relid, secid); ++ ++ return sepgsqlTransSecLabelOut(seclabel); ++} ++ ++/* ++ * Output handler for system columns ++ */ +Datum +securityHeapGetSecLabelSysattr(HeapTuple tuple) +{ + Oid secid = HeapTupleGetSecLabel(tuple); ++ char *seclabel; + -+ return CStringGetTextDatum(securityTransSecLabelOut(secid)); ++ seclabel = securityTransSecLabelOut(tuple->t_tableOid, secid); ++ if (!seclabel) ++ seclabel = pstrdup("unlabeled"); ++ ++ return CStringGetTextDatum(seclabel); +} diff -rpNU3 base/src/backend/catalog/toasting.c sepgsql-new/src/backend/catalog/toasting.c --- base/src/backend/catalog/toasting.c 2008-01-07 23:51:33.000000000 +0900 @@ -1405,6 +1456,42 @@ diff -rpNU3 base/src/backend/catalog/toasting.c sepgsql-new/src/backend/catalog/ /* make the toast relation visible, else index creation will fail */ CommandCounterIncrement(); +diff -rpNU3 base/src/backend/commands/alter.c sepgsql-new/src/backend/commands/alter.c +--- base/src/backend/commands/alter.c 2008-03-19 09:48:23.000000000 +0900 ++++ sepgsql-new/src/backend/commands/alter.c 2009-06-19 15:02:12.000000000 +0900 +@@ -269,3 +269,32 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt) + (int) stmt->objectType); + } + } ++ ++void ++ExecAlterSecLabelStmt(AlterSecLabelStmt *stmt) ++{ ++ DefElem *seclabel = (DefElem *)stmt->secLabel; ++ ++ switch (stmt->objectType) ++ { ++ case OBJECT_DATABASE: ++ AlterDatabaseSecLabel(strVal(linitial(stmt->object)), seclabel); ++ break; ++ case OBJECT_SCHEMA: ++ AlterSchemaSecLabel(strVal(linitial(stmt->object)), seclabel); ++ break; ++ case OBJECT_TABLE: ++ case OBJECT_SEQUENCE: ++ case OBJECT_COLUMN: ++ CheckRelationOwnership(stmt->relation, false); ++ AlterRelationSecLabel(stmt->relation, stmt->subname, ++ stmt->objectType, seclabel); ++ break; ++ case OBJECT_FUNCTION: ++ AlterFunctionSecLabel(stmt->object, stmt->objarg, seclabel); ++ break; ++ default: ++ elog(ERROR, "unrecognized AlterSecLabelStmt type: %d", ++ (int) stmt->objectType); ++ } ++} diff -rpNU3 base/src/backend/commands/cluster.c sepgsql-new/src/backend/commands/cluster.c --- base/src/backend/commands/cluster.c 2008-02-03 01:11:28.000000000 +0900 +++ sepgsql-new/src/backend/commands/cluster.c 2009-03-13 18:14:33.000000000 +0900 @@ -1438,7 +1525,7 @@ diff -rpNU3 base/src/backend/commands/cluster.c sepgsql-new/src/backend/commands rewrite_heap_tuple(rwstate, tuple, copiedTuple); diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/copy.c --- base/src/backend/commands/copy.c 2008-01-07 23:51:33.000000000 +0900 -+++ sepgsql-new/src/backend/commands/copy.c 2009-03-13 18:14:33.000000000 +0900 ++++ sepgsql-new/src/backend/commands/copy.c 2009-06-10 17:43:08.000000000 +0900 @@ -22,7 +22,9 @@ #include "access/heapam.h" @@ -1638,12 +1725,13 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co { bool need_delim = false; FmgrInfo *out_functions = cstate->out_functions; -@@ -1464,8 +1541,10 @@ CopyOneRowTo(CopyState cstate, Oid tuple +@@ -1464,8 +1541,11 @@ CopyOneRowTo(CopyState cstate, Oid tuple foreach(cur, cstate->attnumlist) { int attnum = lfirst_int(cur); - Datum value = values[attnum - 1]; - bool isnull = nulls[attnum - 1]; ++ Oid relid; + Datum value; + bool isnull; + bool force_quot; @@ -1651,14 +1739,15 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co if (!cstate->binary) { -@@ -1474,6 +1553,23 @@ CopyOneRowTo(CopyState cstate, Oid tuple +@@ -1474,6 +1554,24 @@ CopyOneRowTo(CopyState cstate, Oid tuple need_delim = true; } + switch (attnum) + { + case SecurityLabelAttributeNumber: -+ value = CStringGetTextDatum(securityTransSecLabelOut(secLabelId)); ++ relid = RelationGetRelid(cstate->rel); ++ value = CStringGetTextDatum(securityTransSecLabelOut(relid, secLabelId)); + isnull = false; + force_quot = cstate->seclabel_force_quot; + out_fmgr = &cstate->seclabel_out_function; @@ -1675,7 +1764,7 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co if (isnull) { if (!cstate->binary) -@@ -1485,11 +1581,9 @@ CopyOneRowTo(CopyState cstate, Oid tuple +@@ -1485,11 +1583,9 @@ CopyOneRowTo(CopyState cstate, Oid tuple { if (!cstate->binary) { @@ -1689,7 +1778,7 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co list_length(cstate->attnumlist) == 1); else CopyAttributeOutText(cstate, string); -@@ -1498,8 +1592,7 @@ CopyOneRowTo(CopyState cstate, Oid tuple +@@ -1498,8 +1594,7 @@ CopyOneRowTo(CopyState cstate, Oid tuple { bytea *outputbytes; @@ -1699,7 +1788,7 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co CopySendInt32(cstate, VARSIZE(outputbytes) - VARHDRSZ); CopySendData(cstate, VARDATA(outputbytes), VARSIZE(outputbytes) - VARHDRSZ); -@@ -1633,8 +1726,10 @@ CopyFrom(CopyState cstate) +@@ -1633,8 +1728,10 @@ CopyFrom(CopyState cstate) num_defaults; FmgrInfo *in_functions; FmgrInfo oid_in_function; @@ -1710,7 +1799,7 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co int attnum; int i; Oid in_func_oid; -@@ -1737,6 +1832,9 @@ CopyFrom(CopyState cstate) +@@ -1737,6 +1834,9 @@ CopyFrom(CopyState cstate) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is a directory", cstate->filename))); @@ -1720,7 +1809,7 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co } tupDesc = RelationGetDescr(cstate->rel); -@@ -1872,6 +1970,18 @@ CopyFrom(CopyState cstate) +@@ -1872,6 +1972,18 @@ CopyFrom(CopyState cstate) fmgr_info(in_func_oid, &oid_in_function); } @@ -1739,7 +1828,7 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co values = (Datum *) palloc(num_phys_attrs * sizeof(Datum)); nulls = (char *) palloc(num_phys_attrs * sizeof(char)); -@@ -1904,6 +2014,7 @@ CopyFrom(CopyState cstate) +@@ -1904,6 +2016,7 @@ CopyFrom(CopyState cstate) { bool skip_tuple; Oid loaded_oid = InvalidOid; @@ -1747,7 +1836,7 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co CHECK_FOR_INTERRUPTS(); -@@ -1975,31 +2086,55 @@ CopyFrom(CopyState cstate) +@@ -1975,31 +2088,56 @@ CopyFrom(CopyState cstate) /* Loop to read the user attributes on the line. */ foreach(cur, cstate->attnumlist) { @@ -1796,7 +1885,8 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co + seclabel_typioparam, + attForm->atttypmod); + loaded_seclabel -+ = securityTransSecLabelIn(TextDatumGetCString(dat)); ++ = securityTransSecLabelIn(RelationGetRelid(cstate->rel), ++ TextDatumGetCString(dat)); + break; + + default: @@ -1817,7 +1907,7 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co cstate->cur_attname = NULL; cstate->cur_attval = NULL; } -@@ -2045,18 +2180,41 @@ CopyFrom(CopyState cstate) +@@ -2045,18 +2183,42 @@ CopyFrom(CopyState cstate) i = 0; foreach(cur, cstate->attnumlist) { @@ -1852,7 +1942,8 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co + &isnull); + if (!isnull) + loaded_seclabel -+ = securityTransSecLabelIn(TextDatumGetCString(dat)); ++ = securityTransSecLabelIn(RelationGetRelid(cstate->rel), ++ TextDatumGetCString(dat)); + break; + + default: @@ -1867,7 +1958,7 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co cstate->cur_attname = NULL; } } -@@ -2080,6 +2238,9 @@ CopyFrom(CopyState cstate) +@@ -2080,6 +2242,9 @@ CopyFrom(CopyState cstate) if (cstate->oids && file_has_oids) HeapTupleSetOid(tuple, loaded_oid); @@ -1877,7 +1968,7 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co /* Triggers and stuff need to be invoked in query context. */ MemoryContextSwitchTo(oldcontext); -@@ -2102,6 +2263,9 @@ CopyFrom(CopyState cstate) +@@ -2102,6 +2267,9 @@ CopyFrom(CopyState cstate) } } @@ -1887,7 +1978,7 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co if (!skip_tuple) { /* Place tuple in tuple slot */ -@@ -3366,6 +3530,13 @@ CopyGetAttnums(TupleDesc tupDesc, Relati +@@ -3366,6 +3534,13 @@ CopyGetAttnums(TupleDesc tupDesc, Relati } if (attnum == InvalidAttrNumber) { @@ -1901,7 +1992,7 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co if (rel != NULL) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), -@@ -3413,7 +3584,8 @@ copy_dest_receive(TupleTableSlot *slot, +@@ -3413,7 +3588,8 @@ copy_dest_receive(TupleTableSlot *slot, slot_getallattrs(slot); /* And send the data */ @@ -1913,7 +2004,7 @@ diff -rpNU3 base/src/backend/commands/copy.c sepgsql-new/src/backend/commands/co /* diff -rpNU3 base/src/backend/commands/dbcommands.c sepgsql-new/src/backend/commands/dbcommands.c --- base/src/backend/commands/dbcommands.c 2008-11-05 09:57:00.000000000 +0900 -+++ sepgsql-new/src/backend/commands/dbcommands.c 2009-03-13 18:14:33.000000000 +0900 ++++ sepgsql-new/src/backend/commands/dbcommands.c 2009-06-19 15:02:12.000000000 +0900 @@ -40,6 +40,7 @@ #include "miscadmin.h" #include "pgstat.h" @@ -1951,7 +2042,7 @@ diff -rpNU3 base/src/backend/commands/dbcommands.c sepgsql-new/src/backend/comma HeapTupleSetOid(tuple, dboid); + if (dselabel) + { -+ Oid secid = sepgsqlInputGivenSecLabel(dselabel); ++ Oid secid = sepgsqlGivenSecLabelIn(DatabaseRelationId, dselabel); + if (!HeapTupleHasSecLabel(tuple)) + elog(ERROR, "Unable to assign security label on \"%s\"", @@ -1961,48 +2052,71 @@ diff -rpNU3 base/src/backend/commands/dbcommands.c sepgsql-new/src/backend/comma simple_heap_insert(pg_database_rel, tuple); /* Update indexes */ -@@ -858,6 +876,7 @@ AlterDatabase(AlterDatabaseStmt *stmt) - ListCell *option; - int connlimit = -1; - DefElem *dconnlimit = NULL; -+ DefElem *dselabel = NULL; - Datum new_record[Natts_pg_database]; - char new_record_nulls[Natts_pg_database]; - char new_record_repl[Natts_pg_database]; -@@ -875,6 +894,14 @@ AlterDatabase(AlterDatabaseStmt *stmt) - errmsg("conflicting or redundant options"))); - dconnlimit = defel; - } -+ else if (strcmp(defel->defname, "security_context") == 0) -+ { -+ if (dselabel) -+ ereport(ERROR, -+ (errcode(ERRCODE_SYNTAX_ERROR), -+ errmsg("conflicting or redundant options"))); -+ dselabel = defel; -+ } - else - elog(ERROR, "option \"%s\" not recognized", - defel->defname); -@@ -920,6 +947,15 @@ AlterDatabase(AlterDatabaseStmt *stmt) +@@ -1143,6 +1161,61 @@ AlterDatabaseOwner(const char *dbname, O + */ + } - newtuple = heap_modifytuple(tuple, RelationGetDescr(rel), new_record, - new_record_nulls, new_record_repl); -+ if (dselabel) -+ { -+ Oid secid = sepgsqlInputGivenSecLabel(dselabel); ++/* ++ * ALTER DATABASE name SECURITY_LABEL [=] newlabel ++ */ ++void ++AlterDatabaseSecLabel(const char *dbname, DefElem *seclabel) ++{ ++ Relation rel; ++ HeapTuple tuple, newtup; ++ ScanKeyData scankey; ++ SysScanDesc scan; ++ Oid secid; ++ bool replaces[Natts_pg_database]; + -+ if (!HeapTupleHasSecLabel(newtuple)) -+ elog(ERROR, "Unable to assign security label on \"%s\"", -+ RelationGetRelationName(rel)); -+ HeapTupleSetSecLabel(newtuple, secid); -+ } - simple_heap_update(rel, &tuple->t_self, newtuple); ++ /* Translate text representation to security id */ ++ secid = sepgsqlGivenSecLabelIn(DatabaseRelationId, seclabel); ++ ++ /* Fetch the old tuple */ ++ rel = heap_open(DatabaseRelationId, RowExclusiveLock); ++ ScanKeyInit(&scankey, ++ Anum_pg_database_datname, ++ BTEqualStrategyNumber, F_NAMEEQ, ++ NameGetDatum(dbname)); ++ scan = systable_beginscan(rel, DatabaseNameIndexId, true, ++ SnapshotNow, 1, &scankey); ++ tuple = systable_getnext(scan); ++ if (!HeapTupleIsValid(tuple)) ++ ereport(ERROR, ++ (errcode(ERRCODE_UNDEFINED_DATABASE), ++ errmsg("database \"%s\" does not exist", dbname))); ++ ++ /* check DAC permission */ ++ if (!pg_database_ownercheck(HeapTupleGetOid(tuple), GetUserId())) ++ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE, dbname); ++ /* ++ * NOTE: we should not use heap_copytuple() here because of ++ * possibility that the fetched tuple was inserted while ++ * SE-PostgreSQL is disabled and it does not have a field ++ * to store security label. ++ */ ++ memset(replaces, false, sizeof(replaces)); ++ newtup = heap_modify_tuple(tuple, RelationGetDescr(rel), ++ NULL, NULL, replaces); ++ if (!HeapTupleHasSecLabel(newtup)) ++ elog(ERROR, "Unable to set security label on tuples in pg_database"); ++ HeapTupleSetSecLabel(newtup, secid); ++ ++ simple_heap_update(rel, &newtup->t_self, newtup); ++ CatalogUpdateIndexes(rel, newtup); ++ ++ heap_freetuple(newtup); ++ ++ systable_endscan(scan); ++ ++ heap_close(rel, RowExclusiveLock); ++} - /* Update indexes */ + /* + * Helper functions diff -rpNU3 base/src/backend/commands/functioncmds.c sepgsql-new/src/backend/commands/functioncmds.c --- base/src/backend/commands/functioncmds.c 2009-03-15 17:47:25.000000000 +0900 -+++ sepgsql-new/src/backend/commands/functioncmds.c 2009-03-15 17:58:10.000000000 +0900 ++++ sepgsql-new/src/backend/commands/functioncmds.c 2009-06-19 15:02:12.000000000 +0900 @@ -47,6 +47,7 @@ #include "miscadmin.h" #include "parser/parse_func.h" @@ -2011,31 +2125,7 @@ diff -rpNU3 base/src/backend/commands/functioncmds.c sepgsql-new/src/backend/com #include "utils/acl.h" #include "utils/builtins.h" #include "utils/fmgroids.h" -@@ -295,7 +296,8 @@ compute_common_attribute(DefElem *defel, - DefElem **security_item, - List **set_items, - DefElem **cost_item, -- DefElem **rows_item) -+ DefElem **rows_item, -+ DefElem **selabel_item) - { - if (strcmp(defel->defname, "volatility") == 0) - { -@@ -336,6 +338,13 @@ compute_common_attribute(DefElem *defel, - - *rows_item = defel; - } -+ else if (strcmp(defel->defname, "security_context") == 0) -+ { -+ if (*selabel_item) -+ goto duplicate_error; -+ -+ *selabel_item = defel; -+ } - else - return false; - -@@ -412,7 +421,8 @@ compute_attributes_sql_style(List *optio +@@ -412,7 +413,8 @@ compute_attributes_sql_style(List *optio bool *security_definer, ArrayType **proconfig, float4 *procost, @@ -2045,7 +2135,7 @@ diff -rpNU3 base/src/backend/commands/functioncmds.c sepgsql-new/src/backend/com { ListCell *option; DefElem *as_item = NULL; -@@ -423,6 +433,7 @@ compute_attributes_sql_style(List *optio +@@ -423,6 +425,7 @@ compute_attributes_sql_style(List *optio List *set_items = NIL; DefElem *cost_item = NULL; DefElem *rows_item = NULL; @@ -2053,26 +2143,31 @@ diff -rpNU3 base/src/backend/commands/functioncmds.c sepgsql-new/src/backend/com foreach(option, options) { -@@ -450,7 +461,8 @@ compute_attributes_sql_style(List *optio - &security_item, - &set_items, - &cost_item, -- &rows_item)) -+ &rows_item, -+ &selabel_item)) - { - /* recognized common option */ - continue; -@@ -506,6 +518,8 @@ compute_attributes_sql_style(List *optio +@@ -444,6 +447,14 @@ compute_attributes_sql_style(List *optio + errmsg("conflicting or redundant options"))); + language_item = defel; + } ++ else if (strcmp(defel->defname, "security_context") == 0) ++ { ++ if (selabel_item) ++ ereport(ERROR, ++ (errcode(ERRCODE_SYNTAX_ERROR), ++ errmsg("conflicting or redundant options"))); ++ selabel_item = defel; ++ } + else if (compute_common_attribute(defel, + &volatility_item, + &strict_item, +@@ -506,6 +517,8 @@ compute_attributes_sql_style(List *optio (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("ROWS must be positive"))); } + if (selabel_item) -+ *proselabel = sepgsqlInputGivenSecLabel(selabel_item); ++ *proselabel = sepgsqlGivenSecLabelIn(ProcedureRelationId, selabel_item); } -@@ -621,6 +635,7 @@ CreateFunction(CreateFunctionStmt *stmt) +@@ -621,6 +634,7 @@ CreateFunction(CreateFunctionStmt *stmt) ArrayType *proconfig; float4 procost; float4 prorows; @@ -2080,7 +2175,7 @@ diff -rpNU3 base/src/backend/commands/functioncmds.c sepgsql-new/src/backend/com HeapTuple languageTuple; Form_pg_language languageStruct; List *as_clause; -@@ -642,12 +657,13 @@ CreateFunction(CreateFunctionStmt *stmt) +@@ -642,12 +656,13 @@ CreateFunction(CreateFunctionStmt *stmt) proconfig = NULL; procost = -1; /* indicates not set */ prorows = -1; /* indicates not set */ @@ -2095,7 +2190,7 @@ diff -rpNU3 base/src/backend/commands/functioncmds.c sepgsql-new/src/backend/com /* Convert language name to canonical case */ languageName = case_translate_language_name(language); -@@ -801,7 +817,8 @@ CreateFunction(CreateFunctionStmt *stmt) +@@ -801,7 +816,8 @@ CreateFunction(CreateFunctionStmt *stmt) PointerGetDatum(parameterNames), PointerGetDatum(proconfig), procost, @@ -2105,94 +2200,65 @@ diff -rpNU3 base/src/backend/commands/functioncmds.c sepgsql-new/src/backend/com } -@@ -1151,6 +1168,7 @@ AlterFunction(AlterFunctionStmt *stmt) - List *set_items = NIL; - DefElem *cost_item = NULL; - DefElem *rows_item = NULL; -+ DefElem *selabel_item = NULL; +@@ -1133,6 +1149,58 @@ AlterFunctionOwner_internal(Relation rel + } - rel = heap_open(ProcedureRelationId, RowExclusiveLock); - -@@ -1188,7 +1206,8 @@ AlterFunction(AlterFunctionStmt *stmt) - &security_def_item, - &set_items, - &cost_item, -- &rows_item) == false) -+ &rows_item, -+ &selabel_item) == false) - elog(ERROR, "option \"%s\" not recognized", defel->defname); - } - -@@ -1218,7 +1237,7 @@ AlterFunction(AlterFunctionStmt *stmt) - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("ROWS is not applicable when function does not return a set"))); - } -- if (set_items) -+ if (set_items || selabel_item) - { - Datum datum; - bool isnull; -@@ -1227,30 +1246,42 @@ AlterFunction(AlterFunctionStmt *stmt) - char repl_null[Natts_pg_proc]; - char repl_repl[Natts_pg_proc]; - -- /* extract existing proconfig setting */ -- datum = SysCacheGetAttr(PROCOID, tup, Anum_pg_proc_proconfig, &isnull); -- a = isnull ? NULL : DatumGetArrayTypeP(datum); -- -- /* update according to each SET or RESET item, left to right */ -- a = update_proconfig_value(a, set_items); -- -- /* update the tuple */ - memset(repl_repl, ' ', sizeof(repl_repl)); -- repl_repl[Anum_pg_proc_proconfig - 1] = 'r'; - -- if (a == NULL) -+ if (set_items) - { -- repl_val[Anum_pg_proc_proconfig - 1] = (Datum) 0; -- repl_null[Anum_pg_proc_proconfig - 1] = 'n'; -+ /* extract existing proconfig setting */ -+ datum = SysCacheGetAttr(PROCOID, tup, Anum_pg_proc_proconfig, &isnull); -+ a = isnull ? NULL : DatumGetArrayTypeP(datum); + /* ++ * ALTER FUNCTION name(args,...) SECURITY_LABEL [=] newlabel ++ */ ++void ++AlterFunctionSecLabel(List *name, List *argtypes, DefElem *seclabel) ++{ ++ Relation rel; ++ HeapTuple tuple, newtup; ++ Oid proid, secid; ++ bool replaces[Natts_pg_proc]; + -+ /* update according to each SET or RESET item, left to right */ -+ a = update_proconfig_value(a, set_items); ++ /* Translate text representation to security id */ ++ secid = sepgsqlGivenSecLabelIn(ProcedureRelationId, seclabel); + -+ /* update the tuple */ -+ repl_repl[Anum_pg_proc_proconfig - 1] = 'r'; ++ /* open pg_proc system catalog */ ++ rel = heap_open(ProcedureRelationId, RowExclusiveLock); + -+ if (a == NULL) -+ { -+ repl_val[Anum_pg_proc_proconfig - 1] = (Datum) 0; -+ repl_null[Anum_pg_proc_proconfig - 1] = 'n'; -+ } -+ else -+ { -+ repl_val[Anum_pg_proc_proconfig - 1] = PointerGetDatum(a); -+ repl_null[Anum_pg_proc_proconfig - 1] = ' '; -+ } - } -- else -+ tup = heap_modifytuple(tup, RelationGetDescr(rel), -+ repl_val, repl_null, repl_repl); -+ if (selabel_item) - { -- repl_val[Anum_pg_proc_proconfig - 1] = PointerGetDatum(a); -- repl_null[Anum_pg_proc_proconfig - 1] = ' '; -- } -+ Oid secid = sepgsqlInputGivenSecLabel(selabel_item); - -- tup = heap_modifytuple(tup, RelationGetDescr(rel), -- repl_val, repl_null, repl_repl); -+ if (!HeapTupleHasSecLabel(tup)) -+ elog(ERROR, "Unable to assign security label on \"%s\"", -+ RelationGetRelationName(rel)); -+ HeapTupleSetSecLabel(tup, secid); -+ } - } - - /* Do the update */ ++ proid = LookupFuncNameTypeNames(name, argtypes, false); ++ ++ tuple = SearchSysCache(PROCOID, ++ ObjectIdGetDatum(proid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for function %u", proid); ++ ++ /* DAC permission checks */ ++ if (!pg_proc_ownercheck(proid, GetUserId())) ++ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, ++ NameStr(((Form_pg_proc) GETSTRUCT(tuple))->proname)); ++ /* ++ * NOTE: we should not use heap_copytuple() here because of ++ * possibility that the fetched tuple was inserted while ++ * SE-PostgreSQL is disabled and it does not have a field ++ * to store security label. ++ */ ++ memset(replaces, false, sizeof(replaces)); ++ newtup = heap_modify_tuple(tuple, RelationGetDescr(rel), ++ NULL, NULL, replaces); ++ if (!HeapTupleHasSecLabel(newtup)) ++ elog(ERROR, "Unable to set security label on tuples in pg_proc"); ++ HeapTupleSetSecLabel(newtup, secid); ++ ++ simple_heap_update(rel, &newtup->t_self, newtup); ++ CatalogUpdateIndexes(rel, newtup); ++ ++ ReleaseSysCache(tuple); ++ ++ heap_freetuple(newtup); ++ ++ heap_close(rel, RowExclusiveLock); ++} ++ ++/* + * Implements the ALTER FUNCTION utility command (except for the + * RENAME and OWNER clauses, which are handled as part of the generic + * ALTER framework). diff -rpNU3 base/src/backend/commands/lockcmds.c sepgsql-new/src/backend/commands/lockcmds.c --- base/src/backend/commands/lockcmds.c 2008-01-07 23:51:33.000000000 +0900 +++ sepgsql-new/src/backend/commands/lockcmds.c 2009-05-20 17:08:02.000000000 +0900 @@ -2237,9 +2303,100 @@ diff -rpNU3 base/src/backend/commands/proclang.c sepgsql-new/src/backend/command } } else +diff -rpNU3 base/src/backend/commands/schemacmds.c sepgsql-new/src/backend/commands/schemacmds.c +--- base/src/backend/commands/schemacmds.c 2008-01-07 23:51:33.000000000 +0900 ++++ sepgsql-new/src/backend/commands/schemacmds.c 2009-06-19 15:02:12.000000000 +0900 +@@ -25,6 +25,7 @@ + #include "commands/schemacmds.h" + #include "miscadmin.h" + #include "parser/parse_utilcmd.h" ++#include "security/sepgsql.h" + #include "tcop/utility.h" + #include "utils/acl.h" + #include "utils/builtins.h" +@@ -48,6 +49,7 @@ CreateSchemaCommand(CreateSchemaStmt *st + ListCell *parsetree_item; + Oid owner_uid; + Oid saved_uid; ++ Oid secid = InvalidOid; + bool saved_secdefcxt; + AclResult aclresult; + +@@ -93,8 +95,15 @@ CreateSchemaCommand(CreateSchemaStmt *st + if (saved_uid != owner_uid) + SetUserIdAndContext(owner_uid, true); + ++ /* Explicitly given security label */ ++ if (stmt->secLabel) ++ { ++ secid = sepgsqlGivenSecLabelIn(NamespaceRelationId, ++ (DefElem *)stmt->secLabel); ++ } ++ + /* Create the schema's namespace */ +- namespaceId = NamespaceCreate(schemaName, owner_uid); ++ namespaceId = NamespaceCreate(schemaName, owner_uid, secid); + + /* Advance cmd counter to make the namespace visible */ + CommandCounterIncrement(); +@@ -412,3 +421,54 @@ AlterSchemaOwner_internal(HeapTuple tup, + } + + } ++ ++/* ++ * ALTER SCHEMA name SECURITY_LABEL [=] newlabel ++ */ ++void ++AlterSchemaSecLabel(const char *name, DefElem *seclabel) ++{ ++ Relation rel; ++ HeapTuple tuple, newtup; ++ Oid secid; ++ bool replaces[Natts_pg_namespace]; ++ ++ /* Translate text representation to security id */ ++ secid = sepgsqlGivenSecLabelIn(NamespaceRelationId, seclabel); ++ ++ /* open pg_namespace relation */ ++ rel = heap_open(NamespaceRelationId, RowExclusiveLock); ++ tuple = SearchSysCache(NAMESPACENAME, ++ CStringGetDatum(name), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ ereport(ERROR, ++ (errcode(ERRCODE_UNDEFINED_SCHEMA), ++ errmsg("schema \"%s\" does not exist", name))); ++ ++ /* DAC permission check */ ++ if (!pg_namespace_ownercheck(HeapTupleGetOid(tuple), GetUserId())) ++ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_NAMESPACE, ++ NameStr(((Form_pg_namespace) GETSTRUCT(tuple))->nspname)); ++ /* ++ * NOTE: we should not use heap_copytuple() here because of ++ * possibility that the fetched tuple was inserted while ++ * SE-PostgreSQL is disabled and it does not have a field ++ * to store security label. ++ */ ++ memset(replaces, false, sizeof(replaces)); ++ newtup = heap_modify_tuple(tuple, RelationGetDescr(rel), ++ NULL, NULL, replaces); ++ if (!HeapTupleHasSecLabel(newtup)) ++ elog(ERROR, "Unable to set security label on tuples in pg_namespace"); ++ HeapTupleSetSecLabel(newtup, secid); ++ ++ simple_heap_update(rel, &newtup->t_self, newtup); ++ CatalogUpdateIndexes(rel, newtup); ++ ++ heap_freetuple(newtup); ++ ++ ReleaseSysCache(tuple); ++ ++ heap_close(rel, RowExclusiveLock); ++} diff -rpNU3 base/src/backend/commands/sequence.c sepgsql-new/src/backend/commands/sequence.c --- base/src/backend/commands/sequence.c 2008-01-07 23:51:33.000000000 +0900 -+++ sepgsql-new/src/backend/commands/sequence.c 2009-05-20 17:08:02.000000000 +0900 ++++ sepgsql-new/src/backend/commands/sequence.c 2009-06-19 15:02:12.000000000 +0900 @@ -25,6 +25,7 @@ #include "commands/tablecmds.h" #include "miscadmin.h" @@ -2248,7 +2405,15 @@ diff -rpNU3 base/src/backend/commands/sequence.c sepgsql-new/src/backend/command #include "storage/proc.h" #include "utils/acl.h" #include "utils/builtins.h" -@@ -442,6 +443,9 @@ nextval_internal(Oid relid) +@@ -193,6 +194,7 @@ DefineSequence(CreateSeqStmt *seq) + stmt->options = list_make1(defWithOids(false)); + stmt->oncommit = ONCOMMIT_NOOP; + stmt->tablespacename = NULL; ++ stmt->secLabel = seq->secLabel; + + seqoid = DefineRelation(stmt, RELKIND_SEQUENCE); + +@@ -442,6 +444,9 @@ nextval_internal(Oid relid) errmsg("permission denied for sequence %s", RelationGetRelationName(seqrel)))); @@ -2258,7 +2423,7 @@ diff -rpNU3 base/src/backend/commands/sequence.c sepgsql-new/src/backend/command if (elm->last != elm->cached) /* some numbers were cached */ { Assert(elm->last_valid); -@@ -637,6 +641,9 @@ currval_oid(PG_FUNCTION_ARGS) +@@ -637,6 +642,9 @@ currval_oid(PG_FUNCTION_ARGS) errmsg("permission denied for sequence %s", RelationGetRelationName(seqrel)))); @@ -2268,7 +2433,7 @@ diff -rpNU3 base/src/backend/commands/sequence.c sepgsql-new/src/backend/command if (!elm->last_valid) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), -@@ -681,6 +688,9 @@ lastval(PG_FUNCTION_ARGS) +@@ -681,6 +689,9 @@ lastval(PG_FUNCTION_ARGS) errmsg("permission denied for sequence %s", RelationGetRelationName(seqrel)))); @@ -2278,7 +2443,7 @@ diff -rpNU3 base/src/backend/commands/sequence.c sepgsql-new/src/backend/command result = last_used_seq->last; relation_close(seqrel, NoLock); -@@ -717,6 +727,9 @@ do_setval(Oid relid, int64 next, bool is +@@ -717,6 +728,9 @@ do_setval(Oid relid, int64 next, bool is errmsg("permission denied for sequence %s", RelationGetRelationName(seqrel)))); @@ -2290,7 +2455,7 @@ diff -rpNU3 base/src/backend/commands/sequence.c sepgsql-new/src/backend/command diff -rpNU3 base/src/backend/commands/tablecmds.c sepgsql-new/src/backend/commands/tablecmds.c --- base/src/backend/commands/tablecmds.c 2008-11-05 09:57:00.000000000 +0900 -+++ sepgsql-new/src/backend/commands/tablecmds.c 2009-05-20 17:08:02.000000000 +0900 ++++ sepgsql-new/src/backend/commands/tablecmds.c 2009-06-19 15:02:12.000000000 +0900 @@ -57,6 +57,7 @@ #include "parser/parser.h" #include "rewrite/rewriteDefine.h" @@ -2299,15 +2464,7 @@ diff -rpNU3 base/src/backend/commands/tablecmds.c sepgsql-new/src/backend/comman #include "storage/smgr.h" #include "utils/acl.h" #include "utils/builtins.h" -@@ -259,6 +260,7 @@ static void ATExecEnableDisableRule(Rela - char fires_when); - static void ATExecAddInherit(Relation rel, RangeVar *parent); - static void ATExecDropInherit(Relation rel, RangeVar *parent); -+static void ATExecSetSecurityLabel(Relation rel, const char *name, DefElem *defel); - static void copy_relation_data(Relation rel, SMgrRelation dst); - - -@@ -281,6 +283,7 @@ DefineRelation(CreateStmt *stmt, char re +@@ -281,6 +282,7 @@ DefineRelation(CreateStmt *stmt, char re TupleDesc descriptor; List *inheritOids; List *old_constraints; @@ -2315,18 +2472,30 @@ diff -rpNU3 base/src/backend/commands/tablecmds.c sepgsql-new/src/backend/comman bool localHasOids; int parentOidCount; List *rawDefaults; -@@ -365,6 +368,10 @@ DefineRelation(CreateStmt *stmt, char re +@@ -365,6 +367,10 @@ DefineRelation(CreateStmt *stmt, char re schema = MergeAttributes(schema, stmt->inhRelations, stmt->relation->istemp, &inheritOids, &old_constraints, &parentOidCount); + /* + * SELinux: fetch SECURITY_CONTEXT = '...' from CREATE TABLE statement + */ -+ selblList = sepgsqlInputGivenSecLabelRelation(stmt); ++ selblList = sepgsqlParseCreateStmtSecLabelIn(stmt); /* * Create a relation descriptor from the relation schema and create the -@@ -434,7 +441,8 @@ DefineRelation(CreateStmt *stmt, char re +@@ -422,6 +428,11 @@ DefineRelation(CreateStmt *stmt, char re + } + } + ++ /* ++ * SELinux: fetch SECURITY_LABEL = '...' from CREATE TABLE ++ */ ++ selblList = sepgsqlParseCreateStmtSecLabelIn(stmt); ++ + relationId = heap_create_with_catalog(relname, + namespaceId, + tablespaceId, +@@ -434,7 +445,8 @@ DefineRelation(CreateStmt *stmt, char re parentOidCount, stmt->oncommit, reloptions, @@ -2336,7 +2505,7 @@ diff -rpNU3 base/src/backend/commands/tablecmds.c sepgsql-new/src/backend/comman StoreCatalogInheritance(relationId, inheritOids); -@@ -660,6 +668,9 @@ truncate_check_rel(Relation rel) +@@ -660,6 +672,9 @@ truncate_check_rel(Relation rel) errmsg("permission denied: \"%s\" is a system catalog", RelationGetRelationName(rel)))); @@ -2346,24 +2515,6 @@ diff -rpNU3 base/src/backend/commands/tablecmds.c sepgsql-new/src/backend/comman /* * We can never allow truncation of shared or nailed-in-cache relations, * because we can't support changing their relfilenode values. -@@ -2031,6 +2042,7 @@ ATPrepCmd(List **wqueue, Relation rel, A - case AT_DisableRule: - case AT_AddInherit: /* INHERIT / NO INHERIT */ - case AT_DropInherit: -+ case AT_SetSecurityLabel: - ATSimplePermissions(rel, false); - /* These commands never recurse */ - /* No command-specific prep needed */ -@@ -2253,6 +2265,9 @@ ATExecCmd(AlteredTableInfo *tab, Relatio - case AT_DropInherit: - ATExecDropInherit(rel, (RangeVar *) cmd->def); - break; -+ case AT_SetSecurityLabel: -+ ATExecSetSecurityLabel(rel, cmd->name, (DefElem *) cmd->def); -+ break; - default: /* oops */ - elog(ERROR, "unrecognized alter table type: %d", - (int) cmd->subtype); @@ -2591,11 +2606,14 @@ ATRewriteTable(AlteredTableInfo *tab, Oi if (newrel) { @@ -2408,102 +2559,135 @@ diff -rpNU3 base/src/backend/commands/tablecmds.c sepgsql-new/src/backend/comman /* * Look up the equality operators to use in the constraint. * -@@ -6515,6 +6541,95 @@ ATExecDropInherit(Relation rel, RangeVar - heap_close(parent_rel, NoLock); +@@ -6776,6 +6802,128 @@ AlterSeqNamespaces(Relation classRel, Re + relation_close(depRel, AccessShareLock); } -+void -+ATExecSetSecurityLabel(Relation rel, const char *attr_name, DefElem *defel) ++/* ++ * ALTER TABLE/SEQUENCE name SECURITY_LABEL [=] newlabel ++ * ALTER TABLE/SEQUENCE name ALTER column SECURITY_LABEL [=] newlabel ++ */ ++static void ++ExecRelationSetSecLabel(Oid relid, DefElem *seclabel) +{ -+ Relation class_rel; -+ Relation attr_rel; ++ Relation rel; + HeapTuple tuple, newtup; + Oid secid; ++ bool replaces[Natts_pg_class]; + -+ if (!sepgsqlIsEnabled()) ++ /* Translate text representation to security id */ ++ secid = sepgsqlGivenSecLabelIn(RelationRelationId, seclabel); ++ ++ rel = heap_open(RelationRelationId, RowExclusiveLock); ++ tuple = SearchSysCache(RELOID, ++ ObjectIdGetDatum(relid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for relation: %u", relid); ++ ++ memset(replaces, false, sizeof(replaces)); ++ newtup = heap_modify_tuple(tuple, RelationGetDescr(rel), ++ NULL, NULL, replaces); ++ ++ if (!HeapTupleHasSecLabel(newtup)) ++ elog(ERROR, "Unable to set security label on: %s", ++ NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname)); ++ HeapTupleSetSecLabel(newtup, secid); ++ ++ simple_heap_update(rel, &newtup->t_self, newtup); ++ ++ CatalogUpdateIndexes(rel, newtup); ++ ++ ReleaseSysCache(tuple); ++ ++ heap_close(rel, RowExclusiveLock); ++} ++ ++static void ++ExecAttributeSetSecLabel(Oid relid, const char *attname, DefElem *seclabel) ++{ ++ Relation rel; ++ HeapTuple tuple, newtup; ++ Oid secid; ++ bool replaces[Natts_pg_class]; ++ ++ /* Translate text representation to security id */ ++ secid = sepgsqlGivenSecLabelIn(AttributeRelationId, seclabel); ++ ++ rel = heap_open(AttributeRelationId, RowExclusiveLock); ++ tuple = SearchSysCacheAttName(relid, attname); ++ if (!HeapTupleIsValid(tuple)) + ereport(ERROR, -+ (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("SELinux: disabled now"))); ++ (errcode(ERRCODE_UNDEFINED_COLUMN), ++ errmsg("column \"%s\" of relation \"%s\" does not exist", ++ attname, get_rel_name(relid)))); + -+ Assert(IsA(defel, DefElem)); ++ memset(replaces, false, sizeof(replaces)); ++ newtup = heap_modify_tuple(tuple, RelationGetDescr(rel), ++ NULL, NULL, replaces); ++ if (!HeapTupleHasSecLabel(newtup)) ++ elog(ERROR, "Unable to set security label on: %s", ++ NameStr(((Form_pg_attribute) GETSTRUCT(tuple))->attname)); ++ HeapTupleSetSecLabel(newtup, secid); + -+ if (!attr_name) ++ simple_heap_update(rel, &newtup->t_self, newtup); ++ ++ CatalogUpdateIndexes(rel, newtup); ++ ++ ReleaseSysCache(tuple); ++ ++ heap_close(rel, RowExclusiveLock); ++} ++ ++void ++AlterRelationSecLabel(RangeVar *relation, const char *attname, ++ ObjectType objtype, DefElem *seclabel) ++{ ++ Form_pg_class clsForm; ++ HeapTuple tuple; ++ Oid relid; ++ ++ /* Check relation type against type specified in the ALTER command */ ++ relid = RangeVarGetRelid(relation, false); ++ tuple = SearchSysCache(RELOID, ++ ObjectIdGetDatum(relid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for relation %u", relid); ++ clsForm = (Form_pg_class) GETSTRUCT(tuple); ++ ++ switch (objtype) + { -+ Datum values[Natts_pg_class]; -+ bool nulls[Natts_pg_class]; -+ bool replaces[Natts_pg_class]; -+ -+ memset(replaces, false, sizeof(replaces)); -+ -+ class_rel = heap_open(RelationRelationId, RowExclusiveLock); -+ -+ tuple = SearchSysCache(RELOID, -+ ObjectIdGetDatum(RelationGetRelid(rel)), -+ 0, 0, 0); -+ if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "SELinux: cache lookup failed for relation: \"%s\"", -+ RelationGetRelationName(rel)); -+ /* -+ * NOTE: heap_modify_tuple() is necessary to make sure -+ * newtup has HEAP_HAS_SECLABEL and a field to store -+ * security lidentifier. -+ */ -+ newtup = heap_modify_tuple(tuple, RelationGetDescr(class_rel), -+ values, nulls, replaces); -+ if (!HeapTupleHasSecLabel(newtup)) -+ elog(ERROR, "Unable to assign security label on \"%s\"", -+ RelationGetRelationName(class_rel)); -+ -+ secid = sepgsqlInputGivenSecLabel(defel); -+ HeapTupleSetSecLabel(newtup, secid); -+ -+ simple_heap_update(class_rel, &tuple->t_self, newtup); -+ -+ CatalogUpdateIndexes(class_rel, newtup); -+ -+ ReleaseSysCache(tuple); -+ heap_close(class_rel, RowExclusiveLock); ++ case OBJECT_TABLE: ++ case OBJECT_COLUMN: ++ if (clsForm->relkind != RELKIND_RELATION) ++ ereport(ERROR, ++ (errcode(ERRCODE_WRONG_OBJECT_TYPE), ++ errmsg("\"%s\" is not a table", ++ NameStr(clsForm->relname)))); ++ break; ++ case OBJECT_SEQUENCE: ++ if (clsForm->relkind != RELKIND_SEQUENCE) ++ ereport(ERROR, ++ (errcode(ERRCODE_WRONG_OBJECT_TYPE), ++ errmsg("\"%s\" is not a sequence", ++ NameStr(clsForm->relname)))); ++ break; ++ default: ++ elog(ERROR, "unrecognized object type: %d", (int)objtype); ++ break; + } ++ ReleaseSysCache(tuple); ++ ++ /* Exec set security label */ ++ if (objtype != OBJECT_COLUMN) ++ ExecRelationSetSecLabel(relid, seclabel); + else -+ { -+ Datum values[Natts_pg_attribute]; -+ bool nulls[Natts_pg_attribute]; -+ bool replaces[Natts_pg_attribute]; -+ -+ memset(replaces, false, sizeof(replaces)); -+ -+ attr_rel = heap_open(AttributeRelationId, RowExclusiveLock); -+ -+ tuple = SearchSysCacheAttName(RelationGetRelid(rel), -+ attr_name); -+ if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "SELinux: cache lookup failed for column \"%s.%s\"", -+ RelationGetRelationName(rel), attr_name); -+ /* -+ * NOTE: heap_modify_tuple() is necessary to make sure -+ * newtup has HEAP_HAS_SECLABEL and a field to store -+ * security lidentifier. -+ */ -+ newtup = heap_modify_tuple(tuple, RelationGetDescr(attr_rel), -+ values, nulls, replaces); -+ if (!HeapTupleHasSecLabel(newtup)) -+ elog(ERROR, "Unable to assign security label on \"%s\"", -+ RelationGetRelationName(attr_rel)); -+ -+ secid = sepgsqlInputGivenSecLabel(defel); -+ HeapTupleSetSecLabel(newtup, secid); -+ -+ simple_heap_update(attr_rel, &tuple->t_self, newtup); -+ -+ CatalogUpdateIndexes(attr_rel, newtup); -+ -+ ReleaseSysCache(tuple); -+ heap_close(attr_rel, RowExclusiveLock); -+ } ++ ExecAttributeSetSecLabel(relid, attname, seclabel); +} /* - * Execute ALTER TABLE SET SCHEMA + * This code supports diff -rpNU3 base/src/backend/executor/execJunk.c sepgsql-new/src/backend/executor/execJunk.c --- base/src/backend/executor/execJunk.c 2008-01-07 23:51:33.000000000 +0900 +++ sepgsql-new/src/backend/executor/execJunk.c 2009-03-13 18:14:33.000000000 +0900 @@ -2527,7 +2711,7 @@ diff -rpNU3 base/src/backend/executor/execJunk.c sepgsql-new/src/backend/executo * Use the given slot, or make a new slot if we weren't given one. diff -rpNU3 base/src/backend/executor/execMain.c sepgsql-new/src/backend/executor/execMain.c --- base/src/backend/executor/execMain.c 2008-09-25 15:09:40.000000000 +0900 -+++ sepgsql-new/src/backend/executor/execMain.c 2009-03-15 17:38:39.000000000 +0900 ++++ sepgsql-new/src/backend/executor/execMain.c 2009-06-10 21:37:54.000000000 +0900 @@ -38,6 +38,7 @@ #include "access/xact.h" #include "catalog/heap.h" @@ -2643,7 +2827,7 @@ diff -rpNU3 base/src/backend/executor/execMain.c sepgsql-new/src/backend/executo /* ---------------------------------------------------------------- * ExecEndPlan * -@@ -1251,6 +1293,47 @@ ExecEndPlan(PlanState *planstate, EState +@@ -1251,6 +1293,58 @@ ExecEndPlan(PlanState *planstate, EState } } @@ -2655,7 +2839,8 @@ diff -rpNU3 base/src/backend/executor/execMain.c sepgsql-new/src/backend/executo + * header structure of HeapTuple. + */ +static void -+fetchWritableSystemAttribute(JunkFilter *junkfilter, TupleTableSlot *slot, Oid *tts_seclabel) ++fetchWritableSystemAttribute(JunkFilter *junkfilter, TupleTableSlot *slot, ++ Datum *tts_seclabel) +{ + AttrNumber attno; + Datum datum; @@ -2671,36 +2856,46 @@ diff -rpNU3 base/src/backend/executor/execMain.c sepgsql-new/src/backend/executo + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("setting NULL on \"%s\" system column is not supported", + SecurityLabelAttributeName))); -+ *tts_seclabel = securityTransSecLabelIn(TextDatumGetCString(datum)); ++ *tts_seclabel = datum; + } +} + +static void +storeWritableSystemAttribute(Relation rel, TupleTableSlot *slot, HeapTuple tuple) +{ ++ Oid relid = RelationGetRelid(rel); ++ Oid secid; ++ + /* "security_label" */ -+ if (HeapTupleHasSecLabel(tuple)) -+ HeapTupleSetSecLabel(tuple, slot->tts_seclabel); -+ else if (OidIsValid(slot->tts_seclabel)) -+ ereport(ERROR, -+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), -+ errmsg("Unable to assign security label on \"%s\"", -+ RelationGetRelationName(rel)))); ++ if (DatumGetPointer(slot->tts_seclabel) != NULL) ++ { ++ char *seclabel = TextDatumGetCString(slot->tts_seclabel); ++ ++ if (!HeapTupleHasSecLabel(tuple)) ++ ereport(ERROR, ++ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), ++ errmsg("Unable to assign security label on \"%s\"", ++ RelationGetRelationName(rel)))); ++ secid = securityTransSecLabelIn(relid, seclabel); ++ HeapTupleSetSecLabel(tuple, secid); ++ } ++ else if (HeapTupleHasSecLabel(tuple)) ++ HeapTupleSetSecLabel(tuple, InvalidOid); +} + /* ---------------------------------------------------------------- * ExecutePlan * -@@ -1318,6 +1401,8 @@ ExecutePlan(EState *estate, +@@ -1318,6 +1412,8 @@ ExecutePlan(EState *estate, for (;;) { -+ Oid tts_seclabel = InvalidOid; ++ Datum tts_seclabel = PointerGetDatum(NULL); + /* Reset the per-output-tuple exprcontext */ ResetPerTupleExprContext(estate); -@@ -1442,6 +1527,11 @@ lnext: ; +@@ -1442,6 +1538,11 @@ lnext: ; } /* @@ -2712,7 +2907,7 @@ diff -rpNU3 base/src/backend/executor/execMain.c sepgsql-new/src/backend/executo * extract the 'ctid' junk attribute. */ if (operation == CMD_UPDATE || operation == CMD_DELETE) -@@ -1468,6 +1558,7 @@ lnext: ; +@@ -1468,6 +1569,7 @@ lnext: ; if (operation != CMD_DELETE) slot = ExecFilterJunk(junkfilter, slot); } @@ -2720,7 +2915,7 @@ diff -rpNU3 base/src/backend/executor/execMain.c sepgsql-new/src/backend/executo /* * now that we have a tuple, do the appropriate thing with it.. either -@@ -1588,6 +1679,8 @@ ExecInsert(TupleTableSlot *slot, +@@ -1588,6 +1690,8 @@ ExecInsert(TupleTableSlot *slot, resultRelInfo = estate->es_result_relation_info; resultRelationDesc = resultRelInfo->ri_RelationDesc; @@ -2729,7 +2924,7 @@ diff -rpNU3 base/src/backend/executor/execMain.c sepgsql-new/src/backend/executo /* BEFORE ROW INSERT Triggers */ if (resultRelInfo->ri_TrigDesc && resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_INSERT] > 0) -@@ -1624,6 +1717,12 @@ ExecInsert(TupleTableSlot *slot, +@@ -1624,6 +1728,12 @@ ExecInsert(TupleTableSlot *slot, ExecConstraints(resultRelInfo, slot, estate); /* @@ -2742,7 +2937,7 @@ diff -rpNU3 base/src/backend/executor/execMain.c sepgsql-new/src/backend/executo * insert the tuple * * Note: heap_insert returns the tid (location) of the new tuple in the -@@ -1691,6 +1790,12 @@ ExecDelete(ItemPointer tupleid, +@@ -1691,6 +1801,12 @@ ExecDelete(ItemPointer tupleid, } /* @@ -2755,7 +2950,7 @@ diff -rpNU3 base/src/backend/executor/execMain.c sepgsql-new/src/backend/executo * delete the tuple * * Note: if es_crosscheck_snapshot isn't InvalidSnapshot, we check that -@@ -1826,6 +1931,8 @@ ExecUpdate(TupleTableSlot *slot, +@@ -1826,6 +1942,8 @@ ExecUpdate(TupleTableSlot *slot, resultRelInfo = estate->es_result_relation_info; resultRelationDesc = resultRelInfo->ri_RelationDesc; @@ -2764,7 +2959,7 @@ diff -rpNU3 base/src/backend/executor/execMain.c sepgsql-new/src/backend/executo /* BEFORE ROW UPDATE Triggers */ if (resultRelInfo->ri_TrigDesc && resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_UPDATE] > 0) -@@ -1870,6 +1977,12 @@ lreplace:; +@@ -1870,6 +1988,12 @@ lreplace:; ExecConstraints(resultRelInfo, slot, estate); /* @@ -2777,7 +2972,7 @@ diff -rpNU3 base/src/backend/executor/execMain.c sepgsql-new/src/backend/executo * replace the heap tuple * * Note: if es_crosscheck_snapshot isn't InvalidSnapshot, we check that -@@ -2733,7 +2846,8 @@ OpenIntoRel(QueryDesc *queryDesc) +@@ -2733,7 +2857,8 @@ OpenIntoRel(QueryDesc *queryDesc) 0, into->onCommit, reloptions, @@ -2787,7 +2982,7 @@ diff -rpNU3 base/src/backend/executor/execMain.c sepgsql-new/src/backend/executo FreeTupleDesc(tupdesc); -@@ -2839,6 +2953,10 @@ intorel_receive(TupleTableSlot *slot, De +@@ -2839,6 +2964,10 @@ intorel_receive(TupleTableSlot *slot, De tuple = ExecCopySlotTuple(slot); @@ -2874,8 +3069,8 @@ diff -rpNU3 base/src/backend/executor/execScan.c sepgsql-new/src/backend/executo return true; } diff -rpNU3 base/src/backend/executor/execTuples.c sepgsql-new/src/backend/executor/execTuples.c ---- base/src/backend/executor/execTuples.c 2008-01-07 23:51:33.000000000 +0900 -+++ sepgsql-new/src/backend/executor/execTuples.c 2009-03-13 18:14:33.000000000 +0900 +--- base/src/backend/executor/execTuples.c 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/src/backend/executor/execTuples.c 2009-09-10 20:24:37.000000000 +0900 @@ -100,7 +100,7 @@ @@ -2885,7 +3080,7 @@ diff -rpNU3 base/src/backend/executor/execTuples.c sepgsql-new/src/backend/execu /* ---------------------------------------------------------------- -@@ -921,9 +921,9 @@ ExecInitNullTupleSlot(EState *estate, Tu +@@ -941,9 +941,9 @@ ExecInitNullTupleSlot(EState *estate, Tu * ---------------------------------------------------------------- */ TupleDesc @@ -2897,7 +3092,7 @@ diff -rpNU3 base/src/backend/executor/execTuples.c sepgsql-new/src/backend/execu } /* ---------------------------------------------------------------- -@@ -933,13 +933,13 @@ ExecTypeFromTL(List *targetList, bool ha +@@ -953,13 +953,13 @@ ExecTypeFromTL(List *targetList, bool ha * ---------------------------------------------------------------- */ TupleDesc @@ -2914,7 +3109,7 @@ diff -rpNU3 base/src/backend/executor/execTuples.c sepgsql-new/src/backend/execu { TupleDesc typeInfo; ListCell *l; -@@ -951,6 +951,7 @@ ExecTypeFromTLInternal(List *targetList, +@@ -971,6 +971,7 @@ ExecTypeFromTLInternal(List *targetList, else len = ExecTargetListLength(targetList); typeInfo = CreateTemplateTupleDesc(len, hasoid); @@ -2998,11 +3193,12 @@ diff -rpNU3 base/src/backend/executor/spi.c sepgsql-new/src/backend/executor/spi { diff -rpNU3 base/src/backend/libpq/be-fsstubs.c sepgsql-new/src/backend/libpq/be-fsstubs.c --- base/src/backend/libpq/be-fsstubs.c 2008-01-07 23:51:33.000000000 +0900 -+++ sepgsql-new/src/backend/libpq/be-fsstubs.c 2009-03-13 18:14:33.000000000 +0900 -@@ -42,11 +42,14 @@ ++++ sepgsql-new/src/backend/libpq/be-fsstubs.c 2009-06-10 21:37:54.000000000 +0900 +@@ -42,11 +42,15 @@ #include #include ++#include "catalog/pg_largeobject.h" +#include "catalog/pg_security.h" #include "libpq/be-fsstubs.h" #include "libpq/libpq-fs.h" @@ -3014,7 +3210,7 @@ diff -rpNU3 base/src/backend/libpq/be-fsstubs.c sepgsql-new/src/backend/libpq/be #include "utils/memutils.h" -@@ -153,6 +156,10 @@ lo_read(int fd, char *buf, int len) +@@ -153,6 +157,10 @@ lo_read(int fd, char *buf, int len) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("invalid large-object descriptor: %d", fd))); @@ -3025,7 +3221,7 @@ diff -rpNU3 base/src/backend/libpq/be-fsstubs.c sepgsql-new/src/backend/libpq/be status = inv_read(cookies[fd], buf, len); -@@ -175,6 +182,11 @@ lo_write(int fd, const char *buf, int le +@@ -175,6 +183,11 @@ lo_write(int fd, const char *buf, int le errmsg("large object descriptor %d was not opened for writing", fd))); @@ -3037,7 +3233,7 @@ diff -rpNU3 base/src/backend/libpq/be-fsstubs.c sepgsql-new/src/backend/libpq/be status = inv_write(cookies[fd], buf, len); return status; -@@ -363,6 +375,11 @@ lo_import(PG_FUNCTION_ARGS) +@@ -363,6 +376,11 @@ lo_import(PG_FUNCTION_ARGS) */ lobj = inv_open(lobjOid, INV_WRITE, fscxt); @@ -3049,7 +3245,7 @@ diff -rpNU3 base/src/backend/libpq/be-fsstubs.c sepgsql-new/src/backend/libpq/be while ((nbytes = FileRead(fd, buf, BUFSIZE)) > 0) { tmp = inv_write(lobj, buf, nbytes); -@@ -435,6 +452,11 @@ lo_export(PG_FUNCTION_ARGS) +@@ -435,6 +453,11 @@ lo_export(PG_FUNCTION_ARGS) fnamebuf))); /* @@ -3061,7 +3257,7 @@ diff -rpNU3 base/src/backend/libpq/be-fsstubs.c sepgsql-new/src/backend/libpq/be * read in from the inversion file and write to the filesystem */ while ((nbytes = inv_read(lobj, buf, BUFSIZE)) > 0) -@@ -468,12 +490,64 @@ lo_truncate(PG_FUNCTION_ARGS) +@@ -468,12 +491,66 @@ lo_truncate(PG_FUNCTION_ARGS) (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("invalid large-object descriptor: %d", fd))); @@ -3084,10 +3280,12 @@ diff -rpNU3 base/src/backend/libpq/be-fsstubs.c sepgsql-new/src/backend/libpq/be +{ + Oid loid = PG_GETARG_OID(0); + Oid secid; ++ char *seclabel; + + secid = inv_get_security(loid); ++ seclabel = securityTransSecLabelOut(LargeObjectRelationId, secid); + -+ return CStringGetTextDatum(securityTransSecLabelOut(secid)); ++ return CStringGetTextDatum(seclabel); +} + +/* @@ -3101,7 +3299,7 @@ diff -rpNU3 base/src/backend/libpq/be-fsstubs.c sepgsql-new/src/backend/libpq/be + char *seclabel = TextDatumGetCString(PG_GETARG_DATUM(1)); + Oid secid; + -+ secid = securityTransSecLabelIn(seclabel); ++ secid = securityTransSecLabelIn(LargeObjectRelationId, seclabel); + + inv_set_security(loid, secid); + @@ -3127,8 +3325,8 @@ diff -rpNU3 base/src/backend/libpq/be-fsstubs.c sepgsql-new/src/backend/libpq/be * prepares large objects for transaction commit */ diff -rpNU3 base/src/backend/nodes/copyfuncs.c sepgsql-new/src/backend/nodes/copyfuncs.c ---- base/src/backend/nodes/copyfuncs.c 2008-03-19 09:48:23.000000000 +0900 -+++ sepgsql-new/src/backend/nodes/copyfuncs.c 2009-05-20 17:08:02.000000000 +0900 +--- base/src/backend/nodes/copyfuncs.c 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/src/backend/nodes/copyfuncs.c 2009-09-10 20:24:37.000000000 +0900 @@ -226,6 +226,7 @@ CopyScanFields(Scan *from, Scan *newnode CopyPlanFields((Plan *) from, (Plan *) newnode); @@ -3137,7 +3335,7 @@ diff -rpNU3 base/src/backend/nodes/copyfuncs.c sepgsql-new/src/backend/nodes/cop } /* -@@ -1523,6 +1524,8 @@ _copyRangeTblEntry(RangeTblEntry *from) +@@ -1524,6 +1525,8 @@ _copyRangeTblEntry(RangeTblEntry *from) COPY_SCALAR_FIELD(inFromCl); COPY_SCALAR_FIELD(requiredPerms); COPY_SCALAR_FIELD(checkAsUser); @@ -3146,7 +3344,7 @@ diff -rpNU3 base/src/backend/nodes/copyfuncs.c sepgsql-new/src/backend/nodes/cop return newnode; } -@@ -1789,6 +1792,7 @@ _copyColumnDef(ColumnDef *from) +@@ -1790,6 +1793,7 @@ _copyColumnDef(ColumnDef *from) COPY_NODE_FIELD(raw_default); COPY_STRING_FIELD(cooked_default); COPY_NODE_FIELD(constraints); @@ -3154,7 +3352,7 @@ diff -rpNU3 base/src/backend/nodes/copyfuncs.c sepgsql-new/src/backend/nodes/cop return newnode; } -@@ -2105,6 +2109,7 @@ _copyCreateStmt(CreateStmt *from) +@@ -2106,6 +2110,7 @@ _copyCreateStmt(CreateStmt *from) COPY_NODE_FIELD(options); COPY_SCALAR_FIELD(oncommit); COPY_STRING_FIELD(tablespacename); @@ -3162,10 +3360,42 @@ diff -rpNU3 base/src/backend/nodes/copyfuncs.c sepgsql-new/src/backend/nodes/cop return newnode; } +@@ -2328,6 +2333,21 @@ _copyAlterOwnerStmt(AlterOwnerStmt *from + return newnode; + } + ++static AlterSecLabelStmt * ++_copyAlterSecLabelStmt(AlterSecLabelStmt *from) ++{ ++ AlterSecLabelStmt *newnode = makeNode(AlterSecLabelStmt); ++ ++ COPY_SCALAR_FIELD(objectType); ++ COPY_NODE_FIELD(relation); ++ COPY_NODE_FIELD(object); ++ COPY_NODE_FIELD(objarg); ++ COPY_STRING_FIELD(subname); ++ COPY_NODE_FIELD(secLabel); ++ ++ return newnode; ++} ++ + static RuleStmt * + _copyRuleStmt(RuleStmt *from) + { +@@ -3372,6 +3392,9 @@ copyObject(void *from) + case T_AlterOwnerStmt: + retval = _copyAlterOwnerStmt(from); + break; ++ case T_AlterSecLabelStmt: ++ retval = _copyAlterSecLabelStmt(from); ++ break; + case T_RuleStmt: + retval = _copyRuleStmt(from); + break; diff -rpNU3 base/src/backend/nodes/equalfuncs.c sepgsql-new/src/backend/nodes/equalfuncs.c ---- base/src/backend/nodes/equalfuncs.c 2008-03-19 09:48:23.000000000 +0900 -+++ sepgsql-new/src/backend/nodes/equalfuncs.c 2009-03-13 18:14:33.000000000 +0900 -@@ -970,6 +970,7 @@ _equalCreateStmt(CreateStmt *a, CreateSt +--- base/src/backend/nodes/equalfuncs.c 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/src/backend/nodes/equalfuncs.c 2009-09-10 20:24:37.000000000 +0900 +@@ -971,6 +971,7 @@ _equalCreateStmt(CreateStmt *a, CreateSt COMPARE_NODE_FIELD(options); COMPARE_SCALAR_FIELD(oncommit); COMPARE_STRING_FIELD(tablespacename); @@ -3173,7 +3403,27 @@ diff -rpNU3 base/src/backend/nodes/equalfuncs.c sepgsql-new/src/backend/nodes/eq return true; } -@@ -1818,6 +1819,7 @@ _equalColumnDef(ColumnDef *a, ColumnDef +@@ -1162,6 +1163,19 @@ _equalAlterOwnerStmt(AlterOwnerStmt *a, + } + + static bool ++_equalAlterSecLabelStmt(AlterSecLabelStmt *a, AlterSecLabelStmt *b) ++{ ++ COMPARE_SCALAR_FIELD(objectType); ++ COMPARE_NODE_FIELD(relation); ++ COMPARE_NODE_FIELD(object); ++ COMPARE_NODE_FIELD(objarg); ++ COMPARE_STRING_FIELD(subname); ++ COMPARE_NODE_FIELD(secLabel); ++ ++ return true; ++} ++ ++static bool + _equalRuleStmt(RuleStmt *a, RuleStmt *b) + { + COMPARE_NODE_FIELD(relation); +@@ -1819,6 +1833,7 @@ _equalColumnDef(ColumnDef *a, ColumnDef COMPARE_NODE_FIELD(raw_default); COMPARE_STRING_FIELD(cooked_default); COMPARE_NODE_FIELD(constraints); @@ -3181,7 +3431,7 @@ diff -rpNU3 base/src/backend/nodes/equalfuncs.c sepgsql-new/src/backend/nodes/eq return true; } -@@ -1873,6 +1875,8 @@ _equalRangeTblEntry(RangeTblEntry *a, Ra +@@ -1874,6 +1889,8 @@ _equalRangeTblEntry(RangeTblEntry *a, Ra COMPARE_SCALAR_FIELD(inFromCl); COMPARE_SCALAR_FIELD(requiredPerms); COMPARE_SCALAR_FIELD(checkAsUser); @@ -3190,9 +3440,19 @@ diff -rpNU3 base/src/backend/nodes/equalfuncs.c sepgsql-new/src/backend/nodes/eq return true; } +@@ -2298,6 +2315,9 @@ equal(void *a, void *b) + case T_AlterOwnerStmt: + retval = _equalAlterOwnerStmt(a, b); + break; ++ case T_AlterSecLabelStmt: ++ retval = _equalAlterSecLabelStmt(a, b); ++ break; + case T_RuleStmt: + retval = _equalRuleStmt(a, b); + break; diff -rpNU3 base/src/backend/nodes/outfuncs.c sepgsql-new/src/backend/nodes/outfuncs.c ---- base/src/backend/nodes/outfuncs.c 2009-02-02 11:47:17.000000000 +0900 -+++ sepgsql-new/src/backend/nodes/outfuncs.c 2009-05-20 17:08:02.000000000 +0900 +--- base/src/backend/nodes/outfuncs.c 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/src/backend/nodes/outfuncs.c 2009-09-10 20:24:37.000000000 +0900 @@ -282,6 +282,7 @@ _outScanInfo(StringInfo str, Scan *node) _outPlanInfo(str, (Plan *) node); @@ -3209,7 +3469,7 @@ diff -rpNU3 base/src/backend/nodes/outfuncs.c sepgsql-new/src/backend/nodes/outf } static void -@@ -1545,6 +1547,7 @@ _outCreateStmt(StringInfo str, CreateStm +@@ -1546,6 +1548,7 @@ _outCreateStmt(StringInfo str, CreateStm WRITE_NODE_FIELD(options); WRITE_ENUM_FIELD(oncommit, OnCommitAction); WRITE_STRING_FIELD(tablespacename); @@ -3217,7 +3477,7 @@ diff -rpNU3 base/src/backend/nodes/outfuncs.c sepgsql-new/src/backend/nodes/outf } static void -@@ -1660,6 +1663,7 @@ _outColumnDef(StringInfo str, ColumnDef +@@ -1661,6 +1664,7 @@ _outColumnDef(StringInfo str, ColumnDef WRITE_NODE_FIELD(raw_default); WRITE_STRING_FIELD(cooked_default); WRITE_NODE_FIELD(constraints); @@ -3225,7 +3485,7 @@ diff -rpNU3 base/src/backend/nodes/outfuncs.c sepgsql-new/src/backend/nodes/outf } static void -@@ -1834,6 +1838,8 @@ _outRangeTblEntry(StringInfo str, RangeT +@@ -1835,6 +1839,8 @@ _outRangeTblEntry(StringInfo str, RangeT WRITE_BOOL_FIELD(inFromCl); WRITE_UINT_FIELD(requiredPerms); WRITE_OID_FIELD(checkAsUser); @@ -3305,8 +3565,8 @@ diff -rpNU3 base/src/backend/nodes/readfuncs.c sepgsql-new/src/backend/nodes/rea READ_DONE(); } diff -rpNU3 base/src/backend/optimizer/plan/createplan.c sepgsql-new/src/backend/optimizer/plan/createplan.c ---- base/src/backend/optimizer/plan/createplan.c 2008-06-12 22:34:19.000000000 +0900 -+++ sepgsql-new/src/backend/optimizer/plan/createplan.c 2009-05-20 17:08:02.000000000 +0900 +--- base/src/backend/optimizer/plan/createplan.c 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/src/backend/optimizer/plan/createplan.c 2009-09-10 20:24:37.000000000 +0900 @@ -286,6 +286,9 @@ create_scan_plan(PlannerInfo *root, Path break; } @@ -3433,8 +3693,16 @@ diff -rpNU3 base/src/backend/optimizer/util/clauses.c sepgsql-new/src/backend/op diff -rpNU3 base/src/backend/optimizer/util/relnode.c sepgsql-new/src/backend/optimizer/util/relnode.c --- base/src/backend/optimizer/util/relnode.c 2008-01-07 23:51:33.000000000 +0900 -+++ sepgsql-new/src/backend/optimizer/util/relnode.c 2009-05-20 17:08:02.000000000 +0900 -@@ -90,6 +90,7 @@ build_simple_rel(PlannerInfo *root, int ++++ sepgsql-new/src/backend/optimizer/util/relnode.c 2009-06-11 10:19:07.000000000 +0900 +@@ -20,6 +20,7 @@ + #include "optimizer/plancat.h" + #include "optimizer/restrictinfo.h" + #include "parser/parsetree.h" ++#include "security/rowlevel.h" + #include "utils/hsearch.h" + + +@@ -90,6 +91,7 @@ build_simple_rel(PlannerInfo *root, int rel->has_eclass_joins = false; rel->index_outer_relids = NULL; rel->index_inner_paths = NIL; @@ -3579,7 +3847,7 @@ diff -rpNU3 base/src/backend/parser/analyze.c sepgsql-new/src/backend/parser/ana if (origTargetList != NULL) diff -rpNU3 base/src/backend/parser/gram.y sepgsql-new/src/backend/parser/gram.y --- base/src/backend/parser/gram.y 2008-03-19 09:48:23.000000000 +0900 -+++ sepgsql-new/src/backend/parser/gram.y 2009-03-13 18:14:33.000000000 +0900 ++++ sepgsql-new/src/backend/parser/gram.y 2009-06-19 15:02:12.000000000 +0900 @@ -56,6 +56,7 @@ #include "commands/defrem.h" #include "nodes/makefuncs.h" @@ -3588,52 +3856,82 @@ diff -rpNU3 base/src/backend/parser/gram.y sepgsql-new/src/backend/parser/gram.y #include "storage/lmgr.h" #include "utils/date.h" #include "utils/datetime.h" +@@ -150,7 +151,7 @@ static Node *makeXmlExpr(XmlExprOp op, c + + %type stmt schema_stmt + AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterGroupStmt +- AlterObjectSchemaStmt AlterOwnerStmt AlterSeqStmt AlterTableStmt ++ AlterObjectSchemaStmt AlterOwnerStmt AlterSecLabelStmt AlterSeqStmt AlterTableStmt + AlterUserStmt AlterUserSetStmt AlterRoleStmt AlterRoleSetStmt + AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt + ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt @@ -351,6 +352,8 @@ static Node *makeXmlExpr(XmlExprOp op, c %type OptTableSpace OptConsTableSpace OptTableSpaceOwner %type opt_check_option -+%type OptSecurityItem SecurityItem ++%type OptSecLabel SecLabelItem + %type xml_attribute_el %type xml_attribute_list xml_attributes %type xml_root_version opt_xml_root_standalone -@@ -1637,7 +1640,25 @@ alter_table_cmd: +@@ -534,6 +537,7 @@ stmt : + | AlterGroupStmt + | AlterObjectSchemaStmt + | AlterOwnerStmt ++ | AlterSecLabelStmt + | AlterSeqStmt + | AlterTableStmt + | AlterRoleSetStmt +@@ -961,7 +965,7 @@ DropGroupStmt: + *****************************************************************************/ + + CreateSchemaStmt: +- CREATE SCHEMA OptSchemaName AUTHORIZATION RoleId OptSchemaEltList ++ CREATE SCHEMA OptSchemaName AUTHORIZATION RoleId OptSecLabel OptSchemaEltList + { + CreateSchemaStmt *n = makeNode(CreateSchemaStmt); + /* One can omit the schema name or the authorization id. */ +@@ -970,16 +974,18 @@ CreateSchemaStmt: + else + n->schemaname = $5; + n->authid = $5; +- n->schemaElts = $6; ++ n->secLabel = $6; ++ n->schemaElts = $7; + $$ = (Node *)n; + } +- | CREATE SCHEMA ColId OptSchemaEltList ++ | CREATE SCHEMA ColId OptSecLabel OptSchemaEltList + { + CreateSchemaStmt *n = makeNode(CreateSchemaStmt); + /* ...but not both */ + n->schemaname = $3; + n->authid = NULL; +- n->schemaElts = $4; ++ n->secLabel = $4; ++ n->schemaElts = $5; + $$ = (Node *)n; + } + ; +@@ -1637,7 +1643,7 @@ alter_table_cmd: n->def = (Node *) $3; $$ = (Node *)n; } - | alter_rel_cmd -+ /* ALTER TABLE CONTEXT = '...' */ -+ | SecurityItem -+ { -+ AlterTableCmd *n = makeNode(AlterTableCmd); -+ n->subtype = AT_SetSecurityLabel; -+ n->name = NULL; -+ n->def = (Node *) $1; -+ $$ = (Node *) n; -+ } -+ /* ALTER TABLE ALTER [COLUMN] CONTEXT = '...' */ -+ | ALTER opt_column ColId SecurityItem -+ { -+ AlterTableCmd *n = makeNode(AlterTableCmd); -+ n->subtype = AT_SetSecurityLabel; -+ n->name = $3; -+ n->def = (Node *) $4; -+ $$ = (Node *) n; -+ } + | alter_rel_cmd { $$ = $1; } -@@ -1883,7 +1904,7 @@ opt_using: +@@ -1883,7 +1889,7 @@ opt_using: *****************************************************************************/ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' - OptInherit OptWith OnCommitOption OptTableSpace -+ OptInherit OptWith OnCommitOption OptTableSpace OptSecurityItem ++ OptInherit OptWith OnCommitOption OptTableSpace OptSecLabel { CreateStmt *n = makeNode(CreateStmt); $4->istemp = $2; -@@ -1894,10 +1915,11 @@ CreateStmt: CREATE OptTemp TABLE qualifi +@@ -1894,10 +1900,11 @@ CreateStmt: CREATE OptTemp TABLE qualifi n->options = $9; n->oncommit = $10; n->tablespacename = $11; @@ -3642,11 +3940,11 @@ diff -rpNU3 base/src/backend/parser/gram.y sepgsql-new/src/backend/parser/gram.y } | CREATE OptTemp TABLE qualified_name OF qualified_name - '(' OptTableElementList ')' OptWith OnCommitOption OptTableSpace -+ '(' OptTableElementList ')' OptWith OnCommitOption OptTableSpace OptSecurityItem ++ '(' OptTableElementList ')' OptWith OnCommitOption OptTableSpace OptSecLabel { /* SQL99 CREATE TABLE OF (cols) seems to be satisfied * by our inheritance capabilities. Let's try it... -@@ -1911,6 +1933,7 @@ CreateStmt: CREATE OptTemp TABLE qualifi +@@ -1911,6 +1918,7 @@ CreateStmt: CREATE OptTemp TABLE qualifi n->options = $10; n->oncommit = $11; n->tablespacename = $12; @@ -3654,12 +3952,12 @@ diff -rpNU3 base/src/backend/parser/gram.y sepgsql-new/src/backend/parser/gram.y $$ = (Node *)n; } ; -@@ -1953,13 +1976,14 @@ TableElement: +@@ -1953,13 +1961,14 @@ TableElement: | TableConstraint { $$ = $1; } ; -columnDef: ColId Typename ColQualList -+columnDef: ColId Typename ColQualList OptSecurityItem ++columnDef: ColId Typename ColQualList OptSecLabel { ColumnDef *n = makeNode(ColumnDef); n->colname = $1; @@ -3670,67 +3968,136 @@ diff -rpNU3 base/src/backend/parser/gram.y sepgsql-new/src/backend/parser/gram.y $$ = (Node *)n; } ; -@@ -4278,6 +4302,10 @@ common_func_opt_item: +@@ -2420,12 +2429,13 @@ CreateAsElement: + *****************************************************************************/ + + CreateSeqStmt: +- CREATE OptTemp SEQUENCE qualified_name OptSeqList ++ CREATE OptTemp SEQUENCE qualified_name OptSeqList OptSecLabel + { + CreateSeqStmt *n = makeNode(CreateSeqStmt); + $4->istemp = $2; + n->sequence = $4; + n->options = $5; ++ n->secLabel = $6; + $$ = (Node *)n; + } + ; +@@ -4278,7 +4288,7 @@ common_func_opt_item: /* we abuse the normal content of a DefElem here */ $$ = makeDefElem("set", (Node *)$1); } -+ | SecurityItem -+ { -+ $$ = $1; -+ } - ; +- ; ++ ; createfunc_opt_item: -@@ -5361,6 +5389,10 @@ createdb_opt_item: + AS func_as +@@ -4289,6 +4299,10 @@ createfunc_opt_item: { - $$ = makeDefElem("owner", NULL); + $$ = makeDefElem("language", (Node *)makeString($2)); } -+ | SecurityItem ++ | SecLabelItem + { + $$ = $1; + } - ; - - /* -@@ -5409,6 +5441,10 @@ alterdb_opt_item: + | common_func_opt_item { - $$ = makeDefElem("connectionlimit", (Node *)makeInteger($4)); - } -+ | SecurityItem -+ { -+ $$ = $1; -+ } - ; - - -@@ -8736,6 +8772,27 @@ target_el: a_expr AS ColLabel + $$ = $1; +@@ -4923,6 +4937,75 @@ AlterOwnerStmt: ALTER AGGREGATE func_nam } ; +/***************************************************************************** + * -+ * SE-PostgreSQL security items ++ * ALTER THING name SECURITY_LABEL [=] + * + *****************************************************************************/ + -+OptSecurityItem: -+ SecurityItem { $$ = $1; } ++AlterSecLabelStmt: ALTER DATABASE database_name SecLabelItem ++ { ++ AlterSecLabelStmt *n = makeNode(AlterSecLabelStmt); ++ n->objectType = OBJECT_DATABASE; ++ n->object = list_make1(makeString($3)); ++ n->secLabel = (Node *)$4; ++ $$ = (Node *) n; ++ } ++ | ALTER SCHEMA name SecLabelItem ++ { ++ AlterSecLabelStmt *n = makeNode(AlterSecLabelStmt); ++ n->objectType = OBJECT_SCHEMA; ++ n->object = list_make1(makeString($3)); ++ n->secLabel = (Node *)$4; ++ $$ = (Node *) n; ++ } ++ | ALTER TABLE relation_expr SecLabelItem ++ { ++ AlterSecLabelStmt *n = makeNode(AlterSecLabelStmt); ++ n->objectType = OBJECT_TABLE; ++ n->relation = $3; ++ n->secLabel = (Node *)$4; ++ $$ = (Node *) n; ++ } ++ | ALTER TABLE relation_expr ALTER opt_column ColId SecLabelItem ++ { ++ AlterSecLabelStmt *n = makeNode(AlterSecLabelStmt); ++ n->objectType = OBJECT_COLUMN; ++ n->relation = $3; ++ n->subname = $6; ++ n->secLabel = (Node *)$7; ++ $$ = (Node *) n; ++ } ++ | ALTER SEQUENCE relation_expr SecLabelItem ++ { ++ AlterSecLabelStmt *n = makeNode(AlterSecLabelStmt); ++ n->objectType = OBJECT_SEQUENCE; ++ n->relation = $3; ++ n->secLabel = (Node *)$4; ++ $$ = (Node *) n; ++ } ++ | ALTER FUNCTION function_with_argtypes SecLabelItem ++ { ++ AlterSecLabelStmt *n = makeNode(AlterSecLabelStmt); ++ n->objectType = OBJECT_FUNCTION; ++ n->object = $3->funcname; ++ n->objarg = $3->funcargs; ++ n->secLabel = (Node *)$4; ++ $$ = (Node *) n; ++ } ++ ; ++ ++OptSecLabel: SecLabelItem { $$ = $1; } + | /* EMPTY */ { $$ = NULL; } + ; + -+SecurityItem: -+ IDENT opt_equal Sconst ++SecLabelItem: IDENT opt_equal Sconst + { -+ if (!sepgsqlIsEnabled() || -+ strcmp("security_context", $1) != 0) ++ if (strcmp("security_context", $1) != 0) + yyerror("syntax error"); -+ + $$ = makeDefElem($1, (Node *) makeString($3)); + } + ; /***************************************************************************** * +@@ -5361,6 +5444,10 @@ createdb_opt_item: + { + $$ = makeDefElem("owner", NULL); + } ++ | SecLabelItem ++ { ++ $$ = $1; ++ } + ; + + /* +@@ -8736,7 +8823,6 @@ target_el: a_expr AS ColLabel + } + ; + +- + /***************************************************************************** + * + * Names and constants diff -rpNU3 base/src/backend/parser/parse_clause.c sepgsql-new/src/backend/parser/parse_clause.c --- base/src/backend/parser/parse_clause.c 2008-01-07 23:51:33.000000000 +0900 +++ sepgsql-new/src/backend/parser/parse_clause.c 2009-03-13 18:14:33.000000000 +0900 @@ -4170,8 +4537,8 @@ diff -rpNU3 base/src/backend/parser/parse_target.c sepgsql-new/src/backend/parse } } diff -rpNU3 base/src/backend/postmaster/postmaster.c sepgsql-new/src/backend/postmaster/postmaster.c ---- base/src/backend/postmaster/postmaster.c 2008-09-25 15:09:40.000000000 +0900 -+++ sepgsql-new/src/backend/postmaster/postmaster.c 2009-03-13 18:14:33.000000000 +0900 +--- base/src/backend/postmaster/postmaster.c 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/src/backend/postmaster/postmaster.c 2009-09-10 20:24:37.000000000 +0900 @@ -107,6 +107,7 @@ #include "postmaster/pgarch.h" #include "postmaster/postmaster.h" @@ -4190,7 +4557,7 @@ diff -rpNU3 base/src/backend/postmaster/postmaster.c sepgsql-new/src/backend/pos /* Startup/shutdown state */ #define NoShutdown 0 -@@ -1321,6 +1323,10 @@ ServerLoop(void) +@@ -1323,6 +1325,10 @@ ServerLoop(void) if (PgStatPID == 0 && pmState == PM_RUN) PgStatPID = pgstat_start(); @@ -4198,10 +4565,10 @@ diff -rpNU3 base/src/backend/postmaster/postmaster.c sepgsql-new/src/backend/pos + if (sepgsqlWorkerPID == 0 && pmState == PM_RUN) + sepgsqlWorkerPID = sepgsqlStartupWorkerProcess(); + - /* - * Touch the socket and lock file every 58 minutes, to ensure that - * they are not removed by overzealous /tmp-cleaning tasks. We assume -@@ -1911,6 +1917,8 @@ SIGHUP_handler(SIGNAL_ARGS) + /* If we need to signal the autovacuum launcher, do so now */ + if (avlauncher_needs_signal) + { +@@ -1921,6 +1927,8 @@ SIGHUP_handler(SIGNAL_ARGS) signal_child(PgArchPID, SIGHUP); if (SysLoggerPID != 0) signal_child(SysLoggerPID, SIGHUP); @@ -4210,7 +4577,7 @@ diff -rpNU3 base/src/backend/postmaster/postmaster.c sepgsql-new/src/backend/pos /* PgStatPID does not currently need SIGHUP */ /* Reload authentication config files too */ -@@ -1968,6 +1976,9 @@ pmdie(SIGNAL_ARGS) +@@ -1978,6 +1986,9 @@ pmdie(SIGNAL_ARGS) /* and the walwriter too */ if (WalWriterPID != 0) signal_child(WalWriterPID, SIGTERM); @@ -4220,7 +4587,7 @@ diff -rpNU3 base/src/backend/postmaster/postmaster.c sepgsql-new/src/backend/pos pmState = PM_WAIT_BACKENDS; } -@@ -2006,6 +2017,9 @@ pmdie(SIGNAL_ARGS) +@@ -2017,6 +2028,9 @@ pmdie(SIGNAL_ARGS) /* and the walwriter too */ if (WalWriterPID != 0) signal_child(WalWriterPID, SIGTERM); @@ -4230,7 +4597,7 @@ diff -rpNU3 base/src/backend/postmaster/postmaster.c sepgsql-new/src/backend/pos pmState = PM_WAIT_BACKENDS; } -@@ -2039,6 +2053,8 @@ pmdie(SIGNAL_ARGS) +@@ -2050,6 +2064,8 @@ pmdie(SIGNAL_ARGS) signal_child(PgArchPID, SIGQUIT); if (PgStatPID != 0) signal_child(PgStatPID, SIGQUIT); @@ -4239,7 +4606,7 @@ diff -rpNU3 base/src/backend/postmaster/postmaster.c sepgsql-new/src/backend/pos ExitPostmaster(0); break; } -@@ -2287,6 +2303,16 @@ reaper(SIGNAL_ARGS) +@@ -2298,6 +2314,16 @@ reaper(SIGNAL_ARGS) continue; } @@ -4256,7 +4623,7 @@ diff -rpNU3 base/src/backend/postmaster/postmaster.c sepgsql-new/src/backend/pos /* * Else do standard backend child cleanup. */ -@@ -2454,6 +2480,18 @@ HandleChildCrash(int pid, int exitstatus +@@ -2465,6 +2491,18 @@ HandleChildCrash(int pid, int exitstatus signal_child(AutoVacPID, (SendStop ? SIGSTOP : SIGQUIT)); } @@ -4275,7 +4642,7 @@ diff -rpNU3 base/src/backend/postmaster/postmaster.c sepgsql-new/src/backend/pos /* * 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 -@@ -2573,7 +2611,8 @@ PostmasterStateMachine(void) +@@ -2584,7 +2622,8 @@ PostmasterStateMachine(void) StartupPID == 0 && (BgWriterPID == 0 || !FatalError) && WalWriterPID == 0 && @@ -4523,8 +4890,8 @@ diff -rpNU3 base/src/backend/security/rowlevel.c sepgsql-new/src/backend/securit +} diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/security/sepgsql/avc.c --- base/src/backend/security/sepgsql/avc.c 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/backend/security/sepgsql/avc.c 2009-05-20 17:35:01.000000000 +0900 -@@ -0,0 +1,838 @@ ++++ sepgsql-new/src/backend/security/sepgsql/avc.c 2009-06-10 17:43:08.000000000 +0900 +@@ -0,0 +1,859 @@ +/* + * src/backend/security/sepgsql/avc.c + * SE-PostgreSQL userspace access vector cache @@ -4535,6 +4902,7 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu +#include "postgres.h" + +#include "access/hash.h" ++#include "catalog/catalog.h" +#include "catalog/pg_security.h" +#include "libpq/pqsignal.h" +#include "postmaster/postmaster.h" @@ -4548,28 +4916,24 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu +#include + +/* -+ * AVC: userspace Access Vector Cache ++ * AVC: userspace access vector cache + * -+ * SE-PostgreSQL makes inqueries for SELinux to check whether the security -+ * policy allows the required action, or not. However, it need to invoke -+ * system call because SELinux is a kernel feature and it hold its security -+ * policy in the kernel memory. ++ * SE-PostgreSQL asks in-kernel SELinux to make its decision whether ++ * the required accesses should be allowed, or not, based on the unified ++ * security policy. It needs a system call invocation to communicate ++ * a kernel feature, such as SELinux, but it is a heavy task in most cases ++ * due to the context switching. + * -+ * AVC enables to reduce the number of kernel invocation, with caching -+ * the result of inquiries. When we have to make a decision based on the -+ * security policy of SELinux, it tries to find up an appropriate cache -+ * entry on the uAVC. If exist, we don't need to invoke a system call -+ * and can reduce unnecessary overhead. ++ * The userspace avc enables to minimize the number of system call ++ * invocations, using a chache mechanim for the certain pair of security ++ * contexts and object classes (it means the kind of actions). ++ * It enables to hold recently fetched results from the in-kernel SELinux, ++ * and make a decision without context switching, if the cache hit. + * -+ * If not exist, SE-PostgreSQL makes a new cache entry based on the -+ * result of inquiries, and chains it on uAVC to prepare the following -+ * decision makings. -+ * -+ * uAVC has a version number to check whether it is now valid, or not. -+ * Not need to say, uAVC cache entry has to be invalid just after -+ * policy reloaded or state change. -+ * If it is not match the latest one, updated by the policy state -+ * monitoring process, uAVC has to be reseted. ++ * When the state of security policy is changed, the cached results ++ * shall to be invalidated. The state monitoring process launched by ++ * postmaster can receives the notification messages from the kernel ++ * space, and invalidate the current version of avc. + */ +static MemoryContext AvcMemCtx; + @@ -4578,11 +4942,18 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu + +typedef struct +{ ++ Oid relid; ++ Oid secid; ++} sepgsql_sid_t; ++ ++#define AVC_DATUM_NSID_SLOTS 19 ++typedef struct ++{ + uint32 hash_key; + + security_class_t tclass; -+ Oid tsid; -+ Oid nsid; ++ sepgsql_sid_t tsid; ++ sepgsql_sid_t nsid[AVC_DATUM_NSID_SLOTS]; + + access_vector_t allowed; + access_vector_t decided; @@ -4677,7 +5048,7 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu + * returns false, if the given avc_page is already obsolete. + */ +static bool -+sepgsql_avc_check_valid(avc_page *page) ++sepgsql_avc_check_valid(void) +{ + bool result = true; + @@ -4786,28 +5157,27 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu + * cache the result of SELinux's decision for access rights and + * default security context. + */ -+#define avc_hash_key(tcontext, tclass) ((tsid) ^ ((tclass) << 3)) ++#define avc_hash_key(trelid,tsecid,tclass) \ ++ (hash_uint32((trelid) ^ (tsecid) ^ ((tclass) << 3))) + +static avc_datum * -+avc_make_entry(avc_page *page, Oid tsid, security_class_t tclass) ++avc_make_entry(avc_page *page, Oid relid, Oid secid, security_class_t tclass) +{ -+ security_context_t scontext, tcontext, ncontext; -+ security_class_t tclass_ex; -+ MemoryContext oldctx; -+ struct av_decision avd; -+ avc_datum *cache; -+ uint32 hash_key, index; ++ security_context_t scontext, tcontext, ncontext; ++ security_class_t tclass_ex; ++ MemoryContext oldctx; ++ struct av_decision avd; ++ avc_datum *cache; ++ uint32 hash_key, index; + -+ hash_key = avc_hash_key(tsid, tclass); ++ hash_key = avc_hash_key(relid, secid, tclass); + index = hash_key % AVC_HASH_NUM_SLOTS; + + scontext = page->scontext; -+ tcontext = securityLookupSecurityLabel(tsid); -+ if (!tcontext || security_check_context(tcontext) < 0) -+ tcontext = sepgsqlGetUnlabeledLabel(); ++ tcontext = securityRawSecLabelOut(relid, secid); + + /* -+ * Ask SELinux a set of permissions ++ * Compute SELinux permission + */ + tclass_ex = sepgsqlTransToExternalClass(tclass); + if (tclass_ex > 0) @@ -4816,7 +5186,7 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu + tclass_ex, 0, &avd) < 0) + ereport(ERROR, + (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("SELinux: could not compute av_decision: " ++ errmsg("SELinux: unable to compute av_decision: " + "scontext=%s tcontext=%s tclass=%s", + scontext, tcontext, + sepgsqlGetClassString(tclass)))); @@ -4833,14 +5203,18 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu + } + + /* -+ * Ask SELinux a security context for newly created object ++ * Compute New security context + */ -+ if (security_compute_create_raw(scontext, tcontext, tclass_ex, &ncontext) < 0) ++ if (security_compute_create_raw(scontext, tcontext, ++ tclass_ex, &ncontext) < 0) ++ { + ereport(ERROR, + (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("SELinux: could not compute new context: " ++ errmsg("SELinux: unable to compute new context: " + "scontext=%s tcontext=%s tclass=%s", + scontext, tcontext, sepgsqlGetClassString(tclass)))); ++ } ++ + /* + * Copy them to avc_datum + */ @@ -4855,13 +5229,12 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu + PG_RE_THROW(); + } + PG_END_TRY(); -+ strcpy(cache->ncontext, ncontext); -+ freecon(ncontext); + + cache->hash_key = hash_key; + cache->tclass = tclass; -+ cache->tsid = tsid; -+ cache->nsid = InvalidOid; /* assigned later */ ++ cache->tsid.relid = relid; ++ cache->tsid.secid = secid; ++ /* cache->nsid shall be set later */ + + cache->allowed = avd.allowed; + cache->decided = avd.decided; @@ -4871,11 +5244,12 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu + cache->hot_cache = true; + if (avd.flags & SELINUX_AVD_FLAGS_PERMISSIVE) + cache->permissive = true; ++ strcpy(cache->ncontext, ncontext); ++ freecon(ncontext); + + sepgsql_avc_reclaim(page); + + page->slot[index] = lcons(cache, page->slot[index]); -+ + page->avc_count++; + + MemoryContextSwitchTo(oldctx); @@ -4889,18 +5263,19 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu + * on the global state, the caller has to hold SepgsqlAvcLock. + */ +static avc_datum * -+avc_lookup(avc_page *page, Oid tsid, security_class_t tclass) ++avc_lookup(avc_page *page, Oid trelid, Oid tsecid, ++ security_class_t tclass) +{ + avc_datum *cache = NULL; + uint32 hash_key, index; + ListCell *l; + + /* check avc invalidation */ -+ if (!sepgsql_avc_check_valid(page)) ++ if (!sepgsql_avc_check_valid()) + sepgsql_avc_reset(); + + /* lookup avc entry */ -+ hash_key = avc_hash_key(tsid, tclass); ++ hash_key = avc_hash_key(trelid, tsecid, tclass); + index = hash_key % AVC_HASH_NUM_SLOTS; + + foreach (l, page->slot[index]) @@ -4908,7 +5283,8 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu + cache = lfirst(l); + if (cache->hash_key == hash_key + && cache->tclass == tclass -+ && cache->tsid == tsid) ++ && cache->tsid.relid == trelid ++ && cache->tsid.secid == tsecid) + { + cache->hot_cache = true; + return cache; @@ -4992,15 +5368,15 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu + * checks client's privileges on given objects via uAVC. + */ +bool -+sepgsqlClientHasPerms(Oid tsid, -+ security_class_t tclass, -+ access_vector_t required, -+ const char *audit_name, bool abort) ++sepgsqlClientHasPermsSid(Oid relid, Oid secid, ++ security_class_t tclass, ++ access_vector_t required, ++ const char *audit_name, bool abort) +{ -+ security_context_t scon, tcon; -+ access_vector_t denied, audited; -+ avc_datum *cache; -+ bool result = true; ++ security_context_t scontext, tcontext; ++ access_vector_t denied, audited; ++ avc_datum *cache; ++ bool result = true; + + Assert(required != 0); + @@ -5008,11 +5384,10 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu + return true; + +retry: -+ cache = avc_lookup(client_avc_page, tsid, tclass); ++ cache = avc_lookup(client_avc_page, relid, secid, tclass); + if (!cache) -+ cache = avc_make_entry(client_avc_page, tsid, tclass); -+ -+ if (!sepgsql_avc_check_valid(client_avc_page)) ++ cache = avc_make_entry(client_avc_page, relid, secid, tclass); ++ if (!sepgsql_avc_check_valid()) + goto retry; + + denied = required & ~cache->allowed; @@ -5020,10 +5395,9 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu + : (required & cache->auditallow); + if (audited) + { -+ scon = sepgsqlSecurityLabelTransOut(client_avc_page->scontext); -+ tcon = securityTransSecLabelOut(tsid); -+ -+ avc_audit_common(scon, tcon, cache->tclass, ++ scontext = sepgsqlTransSecLabelOut(client_avc_page->scontext); ++ tcontext = securityTransSecLabelOut(relid, secid); ++ avc_audit_common(scontext, tcontext, cache->tclass, + !!denied, audited, audit_name); + } + @@ -5036,52 +5410,76 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu + } + + if (abort && !result) ++ { + ereport(ERROR, + (errcode(ERRCODE_SELINUX_ERROR), + errmsg("SELinux: security policy violation"))); ++ } ++ + return result; +} + ++bool ++sepgsqlClientHasPermsTup(Oid relid, HeapTuple tuple, ++ security_class_t tclass, ++ access_vector_t required, bool abort) ++{ ++ Oid secid = HeapTupleGetSecLabel(tuple); ++ const char *audit_name = sepgsqlAuditName(relid, tuple); ++ ++ return sepgsqlClientHasPermsSid(relid, secid, tclass, required, ++ audit_name, abort); ++} ++ +/* -+ * sepgsqlClientCreate ++ * sepgsqlClientCreateSecid + * sepgsqlClientCreateLabel -+ * It returns security label of database object newly created. -+ * sepgsqlClientCreate() returns it as sepgsql_sid_t, and -+ * sepgsqlClientCreateLabel() returns it as security_context_t. -+ * Please note that these types are not different in this version, -+ * but sepgsql_sid_t is planned to replace by an identifier. + */ +Oid -+sepgsqlClientCreate(Oid tsid, security_class_t tclass) ++sepgsqlClientCreateSecid(Oid trelid, Oid tsecid, ++ security_class_t tclass, Oid nrelid) +{ -+ avc_datum *cache; ++ avc_datum *cache; ++ int index; ++ Oid nsecid; + +retry: -+ cache = avc_lookup(client_avc_page, tsid, tclass); ++ cache = avc_lookup(client_avc_page, trelid, tsecid, tclass); + if (!cache) -+ cache = avc_make_entry(client_avc_page, tsid, tclass); -+ if (!sepgsql_avc_check_valid(client_avc_page)) ++ cache = avc_make_entry(client_avc_page, ++ trelid, tsecid, tclass); ++ ++ index = (nrelid % AVC_DATUM_NSID_SLOTS); ++ if (cache->nsid[index].relid != nrelid) ++ { ++ cache->nsid[index].secid ++ = securityRawSecLabelIn(nrelid, cache->ncontext); ++ cache->nsid[index].relid = nrelid; ++ } ++ nsecid = cache->nsid[index].secid; ++ ++ if (!sepgsql_avc_check_valid()) + goto retry; + -+ if (!OidIsValid(cache->nsid)) -+ cache->nsid = securityLookupSecurityId(cache->ncontext); -+ -+ return cache->nsid; ++ return nsecid; +} + +security_context_t -+sepgsqlClientCreateLabel(Oid tsid, security_class_t tclass) ++sepgsqlClientCreateLabel(Oid trelid, Oid tsecid, ++ security_class_t tclass) +{ -+ avc_datum *cache; ++ avc_datum *cache; + +retry: -+ cache = avc_lookup(client_avc_page, tsid, tclass); ++ cache = avc_lookup(client_avc_page, ++ trelid, tsecid, tclass); + if (!cache) -+ cache = avc_make_entry(client_avc_page, tsid, tclass); -+ if (!sepgsql_avc_check_valid(client_avc_page)) ++ cache = avc_make_entry(client_avc_page, ++ trelid, tsecid, tclass); ++ if (!sepgsql_avc_check_valid()) + goto retry; + -+ return pstrdup(cache->ncontext); ++ return cache->ncontext; +} + +/* @@ -5157,11 +5555,6 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu + if (avc_exception) + return true; + -+ if (security_check_context_raw(scontext) < 0) -+ scontext = sepgsqlGetUnlabeledLabel(); -+ if (security_check_context_raw(tcontext) < 0) -+ tcontext = sepgsqlGetUnlabeledLabel(); -+ + tclass_ex = sepgsqlTransToExternalClass(tclass); + if (tclass_ex > 0) + { @@ -5190,8 +5583,8 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu + : (required & avd.auditallow); + if (audited) + { -+ avc_audit_common(sepgsqlSecurityLabelTransOut(scontext), -+ sepgsqlSecurityLabelTransOut(tcontext), ++ avc_audit_common(sepgsqlTransSecLabelOut(scontext), ++ sepgsqlTransSecLabelOut(tcontext), + tclass, !!denied, audited, audit_name); + } + @@ -5216,11 +5609,6 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu + security_context_t ncontext, result; + security_class_t tclass_ex; + -+ if (security_check_context_raw(scontext) < 0) -+ scontext = sepgsqlGetUnlabeledLabel(); -+ if (security_check_context_raw(tcontext) < 0) -+ tcontext = sepgsqlGetUnlabeledLabel(); -+ + tclass_ex = sepgsqlTransToExternalClass(tclass); + if (security_compute_create_raw(scontext, tcontext, tclass_ex, &ncontext) < 0) + ereport(ERROR, @@ -5365,8 +5753,8 @@ diff -rpNU3 base/src/backend/security/sepgsql/avc.c sepgsql-new/src/backend/secu +} diff -rpNU3 base/src/backend/security/sepgsql/checker.c sepgsql-new/src/backend/security/sepgsql/checker.c --- base/src/backend/security/sepgsql/checker.c 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/backend/security/sepgsql/checker.c 2009-05-20 17:08:02.000000000 +0900 -@@ -0,0 +1,587 @@ ++++ sepgsql-new/src/backend/security/sepgsql/checker.c 2009-06-25 23:06:01.000000000 +0900 +@@ -0,0 +1,577 @@ +/* + * src/backend/security/sepgsql/checker.c + * walks on given Query tree and applies checks @@ -5451,10 +5839,13 @@ diff -rpNU3 base/src/backend/security/sepgsql/checker.c sepgsql-new/src/backend/ + AttrNumber attno; + int nattrs; + security_class_t tclass; -+ const char *audit_name; + + /* + * NOTE: HARDWIRED POLICY IN SE-POSTGRESQL ++ * - User cannot access RELKIND_TOASTVALUE by hand, because ++ * it is used to store variable length data within other ++ * column and tuples, and it should be considered as a part ++ * of content within them. + * - User cannot modify pg_rewrite.* by hand, because it holds + * a parsed Query tree which includes requiredPerms and + * RangeTblEntry with selectedCols/modifiedCols. @@ -5462,9 +5853,9 @@ diff -rpNU3 base/src/backend/security/sepgsql/checker.c sepgsql-new/src/backend/ + * are protected from unexpected manipulation.. + * + * - User cannot modify pg_security.* by hand, because it holds -+ * all the pairs of security identifier and label, so the -+ * correctness of access controls depends on these data are -+ * protected from unexpected manipulation. ++ * all the pairs of security identifier and label, so the ++ * correctness of access controls depends on these data are ++ * protected from unexpected manipulation. + * + * - User cannot modify pg_largeobject.* by hand, because we + * assumes largeobjects are accessed via certain functions @@ -5476,16 +5867,33 @@ diff -rpNU3 base/src/backend/security/sepgsql/checker.c sepgsql-new/src/backend/ + * these system catalogs by hand. Please use approariate + * interfaces. + */ -+ if ((required & (SEPG_DB_TABLE__UPDATE -+ | SEPG_DB_TABLE__INSERT -+ | SEPG_DB_TABLE__DELETE)) != 0 -+ && (relid == RewriteRelationId || -+ relid == SecurityRelationId || -+ relid == LargeObjectRelationId)) -+ ereport(ERROR, -+ (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("SE-PostgreSQL peremptorily prevent to modify " -+ "\"%s\" system catalog by hand", get_rel_name(relid)))); ++ if (!sepgsqlGetExceptionMode()) ++ { ++ switch (relid) ++ { ++ case RewriteRelationId: ++ case SecurityRelationId: ++ case LargeObjectRelationId: ++ if ((required & (SEPG_DB_TABLE__UPDATE | ++ SEPG_DB_TABLE__INSERT | ++ SEPG_DB_TABLE__DELETE)) != 0) ++ ereport(ERROR, ++ (errcode(ERRCODE_SELINUX_ERROR), ++ errmsg("SE-PostgreSQL prevent to modify \"%s\" " ++ "by hand due to the hardwired policy", ++ get_rel_name(relid)))); ++ break; ++ ++ default: ++ if (get_rel_relkind(relid) == RELKIND_TOASTVALUE) ++ ereport(ERROR, ++ (errcode(ERRCODE_SELINUX_ERROR), ++ errmsg("SE-PostgreSQL prevent to accuees \"%s\" " ++ "by hand due to the hardwired policy", ++ get_rel_name(relid)))); ++ break; ++ } ++ } + + /* + * Check db_table:{...} or db_sequence permissions @@ -5503,31 +5911,21 @@ diff -rpNU3 base/src/backend/security/sepgsql/checker.c sepgsql-new/src/backend/ + /* check db_sequence:{xxx} permission */ + if (tclass == SEPG_CLASS_DB_SEQUENCE) + { -+ access_vector_t seq_perms = 0; -+ + if (required & SEPG_DB_TABLE__SELECT) -+ seq_perms |= SEPG_DB_SEQUENCE__GET_VALUE; -+ /* -+ * Now we cannot modify sequence by INSERT/UPDATE/DELETE -+ */ -+ if (seq_perms != 0) + { -+ audit_name = sepgsqlAuditName(RelationRelationId, tuple); -+ sepgsqlClientHasPerms(HeapTupleGetSecLabel(tuple), -+ SEPG_CLASS_DB_SEQUENCE, -+ seq_perms, -+ audit_name, true); ++ sepgsqlClientHasPermsTup(RelationRelationId, tuple, ++ SEPG_CLASS_DB_SEQUENCE, ++ SEPG_DB_SEQUENCE__GET_VALUE, ++ true); + } + } + ReleaseSysCache(tuple); + return; + } + -+ audit_name = sepgsqlAuditName(RelationRelationId, tuple); -+ sepgsqlClientHasPerms(HeapTupleGetSecLabel(tuple), -+ SEPG_CLASS_DB_TABLE, -+ required, -+ audit_name, true); ++ sepgsqlClientHasPermsTup(RelationRelationId, tuple, ++ SEPG_CLASS_DB_TABLE, ++ required, true); + + nattrs = ((Form_pg_class) GETSTRUCT(tuple))->relnatts; + @@ -5572,11 +5970,9 @@ diff -rpNU3 base/src/backend/security/sepgsql/checker.c sepgsql-new/src/backend/ + elog(ERROR, "attribute %d of relation %u does not exist", + attno, relid); + -+ audit_name = sepgsqlAuditName(AttributeRelationId, tuple); -+ sepgsqlClientHasPerms(HeapTupleGetSecLabel(tuple), -+ SEPG_CLASS_DB_COLUMN, -+ attperms, -+ audit_name, true); ++ sepgsqlClientHasPermsTup(AttributeRelationId, tuple, ++ SEPG_CLASS_DB_COLUMN, ++ attperms, true); + ReleaseSysCache(tuple); + } + @@ -5717,19 +6113,15 @@ diff -rpNU3 base/src/backend/security/sepgsql/checker.c sepgsql-new/src/backend/ +sepgsqlExecScan(Relation rel, HeapTuple tuple, uint32 required, bool abort) +{ + security_class_t tclass; -+ const char *audit_name; + + if (!sepgsqlIsEnabled() || + !required || + RelationGetForm(rel)->relkind != RELKIND_RELATION) + return true; + -+ audit_name = sepgsqlAuditName(RelationGetRelid(rel), tuple); + tclass = sepgsqlTupleObjectClass(RelationGetRelid(rel), tuple); -+ return sepgsqlClientHasPerms(HeapTupleGetSecLabel(tuple), -+ tclass, -+ required, -+ audit_name, abort); ++ return sepgsqlClientHasPermsTup(RelationGetRelid(rel), tuple, ++ tclass, required, abort); +} + +uint32 @@ -5763,7 +6155,6 @@ diff -rpNU3 base/src/backend/security/sepgsql/checker.c sepgsql-new/src/backend/ +{ + Form_pg_proc oldpro, newpro; + Datum oldbin, newbin; -+ char *filename; + bool isnull; + + newpro = (Form_pg_proc) GETSTRUCT(newtup); @@ -5772,21 +6163,20 @@ diff -rpNU3 base/src/backend/security/sepgsql/checker.c sepgsql-new/src/backend/ + + newbin = SysCacheGetAttr(PROCOID, newtup, + Anum_pg_proc_probin, &isnull); -+ if (isnull) -+ return; -+ -+ if (HeapTupleIsValid(oldtup)) ++ if (!isnull) + { -+ oldpro = (Form_pg_proc) GETSTRUCT(oldtup); -+ oldbin = SysCacheGetAttr(PROCOID, oldtup, -+ Anum_pg_proc_probin, &isnull); -+ if (!isnull && -+ oldpro->prolang == newpro->prolang && -+ DatumGetBool(DirectFunctionCall2(byteaeq, oldbin, newbin))) -+ return; /* no need to check, if unchanged */ ++ if (HeapTupleIsValid(oldtup)) ++ { ++ oldpro = (Form_pg_proc) GETSTRUCT(oldtup); ++ oldbin = SysCacheGetAttr(PROCOID, oldtup, ++ Anum_pg_proc_probin, &isnull); ++ if (!isnull && ++ oldpro->prolang == newpro->prolang && ++ DatumGetBool(DirectFunctionCall2(byteaeq, oldbin, newbin))) ++ return; /* no need to check, if unchanged */ ++ } ++ sepgsqlCheckDatabaseInstallModule(); + } -+ filename = TextDatumGetCString(newbin); -+ sepgsqlCheckDatabaseInstallModule(filename); +} + +/* @@ -5822,7 +6212,6 @@ diff -rpNU3 base/src/backend/security/sepgsql/checker.c sepgsql-new/src/backend/ +{ + Oid relid = RelationGetRelid(rel); + security_class_t tclass; -+ const char *audit_name; + + if (!sepgsqlIsEnabled()) + return true; @@ -5845,11 +6234,9 @@ diff -rpNU3 base/src/backend/security/sepgsql/checker.c sepgsql-new/src/backend/ + sepgsqlCheckProcedureInstall(rel, newtup, NULL); + + tclass = sepgsqlTupleObjectClass(relid, newtup); -+ audit_name = sepgsqlAuditName(relid, newtup); -+ return sepgsqlClientHasPerms(HeapTupleGetSecLabel(newtup), -+ tclass, -+ SEPG_DB_TUPLE__INSERT, -+ audit_name, internal); ++ return sepgsqlClientHasPermsTup(relid, newtup, tclass, ++ SEPG_DB_TUPLE__INSERT, ++ internal); +} + +bool @@ -5860,7 +6247,6 @@ diff -rpNU3 base/src/backend/security/sepgsql/checker.c sepgsql-new/src/backend/ + access_vector_t required = 0; + security_class_t newclass; + security_class_t oldclass; -+ const char *audit_name; + + if (!sepgsqlIsEnabled()) + return true; @@ -5896,24 +6282,18 @@ diff -rpNU3 base/src/backend/security/sepgsql/checker.c sepgsql-new/src/backend/ + /* check db_procedure:{install}, if necessary */ + sepgsqlCheckProcedureInstall(rel, newtup, oldtup); + -+ audit_name = sepgsqlAuditName(relid, newtup); + if (required != 0) + { -+ audit_name = sepgsqlAuditName(relid, oldtup); -+ if (!sepgsqlClientHasPerms(HeapTupleGetSecLabel(oldtup), -+ oldclass, -+ required, -+ audit_name, internal)) ++ if (!sepgsqlClientHasPermsTup(relid, oldtup, oldclass, ++ required, false)) + return false; + } + + if ((required & SEPG_DB_TUPLE__RELABELFROM) != 0) + { -+ audit_name = sepgsqlAuditName(relid, newtup); -+ if (!sepgsqlClientHasPerms(HeapTupleGetSecLabel(newtup), -+ newclass, -+ SEPG_DB_TUPLE__RELABELTO, -+ audit_name, internal)) ++ if (!sepgsqlClientHasPermsTup(relid, newtup, newclass, ++ SEPG_DB_TUPLE__RELABELTO, ++ internal)) + return false; + } + @@ -5926,7 +6306,6 @@ diff -rpNU3 base/src/backend/security/sepgsql/checker.c sepgsql-new/src/backend/ + Oid relid = RelationGetRelid(rel); + security_class_t tclass; + access_vector_t required = 0; -+ const char *audit_name; + + if (!sepgsqlIsEnabled()) + return true; @@ -5943,12 +6322,11 @@ diff -rpNU3 base/src/backend/security/sepgsql/checker.c sepgsql-new/src/backend/ + + if (required != 0) + { ++ + tclass = sepgsqlTupleObjectClass(relid, oldtup); -+ audit_name = sepgsqlAuditName(relid, oldtup); -+ if (sepgsqlClientHasPerms(HeapTupleGetSecLabel(oldtup), -+ tclass, -+ SEPG_DB_TUPLE__DELETE, -+ audit_name, internal)) ++ if (!sepgsqlClientHasPermsTup(relid, oldtup, tclass, ++ SEPG_DB_TUPLE__DELETE, ++ internal)) + return false; + } + @@ -5956,8 +6334,8 @@ diff -rpNU3 base/src/backend/security/sepgsql/checker.c sepgsql-new/src/backend/ +} diff -rpNU3 base/src/backend/security/sepgsql/core.c sepgsql-new/src/backend/security/sepgsql/core.c --- base/src/backend/security/sepgsql/core.c 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/backend/security/sepgsql/core.c 2009-05-20 17:08:02.000000000 +0900 -@@ -0,0 +1,342 @@ ++++ sepgsql-new/src/backend/security/sepgsql/core.c 2009-06-10 17:43:08.000000000 +0900 +@@ -0,0 +1,326 @@ +/* + * src/backend/security/sepgsql/core.c + * The core facility of SE-PostgreSQL @@ -5981,7 +6359,6 @@ diff -rpNU3 base/src/backend/security/sepgsql/core.c sepgsql-new/src/backend/sec + +static security_context_t clientLabel = NULL; +static security_context_t serverLabel = NULL; -+static security_context_t unlabeledLabel = NULL; + +security_context_t +sepgsqlGetServerLabel(void) @@ -6046,21 +6423,6 @@ diff -rpNU3 base/src/backend/security/sepgsql/core.c sepgsql-new/src/backend/sec + return new_client; +} + -+security_context_t -+sepgsqlGetUnlabeledLabel(void) -+{ -+ if (!unlabeledLabel) -+ { -+ if (security_get_initial_context_raw("unlabeled", -+ &unlabeledLabel) < 0) -+ -+ ereport(ERROR, -+ (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("SELinux: could not get unlabeled label"))); -+ } -+ return unlabeledLabel; -+} -+ +/* + * sepgsqlIsEnabled() + * @@ -6115,7 +6477,7 @@ diff -rpNU3 base/src/backend/security/sepgsql/core.c sepgsql-new/src/backend/sec + errmsg("SELinux: disabled now"))); + + context = sepgsqlGetClientLabel(); -+ context = sepgsqlSecurityLabelTransOut(context); ++ context = sepgsqlTransSecLabelOut(context); + return CStringGetTextDatum(context); +} + @@ -6130,7 +6492,7 @@ diff -rpNU3 base/src/backend/security/sepgsql/core.c sepgsql-new/src/backend/sec + errmsg("SELinux: disabled now"))); + + context = sepgsqlGetServerLabel(); -+ context = sepgsqlSecurityLabelTransOut(context); ++ context = sepgsqlTransSecLabelOut(context); + return CStringGetTextDatum(context); +} + @@ -6262,7 +6624,7 @@ diff -rpNU3 base/src/backend/security/sepgsql/core.c sepgsql-new/src/backend/sec + if (range) + appendStringInfo(&newcon, ":%s", range); + -+ return CStringGetTextDatum(sepgsqlSecurityLabelTransOut(newcon.data)); ++ return CStringGetTextDatum(sepgsqlTransSecLabelOut(newcon.data)); +} + +Datum @@ -6385,8 +6747,8 @@ diff -rpNU3 base/src/backend/security/sepgsql/dummy.c sepgsql-new/src/backend/se +} diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/security/sepgsql/hooks.c --- base/src/backend/security/sepgsql/hooks.c 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/backend/security/sepgsql/hooks.c 2009-05-20 17:08:02.000000000 +0900 -@@ -0,0 +1,985 @@ ++++ sepgsql-new/src/backend/security/sepgsql/hooks.c 2009-06-11 10:19:07.000000000 +0900 +@@ -0,0 +1,905 @@ +/* + * src/backend/security/sepgsql/hooks.c + * SE-PostgreSQL security hooks @@ -6434,11 +6796,18 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + * sepgsqlCheckDatabaseSuperuser + * checks db_database:{superuser} permission when the client tries + * to perform as a superuser on the given databse. ++ * ++ * 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. + */ +static bool -+checkDatabaseCommon(Oid database_oid, access_vector_t perms) ++checkDatabaseCommon(Oid datoid, access_vector_t perms, bool abort) +{ -+ const char *audit_name; + HeapTuple tuple; + bool rc; + @@ -6446,17 +6815,14 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + return true; + + tuple = SearchSysCache(DATABASEOID, -+ ObjectIdGetDatum(database_oid), ++ ObjectIdGetDatum(datoid), + 0, 0, 0); + if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "SELinux: cache lookup failed for database: %u", -+ database_oid); ++ elog(ERROR, "cache lookup failed for database: %u", datoid); + -+ audit_name = sepgsqlAuditName(DatabaseRelationId, tuple); -+ rc = sepgsqlClientHasPerms(HeapTupleGetSecLabel(tuple), -+ SEPG_CLASS_DB_DATABASE, -+ perms, -+ audit_name, false); ++ rc = sepgsqlClientHasPermsTup(DatabaseRelationId, tuple, ++ SEPG_CLASS_DB_DATABASE, ++ perms, abort); + ReleaseSysCache(tuple); + + return rc; @@ -6466,74 +6832,26 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se +sepgsqlCheckDatabaseAccess(Oid database_oid) +{ + return checkDatabaseCommon(database_oid, -+ SEPG_DB_DATABASE__ACCESS); ++ SEPG_DB_DATABASE__ACCESS, ++ false); +} + +bool +sepgsqlCheckDatabaseSuperuser(void) +{ + return checkDatabaseCommon(MyDatabaseId, -+ SEPG_DB_DATABASE__SUPERUSER); ++ SEPG_DB_DATABASE__SUPERUSER, ++ false); +} + -+/* -+ * sepgsqlDatabaseInstallModule -+ * checks db_database:{install_module} permission on -+ * the current database and a given loadable module. -+ */ +void -+sepgsqlCheckDatabaseInstallModule(const char *filename) ++sepgsqlCheckDatabaseInstallModule(void) +{ -+ security_context_t fcontext; -+ HeapTuple tuple; -+ const char *audit_name; -+ char *fullpath; -+ -+ if (!sepgsqlIsEnabled()) -+ return; -+ -+ /* db_database:{module_install} on database */ -+ tuple = SearchSysCache(DATABASEOID, -+ ObjectIdGetDatum(MyDatabaseId), -+ 0, 0, 0); -+ if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "SELinux: cache lookup failed for database: %u", -+ MyDatabaseId); -+ -+ audit_name = sepgsqlAuditName(DatabaseRelationId, tuple); -+ sepgsqlClientHasPerms(HeapTupleGetSecLabel(tuple), -+ SEPG_CLASS_DB_DATABASE, -+ SEPG_DB_DATABASE__INSTALL_MODULE, -+ audit_name, true); -+ ReleaseSysCache(tuple); -+ -+ /* db_databse:module_install on *.so files */ -+ fullpath = expand_dynamic_library_name(filename); -+ if (getfilecon_raw(fullpath, &fcontext) < 0) -+ ereport(ERROR, -+ (errcode_for_file_access(), -+ errmsg("could not access file \"%s\": %m", fullpath))); -+ PG_TRY(); -+ { -+ sepgsqlComputePerms(sepgsqlGetClientLabel(), -+ fcontext, -+ SEPG_CLASS_DB_DATABASE, -+ SEPG_DB_DATABASE__INSTALL_MODULE, -+ fullpath, true); -+ } -+ PG_CATCH(); -+ { -+ freecon(fcontext); -+ PG_RE_THROW(); -+ } -+ PG_END_TRY(); -+ freecon(fcontext); ++ checkDatabaseCommon(MyDatabaseId, ++ SEPG_DB_DATABASE__INSTALL_MODULE, ++ true); +} + -+/* -+ * sepgsqlDatabaseLoadModule -+ * checks capability of database to load a specific library -+ */ +void +sepgsqlCheckDatabaseLoadModule(const char *filename) +{ @@ -6543,6 +6861,13 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + + 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, @@ -6551,13 +6876,10 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for database: %u", MyDatabaseId); + -+ dbcon = securityLookupSecurityLabel(HeapTupleGetSecLabel(tuple)); -+ ++ dbcon = securityRawSecLabelOut(DatabaseRelationId, ++ HeapTupleGetSecLabel(tuple)); + ReleaseSysCache(tuple); + -+ if (!dbcon || security_check_context(dbcon) < 0) -+ dbcon = sepgsqlGetUnlabeledLabel(); -+ + /* Get library context */ + if (getfilecon_raw(filename, &filecon) < 0) + ereport(ERROR, @@ -6583,15 +6905,17 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se +/* + * sepgsqlCheckSchemaSearch + * checks db_schema:{search} permission when the given namespace -+ * is searched. ++ * is searched. It is not available on temporary namespace due to ++ * the limitation of implementation. + * -+ * db_schema:{add_object remove_object} permissions is not now -+ * implemented. ++ * sepgsqlCheckSchemaAddRemove ++ * checks db_schema:{add_object} and db_schema:{remove_object} ++ * permission when a database object within a certain schema ++ * is added or removed. + */ +static bool +sepgsqlCheckSchemaCommon(Oid nsid, access_vector_t required, bool abort) +{ -+ const char *audit_name; + security_class_t tclass; + HeapTuple tuple; + bool rc; @@ -6602,18 +6926,16 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for namespace: %u", nsid); + -+ audit_name = sepgsqlAuditName(NamespaceRelationId, tuple); + tclass = sepgsqlTupleObjectClass(NamespaceRelationId, tuple); -+ rc = sepgsqlClientHasPerms(HeapTupleGetSecLabel(tuple), -+ tclass, -+ required, -+ audit_name, false); ++ rc = sepgsqlClientHasPermsTup(NamespaceRelationId, tuple, ++ tclass, required, false); + ReleaseSysCache(tuple); + + return rc; +} + -+bool sepgsqlCheckSchemaSearch(Oid nsid) ++bool ++sepgsqlCheckSchemaSearch(Oid nsid) +{ + if (!sepgsqlIsEnabled()) + return true; @@ -6698,11 +7020,15 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + * sepgsqlCheckTableTruncate + * checks db_table:{delete} permission when the client tries to + * truncate the given relation. ++ * ++ * 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 perms) +{ -+ const char *audit_name; + security_class_t tclass; + HeapTuple tuple; + @@ -6715,11 +7041,9 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + tclass = sepgsqlTupleObjectClass(RelationRelationId, tuple); + if (tclass == SEPG_CLASS_DB_TABLE) + { -+ audit_name = sepgsqlAuditName(RelationRelationId, tuple); -+ sepgsqlClientHasPerms(HeapTupleGetSecLabel(tuple), -+ SEPG_CLASS_DB_TABLE, -+ perms, -+ audit_name, true); ++ sepgsqlClientHasPermsTup(RelationRelationId, tuple, ++ SEPG_CLASS_DB_TABLE, ++ perms, true); + } + ReleaseSysCache(tuple); +} @@ -6740,7 +7064,6 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + HeapScanDesc scan; + HeapTuple tuple; + security_class_t tclass; -+ const char *audit_name; + + if (!sepgsqlIsEnabled()) + return; @@ -6754,11 +7077,8 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + { + tclass = sepgsqlTupleObjectClass(RelationGetRelid(rel), tuple); -+ audit_name = sepgsqlAuditName(RelationGetRelid(rel), tuple); -+ sepgsqlClientHasPerms(HeapTupleGetSecLabel(tuple), -+ tclass, -+ SEPG_DB_TUPLE__DELETE, -+ audit_name, true); ++ sepgsqlClientHasPermsTup(RelationGetRelid(rel), tuple, tclass, ++ SEPG_DB_TUPLE__DELETE, true); + } + heap_endscan(scan); +} @@ -6766,7 +7086,6 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se +void +sepgsqlCheckTableReference(Relation rel, int16 *attnums, int natts) +{ -+ const char *audit_name; + HeapTuple tuple; + int i; + @@ -6786,24 +7105,31 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + elog(ERROR, "cache lookup failed for attribute %u of %s", + attnums[i], RelationGetRelationName(rel)); + -+ audit_name = sepgsqlAuditName(AttributeRelationId, tuple); -+ sepgsqlClientHasPerms(HeapTupleGetSecLabel(tuple), -+ SEPG_CLASS_DB_COLUMN, -+ SEPG_DB_COLUMN__REFERENCE, -+ audit_name, true); ++ sepgsqlClientHasPermsTup(AttributeRelationId, tuple, ++ SEPG_CLASS_DB_COLUMN, ++ SEPG_DB_COLUMN__REFERENCE, ++ true); + ReleaseSysCache(tuple); + } +} + +/* -+ * sepgsqlCheckSequenceXXXX ++ * sepgsqlCheckSequenceGetValue ++ * checks db_sequence:{get_value} permission when the client ++ * refers the given sequence object without any increments. + * -+ * It checks permissions on db_sequence objects. ++ * sepgsqlCheckSequenceNextValue ++ * checks db_sequence:{next_value} permission when the client ++ * fetchs a value from the given sequence object with an ++ * increment of the counter. ++ * ++ * sepgsqlCheckSequenceSetValue ++ * checks db_sequence:{set_value} permission when the client ++ * set a discretionary value on the given sequence object. + */ +static void +sepgsqlCheckSequenceCommon(Oid seqid, access_vector_t required) +{ -+ const char *audit_name; + HeapTuple tuple; + + if (!sepgsqlIsEnabled()) @@ -6815,11 +7141,9 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for sequence: %u", seqid); + -+ audit_name = sepgsqlAuditName(RelationRelationId, tuple); -+ sepgsqlClientHasPerms(HeapTupleGetSecLabel(tuple), -+ SEPG_CLASS_DB_SEQUENCE, -+ required, -+ audit_name, true); ++ sepgsqlClientHasPermsTup(RelationRelationId, tuple, ++ SEPG_CLASS_DB_SEQUENCE, ++ required, true); + ReleaseSysCache(tuple); +} + @@ -6845,7 +7169,6 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + */ +bool sepgsqlCheckProcedureExecute(Oid proc_oid) +{ -+ const char *audit_name; + HeapTuple tuple; + bool rc; + @@ -6861,11 +7184,10 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "SELinux: cache lookup failed for procedure: %u", proc_oid); + -+ audit_name = sepgsqlAuditName(ProcedureRelationId, tuple); -+ rc = sepgsqlClientHasPerms(HeapTupleGetSecLabel(tuple), -+ SEPG_CLASS_DB_PROCEDURE, -+ SEPG_DB_PROCEDURE__EXECUTE, -+ audit_name, false); ++ rc = sepgsqlClientHasPermsTup(ProcedureRelationId, tuple, ++ SEPG_CLASS_DB_PROCEDURE, ++ SEPG_DB_PROCEDURE__EXECUTE, ++ false); + ReleaseSysCache(tuple); + + return rc; @@ -6918,14 +7240,14 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se +void +sepgsqlCheckProcedureEntrypoint(FmgrInfo *flinfo, HeapTuple protup) +{ -+ struct TrustedProcedureCache *tcache; ++ struct TrustedProcedureCache *tcache; + security_context_t newcon; -+ const char *audit_name; + + if (!sepgsqlIsEnabled()) + return; + -+ newcon = sepgsqlClientCreateLabel(HeapTupleGetSecLabel(protup), ++ newcon = sepgsqlClientCreateLabel(ProcedureRelationId, ++ HeapTupleGetSecLabel(protup), + SEPG_CLASS_PROCESS); + + /* Do nothing, if it is not a trusted procedure */ @@ -6933,11 +7255,10 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + return; + + /* check db_procedure:{entrypoint} */ -+ audit_name = sepgsqlAuditName(ProcedureRelationId, protup); -+ sepgsqlClientHasPerms(HeapTupleGetSecLabel(protup), -+ SEPG_CLASS_DB_PROCEDURE, -+ SEPG_DB_PROCEDURE__ENTRYPOINT, -+ audit_name, true); ++ sepgsqlClientHasPermsTup(ProcedureRelationId, protup, ++ SEPG_CLASS_DB_PROCEDURE, ++ SEPG_DB_PROCEDURE__ENTRYPOINT, ++ true); + + /* check process:{transition} */ + sepgsqlComputePerms(sepgsqlGetClientLabel(), @@ -6950,7 +7271,7 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + tcache = MemoryContextAllocZero(flinfo->fn_mcxt, + sizeof(*tcache) + strlen(newcon)); + memcpy(&tcache->flinfo, flinfo, sizeof(*flinfo)); -+ strcmp(tcache->newcon, newcon); ++ strcpy(tcache->newcon, newcon); + flinfo->fn_addr = sepgsqlTrustedProcedure; + flinfo->fn_extra = tcache; +} @@ -6966,7 +7287,6 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se +static void +checkProcedureInstall(Oid proc_oid) +{ -+ const char *audit_name; + HeapTuple tuple; + + if (!OidIsValid(proc_oid)) @@ -6985,11 +7305,10 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + if (!HeapTupleIsValid(tuple)) + return; + -+ audit_name = sepgsqlAuditName(ProcedureRelationId, tuple); -+ sepgsqlClientHasPerms(HeapTupleGetSecLabel(tuple), -+ SEPG_CLASS_DB_PROCEDURE, -+ SEPG_DB_PROCEDURE__INSTALL, -+ audit_name, true); ++ sepgsqlClientHasPermsTup(ProcedureRelationId, tuple, ++ SEPG_CLASS_DB_PROCEDURE, ++ SEPG_DB_PROCEDURE__INSTALL, ++ true); + ReleaseSysCache(tuple); +} + @@ -7102,10 +7421,10 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + + /* set a default security context */ + sepgsqlSetDefaultSecLabel(rel, lotup); -+ sepgsqlClientHasPerms(HeapTupleGetSecLabel(lotup), -+ SEPG_CLASS_DB_BLOB, -+ SEPG_DB_BLOB__CREATE, -+ NULL, true); ++ sepgsqlClientHasPermsTup(RelationGetRelid(rel), lotup, ++ SEPG_CLASS_DB_BLOB, ++ SEPG_DB_BLOB__CREATE, ++ true); +} + +/* @@ -7118,10 +7437,10 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + if (!sepgsqlIsEnabled()) + return; + -+ sepgsqlClientHasPerms(HeapTupleGetSecLabel(lotup), -+ SEPG_CLASS_DB_BLOB, -+ SEPG_DB_BLOB__DROP, -+ NULL, true); ++ sepgsqlClientHasPermsTup(RelationGetRelid(rel), lotup, ++ SEPG_CLASS_DB_BLOB, ++ SEPG_DB_BLOB__DROP, ++ true); +} + +/* @@ -7134,10 +7453,11 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + if (!sepgsqlIsEnabled()) + return; + -+ sepgsqlClientHasPerms(lobj->secid, -+ SEPG_CLASS_DB_BLOB, -+ SEPG_DB_BLOB__READ, -+ NULL, true); ++ sepgsqlClientHasPermsSid(LargeObjectRelationId, ++ lobj->secid, ++ SEPG_CLASS_DB_BLOB, ++ SEPG_DB_BLOB__READ, ++ NULL, true); +} + +/* @@ -7150,10 +7470,11 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + if (!sepgsqlIsEnabled()) + return; + -+ sepgsqlClientHasPerms(lobj->secid, -+ SEPG_CLASS_DB_BLOB, -+ SEPG_DB_BLOB__WRITE, -+ NULL, true); ++ sepgsqlClientHasPermsSid(LargeObjectRelationId, ++ lobj->secid, ++ SEPG_CLASS_DB_BLOB, ++ SEPG_DB_BLOB__WRITE, ++ NULL, true); +} + +/* @@ -7166,10 +7487,10 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + if (!sepgsqlIsEnabled()) + return; + -+ sepgsqlClientHasPerms(HeapTupleGetSecLabel(tuple), -+ SEPG_CLASS_DB_BLOB, -+ SEPG_DB_BLOB__GETATTR, -+ NULL, true); ++ sepgsqlClientHasPermsTup(LargeObjectRelationId, tuple, ++ SEPG_CLASS_DB_BLOB, ++ SEPG_DB_BLOB__GETATTR, ++ true); +} + +/* @@ -7182,10 +7503,10 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + if (!sepgsqlIsEnabled()) + return; + -+ sepgsqlClientHasPerms(HeapTupleGetSecLabel(tuple), -+ SEPG_CLASS_DB_BLOB, -+ SEPG_DB_BLOB__SETATTR, -+ NULL, true); ++ sepgsqlClientHasPermsTup(LargeObjectRelationId, tuple, ++ SEPG_CLASS_DB_BLOB, ++ SEPG_DB_BLOB__SETATTR, ++ true); +} + +/* @@ -7196,37 +7517,17 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se +sepgsqlCheckBlobExport(LargeObjectDesc *lobj, + int fdesc, const char *filename) +{ -+ security_context_t fcontext; -+ security_class_t fclass; -+ + if (!sepgsqlIsEnabled()) + return; + -+ sepgsqlClientHasPerms(lobj->secid, -+ SEPG_CLASS_DB_BLOB, -+ SEPG_DB_BLOB__READ | SEPG_DB_BLOB__EXPORT, -+ NULL, true); -+ -+ fclass = sepgsqlFileObjectClass(fdesc); -+ if (fgetfilecon_raw(fdesc, &fcontext) < 0) -+ ereport(ERROR, -+ (errcode_for_file_access(), -+ errmsg("could not get security context \"%s\"", filename))); -+ PG_TRY(); -+ { -+ sepgsqlComputePerms(sepgsqlGetClientLabel(), -+ fcontext, -+ fclass, -+ SEPG_FILE__WRITE, -+ filename, true); -+ } -+ PG_CATCH(); -+ { -+ freecon(fcontext); -+ PG_RE_THROW(); -+ } -+ PG_END_TRY(); -+ freecon(fcontext); ++ /* db_blob:{read export} */ ++ sepgsqlClientHasPermsSid(LargeObjectRelationId, ++ lobj->secid, ++ SEPG_CLASS_DB_BLOB, ++ SEPG_DB_BLOB__READ | SEPG_DB_BLOB__EXPORT, ++ NULL, true); ++ /* file:{write} */ ++ sepgsqlCheckFileWrite(fdesc, filename); +} + +/* @@ -7237,37 +7538,17 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se +sepgsqlCheckBlobImport(LargeObjectDesc *lobj, + int fdesc, const char *filename) +{ -+ security_context_t fcontext; -+ security_class_t fclass; -+ + if (!sepgsqlIsEnabled()) + return; + -+ sepgsqlClientHasPerms(lobj->secid, -+ SEPG_CLASS_DB_BLOB, -+ SEPG_DB_BLOB__WRITE | SEPG_DB_BLOB__IMPORT, -+ NULL, true); -+ -+ fclass = sepgsqlFileObjectClass(fdesc); -+ if (fgetfilecon_raw(fdesc, &fcontext) < 0) -+ ereport(ERROR, -+ (errcode_for_file_access(), -+ errmsg("could not get security context \"%s\"", filename))); -+ PG_TRY(); -+ { -+ sepgsqlComputePerms(sepgsqlGetClientLabel(), -+ fcontext, -+ fclass, -+ SEPG_FILE__READ, -+ filename, true); -+ } -+ PG_CATCH(); -+ { -+ freecon(fcontext); -+ PG_RE_THROW(); -+ } -+ PG_END_TRY(); -+ freecon(fcontext); ++ /* db_blob:{write import} */ ++ sepgsqlClientHasPermsSid(LargeObjectRelationId, ++ lobj->secid, ++ SEPG_CLASS_DB_BLOB, ++ SEPG_DB_BLOB__WRITE | SEPG_DB_BLOB__IMPORT, ++ NULL, true); ++ /* file:{read} */ ++ sepgsqlCheckFileRead(fdesc, filename); +} + +/* @@ -7282,17 +7563,17 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + if (HeapTupleGetSecLabel(oldtup) != HeapTupleGetSecLabel(newtup)) + required |= SEPG_DB_BLOB__RELABELFROM; + -+ sepgsqlClientHasPerms(HeapTupleGetSecLabel(oldtup), -+ SEPG_CLASS_DB_BLOB, -+ required, -+ NULL, true); ++ sepgsqlClientHasPermsTup(LargeObjectRelationId, oldtup, ++ SEPG_CLASS_DB_BLOB, ++ required, ++ true); + if ((required & SEPG_DB_BLOB__RELABELFROM) == 0) + return; + -+ sepgsqlClientHasPerms(HeapTupleGetSecLabel(newtup), -+ SEPG_CLASS_DB_BLOB, -+ SEPG_DB_BLOB__RELABELTO, -+ NULL, true); ++ sepgsqlClientHasPermsTup(LargeObjectRelationId, newtup, ++ SEPG_CLASS_DB_BLOB, ++ SEPG_DB_BLOB__RELABELTO, ++ true); +} + +/* @@ -7352,30 +7633,31 @@ diff -rpNU3 base/src/backend/security/sepgsql/hooks.c sepgsql-new/src/backend/se + * procedure, we should not allow it inlined. + */ +bool -+sepgsqlAllowFunctionInlined(HeapTuple proc_tuple) ++sepgsqlAllowFunctionInlined(HeapTuple protup) +{ -+ security_context_t context; ++ security_context_t newcon; + + if (!sepgsqlIsEnabled()) + return true; + -+ context = sepgsqlClientCreateLabel(HeapTupleGetSecLabel(proc_tuple), -+ SEPG_CLASS_PROCESS); ++ newcon = sepgsqlClientCreateLabel(ProcedureRelationId, ++ HeapTupleGetSecLabel(protup), ++ SEPG_CLASS_PROCESS); + /* + * 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. + */ -+ if (strcmp(sepgsqlGetClientLabel(), context) == 0) ++ if (strcmp(sepgsqlGetClientLabel(), newcon) == 0) + return true; + + return false; +} diff -rpNU3 base/src/backend/security/sepgsql/label.c sepgsql-new/src/backend/security/sepgsql/label.c --- base/src/backend/security/sepgsql/label.c 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/backend/security/sepgsql/label.c 2009-06-09 16:05:29.000000000 +0900 -@@ -0,0 +1,521 @@ ++++ sepgsql-new/src/backend/security/sepgsql/label.c 2009-06-19 15:02:12.000000000 +0900 +@@ -0,0 +1,560 @@ +/* + * src/backend/security/sepgsql/label.c + * SE-PostgreSQL security label management @@ -7391,6 +7673,7 @@ diff -rpNU3 base/src/backend/security/sepgsql/label.c sepgsql-new/src/backend/se +#include "catalog/pg_attribute.h" +#include "catalog/pg_class.h" +#include "catalog/pg_database.h" ++#include "catalog/pg_largeobject.h" +#include "catalog/pg_namespace.h" +#include "catalog/pg_proc.h" +#include "catalog/pg_security.h" @@ -7480,7 +7763,7 @@ diff -rpNU3 base/src/backend/security/sepgsql/label.c sepgsql-new/src/backend/se + + /* An entry found */ + FreeFile(filp); -+ return securityLookupSecurityId(context); ++ return securityTransSecLabelIn(DatabaseRelationId, context); + } + FreeFile(filp); + @@ -7488,57 +7771,60 @@ diff -rpNU3 base/src/backend/security/sepgsql/label.c sepgsql-new/src/backend/se + context = sepgsqlComputeCreate(sepgsqlGetClientLabel(), + sepgsqlGetClientLabel(), + SEPG_CLASS_DB_DATABASE); -+ return securityLookupSecurityId(context); ++ return securityTransSecLabelIn(DatabaseRelationId, context); +} + +static Oid -+defaultSchemaSecLabelCommon(security_class_t tclass) ++defaultSecLabelWithDatabase(Oid relid, Oid datoid, security_class_t tclass) +{ + HeapTuple tuple; -+ Oid newsid; ++ Oid datsid; + + if (IsBootstrapProcessingMode()) + { + static Oid cached = InvalidOid; + + if (!OidIsValid(cached)) -+ cached = sepgsqlClientCreate(defaultDatabaseSecLabel(), tclass); ++ cached = defaultDatabaseSecLabel(); ++ datsid = cached; ++ } ++ else ++ { ++ tuple = SearchSysCache(DATABASEOID, ++ ObjectIdGetDatum(datoid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for database: %u", datoid); ++ datsid = HeapTupleGetSecLabel(tuple); + -+ return cached; ++ ReleaseSysCache(tuple); + } + -+ tuple = SearchSysCache(DATABASEOID, -+ ObjectIdGetDatum(MyDatabaseId), -+ 0, 0, 0); -+ if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "cache lookup failed for database: %u", MyDatabaseId); -+ -+ newsid = sepgsqlClientCreate(HeapTupleGetSecLabel(tuple), tclass); -+ -+ ReleaseSysCache(tuple); -+ -+ return newsid; -+ -+ ++ return sepgsqlClientCreateSecid(DatabaseRelationId, datsid, ++ tclass, relid); +} + +static Oid +defaultSchemaSecLabel(void) +{ -+ return defaultSchemaSecLabelCommon(SEPG_CLASS_DB_SCHEMA); ++ return defaultSecLabelWithDatabase(NamespaceRelationId, ++ MyDatabaseId, ++ SEPG_CLASS_DB_SCHEMA); +} + +static Oid +defaultSchemaTempSecLabel(void) +{ -+ return defaultSchemaSecLabelCommon(SEPG_CLASS_DB_SCHEMA_TEMP); ++ return defaultSecLabelWithDatabase(NamespaceRelationId, ++ MyDatabaseId, ++ SEPG_CLASS_DB_SCHEMA_TEMP); +} + +static Oid -+defaultSecLabelWithSchema(Oid nspoid, security_class_t tclass) ++defaultSecLabelWithSchema(Oid relid, Oid nspoid, security_class_t tclass) +{ + HeapTuple tuple; -+ Oid newsid; ++ Oid nspsid; + + if (IsBootstrapProcessingMode()) + { @@ -7546,85 +7832,98 @@ diff -rpNU3 base/src/backend/security/sepgsql/label.c sepgsql-new/src/backend/se + + if (!OidIsValid(cached)) + cached = defaultSchemaSecLabel(); ++ nspsid = cached; ++ } ++ else ++ { ++ tuple = SearchSysCache(NAMESPACEOID, ++ ObjectIdGetDatum(nspoid), ++ 0, 0, 0); ++ if (!HeapTupleIsValid(tuple)) ++ elog(ERROR, "cache lookup failed for namespace: %u", nspoid); + -+ return sepgsqlClientCreate(cached, tclass); ++ nspsid = HeapTupleGetSecLabel(tuple); ++ ++ ReleaseSysCache(tuple); + } + -+ tuple = SearchSysCache(NAMESPACEOID, -+ ObjectIdGetDatum(nspoid), -+ 0, 0, 0); -+ if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "cache lookup failed for namespace: %u", nspoid); -+ -+ newsid = sepgsqlClientCreate(HeapTupleGetSecLabel(tuple), tclass); -+ -+ ReleaseSysCache(tuple); -+ -+ return newsid; ++ return sepgsqlClientCreateSecid(NamespaceRelationId, nspsid, ++ tclass, relid); +} + +static Oid +defaultTableSecLabel(Oid nspoid) +{ -+ return defaultSecLabelWithSchema(nspoid, SEPG_CLASS_DB_TABLE); ++ return defaultSecLabelWithSchema(RelationRelationId, ++ nspoid, ++ SEPG_CLASS_DB_TABLE); +} + +static Oid +defaultSequenceSecLabel(Oid nspoid) +{ -+ return defaultSecLabelWithSchema(nspoid, SEPG_CLASS_DB_SEQUENCE); ++ return defaultSecLabelWithSchema(RelationRelationId, ++ nspoid, ++ SEPG_CLASS_DB_SEQUENCE); +} + +static Oid +defaultProcedureSecLabel(Oid nspoid) +{ -+ return defaultSecLabelWithSchema(nspoid, SEPG_CLASS_DB_PROCEDURE); ++ return defaultSecLabelWithSchema(ProcedureRelationId, ++ nspoid, ++ SEPG_CLASS_DB_PROCEDURE); +} + +static Oid -+defaultSecLabelWithTable(Oid relid, security_class_t tclass) ++defaultSecLabelWithTable(Oid relid, Oid tbloid, security_class_t tclass) +{ + HeapTuple tuple; -+ Oid relsid; ++ Oid tblsid; + + if (IsBootstrapProcessingMode() -+ && (relid == TypeRelationId || -+ relid == ProcedureRelationId || -+ relid == AttributeRelationId || -+ relid == RelationRelationId)) ++ && (tbloid == TypeRelationId || ++ tbloid == ProcedureRelationId || ++ tbloid == AttributeRelationId || ++ tbloid == RelationRelationId)) + { + static Oid cached = InvalidOid; + + if (!OidIsValid(cached)) + cached = defaultTableSecLabel(PG_CATALOG_NAMESPACE); -+ relsid = cached; ++ tblsid = cached; + } + else + { + tuple = SearchSysCache(RELOID, -+ ObjectIdGetDatum(relid), ++ ObjectIdGetDatum(tbloid), + 0, 0, 0); + if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "cache lookup failed for relation: %u", relid); ++ elog(ERROR, "cache lookup failed for relation: %u", tbloid); + -+ relsid = HeapTupleGetSecLabel(tuple); ++ tblsid = HeapTupleGetSecLabel(tuple); + + ReleaseSysCache(tuple); + } + -+ return sepgsqlClientCreate(relsid, tclass); ++ return sepgsqlClientCreateSecid(RelationRelationId, tblsid, ++ tclass, relid); +} + +static Oid -+defaultColumnSecLabel(Oid relid) ++defaultColumnSecLabel(Oid tbloid) +{ -+ return defaultSecLabelWithTable(relid, SEPG_CLASS_DB_COLUMN); ++ return defaultSecLabelWithTable(AttributeRelationId, ++ tbloid, ++ SEPG_CLASS_DB_COLUMN); +} + +static Oid +defaultTupleSecLabel(Oid relid) +{ -+ return defaultSecLabelWithTable(relid, SEPG_CLASS_DB_TUPLE); ++ return defaultSecLabelWithTable(relid, ++ relid, ++ SEPG_CLASS_DB_TUPLE); +} + +static Oid @@ -7646,20 +7945,9 @@ diff -rpNU3 base/src/backend/security/sepgsql/label.c sepgsql-new/src/backend/se + * write new pages, so the default security context is + * only asked when we create a new largeobject. + */ -+ HeapTuple tuple; -+ Oid newsid; -+ -+ tuple = SearchSysCache(DATABASEOID, -+ ObjectIdGetDatum(MyDatabaseId), -+ 0, 0, 0); -+ if (!HeapTupleIsValid(tuple)) -+ elog(ERROR, "cache lookup failed for database: %u", MyDatabaseId); -+ -+ newsid = sepgsqlClientCreate(HeapTupleGetSecLabel(tuple), -+ SEPG_CLASS_DB_BLOB); -+ ReleaseSysCache(tuple); -+ -+ return newsid; ++ return defaultSecLabelWithDatabase(LargeObjectRelationId, ++ MyDatabaseId, ++ SEPG_CLASS_DB_BLOB); +} + +extern void @@ -7726,81 +8014,74 @@ diff -rpNU3 base/src/backend/security/sepgsql/label.c sepgsql-new/src/backend/se + * function invocations to insert new entry for meta security labels. + */ +char * -+sepgsqlMetaSecurityLabel(void) ++sepgsqlMetaSecurityLabel(bool shared) +{ ++ Oid secrelid; + HeapTuple tuple; + security_context_t tcontext; + Oid tsecid; + ++ if (!sepgsqlIsEnabled()) ++ return NULL; ++ ++ secrelid = SecurityRelationId; + tuple = SearchSysCache(RELOID, -+ ObjectIdGetDatum(SecurityRelationId), ++ ObjectIdGetDatum(secrelid), + 0, 0, 0); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "SELinux: cache lookup failed for relation: pg_security"); + + tsecid = HeapTupleGetSecLabel(tuple); ++ tcontext = securityRawSecLabelOut(RelationRelationId, tsecid); + + ReleaseSysCache(tuple); + -+ tcontext = securityLookupSecurityLabel(tsecid); -+ if (!tcontext || security_check_context(tcontext) < 0) -+ tcontext = sepgsqlGetUnlabeledLabel(); -+ + return sepgsqlComputeCreate(sepgsqlGetServerLabel(), + tcontext, + SEPG_CLASS_DB_TUPLE); +} + +/* -+ * sepgsqlInputGivenSecLabel ++ * sepgsqlGivenSecLabelIn + * translate a given security label in text form into a security + * identifier. It can raise an error, if its format is violated, + * but permission checks are done later. + */ +Oid -+sepgsqlInputGivenSecLabel(DefElem *defel) ++sepgsqlGivenSecLabelIn(Oid relid, DefElem *defel) +{ -+ security_context_t context; -+ + if (!defel) + return InvalidOid; + + if (!sepgsqlIsEnabled()) + ereport(ERROR, + (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("SELinux: disabled now"))); ++ errmsg("SELinux is disabled now"))); + -+ context = strVal(defel->arg); -+ if (security_check_context(context) < 0) -+ ereport(ERROR, -+ (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("Not a valid security context: \"%s\"", context))); -+ -+ return securityTransSecLabelIn(context); ++ return securityTransSecLabelIn(relid, strVal(defel->arg)); +} + +/* -+ * sepgsqlInputGivenSecLabelRelation -+ * organize a set of given security labels on CREATE TABLE statement. -+ * User can specify a security label for individual table/columns. -+ * It returns a list of DefElem. !defel->defname means a specified one -+ * for the table, rest of them means one for columns. ++ * sepgsqlParseCreateStmtSecLabelIn ++ * picks up the given security context using CREATE TABLE and ++ * SECURITY_LABEL enhancement. It returns a DefElem list. + */ +List * -+sepgsqlInputGivenSecLabelRelation(CreateStmt *stmt) ++sepgsqlParseCreateStmtSecLabelIn(CreateStmt *stmt) +{ + List *results = NIL; + ListCell *l; -+ DefElem *defel, *newel; ++ DefElem *defel; ++ Oid secid; + + if (stmt->secLabel) + { + defel = (DefElem *) stmt->secLabel; -+ + Assert(IsA(defel, DefElem)); + -+ newel = makeDefElem(NULL, copyObject(defel->arg)); -+ results = lappend(results, newel); ++ secid = sepgsqlGivenSecLabelIn(RelationRelationId, defel); ++ defel = makeDefElem(NULL, makeInteger(secid)); ++ results = lappend(results, defel); + } + + foreach (l, stmt->tableElts) @@ -7810,12 +8091,12 @@ diff -rpNU3 base/src/backend/security/sepgsql/label.c sepgsql-new/src/backend/se + if (cdef->secLabel) + { + defel = (DefElem *) cdef->secLabel; -+ + Assert(IsA(defel, DefElem)); + -+ newel = makeDefElem(pstrdup(cdef->colname), -+ copyObject(defel->arg)); -+ results = lappend(results, newel); ++ secid = sepgsqlGivenSecLabelIn(AttributeRelationId, defel); ++ defel = makeDefElem(pstrdup(cdef->colname), ++ makeInteger(secid)); ++ results = lappend(results, defel); + } + } + @@ -7823,27 +8104,77 @@ diff -rpNU3 base/src/backend/security/sepgsql/label.c sepgsql-new/src/backend/se +} + +/* -+ * sepgsqlSecurityLabelTransIn() -+ * translate external security label into internal one ++ * sepgsqlRawSecLabelIn ++ * correctness checks for the given security context + */ +security_context_t -+sepgsqlSecurityLabelTransIn(security_context_t seclabel) ++sepgsqlRawSecLabelIn(security_context_t seclabel) ++{ ++ if (!sepgsqlIsEnabled()) ++ return seclabel; ++ ++ if (!seclabel || security_check_context_raw(seclabel) < 0) ++ ereport(ERROR, ++ (errcode(ERRCODE_SELINUX_ERROR), ++ errmsg("Invalid security context: \"%s\"", seclabel))); ++ ++ return seclabel; ++} ++ ++/* ++ * sepgsqlRawSecLabelOut ++ * correctness checks for the given security context, ++ * and replace it if invalid security context ++ */ ++security_context_t ++sepgsqlRawSecLabelOut(security_context_t seclabel) ++{ ++ if (!sepgsqlIsEnabled()) ++ return seclabel; ++ ++ if (!seclabel || security_check_context_raw(seclabel) < 0) ++ { ++ security_context_t unlabeledcon; ++ ++ if (security_get_initial_context_raw("unlabeled", ++ &unlabeledcon) < 0) ++ ereport(ERROR, ++ (errcode(ERRCODE_SELINUX_ERROR), ++ errmsg("Unabled to get unlabeled security context"))); ++ PG_TRY(); ++ { ++ seclabel = pstrdup(unlabeledcon); ++ } ++ PG_CATCH(); ++ { ++ freecon(unlabeledcon); ++ PG_RE_THROW(); ++ } ++ PG_END_TRY(); ++ freecon(unlabeledcon); ++ } ++ return seclabel; ++} ++ ++/* ++ * sepgsqlTransSecLabelIn ++ * sepgsqlTransSecLabelOut ++ * translation between human-readable and raw format ++ */ ++security_context_t ++sepgsqlTransSecLabelIn(security_context_t seclabel) +{ + security_context_t rawlabel; + security_context_t result; + -+ if (!sepgsqlIsEnabled()) ++ if (!sepgsqlIsEnabled() || ++ !sepostgresql_use_mcstrans) + return seclabel; + -+ if (!seclabel || security_check_context(seclabel) < 0) -+ ereport(ERROR, -+ (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("Not a valid security context: \"%s\"", seclabel))); -+ + if (selinux_trans_to_raw_context(seclabel, &rawlabel) < 0) + ereport(ERROR, + (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("Failed to translate \"%s\" to raw format", seclabel))); ++ errmsg("SELinux: failed to translate \"%s\"", seclabel))); + PG_TRY(); + { + result = pstrdup(rawlabel); @@ -7859,41 +8190,31 @@ diff -rpNU3 base/src/backend/security/sepgsql/label.c sepgsql-new/src/backend/se + return result; +} + -+/* -+ * sepgsqlSecurityLabelTransOut() -+ * translate internal security label into external one -+ */ +security_context_t -+sepgsqlSecurityLabelTransOut(security_context_t rawlabel) ++sepgsqlTransSecLabelOut(security_context_t seclabel) +{ -+ security_context_t seclabel; ++ security_context_t translabel; + security_context_t result; + -+ if (!sepgsqlIsEnabled()) -+ return rawlabel; ++ if (!sepgsqlIsEnabled() || ++ !sepostgresql_use_mcstrans) ++ return seclabel; + -+ if (!rawlabel || security_check_context(rawlabel) < 0) -+ rawlabel = sepgsqlGetUnlabeledLabel(); -+ -+ if (!sepostgresql_use_mcstrans) -+ return rawlabel; -+ -+ if (selinux_raw_to_trans_context(rawlabel, &seclabel) < 0) ++ if (selinux_raw_to_trans_context(seclabel, &translabel) < 0) + ereport(ERROR, -+ (errcode(ERRCODE_SELINUX_ERROR), -+ errmsg("Failed to translate \"%s\" to readable format", rawlabel))); -+ ++ (errcode(ERRCODE_SELINUX_ERROR), ++ errmsg("SELinux: failed to translate \"%s\"", seclabel))); + PG_TRY(); + { -+ result = pstrdup(seclabel); ++ result = pstrdup(translabel); + } + PG_CATCH(); + { -+ freecon(seclabel); ++ freecon(translabel); + PG_RE_THROW(); + } + PG_END_TRY(); -+ freecon(seclabel); ++ freecon(translabel); + + return result; +} @@ -8776,7 +9097,7 @@ diff -rpNU3 base/src/backend/tcop/pquery.c sepgsql-new/src/backend/tcop/pquery.c /* diff -rpNU3 base/src/backend/tcop/utility.c sepgsql-new/src/backend/tcop/utility.c --- base/src/backend/tcop/utility.c 2008-11-05 09:57:00.000000000 +0900 -+++ sepgsql-new/src/backend/tcop/utility.c 2009-03-13 18:14:33.000000000 +0900 ++++ sepgsql-new/src/backend/tcop/utility.c 2009-06-19 15:02:12.000000000 +0900 @@ -49,6 +49,7 @@ #include "postmaster/bgwriter.h" #include "rewrite/rewriteDefine.h" @@ -8785,21 +9106,88 @@ diff -rpNU3 base/src/backend/tcop/utility.c sepgsql-new/src/backend/tcop/utility #include "storage/fd.h" #include "tcop/pquery.h" #include "tcop/utility.h" -@@ -1022,6 +1023,10 @@ ProcessUtility(Node *parsetree, +@@ -315,6 +316,7 @@ check_xact_readonly(Node *parsetree) + case T_AlterRoleSetStmt: + case T_AlterObjectSchemaStmt: + case T_AlterOwnerStmt: ++ case T_AlterSecLabelStmt: + case T_AlterSeqStmt: + case T_AlterTableStmt: + case T_RenameStmt: +@@ -744,6 +746,10 @@ ProcessUtility(Node *parsetree, + ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree); + break; + ++ case T_AlterSecLabelStmt: ++ ExecAlterSecLabelStmt((AlterSecLabelStmt *) parsetree); ++ break; ++ + case T_AlterTableStmt: + { + List *stmts; +@@ -1022,6 +1028,10 @@ ProcessUtility(Node *parsetree, LoadStmt *stmt = (LoadStmt *) parsetree; closeAllVfds(); /* probably not necessary... */ + -+ /* SELinux checks db_database:{install_module} priv */ -+ sepgsqlCheckDatabaseInstallModule(stmt->filename); ++ /* SELinux checks db_database:{install_module} */ ++ sepgsqlCheckDatabaseInstallModule(); + /* Allowed names are restricted if you're not superuser */ load_file(stmt->filename, !superuser()); } +@@ -1709,6 +1719,28 @@ CreateCommandTag(Node *parsetree) + } + break; + ++ case T_AlterSecLabelStmt: ++ switch (((AlterSecLabelStmt *) parsetree)->objectType) ++ { ++ case OBJECT_DATABASE: ++ tag = "ALTER DATABASE"; ++ break; ++ case OBJECT_SCHEMA: ++ tag = "ALTER SCHEMA"; ++ break; ++ case OBJECT_TABLE: ++ case OBJECT_COLUMN: ++ tag = "ALTER TABLE"; ++ break; ++ case OBJECT_SEQUENCE: ++ tag = "ALTER SEQUENCE"; ++ break; ++ case OBJECT_FUNCTION: ++ tag = "ALTER FUNCTION"; ++ break; ++ } ++ break; ++ + case T_AlterTableStmt: + { + AlterTableStmt *stmt = (AlterTableStmt *) parsetree; +@@ -2248,6 +2280,10 @@ GetCommandLogLevel(Node *parsetree) + lev = LOGSTMT_DDL; + break; + ++ case T_AlterSecLabelStmt: ++ lev = LOGSTMT_DDL; ++ break; ++ + case T_AlterTableStmt: + lev = LOGSTMT_DDL; + break; diff -rpNU3 base/src/backend/utils/adt/genfile.c sepgsql-new/src/backend/utils/adt/genfile.c --- base/src/backend/utils/adt/genfile.c 2008-06-12 22:34:19.000000000 +0900 -+++ sepgsql-new/src/backend/utils/adt/genfile.c 2009-05-21 08:49:49.000000000 +0900 -@@ -109,6 +109,9 @@ pg_read_file(PG_FUNCTION_ARGS) ++++ sepgsql-new/src/backend/utils/adt/genfile.c 2009-06-10 21:37:54.000000000 +0900 +@@ -25,6 +25,7 @@ + #include "funcapi.h" + #include "miscadmin.h" + #include "postmaster/syslogger.h" ++#include "security/sepgsql.h" + #include "storage/fd.h" + #include "utils/builtins.h" + #include "utils/memutils.h" +@@ -109,6 +110,9 @@ pg_read_file(PG_FUNCTION_ARGS) errmsg("could not open file \"%s\" for reading: %m", filename))); @@ -9028,9 +9416,9 @@ diff -rpNU3 base/src/backend/utils/cache/catcache.c sepgsql-new/src/backend/util /* * SearchCatCacheList diff -rpNU3 base/src/backend/utils/cache/plancache.c sepgsql-new/src/backend/utils/cache/plancache.c ---- base/src/backend/utils/cache/plancache.c 2009-02-02 11:47:17.000000000 +0900 -+++ sepgsql-new/src/backend/utils/cache/plancache.c 2009-03-13 18:14:33.000000000 +0900 -@@ -880,12 +880,14 @@ PlanCacheComputeResultDesc(List *stmt_li +--- base/src/backend/utils/cache/plancache.c 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/src/backend/utils/cache/plancache.c 2009-09-10 20:24:37.000000000 +0900 +@@ -894,12 +894,14 @@ PlanCacheComputeResultDesc(List *stmt_li if (IsA(node, Query)) { query = (Query *) node; @@ -9047,7 +9435,7 @@ diff -rpNU3 base/src/backend/utils/cache/plancache.c sepgsql-new/src/backend/uti } /* other cases shouldn't happen, but return NULL */ break; -@@ -896,13 +898,15 @@ PlanCacheComputeResultDesc(List *stmt_li +@@ -910,13 +912,15 @@ PlanCacheComputeResultDesc(List *stmt_li { query = (Query *) node; Assert(query->returningList); @@ -9207,8 +9595,8 @@ diff -rpNU3 base/src/backend/utils/cache/syscache.c sepgsql-new/src/backend/util * * A convenience routine that does SearchSysCache and (if successful) diff -rpNU3 base/src/backend/utils/fmgr/dfmgr.c sepgsql-new/src/backend/utils/fmgr/dfmgr.c ---- base/src/backend/utils/fmgr/dfmgr.c 2008-01-07 23:51:33.000000000 +0900 -+++ sepgsql-new/src/backend/utils/fmgr/dfmgr.c 2009-03-13 18:14:33.000000000 +0900 +--- base/src/backend/utils/fmgr/dfmgr.c 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/src/backend/utils/fmgr/dfmgr.c 2009-09-10 20:24:37.000000000 +0900 @@ -22,6 +22,7 @@ #include "port/dynloader/win32.h" #endif @@ -9245,7 +9633,7 @@ diff -rpNU3 base/src/backend/utils/fmgr/dfmgr.c sepgsql-new/src/backend/utils/fm /* Unload the library if currently loaded */ internal_unload_library(fullname); -@@ -395,7 +401,7 @@ file_exists(const char *name) +@@ -403,7 +409,7 @@ file_exists(const char *name) * * The result will always be freshly palloc'd. */ @@ -9323,8 +9711,8 @@ diff -rpNU3 base/src/backend/utils/init/postinit.c sepgsql-new/src/backend/utils * Figure out our postgres user id, and see if we are a superuser. * diff -rpNU3 base/src/backend/utils/misc/guc.c sepgsql-new/src/backend/utils/misc/guc.c ---- base/src/backend/utils/misc/guc.c 2008-09-25 15:09:40.000000000 +0900 -+++ sepgsql-new/src/backend/utils/misc/guc.c 2009-05-29 11:12:01.000000000 +0900 +--- base/src/backend/utils/misc/guc.c 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/src/backend/utils/misc/guc.c 2009-09-10 20:24:37.000000000 +0900 @@ -54,6 +54,7 @@ #include "postmaster/postmaster.h" #include "postmaster/syslogger.h" @@ -9574,6 +9962,17 @@ diff -rpNU3 base/src/include/catalog/pg_attribute.h sepgsql-new/src/include/cata /* ---------------- * pg_index +diff -rpNU3 base/src/include/catalog/pg_namespace.h sepgsql-new/src/include/catalog/pg_namespace.h +--- base/src/include/catalog/pg_namespace.h 2008-01-07 23:51:33.000000000 +0900 ++++ sepgsql-new/src/include/catalog/pg_namespace.h 2009-06-19 15:02:12.000000000 +0900 +@@ -82,6 +82,6 @@ DESCR("standard public schema"); + /* + * prototypes for functions in pg_namespace.c + */ +-extern Oid NamespaceCreate(const char *nspName, Oid ownerId); ++extern Oid NamespaceCreate(const char *nspName, Oid ownerId, Oid secid); + + #endif /* PG_NAMESPACE_H */ diff -rpNU3 base/src/include/catalog/pg_proc.h sepgsql-new/src/include/catalog/pg_proc.h --- base/src/include/catalog/pg_proc.h 2008-01-07 23:51:33.000000000 +0900 +++ sepgsql-new/src/include/catalog/pg_proc.h 2009-03-13 18:14:33.000000000 +0900 @@ -9612,7 +10011,7 @@ diff -rpNU3 base/src/include/catalog/pg_proc.h sepgsql-new/src/include/catalog/p diff -rpNU3 base/src/include/catalog/pg_security.h sepgsql-new/src/include/catalog/pg_security.h --- base/src/include/catalog/pg_security.h 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/include/catalog/pg_security.h 2009-03-13 18:14:33.000000000 +0900 ++++ sepgsql-new/src/include/catalog/pg_security.h 2009-06-10 17:43:08.000000000 +0900 @@ -0,0 +1,58 @@ +/* + * src/include/catalog/pg_security.h @@ -9657,21 +10056,76 @@ diff -rpNU3 base/src/include/catalog/pg_security.h sepgsql-new/src/include/catal +securityTupleDescHasSecLabel(Relation rel); + +extern Oid -+securityLookupSecurityId(const char *seclabel); ++securityRawSecLabelIn(Oid relid, char *seclabel); + +extern char * -+securityLookupSecurityLabel(Oid secid); ++securityRawSecLabelOut(Oid relid, Oid secid); + +extern Oid -+securityTransSecLabelIn(char *seclabel); ++securityTransSecLabelIn(Oid relid, char *seclabel); + +extern char * -+securityTransSecLabelOut(Oid secid); ++securityTransSecLabelOut(Oid relid, Oid secid); + +extern Datum +securityHeapGetSecLabelSysattr(HeapTuple tuple); + +#endif /* PG_SELINUX_H */ +diff -rpNU3 base/src/include/commands/alter.h sepgsql-new/src/include/commands/alter.h +--- base/src/include/commands/alter.h 2008-01-07 23:51:33.000000000 +0900 ++++ sepgsql-new/src/include/commands/alter.h 2009-06-19 15:02:12.000000000 +0900 +@@ -19,5 +19,6 @@ + extern void ExecRenameStmt(RenameStmt *stmt); + extern void ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt); + extern void ExecAlterOwnerStmt(AlterOwnerStmt *stmt); ++extern void ExecAlterSecLabelStmt(AlterSecLabelStmt *stmt); + + #endif /* ALTER_H */ +diff -rpNU3 base/src/include/commands/dbcommands.h sepgsql-new/src/include/commands/dbcommands.h +--- base/src/include/commands/dbcommands.h 2008-01-07 23:51:33.000000000 +0900 ++++ sepgsql-new/src/include/commands/dbcommands.h 2009-06-19 15:02:12.000000000 +0900 +@@ -58,6 +58,7 @@ extern void RenameDatabase(const char *o + extern void AlterDatabase(AlterDatabaseStmt *stmt); + extern void AlterDatabaseSet(AlterDatabaseSetStmt *stmt); + extern void AlterDatabaseOwner(const char *dbname, Oid newOwnerId); ++extern void AlterDatabaseSecLabel(const char *dbname, DefElem *seclabel); + + extern Oid get_database_oid(const char *dbname); + extern char *get_database_name(Oid dbid); +diff -rpNU3 base/src/include/commands/defrem.h sepgsql-new/src/include/commands/defrem.h +--- base/src/include/commands/defrem.h 2008-01-07 23:51:33.000000000 +0900 ++++ sepgsql-new/src/include/commands/defrem.h 2009-06-19 15:02:12.000000000 +0900 +@@ -54,6 +54,7 @@ extern void SetFunctionArgType(Oid funcO + extern void RenameFunction(List *name, List *argtypes, const char *newname); + extern void AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId); + extern void AlterFunctionOwner_oid(Oid procOid, Oid newOwnerId); ++extern void AlterFunctionSecLabel(List *name, List *argtypes, DefElem *seclabel); + extern void AlterFunction(AlterFunctionStmt *stmt); + extern void CreateCast(CreateCastStmt *stmt); + extern void DropCast(DropCastStmt *stmt); +diff -rpNU3 base/src/include/commands/schemacmds.h sepgsql-new/src/include/commands/schemacmds.h +--- base/src/include/commands/schemacmds.h 2008-01-07 23:51:33.000000000 +0900 ++++ sepgsql-new/src/include/commands/schemacmds.h 2009-06-19 15:02:12.000000000 +0900 +@@ -26,5 +26,6 @@ extern void RemoveSchemaById(Oid schemaO + extern void RenameSchema(const char *oldname, const char *newname); + extern void AlterSchemaOwner(const char *name, Oid newOwnerId); + extern void AlterSchemaOwner_oid(Oid schemaOid, Oid newOwnerId); ++extern void AlterSchemaSecLabel(const char *name, DefElem *seclabel); + + #endif /* SCHEMACMDS_H */ +diff -rpNU3 base/src/include/commands/tablecmds.h sepgsql-new/src/include/commands/tablecmds.h +--- base/src/include/commands/tablecmds.h 2008-02-03 01:11:28.000000000 +0900 ++++ sepgsql-new/src/include/commands/tablecmds.h 2009-06-19 15:02:12.000000000 +0900 +@@ -34,6 +34,9 @@ extern void AlterRelationNamespaceIntern + Oid oldNspOid, Oid newNspOid, + bool hasDependEntry); + ++extern void AlterRelationSecLabel(RangeVar *relation, const char *attname, ++ ObjectType objtype, DefElem *seclabel); ++ + extern void CheckTableNotInUse(Relation rel, const char *stmt); + + extern void ExecuteTruncate(TruncateStmt *stmt); diff -rpNU3 base/src/include/executor/executor.h sepgsql-new/src/include/executor/executor.h --- base/src/include/executor/executor.h 2008-01-07 23:51:33.000000000 +0900 +++ sepgsql-new/src/include/executor/executor.h 2009-03-13 18:14:33.000000000 +0900 @@ -9704,18 +10158,16 @@ diff -rpNU3 base/src/include/executor/executor.h sepgsql-new/src/include/executo extern void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg); diff -rpNU3 base/src/include/executor/tuptable.h sepgsql-new/src/include/executor/tuptable.h ---- base/src/include/executor/tuptable.h 2008-01-07 23:51:33.000000000 +0900 -+++ sepgsql-new/src/include/executor/tuptable.h 2009-03-13 18:14:33.000000000 +0900 -@@ -118,6 +118,9 @@ typedef struct TupleTableSlot - MinimalTuple tts_mintuple; /* set if it's a minimal tuple, else NULL */ - HeapTupleData tts_minhdr; /* workspace if it's a minimal tuple */ +--- base/src/include/executor/tuptable.h 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/src/include/executor/tuptable.h 2009-09-10 20:24:37.000000000 +0900 +@@ -127,6 +127,7 @@ typedef struct TupleTableSlot + MinimalTuple tts_mintuple; /* minimal tuple, or NULL if none */ + HeapTupleData tts_minhdr; /* workspace for minimal-tuple-only case */ long tts_off; /* saved state for slot_deform_tuple */ -+ -+ /* temporary storages for writable system columns */ -+ Oid tts_seclabel; ++ Datum tts_seclabel; /* temp storage for the given security_label */ } TupleTableSlot; - /* + #define TTS_HAS_PHYSICAL_TUPLE(slot) \ diff -rpNU3 base/src/include/fmgr.h sepgsql-new/src/include/fmgr.h --- base/src/include/fmgr.h 2008-01-07 23:51:33.000000000 +0900 +++ sepgsql-new/src/include/fmgr.h 2009-03-13 18:14:33.000000000 +0900 @@ -9756,9 +10208,20 @@ diff -rpNU3 base/src/include/libpq/be-fsstubs.h sepgsql-new/src/include/libpq/be /* * These are not fmgr-callable, but are available to C code. * Probably these should have had the underscore-free names, +diff -rpNU3 base/src/include/nodes/nodes.h sepgsql-new/src/include/nodes/nodes.h +--- base/src/include/nodes/nodes.h 2008-01-07 23:51:33.000000000 +0900 ++++ sepgsql-new/src/include/nodes/nodes.h 2009-06-19 15:02:12.000000000 +0900 +@@ -313,6 +313,7 @@ typedef enum NodeTag + T_CreateEnumStmt, + T_AlterTSDictionaryStmt, + T_AlterTSConfigurationStmt, ++ T_AlterSecLabelStmt, + + /* + * TAGS FOR PARSE TREE NODES (parsenodes.h) diff -rpNU3 base/src/include/nodes/parsenodes.h sepgsql-new/src/include/nodes/parsenodes.h --- base/src/include/nodes/parsenodes.h 2008-03-19 09:48:23.000000000 +0900 -+++ sepgsql-new/src/include/nodes/parsenodes.h 2009-04-19 23:18:14.000000000 +0900 ++++ sepgsql-new/src/include/nodes/parsenodes.h 2009-06-19 15:02:12.000000000 +0900 @@ -14,6 +14,7 @@ #ifndef PARSENODES_H #define PARSENODES_H @@ -9784,16 +10247,14 @@ diff -rpNU3 base/src/include/nodes/parsenodes.h sepgsql-new/src/include/nodes/pa } RangeTblEntry; /* -@@ -917,7 +921,8 @@ typedef enum AlterTableType - AT_EnableReplicaRule, /* ENABLE REPLICA RULE name */ - AT_DisableRule, /* DISABLE RULE name */ - AT_AddInherit, /* INHERIT parent */ -- AT_DropInherit /* NO INHERIT parent */ -+ AT_DropInherit, /* NO INHERIT parent */ -+ AT_SetSecurityLabel, /* SECURITY_LABEL */ - } AlterTableType; +@@ -857,6 +861,7 @@ typedef struct CreateSchemaStmt + NodeTag type; + char *schemaname; /* the name of the schema to create */ + char *authid; /* the owner of the created schema */ ++ Node *secLabel; /* explicitly specified security label */ + List *schemaElts; /* schema components (list of parsenodes) */ + } CreateSchemaStmt; - typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */ @@ -1108,6 +1113,7 @@ typedef struct CreateStmt List *options; /* options from WITH clause */ OnCommitAction oncommit; /* what do we do at COMMIT? */ @@ -9802,6 +10263,35 @@ diff -rpNU3 base/src/include/nodes/parsenodes.h sepgsql-new/src/include/nodes/pa } CreateStmt; /* ---------- +@@ -1320,6 +1326,7 @@ typedef struct CreateSeqStmt + NodeTag type; + RangeVar *sequence; /* the sequence to create */ + List *options; ++ Node *secLabel; + } CreateSeqStmt; + + typedef struct AlterSeqStmt +@@ -1671,6 +1678,20 @@ typedef struct AlterOwnerStmt + char *newowner; /* the new owner */ + } AlterOwnerStmt; + ++/* ---------------------- ++ * Alter Object Security Label Statement ++ * ---------------------- ++ */ ++typedef struct AlterSecLabelStmt ++{ ++ NodeTag type; ++ ObjectType objectType; /* OBJECT_TABLE, OBJECT_COLUMN, etc */ ++ RangeVar *relation; /* in case it's a table */ ++ List *object; /* in case it's some other object */ ++ List *objarg; /* argument types, if applicable */ ++ char *subname; /* column name, if needed */ ++ Node *secLabel; /* the new security label */ ++} AlterSecLabelStmt; + + /* ---------------------- + * Create Rule Statement diff -rpNU3 base/src/include/nodes/plannodes.h sepgsql-new/src/include/nodes/plannodes.h --- base/src/include/nodes/plannodes.h 2008-01-07 23:51:33.000000000 +0900 +++ sepgsql-new/src/include/nodes/plannodes.h 2009-05-20 17:08:02.000000000 +0900 @@ -9836,8 +10326,8 @@ diff -rpNU3 base/src/include/nodes/plannodes.h sepgsql-new/src/include/nodes/pla /* ---------------- diff -rpNU3 base/src/include/nodes/relation.h sepgsql-new/src/include/nodes/relation.h ---- base/src/include/nodes/relation.h 2009-02-02 11:47:17.000000000 +0900 -+++ sepgsql-new/src/include/nodes/relation.h 2009-05-20 17:08:02.000000000 +0900 +--- base/src/include/nodes/relation.h 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/src/include/nodes/relation.h 2009-09-10 20:24:37.000000000 +0900 @@ -366,6 +366,15 @@ typedef struct RelOptInfo * list just to avoid recomputing the best inner indexscan repeatedly for * similar outer relations. See comments for InnerIndexscanInfo. @@ -9943,8 +10433,8 @@ diff -rpNU3 base/src/include/security/rowlevel.h sepgsql-new/src/include/securit +#endif /* PG_SELINUX_H */ diff -rpNU3 base/src/include/security/sepgsql.h sepgsql-new/src/include/security/sepgsql.h --- base/src/include/security/sepgsql.h 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/include/security/sepgsql.h 2009-05-29 11:12:01.000000000 +0900 -@@ -0,0 +1,457 @@ ++++ sepgsql-new/src/include/security/sepgsql.h 2009-06-19 15:02:12.000000000 +0900 +@@ -0,0 +1,466 @@ +/* + * src/include/utils/sepgsql.h + * Headers of SE-PostgreSQL @@ -10130,15 +10620,21 @@ diff -rpNU3 base/src/include/security/sepgsql.h sepgsql-new/src/include/security +extern void sepgsqlAvcSwitchClient(void); + +extern bool -+sepgsqlClientHasPerms(Oid tsecid, -+ security_class_t tclass, -+ access_vector_t required, -+ const char *audit_name, bool abort); ++sepgsqlClientHasPermsTup(Oid relid, HeapTuple tuple, ++ security_class_t tclass, ++ access_vector_t required, bool abort); ++extern bool ++sepgsqlClientHasPermsSid(Oid relid, Oid secid, ++ security_class_t tclass, ++ access_vector_t required, ++ const char *audit_name, bool abort); +extern Oid -+sepgsqlClientCreate(Oid tsecid, security_class_t tclass); ++sepgsqlClientCreateSecid(Oid trelid, Oid tsecid, ++ security_class_t tclass, Oid nrelid); + +extern security_context_t -+sepgsqlClientCreateLabel(Oid tsecid, security_class_t tclass); ++sepgsqlClientCreateLabel(Oid trelid, Oid tsecid, ++ security_class_t tclass); + +extern bool +sepgsqlComputePerms(security_context_t scontext, @@ -10189,9 +10685,6 @@ diff -rpNU3 base/src/include/security/sepgsql.h sepgsql-new/src/include/security +sepgsqlGetClientLabel(void); + +extern security_context_t -+sepgsqlGetUnlabeledLabel(void); -+ -+extern security_context_t +sepgsqlSwitchClient(security_context_t new_client); + +extern bool @@ -10209,6 +10702,12 @@ diff -rpNU3 base/src/include/security/sepgsql.h sepgsql-new/src/include/security +extern bool +sepgsqlCheckDatabaseSuperuser(void); + ++extern void ++sepgsqlCheckDatabaseInstallModule(void); ++ ++extern void ++sepgsqlCheckDatabaseLoadModule(const char *filename); ++ +extern bool +sepgsqlCheckSchemaSearch(Oid nsid); + @@ -10216,12 +10715,6 @@ diff -rpNU3 base/src/include/security/sepgsql.h sepgsql-new/src/include/security +sepgsqlCheckSchemaAddRemove(Relation rel, HeapTuple newtup, HeapTuple oldtup); + +extern void -+sepgsqlCheckDatabaseInstallModule(const char *filename); -+ -+extern void -+sepgsqlCheckDatabaseLoadModule(const char *filename); -+ -+extern void +sepgsqlCheckTableLock(Oid table_oid); + +extern void @@ -10295,19 +10788,25 @@ diff -rpNU3 base/src/include/security/sepgsql.h sepgsql-new/src/include/security +sepgsqlSetDefaultSecLabel(Relation rel, HeapTuple tuple); + +extern security_context_t -+sepgsqlMetaSecurityLabel(void); ++sepgsqlMetaSecurityLabel(bool shared); + +extern Oid -+sepgsqlInputGivenSecLabel(DefElem *defel); ++sepgsqlGivenSecLabelIn(Oid relid, DefElem *defel); + +extern List * -+sepgsqlInputGivenSecLabelRelation(CreateStmt *stmt); ++sepgsqlParseCreateStmtSecLabelIn(CreateStmt *stmt); + +extern security_context_t -+sepgsqlSecurityLabelTransIn(security_context_t label); ++sepgsqlTransSecLabelIn(security_context_t seclabel); + +extern security_context_t -+sepgsqlSecurityLabelTransOut(security_context_t label); ++sepgsqlTransSecLabelOut(security_context_t seclabel); ++ ++extern security_context_t ++sepgsqlRawSecLabelIn(security_context_t seclabel); ++ ++extern security_context_t ++sepgsqlRawSecLabelOut(security_context_t seclabel); + +/* + * perms.c : SELinux permission related stuff @@ -10333,10 +10832,6 @@ diff -rpNU3 base/src/include/security/sepgsql.h sepgsql-new/src/include/security +extern const char * +sepgsqlGetPermissionString(security_class_t tclass, access_vector_t av); + -+extern bool -+sepgsqlCheckObjectPerms(Relation rel, HeapTuple tuple, -+ access_vector_t required, bool abort); -+ +#else /* HAVE_SELINUX */ + +/* avc.c */ @@ -10359,6 +10854,8 @@ diff -rpNU3 base/src/include/security/sepgsql.h sepgsql-new/src/include/security +/* hooks.c */ +#define sepgsqlCheckDatabaseAccess(a) (true) +#define sepgsqlCheckDatabaseSuperuser() (true) ++#define sepgsqlCheckDatabaseInstallModule() do {} while(0) ++#define sepgsqlCheckDatabaseLoadModule(a) do {} while(0) +#define sepgsqlCheckSchemaSearch(a) (true) +#define sepgsqlCheckTableLock(a) do {} while(0) +#define sepgsqlCheckTableTruncate(a) do {} while(0) @@ -10382,11 +10879,13 @@ diff -rpNU3 base/src/include/security/sepgsql.h sepgsql-new/src/include/security +#define sepgsqlAllowFunctionInlined(a) (true) +/* label.c */ +#define sepgsqlTupleDescHasSecLabel(a) (false) -+#define sepgsqlMetaSecurityLabel() (NULL) -+#define sepgsqlInputGivenSecLabel(a) (InvalidOid) -+#define sepgsqlInputGivenSecLabelRelation(a) (NIL) -+#define sepgsqlSecurityLabelTransIn(a) (a) -+#define sepgsqlSecurityLabelTransOut(a) (a) ++#define sepgsqlMetaSecurityLabel(a) (NULL) ++#define sepgsqlGivenSecLabelIn(a,b) (InvalidOid) ++#define sepgsqlParseCreateStmtSecLabelIn(a) (NIL) ++#define sepgsqlTransSecLabelIn(a) (a) ++#define sepgsqlTransSecLabelOut(a) (a) ++#define sepgsqlRawSecLabelIn(a) (a) ++#define sepgsqlRawSecLabelOut(a) (a) + +#endif /* HAVE_SELINUX */ + diff --git a/sepostgresql-test-8.3.patch b/sepostgresql-test-8.3.patch index 7cb50b9..dff7d4c 100644 --- a/sepostgresql-test-8.3.patch +++ b/sepostgresql-test-8.3.patch @@ -20,8 +20,8 @@ diff -rpNU3 base/src/test/regress/expected/sanity_check.out sepgsql-new/src/test -- another sanity check: every system catalog that has OIDs should have diff -rpNU3 base/src/test/sepgsql/Makefile sepgsql-new/src/test/sepgsql/Makefile --- base/src/test/sepgsql/Makefile 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/test/sepgsql/Makefile 2009-03-03 18:21:14.000000000 +0900 -@@ -0,0 +1,65 @@ ++++ sepgsql-new/src/test/sepgsql/Makefile 2009-06-10 21:37:54.000000000 +0900 +@@ -0,0 +1,62 @@ +# ---------------------------------------------------- +# Makefile for SE-PostgreSQL testcases +# ---------------------------------------------------- @@ -46,7 +46,7 @@ diff -rpNU3 base/src/test/sepgsql/Makefile sepgsql-new/src/test/sepgsql/Makefile + +results.diff: $(TESTCASES:sql/%.sql=results/%.diff) + @for x in $^; do cat $$x >> $@; done -+ @test -s $@ && echo "HINT: See $@ to confirm errors" || : ++ @test -s $@ && echo "HINT: See $(shell pwd)/$@ to confirm errors" || : + +results/%.diff: sql/%.sql + @./launch_psql $(PSQL) -a $(DBNAME) < $< >& $(@:%.diff=%.out) @@ -73,9 +73,9 @@ diff -rpNU3 base/src/test/sepgsql/Makefile sepgsql-new/src/test/sepgsql/Makefile + @$(PSQL) -qt -c 'SHOW sepostgresql' -d $(DBNAME) 2>/dev/null | grep -q on || \ + (echo "HINT: database \"$(DBNAME)\" is not available"; \ + echo "HINT: SE-PostgreSQL may not be available on server"; exit 1) -+ @$(GETSEBOOL) allow_user_postgresql_connect | grep -q on || \ ++ @$(GETSEBOOL) allow_user_postgresql_connect | grep -q 'on$$' || \ + (echo "HINT: check allow_user_postgresql_connect boolean"; exit 1) -+ @$(GETSEBOOL) sepgsql_regression_test_mode | grep -q on || \ ++ @$(GETSEBOOL) sepgsql_regression_test_mode | grep -q 'on$$' || \ + (echo "HINT: check sepgsql_regression_test_mode boolean"; \ + echo "HINT: check sepostgresql-devel.pp installed"; exit 1) + @$(RUNCON) -t sepgsql_test_t -l s0-s0:c0.c15 \ @@ -83,15 +83,14 @@ diff -rpNU3 base/src/test/sepgsql/Makefile sepgsql-new/src/test/sepgsql/Makefile + (echo "HINT: /sbin/restorecon -R and restart"; \ + echo "HINT: user shell should have 's0-s0:c0.c15' range, at least"; \ + echo " semanage enables to set up it"; exit 1) -+ @test -x /etc/init.d/mcstrans && /etc/init.d/mcstrans status >& /dev/null && \ -+ (echo "HINT: stop mcstrans daemon"; exit 1) || \ -+ (test $$? -eq 3 && exit 0 || exit 1) + @echo "PASS: check runtime environment" diff -rpNU3 base/src/test/sepgsql/expected/basic.out sepgsql-new/src/test/sepgsql/expected/basic.out --- base/src/test/sepgsql/expected/basic.out 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/test/sepgsql/expected/basic.out 2009-03-15 17:38:39.000000000 +0900 -@@ -0,0 +1,108 @@ ++++ sepgsql-new/src/test/sepgsql/expected/basic.out 2009-06-10 21:37:54.000000000 +0900 +@@ -0,0 +1,114 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 ++SET sepostgresql_mcstrans TO off; ++SET +SELECT sepgsql_getcon(); + sepgsql_getcon +----------------------------------------------------- @@ -141,6 +140,8 @@ diff -rpNU3 base/src/test/sepgsql/expected/basic.out sepgsql-new/src/test/sepgsq +) inherits(t2); +CREATE TABLE +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 ++SET sepostgresql_mcstrans TO off; ++SET +SELECT sepgsql_getcon(); + sepgsql_getcon +--------------------------------------------------- @@ -148,7 +149,7 @@ diff -rpNU3 base/src/test/sepgsql/expected/basic.out sepgsql-new/src/test/sepgsq +(1 row) + +SELECT * FROM t1; -- to be denied -+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c ++ERROR: SELinux: security policy violation +SELECT a, b FROM t1; + a | b +---+----- @@ -157,13 +158,13 @@ diff -rpNU3 base/src/test/sepgsql/expected/basic.out sepgsql-new/src/test/sepgsq +(2 rows) + +SELECT COUNT(*) FROM t1 WHERE c; -- to be denied -+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c ++ERROR: SELinux: security policy violation +UPDATE t1 SET b = 'ccc'; -- to be denied -+ERROR: SELinux: denied { update } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_ro_table_t:s0 tclass=db_column name=t1.b ++ERROR: SELinux: security policy violation +UPDATE t1 SET a = a + 2; +UPDATE 2 +INSERT INTO t1 VALUES (5, 'eee', true); -- to be denied -+ERROR: SELinux: denied { insert } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_ro_table_t:s0 tclass=db_column name=t1.b ++ERROR: SELinux: security policy violation +INSERT INTO t1 VALUES (5); +INSERT 0 1 +SELECT * FROM t2; @@ -177,13 +178,15 @@ diff -rpNU3 base/src/test/sepgsql/expected/basic.out sepgsql-new/src/test/sepgsq +(0 rows) + +SELECT t3 FROM t3; -- to be denied -+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0:c1 tclass=db_column name=t3.x ++ERROR: SELinux: security policy violation +SELECT 1 FROM t3; + ?column? +---------- +(0 rows) + +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c1 ++SET sepostgresql_mcstrans TO off; ++SET +SELECT sepgsql_getcon(); + sepgsql_getcon +--------------------------------------------------- @@ -191,9 +194,9 @@ diff -rpNU3 base/src/test/sepgsql/expected/basic.out sepgsql-new/src/test/sepgsq +(1 row) + +SELECT * FROM t2; -- to be denied -+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c1 tcontext=unconfined_u:object_r:sepgsql_table_t:s0:c0 tclass=db_table name=t2 ++ERROR: SELinux: security policy violation +SELECT t2 FROM t2; -- to be denied -+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c1 tcontext=unconfined_u:object_r:sepgsql_table_t:s0:c0 tclass=db_table name=t2 ++ERROR: SELinux: security policy violation +SELECT t3 FROM t3; + t3 +---- @@ -201,9 +204,11 @@ diff -rpNU3 base/src/test/sepgsql/expected/basic.out sepgsql-new/src/test/sepgsq + diff -rpNU3 base/src/test/sepgsql/expected/copy_stmt.out sepgsql-new/src/test/sepgsql/expected/copy_stmt.out --- base/src/test/sepgsql/expected/copy_stmt.out 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/test/sepgsql/expected/copy_stmt.out 2009-03-02 00:24:34.000000000 +0900 -@@ -0,0 +1,90 @@ ++++ sepgsql-new/src/test/sepgsql/expected/copy_stmt.out 2009-06-10 21:37:54.000000000 +0900 +@@ -0,0 +1,94 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 ++SET sepostgresql_mcstrans TO off; ++SET +SELECT sepgsql_getcon(); + sepgsql_getcon +----------------------------------------------------- @@ -256,6 +261,8 @@ diff -rpNU3 base/src/test/sepgsql/expected/copy_stmt.out sepgsql-new/src/test/se +INSERT INTO t2 VALUES (1, 'sss'), (2, 'ttt'); +INSERT 0 2 +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 ++SET sepostgresql_mcstrans TO off; ++SET +SELECT sepgsql_getcon(); + sepgsql_getcon +--------------------------------------------------- @@ -269,11 +276,11 @@ diff -rpNU3 base/src/test/sepgsql/expected/copy_stmt.out sepgsql-new/src/test/se +COPY t1 TO '/tmp/sepgsql_test_copy_1'; +COPY 4 +COPY t1 TO '/tmp/sepgsql_test_copy_2'; -- to be denied -+ERROR: SELinux: denied { write } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:postgresql_db_t:s0 tclass=file name=/tmp/sepgsql_test_copy_2 ++ERROR: SELinux: security policy violation +COPY t2 TO stdout; -- to be denied -+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t2.y ++ERROR: SELinux: security policy violation +COPY t2 FROM stdin; -- to be denied -+ERROR: SELinux: denied { insert } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t2.y ++ERROR: SELinux: security policy violation +COPY t2 (x) TO stdout; +1 +2 @@ -281,7 +288,7 @@ diff -rpNU3 base/src/test/sepgsql/expected/copy_stmt.out sepgsql-new/src/test/se +2 +COPY t3 TO stdout; +COPY t3 FROM '/tmp/sepgsql_test_copy_1'; -- to be denied -+ERROR: SELinux: denied { insert } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_ro_table_t:s0 tclass=db_table name=t3 ++ERROR: SELinux: security policy violation +COPY t1 FROM '/tmp/sepgsql_test_copy_1'; +COPY 4 +COPY t1 TO stdout; @@ -295,9 +302,11 @@ diff -rpNU3 base/src/test/sepgsql/expected/copy_stmt.out sepgsql-new/src/test/se +4 ddd diff -rpNU3 base/src/test/sepgsql/expected/enhanced_ddl_stmt.out sepgsql-new/src/test/sepgsql/expected/enhanced_ddl_stmt.out --- base/src/test/sepgsql/expected/enhanced_ddl_stmt.out 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/test/sepgsql/expected/enhanced_ddl_stmt.out 2009-03-15 17:38:39.000000000 +0900 -@@ -0,0 +1,180 @@ ++++ sepgsql-new/src/test/sepgsql/expected/enhanced_ddl_stmt.out 2009-06-19 15:02:12.000000000 +0900 +@@ -0,0 +1,182 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 ++SET sepostgresql_mcstrans TO off; ++SET +SELECT sepgsql_getcon(); + sepgsql_getcon +----------------------------------------------------- @@ -384,12 +393,12 @@ diff -rpNU3 base/src/test/sepgsql/expected/enhanced_ddl_stmt.out sepgsql-new/src + a int, + b text +) SECURITY_CONTEXT = 'unconfined_u:object_r:invalid_label_t:s0'; -- to be failed -+ERROR: invalid security label: unconfined_u:object_r:invalid_label_t:s0 ++ERROR: Invalid security context: "unconfined_u:object_r:invalid_label_t:s0" +CREATE TABLE t4 ( + a int, + b text +) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0'; -- to be denied -+ERROR: SELinux: denied { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 tcontext=unconfined_u:object_r:sepgsql_proc_t:s0 tclass=db_table name=t4 ++ERROR: SELinux: security policy violation +-- ALTER TABLE with SECURITY_CONTEXT clause +ALTER TABLE t2 SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0'; +ALTER TABLE @@ -442,20 +451,20 @@ diff -rpNU3 base/src/test/sepgsql/expected/enhanced_ddl_stmt.out sepgsql-new/src + LANGUAGE 'sql' + SECURITY_CONTEXT = 'unconfined_u:object_r:invalid_label_t:s0' + AS 'SELECT $1 + $1'; -- to be failed -+ERROR: invalid security label: unconfined_u:object_r:invalid_label_t:s0 ++ERROR: Invalid security context: "unconfined_u:object_r:invalid_label_t:s0" +CREATE FUNCTION f2 (int) RETURNS int + LANGUAGE 'sql' + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c16' + AS 'SELECT $1 + $1'; -- to be denied -+ERROR: SELinux: denied { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 tcontext=unconfined_u:object_r:sepgsql_proc_t:s0:c16 tclass=db_procedure name=f2 ++ERROR: SELinux: security policy violation +CREATE FUNCTION f2 (int) RETURNS int + LANGUAGE 'sql' + AS 'SELECT $1 + $1'; +CREATE FUNCTION +SELECT proname, security_context FROM pg_proc WHERE oid = 'f2'::regproc; -+ proname | security_context -+---------+----------------------------------------- -+ f2 | unconfined_u:object_r:sepgsql_proc_t:s0 ++ proname | security_context ++---------+---------------------------------------------- ++ f2 | unconfined_u:object_r:sepgsql_proc_exec_t:s0 +(1 row) + +-- ALTER FUNCTION with SECURITY_CONTEXT clause @@ -470,18 +479,20 @@ diff -rpNU3 base/src/test/sepgsql/expected/enhanced_ddl_stmt.out sepgsql-new/src + +ALTER FUNCTION f2(int) + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c16'; -- to be denied -+ERROR: SELinux: denied { relabelto } scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 tcontext=unconfined_u:object_r:sepgsql_proc_t:s0:c16 tclass=db_procedure name=f2 ++ERROR: SELinux: security policy violation +SELECT proname, security_context FROM pg_proc WHERE oid = 'f2'::regproc; -+ proname | security_context -+---------+----------------------------------------- -+ f2 | unconfined_u:object_r:sepgsql_proc_t:s0 ++ proname | security_context ++---------+---------------------------------------------- ++ f2 | unconfined_u:object_r:sepgsql_proc_exec_t:s0 +(1 row) + diff -rpNU3 base/src/test/sepgsql/expected/join_query.out sepgsql-new/src/test/sepgsql/expected/join_query.out --- base/src/test/sepgsql/expected/join_query.out 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/test/sepgsql/expected/join_query.out 2009-03-15 17:38:39.000000000 +0900 -@@ -0,0 +1,85 @@ ++++ sepgsql-new/src/test/sepgsql/expected/join_query.out 2009-06-10 21:37:54.000000000 +0900 +@@ -0,0 +1,89 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 ++SET sepostgresql_mcstrans TO off; ++SET +SELECT sepgsql_getcon(); + sepgsql_getcon +----------------------------------------------------- @@ -538,6 +549,8 @@ diff -rpNU3 base/src/test/sepgsql/expected/join_query.out sepgsql-new/src/test/s +INSERT INTO t2 VALUES (1, 'sss'), (5, 'ttt'); +INSERT 0 2 +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 ++SET sepostgresql_mcstrans TO off; ++SET +SELECT sepgsql_getcon(); + sepgsql_getcon +--------------------------------------------------- @@ -545,7 +558,7 @@ diff -rpNU3 base/src/test/sepgsql/expected/join_query.out sepgsql-new/src/test/s +(1 row) + +SELECT * FROM t1 JOIN t2 ON a = x; -- to be denied -+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c ++ERROR: SELinux: security policy violation +SELECT a, b, y FROM t1 JOIN t2 ON a = x; + a | b | y +---+-----+----- @@ -557,7 +570,7 @@ diff -rpNU3 base/src/test/sepgsql/expected/join_query.out sepgsql-new/src/test/s +(5 rows) + +SELECT a, b, y FROM t1 JOIN t2 ON c = x; -- to be denied -+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c ++ERROR: SELinux: security policy violation +SELECT COUNT(*) FROM t1 JOIN t2 ON a = x; + count +------- @@ -565,12 +578,14 @@ diff -rpNU3 base/src/test/sepgsql/expected/join_query.out sepgsql-new/src/test/s +(1 row) + +SELECT j FROM (t1 JOIN t2 ON a = x) AS j; -- to be denied -+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c ++ERROR: SELinux: security policy violation diff -rpNU3 base/src/test/sepgsql/expected/large_object.out sepgsql-new/src/test/sepgsql/expected/large_object.out --- base/src/test/sepgsql/expected/large_object.out 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/test/sepgsql/expected/large_object.out 2009-03-03 14:31:40.000000000 +0900 -@@ -0,0 +1,293 @@ ++++ sepgsql-new/src/test/sepgsql/expected/large_object.out 2009-06-10 21:37:54.000000000 +0900 +@@ -0,0 +1,299 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 ++SET sepostgresql_mcstrans TO off; ++SET +SELECT sepgsql_getcon(); + sepgsql_getcon +----------------------------------------------------- @@ -623,6 +638,8 @@ diff -rpNU3 base/src/test/sepgsql/expected/large_object.out sepgsql-new/src/test +(1 row) + +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0:c0 ++SET sepostgresql_mcstrans TO off; ++SET +SELECT sepgsql_getcon(); + sepgsql_getcon +------------------------------------------------ @@ -805,6 +822,8 @@ diff -rpNU3 base/src/test/sepgsql/expected/large_object.out sepgsql-new/src/test +COMMIT; +COMMIT +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 ++SET sepostgresql_mcstrans TO off; ++SET +SELECT sepgsql_getcon(); + sepgsql_getcon +----------------------------------------------------- @@ -832,23 +851,23 @@ diff -rpNU3 base/src/test/sepgsql/expected/large_object.out sepgsql-new/src/test +(2 rows) + +SELECT lo_get_security(loid) FROM lolabel; -+ lo_get_security -+--------------------------------------------------------- ++ lo_get_security ++------------------------------------------------- + system_u:object_r:sepgsql_blob_t:s0:c4 + system_u:object_r:sepgsql_blob_t:s0:c4 + system_u:object_r:sepgsql_secret_blob_t:s0 -+ unconfined_u:object_r:sepgsql_test_sepgsql_blob_t:s0:c0 ++ unconfined_u:object_r:user_sepgsql_blob_t:s0:c0 +(4 rows) + +SELECT security_context, lo_label(loid) AS label, count(*) + FROM pg_largeobject WHERE loid in (SELECT loid FROM lolabel) + GROUP BY security_context, loid ORDER BY label; -+ security_context | label | count -+---------------------------------------------------------+----------+------- -+ unconfined_u:object_r:sepgsql_test_sepgsql_blob_t:s0:c0 | local | 1 -+ system_u:object_r:sepgsql_blob_t:s0:c4 | normal | 10 -+ system_u:object_r:sepgsql_blob_t:s0:c4 | readonly | 10 -+ system_u:object_r:sepgsql_secret_blob_t:s0 | secret | 10 ++ security_context | label | count ++-------------------------------------------------+----------+------- ++ unconfined_u:object_r:user_sepgsql_blob_t:s0:c0 | local | 1 ++ system_u:object_r:sepgsql_blob_t:s0:c4 | normal | 10 ++ system_u:object_r:sepgsql_blob_t:s0:c4 | readonly | 10 ++ system_u:object_r:sepgsql_secret_blob_t:s0 | secret | 10 +(4 rows) + +ROLLBACK; @@ -865,9 +884,11 @@ diff -rpNU3 base/src/test/sepgsql/expected/large_object.out sepgsql-new/src/test + diff -rpNU3 base/src/test/sepgsql/expected/row_level.out sepgsql-new/src/test/sepgsql/expected/row_level.out --- base/src/test/sepgsql/expected/row_level.out 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/test/sepgsql/expected/row_level.out 2009-03-02 00:24:34.000000000 +0900 -@@ -0,0 +1,131 @@ ++++ sepgsql-new/src/test/sepgsql/expected/row_level.out 2009-06-10 21:37:54.000000000 +0900 +@@ -0,0 +1,136 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 ++SET sepostgresql_mcstrans TO off; ++SET +SELECT sepgsql_getcon(); + sepgsql_getcon +----------------------------------------------------- @@ -936,6 +957,8 @@ diff -rpNU3 base/src/test/sepgsql/expected/row_level.out sepgsql-new/src/test/se +(3 rows) + +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0:c0 ++SET sepostgresql_mcstrans TO off; ++SET +SELECT sepgsql_getcon(); + sepgsql_getcon +------------------------------------------------ @@ -996,13 +1019,16 @@ diff -rpNU3 base/src/test/sepgsql/expected/row_level.out sepgsql-new/src/test/se +CONTEXT: SQL statement "SELECT 1 FROM ONLY "public"."t2" x WHERE $1 OPERATOR(pg_catalog.=) "x" FOR SHARE OF x" +DELETE FROM t1 WHERE a not in (SELECT x FROM t2); -- to be failed +ERROR: SELinux: security policy violation ++CONTEXT: SQL statement "SELECT 1 FROM ONLY "public"."t2" x WHERE $1 OPERATOR(pg_catalog.=) "x" FOR SHARE OF x" +DELETE FROM t1 WHERE a = 7; +DELETE 1 diff -rpNU3 base/src/test/sepgsql/expected/security_label.out sepgsql-new/src/test/sepgsql/expected/security_label.out --- base/src/test/sepgsql/expected/security_label.out 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/test/sepgsql/expected/security_label.out 2009-03-02 00:24:34.000000000 +0900 -@@ -0,0 +1,127 @@ ++++ sepgsql-new/src/test/sepgsql/expected/security_label.out 2009-06-10 21:37:54.000000000 +0900 +@@ -0,0 +1,129 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 ++SET sepostgresql_mcstrans TO off; ++SET +SELECT sepgsql_getcon(); + sepgsql_getcon +----------------------------------------------------- @@ -1051,7 +1077,7 @@ diff -rpNU3 base/src/test/sepgsql/expected/security_label.out sepgsql-new/src/te +INSERT INTO t1 VALUES (4, 'ddd'), (5, 'eee'); +INSERT 0 2 +INSERT INTO t1 (security_context, a, b) VALUES ('invalid security context', 6, 'fff'); -- to be failed -+ERROR: invalid security label: invalid security context ++ERROR: Invalid security context: "invalid security context" +INSERT INTO t1 (security_context, a, b) VALUES ('system_u:object_r:sepgsql_table_t:s0:c20', 6, 'fff'); -- to be denied +INSERT 0 0 +SELECT security_context, * FROM t1; @@ -1131,8 +1157,8 @@ diff -rpNU3 base/src/test/sepgsql/expected/security_label.out sepgsql-new/src/te +system_u:object_r:sepgsql_table_t:s0:c4 13 nnn diff -rpNU3 base/src/test/sepgsql/launch_psql.c sepgsql-new/src/test/sepgsql/launch_psql.c --- base/src/test/sepgsql/launch_psql.c 1970-01-01 09:00:00.000000000 +0900 -+++ sepgsql-new/src/test/sepgsql/launch_psql.c 2009-03-02 00:24:34.000000000 +0900 -@@ -0,0 +1,87 @@ ++++ sepgsql-new/src/test/sepgsql/launch_psql.c 2009-06-10 21:37:54.000000000 +0900 +@@ -0,0 +1,91 @@ +/* + * launch_psql.c + * @@ -1189,6 +1215,10 @@ diff -rpNU3 base/src/test/sepgsql/launch_psql.c sepgsql-new/src/test/sepgsql/lau + pclose(filp); + filp = NULL; + } ++ /* Inject SET sepostgresql_mcstrans TO off */ ++ ofs = strlen(buffer); ++ snprintf(buffer + ofs, sizeof(buffer) - ofs, ++ "\nSET sepostgresql_mcstrans TO off;\n"); + + /* Inject a pseudo sepgsql_getcon() to confirm new context */ + ofs = strlen(buffer); diff --git a/sepostgresql-utils-8.3.patch b/sepostgresql-utils-8.3.patch index 7fab346..25faf9a 100644 --- a/sepostgresql-utils-8.3.patch +++ b/sepostgresql-utils-8.3.patch @@ -1,6 +1,6 @@ diff -rpNU3 base/src/bin/initdb/initdb.c sepgsql-new/src/bin/initdb/initdb.c ---- base/src/bin/initdb/initdb.c 2008-11-05 09:57:00.000000000 +0900 -+++ sepgsql-new/src/bin/initdb/initdb.c 2009-03-13 18:14:33.000000000 +0900 +--- base/src/bin/initdb/initdb.c 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/src/bin/initdb/initdb.c 2009-09-10 20:24:37.000000000 +0900 @@ -94,6 +94,7 @@ static bool debug = false; static bool noclean = false; static bool show_setting = false; @@ -9,7 +9,7 @@ diff -rpNU3 base/src/bin/initdb/initdb.c sepgsql-new/src/bin/initdb/initdb.c /* internal vars */ -@@ -1212,6 +1213,13 @@ setup_config(void) +@@ -1224,6 +1225,13 @@ setup_config(void) "#default_text_search_config = 'pg_catalog.simple'", repltok); @@ -23,7 +23,7 @@ diff -rpNU3 base/src/bin/initdb/initdb.c sepgsql-new/src/bin/initdb/initdb.c snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data); writefile(path, conflines); -@@ -2383,6 +2391,7 @@ usage(const char *progname) +@@ -2395,6 +2403,7 @@ usage(const char *progname) printf(_(" -U, --username=NAME database superuser name\n")); printf(_(" -W, --pwprompt prompt for a password for the new superuser\n")); printf(_(" --pwfile=FILE read password for the new superuser from file\n")); @@ -31,7 +31,7 @@ diff -rpNU3 base/src/bin/initdb/initdb.c sepgsql-new/src/bin/initdb/initdb.c printf(_(" -?, --help show this help, then exit\n")); printf(_(" -V, --version output version information, then exit\n")); printf(_("\nLess commonly used options:\n")); -@@ -2417,6 +2426,7 @@ main(int argc, char *argv[]) +@@ -2429,6 +2438,7 @@ main(int argc, char *argv[]) {"auth", required_argument, NULL, 'A'}, {"pwprompt", no_argument, NULL, 'W'}, {"pwfile", required_argument, NULL, 9}, @@ -39,7 +39,7 @@ diff -rpNU3 base/src/bin/initdb/initdb.c sepgsql-new/src/bin/initdb/initdb.c {"username", required_argument, NULL, 'U'}, {"help", no_argument, NULL, '?'}, {"version", no_argument, NULL, 'V'}, -@@ -2531,6 +2541,9 @@ main(int argc, char *argv[]) +@@ -2543,6 +2553,9 @@ main(int argc, char *argv[]) case 9: pwfilename = xstrdup(optarg); break; @@ -50,8 +50,8 @@ diff -rpNU3 base/src/bin/initdb/initdb.c sepgsql-new/src/bin/initdb/initdb.c show_setting = true; break; diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c ---- base/src/bin/pg_dump/pg_dump.c 2009-02-02 11:47:17.000000000 +0900 -+++ sepgsql-new/src/bin/pg_dump/pg_dump.c 2009-03-13 18:14:33.000000000 +0900 +--- base/src/bin/pg_dump/pg_dump.c 2009-09-10 20:11:35.000000000 +0900 ++++ sepgsql-new/src/bin/pg_dump/pg_dump.c 2009-09-10 20:24:37.000000000 +0900 @@ -118,6 +118,8 @@ static int g_numNamespaces; /* flag to turn on/off dollar quoting */ static int disable_dollar_quoting = 0; @@ -121,7 +121,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c fmtQualifiedId(tbinfo->dobj.namespace->dobj.name, classname)); } -@@ -1785,11 +1810,29 @@ dumpBlobComments(Archive *AH, void *arg) +@@ -1791,11 +1816,29 @@ dumpBlobComments(Archive *AH, void *arg) Oid blobOid; char *comment; @@ -152,7 +152,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c comment = PQgetvalue(res, i, 1); printfPQExpBuffer(commentcmd, "COMMENT ON LARGE OBJECT %u IS ", -@@ -2887,6 +2930,7 @@ getTables(int *numTables) +@@ -2893,6 +2936,7 @@ getTables(int *numTables) int i_owning_col; int i_reltablespace; int i_reloptions; @@ -160,7 +160,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c /* Make sure we are in proper schema */ selectSourceSchema("pg_catalog"); -@@ -2926,7 +2970,8 @@ getTables(int *numTables) +@@ -2932,7 +2976,8 @@ getTables(int *numTables) "d.refobjid as owning_tab, " "d.refobjsubid as owning_col, " "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, " @@ -170,7 +170,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c "from pg_class c " "left join pg_depend d on " "(c.relkind = '%c' and " -@@ -2936,6 +2981,7 @@ getTables(int *numTables) +@@ -2942,6 +2987,7 @@ getTables(int *numTables) "where relkind in ('%c', '%c', '%c', '%c') " "order by c.oid", username_subquery, @@ -178,7 +178,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c RELKIND_SEQUENCE, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW, RELKIND_COMPOSITE_TYPE); -@@ -2955,7 +3001,8 @@ getTables(int *numTables) +@@ -2961,7 +3007,8 @@ getTables(int *numTables) "d.refobjid as owning_tab, " "d.refobjsubid as owning_col, " "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, " @@ -188,7 +188,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c "from pg_class c " "left join pg_depend d on " "(c.relkind = '%c' and " -@@ -2984,7 +3031,8 @@ getTables(int *numTables) +@@ -2990,7 +3037,8 @@ getTables(int *numTables) "d.refobjid as owning_tab, " "d.refobjsubid as owning_col, " "NULL as reltablespace, " @@ -198,7 +198,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c "from pg_class c " "left join pg_depend d on " "(c.relkind = '%c' and " -@@ -3009,7 +3057,8 @@ getTables(int *numTables) +@@ -3015,7 +3063,8 @@ getTables(int *numTables) "NULL::oid as owning_tab, " "NULL::int4 as owning_col, " "NULL as reltablespace, " @@ -208,7 +208,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c "from pg_class " "where relkind in ('%c', '%c', '%c') " "order by oid", -@@ -3029,7 +3078,8 @@ getTables(int *numTables) +@@ -3035,7 +3084,8 @@ getTables(int *numTables) "NULL::oid as owning_tab, " "NULL::int4 as owning_col, " "NULL as reltablespace, " @@ -218,7 +218,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c "from pg_class " "where relkind in ('%c', '%c', '%c') " "order by oid", -@@ -3059,7 +3109,8 @@ getTables(int *numTables) +@@ -3065,7 +3115,8 @@ getTables(int *numTables) "NULL::oid as owning_tab, " "NULL::int4 as owning_col, " "NULL as reltablespace, " @@ -228,7 +228,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c "from pg_class c " "where relkind in ('%c', '%c') " "order by oid", -@@ -3102,6 +3153,7 @@ getTables(int *numTables) +@@ -3108,6 +3159,7 @@ getTables(int *numTables) i_owning_col = PQfnumber(res, "owning_col"); i_reltablespace = PQfnumber(res, "reltablespace"); i_reloptions = PQfnumber(res, "reloptions"); @@ -236,7 +236,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c for (i = 0; i < ntups; i++) { -@@ -3132,6 +3184,7 @@ getTables(int *numTables) +@@ -3138,6 +3190,7 @@ getTables(int *numTables) } tblinfo[i].reltablespace = strdup(PQgetvalue(res, i, i_reltablespace)); tblinfo[i].reloptions = strdup(PQgetvalue(res, i, i_reloptions)); @@ -244,7 +244,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c /* other fields were zeroed above */ -@@ -4320,6 +4373,7 @@ getTableAttrs(TableInfo *tblinfo, int nu +@@ -4326,6 +4379,7 @@ getTableAttrs(TableInfo *tblinfo, int nu int i_atthasdef; int i_attisdropped; int i_attislocal; @@ -252,7 +252,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c PGresult *res; int ntups; bool hasdefaults; -@@ -4362,12 +4416,14 @@ getTableAttrs(TableInfo *tblinfo, int nu +@@ -4368,12 +4422,14 @@ getTableAttrs(TableInfo *tblinfo, int nu /* need left join here to not fail on dropped columns ... */ appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, a.attstattarget, a.attstorage, t.typstorage, " "a.attnotnull, a.atthasdef, a.attisdropped, a.attislocal, " @@ -268,7 +268,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c tbinfo->dobj.catId.oid); } else if (g_fout->remoteVersion >= 70100) -@@ -4379,7 +4435,8 @@ getTableAttrs(TableInfo *tblinfo, int nu +@@ -4385,7 +4441,8 @@ getTableAttrs(TableInfo *tblinfo, int nu */ appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, -1 as attstattarget, a.attstorage, t.typstorage, " "a.attnotnull, a.atthasdef, false as attisdropped, false as attislocal, " @@ -278,7 +278,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c "from pg_attribute a left join pg_type t " "on a.atttypid = t.oid " "where a.attrelid = '%u'::oid " -@@ -4392,7 +4449,8 @@ getTableAttrs(TableInfo *tblinfo, int nu +@@ -4398,7 +4455,8 @@ getTableAttrs(TableInfo *tblinfo, int nu /* format_type not available before 7.1 */ appendPQExpBuffer(q, "SELECT attnum, attname, atttypmod, -1 as attstattarget, attstorage, attstorage as typstorage, " "attnotnull, atthasdef, false as attisdropped, false as attislocal, " @@ -288,7 +288,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c "from pg_attribute a " "where attrelid = '%u'::oid " "and attnum > 0::int2 " -@@ -4416,6 +4474,7 @@ getTableAttrs(TableInfo *tblinfo, int nu +@@ -4422,6 +4480,7 @@ getTableAttrs(TableInfo *tblinfo, int nu i_atthasdef = PQfnumber(res, "atthasdef"); i_attisdropped = PQfnumber(res, "attisdropped"); i_attislocal = PQfnumber(res, "attislocal"); @@ -296,7 +296,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c tbinfo->numatts = ntups; tbinfo->attnames = (char **) malloc(ntups * sizeof(char *)); -@@ -4426,6 +4485,7 @@ getTableAttrs(TableInfo *tblinfo, int nu +@@ -4432,6 +4491,7 @@ getTableAttrs(TableInfo *tblinfo, int nu tbinfo->typstorage = (char *) malloc(ntups * sizeof(char)); tbinfo->attisdropped = (bool *) malloc(ntups * sizeof(bool)); tbinfo->attislocal = (bool *) malloc(ntups * sizeof(bool)); @@ -304,7 +304,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c tbinfo->notnull = (bool *) malloc(ntups * sizeof(bool)); tbinfo->attrdefs = (AttrDefInfo **) malloc(ntups * sizeof(AttrDefInfo *)); tbinfo->inhAttrs = (bool *) malloc(ntups * sizeof(bool)); -@@ -4449,6 +4509,7 @@ getTableAttrs(TableInfo *tblinfo, int nu +@@ -4455,6 +4515,7 @@ getTableAttrs(TableInfo *tblinfo, int nu tbinfo->typstorage[j] = *(PQgetvalue(res, j, i_typstorage)); tbinfo->attisdropped[j] = (PQgetvalue(res, j, i_attisdropped)[0] == 't'); tbinfo->attislocal[j] = (PQgetvalue(res, j, i_attislocal)[0] == 't'); @@ -312,7 +312,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c tbinfo->notnull[j] = (PQgetvalue(res, j, i_attnotnull)[0] == 't'); tbinfo->attrdefs[j] = NULL; /* fix below */ if (PQgetvalue(res, j, i_atthasdef)[0] == 't') -@@ -6430,6 +6491,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) +@@ -6436,6 +6497,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) char *procost; char *prorows; char *lanname; @@ -320,7 +320,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c char *rettypename; int nallargs; char **allargtypes = NULL; -@@ -6459,9 +6521,11 @@ dumpFunc(Archive *fout, FuncInfo *finfo) +@@ -6465,9 +6527,11 @@ dumpFunc(Archive *fout, FuncInfo *finfo) "proallargtypes, proargmodes, proargnames, " "provolatile, proisstrict, prosecdef, " "proconfig, procost, prorows, " @@ -333,7 +333,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c finfo->dobj.catId.oid); } else if (g_fout->remoteVersion >= 80100) -@@ -6471,7 +6535,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo) +@@ -6477,7 +6541,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo) "proallargtypes, proargmodes, proargnames, " "provolatile, proisstrict, prosecdef, " "null as proconfig, 0 as procost, 0 as prorows, " @@ -343,7 +343,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c "FROM pg_catalog.pg_proc " "WHERE oid = '%u'::pg_catalog.oid", finfo->dobj.catId.oid); -@@ -6485,7 +6550,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo) +@@ -6491,7 +6556,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo) "proargnames, " "provolatile, proisstrict, prosecdef, " "null as proconfig, 0 as procost, 0 as prorows, " @@ -353,7 +353,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c "FROM pg_catalog.pg_proc " "WHERE oid = '%u'::pg_catalog.oid", finfo->dobj.catId.oid); -@@ -6499,7 +6565,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo) +@@ -6505,7 +6571,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo) "null as proargnames, " "provolatile, proisstrict, prosecdef, " "null as proconfig, 0 as procost, 0 as prorows, " @@ -363,7 +363,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c "FROM pg_catalog.pg_proc " "WHERE oid = '%u'::pg_catalog.oid", finfo->dobj.catId.oid); -@@ -6515,7 +6582,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo) +@@ -6521,7 +6588,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo) "proisstrict, " "'f'::boolean as prosecdef, " "null as proconfig, 0 as procost, 0 as prorows, " @@ -373,7 +373,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c "FROM pg_proc " "WHERE oid = '%u'::oid", finfo->dobj.catId.oid); -@@ -6531,7 +6599,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo) +@@ -6537,7 +6605,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo) "'f'::boolean as proisstrict, " "'f'::boolean as prosecdef, " "null as proconfig, 0 as procost, 0 as prorows, " @@ -383,7 +383,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c "FROM pg_proc " "WHERE oid = '%u'::oid", finfo->dobj.catId.oid); -@@ -6562,6 +6631,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) +@@ -6568,6 +6637,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) procost = PQgetvalue(res, 0, PQfnumber(res, "procost")); prorows = PQgetvalue(res, 0, PQfnumber(res, "prorows")); lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname")); @@ -391,7 +391,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c /* * See backend/commands/define.c for details of how the 'AS' clause is -@@ -6699,6 +6769,9 @@ dumpFunc(Archive *fout, FuncInfo *finfo) +@@ -6705,6 +6775,9 @@ dumpFunc(Archive *fout, FuncInfo *finfo) if (prosecdef[0] == 't') appendPQExpBuffer(q, " SECURITY DEFINER"); @@ -401,7 +401,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c /* * COST and ROWS are emitted only if present and not default, so as not to * break backwards-compatibility of the dump without need. Keep this code -@@ -8780,6 +8853,10 @@ dumpTableSchema(Archive *fout, TableInfo +@@ -8786,6 +8859,10 @@ dumpTableSchema(Archive *fout, TableInfo if (tbinfo->notnull[j] && !tbinfo->inhNotNull[j]) appendPQExpBuffer(q, " NOT NULL"); @@ -412,7 +412,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c actual_atts++; } } -@@ -8827,6 +8904,9 @@ dumpTableSchema(Archive *fout, TableInfo +@@ -8833,6 +8910,9 @@ dumpTableSchema(Archive *fout, TableInfo if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0) appendPQExpBuffer(q, "\nWITH (%s)", tbinfo->reloptions); @@ -422,7 +422,7 @@ diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c appendPQExpBuffer(q, ";\n"); /* Loop dumping statistics and storage statements */ -@@ -10244,6 +10324,13 @@ fmtCopyColumnList(const TableInfo *ti) +@@ -10250,6 +10330,13 @@ fmtCopyColumnList(const TableInfo *ti) appendPQExpBuffer(q, "("); needComma = false; diff --git a/sepostgresql.init b/sepostgresql.init index 8faef56..e70a789 100644 --- a/sepostgresql.init +++ b/sepostgresql.init @@ -7,9 +7,9 @@ # pidfile: /var/run/postmaster.pid #--------------------------------------------------------------------- -PGVERSION="8.3.7" +PGVERSION="8.3.8" PGMAJORVERSION=`echo "$PGVERSION" | sed 's/^\([0-9]*\.[0-9a-z]*\).*$/\1/'` -SEPGVERSION="1990" +SEPGVERSION="2300" # source function library . /etc/rc.d/init.d/functions diff --git a/sepostgresql.spec b/sepostgresql.spec index c17cbf7..50e0117 100644 --- a/sepostgresql.spec +++ b/sepostgresql.spec @@ -11,8 +11,8 @@ Summary: Security Enhanced PostgreSQL Name: sepostgresql -Version: 8.3.7 -Release: 1990%{?dist} +Version: 8.3.8 +Release: 2300%{?dist} License: BSD Group: Applications/Databases Url: http://code.google.com/p/sepgsql/ @@ -36,7 +36,7 @@ Requires(post): policycoreutils /sbin/chkconfig Requires(preun): /sbin/chkconfig /sbin/service Requires(postun): policycoreutils Requires: postgresql-server = %{version} -Requires: policycoreutils >= 2.0.16 libselinux >= 2.0.43 +Requires: policycoreutils >= 2.0.16 libselinux >= 2.0.80 Requires: selinux-policy >= 3.4.2 Requires: tzdata logrotate @@ -199,6 +199,9 @@ fi %attr(700,sepgsql,sepgsql) %dir %{_localstatedir}/lib/sepgsql/backups %changelog +* Thu Sep 10 2009 KaiGai Kohei - 8.3.8-2300 +- upgrade base PostgreSQL v8.3.7->8.3.8 + * Tue Jun 9 2009 KaiGai Kohei - 8.3.7-1990 - backport features from v8.4devel, it also needs libselinux-2.0.80 diff --git a/sources b/sources index 7a88da9..76ef09b 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -7b7e91a2221e55fe1b167e663217a96d postgresql-8.3.7.tar.bz2 +aac683d03f765dc58a3a0e5eaa1927bf postgresql-8.3.8.tar.bz2