mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-23 19:39:53 +08:00
Support SECURITY LABEL on databases, tablespaces, and roles.
This requires a new shared catalog, pg_shseclabel. Along the way, fix the security_label regression tests so that they don't monkey with the labels of any pre-existing objects. This is unlikely to matter in practice, since only the label for the "dummy" provider was being manipulated. But this way still seems cleaner. KaiGai Kohei, with fairly extensive hacking by me.
This commit is contained in:
parent
cacd42d62c
commit
463f2625a5
@ -238,6 +238,11 @@
|
||||
<entry>comments on shared objects</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><link linkend="catalog-pg-shseclabel"><structname>pg_shseclabel</structname></link></entry>
|
||||
<entry>security labels on shared database objects</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><link linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link></entry>
|
||||
<entry>planner statistics</entry>
|
||||
@ -4681,6 +4686,12 @@
|
||||
way to view security labels, see <xref linkend="view-pg-seclabels">.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
See also <link linkend="catalog-pg-shseclabel"><structname>pg_shseclabel</structname></link>,
|
||||
which performs a similar function for security labels of database objects
|
||||
that are shared across a database cluster.
|
||||
</para>
|
||||
|
||||
<table>
|
||||
<title><structname>pg_seclabel</structname> Columns</title>
|
||||
|
||||
@ -4959,6 +4970,73 @@
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="catalog-pg-shseclabel">
|
||||
<title><structname>pg_shseclabel</structname></title>
|
||||
|
||||
<indexterm zone="catalog-pg-shseclabel">
|
||||
<primary>pg_shseclabel</primary>
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
The catalog <structname>pg_shseclabel</structname> stores security
|
||||
lables on shared database objects. Security labels can be manipulated
|
||||
with the <xref linkend="sql-security-label"> command. For an easier
|
||||
way to view security labels, see <xref linkend="view-pg-seclabels">.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
See also <link linkend="catalog-pg-seclabel"><structname>pg_seclabel</structname></link>,
|
||||
which performs a similar function for security labels involving objects
|
||||
within a single database.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Unlike most system catalogs, <structname>pg_shseclabel</structname>
|
||||
is shared across all databases of a cluster: there is only one
|
||||
copy of <structname>pg_shseclabel</structname> per cluster, not
|
||||
one per database.
|
||||
</para>
|
||||
|
||||
<table>
|
||||
<title><structname>pg_shseclabel</structname> Columns</title>
|
||||
<tgroup cols="4">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Name</entry>
|
||||
<entry>Type</entry>
|
||||
<entry>References</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><structfield>objoid</structfield></entry>
|
||||
<entry><type>oid</type></entry>
|
||||
<entry>any OID column</entry>
|
||||
<entry>The OID of the object this security label pertains to</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><structfield>classoid</structfield></entry>
|
||||
<entry><type>oid</type></entry>
|
||||
<entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry>
|
||||
<entry>The OID of the system catalog this object appears in</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><structfield>provider</structfield></entry>
|
||||
<entry><type>name</type></entry>
|
||||
<entry></entry>
|
||||
<entry>The label provider associated with this label.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><structfield>label</structfield></entry>
|
||||
<entry><type>text</type></entry>
|
||||
<entry></entry>
|
||||
<entry>The security label applied to this object.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="catalog-pg-statistic">
|
||||
<title><structname>pg_statistic</structname></title>
|
||||
|
@ -26,13 +26,16 @@ SECURITY LABEL [ FOR <replaceable class="PARAMETER">provider</replaceable> ] ON
|
||||
TABLE <replaceable class="PARAMETER">object_name</replaceable> |
|
||||
COLUMN <replaceable class="PARAMETER">table_name</replaceable>.<replaceable class="PARAMETER">column_name</replaceable> |
|
||||
AGGREGATE <replaceable class="PARAMETER">agg_name</replaceable> (<replaceable class="PARAMETER">agg_type</replaceable> [, ...] ) |
|
||||
DATABASE <replaceable class="PARAMETER">object_name</replaceable> |
|
||||
DOMAIN <replaceable class="PARAMETER">object_name</replaceable> |
|
||||
FOREIGN TABLE <replaceable class="PARAMETER">object_name</replaceable>
|
||||
FUNCTION <replaceable class="PARAMETER">function_name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) |
|
||||
LARGE OBJECT <replaceable class="PARAMETER">large_object_oid</replaceable> |
|
||||
[ PROCEDURAL ] LANGUAGE <replaceable class="PARAMETER">object_name</replaceable> |
|
||||
ROLE <replaceable class="PARAMETER">object_name</replaceable> |
|
||||
SCHEMA <replaceable class="PARAMETER">object_name</replaceable> |
|
||||
SEQUENCE <replaceable class="PARAMETER">object_name</replaceable> |
|
||||
TABLESPACE <replaceable class="PARAMETER">object_name</replaceable> |
|
||||
TYPE <replaceable class="PARAMETER">object_name</replaceable> |
|
||||
VIEW <replaceable class="PARAMETER">object_name</replaceable>
|
||||
} IS '<replaceable class="PARAMETER">label</replaceable>'
|
||||
|
@ -39,7 +39,7 @@ POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
|
||||
pg_ts_parser.h pg_ts_template.h pg_extension.h \
|
||||
pg_foreign_data_wrapper.h pg_foreign_server.h pg_user_mapping.h \
|
||||
pg_foreign_table.h \
|
||||
pg_default_acl.h pg_seclabel.h pg_collation.h \
|
||||
pg_default_acl.h pg_seclabel.h pg_shseclabel.h pg_collation.h \
|
||||
toasting.h indexing.h \
|
||||
)
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "catalog/pg_db_role_setting.h"
|
||||
#include "catalog/pg_shdepend.h"
|
||||
#include "catalog/pg_shdescription.h"
|
||||
#include "catalog/pg_shseclabel.h"
|
||||
#include "catalog/pg_tablespace.h"
|
||||
#include "catalog/toasting.h"
|
||||
#include "miscadmin.h"
|
||||
@ -380,6 +381,7 @@ IsSharedRelation(Oid relationId)
|
||||
relationId == PLTemplateRelationId ||
|
||||
relationId == SharedDescriptionRelationId ||
|
||||
relationId == SharedDependRelationId ||
|
||||
relationId == SharedSecLabelRelationId ||
|
||||
relationId == TableSpaceRelationId ||
|
||||
relationId == DbRoleSettingRelationId)
|
||||
return true;
|
||||
@ -394,6 +396,7 @@ IsSharedRelation(Oid relationId)
|
||||
relationId == SharedDescriptionObjIndexId ||
|
||||
relationId == SharedDependDependerIndexId ||
|
||||
relationId == SharedDependReferenceIndexId ||
|
||||
relationId == SharedSecLabelObjectIndexId ||
|
||||
relationId == TablespaceOidIndexId ||
|
||||
relationId == TablespaceNameIndexId ||
|
||||
relationId == DbRoleSettingDatidRolidIndexId)
|
||||
|
@ -283,7 +283,37 @@ FROM
|
||||
pg_seclabel l
|
||||
JOIN pg_namespace nsp ON l.classoid = nsp.tableoid AND l.objoid = nsp.oid
|
||||
WHERE
|
||||
l.objsubid = 0;
|
||||
l.objsubid = 0
|
||||
UNION ALL
|
||||
SELECT
|
||||
l.objoid, l.classoid, 0::int4 AS objsubid,
|
||||
'database'::text AS objtype,
|
||||
NULL::oid AS objnamespace,
|
||||
quote_ident(dat.datname) AS objname,
|
||||
l.provider, l.label
|
||||
FROM
|
||||
pg_shseclabel l
|
||||
JOIN pg_database dat ON l.classoid = dat.tableoid AND l.objoid = dat.oid
|
||||
UNION ALL
|
||||
SELECT
|
||||
l.objoid, l.classoid, 0::int4 AS objsubid,
|
||||
'tablespace'::text AS objtype,
|
||||
NULL::oid AS objnamespace,
|
||||
quote_ident(spc.spcname) AS objname,
|
||||
l.provider, l.label
|
||||
FROM
|
||||
pg_shseclabel l
|
||||
JOIN pg_tablespace spc ON l.classoid = spc.tableoid AND l.objoid = spc.oid
|
||||
UNION ALL
|
||||
SELECT
|
||||
l.objoid, l.classoid, 0::int4 AS objsubid,
|
||||
'role'::text AS objtype,
|
||||
NULL::oid AS objnamespace,
|
||||
quote_ident(rol.rolname) AS objname,
|
||||
l.provider, l.label
|
||||
FROM
|
||||
pg_shseclabel l
|
||||
JOIN pg_authid rol ON l.classoid = rol.tableoid AND l.objoid = rol.oid;
|
||||
|
||||
CREATE VIEW pg_settings AS
|
||||
SELECT * FROM pg_show_all_settings() AS A;
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "catalog/pg_tablespace.h"
|
||||
#include "commands/comment.h"
|
||||
#include "commands/dbcommands.h"
|
||||
#include "commands/seclabel.h"
|
||||
#include "commands/tablespace.h"
|
||||
#include "mb/pg_wchar.h"
|
||||
#include "miscadmin.h"
|
||||
@ -822,9 +823,11 @@ dropdb(const char *dbname, bool missing_ok)
|
||||
ReleaseSysCache(tup);
|
||||
|
||||
/*
|
||||
* Delete any comments associated with the database.
|
||||
* Delete any comments or security labels associated with
|
||||
* the database.
|
||||
*/
|
||||
DeleteSharedComments(db_id, DatabaseRelationId);
|
||||
DeleteSharedSecurityLabel(db_id, DatabaseRelationId);
|
||||
|
||||
/*
|
||||
* Remove settings associated with this database
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_seclabel.h"
|
||||
#include "catalog/pg_shseclabel.h"
|
||||
#include "commands/seclabel.h"
|
||||
#include "miscadmin.h"
|
||||
#include "utils/acl.h"
|
||||
@ -24,6 +25,7 @@
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/rel.h"
|
||||
#include "utils/syscache.h"
|
||||
#include "utils/tqual.h"
|
||||
|
||||
typedef struct
|
||||
@ -135,8 +137,56 @@ ExecSecLabelStmt(SecLabelStmt *stmt)
|
||||
}
|
||||
|
||||
/*
|
||||
* GetSecurityLabel returns the security label for a database object for a
|
||||
* given provider, or NULL if there is no such label.
|
||||
* GetSharedSecurityLabel returns the security label for a shared object for
|
||||
* a given provider, or NULL if there is no such label.
|
||||
*/
|
||||
static char *
|
||||
GetSharedSecurityLabel(const ObjectAddress *object, const char *provider)
|
||||
{
|
||||
Relation pg_shseclabel;
|
||||
ScanKeyData keys[3];
|
||||
SysScanDesc scan;
|
||||
HeapTuple tuple;
|
||||
Datum datum;
|
||||
bool isnull;
|
||||
char *seclabel = NULL;
|
||||
|
||||
ScanKeyInit(&keys[0],
|
||||
Anum_pg_shseclabel_objoid,
|
||||
BTEqualStrategyNumber, F_OIDEQ,
|
||||
ObjectIdGetDatum(object->objectId));
|
||||
ScanKeyInit(&keys[1],
|
||||
Anum_pg_shseclabel_classoid,
|
||||
BTEqualStrategyNumber, F_OIDEQ,
|
||||
ObjectIdGetDatum(object->classId));
|
||||
ScanKeyInit(&keys[2],
|
||||
Anum_pg_shseclabel_provider,
|
||||
BTEqualStrategyNumber, F_TEXTEQ,
|
||||
CStringGetTextDatum(provider));
|
||||
|
||||
pg_shseclabel = heap_open(SharedSecLabelRelationId, AccessShareLock);
|
||||
|
||||
scan = systable_beginscan(pg_shseclabel, SharedSecLabelObjectIndexId, true,
|
||||
SnapshotNow, 3, keys);
|
||||
|
||||
tuple = systable_getnext(scan);
|
||||
if (HeapTupleIsValid(tuple))
|
||||
{
|
||||
datum = heap_getattr(tuple, Anum_pg_shseclabel_label,
|
||||
RelationGetDescr(pg_shseclabel), &isnull);
|
||||
if (!isnull)
|
||||
seclabel = TextDatumGetCString(datum);
|
||||
}
|
||||
systable_endscan(scan);
|
||||
|
||||
heap_close(pg_shseclabel, AccessShareLock);
|
||||
|
||||
return seclabel;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetSecurityLabel returns the security label for a shared or database object
|
||||
* for a given provider, or NULL if there is no such label.
|
||||
*/
|
||||
char *
|
||||
GetSecurityLabel(const ObjectAddress *object, const char *provider)
|
||||
@ -149,8 +199,11 @@ GetSecurityLabel(const ObjectAddress *object, const char *provider)
|
||||
bool isnull;
|
||||
char *seclabel = NULL;
|
||||
|
||||
Assert(!IsSharedRelation(object->classId));
|
||||
/* Shared objects have their own security label catalog. */
|
||||
if (IsSharedRelation(object->classId))
|
||||
return GetSharedSecurityLabel(object, provider);
|
||||
|
||||
/* Must be an unshared object, so examine pg_seclabel. */
|
||||
ScanKeyInit(&keys[0],
|
||||
Anum_pg_seclabel_objoid,
|
||||
BTEqualStrategyNumber, F_OIDEQ,
|
||||
@ -188,6 +241,84 @@ GetSecurityLabel(const ObjectAddress *object, const char *provider)
|
||||
return seclabel;
|
||||
}
|
||||
|
||||
/*
|
||||
* SetSharedSecurityLabel is a helper function of SetSecurityLabel to
|
||||
* handle shared database objects.
|
||||
*/
|
||||
static void
|
||||
SetSharedSecurityLabel(const ObjectAddress *object,
|
||||
const char *provider, const char *label)
|
||||
{
|
||||
Relation pg_shseclabel;
|
||||
ScanKeyData keys[4];
|
||||
SysScanDesc scan;
|
||||
HeapTuple oldtup;
|
||||
HeapTuple newtup = NULL;
|
||||
Datum values[Natts_pg_shseclabel];
|
||||
bool nulls[Natts_pg_shseclabel];
|
||||
bool replaces[Natts_pg_shseclabel];
|
||||
|
||||
/* Prepare to form or update a tuple, if necessary. */
|
||||
memset(nulls, false, sizeof(nulls));
|
||||
memset(replaces, false, sizeof(replaces));
|
||||
values[Anum_pg_shseclabel_objoid - 1] = ObjectIdGetDatum(object->objectId);
|
||||
values[Anum_pg_shseclabel_classoid - 1] = ObjectIdGetDatum(object->classId);
|
||||
values[Anum_pg_shseclabel_provider - 1] = CStringGetTextDatum(provider);
|
||||
if (label != NULL)
|
||||
values[Anum_pg_shseclabel_label - 1] = CStringGetTextDatum(label);
|
||||
|
||||
/* Use the index to search for a matching old tuple */
|
||||
ScanKeyInit(&keys[0],
|
||||
Anum_pg_shseclabel_objoid,
|
||||
BTEqualStrategyNumber, F_OIDEQ,
|
||||
ObjectIdGetDatum(object->objectId));
|
||||
ScanKeyInit(&keys[1],
|
||||
Anum_pg_shseclabel_classoid,
|
||||
BTEqualStrategyNumber, F_OIDEQ,
|
||||
ObjectIdGetDatum(object->classId));
|
||||
ScanKeyInit(&keys[2],
|
||||
Anum_pg_shseclabel_provider,
|
||||
BTEqualStrategyNumber, F_TEXTEQ,
|
||||
CStringGetTextDatum(provider));
|
||||
|
||||
pg_shseclabel = heap_open(SharedSecLabelRelationId, RowExclusiveLock);
|
||||
|
||||
scan = systable_beginscan(pg_shseclabel, SharedSecLabelObjectIndexId, true,
|
||||
SnapshotNow, 3, keys);
|
||||
|
||||
oldtup = systable_getnext(scan);
|
||||
if (HeapTupleIsValid(oldtup))
|
||||
{
|
||||
if (label == NULL)
|
||||
simple_heap_delete(pg_shseclabel, &oldtup->t_self);
|
||||
else
|
||||
{
|
||||
replaces[Anum_pg_shseclabel_label - 1] = true;
|
||||
newtup = heap_modify_tuple(oldtup, RelationGetDescr(pg_shseclabel),
|
||||
values, nulls, replaces);
|
||||
simple_heap_update(pg_shseclabel, &oldtup->t_self, newtup);
|
||||
}
|
||||
}
|
||||
systable_endscan(scan);
|
||||
|
||||
/* If we didn't find an old tuple, insert a new one */
|
||||
if (newtup == NULL && label != NULL)
|
||||
{
|
||||
newtup = heap_form_tuple(RelationGetDescr(pg_shseclabel),
|
||||
values, nulls);
|
||||
simple_heap_insert(pg_shseclabel, newtup);
|
||||
}
|
||||
|
||||
/* Update indexes, if necessary */
|
||||
if (newtup != NULL)
|
||||
{
|
||||
CatalogUpdateIndexes(pg_shseclabel, newtup);
|
||||
heap_freetuple(newtup);
|
||||
}
|
||||
|
||||
heap_close(pg_shseclabel, RowExclusiveLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* SetSecurityLabel attempts to set the security label for the specified
|
||||
* provider on the specified object to the given value. NULL means that any
|
||||
@ -206,8 +337,12 @@ SetSecurityLabel(const ObjectAddress *object,
|
||||
bool nulls[Natts_pg_seclabel];
|
||||
bool replaces[Natts_pg_seclabel];
|
||||
|
||||
/* Security labels on shared objects are not supported. */
|
||||
Assert(!IsSharedRelation(object->classId));
|
||||
/* Shared objects have their own security label catalog. */
|
||||
if (IsSharedRelation(object->classId))
|
||||
{
|
||||
SetSharedSecurityLabel(object, provider, label);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Prepare to form or update a tuple, if necessary. */
|
||||
memset(nulls, false, sizeof(nulls));
|
||||
@ -275,6 +410,38 @@ SetSecurityLabel(const ObjectAddress *object,
|
||||
heap_close(pg_seclabel, RowExclusiveLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* DeleteSharedSecurityLabel is a helper function of DeleteSecurityLabel
|
||||
* to handle shared database objects.
|
||||
*/
|
||||
void
|
||||
DeleteSharedSecurityLabel(Oid objectId, Oid classId)
|
||||
{
|
||||
Relation pg_shseclabel;
|
||||
ScanKeyData skey[2];
|
||||
SysScanDesc scan;
|
||||
HeapTuple oldtup;
|
||||
|
||||
ScanKeyInit(&skey[0],
|
||||
Anum_pg_shseclabel_objoid,
|
||||
BTEqualStrategyNumber, F_OIDEQ,
|
||||
ObjectIdGetDatum(objectId));
|
||||
ScanKeyInit(&skey[1],
|
||||
Anum_pg_shseclabel_classoid,
|
||||
BTEqualStrategyNumber, F_OIDEQ,
|
||||
ObjectIdGetDatum(classId));
|
||||
|
||||
pg_shseclabel = heap_open(SharedSecLabelRelationId, RowExclusiveLock);
|
||||
|
||||
scan = systable_beginscan(pg_shseclabel, SharedSecLabelObjectIndexId, true,
|
||||
SnapshotNow, 2, skey);
|
||||
while (HeapTupleIsValid(oldtup = systable_getnext(scan)))
|
||||
simple_heap_delete(pg_shseclabel, &oldtup->t_self);
|
||||
systable_endscan(scan);
|
||||
|
||||
heap_close(pg_shseclabel, RowExclusiveLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* DeleteSecurityLabel removes all security labels for an object (and any
|
||||
* sub-objects, if applicable).
|
||||
@ -288,9 +455,13 @@ DeleteSecurityLabel(const ObjectAddress *object)
|
||||
HeapTuple oldtup;
|
||||
int nkeys;
|
||||
|
||||
/* Security labels on shared objects are not supported. */
|
||||
/* Shared objects have their own security label catalog. */
|
||||
if (IsSharedRelation(object->classId))
|
||||
{
|
||||
Assert(object->objectSubId == 0);
|
||||
DeleteSharedSecurityLabel(object->objectId, object->classId);
|
||||
return;
|
||||
}
|
||||
|
||||
ScanKeyInit(&skey[0],
|
||||
Anum_pg_seclabel_objoid,
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include "catalog/pg_tablespace.h"
|
||||
#include "commands/comment.h"
|
||||
#include "commands/defrem.h"
|
||||
#include "commands/seclabel.h"
|
||||
#include "commands/tablespace.h"
|
||||
#include "miscadmin.h"
|
||||
#include "postmaster/bgwriter.h"
|
||||
@ -448,9 +449,10 @@ DropTableSpace(DropTableSpaceStmt *stmt)
|
||||
heap_endscan(scandesc);
|
||||
|
||||
/*
|
||||
* Remove any comments on this tablespace.
|
||||
* Remove any comments or security labels on this tablespace.
|
||||
*/
|
||||
DeleteSharedComments(tablespaceoid, TableSpaceRelationId);
|
||||
DeleteSharedSecurityLabel(tablespaceoid, TableSpaceRelationId);
|
||||
|
||||
/*
|
||||
* Remove dependency on owner.
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "catalog/pg_db_role_setting.h"
|
||||
#include "commands/comment.h"
|
||||
#include "commands/dbcommands.h"
|
||||
#include "commands/seclabel.h"
|
||||
#include "commands/user.h"
|
||||
#include "libpq/md5.h"
|
||||
#include "miscadmin.h"
|
||||
@ -1000,9 +1001,10 @@ DropRole(DropRoleStmt *stmt)
|
||||
systable_endscan(sscan);
|
||||
|
||||
/*
|
||||
* Remove any comments on this role.
|
||||
* Remove any comments or security labels on this role.
|
||||
*/
|
||||
DeleteSharedComments(roleid, AuthIdRelationId);
|
||||
DeleteSharedSecurityLabel(roleid, AuthIdRelationId);
|
||||
|
||||
/*
|
||||
* Remove settings for this role.
|
||||
|
@ -5068,11 +5068,14 @@ opt_provider: FOR ColId_or_Sconst { $$ = $2; }
|
||||
|
||||
security_label_type:
|
||||
COLUMN { $$ = OBJECT_COLUMN; }
|
||||
| DATABASE { $$ = OBJECT_DATABASE; }
|
||||
| FOREIGN TABLE { $$ = OBJECT_FOREIGN_TABLE; }
|
||||
| SCHEMA { $$ = OBJECT_SCHEMA; }
|
||||
| SEQUENCE { $$ = OBJECT_SEQUENCE; }
|
||||
| TABLE { $$ = OBJECT_TABLE; }
|
||||
| DOMAIN_P { $$ = OBJECT_TYPE; }
|
||||
| ROLE { $$ = OBJECT_ROLE; }
|
||||
| TABLESPACE { $$ = OBJECT_TABLESPACE; }
|
||||
| TYPE_P { $$ = OBJECT_TYPE; }
|
||||
| VIEW { $$ = OBJECT_VIEW; }
|
||||
;
|
||||
|
@ -1166,3 +1166,47 @@ processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern,
|
||||
return added_clause;
|
||||
#undef WHEREAND
|
||||
}
|
||||
|
||||
/*
|
||||
* buildShSecLabelQuery
|
||||
*
|
||||
* Build a query to retrieve security labels for a shared object.
|
||||
*/
|
||||
void
|
||||
buildShSecLabelQuery(PGconn *conn, const char *catalog_name, uint32 objectId,
|
||||
PQExpBuffer sql)
|
||||
{
|
||||
appendPQExpBuffer(sql,
|
||||
"SELECT provider, label FROM pg_catalog.pg_shseclabel "
|
||||
"WHERE classoid = '%s'::pg_catalog.regclass AND "
|
||||
"objoid = %u", catalog_name, objectId);
|
||||
}
|
||||
|
||||
/*
|
||||
* emitShSecLabels
|
||||
*
|
||||
* Format security label data retrieved by the query generated in
|
||||
* buildShSecLabelQuery.
|
||||
*/
|
||||
void
|
||||
emitShSecLabels(PGconn *conn, PGresult *res, PQExpBuffer buffer,
|
||||
const char *target, const char *objname)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PQntuples(res); i++)
|
||||
{
|
||||
char *provider = PQgetvalue(res, i, 0);
|
||||
char *label = PQgetvalue(res, i, 1);
|
||||
|
||||
/* must use fmtId result before calling it again */
|
||||
appendPQExpBuffer(buffer,
|
||||
"SECURITY LABEL FOR %s ON %s",
|
||||
fmtId(provider), target);
|
||||
appendPQExpBuffer(buffer,
|
||||
" %s IS ",
|
||||
fmtId(objname));
|
||||
appendStringLiteralConn(buffer, label, conn);
|
||||
appendPQExpBuffer(buffer, ";\n");
|
||||
}
|
||||
}
|
||||
|
@ -47,5 +47,9 @@ extern bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf,
|
||||
bool have_where, bool force_escape,
|
||||
const char *schemavar, const char *namevar,
|
||||
const char *altnamevar, const char *visibilityrule);
|
||||
extern void buildShSecLabelQuery(PGconn *conn, const char *catalog_name,
|
||||
uint32 objectId, PQExpBuffer sql);
|
||||
extern void emitShSecLabels(PGconn *conn, PGresult *res,
|
||||
PQExpBuffer buffer, const char *target, const char *objname);
|
||||
|
||||
#endif /* DUMPUTILS_H */
|
||||
|
@ -2048,6 +2048,24 @@ dumpDatabase(Archive *AH)
|
||||
|
||||
PQclear(res);
|
||||
|
||||
/* Dump shared security label. */
|
||||
if (!no_security_labels && g_fout->remoteVersion >= 90200)
|
||||
{
|
||||
PQExpBuffer seclabelQry = createPQExpBuffer();
|
||||
|
||||
buildShSecLabelQuery(g_conn, "pg_database", dbCatId.oid, seclabelQry);
|
||||
res = PQexec(g_conn, seclabelQry->data);
|
||||
check_sql_result(res, g_conn, seclabelQry->data, PGRES_TUPLES_OK);
|
||||
resetPQExpBuffer(seclabelQry);
|
||||
emitShSecLabels(g_conn, res, seclabelQry, "DATABASE", datname);
|
||||
if (strlen(seclabelQry->data))
|
||||
ArchiveEntry(AH, dbCatId, createDumpId(), datname, NULL, NULL,
|
||||
dba, false, "SECURITY LABEL", SECTION_NONE,
|
||||
seclabelQry->data, "", NULL,
|
||||
&dbDumpId, 1, NULL, NULL);
|
||||
destroyPQExpBuffer(seclabelQry);
|
||||
}
|
||||
|
||||
destroyPQExpBuffer(dbQry);
|
||||
destroyPQExpBuffer(delQry);
|
||||
destroyPQExpBuffer(creaQry);
|
||||
|
@ -52,6 +52,9 @@ static void dumpTimestamp(char *msg);
|
||||
static void doShellQuoting(PQExpBuffer buf, const char *str);
|
||||
|
||||
static int runPgDump(const char *dbname);
|
||||
static void buildShSecLabels(PGconn *conn, const char *catalog_name,
|
||||
uint32 objectId, PQExpBuffer buffer,
|
||||
const char *target, const char *objname);
|
||||
static PGconn *connectDatabase(const char *dbname, const char *pghost, const char *pgport,
|
||||
const char *pguser, enum trivalue prompt_password, bool fail_on_error);
|
||||
static PGresult *executeQuery(PGconn *conn, const char *query);
|
||||
@ -718,15 +721,15 @@ dumpRoles(PGconn *conn)
|
||||
for (i = 0; i < PQntuples(res); i++)
|
||||
{
|
||||
const char *rolename;
|
||||
Oid auth_oid;
|
||||
|
||||
auth_oid = atooid(PQgetvalue(res, i, i_oid));
|
||||
rolename = PQgetvalue(res, i, i_rolname);
|
||||
|
||||
resetPQExpBuffer(buf);
|
||||
|
||||
if (binary_upgrade)
|
||||
{
|
||||
Oid auth_oid = atooid(PQgetvalue(res, i, i_oid));
|
||||
|
||||
appendPQExpBuffer(buf, "\n-- For binary upgrade, must preserve pg_authid.oid\n");
|
||||
appendPQExpBuffer(buf,
|
||||
"SELECT binary_upgrade.set_next_pg_authid_oid('%u'::pg_catalog.oid);\n\n",
|
||||
@ -796,6 +799,10 @@ dumpRoles(PGconn *conn)
|
||||
appendPQExpBuffer(buf, ";\n");
|
||||
}
|
||||
|
||||
if (!no_security_labels && server_version >= 90200)
|
||||
buildShSecLabels(conn, "pg_authid", auth_oid,
|
||||
buf, "ROLE", rolename);
|
||||
|
||||
fprintf(OPF, "%s", buf->data);
|
||||
|
||||
if (server_version >= 70300)
|
||||
@ -981,7 +988,7 @@ dumpTablespaces(PGconn *conn)
|
||||
* pg_xxx)
|
||||
*/
|
||||
if (server_version >= 90000)
|
||||
res = executeQuery(conn, "SELECT spcname, "
|
||||
res = executeQuery(conn, "SELECT oid, spcname, "
|
||||
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
|
||||
"spclocation, spcacl, "
|
||||
"array_to_string(spcoptions, ', '),"
|
||||
@ -990,7 +997,7 @@ dumpTablespaces(PGconn *conn)
|
||||
"WHERE spcname !~ '^pg_' "
|
||||
"ORDER BY 1");
|
||||
else if (server_version >= 80200)
|
||||
res = executeQuery(conn, "SELECT spcname, "
|
||||
res = executeQuery(conn, "SELECT oid, spcname, "
|
||||
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
|
||||
"spclocation, spcacl, null, "
|
||||
"pg_catalog.shobj_description(oid, 'pg_tablespace') "
|
||||
@ -998,7 +1005,7 @@ dumpTablespaces(PGconn *conn)
|
||||
"WHERE spcname !~ '^pg_' "
|
||||
"ORDER BY 1");
|
||||
else
|
||||
res = executeQuery(conn, "SELECT spcname, "
|
||||
res = executeQuery(conn, "SELECT oid, spcname, "
|
||||
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
|
||||
"spclocation, spcacl, "
|
||||
"null, null "
|
||||
@ -1012,12 +1019,13 @@ dumpTablespaces(PGconn *conn)
|
||||
for (i = 0; i < PQntuples(res); i++)
|
||||
{
|
||||
PQExpBuffer buf = createPQExpBuffer();
|
||||
char *spcname = PQgetvalue(res, i, 0);
|
||||
char *spcowner = PQgetvalue(res, i, 1);
|
||||
char *spclocation = PQgetvalue(res, i, 2);
|
||||
char *spcacl = PQgetvalue(res, i, 3);
|
||||
char *spcoptions = PQgetvalue(res, i, 4);
|
||||
char *spccomment = PQgetvalue(res, i, 5);
|
||||
uint32 spcoid = atooid(PQgetvalue(res, i, 0));
|
||||
char *spcname = PQgetvalue(res, i, 1);
|
||||
char *spcowner = PQgetvalue(res, i, 2);
|
||||
char *spclocation = PQgetvalue(res, i, 3);
|
||||
char *spcacl = PQgetvalue(res, i, 4);
|
||||
char *spcoptions = PQgetvalue(res, i, 5);
|
||||
char *spccomment = PQgetvalue(res, i, 6);
|
||||
char *fspcname;
|
||||
|
||||
/* needed for buildACLCommands() */
|
||||
@ -1051,6 +1059,10 @@ dumpTablespaces(PGconn *conn)
|
||||
appendPQExpBuffer(buf, ";\n");
|
||||
}
|
||||
|
||||
if (!no_security_labels && server_version >= 90200)
|
||||
buildShSecLabels(conn, "pg_tablespace", spcoid,
|
||||
buf, "TABLESPACE", fspcname);
|
||||
|
||||
fprintf(OPF, "%s", buf->data);
|
||||
|
||||
free(fspcname);
|
||||
@ -1615,6 +1627,28 @@ runPgDump(const char *dbname)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* buildShSecLabels
|
||||
*
|
||||
* Build SECURITY LABEL command(s) for an shared object
|
||||
*
|
||||
* The caller has to provide object type and identifier to select security
|
||||
* labels from pg_seclabels system view.
|
||||
*/
|
||||
static void
|
||||
buildShSecLabels(PGconn *conn, const char *catalog_name, uint32 objectId,
|
||||
PQExpBuffer buffer, const char *target, const char *objname)
|
||||
{
|
||||
PQExpBuffer sql = createPQExpBuffer();
|
||||
PGresult *res;
|
||||
|
||||
buildShSecLabelQuery(conn, catalog_name, objectId, sql);
|
||||
res = executeQuery(conn, sql->data);
|
||||
emitShSecLabels(conn, res, buffer, target, objname);
|
||||
|
||||
PQclear(res);
|
||||
destroyPQExpBuffer(sql);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a database connection with the given parameters. An
|
||||
|
@ -53,6 +53,6 @@
|
||||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 201107171
|
||||
#define CATALOG_VERSION_NO 201107201
|
||||
|
||||
#endif
|
||||
|
@ -294,6 +294,9 @@ DECLARE_UNIQUE_INDEX(pg_db_role_setting_databaseid_rol_index, 2965, on pg_db_rol
|
||||
DECLARE_UNIQUE_INDEX(pg_seclabel_object_index, 3597, on pg_seclabel using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops, provider text_ops));
|
||||
#define SecLabelObjectIndexId 3597
|
||||
|
||||
DECLARE_UNIQUE_INDEX(pg_shseclabel_object_index, 3593, on pg_shseclabel using btree(objoid oid_ops, classoid oid_ops, provider text_ops));
|
||||
#define SharedSecLabelObjectIndexId 3593
|
||||
|
||||
DECLARE_UNIQUE_INDEX(pg_extension_oid_index, 3080, on pg_extension using btree(oid oid_ops));
|
||||
#define ExtensionOidIndexId 3080
|
||||
|
||||
|
41
src/include/catalog/pg_shseclabel.h
Normal file
41
src/include/catalog/pg_shseclabel.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* -------------------------------------------------------------------------
|
||||
*
|
||||
* pg_shseclabel.h
|
||||
* definition of the system "security label" relation (pg_shseclabel)
|
||||
*
|
||||
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef PG_SHSECLABEL_H
|
||||
#define PG_SHSECLABEL_H
|
||||
|
||||
#include "catalog/genbki.h"
|
||||
|
||||
/* ----------------
|
||||
* pg_shseclabel definition. cpp turns this into
|
||||
* typedef struct FormData_pg_shseclabel
|
||||
* ----------------
|
||||
*/
|
||||
#define SharedSecLabelRelationId 3592
|
||||
|
||||
CATALOG(pg_shseclabel,3592) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
|
||||
{
|
||||
Oid objoid; /* OID of the shared object itself */
|
||||
Oid classoid; /* OID of table containing the shared object */
|
||||
text provider; /* name of label provider */
|
||||
text label; /* security label of the object */
|
||||
} FormData_pg_shseclabel;
|
||||
|
||||
/* ----------------
|
||||
* compiler constants for pg_shseclabel
|
||||
* ----------------
|
||||
*/
|
||||
#define Natts_pg_shseclabel 4
|
||||
#define Anum_pg_shseclabel_objoid 1
|
||||
#define Anum_pg_shseclabel_classoid 2
|
||||
#define Anum_pg_shseclabel_provider 3
|
||||
#define Anum_pg_shseclabel_label 4
|
||||
|
||||
#endif /* PG_SHSECLABEL_H */
|
@ -21,6 +21,7 @@ extern char *GetSecurityLabel(const ObjectAddress *object,
|
||||
extern void SetSecurityLabel(const ObjectAddress *object,
|
||||
const char *provider, const char *label);
|
||||
extern void DeleteSecurityLabel(const ObjectAddress *object);
|
||||
extern void DeleteSharedSecurityLabel(Oid objectId, Oid classId);
|
||||
|
||||
/*
|
||||
* Statement and ESP hook support
|
||||
|
@ -1276,8 +1276,8 @@ drop table cchild;
|
||||
-- Check that ruleutils are working
|
||||
--
|
||||
SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schema' ORDER BY viewname;
|
||||
viewname | definition
|
||||
---------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
viewname | definition
|
||||
---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
iexit | SELECT ih.name, ih.thepath, interpt_pp(ih.thepath, r.thepath) AS exit FROM ihighway ih, ramp r WHERE (ih.thepath ## r.thepath);
|
||||
pg_available_extension_versions | SELECT e.name, e.version, (x.extname IS NOT NULL) AS installed, e.superuser, e.relocatable, e.schema, e.requires, e.comment FROM (pg_available_extension_versions() e(name, version, superuser, relocatable, schema, requires, comment) LEFT JOIN pg_extension x ON (((e.name = x.extname) AND (e.version = x.extversion))));
|
||||
pg_available_extensions | SELECT e.name, e.default_version, x.extversion AS installed_version, e.comment FROM (pg_available_extensions() e(name, default_version, comment) LEFT JOIN pg_extension x ON ((e.name = x.extname)));
|
||||
@ -1289,7 +1289,7 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
|
||||
pg_prepared_xacts | SELECT p.transaction, p.gid, p.prepared, u.rolname AS owner, d.datname AS database FROM ((pg_prepared_xact() p(transaction, gid, prepared, ownerid, dbid) LEFT JOIN pg_authid u ON ((p.ownerid = u.oid))) LEFT JOIN pg_database d ON ((p.dbid = d.oid)));
|
||||
pg_roles | SELECT pg_authid.rolname, pg_authid.rolsuper, pg_authid.rolinherit, pg_authid.rolcreaterole, pg_authid.rolcreatedb, pg_authid.rolcatupdate, pg_authid.rolcanlogin, pg_authid.rolreplication, pg_authid.rolconnlimit, '********'::text AS rolpassword, pg_authid.rolvaliduntil, s.setconfig AS rolconfig, pg_authid.oid FROM (pg_authid LEFT JOIN pg_db_role_setting s ON (((pg_authid.oid = s.setrole) AND (s.setdatabase = (0)::oid))));
|
||||
pg_rules | SELECT n.nspname AS schemaname, c.relname AS tablename, r.rulename, pg_get_ruledef(r.oid) AS definition FROM ((pg_rewrite r JOIN pg_class c ON ((c.oid = r.ev_class))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (r.rulename <> '_RETURN'::name);
|
||||
pg_seclabels | (((((SELECT l.objoid, l.classoid, l.objsubid, CASE WHEN (rel.relkind = 'r'::"char") THEN 'table'::text WHEN (rel.relkind = 'v'::"char") THEN 'view'::text WHEN (rel.relkind = 'S'::"char") THEN 'sequence'::text WHEN (rel.relkind = 'f'::"char") THEN 'foreign table'::text ELSE NULL::text END AS objtype, rel.relnamespace AS objnamespace, CASE WHEN pg_table_is_visible(rel.oid) THEN quote_ident((rel.relname)::text) ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((rel.relname)::text)) END AS objname, l.provider, l.label FROM ((pg_seclabel l JOIN pg_class rel ON (((l.classoid = rel.tableoid) AND (l.objoid = rel.oid)))) JOIN pg_namespace nsp ON ((rel.relnamespace = nsp.oid))) WHERE (l.objsubid = 0) UNION ALL SELECT l.objoid, l.classoid, l.objsubid, 'column'::text AS objtype, rel.relnamespace AS objnamespace, ((CASE WHEN pg_table_is_visible(rel.oid) THEN quote_ident((rel.relname)::text) ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((rel.relname)::text)) END || '.'::text) || (att.attname)::text) AS objname, l.provider, l.label FROM (((pg_seclabel l JOIN pg_class rel ON (((l.classoid = rel.tableoid) AND (l.objoid = rel.oid)))) JOIN pg_attribute att ON (((rel.oid = att.attrelid) AND (l.objsubid = att.attnum)))) JOIN pg_namespace nsp ON ((rel.relnamespace = nsp.oid))) WHERE (l.objsubid <> 0)) UNION ALL SELECT l.objoid, l.classoid, l.objsubid, CASE WHEN (pro.proisagg = true) THEN 'aggregate'::text WHEN (pro.proisagg = false) THEN 'function'::text ELSE NULL::text END AS objtype, pro.pronamespace AS objnamespace, (((CASE WHEN pg_function_is_visible(pro.oid) THEN quote_ident((pro.proname)::text) ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((pro.proname)::text)) END || '('::text) || pg_get_function_arguments(pro.oid)) || ')'::text) AS objname, l.provider, l.label FROM ((pg_seclabel l JOIN pg_proc pro ON (((l.classoid = pro.tableoid) AND (l.objoid = pro.oid)))) JOIN pg_namespace nsp ON ((pro.pronamespace = nsp.oid))) WHERE (l.objsubid = 0)) UNION ALL SELECT l.objoid, l.classoid, l.objsubid, CASE WHEN (typ.typtype = 'd'::"char") THEN 'domain'::text ELSE 'type'::text END AS objtype, typ.typnamespace AS objnamespace, CASE WHEN pg_type_is_visible(typ.oid) THEN quote_ident((typ.typname)::text) ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((typ.typname)::text)) END AS objname, l.provider, l.label FROM ((pg_seclabel l JOIN pg_type typ ON (((l.classoid = typ.tableoid) AND (l.objoid = typ.oid)))) JOIN pg_namespace nsp ON ((typ.typnamespace = nsp.oid))) WHERE (l.objsubid = 0)) UNION ALL SELECT l.objoid, l.classoid, l.objsubid, 'large object'::text AS objtype, NULL::oid AS objnamespace, (l.objoid)::text AS objname, l.provider, l.label FROM (pg_seclabel l JOIN pg_largeobject_metadata lom ON ((l.objoid = lom.oid))) WHERE ((l.classoid = ('pg_largeobject'::regclass)::oid) AND (l.objsubid = 0))) UNION ALL SELECT l.objoid, l.classoid, l.objsubid, 'language'::text AS objtype, NULL::oid AS objnamespace, quote_ident((lan.lanname)::text) AS objname, l.provider, l.label FROM (pg_seclabel l JOIN pg_language lan ON (((l.classoid = lan.tableoid) AND (l.objoid = lan.oid)))) WHERE (l.objsubid = 0)) UNION ALL SELECT l.objoid, l.classoid, l.objsubid, 'schema'::text AS objtype, nsp.oid AS objnamespace, quote_ident((nsp.nspname)::text) AS objname, l.provider, l.label FROM (pg_seclabel l JOIN pg_namespace nsp ON (((l.classoid = nsp.tableoid) AND (l.objoid = nsp.oid)))) WHERE (l.objsubid = 0);
|
||||
pg_seclabels | ((((((((SELECT l.objoid, l.classoid, l.objsubid, CASE WHEN (rel.relkind = 'r'::"char") THEN 'table'::text WHEN (rel.relkind = 'v'::"char") THEN 'view'::text WHEN (rel.relkind = 'S'::"char") THEN 'sequence'::text WHEN (rel.relkind = 'f'::"char") THEN 'foreign table'::text ELSE NULL::text END AS objtype, rel.relnamespace AS objnamespace, CASE WHEN pg_table_is_visible(rel.oid) THEN quote_ident((rel.relname)::text) ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((rel.relname)::text)) END AS objname, l.provider, l.label FROM ((pg_seclabel l JOIN pg_class rel ON (((l.classoid = rel.tableoid) AND (l.objoid = rel.oid)))) JOIN pg_namespace nsp ON ((rel.relnamespace = nsp.oid))) WHERE (l.objsubid = 0) UNION ALL SELECT l.objoid, l.classoid, l.objsubid, 'column'::text AS objtype, rel.relnamespace AS objnamespace, ((CASE WHEN pg_table_is_visible(rel.oid) THEN quote_ident((rel.relname)::text) ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((rel.relname)::text)) END || '.'::text) || (att.attname)::text) AS objname, l.provider, l.label FROM (((pg_seclabel l JOIN pg_class rel ON (((l.classoid = rel.tableoid) AND (l.objoid = rel.oid)))) JOIN pg_attribute att ON (((rel.oid = att.attrelid) AND (l.objsubid = att.attnum)))) JOIN pg_namespace nsp ON ((rel.relnamespace = nsp.oid))) WHERE (l.objsubid <> 0)) UNION ALL SELECT l.objoid, l.classoid, l.objsubid, CASE WHEN (pro.proisagg = true) THEN 'aggregate'::text WHEN (pro.proisagg = false) THEN 'function'::text ELSE NULL::text END AS objtype, pro.pronamespace AS objnamespace, (((CASE WHEN pg_function_is_visible(pro.oid) THEN quote_ident((pro.proname)::text) ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((pro.proname)::text)) END || '('::text) || pg_get_function_arguments(pro.oid)) || ')'::text) AS objname, l.provider, l.label FROM ((pg_seclabel l JOIN pg_proc pro ON (((l.classoid = pro.tableoid) AND (l.objoid = pro.oid)))) JOIN pg_namespace nsp ON ((pro.pronamespace = nsp.oid))) WHERE (l.objsubid = 0)) UNION ALL SELECT l.objoid, l.classoid, l.objsubid, CASE WHEN (typ.typtype = 'd'::"char") THEN 'domain'::text ELSE 'type'::text END AS objtype, typ.typnamespace AS objnamespace, CASE WHEN pg_type_is_visible(typ.oid) THEN quote_ident((typ.typname)::text) ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((typ.typname)::text)) END AS objname, l.provider, l.label FROM ((pg_seclabel l JOIN pg_type typ ON (((l.classoid = typ.tableoid) AND (l.objoid = typ.oid)))) JOIN pg_namespace nsp ON ((typ.typnamespace = nsp.oid))) WHERE (l.objsubid = 0)) UNION ALL SELECT l.objoid, l.classoid, l.objsubid, 'large object'::text AS objtype, NULL::oid AS objnamespace, (l.objoid)::text AS objname, l.provider, l.label FROM (pg_seclabel l JOIN pg_largeobject_metadata lom ON ((l.objoid = lom.oid))) WHERE ((l.classoid = ('pg_largeobject'::regclass)::oid) AND (l.objsubid = 0))) UNION ALL SELECT l.objoid, l.classoid, l.objsubid, 'language'::text AS objtype, NULL::oid AS objnamespace, quote_ident((lan.lanname)::text) AS objname, l.provider, l.label FROM (pg_seclabel l JOIN pg_language lan ON (((l.classoid = lan.tableoid) AND (l.objoid = lan.oid)))) WHERE (l.objsubid = 0)) UNION ALL SELECT l.objoid, l.classoid, l.objsubid, 'schema'::text AS objtype, nsp.oid AS objnamespace, quote_ident((nsp.nspname)::text) AS objname, l.provider, l.label FROM (pg_seclabel l JOIN pg_namespace nsp ON (((l.classoid = nsp.tableoid) AND (l.objoid = nsp.oid)))) WHERE (l.objsubid = 0)) UNION ALL SELECT l.objoid, l.classoid, 0 AS objsubid, 'database'::text AS objtype, NULL::oid AS objnamespace, quote_ident((dat.datname)::text) AS objname, l.provider, l.label FROM (pg_shseclabel l JOIN pg_database dat ON (((l.classoid = dat.tableoid) AND (l.objoid = dat.oid))))) UNION ALL SELECT l.objoid, l.classoid, 0 AS objsubid, 'tablespace'::text AS objtype, NULL::oid AS objnamespace, quote_ident((spc.spcname)::text) AS objname, l.provider, l.label FROM (pg_shseclabel l JOIN pg_tablespace spc ON (((l.classoid = spc.tableoid) AND (l.objoid = spc.oid))))) UNION ALL SELECT l.objoid, l.classoid, 0 AS objsubid, 'role'::text AS objtype, NULL::oid AS objnamespace, quote_ident((rol.rolname)::text) AS objname, l.provider, l.label FROM (pg_shseclabel l JOIN pg_authid rol ON (((l.classoid = rol.tableoid) AND (l.objoid = rol.oid))));
|
||||
pg_settings | SELECT a.name, a.setting, a.unit, a.category, a.short_desc, a.extra_desc, a.context, a.vartype, a.source, a.min_val, a.max_val, a.enumvals, a.boot_val, a.reset_val, a.sourcefile, a.sourceline FROM pg_show_all_settings() a(name, setting, unit, category, short_desc, extra_desc, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, sourcefile, sourceline);
|
||||
pg_shadow | SELECT pg_authid.rolname AS usename, pg_authid.oid AS usesysid, pg_authid.rolcreatedb AS usecreatedb, pg_authid.rolsuper AS usesuper, pg_authid.rolcatupdate AS usecatupd, pg_authid.rolreplication AS userepl, pg_authid.rolpassword AS passwd, (pg_authid.rolvaliduntil)::abstime AS valuntil, s.setconfig AS useconfig FROM (pg_authid LEFT JOIN pg_db_role_setting s ON (((pg_authid.oid = s.setrole) AND (s.setdatabase = (0)::oid)))) WHERE pg_authid.rolcanlogin;
|
||||
pg_stat_activity | SELECT s.datid, d.datname, s.procpid, s.usesysid, u.rolname AS usename, s.application_name, s.client_addr, s.client_hostname, s.client_port, s.backend_start, s.xact_start, s.query_start, s.waiting, s.current_query FROM pg_database d, pg_stat_get_activity(NULL::integer) s(datid, procpid, usesysid, application_name, current_query, waiting, xact_start, query_start, backend_start, client_addr, client_hostname, client_port), pg_authid u WHERE ((s.datid = d.oid) AND (s.usesysid = u.oid));
|
||||
|
@ -120,6 +120,7 @@ SELECT relname, relhasindex
|
||||
pg_seclabel | t
|
||||
pg_shdepend | t
|
||||
pg_shdescription | t
|
||||
pg_shseclabel | t
|
||||
pg_statistic | t
|
||||
pg_tablespace | t
|
||||
pg_trigger | t
|
||||
@ -157,7 +158,7 @@ SELECT relname, relhasindex
|
||||
timetz_tbl | f
|
||||
tinterval_tbl | f
|
||||
varchar_tbl | f
|
||||
(146 rows)
|
||||
(147 rows)
|
||||
|
||||
--
|
||||
-- another sanity check: every system catalog that has OIDs should have
|
||||
|
@ -12,7 +12,7 @@ DROP TABLE IF EXISTS seclabel_tbl1;
|
||||
DROP TABLE IF EXISTS seclabel_tbl2;
|
||||
DROP TABLE IF EXISTS seclabel_tbl3;
|
||||
|
||||
CREATE USER seclabel_user1;
|
||||
CREATE USER seclabel_user1 WITH CREATEROLE;
|
||||
CREATE USER seclabel_user2;
|
||||
|
||||
CREATE TABLE seclabel_tbl1 (a int, b text);
|
||||
@ -34,6 +34,11 @@ SECURITY LABEL FOR 'dummy' ON TABLE seclabel_tbl1 IS 'classified'; -- fail
|
||||
SECURITY LABEL ON TABLE seclabel_tbl1 IS '...invalid label...'; -- fail
|
||||
SECURITY LABEL ON TABLE seclabel_tbl3 IS 'unclassified'; -- fail
|
||||
|
||||
SECURITY LABEL ON ROLE seclabel_user1 IS 'classified'; -- fail
|
||||
SECURITY LABEL FOR 'dummy' ON ROLE seclabel_user1 IS 'classified'; -- fail
|
||||
SECURITY LABEL ON ROLE seclabel_user1 IS '...invalid label...'; -- fail
|
||||
SECURITY LABEL ON ROLE seclabel_user3 IS 'unclassified'; -- fail
|
||||
|
||||
-- Load dummy external security provider
|
||||
LOAD '@libdir@/dummy_seclabel@DLSUFFIX@';
|
||||
|
||||
@ -55,21 +60,38 @@ SET SESSION AUTHORIZATION seclabel_user2;
|
||||
SECURITY LABEL ON TABLE seclabel_tbl1 IS 'unclassified'; -- fail
|
||||
SECURITY LABEL ON TABLE seclabel_tbl2 IS 'classified'; -- OK
|
||||
|
||||
--
|
||||
-- Test for shared database object
|
||||
--
|
||||
SET SESSION AUTHORIZATION seclabel_user1;
|
||||
|
||||
SECURITY LABEL ON ROLE seclabel_user1 IS 'classified'; -- OK
|
||||
SECURITY LABEL ON ROLE seclabel_user1 IS '...invalid label...'; -- fail
|
||||
SECURITY LABEL FOR 'dummy' ON ROLE seclabel_user2 IS 'unclassified'; -- OK
|
||||
SECURITY LABEL FOR 'unknown_seclabel' ON ROLE seclabel_user1 IS 'unclassified'; -- fail
|
||||
SECURITY LABEL ON ROLE seclabel_user1 IS 'secret'; -- fail (not superuser)
|
||||
SECURITY LABEL ON ROLE seclabel_user3 IS 'unclassified'; -- fail (not found)
|
||||
|
||||
SET SESSION AUTHORIZATION seclabel_user2;
|
||||
SECURITY LABEL ON ROLE seclabel_user2 IS 'unclassified'; -- fail (not privileged)
|
||||
|
||||
RESET SESSION AUTHORIZATION;
|
||||
|
||||
--
|
||||
-- Test for various types of object
|
||||
--
|
||||
RESET SESSION AUTHORIZATION;
|
||||
|
||||
SECURITY LABEL ON TABLE seclabel_tbl1 IS 'top secret'; -- OK
|
||||
SECURITY LABEL ON VIEW seclabel_view1 IS 'classified'; -- OK
|
||||
SECURITY LABEL ON FUNCTION seclabel_four() IS 'classified'; -- OK
|
||||
SECURITY LABEL ON DOMAIN seclabel_domain IS 'classified'; -- OK
|
||||
SECURITY LABEL ON LANGUAGE plpgsql IS 'unclassified'; -- OK
|
||||
SECURITY LABEL ON SCHEMA public IS 'unclassified'; -- OK
|
||||
CREATE SCHEMA seclabel_test;
|
||||
SECURITY LABEL ON SCHEMA seclabel_test IS 'unclassified'; -- OK
|
||||
|
||||
SELECT objtype, objname, provider, label FROM pg_seclabels
|
||||
ORDER BY objtype, objname;
|
||||
|
||||
SECURITY LABEL ON LANGUAGE plpgsql IS NULL; -- OK
|
||||
SECURITY LABEL ON SCHEMA public IS NULL; -- OK
|
||||
|
||||
-- clean up objects
|
||||
DROP FUNCTION seclabel_four();
|
||||
DROP DOMAIN seclabel_domain;
|
||||
@ -78,6 +100,7 @@ DROP TABLE seclabel_tbl1;
|
||||
DROP TABLE seclabel_tbl2;
|
||||
DROP USER seclabel_user1;
|
||||
DROP USER seclabel_user2;
|
||||
DROP SCHEMA seclabel_test;
|
||||
|
||||
-- make sure we don't have any leftovers
|
||||
SELECT objtype, objname, provider, label FROM pg_seclabels
|
||||
|
@ -8,7 +8,7 @@ DROP ROLE IF EXISTS seclabel_user2;
|
||||
DROP TABLE IF EXISTS seclabel_tbl1;
|
||||
DROP TABLE IF EXISTS seclabel_tbl2;
|
||||
DROP TABLE IF EXISTS seclabel_tbl3;
|
||||
CREATE USER seclabel_user1;
|
||||
CREATE USER seclabel_user1 WITH CREATEROLE;
|
||||
CREATE USER seclabel_user2;
|
||||
CREATE TABLE seclabel_tbl1 (a int, b text);
|
||||
CREATE TABLE seclabel_tbl2 (x int, y text);
|
||||
@ -29,6 +29,14 @@ SECURITY LABEL ON TABLE seclabel_tbl1 IS '...invalid label...'; -- fail
|
||||
ERROR: no security label providers have been loaded
|
||||
SECURITY LABEL ON TABLE seclabel_tbl3 IS 'unclassified'; -- fail
|
||||
ERROR: no security label providers have been loaded
|
||||
SECURITY LABEL ON ROLE seclabel_user1 IS 'classified'; -- fail
|
||||
ERROR: no security label providers have been loaded
|
||||
SECURITY LABEL FOR 'dummy' ON ROLE seclabel_user1 IS 'classified'; -- fail
|
||||
ERROR: security label provider "dummy" is not loaded
|
||||
SECURITY LABEL ON ROLE seclabel_user1 IS '...invalid label...'; -- fail
|
||||
ERROR: no security label providers have been loaded
|
||||
SECURITY LABEL ON ROLE seclabel_user3 IS 'unclassified'; -- fail
|
||||
ERROR: no security label providers have been loaded
|
||||
-- Load dummy external security provider
|
||||
LOAD '@abs_builddir@/dummy_seclabel@DLSUFFIX@';
|
||||
--
|
||||
@ -52,13 +60,34 @@ SET SESSION AUTHORIZATION seclabel_user2;
|
||||
SECURITY LABEL ON TABLE seclabel_tbl1 IS 'unclassified'; -- fail
|
||||
ERROR: must be owner of relation seclabel_tbl1
|
||||
SECURITY LABEL ON TABLE seclabel_tbl2 IS 'classified'; -- OK
|
||||
--
|
||||
-- Test for shared database object
|
||||
--
|
||||
SET SESSION AUTHORIZATION seclabel_user1;
|
||||
SECURITY LABEL ON ROLE seclabel_user1 IS 'classified'; -- OK
|
||||
SECURITY LABEL ON ROLE seclabel_user1 IS '...invalid label...'; -- fail
|
||||
ERROR: '...invalid label...' is not a valid security label
|
||||
SECURITY LABEL FOR 'dummy' ON ROLE seclabel_user2 IS 'unclassified'; -- OK
|
||||
SECURITY LABEL FOR 'unknown_seclabel' ON ROLE seclabel_user1 IS 'unclassified'; -- fail
|
||||
ERROR: security label provider "unknown_seclabel" is not loaded
|
||||
SECURITY LABEL ON ROLE seclabel_user1 IS 'secret'; -- fail (not superuser)
|
||||
ERROR: only superuser can set 'secret' label
|
||||
SECURITY LABEL ON ROLE seclabel_user3 IS 'unclassified'; -- fail (not found)
|
||||
ERROR: role "seclabel_user3" does not exist
|
||||
SET SESSION AUTHORIZATION seclabel_user2;
|
||||
SECURITY LABEL ON ROLE seclabel_user2 IS 'unclassified'; -- fail (not privileged)
|
||||
ERROR: must have CREATEROLE privilege
|
||||
RESET SESSION AUTHORIZATION;
|
||||
--
|
||||
-- Test for various types of object
|
||||
--
|
||||
RESET SESSION AUTHORIZATION;
|
||||
SECURITY LABEL ON TABLE seclabel_tbl1 IS 'top secret'; -- OK
|
||||
SECURITY LABEL ON VIEW seclabel_view1 IS 'classified'; -- OK
|
||||
SECURITY LABEL ON FUNCTION seclabel_four() IS 'classified'; -- OK
|
||||
SECURITY LABEL ON DOMAIN seclabel_domain IS 'classified'; -- OK
|
||||
SECURITY LABEL ON LANGUAGE plpgsql IS 'unclassified'; -- OK
|
||||
SECURITY LABEL ON SCHEMA public IS 'unclassified'; -- OK
|
||||
CREATE SCHEMA seclabel_test;
|
||||
SECURITY LABEL ON SCHEMA seclabel_test IS 'unclassified'; -- OK
|
||||
SELECT objtype, objname, provider, label FROM pg_seclabels
|
||||
ORDER BY objtype, objname;
|
||||
objtype | objname | provider | label
|
||||
@ -66,15 +95,14 @@ SELECT objtype, objname, provider, label FROM pg_seclabels
|
||||
column | seclabel_tbl1.a | dummy | unclassified
|
||||
domain | seclabel_domain | dummy | classified
|
||||
function | seclabel_four() | dummy | classified
|
||||
language | plpgsql | dummy | unclassified
|
||||
schema | public | dummy | unclassified
|
||||
role | seclabel_user1 | dummy | classified
|
||||
role | seclabel_user2 | dummy | unclassified
|
||||
schema | seclabel_test | dummy | unclassified
|
||||
table | seclabel_tbl1 | dummy | top secret
|
||||
table | seclabel_tbl2 | dummy | classified
|
||||
view | seclabel_view1 | dummy | classified
|
||||
(8 rows)
|
||||
(9 rows)
|
||||
|
||||
SECURITY LABEL ON LANGUAGE plpgsql IS NULL; -- OK
|
||||
SECURITY LABEL ON SCHEMA public IS NULL; -- OK
|
||||
-- clean up objects
|
||||
DROP FUNCTION seclabel_four();
|
||||
DROP DOMAIN seclabel_domain;
|
||||
@ -83,6 +111,7 @@ DROP TABLE seclabel_tbl1;
|
||||
DROP TABLE seclabel_tbl2;
|
||||
DROP USER seclabel_user1;
|
||||
DROP USER seclabel_user2;
|
||||
DROP SCHEMA seclabel_test;
|
||||
-- make sure we don't have any leftovers
|
||||
SELECT objtype, objname, provider, label FROM pg_seclabels
|
||||
ORDER BY objtype, objname;
|
||||
|
Loading…
Reference in New Issue
Block a user