diff options
Diffstat (limited to 'src/bin/pg_dump/dumputils.c')
-rw-r--r-- | src/bin/pg_dump/dumputils.c | 78 |
1 files changed, 63 insertions, 15 deletions
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c index 8037c1d7e16..a9a27625707 100644 --- a/src/bin/pg_dump/dumputils.c +++ b/src/bin/pg_dump/dumputils.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.48 2009/08/04 21:56:08 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.49 2009/10/05 19:24:45 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -490,18 +490,22 @@ parsePGArray(const char *atext, char ***itemarray, int *nitems) * acls: the ACL string fetched from the database * owner: username of object owner (will be passed through fmtId); can be * NULL or empty string to indicate "no owner known" + * prefix: string to prefix to each generated command; typically empty * remoteVersion: version of database * * Returns TRUE if okay, FALSE if could not parse the acl string. * The resulting commands (if any) are appended to the contents of 'sql'. * + * Note: when processing a default ACL, prefix is "ALTER DEFAULT PRIVILEGES " + * or something similar, and name is an empty string. + * * Note: beware of passing a fmtId() result directly as 'name' or 'subname', * since this routine uses fmtId() internally. */ bool buildACLCommands(const char *name, const char *subname, const char *type, const char *acls, const char *owner, - int remoteVersion, + const char *prefix, int remoteVersion, PQExpBuffer sql) { char **aclitems; @@ -549,7 +553,7 @@ buildACLCommands(const char *name, const char *subname, * wire-in knowledge about the default public privileges for different * kinds of objects. */ - appendPQExpBuffer(firstsql, "REVOKE ALL"); + appendPQExpBuffer(firstsql, "%sREVOKE ALL", prefix); if (subname) appendPQExpBuffer(firstsql, "(%s)", subname); appendPQExpBuffer(firstsql, " ON %s %s FROM PUBLIC;\n", type, name); @@ -564,8 +568,8 @@ buildACLCommands(const char *name, const char *subname, if (remoteVersion < 80200 && strcmp(type, "DATABASE") == 0) { /* database CONNECT priv didn't exist before 8.2 */ - appendPQExpBuffer(firstsql, "GRANT CONNECT ON %s %s TO PUBLIC;\n", - type, name); + appendPQExpBuffer(firstsql, "%sGRANT CONNECT ON %s %s TO PUBLIC;\n", + prefix, type, name); } /* Scan individual ACL items */ @@ -594,20 +598,20 @@ buildACLCommands(const char *name, const char *subname, ? strcmp(privswgo->data, "ALL") != 0 : strcmp(privs->data, "ALL") != 0) { - appendPQExpBuffer(firstsql, "REVOKE ALL"); + appendPQExpBuffer(firstsql, "%sREVOKE ALL", prefix); if (subname) appendPQExpBuffer(firstsql, "(%s)", subname); appendPQExpBuffer(firstsql, " ON %s %s FROM %s;\n", type, name, fmtId(grantee->data)); if (privs->len > 0) appendPQExpBuffer(firstsql, - "GRANT %s ON %s %s TO %s;\n", - privs->data, type, name, + "%sGRANT %s ON %s %s TO %s;\n", + prefix, privs->data, type, name, fmtId(grantee->data)); if (privswgo->len > 0) appendPQExpBuffer(firstsql, - "GRANT %s ON %s %s TO %s WITH GRANT OPTION;\n", - privswgo->data, type, name, + "%sGRANT %s ON %s %s TO %s WITH GRANT OPTION;\n", + prefix, privswgo->data, type, name, fmtId(grantee->data)); } } @@ -623,8 +627,8 @@ buildACLCommands(const char *name, const char *subname, if (privs->len > 0) { - appendPQExpBuffer(secondsql, "GRANT %s ON %s %s TO ", - privs->data, type, name); + appendPQExpBuffer(secondsql, "%sGRANT %s ON %s %s TO ", + prefix, privs->data, type, name); if (grantee->len == 0) appendPQExpBuffer(secondsql, "PUBLIC;\n"); else if (strncmp(grantee->data, "group ", @@ -636,8 +640,8 @@ buildACLCommands(const char *name, const char *subname, } if (privswgo->len > 0) { - appendPQExpBuffer(secondsql, "GRANT %s ON %s %s TO ", - privswgo->data, type, name); + appendPQExpBuffer(secondsql, "%sGRANT %s ON %s %s TO ", + prefix, privswgo->data, type, name); if (grantee->len == 0) appendPQExpBuffer(secondsql, "PUBLIC"); else if (strncmp(grantee->data, "group ", @@ -661,7 +665,7 @@ buildACLCommands(const char *name, const char *subname, */ if (!found_owner_privs && owner) { - appendPQExpBuffer(firstsql, "REVOKE ALL"); + appendPQExpBuffer(firstsql, "%sREVOKE ALL", prefix); if (subname) appendPQExpBuffer(firstsql, "(%s)", subname); appendPQExpBuffer(firstsql, " ON %s %s FROM %s;\n", @@ -683,6 +687,50 @@ buildACLCommands(const char *name, const char *subname, } /* + * Build ALTER DEFAULT PRIVILEGES command(s) for single pg_default_acl entry. + * + * type: the object type (as seen in GRANT command) + * nspname: schema name, or NULL for global default privileges + * acls: the ACL string fetched from the database + * owner: username of privileges owner (will be passed through fmtId) + * remoteVersion: version of database + * + * Returns TRUE if okay, FALSE if could not parse the acl string. + * The resulting commands (if any) are appended to the contents of 'sql'. + */ +bool +buildDefaultACLCommands(const char *type, const char *nspname, + const char *acls, const char *owner, + int remoteVersion, + PQExpBuffer sql) +{ + bool result; + PQExpBuffer prefix; + + prefix = createPQExpBuffer(); + + /* + * We incorporate the target role directly into the command, rather than + * playing around with SET ROLE or anything like that. This is so that + * a permissions error leads to nothing happening, rather than + * changing default privileges for the wrong user. + */ + appendPQExpBuffer(prefix, "ALTER DEFAULT PRIVILEGES FOR ROLE %s ", + fmtId(owner)); + if (nspname) + appendPQExpBuffer(prefix, "IN SCHEMA %s ", fmtId(nspname)); + + result = buildACLCommands("", NULL, + type, acls, owner, + prefix->data, remoteVersion, + sql); + + destroyPQExpBuffer(prefix); + + return result; +} + +/* * This will parse an aclitem string, having the general form * username=privilegecodes/grantor * or |