Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6918d90

Browse files
committed
pg_upgrade_ACL_check_v9.patch
1 parent350f477 commit6918d90

File tree

3 files changed

+374
-0
lines changed

3 files changed

+374
-0
lines changed

‎src/bin/pg_upgrade/check.c

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
staticvoidcheck_new_cluster_is_empty(void);
1818
staticvoidcheck_databases_are_compatible(void);
19+
staticvoidcheck_for_changed_signatures(void);
1920
staticvoidcheck_locale_and_encoding(DbInfo*olddb,DbInfo*newdb);
2021
staticboolequivalent_locale(intcategory,constchar*loca,constchar*locb);
2122
staticvoidcheck_is_install_user(ClusterInfo*cluster);
@@ -142,6 +143,8 @@ check_and_dump_old_cluster(bool live_check)
142143
if (GET_MAJOR_VERSION(old_cluster.major_version) <=804)
143144
new_9_0_populate_pg_largeobject_metadata(&old_cluster, true);
144145

146+
get_non_default_acl_infos(&old_cluster);
147+
145148
/*
146149
* While not a check option, we do this now because this is the only time
147150
* the old server is running.
@@ -161,6 +164,7 @@ check_new_cluster(void)
161164

162165
check_new_cluster_is_empty();
163166
check_databases_are_compatible();
167+
check_for_changed_signatures();
164168

165169
check_loadable_libraries();
166170

@@ -443,6 +447,223 @@ check_databases_are_compatible(void)
443447
}
444448
}
445449

450+
/*
451+
* Find the location of the last dot, return NULL if not found.
452+
*/
453+
staticchar*
454+
last_dot_location(constchar*identity)
455+
{
456+
constchar*p,
457+
*ret=NULL;
458+
459+
for (p=identity;*p;p++)
460+
if (*p=='.')
461+
ret=p;
462+
returnunconstify(char*,ret);
463+
}
464+
465+
/*
466+
* check_for_changed_signatures()
467+
*
468+
* Check that the old cluster doesn't have non-default ACL's for system objects
469+
* (relations, attributes, functions and procedures) which have different
470+
* signatures in the new cluster. Otherwise generate revoke_objects.sql.
471+
*/
472+
staticvoid
473+
check_for_changed_signatures(void)
474+
{
475+
PGconn*conn;
476+
charsubquery[QUERY_ALLOC];
477+
PGresult*res;
478+
intntups;
479+
inti_obj_ident;
480+
intdbnum;
481+
boolneed_check= false;
482+
FILE*script=NULL;
483+
boolfound_changed= false;
484+
charoutput_path[MAXPGPATH];
485+
486+
prep_status("Checking for system objects with non-default ACL");
487+
488+
for (dbnum=0;dbnum<old_cluster.dbarr.ndbs;dbnum++)
489+
if (old_cluster.dbarr.dbs[dbnum].non_def_acl_arr.nacls>0)
490+
{
491+
need_check= true;
492+
break;
493+
}
494+
/*
495+
* The old cluster doesn't have system objects with non-default ACL so
496+
* quickly exit.
497+
*/
498+
if (!need_check)
499+
{
500+
check_ok();
501+
return;
502+
}
503+
504+
snprintf(output_path,sizeof(output_path),"revoke_objects.sql");
505+
506+
snprintf(subquery,sizeof(subquery),
507+
/* Get system relations which created in pg_catalog */
508+
"SELECT 'pg_class'::regclass classid, oid objid, 0 objsubid "
509+
"FROM pg_catalog.pg_class "
510+
"WHERE relnamespace = 'pg_catalog'::regnamespace "
511+
"UNION ALL "
512+
/* Get system relations attributes which created in pg_catalog */
513+
"SELECT 'pg_class'::regclass, att.attrelid, att.attnum "
514+
"FROM pg_catalog.pg_class rel "
515+
"INNER JOIN pg_catalog.pg_attribute att ON rel.oid = att.attrelid "
516+
"WHERE rel.relnamespace = 'pg_catalog'::regnamespace "
517+
"UNION ALL "
518+
/* Get system functions and procedure which created in pg_catalog */
519+
"SELECT 'pg_proc'::regclass, oid, 0 "
520+
"FROM pg_catalog.pg_proc "
521+
"WHERE pronamespace = 'pg_catalog'::regnamespace ");
522+
523+
conn=connectToServer(&new_cluster,"template1");
524+
res=executeQueryOrDie(conn,
525+
"SELECT ident.type, ident.identity "
526+
"FROM (%s) obj, "
527+
"LATERAL pg_catalog.pg_identify_object("
528+
" obj.classid, obj.objid, obj.objsubid) ident "
529+
/*
530+
* Don't rely on database collation, since we use strcmp
531+
* comparison to find non-default ACLs.
532+
*/
533+
"ORDER BY ident.identity COLLATE \"C\";",subquery);
534+
ntups=PQntuples(res);
535+
536+
i_obj_ident=PQfnumber(res,"identity");
537+
538+
for (dbnum=0;dbnum<old_cluster.dbarr.ndbs;dbnum++)
539+
{
540+
DbInfo*dbinfo=&old_cluster.dbarr.dbs[dbnum];
541+
booldb_used= false;
542+
intaclnum=0,
543+
objnum=0;
544+
545+
/*
546+
* For every database check system objects with non-default ACL.
547+
*
548+
* AclInfo array is sorted by obj_ident. This allows us to compare
549+
* AclInfo entries with the query result above efficiently.
550+
*/
551+
for (aclnum=0;aclnum<dbinfo->non_def_acl_arr.nacls;aclnum++)
552+
{
553+
AclInfo*aclinfo=&dbinfo->non_def_acl_arr.aclinfos[aclnum];
554+
boolreport= false;
555+
556+
while (objnum<ntups)
557+
{
558+
intret;
559+
560+
ret=strcmp(aclinfo->obj_ident,
561+
PQgetvalue(res,objnum,i_obj_ident));
562+
563+
/*
564+
* The new cluster doesn't have an object with same identity,
565+
* exit the loop, report below and check next object.
566+
*/
567+
if (ret<0)
568+
{
569+
report= true;
570+
break;
571+
}
572+
/*
573+
* The new cluster has an object with same identity, just exit
574+
* the loop.
575+
*/
576+
elseif (ret==0)
577+
{
578+
objnum++;
579+
break;
580+
}
581+
else
582+
objnum++;
583+
}
584+
585+
if (report)
586+
{
587+
found_changed= true;
588+
if (script==NULL&& (script=fopen_priv(output_path,"w"))==NULL)
589+
pg_fatal("could not open file \"%s\": %s\n",
590+
output_path,strerror(errno));
591+
if (!db_used)
592+
{
593+
PQExpBufferDataconn_buf;
594+
595+
initPQExpBuffer(&conn_buf);
596+
appendPsqlMetaConnect(&conn_buf,dbinfo->db_name);
597+
fputs(conn_buf.data,script);
598+
termPQExpBuffer(&conn_buf);
599+
600+
db_used= true;
601+
}
602+
603+
/* Handle columns separately */
604+
if (strstr(aclinfo->obj_type,"column")!=NULL)
605+
{
606+
char*pdot=last_dot_location(aclinfo->obj_ident);
607+
PQExpBufferDataident_buf;
608+
609+
if (pdot==NULL||*(pdot+1)=='\0')
610+
pg_fatal("invalid column identity \"%s\"",
611+
aclinfo->obj_ident);
612+
613+
initPQExpBuffer(&ident_buf);
614+
appendBinaryPQExpBuffer(&ident_buf,aclinfo->obj_ident,
615+
pdot-aclinfo->obj_ident);
616+
617+
fprintf(script,"REVOKE ALL (%s) ON %s FROM %s;\n",
618+
/* pg_identify_object() quotes identity if necessary */
619+
pdot+1,ident_buf.data,
620+
/* role_names is already quoted */
621+
aclinfo->role_names);
622+
termPQExpBuffer(&ident_buf);
623+
}
624+
/*
625+
* For relations except sequences we don't need to specify
626+
* the object type.
627+
*/
628+
elseif (aclinfo->is_relation&&
629+
strcmp(aclinfo->obj_type,"sequence")!=0)
630+
fprintf(script,"REVOKE ALL ON %s FROM %s;\n",
631+
/* pg_identify_object() quotes identity if necessary */
632+
aclinfo->obj_ident,
633+
/* role_names is already quoted */
634+
aclinfo->role_names);
635+
/* Other object types */
636+
else
637+
fprintf(script,"REVOKE ALL ON %s %s FROM %s;\n",
638+
aclinfo->obj_type,
639+
/* pg_identify_object() quotes identity if necessary */
640+
aclinfo->obj_ident,
641+
/* role_names is already quoted */
642+
aclinfo->role_names);
643+
}
644+
}
645+
}
646+
647+
PQclear(res);
648+
PQfinish(conn);
649+
650+
if (script)
651+
fclose(script);
652+
653+
if (found_changed)
654+
{
655+
pg_log(PG_REPORT,"fatal\n");
656+
pg_fatal("Your installation contains non-default privileges for system objects\n"
657+
"for which the API has changed. To perform the upgrade, reset these\n"
658+
"privileges to default. The file\n"
659+
" %s\n"
660+
"when executed by psql will revoke non-default privileges for those objects.\n\n",
661+
output_path);
662+
}
663+
else
664+
check_ok();
665+
}
666+
446667

447668
/*
448669
* create_script_for_cluster_analyze()

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp