 contrib/sepgsql/dml.c              |   37 ++++++++++----
 contrib/sepgsql/expected/dml.out   |    6 +-
 contrib/sepgsql/expected/label.out |    4 +-
 contrib/sepgsql/expected/misc.out  |    2 +-
 contrib/sepgsql/hooks.c            |    4 +-
 contrib/sepgsql/label.c            |   89 ++++++++++++++++++++++++++++-------
 contrib/sepgsql/proc.c             |    3 +-
 contrib/sepgsql/relation.c         |   20 ++++++--
 contrib/sepgsql/schema.c           |    3 +-
 contrib/sepgsql/selinux.c          |    6 +-
 contrib/sepgsql/sql/label.sql      |    2 +-
 doc/src/sgml/sepgsql.sgml          |    2 +-
 12 files changed, 128 insertions(+), 50 deletions(-)

diff --git a/contrib/sepgsql/dml.c b/contrib/sepgsql/dml.c
index 684b5ee..358a264 100644
--- a/contrib/sepgsql/dml.c
+++ b/contrib/sepgsql/dml.c
@@ -14,6 +14,7 @@
 #include "access/tupdesc.h"
 #include "catalog/catalog.h"
 #include "catalog/heap.h"
+#include "catalog/dependency.h"
 #include "catalog/pg_attribute.h"
 #include "catalog/pg_class.h"
 #include "catalog/pg_inherits_fn.h"
@@ -151,6 +152,7 @@ check_relation_privileges(Oid relOid,
 	char		relkind = get_rel_relkind(relOid);
 	char	   *scontext = sepgsql_get_client_label();
 	char	   *tcontext;
+	char	   *audit_name;
 	Bitmapset  *columns;
 	int			index;
 	bool		result = true;
@@ -183,6 +185,7 @@ check_relation_privileges(Oid relOid,
 	 * Check permissions on the relation
 	 */
 	tcontext = sepgsql_get_label(RelationRelationId, relOid, 0);
+	audit_name = getObjectDescriptionOids(RelationRelationId, relOid);
 	switch (relkind)
 	{
 		case RELKIND_RELATION:
@@ -190,10 +193,8 @@ check_relation_privileges(Oid relOid,
 										 tcontext,
 										 SEPG_CLASS_DB_TABLE,
 										 required,
-										 get_rel_name(relOid),
+										 audit_name,
 										 abort);
-			if (!result)
-				return false;
 			break;
 
 		case RELKIND_SEQUENCE:
@@ -204,23 +205,31 @@ check_relation_privileges(Oid relOid,
 											 tcontext,
 											 SEPG_CLASS_DB_SEQUENCE,
 											 SEPG_DB_SEQUENCE__GET_VALUE,
-											 get_rel_name(relOid),
+											 audit_name,
 											 abort);
-			return result;
+			break;
 
 		case RELKIND_VIEW:
 			result = sepgsql_check_perms(scontext,
 										 tcontext,
 										 SEPG_CLASS_DB_VIEW,
 										 SEPG_DB_VIEW__EXPAND,
-										 get_rel_name(relOid),
+										 audit_name,
 										 abort);
-			return result;
+			break;
 
 		default:
 			/* nothing to be checked */
-			return true;
+			break;
 	}
+	pfree(tcontext);
+	pfree(audit_name);
+
+	/*
+	 * Only columns owned by relations shall be checked
+	 */
+	if (relkind != RELKIND_RELATION)
+		return true;
 
 	/*
 	 * Check permissions on the columns
@@ -233,7 +242,7 @@ check_relation_privileges(Oid relOid,
 	{
 		AttrNumber	attnum;
 		uint32		column_perms = 0;
-		char		audit_name[NAMEDATALEN * 2 + 10];
+		ObjectAddress	object;
 
 		if (bms_is_member(index, selected))
 			column_perms |= SEPG_DB_COLUMN__SELECT;
@@ -250,8 +259,11 @@ check_relation_privileges(Oid relOid,
 		/* obtain column's permission */
 		attnum = index + FirstLowInvalidHeapAttributeNumber;
 		tcontext = sepgsql_get_label(RelationRelationId, relOid, attnum);
-		snprintf(audit_name, sizeof(audit_name), "%s.%s",
-				 get_rel_name(relOid), get_attname(relOid, attnum));
+
+		object.classId = RelationRelationId;
+		object.objectId = relOid;
+		object.objectSubId = attnum;
+		audit_name = getObjectDescription(&object);
 
 		result = sepgsql_check_perms(scontext,
 									 tcontext,
@@ -259,6 +271,9 @@ check_relation_privileges(Oid relOid,
 									 column_perms,
 									 audit_name,
 									 abort);
+		pfree(tcontext);
+		pfree(audit_name);
+
 		if (!result)
 			return result;
 	}
diff --git a/contrib/sepgsql/expected/dml.out b/contrib/sepgsql/expected/dml.out
index 5625ebc..c1bbbba 100644
--- a/contrib/sepgsql/expected/dml.out
+++ b/contrib/sepgsql/expected/dml.out
@@ -42,15 +42,15 @@ SELECT objtype, objname, label FROM pg_seclabels
  table   | t3      | system_u:object_r:sepgsql_fixed_table_t:s0
  table   | t4      | system_u:object_r:sepgsql_secret_table_t:s0
  table   | t5      | system_u:object_r:sepgsql_table_t:s0
- column  | t5.g    | system_u:object_r:sepgsql_secret_table_t:s0
- column  | t5.f    | system_u:object_r:sepgsql_ro_table_t:s0
  column  | t5.e    | system_u:object_r:sepgsql_table_t:s0
+ column  | t5.f    | system_u:object_r:sepgsql_ro_table_t:s0
+ column  | t5.g    | system_u:object_r:sepgsql_secret_table_t:s0
 (8 rows)
 
 -- Hardwired Rules
 UPDATE pg_attribute SET attisdropped = true
     WHERE attrelid = 't5'::regclass AND attname = 'f';	-- failed
-ERROR:  selinux: hardwired security policy violation
+ERROR:  SELinux: hardwired security policy violation
 --
 -- Simple DML statements
 --
diff --git a/contrib/sepgsql/expected/label.out b/contrib/sepgsql/expected/label.out
index 0f0615c..daf8d08 100644
--- a/contrib/sepgsql/expected/label.out
+++ b/contrib/sepgsql/expected/label.out
@@ -56,8 +56,8 @@ SELECT sepgsql_getcon();	-- confirm client privilege
 SECURITY LABEL ON TABLE t1
     IS 'system_u:object_r:sepgsql_ro_table_t:s0';	-- ok
 SECURITY LABEL ON TABLE t2
-    IS 'invalid seuciryt context';			-- be failed
-ERROR:  invalid security label: "invalid seuciryt context"
+    IS 'invalid security context';			-- be failed
+ERROR:  SELinux: invalid security label: "invalid security context"
 SECURITY LABEL ON COLUMN t2
     IS 'system_u:object_r:sepgsql_ro_table_t:s0';	-- be failed
 ERROR:  improper relation name (too many dotted names): 
diff --git a/contrib/sepgsql/expected/misc.out b/contrib/sepgsql/expected/misc.out
index 5242333..329852c 100644
--- a/contrib/sepgsql/expected/misc.out
+++ b/contrib/sepgsql/expected/misc.out
@@ -2,4 +2,4 @@
 -- Regression Test for Misc Permission Checks
 --
 LOAD '$libdir/sepgsql';		-- failed
-ERROR:  SELinux: LOAD is not allowed anyway.
+ERROR:  SELinux: LOAD is not permitted
diff --git a/contrib/sepgsql/hooks.c b/contrib/sepgsql/hooks.c
index bc7ce51..83a505e 100644
--- a/contrib/sepgsql/hooks.c
+++ b/contrib/sepgsql/hooks.c
@@ -91,7 +91,7 @@ sepgsql_client_auth(Port *port, int status)
 	if (getpeercon_raw(port->sock, &context) < 0)
 		ereport(FATAL,
 				(errcode(ERRCODE_INTERNAL_ERROR),
-				 errmsg("SELinux: unable to get peer label")));
+				 errmsg("SELinux: unable to get peer label: %m")));
 
 	sepgsql_set_client_label(context);
 
@@ -414,7 +414,7 @@ _PG_init(void)
 	if (getcon_raw(&context) < 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_INTERNAL_ERROR),
-				 errmsg("SELinux: failed to get server security label")));
+				 errmsg("SELinux: failed to get server security label: %m")));
 	sepgsql_set_client_label(context);
 
 	/* Security label provider hook */
diff --git a/contrib/sepgsql/label.c b/contrib/sepgsql/label.c
index ad568f8..828512a 100644
--- a/contrib/sepgsql/label.c
+++ b/contrib/sepgsql/label.c
@@ -81,7 +81,7 @@ sepgsql_get_label(Oid classId, Oid objectId, int32 subId)
 		if (security_get_initial_context_raw("unlabeled", &unlabeled) < 0)
 			ereport(ERROR,
 					(errcode(ERRCODE_INTERNAL_ERROR),
-					 errmsg("SELinux: failed to get initial security label")));
+					 errmsg("SELinux: failed to get initial security label: %m")));
 		PG_TRY();
 		{
 			label = pstrdup(unlabeled);
@@ -184,7 +184,7 @@ sepgsql_mcstrans_in(PG_FUNCTION_ARGS)
 									 &raw_label) < 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_INTERNAL_ERROR),
-				 errmsg("SELinux: could not translate security label")));
+				 errmsg("SELinux: could not translate security label: %m")));
 
 	PG_TRY();
 	{
@@ -224,7 +224,7 @@ sepgsql_mcstrans_out(PG_FUNCTION_ARGS)
 									 &qual_label) < 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_INTERNAL_ERROR),
-				 errmsg("SELinux: could not translate security label")));
+				 errmsg("SELinux: could not translate security label: %m")));
 
 	PG_TRY();
 	{
@@ -242,6 +242,51 @@ sepgsql_mcstrans_out(PG_FUNCTION_ARGS)
 }
 
 /*
+ * quote_object_names
+ *
+ * It tries to quote the supplied identifiers
+ */
+static char *
+quote_object_name(const char *src1, const char *src2,
+				  const char *src3, const char *src4)
+{
+	StringInfoData	result;
+	const char	   *temp;
+
+	initStringInfo(&result);
+
+	if (src1)
+	{
+		temp = quote_identifier(src1);
+		appendStringInfo(&result, "%s", temp);
+		if (src1 != temp)
+			pfree((void *)temp);
+	}
+	if (src2)
+	{
+		temp = quote_identifier(src2);
+		appendStringInfo(&result, ".%s", temp);
+		if (src2 != temp)
+			pfree((void *)temp);
+	}
+	if (src3)
+	{
+		temp = quote_identifier(src3);
+		appendStringInfo(&result, ".%s", temp);
+		if (src3 != temp)
+			pfree((void *)temp);
+	}
+	if (src4)
+	{
+		temp = quote_identifier(src4);
+		appendStringInfo(&result, ".%s", temp);
+		if (src4 != temp)
+			pfree((void *)temp);
+	}
+	return result.data;
+}
+
+/*
  * exec_object_restorecon
  *
  * This routine is a helper called by sepgsql_restorecon; it set up
@@ -273,7 +318,7 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
 		Form_pg_class		relForm;
 		Form_pg_attribute	attForm;
 		Form_pg_proc		proForm;
-		char				objname[NAMEDATALEN * 4 + 10];
+		char			   *objname;
 		int					objtype = 1234;
 		ObjectAddress		object;
 		security_context_t	context;
@@ -288,8 +333,10 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
 				nspForm = (Form_pg_namespace) GETSTRUCT(tuple);
 
 				objtype = SELABEL_DB_SCHEMA;
-				snprintf(objname, sizeof(objname), "%s.%s",
-						 database_name, NameStr(nspForm->nspname));
+
+				objname = quote_object_name(database_name,
+											NameStr(nspForm->nspname),
+											NULL, NULL);
 
 				object.classId = NamespaceRelationId;
 				object.objectId = HeapTupleGetOid(tuple);
@@ -309,9 +356,10 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
 					continue;	/* no need to assign security label */
 
 				namespace_name = get_namespace_name(relForm->relnamespace);
-				snprintf(objname, sizeof(objname), "%s.%s.%s",
-						 database_name, namespace_name,
-						 NameStr(relForm->relname));
+				objname = quote_object_name(database_name,
+											namespace_name,
+											NameStr(relForm->relname),
+											NULL);
 				pfree(namespace_name);
 
 				object.classId = RelationRelationId;
@@ -330,11 +378,12 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
 				namespace_id = get_rel_namespace(attForm->attrelid);
 				namespace_name = get_namespace_name(namespace_id);
 				relation_name = get_rel_name(attForm->attrelid);
-				snprintf(objname, sizeof(objname), "%s.%s.%s.%s",
-						 database_name, namespace_name,
-						 relation_name, NameStr(attForm->attname));
-				pfree(relation_name);
+				objname = quote_object_name(database_name,
+											namespace_name,
+											relation_name,
+											NameStr(attForm->attname));
 				pfree(namespace_name);
+				pfree(relation_name);
 
 				object.classId = RelationRelationId;
 				object.objectId = attForm->attrelid;
@@ -347,9 +396,10 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
 				objtype = SELABEL_DB_PROCEDURE;
 
 				namespace_name = get_namespace_name(proForm->pronamespace);
-				snprintf(objname, sizeof(objname), "%s.%s.%s",
-						 database_name, namespace_name,
-						 NameStr(proForm->proname));
+				objname = quote_object_name(database_name,
+											namespace_name,
+											NameStr(proForm->proname),
+											NULL);
 				pfree(namespace_name);
 
 				object.classId = ProcedureRelationId;
@@ -359,6 +409,7 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
 
 			default:
 				elog(ERROR, "unexpected catalog id: %u", catalogId);
+				objname = NULL;		/* for compiler quiet */
 				break;
 		}
 
@@ -389,7 +440,9 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
 		else
 			ereport(ERROR,
 					(errcode(ERRCODE_INTERNAL_ERROR),
-					 errmsg("SELinux: could not determine initial security label for %s (type=%d)", objname, objtype)));
+					 errmsg("SELinux: could not determine initial security label for %s (type=%d): %m", objname, objtype)));
+
+		pfree(objname);
 	}
 	systable_endscan(sscan);
 
@@ -449,7 +502,7 @@ sepgsql_restorecon(PG_FUNCTION_ARGS)
 	if (!sehnd)
 		ereport(ERROR,
 				(errcode(ERRCODE_INTERNAL_ERROR),
-				 errmsg("SELinux: failed to initialize labeling handle")));
+				 errmsg("SELinux: failed to initialize labeling handle: %m")));
 	PG_TRY();
 	{
 		/*
diff --git a/contrib/sepgsql/launcher b/contrib/sepgsql/launcher
old mode 100644
new mode 100755
diff --git a/contrib/sepgsql/proc.c b/contrib/sepgsql/proc.c
index f1a7b9b..5a0c494 100644
--- a/contrib/sepgsql/proc.c
+++ b/contrib/sepgsql/proc.c
@@ -13,6 +13,7 @@
 #include "access/genam.h"
 #include "access/heapam.h"
 #include "access/sysattr.h"
+#include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/pg_namespace.h"
 #include "catalog/pg_proc.h"
@@ -99,7 +100,7 @@ sepgsql_proc_relabel(Oid functionId, const char *seclabel)
 	char	   *tcontext;
 	char	   *audit_name;
 
-	audit_name = get_func_name(functionId);
+	audit_name = getObjectDescriptionOids(ProcedureRelationId, functionId);
 
 	/*
 	 * check db_procedure:{setattr relabelfrom} permission
diff --git a/contrib/sepgsql/relation.c b/contrib/sepgsql/relation.c
index ceaa6b0..ed5e3ad 100644
--- a/contrib/sepgsql/relation.c
+++ b/contrib/sepgsql/relation.c
@@ -14,6 +14,7 @@
 #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"
@@ -79,15 +80,18 @@ sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
 {
 	char	   *scontext = sepgsql_get_client_label();
 	char	   *tcontext;
-	char		audit_name[NAMEDATALEN * 2 + 10];
+	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")));
 
-	snprintf(audit_name, sizeof(audit_name), "%s.%s",
-			 get_rel_name(relOid), get_attname(relOid, attnum));
+	object.classId = RelationRelationId;
+	object.objectId = relOid;
+	object.objectSubId = attnum;
+	audit_name = getObjectDescription(&object);
 
 	/*
 	 * check db_column:{setattr relabelfrom} permission
@@ -100,7 +104,6 @@ sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
 						SEPG_DB_COLUMN__RELABELFROM,
 						audit_name,
 						true);
-	pfree(tcontext);
 
 	/*
 	 * check db_column:{relabelto} permission
@@ -111,6 +114,9 @@ sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
 						SEPG_DB_PROCEDURE__RELABELTO,
 						audit_name,
 						true);
+
+	pfree(tcontext);
+	pfree(audit_name);
 }
 
 /*
@@ -239,7 +245,7 @@ sepgsql_relation_relabel(Oid relOid, const char *seclabel)
 				 errmsg("cannot set security labels on relations except "
 						"for tables, sequences or views")));
 
-	audit_name = get_rel_name(relOid);
+	audit_name = getObjectDescriptionOids(RelationRelationId, relOid);
 
 	/*
 	 * check db_xxx:{setattr relabelfrom} permission
@@ -253,7 +259,6 @@ sepgsql_relation_relabel(Oid relOid, const char *seclabel)
 						SEPG_DB_TABLE__RELABELFROM,
 						audit_name,
 						true);
-	pfree(tcontext);
 
 	/*
 	 * check db_xxx:{relabelto} permission
@@ -264,4 +269,7 @@ sepgsql_relation_relabel(Oid relOid, const char *seclabel)
 						SEPG_DB_TABLE__RELABELTO,
 						audit_name,
 						true);
+
+	pfree(tcontext);
+	pfree(audit_name);
 }
diff --git a/contrib/sepgsql/schema.c b/contrib/sepgsql/schema.c
index df33a02..8538d18 100644
--- a/contrib/sepgsql/schema.c
+++ b/contrib/sepgsql/schema.c
@@ -10,6 +10,7 @@
  */
 #include "postgres.h"
 
+#include "catalog/dependency.h"
 #include "catalog/pg_namespace.h"
 #include "commands/seclabel.h"
 #include "utils/lsyscache.h"
@@ -68,7 +69,7 @@ sepgsql_schema_relabel(Oid namespaceId, const char *seclabel)
 	char	   *tcontext;
 	char	   *audit_name;
 
-	audit_name = get_namespace_name(namespaceId);
+	audit_name = getObjectDescriptionOids(NamespaceRelationId, namespaceId);
 
 	/*
 	 * check db_schema:{setattr relabelfrom} permission
diff --git a/contrib/sepgsql/selinux.c b/contrib/sepgsql/selinux.c
index a67bd56..03ba25c 100644
--- a/contrib/sepgsql/selinux.c
+++ b/contrib/sepgsql/selinux.c
@@ -396,7 +396,7 @@ sepgsql_audit_log(bool denied,
 	appendStringInfo(&buf, " scontext=%s tcontext=%s tclass=%s",
 					 scontext, tcontext, class_name);
 	if (audit_name)
-		appendStringInfo(&buf, " name=%s", audit_name);
+		appendStringInfo(&buf, " name=\"%s\"", audit_name);
 
 	ereport(LOG, (errmsg("SELinux: %s", buf.data)));
 }
@@ -459,7 +459,7 @@ sepgsql_compute_avd(const char *scontext,
 		ereport(ERROR,
 				(errcode(ERRCODE_INTERNAL_ERROR),
 				 errmsg("SELinux could not compute av_decision: "
-						"scontext=%s tcontext=%s tclass=%s",
+						"scontext=%s tcontext=%s tclass=%s: %m",
 						scontext, tcontext, tclass_name)));
 
 	/*
@@ -545,7 +545,7 @@ sepgsql_compute_create(const char *scontext,
 		ereport(ERROR,
 				(errcode(ERRCODE_INTERNAL_ERROR),
 				 errmsg("SELinux could not compute a new context: "
-						"scontext=%s tcontext=%s tclass=%s",
+						"scontext=%s tcontext=%s tclass=%s: %m",
 						scontext, tcontext, tclass_name)));
 
 	/*
diff --git a/contrib/sepgsql/sql/label.sql b/contrib/sepgsql/sql/label.sql
index 3162494..1100fcb 100644
--- a/contrib/sepgsql/sql/label.sql
+++ b/contrib/sepgsql/sql/label.sql
@@ -46,7 +46,7 @@ SELECT objtype, objname, label FROM pg_seclabels
 SECURITY LABEL ON TABLE t1
     IS 'system_u:object_r:sepgsql_ro_table_t:s0';	-- ok
 SECURITY LABEL ON TABLE t2
-    IS 'invalid seuciryt context';			-- be failed
+    IS 'invalid security context';			-- be failed
 SECURITY LABEL ON COLUMN t2
     IS 'system_u:object_r:sepgsql_ro_table_t:s0';	-- be failed
 SECURITY LABEL ON COLUMN t2.b
diff --git a/doc/src/sgml/sepgsql.sgml b/doc/src/sgml/sepgsql.sgml
index 7b56506..805dfde 100644
--- a/doc/src/sgml/sepgsql.sgml
+++ b/doc/src/sgml/sepgsql.sgml
@@ -75,7 +75,7 @@
     <term><productname>libselinux</productname></term>
     <listitem>
      <para>
-      v2.0.80 or later
+      v2.0.93 or later
      </para>
      <para>
       This library provides a set of APIs to communicate with
