mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Make dumpACL behave more reasonably for case where owner has revoked
some of his own privileges.
This commit is contained in:
		@@ -22,7 +22,7 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * IDENTIFICATION
 | 
					 * IDENTIFICATION
 | 
				
			||||||
 *	  $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.257 2002/04/29 17:30:18 tgl Exp $
 | 
					 *	  $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.258 2002/05/06 18:33:45 tgl Exp $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *-------------------------------------------------------------------------
 | 
					 *-------------------------------------------------------------------------
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -79,7 +79,7 @@ static void dumpComment(Archive *fout, const char *target, const char *oid,
 | 
				
			|||||||
			const char *((*deps)[]));
 | 
								const char *((*deps)[]));
 | 
				
			||||||
static void dumpOneDomain(Archive *fout, TypeInfo *tinfo);
 | 
					static void dumpOneDomain(Archive *fout, TypeInfo *tinfo);
 | 
				
			||||||
static void dumpSequence(Archive *fout, TableInfo tbinfo, const bool schemaOnly, const bool dataOnly);
 | 
					static void dumpSequence(Archive *fout, TableInfo tbinfo, const bool schemaOnly, const bool dataOnly);
 | 
				
			||||||
static void dumpACL(Archive *fout, TableInfo tbinfo);
 | 
					static void dumpACL(Archive *fout, TableInfo *tbinfo);
 | 
				
			||||||
static void dumpTriggers(Archive *fout, const char *tablename,
 | 
					static void dumpTriggers(Archive *fout, const char *tablename,
 | 
				
			||||||
			 TableInfo *tblinfo, int numTables);
 | 
								 TableInfo *tblinfo, int numTables);
 | 
				
			||||||
static void dumpRules(Archive *fout, const char *tablename,
 | 
					static void dumpRules(Archive *fout, const char *tablename,
 | 
				
			||||||
@@ -4129,58 +4129,27 @@ GetPrivileges(Archive *AH, const char *s)
 | 
				
			|||||||
		return strdup(aclbuf);
 | 
							return strdup(aclbuf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * The name says it all; a function to append a string if the dest
 | 
					 | 
				
			||||||
 * is big enough. If not, it does a realloc.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
strcatalloc(char **dest, int *dSize, char *src)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int			dLen = strlen(*dest);
 | 
					 | 
				
			||||||
	int			sLen = strlen(src);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((dLen + sLen) >= *dSize)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		*dSize = (dLen + sLen) * 2;
 | 
					 | 
				
			||||||
		*dest = realloc(*dest, *dSize);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	strcpy(*dest + dLen, src);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * dumpACL:
 | 
					 * dumpACL:
 | 
				
			||||||
 *	  Write out grant/revoke information
 | 
					 *	  Write out grant/revoke information for a table, view or sequence
 | 
				
			||||||
 *	  Called for sequences and tables
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
dumpACL(Archive *fout, TableInfo tbinfo)
 | 
					dumpACL(Archive *fout, TableInfo *tbinfo)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *acls = tbinfo.relacl;
 | 
						const char *acls = tbinfo->relacl;
 | 
				
			||||||
	char	   *aclbuf,
 | 
						char	   *aclbuf,
 | 
				
			||||||
			   *tok,
 | 
								   *tok,
 | 
				
			||||||
			   *eqpos,
 | 
								   *eqpos,
 | 
				
			||||||
			   *priv;
 | 
								   *priv;
 | 
				
			||||||
	char	   *objoid;
 | 
						char	   *objoid;
 | 
				
			||||||
	char	   *sql;
 | 
						PQExpBuffer sql;
 | 
				
			||||||
	char		tmp[1024];
 | 
						bool		found_owner_privs = false;
 | 
				
			||||||
	int			sSize = 4096;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (strlen(acls) == 0)
 | 
						if (strlen(acls) == 0)
 | 
				
			||||||
		return;					/* table has default permissions */
 | 
							return;					/* table has default permissions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						sql = createPQExpBuffer();
 | 
				
			||||||
	 * Allocate a larginsh buffer for the output SQL.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	sql = (char *) malloc(sSize);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Revoke Default permissions for PUBLIC. Is this actually necessary,
 | 
					 | 
				
			||||||
	 * or is it just a waste of time?
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	sprintf(sql, "REVOKE ALL on %s from PUBLIC;\n",
 | 
					 | 
				
			||||||
			fmtId(tbinfo.relname, force_quotes));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Make a working copy of acls so we can use strtok */
 | 
						/* Make a working copy of acls so we can use strtok */
 | 
				
			||||||
	aclbuf = strdup(acls);
 | 
						aclbuf = strdup(acls);
 | 
				
			||||||
@@ -4202,9 +4171,10 @@ dumpACL(Archive *fout, TableInfo tbinfo)
 | 
				
			|||||||
		if (!eqpos)
 | 
							if (!eqpos)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			write_msg(NULL, "could not parse ACL list ('%s') for relation %s\n",
 | 
								write_msg(NULL, "could not parse ACL list ('%s') for relation %s\n",
 | 
				
			||||||
					  acls, tbinfo.relname);
 | 
										  acls, tbinfo->relname);
 | 
				
			||||||
			exit_nicely();
 | 
								exit_nicely();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							*eqpos = '\0';			/* it's ok to clobber aclbuf */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * Parse the privileges (right-hand side).	Skip if there are
 | 
							 * Parse the privileges (right-hand side).	Skip if there are
 | 
				
			||||||
@@ -4213,41 +4183,69 @@ dumpACL(Archive *fout, TableInfo tbinfo)
 | 
				
			|||||||
		priv = GetPrivileges(fout, eqpos + 1);
 | 
							priv = GetPrivileges(fout, eqpos + 1);
 | 
				
			||||||
		if (*priv)
 | 
							if (*priv)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			sprintf(tmp, "GRANT %s on %s to ",
 | 
								if (strcmp(tok, tbinfo->usename) == 0)
 | 
				
			||||||
					priv, fmtId(tbinfo.relname, force_quotes));
 | 
					 | 
				
			||||||
			strcatalloc(&sql, &sSize, tmp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			/*
 | 
					 | 
				
			||||||
			 * Note: fmtId() can only be called once per printf, so don't
 | 
					 | 
				
			||||||
			 * try to merge printing of username into the above printf.
 | 
					 | 
				
			||||||
			 */
 | 
					 | 
				
			||||||
			if (eqpos == tok)
 | 
					 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				/* Empty left-hand side means "PUBLIC" */
 | 
									/*
 | 
				
			||||||
				strcatalloc(&sql, &sSize, "PUBLIC;\n");
 | 
									 * For the owner, the default privilege level is ALL.
 | 
				
			||||||
 | 
									 */
 | 
				
			||||||
 | 
									found_owner_privs = true;
 | 
				
			||||||
 | 
									if (strcmp(priv, "ALL") != 0)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										/* NB: only one fmtId per appendPQExpBuffer! */
 | 
				
			||||||
 | 
										appendPQExpBuffer(sql, "REVOKE ALL ON %s FROM ",
 | 
				
			||||||
 | 
														  fmtId(tbinfo->relname, force_quotes));
 | 
				
			||||||
 | 
										appendPQExpBuffer(sql, "%s;\n", fmtId(tok, force_quotes));
 | 
				
			||||||
 | 
										appendPQExpBuffer(sql, "GRANT %s ON %s TO ",
 | 
				
			||||||
 | 
														  priv,
 | 
				
			||||||
 | 
														  fmtId(tbinfo->relname, force_quotes));
 | 
				
			||||||
 | 
										appendPQExpBuffer(sql, "%s;\n", fmtId(tok, force_quotes));
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				*eqpos = '\0';	/* it's ok to clobber aclbuf */
 | 
									/*
 | 
				
			||||||
				if (strncmp(tok, "group ", strlen("group ")) == 0)
 | 
									 * Otherwise can assume we are starting from no privs.
 | 
				
			||||||
					sprintf(tmp, "GROUP %s;\n",
 | 
									 */
 | 
				
			||||||
							fmtId(tok + strlen("group "), force_quotes));
 | 
									appendPQExpBuffer(sql, "GRANT %s ON %s TO ",
 | 
				
			||||||
 | 
													  priv,
 | 
				
			||||||
 | 
													  fmtId(tbinfo->relname, force_quotes));
 | 
				
			||||||
 | 
									if (eqpos == tok)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										/* Empty left-hand side means "PUBLIC" */
 | 
				
			||||||
 | 
										appendPQExpBuffer(sql, "PUBLIC;\n");
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else if (strncmp(tok, "group ", strlen("group ")) == 0)
 | 
				
			||||||
 | 
										appendPQExpBuffer(sql, "GROUP %s;\n",
 | 
				
			||||||
 | 
														  fmtId(tok + strlen("group "),
 | 
				
			||||||
 | 
																force_quotes));
 | 
				
			||||||
				else
 | 
									else
 | 
				
			||||||
					sprintf(tmp, "%s;\n", fmtId(tok, force_quotes));
 | 
										appendPQExpBuffer(sql, "%s;\n", fmtId(tok, force_quotes));
 | 
				
			||||||
				strcatalloc(&sql, &sSize, tmp);
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		free(priv);
 | 
							free(priv);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * If we didn't find any owner privs, the owner must have revoked 'em all
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (!found_owner_privs && *tbinfo->usename)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							appendPQExpBuffer(sql, "REVOKE ALL ON %s FROM ",
 | 
				
			||||||
 | 
											  fmtId(tbinfo->relname, force_quotes));
 | 
				
			||||||
 | 
							appendPQExpBuffer(sql, "%s;\n", fmtId(tbinfo->usename, force_quotes));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(aclbuf);
 | 
						free(aclbuf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (tbinfo.viewdef != NULL)
 | 
						if (tbinfo->viewdef != NULL)
 | 
				
			||||||
		objoid = tbinfo.viewoid;
 | 
							objoid = tbinfo->viewoid;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		objoid = tbinfo.oid;
 | 
							objoid = tbinfo->oid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ArchiveEntry(fout, objoid, tbinfo.relname, "ACL", NULL, sql, "", "", "", NULL, NULL);
 | 
						ArchiveEntry(fout, objoid, tbinfo->relname, "ACL",
 | 
				
			||||||
 | 
									 NULL, sql->data, "", "", "", NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						destroyPQExpBuffer(sql);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@@ -4350,7 +4348,7 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
 | 
				
			|||||||
			/* becomeUser(fout, tblinfo[i].usename); */
 | 
								/* becomeUser(fout, tblinfo[i].usename); */
 | 
				
			||||||
			dumpSequence(fout, tblinfo[i], schemaOnly, dataOnly);
 | 
								dumpSequence(fout, tblinfo[i], schemaOnly, dataOnly);
 | 
				
			||||||
			if (!aclsSkip)
 | 
								if (!aclsSkip)
 | 
				
			||||||
				dumpACL(fout, tblinfo[i]);
 | 
									dumpACL(fout, &tblinfo[i]);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (serialSeq)
 | 
						if (serialSeq)
 | 
				
			||||||
@@ -4486,7 +4484,7 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
 | 
				
			|||||||
							 NULL, NULL);
 | 
												 NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (!aclsSkip)
 | 
									if (!aclsSkip)
 | 
				
			||||||
					dumpACL(fout, tblinfo[i]);
 | 
										dumpACL(fout, &tblinfo[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user