diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
new file mode 100644
index 515a40e..26bf35f
*** a/doc/src/sgml/catalogs.sgml
--- b/doc/src/sgml/catalogs.sgml
***************
*** 1416,1430 ****
       </row>
  
       <row>
-       <entry><structfield>rolcatupdate</structfield></entry>
-       <entry><type>bool</type></entry>
-       <entry>
-        Role can update system catalogs directly.  (Even a superuser cannot do
-        this unless this column is true)
-       </entry>
-      </row>
- 
-      <row>
        <entry><structfield>rolcanlogin</structfield></entry>
        <entry><type>bool</type></entry>
        <entry>
--- 1416,1421 ----
*************** SELECT * FROM pg_locks pl LEFT JOIN pg_p
*** 8492,8507 ****
       </row>
  
       <row>
-       <entry><structfield>rolcatupdate</structfield></entry>
-       <entry><type>bool</type></entry>
-       <entry></entry>
-       <entry>
-        Role can update system catalogs directly.  (Even a superuser cannot do
-        this unless this column is true)
-       </entry>
-      </row>
- 
-      <row>
        <entry><structfield>rolcanlogin</structfield></entry>
        <entry><type>bool</type></entry>
        <entry></entry>
--- 8483,8488 ----
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
new file mode 100644
index 1e3888e..da4ba4e
*** a/src/backend/catalog/aclchk.c
--- b/src/backend/catalog/aclchk.c
*************** aclcheck_error_type(AclResult aclerr, Oi
*** 3423,3448 ****
  }
  
  
- /* Check if given user has rolcatupdate privilege according to pg_authid */
- static bool
- has_rolcatupdate(Oid roleid)
- {
- 	bool		rolcatupdate;
- 	HeapTuple	tuple;
- 
- 	tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
- 	if (!HeapTupleIsValid(tuple))
- 		ereport(ERROR,
- 				(errcode(ERRCODE_UNDEFINED_OBJECT),
- 				 errmsg("role with OID %u does not exist", roleid)));
- 
- 	rolcatupdate = ((Form_pg_authid) GETSTRUCT(tuple))->rolcatupdate;
- 
- 	ReleaseSysCache(tuple);
- 
- 	return rolcatupdate;
- }
- 
  /*
   * Relay for the various pg_*_mask routines depending on object kind
   */
--- 3423,3428 ----
*************** pg_class_aclmask(Oid table_oid, Oid role
*** 3619,3646 ****
  	classForm = (Form_pg_class) GETSTRUCT(tuple);
  
  	/*
! 	 * Deny anyone permission to update a system catalog unless
! 	 * pg_authid.rolcatupdate is set.   (This is to let superusers protect
! 	 * themselves from themselves.)  Also allow it if allowSystemTableMods.
! 	 *
! 	 * As of 7.4 we have some updatable system views; those shouldn't be
! 	 * protected in this way.  Assume the view rules can take care of
! 	 * themselves.  ACL_USAGE is if we ever have system sequences.
! 	 */
! 	if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE | ACL_USAGE)) &&
! 		IsSystemClass(table_oid, classForm) &&
! 		classForm->relkind != RELKIND_VIEW &&
! 		!has_rolcatupdate(roleid) &&
! 		!allowSystemTableMods)
! 	{
! #ifdef ACLDEBUG
! 		elog(DEBUG2, "permission denied for system catalog update");
! #endif
! 		mask &= ~(ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE | ACL_USAGE);
! 	}
! 
! 	/*
! 	 * Otherwise, superusers bypass all permission-checking.
  	 */
  	if (superuser_arg(roleid))
  	{
--- 3599,3605 ----
  	classForm = (Form_pg_class) GETSTRUCT(tuple);
  
  	/*
! 	 * Superusers bypass all permission-checking.
  	 */
  	if (superuser_arg(roleid))
  	{
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
new file mode 100644
index 5e69e2b..2800f73
*** a/src/backend/catalog/system_views.sql
--- b/src/backend/catalog/system_views.sql
*************** CREATE VIEW pg_roles AS
*** 13,19 ****
          rolinherit,
          rolcreaterole,
          rolcreatedb,
-         rolcatupdate,
          rolcanlogin,
          rolreplication,
          rolconnlimit,
--- 13,18 ----
*************** CREATE VIEW pg_shadow AS
*** 31,37 ****
          pg_authid.oid AS usesysid,
          rolcreatedb AS usecreatedb,
          rolsuper AS usesuper,
-         rolcatupdate AS usecatupd,
          rolreplication AS userepl,
          rolbypassrls AS usebypassrls,
          rolpassword AS passwd,
--- 30,35 ----
*************** CREATE VIEW pg_user AS
*** 57,63 ****
          usesysid,
          usecreatedb,
          usesuper,
-         usecatupd,
          userepl,
          usebypassrls,
          '********'::text as passwd,
--- 55,60 ----
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
new file mode 100644
index 2210eed..1d3b658
*** a/src/backend/commands/user.c
--- b/src/backend/commands/user.c
*************** CreateRole(CreateRoleStmt *stmt)
*** 368,375 ****
  	new_record[Anum_pg_authid_rolinherit - 1] = BoolGetDatum(inherit);
  	new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole);
  	new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(createdb);
- 	/* superuser gets catupdate right by default */
- 	new_record[Anum_pg_authid_rolcatupdate - 1] = BoolGetDatum(issuper);
  	new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(canlogin);
  	new_record[Anum_pg_authid_rolreplication - 1] = BoolGetDatum(isreplication);
  	new_record[Anum_pg_authid_rolconnlimit - 1] = Int32GetDatum(connlimit);
--- 368,373 ----
*************** AlterRole(AlterRoleStmt *stmt)
*** 734,753 ****
  	MemSet(new_record_repl, false, sizeof(new_record_repl));
  
  	/*
! 	 * issuper/createrole/catupdate/etc
! 	 *
! 	 * XXX It's rather unclear how to handle catupdate.  It's probably best to
! 	 * keep it equal to the superuser status, otherwise you could end up with
! 	 * a situation where no existing superuser can alter the catalogs,
! 	 * including pg_authid!
  	 */
  	if (issuper >= 0)
  	{
  		new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper > 0);
  		new_record_repl[Anum_pg_authid_rolsuper - 1] = true;
- 
- 		new_record[Anum_pg_authid_rolcatupdate - 1] = BoolGetDatum(issuper > 0);
- 		new_record_repl[Anum_pg_authid_rolcatupdate - 1] = true;
  	}
  
  	if (inherit >= 0)
--- 732,743 ----
  	MemSet(new_record_repl, false, sizeof(new_record_repl));
  
  	/*
! 	 * issuper/createrole/etc
  	 */
  	if (issuper >= 0)
  	{
  		new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper > 0);
  		new_record_repl[Anum_pg_authid_rolsuper - 1] = true;
  	}
  
  	if (inherit >= 0)
diff --git a/src/include/catalog/pg_authid.h b/src/include/catalog/pg_authid.h
new file mode 100644
index e01e6aa..f60d08b
*** a/src/include/catalog/pg_authid.h
--- b/src/include/catalog/pg_authid.h
*************** CATALOG(pg_authid,1260) BKI_SHARED_RELAT
*** 49,55 ****
  	bool		rolinherit;		/* inherit privileges from other roles? */
  	bool		rolcreaterole;	/* allowed to create more roles? */
  	bool		rolcreatedb;	/* allowed to create databases? */
- 	bool		rolcatupdate;	/* allowed to alter catalogs manually? */
  	bool		rolcanlogin;	/* allowed to log in as session user? */
  	bool		rolreplication; /* role used for streaming replication */
  	bool		rolbypassrls;	/* allowed to bypass row level security? */
--- 49,54 ----
*************** typedef FormData_pg_authid *Form_pg_auth
*** 74,92 ****
   *		compiler constants for pg_authid
   * ----------------
   */
! #define Natts_pg_authid					12
  #define Anum_pg_authid_rolname			1
  #define Anum_pg_authid_rolsuper			2
  #define Anum_pg_authid_rolinherit		3
  #define Anum_pg_authid_rolcreaterole	4
  #define Anum_pg_authid_rolcreatedb		5
! #define Anum_pg_authid_rolcatupdate		6
! #define Anum_pg_authid_rolcanlogin		7
! #define Anum_pg_authid_rolreplication	8
! #define Anum_pg_authid_rolbypassrls		9
! #define Anum_pg_authid_rolconnlimit		10
! #define Anum_pg_authid_rolpassword		11
! #define Anum_pg_authid_rolvaliduntil	12
  
  /* ----------------
   *		initial contents of pg_authid
--- 73,90 ----
   *		compiler constants for pg_authid
   * ----------------
   */
! #define Natts_pg_authid					11
  #define Anum_pg_authid_rolname			1
  #define Anum_pg_authid_rolsuper			2
  #define Anum_pg_authid_rolinherit		3
  #define Anum_pg_authid_rolcreaterole	4
  #define Anum_pg_authid_rolcreatedb		5
! #define Anum_pg_authid_rolcanlogin		6
! #define Anum_pg_authid_rolreplication	7
! #define Anum_pg_authid_rolbypassrls		8
! #define Anum_pg_authid_rolconnlimit		9
! #define Anum_pg_authid_rolpassword		10
! #define Anum_pg_authid_rolvaliduntil	11
  
  /* ----------------
   *		initial contents of pg_authid
*************** typedef FormData_pg_authid *Form_pg_auth
*** 95,101 ****
   * user choices.
   * ----------------
   */
! DATA(insert OID = 10 ( "POSTGRES" t t t t t t t t -1 _null_ _null_));
  
  #define BOOTSTRAP_SUPERUSERID 10
  
--- 93,99 ----
   * user choices.
   * ----------------
   */
! DATA(insert OID = 10 ( "POSTGRES" t t t t t t t -1 _null_ _null_));
  
  #define BOOTSTRAP_SUPERUSERID 10
  
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
new file mode 100644
index 74b0450..0db1df3
*** a/src/test/regress/expected/privileges.out
--- b/src/test/regress/expected/privileges.out
*************** ERROR:  role "nosuchuser" does not exist
*** 676,682 ****
  select has_table_privilege('pg_authid','sel');
  ERROR:  unrecognized privilege type: "sel"
  select has_table_privilege(-999999,'pg_authid','update');
! ERROR:  role with OID 4293967297 does not exist
  select has_table_privilege(1,'select');
   has_table_privilege 
  ---------------------
--- 676,686 ----
  select has_table_privilege('pg_authid','sel');
  ERROR:  unrecognized privilege type: "sel"
  select has_table_privilege(-999999,'pg_authid','update');
!  has_table_privilege 
! ---------------------
!  f
! (1 row)
! 
  select has_table_privilege(1,'select');
   has_table_privilege 
  ---------------------
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
new file mode 100644
index d50b103..4af4e05
*** a/src/test/regress/expected/rules.out
--- b/src/test/regress/expected/rules.out
*************** pg_roles| SELECT pg_authid.rolname,
*** 1406,1412 ****
      pg_authid.rolinherit,
      pg_authid.rolcreaterole,
      pg_authid.rolcreatedb,
-     pg_authid.rolcatupdate,
      pg_authid.rolcanlogin,
      pg_authid.rolreplication,
      pg_authid.rolconnlimit,
--- 1406,1411 ----
*************** pg_shadow| SELECT pg_authid.rolname AS u
*** 1607,1613 ****
      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.rolbypassrls AS usebypassrls,
      pg_authid.rolpassword AS passwd,
--- 1606,1611 ----
*************** pg_user| SELECT pg_shadow.usename,
*** 2062,2068 ****
      pg_shadow.usesysid,
      pg_shadow.usecreatedb,
      pg_shadow.usesuper,
-     pg_shadow.usecatupd,
      pg_shadow.userepl,
      pg_shadow.usebypassrls,
      '********'::text AS passwd,
--- 2060,2065 ----
