Commit fb97d2b6 authored by Tom Lane's avatar Tom Lane

Correct permissions-checking bugs associated with ancient decision to

copy PUBLIC access rights into each newly created ACL entry.  Instead
treat each ACL entry as independent flags.  Also clean up some ugliness
in acl.h API.
parent cdd230d6
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Copyright (c) 1999, PostgreSQL Global Development Group * Copyright (c) 1999, PostgreSQL Global Development Group
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.28 2001/05/27 09:59:29 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.29 2001/06/05 19:34:56 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -507,13 +507,9 @@ CommentType(char *type, char *comment) ...@@ -507,13 +507,9 @@ CommentType(char *type, char *comment)
/*** First, validate user ***/ /*** First, validate user ***/
#ifndef NO_SECURITY
if (!pg_ownercheck(GetUserId(), type, TYPENAME)) if (!pg_ownercheck(GetUserId(), type, TYPENAME))
{
elog(ERROR, "you are not permitted to comment on type '%s'", elog(ERROR, "you are not permitted to comment on type '%s'",
type); type);
}
#endif
/*** Next, find the type's oid ***/ /*** Next, find the type's oid ***/
...@@ -561,21 +557,15 @@ CommentAggregate(char *aggregate, List *arguments, char *comment) ...@@ -561,21 +557,15 @@ CommentAggregate(char *aggregate, List *arguments, char *comment)
/*** Next, validate the user's attempt to comment ***/ /*** Next, validate the user's attempt to comment ***/
#ifndef NO_SECURITY
if (!pg_aggr_ownercheck(GetUserId(), aggregate, baseoid)) if (!pg_aggr_ownercheck(GetUserId(), aggregate, baseoid))
{ {
if (aggtypename) if (aggtypename)
{
elog(ERROR, "you are not permitted to comment on aggregate '%s' %s '%s'", elog(ERROR, "you are not permitted to comment on aggregate '%s' %s '%s'",
aggregate, "with type", aggtypename); aggregate, "with type", aggtypename);
}
else else
{
elog(ERROR, "you are not permitted to comment on aggregate '%s'", elog(ERROR, "you are not permitted to comment on aggregate '%s'",
aggregate); aggregate);
} }
}
#endif
/*** Now, attempt to find the actual tuple in pg_aggregate ***/ /*** Now, attempt to find the actual tuple in pg_aggregate ***/
...@@ -646,11 +636,9 @@ CommentProc(char *function, List *arguments, char *comment) ...@@ -646,11 +636,9 @@ CommentProc(char *function, List *arguments, char *comment)
/*** Now, validate the user's ability to comment on this function ***/ /*** Now, validate the user's ability to comment on this function ***/
#ifndef NO_SECURITY
if (!pg_func_ownercheck(GetUserId(), function, argcount, argoids)) if (!pg_func_ownercheck(GetUserId(), function, argcount, argoids))
elog(ERROR, "you are not permitted to comment on function '%s'", elog(ERROR, "you are not permitted to comment on function '%s'",
function); function);
#endif
/*** Now, find the corresponding oid for this procedure ***/ /*** Now, find the corresponding oid for this procedure ***/
...@@ -745,13 +733,9 @@ CommentOperator(char *opername, List *arguments, char *comment) ...@@ -745,13 +733,9 @@ CommentOperator(char *opername, List *arguments, char *comment)
/*** Valid user's ability to comment on this operator ***/ /*** Valid user's ability to comment on this operator ***/
#ifndef NO_SECURITY if (!pg_oper_ownercheck(GetUserId(), oid))
if (!pg_ownercheck(GetUserId(), (char *) ObjectIdGetDatum(oid), OPEROID))
{
elog(ERROR, "you are not permitted to comment on operator '%s'", elog(ERROR, "you are not permitted to comment on operator '%s'",
opername); opername);
}
#endif
/*** Get the procedure associated with the operator ***/ /*** Get the procedure associated with the operator ***/
...@@ -792,13 +776,9 @@ CommentTrigger(char *trigger, char *relname, char *comment) ...@@ -792,13 +776,9 @@ CommentTrigger(char *trigger, char *relname, char *comment)
/*** First, validate the user's action ***/ /*** First, validate the user's action ***/
#ifndef NO_SECURITY
if (!pg_ownercheck(GetUserId(), relname, RELNAME)) if (!pg_ownercheck(GetUserId(), relname, RELNAME))
{
elog(ERROR, "you are not permitted to comment on trigger '%s' %s '%s'", elog(ERROR, "you are not permitted to comment on trigger '%s' %s '%s'",
trigger, "defined for relation", relname); trigger, "defined for relation", relname);
}
#endif
/*** Now, fetch the trigger oid from pg_trigger ***/ /*** Now, fetch the trigger oid from pg_trigger ***/
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.60 2001/03/22 03:59:23 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.61 2001/06/05 19:34:56 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -81,9 +81,7 @@ RemoveOperator(char *operatorName, /* operator name */ ...@@ -81,9 +81,7 @@ RemoveOperator(char *operatorName, /* operator name */
if (HeapTupleIsValid(tup)) if (HeapTupleIsValid(tup))
{ {
if (!pg_ownercheck(GetUserId(), if (!pg_oper_ownercheck(GetUserId(), tup->t_data->t_oid))
(char *) ObjectIdGetDatum(tup->t_data->t_oid),
OPEROID))
elog(ERROR, "RemoveOperator: operator '%s': permission denied", elog(ERROR, "RemoveOperator: operator '%s': permission denied",
operatorName); operatorName);
......
...@@ -8,14 +8,14 @@ ...@@ -8,14 +8,14 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.59 2001/05/27 09:59:30 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.60 2001/06/05 19:34:56 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include <ctype.h>
#include "postgres.h" #include "postgres.h"
#include <ctype.h>
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/pg_shadow.h" #include "catalog/pg_shadow.h"
...@@ -392,7 +392,8 @@ acldefault(char *relname, AclId ownerid) ...@@ -392,7 +392,8 @@ acldefault(char *relname, AclId ownerid)
/* /*
* Add or replace an item in an ACL array. * Add or replace an item in an ACL array. The result is a modified copy;
* the input object is not changed.
* *
* NB: caller is responsible for having detoasted the input ACL, if needed. * NB: caller is responsible for having detoasted the input ACL, if needed.
*/ */
...@@ -402,8 +403,7 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg) ...@@ -402,8 +403,7 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
Acl *new_acl; Acl *new_acl;
AclItem *old_aip, AclItem *old_aip,
*new_aip; *new_aip;
int src, int dst,
dst,
num; num;
/* These checks for null input are probably dead code, but... */ /* These checks for null input are probably dead code, but... */
...@@ -431,14 +431,14 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg) ...@@ -431,14 +431,14 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
if (dst < num && aclitemeq(mod_aip, old_aip + dst)) if (dst < num && aclitemeq(mod_aip, old_aip + dst))
{ {
/* modify in-place */ /* found a match, so modify existing item */
new_acl = makeacl(num); new_acl = makeacl(num);
new_aip = ACL_DAT(new_acl); new_aip = ACL_DAT(new_acl);
memcpy((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl)); memcpy((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
src = dst;
} }
else else
{ {
/* need to insert a new item */
new_acl = makeacl(num + 1); new_acl = makeacl(num + 1);
new_aip = ACL_DAT(new_acl); new_aip = ACL_DAT(new_acl);
if (dst == 0) if (dst == 0)
...@@ -460,20 +460,21 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg) ...@@ -460,20 +460,21 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
(char *) (old_aip + dst), (char *) (old_aip + dst),
(num - dst) * sizeof(AclItem)); (num - dst) * sizeof(AclItem));
} }
/* initialize the new entry with no permissions */
new_aip[dst].ai_id = mod_aip->ai_id; new_aip[dst].ai_id = mod_aip->ai_id;
new_aip[dst].ai_idtype = mod_aip->ai_idtype; new_aip[dst].ai_idtype = mod_aip->ai_idtype;
new_aip[dst].ai_mode = 0;
num++; /* set num to the size of new_acl */ num++; /* set num to the size of new_acl */
src = 0; /* if add or del, start from world entry */
} }
/* apply the permissions mod */ /* apply the permissions mod */
switch (modechg) switch (modechg)
{ {
case ACL_MODECHG_ADD: case ACL_MODECHG_ADD:
new_aip[dst].ai_mode = old_aip[src].ai_mode | mod_aip->ai_mode; new_aip[dst].ai_mode |= mod_aip->ai_mode;
break; break;
case ACL_MODECHG_DEL: case ACL_MODECHG_DEL:
new_aip[dst].ai_mode = old_aip[src].ai_mode & ~mod_aip->ai_mode; new_aip[dst].ai_mode &= ~mod_aip->ai_mode;
break; break;
case ACL_MODECHG_EQL: case ACL_MODECHG_EQL:
new_aip[dst].ai_mode = mod_aip->ai_mode; new_aip[dst].ai_mode = mod_aip->ai_mode;
...@@ -487,16 +488,10 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg) ...@@ -487,16 +488,10 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
*/ */
if (new_aip[dst].ai_mode == 0 && dst > 0) if (new_aip[dst].ai_mode == 0 && dst > 0)
{ {
int i; memmove((char *) (new_aip + dst),
(char *) (new_aip + dst + 1),
for (i = dst + 1; i < num; i++) (num - dst - 1) * sizeof(AclItem));
{
new_aip[i - 1].ai_id = new_aip[i].ai_id;
new_aip[i - 1].ai_idtype = new_aip[i].ai_idtype;
new_aip[i - 1].ai_mode = new_aip[i].ai_mode;
}
ARR_DIMS(new_acl)[0] = num - 1; ARR_DIMS(new_acl)[0] = num - 1;
/* Adjust also the array size because it is used for memcpy */
ARR_SIZE(new_acl) -= sizeof(AclItem); ARR_SIZE(new_acl) -= sizeof(AclItem);
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: acl.h,v 1.32 2001/05/27 09:59:30 petere Exp $ * $Id: acl.h,v 1.33 2001/06/05 19:34:56 tgl Exp $
* *
* NOTES * NOTES
* For backward-compatibility purposes we have to allow there * For backward-compatibility purposes we have to allow there
...@@ -164,7 +164,7 @@ typedef ArrayType IdList; ...@@ -164,7 +164,7 @@ typedef ArrayType IdList;
#define ACLCHECK_NO_CLASS 2 #define ACLCHECK_NO_CLASS 2
#define ACLCHECK_NOT_OWNER 3 #define ACLCHECK_NOT_OWNER 3
/* warning messages. set these in aclchk.c. */ /* error messages (index by ACL_CHECK_* result code). set in aclchk.c. */
extern char *aclcheck_error_strings[]; extern char *aclcheck_error_strings[];
/* /*
...@@ -201,10 +201,12 @@ extern AclId get_grosysid(char *groname); ...@@ -201,10 +201,12 @@ extern AclId get_grosysid(char *groname);
extern char *get_groname(AclId grosysid); extern char *get_groname(AclId grosysid);
extern int32 pg_aclcheck(char *relname, Oid userid, AclMode mode); extern int32 pg_aclcheck(char *relname, Oid userid, AclMode mode);
extern int32 pg_ownercheck(Oid userid, const char *value, int cacheid);
extern int32 pg_func_ownercheck(Oid userid, char *funcname, extern bool pg_ownercheck(Oid userid, const char *name, int cacheid);
extern bool pg_oper_ownercheck(Oid userid, Oid oprid);
extern bool pg_func_ownercheck(Oid userid, char *funcname,
int nargs, Oid *arglist); int nargs, Oid *arglist);
extern int32 pg_aggr_ownercheck(Oid userid, char *aggname, extern bool pg_aggr_ownercheck(Oid userid, char *aggname,
Oid basetypeID); Oid basetypeID);
#endif /* ACL_H */ #endif /* ACL_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment