summaryrefslogtreecommitdiff
path: root/contrib/sepgsql/relation.c
diff options
context:
space:
mode:
authorMichael P2011-07-05 03:16:11 +0000
committerMichael P2011-07-06 03:40:35 +0000
commit0bbfc1e6338b5d98d6cb83fa75f2c38f527d4d4b (patch)
tree46fa412a31d08ea6e53d488ae7bc231df0b273da /contrib/sepgsql/relation.c
parent091b0e828cf0fd5bbd1f9ae58ab96fc983e55d77 (diff)
parenta4bebdd92624e018108c2610fc3f2c1584b6c687 (diff)
Merge commit 'a4bebdd92624e018108c2610fc3f2c1584b6c687' into master
This is the commit merge of Postgres-XC with the intersection of PostgreSQL REL9_1_STABLE and master branches. Conflicts: COPYRIGHT contrib/pgbench/pgbench.c src/Makefile src/backend/access/transam/recovery.conf.sample src/backend/access/transam/varsup.c src/backend/access/transam/xlog.c src/backend/catalog/Makefile src/backend/catalog/dependency.c src/backend/catalog/system_views.sql src/backend/commands/copy.c src/backend/commands/explain.c src/backend/commands/sequence.c src/backend/commands/tablecmds.c src/backend/commands/vacuum.c src/backend/executor/nodeAgg.c src/backend/nodes/copyfuncs.c src/backend/nodes/equalfuncs.c src/backend/nodes/outfuncs.c src/backend/nodes/readfuncs.c src/backend/optimizer/path/allpaths.c src/backend/optimizer/plan/createplan.c src/backend/optimizer/plan/setrefs.c src/backend/parser/gram.y src/backend/parser/parse_utilcmd.c src/backend/postmaster/postmaster.c src/backend/rewrite/rewriteHandler.c src/backend/storage/lmgr/proc.c src/backend/tcop/postgres.c src/backend/utils/adt/ruleutils.c src/backend/utils/init/postinit.c src/backend/utils/misc/guc.c src/backend/utils/misc/postgresql.conf.sample src/backend/utils/sort/tuplesort.c src/bin/initdb/initdb.c src/bin/pg_ctl/pg_ctl.c src/bin/pg_dump/pg_dump.c src/include/access/xlog.h src/include/catalog/catversion.h src/include/catalog/indexing.h src/include/catalog/pg_aggregate.h src/include/catalog/pg_proc.h src/include/commands/copy.h src/include/nodes/parsenodes.h src/include/nodes/primnodes.h src/include/optimizer/pathnode.h src/include/parser/kwlist.h src/include/storage/procarray.h src/test/regress/expected/.gitignore src/test/regress/expected/aggregates.out src/test/regress/expected/alter_table.out src/test/regress/expected/bit.out src/test/regress/expected/box.out src/test/regress/expected/delete.out src/test/regress/expected/float4.out src/test/regress/expected/float8.out src/test/regress/expected/int2.out src/test/regress/expected/int8.out src/test/regress/expected/interval.out src/test/regress/expected/numeric.out src/test/regress/expected/point.out src/test/regress/expected/polygon.out src/test/regress/expected/sequence.out src/test/regress/expected/timestamp.out src/test/regress/expected/timestamptz.out src/test/regress/expected/transactions.out src/test/regress/expected/window.out src/test/regress/input/misc.source src/test/regress/output/create_misc_1.source src/test/regress/output/misc.source src/test/regress/sql/aggregates.sql src/test/regress/sql/alter_table.sql src/test/regress/sql/bit.sql src/test/regress/sql/box.sql src/test/regress/sql/delete.sql src/test/regress/sql/domain.sql src/test/regress/sql/float4.sql src/test/regress/sql/float8.sql src/test/regress/sql/int2.sql src/test/regress/sql/int8.sql src/test/regress/sql/interval.sql src/test/regress/sql/lseg.sql src/test/regress/sql/numeric.sql src/test/regress/sql/path.sql src/test/regress/sql/point.sql src/test/regress/sql/polygon.sql src/test/regress/sql/portals.sql src/test/regress/sql/sequence.sql src/test/regress/sql/timestamp.sql src/test/regress/sql/timestamptz.sql src/test/regress/sql/transactions.sql src/test/regress/sql/window.sql src/test/regress/sql/with.sql
Diffstat (limited to 'contrib/sepgsql/relation.c')
-rw-r--r--contrib/sepgsql/relation.c276
1 files changed, 276 insertions, 0 deletions
diff --git a/contrib/sepgsql/relation.c b/contrib/sepgsql/relation.c
new file mode 100644
index 0000000000..963cfdf9f1
--- /dev/null
+++ b/contrib/sepgsql/relation.c
@@ -0,0 +1,276 @@
+/* -------------------------------------------------------------------------
+ *
+ * contrib/sepgsql/label.c
+ *
+ * Routines corresponding to relation/attribute objects
+ *
+ * Copyright (c) 2010-2011, PostgreSQL Global Development Group
+ *
+ * -------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "access/genam.h"
+#include "access/heapam.h"
+#include "access/sysattr.h"
+#include "catalog/indexing.h"
+#include "catalog/dependency.h"
+#include "catalog/pg_attribute.h"
+#include "catalog/pg_class.h"
+#include "catalog/pg_namespace.h"
+#include "commands/seclabel.h"
+#include "utils/fmgroids.h"
+#include "utils/lsyscache.h"
+#include "utils/tqual.h"
+
+#include "sepgsql.h"
+
+/*
+ * sepgsql_attribute_post_create
+ *
+ * This routine assigns a default security label on a newly defined
+ * column, using ALTER TABLE ... ADD COLUMN.
+ * Note that this routine is not invoked in the case of CREATE TABLE,
+ * although it also defines columns in addition to table.
+ */
+void
+sepgsql_attribute_post_create(Oid relOid, AttrNumber attnum)
+{
+ char *scontext = sepgsql_get_client_label();
+ char *tcontext;
+ char *ncontext;
+ ObjectAddress object;
+
+ /*
+ * Only attributes within regular relation have individual security
+ * labels.
+ */
+ if (get_rel_relkind(relOid) != RELKIND_RELATION)
+ return;
+
+ /*
+ * Compute a default security label when we create a new procedure object
+ * under the specified namespace.
+ */
+ scontext = sepgsql_get_client_label();
+ tcontext = sepgsql_get_label(RelationRelationId, relOid, 0);
+ ncontext = sepgsql_compute_create(scontext, tcontext,
+ SEPG_CLASS_DB_COLUMN);
+
+ /*
+ * Assign the default security label on a new procedure
+ */
+ object.classId = RelationRelationId;
+ object.objectId = relOid;
+ object.objectSubId = attnum;
+ SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
+
+ pfree(tcontext);
+ pfree(ncontext);
+}
+
+/*
+ * sepgsql_attribute_relabel
+ *
+ * It checks privileges to relabel the supplied column
+ * by the `seclabel'.
+ */
+void
+sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
+ const char *seclabel)
+{
+ char *scontext = sepgsql_get_client_label();
+ char *tcontext;
+ char *audit_name;
+ ObjectAddress object;
+
+ if (get_rel_relkind(relOid) != RELKIND_RELATION)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot set security label on non-regular columns")));
+
+ object.classId = RelationRelationId;
+ object.objectId = relOid;
+ object.objectSubId = attnum;
+ audit_name = getObjectDescription(&object);
+
+ /*
+ * check db_column:{setattr relabelfrom} permission
+ */
+ tcontext = sepgsql_get_label(RelationRelationId, relOid, attnum);
+ sepgsql_check_perms(scontext,
+ tcontext,
+ SEPG_CLASS_DB_COLUMN,
+ SEPG_DB_COLUMN__SETATTR |
+ SEPG_DB_COLUMN__RELABELFROM,
+ audit_name,
+ true);
+
+ /*
+ * check db_column:{relabelto} permission
+ */
+ sepgsql_check_perms(scontext,
+ seclabel,
+ SEPG_CLASS_DB_COLUMN,
+ SEPG_DB_PROCEDURE__RELABELTO,
+ audit_name,
+ true);
+
+ pfree(tcontext);
+ pfree(audit_name);
+}
+
+/*
+ * sepgsql_relation_post_create
+ *
+ * The post creation hook of relation/attribute
+ */
+void
+sepgsql_relation_post_create(Oid relOid)
+{
+ Relation rel;
+ ScanKeyData skey;
+ SysScanDesc sscan;
+ HeapTuple tuple;
+ Form_pg_class classForm;
+ ObjectAddress object;
+ uint16 tclass;
+ char *scontext; /* subject */
+ char *tcontext; /* schema */
+ char *rcontext; /* relation */
+ char *ccontext; /* column */
+
+ /*
+ * Fetch catalog record of the new relation. Because pg_class entry is not
+ * visible right now, we need to scan the catalog using SnapshotSelf.
+ */
+ rel = heap_open(RelationRelationId, AccessShareLock);
+
+ ScanKeyInit(&skey,
+ ObjectIdAttributeNumber,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(relOid));
+
+ sscan = systable_beginscan(rel, ClassOidIndexId, true,
+ SnapshotSelf, 1, &skey);
+
+ tuple = systable_getnext(sscan);
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "catalog lookup failed for relation %u", relOid);
+
+ classForm = (Form_pg_class) GETSTRUCT(tuple);
+
+ if (classForm->relkind == RELKIND_RELATION)
+ tclass = SEPG_CLASS_DB_TABLE;
+ else if (classForm->relkind == RELKIND_SEQUENCE)
+ tclass = SEPG_CLASS_DB_SEQUENCE;
+ else if (classForm->relkind == RELKIND_VIEW)
+ tclass = SEPG_CLASS_DB_VIEW;
+ else
+ goto out; /* No need to assign individual labels */
+
+ /*
+ * Compute a default security label when we create a new relation object
+ * under the specified namespace.
+ */
+ scontext = sepgsql_get_client_label();
+ tcontext = sepgsql_get_label(NamespaceRelationId,
+ classForm->relnamespace, 0);
+ rcontext = sepgsql_compute_create(scontext, tcontext, tclass);
+
+ /*
+ * Assign the default security label on the new relation
+ */
+ object.classId = RelationRelationId;
+ object.objectId = relOid;
+ object.objectSubId = 0;
+ SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, rcontext);
+
+ /*
+ * We also assigns a default security label on columns of the new regular
+ * tables.
+ */
+ if (classForm->relkind == RELKIND_RELATION)
+ {
+ AttrNumber index;
+
+ ccontext = sepgsql_compute_create(scontext, rcontext,
+ SEPG_CLASS_DB_COLUMN);
+ for (index = FirstLowInvalidHeapAttributeNumber + 1;
+ index <= classForm->relnatts;
+ index++)
+ {
+ if (index == InvalidAttrNumber)
+ continue;
+
+ if (index == ObjectIdAttributeNumber && !classForm->relhasoids)
+ continue;
+
+ object.classId = RelationRelationId;
+ object.objectId = relOid;
+ object.objectSubId = index;
+ SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ccontext);
+ }
+ pfree(ccontext);
+ }
+ pfree(rcontext);
+out:
+ systable_endscan(sscan);
+ heap_close(rel, AccessShareLock);
+}
+
+/*
+ * sepgsql_relation_relabel
+ *
+ * It checks privileges to relabel the supplied relation by the `seclabel'.
+ */
+void
+sepgsql_relation_relabel(Oid relOid, const char *seclabel)
+{
+ char *scontext = sepgsql_get_client_label();
+ char *tcontext;
+ char *audit_name;
+ char relkind;
+ uint16_t tclass = 0;
+
+ relkind = get_rel_relkind(relOid);
+ if (relkind == RELKIND_RELATION)
+ tclass = SEPG_CLASS_DB_TABLE;
+ else if (relkind == RELKIND_SEQUENCE)
+ tclass = SEPG_CLASS_DB_SEQUENCE;
+ else if (relkind == RELKIND_VIEW)
+ tclass = SEPG_CLASS_DB_VIEW;
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot set security labels on relations except "
+ "for tables, sequences or views")));
+
+ audit_name = getObjectDescriptionOids(RelationRelationId, relOid);
+
+ /*
+ * check db_xxx:{setattr relabelfrom} permission
+ */
+ tcontext = sepgsql_get_label(RelationRelationId, relOid, 0);
+
+ sepgsql_check_perms(scontext,
+ tcontext,
+ tclass,
+ SEPG_DB_TABLE__SETATTR |
+ SEPG_DB_TABLE__RELABELFROM,
+ audit_name,
+ true);
+
+ /*
+ * check db_xxx:{relabelto} permission
+ */
+ sepgsql_check_perms(scontext,
+ seclabel,
+ tclass,
+ SEPG_DB_TABLE__RELABELTO,
+ audit_name,
+ true);
+
+ pfree(tcontext);
+ pfree(audit_name);
+}