]> granicus.if.org Git - postgresql/commitdiff
Fix grant option dumping and related cross-version compatibility issues.
authorPeter Eisentraut <peter_e@gmx.net>
Thu, 24 Jul 2003 15:52:53 +0000 (15:52 +0000)
committerPeter Eisentraut <peter_e@gmx.net>
Thu, 24 Jul 2003 15:52:53 +0000 (15:52 +0000)
src/bin/pg_dump/dumputils.c

index 6b8bafdb32c79079453055fd3440ca46e58b79cd..7d2f79d1e0cef7af2bd298930db46af9938e07b0 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Header: /cvsroot/pgsql/src/bin/pg_dump/dumputils.c,v 1.4 2003/05/30 22:55:15 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/dumputils.c,v 1.5 2003/07/24 15:52:53 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -24,6 +24,7 @@ static bool parseAclItem(const char *item, const char *type, const char *name,
                                                 PQExpBuffer grantee, PQExpBuffer grantor,
                                                 PQExpBuffer privs, PQExpBuffer privswgo);
 static void AddAcl(PQExpBuffer aclbuf, const char *keyword);
+#define supports_grant_options(version) ((version) >= 70400)
 
 
 /*
@@ -187,6 +188,7 @@ buildACLCommands(const char *name, const char *type,
        char       *aclbuf,
                           *tok;
        PQExpBuffer grantee, grantor, privs, privswgo;
+       PQExpBuffer     firstsql, secondsql;
        bool            found_owner_privs = false;
 
        if (strlen(acls) == 0)
@@ -196,13 +198,23 @@ buildACLCommands(const char *name, const char *type,
        grantor = createPQExpBuffer();
        privs = createPQExpBuffer();
        privswgo = createPQExpBuffer();
+       /*
+        * At the end, these two will be pasted together to form the
+        * result.  But the owner privileges need to go before the other
+        * ones to keep the dependencies valid.  In recent versions this
+        * is normally the case, but in old versions they come after the
+        * PUBLIC privileges and that results in problems if we need to
+        * run REVOKE on the owner privileges.
+        */
+       firstsql = createPQExpBuffer();
+       secondsql = createPQExpBuffer();
 
        /*
         * Always start with REVOKE ALL FROM PUBLIC, so that we don't have to
         * wire-in knowledge about the default public privileges for different
         * kinds of objects.
         */
-       appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM PUBLIC;\n",
+       appendPQExpBuffer(firstsql, "REVOKE ALL ON %s %s FROM PUBLIC;\n",
                                          type, name);
 
        /* Make a working copy of acls so we can use strtok */
@@ -234,24 +246,28 @@ buildACLCommands(const char *name, const char *type,
 
                if (privs->len > 0 || privswgo->len > 0)
                {
-                       if (owner && strcmp(grantee->data, owner) == 0)
+                       if (owner
+                               && strcmp(grantee->data, owner) == 0
+                               && strcmp(grantor->data, owner) == 0)
                        {
+                               found_owner_privs = true;
                                /*
-                                * For the owner, the default privilege level is
-                                * ALL WITH GRANT OPTION.
+                                * For the owner, the default privilege level is ALL
+                                * WITH GRANT OPTION (only ALL prior to 7.4).
                                 */
-                               found_owner_privs = true;
-                               if (strcmp(privswgo->data, "ALL") != 0)
+                               if (supports_grant_options(remoteVersion)
+                                       ? strcmp(privswgo->data, "ALL") != 0
+                                       : strcmp(privs->data, "ALL") != 0)
                                {
-                                       appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM %s;\n",
+                                       appendPQExpBuffer(firstsql, "REVOKE ALL ON %s %s FROM %s;\n",
                                                                          type, name,
                                                                          fmtId(grantee->data));
                                        if (privs->len > 0)
-                                               appendPQExpBuffer(sql, "GRANT %s ON %s %s TO %s;\n",
+                                               appendPQExpBuffer(firstsql, "GRANT %s ON %s %s TO %s;\n",
                                                                                  privs->data, type, name,
                                                                                  fmtId(grantee->data));
                                        if (privswgo->len > 0)
-                                               appendPQExpBuffer(sql, "GRANT %s ON %s %s TO %s WITH GRANT OPTION;\n",
+                                               appendPQExpBuffer(firstsql, "GRANT %s ON %s %s TO %s WITH GRANT OPTION;\n",
                                                                                  privswgo->data, type, name,
                                                                                  fmtId(grantee->data));
                                }
@@ -261,48 +277,44 @@ buildACLCommands(const char *name, const char *type,
                                /*
                                 * Otherwise can assume we are starting from no privs.
                                 */
+                               if (grantor->len > 0
+                                       && (!owner || strcmp(owner, grantor->data) != 0))
+                                       appendPQExpBuffer(secondsql, "SET SESSION AUTHORIZATION %s;\n",
+                                                                         fmtId(grantor->data));
+
                                if (privs->len > 0)
                                {
-                                       appendPQExpBuffer(sql, "GRANT %s ON %s %s TO ",
+                                       appendPQExpBuffer(secondsql, "GRANT %s ON %s %s TO ",
                                                                          privs->data, type, name);
                                        if (grantee->len == 0)
-                                               appendPQExpBuffer(sql, "PUBLIC;\n");
+                                               appendPQExpBuffer(secondsql, "PUBLIC;\n");
                                        else if (strncmp(grantee->data, "group ",
                                                                         strlen("group ")) == 0)
-                                               appendPQExpBuffer(sql, "GROUP %s;\n",
+                                               appendPQExpBuffer(secondsql, "GROUP %s;\n",
                                                                                  fmtId(grantee->data + strlen("group ")));
                                        else
-                                               appendPQExpBuffer(sql, "%s;\n", fmtId(grantee->data));
+                                               appendPQExpBuffer(secondsql, "%s;\n", fmtId(grantee->data));
                                }
                                if (privswgo->len > 0)
                                {
-                                       appendPQExpBuffer(sql, "GRANT %s ON %s %s TO ",
+                                       appendPQExpBuffer(secondsql, "GRANT %s ON %s %s TO ",
                                                                          privswgo->data, type, name);
                                        if (grantee->len == 0)
-                                               appendPQExpBuffer(sql, "PUBLIC");
+                                               appendPQExpBuffer(secondsql, "PUBLIC");
                                        else if (strncmp(grantee->data, "group ",
                                                                         strlen("group ")) == 0)
-                                               appendPQExpBuffer(sql, "GROUP %s",
+                                               appendPQExpBuffer(secondsql, "GROUP %s",
                                                                                  fmtId(grantee->data + strlen("group ")));
                                        else
-                                               appendPQExpBuffer(sql, "%s", fmtId(grantee->data));
-                                       appendPQExpBuffer(sql, " WITH GRANT OPTION;\n");
+                                               appendPQExpBuffer(secondsql, "%s", fmtId(grantee->data));
+                                       appendPQExpBuffer(secondsql, " WITH GRANT OPTION;\n");
                                }
+
+                               if (grantor->len > 0
+                                       && (!owner || strcmp(owner, grantor->data) != 0))
+                                       appendPQExpBuffer(secondsql, "RESET SESSION AUTHORIZATION;\n");
                        }
                }
-               else
-               {
-                       /* No privileges.  Issue explicit REVOKE for safety. */
-                       if (grantee->len == 0)
-                               ; /* Empty left-hand side means "PUBLIC"; already did it */
-                       else if (strncmp(grantee->data, "group ", strlen("group ")) == 0)
-                               appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM GROUP %s;\n",
-                                                                 type, name,
-                                                                 fmtId(grantee->data + strlen("group ")));
-                       else
-                               appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM %s;\n",
-                                                                 type, name, fmtId(grantee->data));
-               }
        }
 
        /*
@@ -311,7 +323,7 @@ buildACLCommands(const char *name, const char *type,
         */
        if (!found_owner_privs && owner)
        {
-               appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM %s;\n",
+               appendPQExpBuffer(firstsql, "REVOKE ALL ON %s %s FROM %s;\n",
                                                  type, name, fmtId(owner));
        }
 
@@ -321,6 +333,10 @@ buildACLCommands(const char *name, const char *type,
        destroyPQExpBuffer(privs);
        destroyPQExpBuffer(privswgo);
 
+       appendPQExpBuffer(sql, "%s%s", firstsql->data, secondsql->data);
+       destroyPQExpBuffer(firstsql);
+       destroyPQExpBuffer(secondsql);
+
        return true;
 }