pgsql-v9.1-security-label-1.v1.patch

application/octect-stream

Filename: pgsql-v9.1-security-label-1.v1.patch
Type: application/octect-stream
Part: 0
Message: security label support, part.1

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: context
Series: patch v9
File+
src/backend/catalog/dependency.c 8 0
src/backend/catalog/Makefile 1 0
src/backend/commands/Makefile 1 0
src/backend/commands/seclabel.c 259 0
src/include/catalog/indexing.h 3 0
src/include/catalog/pg_seclabel.h 41 0
src/include/catalog/toasting.h 1 0
src/include/commands/seclabel.h 21 0
src/test/regress/expected/sanity_check.out 2 0
*** a/src/backend/catalog/Makefile
--- b/src/backend/catalog/Makefile
***************
*** 37,43 **** POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
  	pg_ts_config.h pg_ts_config_map.h pg_ts_dict.h \
  	pg_ts_parser.h pg_ts_template.h \
  	pg_foreign_data_wrapper.h pg_foreign_server.h pg_user_mapping.h \
! 	pg_default_acl.h \
  	toasting.h indexing.h \
      )
  
--- 37,43 ----
  	pg_ts_config.h pg_ts_config_map.h pg_ts_dict.h \
  	pg_ts_parser.h pg_ts_template.h \
  	pg_foreign_data_wrapper.h pg_foreign_server.h pg_user_mapping.h \
! 	pg_default_acl.h pg_seclabel.h \
  	toasting.h indexing.h \
      )
  
*** a/src/backend/catalog/dependency.c
--- b/src/backend/catalog/dependency.c
***************
*** 57,62 ****
--- 57,63 ----
  #include "commands/defrem.h"
  #include "commands/proclang.h"
  #include "commands/schemacmds.h"
+ #include "commands/seclabel.h"
  #include "commands/tablespace.h"
  #include "commands/trigger.h"
  #include "commands/typecmds.h"
***************
*** 1010,1015 **** deleteOneObject(const ObjectAddress *object, Relation depRel)
--- 1011,1023 ----
  	DeleteComments(object->objectId, object->classId, object->objectSubId);
  
  	/*
+ 	 * Delete any security labels associated with this object. (This is also
+ 	 * a convenient place to do it instead of having every object type know
+ 	 * to do it.)
+ 	 */
+ 	DeleteSecurityLabel(object->classId, object->objectId, object->objectSubId);
+ 
+ 	/*
  	 * CommandCounterIncrement here to ensure that preceding changes are all
  	 * visible to the next deletion step.
  	 */
*** a/src/backend/commands/Makefile
--- b/src/backend/commands/Makefile
***************
*** 17,23 **** OBJS = aggregatecmds.o alter.o analyze.o async.o cluster.o comment.o  \
  	dbcommands.o define.o discard.o explain.o foreigncmds.o functioncmds.o \
  	indexcmds.o lockcmds.o operatorcmds.o opclasscmds.o \
  	portalcmds.o prepare.o proclang.o \
! 	schemacmds.o sequence.o tablecmds.o tablespace.o trigger.o \
  	tsearchcmds.o typecmds.o user.o vacuum.o vacuumlazy.o \
  	variable.o view.o
  
--- 17,23 ----
  	dbcommands.o define.o discard.o explain.o foreigncmds.o functioncmds.o \
  	indexcmds.o lockcmds.o operatorcmds.o opclasscmds.o \
  	portalcmds.o prepare.o proclang.o \
! 	schemacmds.o seclabel.o sequence.o tablecmds.o tablespace.o trigger.o \
  	tsearchcmds.o typecmds.o user.o vacuum.o vacuumlazy.o \
  	variable.o view.o
  
*** /dev/null
--- b/src/backend/commands/seclabel.c
***************
*** 0 ****
--- 1,259 ----
+ /* -------------------------------------------------------------------------
+  *
+  * seclabel.c
+  *    routines to support security label feature.
+  *
+  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  * -------------------------------------------------------------------------
+  */
+ #include "postgres.h"
+ 
+ #include "access/genam.h"
+ #include "access/heapam.h"
+ #include "catalog/catalog.h"
+ #include "catalog/indexing.h"
+ #include "catalog/pg_seclabel.h"
+ #include "commands/seclabel.h"
+ #include "utils/builtins.h"
+ #include "utils/fmgroids.h"
+ #include "utils/rel.h"
+ #include "utils/tqual.h"
+ 
+ /*
+  * GetLocalSecLabel
+  *
+  * It tries to look up a security label entry for the given OID of the
+  * relation, object itself and sub identifier (if needed) from the
+  * pg_seclabel system catalog.
+  * It returns NULL, if no valid entry. Elsewhere, it returns a security
+  * label of the specified object.
+  */
+ static char *
+ GetLocalSecLabel(Oid classOid, Oid objOid, int4 subId)
+ {
+ 	Relation	pg_seclabel;
+ 	ScanKeyData	keys[3];
+ 	SysScanDesc	scan;
+ 	HeapTuple	tuple;
+ 	Datum		datum;
+ 	bool		isnull;
+ 	char	   *seclabel = NULL;
+ 
+ 	ScanKeyInit(&keys[0],
+ 				Anum_pg_seclabel_reloid,
+ 				BTEqualStrategyNumber, F_OIDEQ,
+ 				ObjectIdGetDatum(classOid));
+ 	ScanKeyInit(&keys[1],
+ 				Anum_pg_seclabel_objoid,
+ 				BTEqualStrategyNumber, F_OIDEQ,
+ 				ObjectIdGetDatum(objOid));
+ 	ScanKeyInit(&keys[2],
+ 				Anum_pg_seclabel_subid,
+ 				BTEqualStrategyNumber, F_INT4EQ,
+ 				Int32GetDatum(subId));
+ 
+ 	pg_seclabel = heap_open(SecLabelRelationId, AccessShareLock);
+ 
+ 	scan = systable_beginscan(pg_seclabel, SecLabelObjectIndexId, true,
+ 							  SnapshotNow, 3, keys);
+ 
+ 	tuple = systable_getnext(scan);
+ 	if (HeapTupleIsValid(tuple))
+ 	{
+ 		datum = heap_getattr(tuple, Anum_pg_seclabel_label,
+ 							 RelationGetDescr(pg_seclabel), &isnull);
+ 		if (!isnull)
+ 			seclabel = TextDatumGetCString(datum);
+ 	}
+ 	systable_endscan(scan);
+ 
+ 	heap_close(pg_seclabel, AccessShareLock);
+ 
+ 	return seclabel;
+ }
+ 
+ /*
+  * SetLocalSecLabel
+  *
+  * It tries to insert/update/delete a security label for the given OID
+  * of the relation, object itself and sub identifier (if needed) on the
+  * pg_seclabel system catalog.
+  * If given 'new_label' is NULL, it tries to delete the specified entry.
+  * Elsewhere, it tries to insert (if no specified entry now) or update
+  * security label of the specified entry.
+  */
+ static void
+ SetLocalSecLabel(Oid classOid, Oid objOid, int4 subId, const char *seclabel)
+ {
+ 	Relation	pg_seclabel;
+ 	ScanKeyData	keys[3];
+ 	SysScanDesc	scan;
+ 	HeapTuple	oldtup;
+ 	HeapTuple	newtup = NULL;
+ 	Datum		values[Natts_pg_seclabel];
+ 	bool		nulls[Natts_pg_seclabel];
+ 	bool		replaces[Natts_pg_seclabel];
+ 
+ 	ScanKeyInit(&keys[0],
+ 				Anum_pg_seclabel_reloid,
+ 				BTEqualStrategyNumber, F_OIDEQ,
+                 ObjectIdGetDatum(classOid));
+ 	ScanKeyInit(&keys[1],
+ 				Anum_pg_seclabel_objoid,
+ 				BTEqualStrategyNumber, F_OIDEQ,
+ 				ObjectIdGetDatum(objOid));
+ 	ScanKeyInit(&keys[2],
+ 				Anum_pg_seclabel_subid,
+ 				BTEqualStrategyNumber, F_INT4EQ,
+ 				Int32GetDatum(subId));
+ 
+ 	pg_seclabel = heap_open(SecLabelRelationId, RowExclusiveLock);
+ 
+ 	scan = systable_beginscan(pg_seclabel, SecLabelObjectIndexId, true,
+ 							  SnapshotNow, 3, keys);
+ 
+ 	oldtup = systable_getnext(scan);
+ 	if (HeapTupleIsValid(oldtup))
+ 	{
+ 		if (seclabel != NULL)
+ 		{
+ 			/*
+ 			 * update the specified security label entry
+ 			 */
+ 			memset(nulls, false, sizeof(nulls));
+ 			memset(replaces, false, sizeof(replaces));
+ 
+ 			replaces[Anum_pg_seclabel_label - 1] = true;
+ 			values[Anum_pg_seclabel_label - 1]
+ 				= CStringGetTextDatum(seclabel);
+ 
+ 			newtup = heap_modify_tuple(oldtup, RelationGetDescr(pg_seclabel),
+ 									   values, nulls, replaces);
+ 			simple_heap_update(pg_seclabel, &oldtup->t_self, newtup);
+ 
+ 			CatalogUpdateIndexes(pg_seclabel, newtup);
+ 
+ 			heap_freetuple(newtup);
+ 		}
+ 		else
+ 		{
+ 			/*
+ 			 * when new_label = NULL, it means to remove the matched
+ 			 * entry from pg_seclabel.
+ 			 */
+ 			simple_heap_delete(pg_seclabel, &oldtup->t_self);
+ 		}
+ 	}
+ 	else if (seclabel != NULL)
+ 	{
+ 		/*
+ 		 * insert a new security label entry
+ 		 */
+ 		memset(nulls, false, sizeof(nulls));
+ 		values[Anum_pg_seclabel_reloid - 1] = ObjectIdGetDatum(classOid);
+ 		values[Anum_pg_seclabel_objoid - 1] = ObjectIdGetDatum(objOid);
+ 		values[Anum_pg_seclabel_subid - 1] = Int32GetDatum(subId);
+ 		values[Anum_pg_seclabel_label - 1] = CStringGetTextDatum(seclabel);
+ 
+ 		newtup = heap_form_tuple(RelationGetDescr(pg_seclabel),
+ 								 values, nulls);
+ 		simple_heap_insert(pg_seclabel, newtup);
+ 
+ 		CatalogUpdateIndexes(pg_seclabel, newtup);
+ 
+ 		heap_freetuple(newtup);
+ 	}
+ 	systable_endscan(scan);
+ 		
+ 	heap_close(pg_seclabel, RowExclusiveLock);
+ }
+ 
+ /*
+  * DeleteLocalSecLabel
+  *
+  * It tries to delete entries of security labels for the given OID
+  * of the relation, object itself and sub identifier (if needed) on
+  * the pg_seclabel system catalog.
+  * If given 'subId' is 0, all security labels matching the classOid
+  * and objOid will be removed.
+  */
+ static void
+ DeleteLocalSecLabel(Oid classOid, Oid objOid, int4 subId)
+ {
+ 	Relation	pg_seclabel;
+ 	ScanKeyData	keys[3];
+ 	SysScanDesc	scan;
+ 	HeapTuple	oldtup;
+ 	int			nkeys = 2;
+ 
+ 	ScanKeyInit(&keys[0],
+ 				Anum_pg_seclabel_reloid,
+ 				BTEqualStrategyNumber, F_OIDEQ,
+ 				ObjectIdGetDatum(classOid));
+ 	ScanKeyInit(&keys[1],
+ 				Anum_pg_seclabel_objoid,
+ 				BTEqualStrategyNumber, F_OIDEQ,
+ 				ObjectIdGetDatum(objOid));
+ 	if (subId != 0)
+ 	{
+ 		ScanKeyInit(&keys[2],
+ 					Anum_pg_seclabel_subid,
+ 					BTEqualStrategyNumber, F_INT4EQ,
+ 					Int32GetDatum(subId));
+ 		nkeys++;
+ 	}
+ 
+ 	pg_seclabel = heap_open(SecLabelRelationId, RowExclusiveLock);
+ 
+ 	scan = systable_beginscan(pg_seclabel, SecLabelObjectIndexId, true,
+ 							  SnapshotNow, nkeys, keys);
+ 	while (HeapTupleIsValid(oldtup = systable_getnext(scan)))
+ 	{
+ 		simple_heap_delete(pg_seclabel, &oldtup->t_self);
+ 	}
+ 	systable_endscan(scan);
+ 
+ 	heap_close(pg_seclabel, RowExclusiveLock);
+ }
+ 
+ /*
+  * GetSecurityLabel
+  *
+  * An internal API to get a security label of the specified object.
+  */
+ char *
+ GetSecurityLabel(Oid classOid, Oid objOid, int4 subId)
+ {
+ 	Assert(!IsSharedRelation(classOid));
+ 
+ 	return GetLocalSecLabel(classOid, objOid, subId);
+ }
+ 
+ /*
+  * SetSecurityLabel
+  *
+  * An internal API to set a security label of the specified object.
+  */
+ void
+ SetSecurityLabel(Oid classOid, Oid objOid, int4 subId,
+ 				 const char *seclabel)
+ {
+ 	Assert(!IsSharedRelation(classOid));
+ 
+ 	SetLocalSecLabel(classOid, objOid, subId, seclabel);
+ }
+ 
+ /*
+  * DeleteSecurityLabel
+  *
+  * An internal API to delete a security label of the specified object.
+  */
+ void
+ DeleteSecurityLabel(Oid classOid, Oid objOid, int4 subId)
+ {
+ 	Assert(!IsSharedRelation(classOid));
+ 
+ 	DeleteLocalSecLabel(classOid, objOid, subId);
+ }
*** a/src/include/catalog/indexing.h
--- b/src/include/catalog/indexing.h
***************
*** 281,286 **** DECLARE_UNIQUE_INDEX(pg_default_acl_oid_index, 828, on pg_default_acl using btre
--- 281,289 ----
  DECLARE_UNIQUE_INDEX(pg_db_role_setting_databaseid_rol_index, 2965, on pg_db_role_setting using btree(setdatabase oid_ops, setrole oid_ops));
  #define DbRoleSettingDatidRolidIndexId	2965
  
+ DECLARE_UNIQUE_INDEX(pg_seclabel_object_index, 3038, on pg_seclabel using btree(reloid oid_ops, objoid oid_ops, subid int4_ops));
+ #define SecLabelObjectIndexId				3038
+ 
  /* last step of initialization script: build the indexes declared above */
  BUILD_INDICES
  
*** /dev/null
--- b/src/include/catalog/pg_seclabel.h
***************
*** 0 ****
--- 1,41 ----
+ /* -------------------------------------------------------------------------
+  *
+  * pg_seclabel.h
+  *    definition of the system "security label" relation (pg_seclabel)
+  *
+  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  * -------------------------------------------------------------------------
+  */
+ #ifndef PG_SECLABEL_H
+ #define PG_SECLABEL_H
+ 
+ #include "catalog/genbki.h"
+ 
+ /* ----------------
+  *		pg_seclabel definition.  cpp turns this into
+  *		typedef struct FormData_pg_seclabel
+  * ----------------
+  */
+ #define SecLabelRelationId		3037
+ 
+ CATALOG(pg_seclabel,3037) BKI_WITHOUT_OIDS
+ {
+ 	Oid			reloid;		/* OID of table containing the object */
+ 	Oid			objoid;		/* OID of the object itself */
+ 	int4		subid;		/* column number, or 0 if not used */
+ 	text		label;		/* security label of the object */
+ } FormData_pg_seclabel;
+ 
+ /* ----------------
+  *		compiler constants for pg_seclabel
+  * ----------------
+  */
+ #define Natts_pg_seclabel			4
+ #define Anum_pg_seclabel_reloid		1
+ #define Anum_pg_seclabel_objoid		2
+ #define Anum_pg_seclabel_subid		3
+ #define Anum_pg_seclabel_label		4
+ 
+ #endif	/* PG_SECLABEL_H */
*** a/src/include/catalog/toasting.h
--- b/src/include/catalog/toasting.h
***************
*** 45,50 **** DECLARE_TOAST(pg_constraint, 2832, 2833);
--- 45,51 ----
  DECLARE_TOAST(pg_description, 2834, 2835);
  DECLARE_TOAST(pg_proc, 2836, 2837);
  DECLARE_TOAST(pg_rewrite, 2838, 2839);
+ DECLARE_TOAST(pg_seclabel, 3039, 3040);
  DECLARE_TOAST(pg_statistic, 2840, 2841);
  DECLARE_TOAST(pg_trigger, 2336, 2337);
  
*** /dev/null
--- b/src/include/commands/seclabel.h
***************
*** 0 ****
--- 1,21 ----
+ /*
+  * seclabel.h
+  *
+  * Prototypes for functions in commands/seclabel.c
+  *
+  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  */
+ #ifndef SECLABEL_H
+ #define SECLABEL_H
+ 
+ /*
+  * Internal APIs
+  */
+ extern char *GetSecurityLabel(Oid classOid, Oid objOid, int4 subId);
+ extern void  SetSecurityLabel(Oid classOid, Oid objOid, int4 subId,
+ 							  const char *seclabel);
+ extern void  DeleteSecurityLabel(Oid classOid, Oid objOid, int4 subId);
+ 
+ #endif	/* SECLABEL_H */
+ 
*** a/src/test/regress/expected/sanity_check.out
--- b/src/test/regress/expected/sanity_check.out
***************
*** 114,119 **** SELECT relname, relhasindex
--- 114,120 ----
   pg_pltemplate           | t
   pg_proc                 | t
   pg_rewrite              | t
+  pg_seclabel             | t
   pg_shdepend             | t
   pg_shdescription        | t
   pg_statistic            | t
***************
*** 153,159 **** SELECT relname, relhasindex
   timetz_tbl              | f
   tinterval_tbl           | f
   varchar_tbl             | f
! (142 rows)
  
  --
  -- another sanity check: every system catalog that has OIDs should have
--- 154,160 ----
   timetz_tbl              | f
   tinterval_tbl           | f
   varchar_tbl             | f
! (143 rows)
  
  --
  -- another sanity check: every system catalog that has OIDs should have