Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit e4949f9

Browse files
committed
From: Dan McGuirk <mcguirk@indirect.com>
Subject: [HACKERS] better access control error messages This patch replaces the 'no such class or insufficient privilege' with distinct error messages that tell you whether the table really doesn't exist or whether access was denied.
1 parent c00c511 commit e4949f9

File tree

6 files changed

+63
-43
lines changed

6 files changed

+63
-43
lines changed

src/backend/commands/copy.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
*
88
* IDENTIFICATION
9-
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.21 1997/01/10 17:46:33 momjian Exp $
9+
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.22 1997/03/12 20:47:32 scrappy Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -102,13 +102,15 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
102102
Relation rel;
103103
extern char *UserName; /* defined in global.c */
104104
const AclMode required_access = from ? ACL_WR : ACL_RD;
105+
int result;
105106

106107
rel = heap_openr(relname);
107108
if (rel == NULL) elog(WARN, "COPY command failed. Class %s "
108109
"does not exist.", relname);
109-
110-
if (!pg_aclcheck(relname, UserName, required_access))
111-
elog(WARN, "%s %s", relname, ACL_NO_PRIV_WARNING);
110+
111+
result = pg_aclcheck(relname, UserName, required_access);
112+
if(result != ACLCHECK_OK)
113+
elog(WARN, "%s: %s", relname, aclcheck_error_strings[result]);
112114
/* Above should not return */
113115
else if (!superuser() && !pipe)
114116
elog(WARN, "You must have Postgres superuser privilege to do a COPY "

src/backend/executor/execMain.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
*
2727
*
2828
* IDENTIFICATION
29-
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.10 1997/01/22 05:26:27 vadim Exp $
29+
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.11 1997/03/12 20:47:41 scrappy Exp $
3030
*
3131
*-------------------------------------------------------------------------
3232
*/
@@ -289,7 +289,7 @@ ExecCheckPerms(CmdType operation,
289289
HeapTuple htp;
290290
List *lp;
291291
List *qvars, *tvars;
292-
int32 ok = 1;
292+
int32 ok = 1, aclcheck_result = -1;
293293
char *opstr;
294294
NameData rname;
295295
char *userName;
@@ -317,21 +317,21 @@ ExecCheckPerms(CmdType operation,
317317
if (intMember(resultRelation, qvars) ||
318318
intMember(resultRelation, tvars)) {
319319
/* result relation is scanned */
320-
ok = CHECK(ACL_RD);
320+
ok = ((aclcheck_result = CHECK(ACL_RD)) == ACLCHECK_OK);
321321
opstr = "read";
322322
if (!ok)
323323
break;
324324
}
325325
switch (operation) {
326326
case CMD_INSERT:
327-
ok = CHECK(ACL_AP) ||
328-
CHECK(ACL_WR);
327+
ok = ((aclcheck_result = CHECK(ACL_AP)) == ACLCHECK_OK) ||
328+
((aclcheck_result = CHECK(ACL_WR)) == ACLCHECK_OK);
329329
opstr = "append";
330330
break;
331331
case CMD_NOTIFY: /* what does this mean?? -- jw, 1/6/94 */
332332
case CMD_DELETE:
333333
case CMD_UPDATE:
334-
ok = CHECK(ACL_WR);
334+
ok = ((aclcheck_result = CHECK(ACL_WR)) == ACLCHECK_OK);
335335
opstr = "write";
336336
break;
337337
default:
@@ -340,7 +340,7 @@ ExecCheckPerms(CmdType operation,
340340
}
341341
} else {
342342
/* XXX NOTIFY?? */
343-
ok = CHECK(ACL_RD);
343+
ok = ((aclcheck_result = CHECK(ACL_RD)) == ACLCHECK_OK);
344344
opstr = "read";
345345
}
346346
if (!ok)
@@ -352,7 +352,7 @@ ExecCheckPerms(CmdType operation,
352352
elog(WARN, "%s on \"%-.*s\": permission denied", opstr,
353353
NAMEDATALEN, rname.data);
354354
*/
355-
elog(WARN, "%s %s", rname.data, ACL_NO_PRIV_WARNING);
355+
elog(WARN, "%s: %s", rname.data, aclcheck_error_strings[aclcheck_result]);
356356
}
357357
}
358358

src/backend/parser/parse_query.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/Attic/parse_query.c,v 1.14 1997/02/14 23:02:29 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/Attic/parse_query.c,v 1.15 1997/03/12 20:47:57 scrappy Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -133,7 +133,7 @@ addRangeTableEntry(ParseState *pstate,
133133
relation = heap_openr(relname);
134134
if (relation == NULL) {
135135
elog(WARN,"%s: %s",
136-
relname, ACL_NO_PRIV_WARNING);
136+
relname, aclcheck_error_strings[ACLCHECK_NO_CLASS]);
137137
}
138138

139139
/*

src/backend/tcop/aclchk.c

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/tcop/Attic/aclchk.c,v 1.6 1997/01/23 19:33:31 scrappy Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/tcop/Attic/aclchk.c,v 1.7 1997/03/12 20:48:17 scrappy Exp $
1111
*
1212
* NOTES
1313
* See acl.h.
@@ -17,7 +17,7 @@
1717
#include <string.h>
1818
#include "postgres.h"
1919

20-
#include "utils/acl.h" /* where declarations for this file goes */
20+
#include "utils/acl.h" /* where declarations for this file go */
2121
#include "access/heapam.h"
2222
#include "access/htup.h"
2323
#include "access/tupmacs.h"
@@ -55,6 +55,15 @@
5555
#define Name_pg_group "pggroup"
5656
#endif
5757

58+
/* warning messages, now more explicit. */
59+
/* should correspond to the order of the ACLCHK_* result codes above. */
60+
char *aclcheck_error_strings[] = {
61+
"No error.",
62+
"Permission denied.",
63+
"Table does not exist.",
64+
"Must be table owner."
65+
};
66+
5867
#ifdef ACLDEBUG_TRACE
5968
static
6069
dumpacl(Acl *acl)
@@ -268,10 +277,10 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
268277
* the system never creates an empty ACL.
269278
*/
270279
if (num < 1) {
271-
#ifdef ACLDEBUG_TRACE
280+
#ifdef ACLDEBUG_TRACE || 1
272281
elog(DEBUG, "aclcheck: zero-length ACL, returning 1");
273282
#endif
274-
return(1);
283+
return ACLCHECK_OK;
275284
}
276285

277286
switch (idtype) {
@@ -284,7 +293,7 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
284293
elog(DEBUG, "aclcheck: found %d/%d",
285294
aip->ai_id, aip->ai_mode);
286295
#endif
287-
return((aip->ai_mode & mode) ? 1 : 0);
296+
return((aip->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV);
288297
}
289298
}
290299
for (found_group = 0;
@@ -304,7 +313,7 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
304313
elog(DEBUG, "aclcheck: found %d/%d",
305314
aip->ai_id, aip->ai_mode);
306315
#endif
307-
return(0);
316+
return ACLCHECK_NO_PRIV;
308317
}
309318
#endif
310319
}
@@ -313,7 +322,7 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
313322
#ifdef ACLDEBUG_TRACE
314323
elog(DEBUG,"aclcheck: all groups ok");
315324
#endif
316-
return(1);
325+
return ACLCHECK_OK;
317326
}
318327
break;
319328
case ACL_IDTYPE_GID:
@@ -329,7 +338,7 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
329338
elog(DEBUG, "aclcheck: found %d/%d",
330339
aip->ai_id, aip->ai_mode);
331340
#endif
332-
return((aip->ai_mode & mode) ? 1 : 0);
341+
return((aip->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV);
333342
}
334343
}
335344
break;
@@ -343,7 +352,7 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
343352
#ifdef ACLDEBUG_TRACE
344353
elog(DEBUG, "aclcheck: using world=%d", aidat->ai_mode);
345354
#endif
346-
return((aidat->ai_mode & mode) ? 1 : 0);
355+
return((aidat->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV);
347356
}
348357

349358
int32
@@ -370,7 +379,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
370379
pg_database table, there is still additional permissions checking
371380
in dbcommands.c */
372381
if (mode & ACL_AP)
373-
return (1);
382+
return ACLCHECK_OK;
374383
}
375384

376385
/*
@@ -383,7 +392,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
383392
!((Form_pg_user) GETSTRUCT(htp))->usecatupd) {
384393
elog(DEBUG, "pg_aclcheck: catalog update to \"%-.*s\": permission denied",
385394
NAMEDATALEN, relname);
386-
return(0);
395+
return ACLCHECK_NO_PRIV;
387396
}
388397

389398
/*
@@ -394,7 +403,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
394403
elog(DEBUG, "pg_aclcheck: \"%-.*s\" is superuser",
395404
NAMEDATALEN, usename);
396405
#endif
397-
return(1);
406+
return ACLCHECK_OK;
398407
}
399408

400409
#ifndef ACLDEBUG
@@ -403,7 +412,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
403412
if (!HeapTupleIsValid(htp)) {
404413
elog(WARN, "pg_aclcheck: class \"%-.*s\" not found",
405414
NAMEDATALEN, relname);
406-
return(1);
415+
/* an elog(WARN) kills us, so no need to return anything. */
407416
}
408417
if (!heap_attisnull(htp, Anum_pg_class_relacl)) {
409418
relation = heap_openr(RelationRelationName);
@@ -436,7 +445,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
436445
if (!RelationIsValid(relation)) {
437446
elog(NOTICE, "pg_checkacl: could not open \"%-.*s\"??",
438447
RelationRelationName);
439-
return(1);
448+
return ACLCHECK_NO_CLASS;
440449
}
441450
fmgr_info(NameEqualRegProcedure,
442451
&relkey[0].sk_func,
@@ -494,8 +503,8 @@ pg_ownercheck(char *usename,
494503
switch (cacheid) {
495504
case OPROID:
496505
if (!HeapTupleIsValid(htp))
497-
elog(WARN, "pg_ownercheck: operator %d not found",
498-
(int) value);
506+
elog(WARN, "pg_ownercheck: operator %ld not found",
507+
PointerGetDatum(value));
499508
owner_id = ((OperatorTupleForm) GETSTRUCT(htp))->oprowner;
500509
break;
501510
case PRONAME:

src/backend/tcop/utility.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.11 1997/01/16 14:56:21 momjian Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.12 1997/03/12 20:48:27 scrappy Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -381,10 +381,13 @@ ProcessUtility(Node *parsetree,
381381
case T_RuleStmt: /* CREATE RULE */
382382
{
383383
RuleStmt *stmt = (RuleStmt *)parsetree;
384+
int aclcheck_result;
385+
384386
#ifndef NO_SECURITY
385387
relname = stmt->object->relname;
386-
if (!pg_aclcheck(relname, userName, ACL_RU))
387-
elog(WARN, "%s %s", relname, ACL_NO_PRIV_WARNING);
388+
aclcheck_result = pg_aclcheck(relname, userName, ACL_RU);
389+
if(aclcheck_result != ACLCHECK_OK)
390+
elog(WARN, "%s: %s", relname, aclcheck_error_strings[aclcheck_result]);
388391
#endif
389392
commandTag = "CREATE";
390393
CHECK_IF_ABORTED();
@@ -423,19 +426,21 @@ ProcessUtility(Node *parsetree,
423426
relname);
424427
#ifndef NO_SECURITY
425428
if (!pg_ownercheck(userName, relname, RELNAME))
426-
elog(WARN, "you do not own class \"%s\"",
427-
relname);
429+
elog(WARN, "%s: %s", relationName, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
428430
#endif
429431
RemoveIndex(relname);
430432
break;
431433
case RULE:
432434
{
433435
char *rulename = stmt->name;
436+
int aclcheck_result;
434437
#ifndef NO_SECURITY
435438

436439
relationName = RewriteGetRuleEventRel(rulename);
437-
if (!pg_aclcheck(relationName, userName, ACL_RU))
438-
elog(WARN, "%s %s", relationName, ACL_NO_PRIV_WARNING);
440+
aclcheck_result = pg_aclcheck(relationName, userName, ACL_RU);
441+
if(aclcheck_result != ACLCHECK_OK) {
442+
elog(WARN, "%s: %s", relationName, aclcheck_error_strings[aclcheck_result]);
443+
}
439444
#endif
440445
RemoveRewriteRule(rulename);
441446
}
@@ -457,7 +462,7 @@ ProcessUtility(Node *parsetree,
457462
ruleName = MakeRetrieveViewRuleName(viewName);
458463
relationName = RewriteGetRuleEventRel(ruleName);
459464
if (!pg_ownercheck(userName, relationName, RELNAME))
460-
elog(WARN, "%s %s", relationName, ACL_NO_PRIV_WARNING);
465+
elog(WARN, "%s: %s", relationName, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
461466
pfree(ruleName);
462467
#endif
463468
RemoveView(viewName);

src/include/utils/acl.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: acl.h,v 1.4 1996/11/10 03:06:14 momjian Exp $
9+
* $Id: acl.h,v 1.5 1997/03/12 20:48:48 scrappy Exp $
1010
*
1111
* NOTES
1212
* For backward-compatability purposes we have to allow there
@@ -111,10 +111,14 @@ typedef ArrayType IdList;
111111
#define ACL_MODE_WR_CHR 'w'
112112
#define ACL_MODE_RU_CHR 'R'
113113

114-
/* we use this warning string both for non-existent tables and
115-
insufficient privilege so non-privileged users cannot ascertain whether
116-
the class exists or not */
117-
#define ACL_NO_PRIV_WARNING "Either no such class or insufficient privilege"
114+
/* result codes for pg_aclcheck */
115+
#define ACLCHECK_OK 0
116+
#define ACLCHECK_NO_PRIV 1
117+
#define ACLCHECK_NO_CLASS 2
118+
#define ACLCHECK_NOT_OWNER 3
119+
120+
/* warning messages. set these in aclchk.c. */
121+
extern char *aclcheck_error_strings[];
118122

119123
/*
120124
* Enable ACL execution tracing and table dumps

0 commit comments

Comments
 (0)