diff options
author | Michael P | 2011-07-05 03:16:11 +0000 |
---|---|---|
committer | Michael P | 2011-07-06 03:40:35 +0000 |
commit | 0bbfc1e6338b5d98d6cb83fa75f2c38f527d4d4b (patch) | |
tree | 46fa412a31d08ea6e53d488ae7bc231df0b273da /contrib/sepgsql/relation.c | |
parent | 091b0e828cf0fd5bbd1f9ae58ab96fc983e55d77 (diff) | |
parent | a4bebdd92624e018108c2610fc3f2c1584b6c687 (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.c | 276 |
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); +} |