It can sometimes be useful to match against a superuser in pg_hba.conf.
For example, one could imagine wanting to reject nonsuperuser from a
particular database.


This used to be possible by creating an empty role and matching against
that, but that functionality was removed (a long time ago) by commit
94cd0f1ad8a.


Adding another keyword can break backwards compatibility, of course.  So
that is an issue that needs to be discussed, but I don't imagine too
many people are using role names "superuser" and "nonsuperuser". Those
who are will have to quote them.

-- 

Vik Fearing                                          +33 6 46 75 15 36
http://2ndQuadrant.fr     PostgreSQL : Expertise, Formation et Support

diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml
index 5f1eec78fb..c0d1e00266 100644
--- a/doc/src/sgml/client-auth.sgml
+++ b/doc/src/sgml/client-auth.sgml
@@ -250,7 +250,11 @@ hostnogssenc <replaceable>database</replaceable>  <replaceable>user</replaceable
       <para>
        Specifies which database user name(s) this record
        matches. The value <literal>all</literal> specifies that it
-       matches all users.  Otherwise, this is either the name of a specific
+       matches all users.
+       The value <literal>superuser</literal> specifies that it matches all
+       superusers.  The value <literal>nonsuperuser</literal> specifies that it
+       matches no superusers.
+       Otherwise, this is either the name of a specific
        database user, or a group name preceded by <literal>+</literal>.
        (Recall that there is no real distinction between users and groups
        in <productname>PostgreSQL</productname>; a <literal>+</literal> mark really means
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index b6de92783a..a7a59a0510 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -596,6 +596,16 @@ check_role(const char *role, Oid roleid, List *tokens)
 			if (is_member(roleid, tok->string + 1))
 				return true;
 		}
+		else if (token_is_keyword(tok, "superuser"))
+		{
+			if (superuser_arg(roleid))
+				return true;
+		}
+		else if (token_is_keyword(tok, "nonsuperuser"))
+		{
+			if (!superuser_arg(roleid))
+				return true;
+		}
 		else if (token_matches(tok, role) ||
 				 token_is_keyword(tok, "all"))
 			return true;

Reply via email to