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

Commitb5eebc1

Browse files
committed
Centralize code for interpreting schema references, which had gotten
copied more places than I first thought it would. This fixes a bug:a couple of these places were neglecting to enforce USAGE access onexplicitly-referenced schemas.
1 parent7b970bc commitb5eebc1

File tree

6 files changed

+99
-223
lines changed

6 files changed

+99
-223
lines changed

‎src/backend/catalog/namespace.c

Lines changed: 69 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
1515
* IDENTIFICATION
16-
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.26 2002/07/20 05:16:56 momjian Exp $
16+
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.27 2002/07/29 23:46:35 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -164,18 +164,7 @@ RangeVarGetRelid(const RangeVar *relation, bool failOK)
164164
if (relation->schemaname)
165165
{
166166
/* use exact schema given */
167-
AclResultaclresult;
168-
169-
namespaceId=GetSysCacheOid(NAMESPACENAME,
170-
CStringGetDatum(relation->schemaname),
171-
0,0,0);
172-
if (!OidIsValid(namespaceId))
173-
elog(ERROR,"Namespace \"%s\" does not exist",
174-
relation->schemaname);
175-
aclresult=pg_namespace_aclcheck(namespaceId,GetUserId(),ACL_USAGE);
176-
if (aclresult!=ACLCHECK_OK)
177-
aclcheck_error(aclresult,relation->schemaname);
178-
167+
namespaceId=LookupExplicitNamespace(relation->schemaname);
179168
relId=get_relname_relid(relation->relname,namespaceId);
180169
}
181170
else
@@ -239,6 +228,7 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation)
239228
if (!OidIsValid(namespaceId))
240229
elog(ERROR,"Namespace \"%s\" does not exist",
241230
newRelation->schemaname);
231+
/* we do not check for USAGE rights here! */
242232
}
243233
else
244234
{
@@ -431,53 +421,19 @@ FuncCandidateList
431421
FuncnameGetCandidates(List*names,intnargs)
432422
{
433423
FuncCandidateListresultList=NULL;
434-
char*catalogname;
435-
char*schemaname=NULL;
436-
char*funcname=NULL;
424+
char*schemaname;
425+
char*funcname;
437426
OidnamespaceId;
438427
CatCList*catlist;
439428
inti;
440429

441430
/* deconstruct the name list */
442-
switch (length(names))
443-
{
444-
case1:
445-
funcname=strVal(lfirst(names));
446-
break;
447-
case2:
448-
schemaname=strVal(lfirst(names));
449-
funcname=strVal(lsecond(names));
450-
break;
451-
case3:
452-
catalogname=strVal(lfirst(names));
453-
schemaname=strVal(lsecond(names));
454-
funcname=strVal(lfirst(lnext(lnext(names))));
455-
/*
456-
* We check the catalog name and then ignore it.
457-
*/
458-
if (strcmp(catalogname,DatabaseName)!=0)
459-
elog(ERROR,"Cross-database references are not implemented");
460-
break;
461-
default:
462-
elog(ERROR,"Improper qualified name (too many dotted names): %s",
463-
NameListToString(names));
464-
break;
465-
}
431+
DeconstructQualifiedName(names,&schemaname,&funcname);
466432

467433
if (schemaname)
468434
{
469435
/* use exact schema given */
470-
AclResultaclresult;
471-
472-
namespaceId=GetSysCacheOid(NAMESPACENAME,
473-
CStringGetDatum(schemaname),
474-
0,0,0);
475-
if (!OidIsValid(namespaceId))
476-
elog(ERROR,"Namespace \"%s\" does not exist",
477-
schemaname);
478-
aclresult=pg_namespace_aclcheck(namespaceId,GetUserId(),ACL_USAGE);
479-
if (aclresult!=ACLCHECK_OK)
480-
aclcheck_error(aclresult,schemaname);
436+
namespaceId=LookupExplicitNamespace(schemaname);
481437
}
482438
else
483439
{
@@ -684,53 +640,19 @@ FuncCandidateList
684640
OpernameGetCandidates(List*names,charoprkind)
685641
{
686642
FuncCandidateListresultList=NULL;
687-
char*catalogname;
688-
char*schemaname=NULL;
689-
char*opername=NULL;
643+
char*schemaname;
644+
char*opername;
690645
OidnamespaceId;
691646
CatCList*catlist;
692647
inti;
693648

694649
/* deconstruct the name list */
695-
switch (length(names))
696-
{
697-
case1:
698-
opername=strVal(lfirst(names));
699-
break;
700-
case2:
701-
schemaname=strVal(lfirst(names));
702-
opername=strVal(lsecond(names));
703-
break;
704-
case3:
705-
catalogname=strVal(lfirst(names));
706-
schemaname=strVal(lsecond(names));
707-
opername=strVal(lfirst(lnext(lnext(names))));
708-
/*
709-
* We check the catalog name and then ignore it.
710-
*/
711-
if (strcmp(catalogname,DatabaseName)!=0)
712-
elog(ERROR,"Cross-database references are not implemented");
713-
break;
714-
default:
715-
elog(ERROR,"Improper qualified name (too many dotted names): %s",
716-
NameListToString(names));
717-
break;
718-
}
650+
DeconstructQualifiedName(names,&schemaname,&opername);
719651

720652
if (schemaname)
721653
{
722654
/* use exact schema given */
723-
AclResultaclresult;
724-
725-
namespaceId=GetSysCacheOid(NAMESPACENAME,
726-
CStringGetDatum(schemaname),
727-
0,0,0);
728-
if (!OidIsValid(namespaceId))
729-
elog(ERROR,"Namespace \"%s\" does not exist",
730-
schemaname);
731-
aclresult=pg_namespace_aclcheck(namespaceId,GetUserId(),ACL_USAGE);
732-
if (aclresult!=ACLCHECK_OK)
733-
aclcheck_error(aclresult,schemaname);
655+
namespaceId=LookupExplicitNamespace(schemaname);
734656
}
735657
else
736658
{
@@ -1105,25 +1027,22 @@ OpclassIsVisible(Oid opcid)
11051027
returnvisible;
11061028
}
11071029

1108-
11091030
/*
1110-
* QualifiedNameGetCreationNamespace
1111-
*Given a possibly-qualified name for an object (in List-of-Values
1112-
*format), determine what namespace the object should be created in.
1113-
*Also extract and return the object name (last component of list).
1031+
* DeconstructQualifiedName
1032+
*Given a possibly-qualified name expressed as a list of String nodes,
1033+
*extract the schema name and object name.
11141034
*
1115-
* This is *not* used for tables. Hence, the TEMP table namespace is
1116-
* never selected as the creation target.
1035+
* *nspname_p is set to NULL if there is no explicit schema name.
11171036
*/
1118-
Oid
1119-
QualifiedNameGetCreationNamespace(List*names,char**objname_p)
1037+
void
1038+
DeconstructQualifiedName(List*names,
1039+
char**nspname_p,
1040+
char**objname_p)
11201041
{
11211042
char*catalogname;
11221043
char*schemaname=NULL;
11231044
char*objname=NULL;
1124-
OidnamespaceId;
11251045

1126-
/* deconstruct the name list */
11271046
switch (length(names))
11281047
{
11291048
case1:
@@ -1149,6 +1068,55 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p)
11491068
break;
11501069
}
11511070

1071+
*nspname_p=schemaname;
1072+
*objname_p=objname;
1073+
}
1074+
1075+
/*
1076+
* LookupExplicitNamespace
1077+
*Process an explicitly-specified schema name: look up the schema
1078+
*and verify we have USAGE (lookup) rights in it.
1079+
*
1080+
* Returns the namespace OID. Raises elog if any problem.
1081+
*/
1082+
Oid
1083+
LookupExplicitNamespace(char*nspname)
1084+
{
1085+
OidnamespaceId;
1086+
AclResultaclresult;
1087+
1088+
namespaceId=GetSysCacheOid(NAMESPACENAME,
1089+
CStringGetDatum(nspname),
1090+
0,0,0);
1091+
if (!OidIsValid(namespaceId))
1092+
elog(ERROR,"Namespace \"%s\" does not exist",nspname);
1093+
1094+
aclresult=pg_namespace_aclcheck(namespaceId,GetUserId(),ACL_USAGE);
1095+
if (aclresult!=ACLCHECK_OK)
1096+
aclcheck_error(aclresult,nspname);
1097+
1098+
returnnamespaceId;
1099+
}
1100+
1101+
/*
1102+
* QualifiedNameGetCreationNamespace
1103+
*Given a possibly-qualified name for an object (in List-of-Values
1104+
*format), determine what namespace the object should be created in.
1105+
*Also extract and return the object name (last component of list).
1106+
*
1107+
* This is *not* used for tables. Hence, the TEMP table namespace is
1108+
* never selected as the creation target.
1109+
*/
1110+
Oid
1111+
QualifiedNameGetCreationNamespace(List*names,char**objname_p)
1112+
{
1113+
char*schemaname;
1114+
char*objname;
1115+
OidnamespaceId;
1116+
1117+
/* deconstruct the name list */
1118+
DeconstructQualifiedName(names,&schemaname,&objname);
1119+
11521120
if (schemaname)
11531121
{
11541122
/* use exact schema given */
@@ -1158,6 +1126,7 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p)
11581126
if (!OidIsValid(namespaceId))
11591127
elog(ERROR,"Namespace \"%s\" does not exist",
11601128
schemaname);
1129+
/* we do not check for USAGE rights here! */
11611130
}
11621131
else
11631132
{

‎src/backend/commands/comment.c

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Copyright (c) 1996-2001, PostgreSQL Global Development Group
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.52 2002/07/20 05:16:57 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.53 2002/07/29 23:46:35 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -22,7 +22,6 @@
2222
#include"catalog/pg_constraint.h"
2323
#include"catalog/pg_database.h"
2424
#include"catalog/pg_description.h"
25-
#include"catalog/pg_namespace.h"
2625
#include"catalog/pg_operator.h"
2726
#include"catalog/pg_rewrite.h"
2827
#include"catalog/pg_trigger.h"
@@ -468,36 +467,28 @@ CommentNamespace(List *qualname, char *comment)
468467
{
469468
Oidoid;
470469
Oidclassoid;
471-
HeapTupletp;
472470
char*namespace;
473471

474472
if (length(qualname)!=1)
475473
elog(ERROR,"CommentSchema: schema name may not be qualified");
476474
namespace=strVal(lfirst(qualname));
477475

478-
tp=SearchSysCache(NAMESPACENAME,
479-
CStringGetDatum(namespace),
480-
0,0,0);
481-
if (!HeapTupleIsValid(tp))
476+
oid=GetSysCacheOid(NAMESPACENAME,
477+
CStringGetDatum(namespace),
478+
0,0,0);
479+
if (!OidIsValid(oid))
482480
elog(ERROR,"CommentSchema: Schema \"%s\" could not be found",
483481
namespace);
484482

485-
/* no TupleDesc here to Assert(...->tdhasoid); */
486-
oid=HeapTupleGetOid(tp);
487-
488483
/* Check object security */
489484
if (!pg_namespace_ownercheck(oid,GetUserId()))
490485
aclcheck_error(ACLCHECK_NOT_OWNER,namespace);
491486

492487
/* pg_namespace doesn't have a hard-coded OID, so must look it up */
493-
classoid=get_relname_relid(NamespaceRelationName,PG_CATALOG_NAMESPACE);
494-
Assert(OidIsValid(classoid));
488+
classoid=get_system_catalog_relid(NamespaceRelationName);
495489

496490
/* Call CreateComments() to create/drop the comments */
497491
CreateComments(oid,classoid,0,comment);
498-
499-
/* Cleanup */
500-
ReleaseSysCache(tp);
501492
}
502493

503494
/*
@@ -607,8 +598,7 @@ CommentRule(List *qualname, char *comment)
607598
aclcheck_error(aclcheck,rulename);
608599

609600
/* pg_rewrite doesn't have a hard-coded OID, so must look it up */
610-
classoid=get_relname_relid(RewriteRelationName,PG_CATALOG_NAMESPACE);
611-
Assert(OidIsValid(classoid));
601+
classoid=get_system_catalog_relid(RewriteRelationName);
612602

613603
/* Call CreateComments() to create/drop the comments */
614604

@@ -740,8 +730,7 @@ CommentOperator(List *opername, List *arguments, char *comment)
740730
aclcheck_error(ACLCHECK_NOT_OWNER,NameListToString(opername));
741731

742732
/* pg_operator doesn't have a hard-coded OID, so must look it up */
743-
classoid=get_relname_relid(OperatorRelationName,PG_CATALOG_NAMESPACE);
744-
Assert(OidIsValid(classoid));
733+
classoid=get_system_catalog_relid(OperatorRelationName);
745734

746735
/* Call CreateComments() to create/drop the comments */
747736
CreateComments(oid,classoid,0,comment);

‎src/backend/commands/indexcmds.c

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.78 2002/07/20 05:16:57 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.79 2002/07/29 23:46:35 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -410,9 +410,8 @@ static Oid
410410
GetAttrOpClass(IndexElem*attribute,OidattrType,
411411
char*accessMethodName,OidaccessMethodId)
412412
{
413-
char*catalogname;
414-
char*schemaname=NULL;
415-
char*opcname=NULL;
413+
char*schemaname;
414+
char*opcname;
416415
HeapTupletuple;
417416
OidopClassId,
418417
opInputType;
@@ -434,42 +433,14 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType,
434433
*/
435434

436435
/* deconstruct the name list */
437-
switch (length(attribute->opclass))
438-
{
439-
case1:
440-
opcname=strVal(lfirst(attribute->opclass));
441-
break;
442-
case2:
443-
schemaname=strVal(lfirst(attribute->opclass));
444-
opcname=strVal(lsecond(attribute->opclass));
445-
break;
446-
case3:
447-
catalogname=strVal(lfirst(attribute->opclass));
448-
schemaname=strVal(lsecond(attribute->opclass));
449-
opcname=strVal(lfirst(lnext(lnext(attribute->opclass))));
450-
/*
451-
* We check the catalog name and then ignore it.
452-
*/
453-
if (strcmp(catalogname,DatabaseName)!=0)
454-
elog(ERROR,"Cross-database references are not implemented");
455-
break;
456-
default:
457-
elog(ERROR,"Improper opclass name (too many dotted names): %s",
458-
NameListToString(attribute->opclass));
459-
break;
460-
}
436+
DeconstructQualifiedName(attribute->opclass,&schemaname,&opcname);
461437

462438
if (schemaname)
463439
{
464440
/* Look in specific schema only */
465441
OidnamespaceId;
466442

467-
namespaceId=GetSysCacheOid(NAMESPACENAME,
468-
CStringGetDatum(schemaname),
469-
0,0,0);
470-
if (!OidIsValid(namespaceId))
471-
elog(ERROR,"Namespace \"%s\" does not exist",
472-
schemaname);
443+
namespaceId=LookupExplicitNamespace(schemaname);
473444
tuple=SearchSysCache(CLAAMNAMENSP,
474445
ObjectIdGetDatum(accessMethodId),
475446
PointerGetDatum(opcname),

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp