Allow GRANT/REVOKE to/from more than one user per invocation. Command tag
for GRANT/REVOKE is now just that, not "CHANGE". On the way, migrate some of the aclitem internal representation away from the parser and build a real parse tree instead. Also add some 'const' qualifiers.
This commit is contained in:
parent
202548d6cc
commit
7ceed2a9b5
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/grant.sgml,v 1.10 2001/05/27 09:59:28 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/grant.sgml,v 1.11 2001/06/09 23:21:54 petere Exp $
|
||||||
Postgres documentation
|
Postgres documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ Postgres documentation
|
|||||||
<synopsis>
|
<synopsis>
|
||||||
GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } [,...] | ALL [ PRIVILEGES ] }
|
GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } [,...] | ALL [ PRIVILEGES ] }
|
||||||
ON [ TABLE ] <replaceable class="PARAMETER">objectname</replaceable> [, ...]
|
ON [ TABLE ] <replaceable class="PARAMETER">objectname</replaceable> [, ...]
|
||||||
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC }
|
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
|
||||||
</synopsis>
|
</synopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/revoke.sgml,v 1.14 2001/05/27 09:59:28 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/revoke.sgml,v 1.15 2001/06/09 23:21:54 petere Exp $
|
||||||
Postgres documentation
|
Postgres documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ Postgres documentation
|
|||||||
<synopsis>
|
<synopsis>
|
||||||
REVOKE { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } [,...] | ALL [ PRIVILEGES ] }
|
REVOKE { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } [,...] | ALL [ PRIVILEGES ] }
|
||||||
ON [ TABLE ] <replaceable class="PARAMETER">object</replaceable> [, ...]
|
ON [ TABLE ] <replaceable class="PARAMETER">object</replaceable> [, ...]
|
||||||
FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC }
|
FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
|
||||||
</synopsis>
|
</synopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.49 2001/06/05 19:34:56 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.50 2001/06/09 23:21:54 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* See acl.h.
|
* See acl.h.
|
||||||
@ -63,31 +63,40 @@ dumpacl(Acl *acl)
|
|||||||
|
|
||||||
#endif /* ACLDEBUG */
|
#endif /* ACLDEBUG */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ChangeAcl
|
* Called to execute the utility commands GRANT and REVOKE
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ChangeAcl(char *relname,
|
ExecuteGrantStmt(GrantStmt *stmt)
|
||||||
AclItem *mod_aip,
|
|
||||||
unsigned modechg)
|
|
||||||
{
|
{
|
||||||
unsigned i;
|
List *i;
|
||||||
Acl *old_acl,
|
List *j;
|
||||||
*new_acl;
|
|
||||||
|
/* see comment in pg_type.h */
|
||||||
|
Assert(ACLITEMSIZE == sizeof(AclItem));
|
||||||
|
|
||||||
|
foreach(i, stmt->relnames)
|
||||||
|
{
|
||||||
|
char *relname = strVal(lfirst(i));
|
||||||
Relation relation;
|
Relation relation;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
HeapTuple newtuple;
|
Form_pg_class pg_class_tuple;
|
||||||
Datum aclDatum;
|
Datum aclDatum;
|
||||||
|
bool isNull;
|
||||||
|
Acl *old_acl;
|
||||||
|
Acl *new_acl;
|
||||||
|
unsigned i;
|
||||||
|
HeapTuple newtuple;
|
||||||
Datum values[Natts_pg_class];
|
Datum values[Natts_pg_class];
|
||||||
char nulls[Natts_pg_class];
|
char nulls[Natts_pg_class];
|
||||||
char replaces[Natts_pg_class];
|
char replaces[Natts_pg_class];
|
||||||
Relation idescs[Num_pg_class_indices];
|
|
||||||
bool isNull;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find the pg_class tuple matching 'relname' and extract the ACL. If
|
if (!pg_ownercheck(GetUserId(), relname, RELNAME))
|
||||||
* there's no ACL, create a default using the pg_class.relowner field.
|
elog(ERROR, "permission denied");
|
||||||
*/
|
|
||||||
|
/* open pg_class */
|
||||||
relation = heap_openr(RelationRelationName, RowExclusiveLock);
|
relation = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||||
tuple = SearchSysCache(RELNAME,
|
tuple = SearchSysCache(RELNAME,
|
||||||
PointerGetDatum(relname),
|
PointerGetDatum(relname),
|
||||||
@ -95,42 +104,64 @@ ChangeAcl(char *relname,
|
|||||||
if (!HeapTupleIsValid(tuple))
|
if (!HeapTupleIsValid(tuple))
|
||||||
{
|
{
|
||||||
heap_close(relation, RowExclusiveLock);
|
heap_close(relation, RowExclusiveLock);
|
||||||
elog(ERROR, "ChangeAcl: class \"%s\" not found",
|
elog(ERROR, "relation \"%s\" not found",
|
||||||
relname);
|
relname);
|
||||||
}
|
}
|
||||||
|
pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
|
||||||
|
|
||||||
|
if (pg_class_tuple->relkind == RELKIND_INDEX)
|
||||||
|
elog(ERROR, "\"%s\" is an index",
|
||||||
|
relname);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there's no ACL, create a default using the
|
||||||
|
* pg_class.relowner field.
|
||||||
|
*/
|
||||||
aclDatum = SysCacheGetAttr(RELNAME, tuple, Anum_pg_class_relacl,
|
aclDatum = SysCacheGetAttr(RELNAME, tuple, Anum_pg_class_relacl,
|
||||||
&isNull);
|
&isNull);
|
||||||
if (isNull)
|
if (isNull)
|
||||||
{
|
old_acl = acldefault(relname, pg_class_tuple->relowner);
|
||||||
/* No ACL, so build default ACL for rel */
|
|
||||||
AclId ownerId;
|
|
||||||
|
|
||||||
ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
|
|
||||||
old_acl = acldefault(relname, ownerId);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
/* get a detoasted copy of the rel's ACL */
|
/* get a detoasted copy of the rel's ACL */
|
||||||
old_acl = DatumGetAclPCopy(aclDatum);
|
old_acl = DatumGetAclPCopy(aclDatum);
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ACLDEBUG
|
#ifdef ACLDEBUG
|
||||||
dumpacl(old_acl);
|
dumpacl(old_acl);
|
||||||
#endif
|
#endif
|
||||||
|
new_acl = old_acl;
|
||||||
|
|
||||||
new_acl = aclinsert3(old_acl, mod_aip, modechg);
|
foreach(j, stmt->grantees)
|
||||||
|
{
|
||||||
|
PrivGrantee *grantee = (PrivGrantee *)lfirst(j);
|
||||||
|
char *granteeString;
|
||||||
|
char *aclString;
|
||||||
|
AclItem aclitem;
|
||||||
|
unsigned modechg;
|
||||||
|
|
||||||
|
if (grantee->username)
|
||||||
|
granteeString = aclmakeuser("U", grantee->username);
|
||||||
|
else if (grantee->groupname)
|
||||||
|
granteeString = aclmakeuser("G", grantee->groupname);
|
||||||
|
else
|
||||||
|
granteeString = aclmakeuser("A", "");
|
||||||
|
|
||||||
|
aclString = makeAclString(stmt->privileges, granteeString,
|
||||||
|
stmt->is_grant ? '+' : '-');
|
||||||
|
|
||||||
|
/* Convert string ACL spec into internal form */
|
||||||
|
aclparse(aclString, &aclitem, &modechg);
|
||||||
|
new_acl = aclinsert3(new_acl, &aclitem, modechg);
|
||||||
#ifdef ACLDEBUG
|
#ifdef ACLDEBUG
|
||||||
dumpacl(new_acl);
|
dumpacl(new_acl);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* finished building new ACL value, now insert it */
|
||||||
for (i = 0; i < Natts_pg_class; ++i)
|
for (i = 0; i < Natts_pg_class; ++i)
|
||||||
{
|
{
|
||||||
replaces[i] = ' ';
|
replaces[i] = ' ';
|
||||||
nulls[i] = ' '; /* ignored if replaces[i] == ' ' anyway */
|
nulls[i] = ' '; /* ignored if replaces[i]==' ' anyway */
|
||||||
values[i] = (Datum) NULL; /* ignored if replaces[i] == ' '
|
values[i] = (Datum) NULL; /* ignored if replaces[i]==' ' anyway */
|
||||||
* anyway */
|
|
||||||
}
|
}
|
||||||
replaces[Anum_pg_class_relacl - 1] = 'r';
|
replaces[Anum_pg_class_relacl - 1] = 'r';
|
||||||
values[Anum_pg_class_relacl - 1] = PointerGetDatum(new_acl);
|
values[Anum_pg_class_relacl - 1] = PointerGetDatum(new_acl);
|
||||||
@ -140,18 +171,24 @@ ChangeAcl(char *relname,
|
|||||||
|
|
||||||
simple_heap_update(relation, &newtuple->t_self, newtuple);
|
simple_heap_update(relation, &newtuple->t_self, newtuple);
|
||||||
|
|
||||||
/* keep the catalog indices up to date */
|
{
|
||||||
|
/* keep the catalog indexes up to date */
|
||||||
|
Relation idescs[Num_pg_class_indices];
|
||||||
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices,
|
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices,
|
||||||
idescs);
|
idescs);
|
||||||
CatalogIndexInsert(idescs, Num_pg_class_indices, relation, newtuple);
|
CatalogIndexInsert(idescs, Num_pg_class_indices, relation, newtuple);
|
||||||
CatalogCloseIndices(Num_pg_class_indices, idescs);
|
CatalogCloseIndices(Num_pg_class_indices, idescs);
|
||||||
|
}
|
||||||
heap_close(relation, RowExclusiveLock);
|
|
||||||
|
|
||||||
pfree(old_acl);
|
pfree(old_acl);
|
||||||
pfree(new_acl);
|
pfree(new_acl);
|
||||||
|
|
||||||
|
heap_close(relation, RowExclusiveLock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AclId
|
AclId
|
||||||
get_grosysid(char *groname)
|
get_grosysid(char *groname)
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.143 2001/06/05 05:26:03 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.144 2001/06/09 23:21:54 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
#include "optimizer/clauses.h"
|
#include "optimizer/clauses.h"
|
||||||
#include "optimizer/planmain.h"
|
#include "optimizer/planmain.h"
|
||||||
#include "utils/acl.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1856,14 +1855,29 @@ _copyAlterTableStmt(AlterTableStmt *from)
|
|||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ChangeACLStmt *
|
static GrantStmt *
|
||||||
_copyChangeACLStmt(ChangeACLStmt *from)
|
_copyGrantStmt(GrantStmt *from)
|
||||||
{
|
{
|
||||||
ChangeACLStmt *newnode = makeNode(ChangeACLStmt);
|
GrantStmt *newnode = makeNode(GrantStmt);
|
||||||
|
|
||||||
Node_Copy(from, newnode, relNames);
|
newnode->is_grant = from->is_grant;
|
||||||
if (from->aclString)
|
Node_Copy(from, newnode, relnames);
|
||||||
newnode->aclString = pstrdup(from->aclString);
|
if (from->privileges)
|
||||||
|
newnode->privileges = pstrdup(from->privileges);
|
||||||
|
Node_Copy(from, newnode, grantees);
|
||||||
|
|
||||||
|
return newnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PrivGrantee *
|
||||||
|
_copyPrivGrantee(PrivGrantee *from)
|
||||||
|
{
|
||||||
|
PrivGrantee *newnode = makeNode(PrivGrantee);
|
||||||
|
|
||||||
|
if (from->username)
|
||||||
|
newnode->username = pstrdup(from->username);
|
||||||
|
if (from->groupname)
|
||||||
|
newnode->groupname = pstrdup(from->groupname);
|
||||||
|
|
||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
@ -2729,8 +2743,8 @@ copyObject(void *from)
|
|||||||
case T_AlterTableStmt:
|
case T_AlterTableStmt:
|
||||||
retval = _copyAlterTableStmt(from);
|
retval = _copyAlterTableStmt(from);
|
||||||
break;
|
break;
|
||||||
case T_ChangeACLStmt:
|
case T_GrantStmt:
|
||||||
retval = _copyChangeACLStmt(from);
|
retval = _copyGrantStmt(from);
|
||||||
break;
|
break;
|
||||||
case T_ClosePortalStmt:
|
case T_ClosePortalStmt:
|
||||||
retval = _copyClosePortalStmt(from);
|
retval = _copyClosePortalStmt(from);
|
||||||
@ -2943,6 +2957,9 @@ copyObject(void *from)
|
|||||||
case T_FkConstraint:
|
case T_FkConstraint:
|
||||||
retval = _copyFkConstraint(from);
|
retval = _copyFkConstraint(from);
|
||||||
break;
|
break;
|
||||||
|
case T_PrivGrantee:
|
||||||
|
retval = _copyPrivGrantee(from);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "copyObject: don't know how to copy node type %d",
|
elog(ERROR, "copyObject: don't know how to copy node type %d",
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.91 2001/06/05 05:26:03 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.92 2001/06/09 23:21:54 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
#include "nodes/plannodes.h"
|
#include "nodes/plannodes.h"
|
||||||
#include "nodes/relation.h"
|
#include "nodes/relation.h"
|
||||||
#include "utils/acl.h"
|
|
||||||
#include "utils/datum.h"
|
#include "utils/datum.h"
|
||||||
|
|
||||||
|
|
||||||
@ -755,16 +754,27 @@ _equalAlterTableStmt(AlterTableStmt *a, AlterTableStmt *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_equalChangeACLStmt(ChangeACLStmt *a, ChangeACLStmt *b)
|
_equalGrantStmt(GrantStmt *a, GrantStmt *b)
|
||||||
{
|
{
|
||||||
if (!equal(a->relNames, b->relNames))
|
if (a->is_grant != b->is_grant)
|
||||||
return false;
|
return false;
|
||||||
if (!equalstr(a->aclString, b->aclString))
|
if (!equal(a->relnames, b->relnames))
|
||||||
|
return false;
|
||||||
|
if (!equalstr(a->privileges, b->privileges))
|
||||||
|
return false;
|
||||||
|
if (!equal(a->grantees, b->grantees))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_equalPrivGrantee(PrivGrantee *a, PrivGrantee *b)
|
||||||
|
{
|
||||||
|
return equalstr(a->username, b->username)
|
||||||
|
&& equalstr(a->groupname, b->groupname);
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_equalClosePortalStmt(ClosePortalStmt *a, ClosePortalStmt *b)
|
_equalClosePortalStmt(ClosePortalStmt *a, ClosePortalStmt *b)
|
||||||
{
|
{
|
||||||
@ -1898,8 +1908,8 @@ equal(void *a, void *b)
|
|||||||
case T_AlterTableStmt:
|
case T_AlterTableStmt:
|
||||||
retval = _equalAlterTableStmt(a, b);
|
retval = _equalAlterTableStmt(a, b);
|
||||||
break;
|
break;
|
||||||
case T_ChangeACLStmt:
|
case T_GrantStmt:
|
||||||
retval = _equalChangeACLStmt(a, b);
|
retval = _equalGrantStmt(a, b);
|
||||||
break;
|
break;
|
||||||
case T_ClosePortalStmt:
|
case T_ClosePortalStmt:
|
||||||
retval = _equalClosePortalStmt(a, b);
|
retval = _equalClosePortalStmt(a, b);
|
||||||
@ -2113,6 +2123,9 @@ equal(void *a, void *b)
|
|||||||
case T_FkConstraint:
|
case T_FkConstraint:
|
||||||
retval = _equalFkConstraint(a, b);
|
retval = _equalFkConstraint(a, b);
|
||||||
break;
|
break;
|
||||||
|
case T_PrivGrantee:
|
||||||
|
retval = _equalPrivGrantee(a, b);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
elog(NOTICE, "equal: don't know whether nodes of type %d are equal",
|
elog(NOTICE, "equal: don't know whether nodes of type %d are equal",
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.229 2001/06/07 04:50:56 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.230 2001/06/09 23:21:54 petere Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -177,7 +177,9 @@ static void doNegateFloat(Value *v);
|
|||||||
OptUseOp, opt_class, SpecialRuleRelation
|
OptUseOp, opt_class, SpecialRuleRelation
|
||||||
|
|
||||||
%type <str> opt_level, opt_encoding
|
%type <str> opt_level, opt_encoding
|
||||||
%type <str> privileges, operation_commalist, grantee
|
%type <str> privileges, operation_commalist
|
||||||
|
%type <node> grantee
|
||||||
|
%type <list> grantee_list
|
||||||
%type <chr> operation, TriggerOneEvent
|
%type <chr> operation, TriggerOneEvent
|
||||||
|
|
||||||
%type <list> stmtblock, stmtmulti,
|
%type <list> stmtblock, stmtmulti,
|
||||||
@ -2241,14 +2243,18 @@ from_in: IN
|
|||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* QUERY:
|
* GRANT privileges ON [TABLE] relation_name_list TO [GROUP] grantee, ...
|
||||||
* GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
|
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
GrantStmt: GRANT privileges ON opt_table relation_name_list TO grantee opt_with_grant
|
GrantStmt: GRANT privileges ON opt_table relation_name_list TO grantee_list opt_with_grant
|
||||||
{
|
{
|
||||||
$$ = (Node*)makeAclStmt($2,$5,$7,'+');
|
GrantStmt *n = makeNode(GrantStmt);
|
||||||
|
n->is_grant = true;
|
||||||
|
n->relnames = $5;
|
||||||
|
n->privileges = $2;
|
||||||
|
n->grantees = $7;
|
||||||
|
$$ = (Node*)n;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -2308,18 +2314,31 @@ operation: SELECT
|
|||||||
|
|
||||||
grantee: PUBLIC
|
grantee: PUBLIC
|
||||||
{
|
{
|
||||||
$$ = aclmakeuser("A","");
|
PrivGrantee *n = makeNode(PrivGrantee);
|
||||||
|
n->username = NULL;
|
||||||
|
n->groupname = NULL;
|
||||||
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
| GROUP ColId
|
| GROUP ColId
|
||||||
{
|
{
|
||||||
$$ = aclmakeuser("G",$2);
|
PrivGrantee *n = makeNode(PrivGrantee);
|
||||||
|
n->username = NULL;
|
||||||
|
n->groupname = $2;
|
||||||
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
| ColId
|
| ColId
|
||||||
{
|
{
|
||||||
$$ = aclmakeuser("U",$1);
|
PrivGrantee *n = makeNode(PrivGrantee);
|
||||||
|
n->username = $1;
|
||||||
|
n->groupname = NULL;
|
||||||
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
grantee_list: grantee { $$ = makeList1($1); }
|
||||||
|
| grantee_list ',' grantee { $$ = lappend($1, $3); }
|
||||||
|
|
||||||
|
|
||||||
opt_with_grant: WITH GRANT OPTION
|
opt_with_grant: WITH GRANT OPTION
|
||||||
{
|
{
|
||||||
elog(ERROR,"WITH GRANT OPTION is not supported. Only relation owners can set privileges");
|
elog(ERROR,"WITH GRANT OPTION is not supported. Only relation owners can set privileges");
|
||||||
@ -2330,14 +2349,18 @@ opt_with_grant: WITH GRANT OPTION
|
|||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* QUERY:
|
* REVOKE privileges ON [TABLE] relation_name_list FROM user, ...
|
||||||
* REVOKE [privileges] ON [relation_name] FROM [user]
|
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
RevokeStmt: REVOKE privileges ON opt_table relation_name_list FROM grantee
|
RevokeStmt: REVOKE privileges ON opt_table relation_name_list FROM grantee_list
|
||||||
{
|
{
|
||||||
$$ = (Node*)makeAclStmt($2,$5,$7,'-');
|
GrantStmt *n = makeNode(GrantStmt);
|
||||||
|
n->is_grant = false;
|
||||||
|
n->relnames = $5;
|
||||||
|
n->privileges = $2;
|
||||||
|
n->grantees = $7;
|
||||||
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.112 2001/05/30 20:52:32 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.113 2001/06/09 23:21:54 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -472,13 +472,13 @@ ProcessUtility(Node *parsetree,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case T_ChangeACLStmt:
|
case T_GrantStmt:
|
||||||
{
|
{
|
||||||
ChangeACLStmt *stmt = (ChangeACLStmt *) parsetree;
|
GrantStmt *stmt = (GrantStmt *) parsetree;
|
||||||
|
commandTag = stmt->is_grant ? "GRANT" : "REVOKE";
|
||||||
|
set_ps_display(commandTag);
|
||||||
|
|
||||||
set_ps_display(commandTag = "CHANGE");
|
ExecuteGrantStmt(stmt);
|
||||||
|
|
||||||
ExecuteChangeACLStmt(stmt);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.60 2001/06/05 19:34:56 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.61 2001/06/09 23:21:55 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -27,15 +27,13 @@
|
|||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
static char *getid(char *s, char *n);
|
static const char *getid(const char *s, char *n);
|
||||||
static bool aclitemeq(AclItem *a1, AclItem *a2);
|
static bool aclitemeq(const AclItem *a1, const AclItem *a2);
|
||||||
static bool aclitemgt(AclItem *a1, AclItem *a2);
|
static bool aclitemgt(const AclItem *a1, const AclItem *a2);
|
||||||
static char *aclparse(char *s, AclItem *aip, unsigned *modechg);
|
|
||||||
|
|
||||||
#define ACL_IDTYPE_GID_KEYWORD "group"
|
#define ACL_IDTYPE_GID_KEYWORD "group"
|
||||||
#define ACL_IDTYPE_UID_KEYWORD "user"
|
#define ACL_IDTYPE_UID_KEYWORD "user"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getid
|
* getid
|
||||||
* Consumes the first alphanumeric string (identifier) found in string
|
* Consumes the first alphanumeric string (identifier) found in string
|
||||||
@ -48,11 +46,11 @@ static char *aclparse(char *s, AclItem *aip, unsigned *modechg);
|
|||||||
* - loads the identifier into 'name'. (If no identifier is found, 'name'
|
* - loads the identifier into 'name'. (If no identifier is found, 'name'
|
||||||
* contains an empty string.) name must be NAMEDATALEN bytes.
|
* contains an empty string.) name must be NAMEDATALEN bytes.
|
||||||
*/
|
*/
|
||||||
static char *
|
static const char *
|
||||||
getid(char *s, char *n)
|
getid(const char *s, char *n)
|
||||||
{
|
{
|
||||||
unsigned len;
|
unsigned len;
|
||||||
char *id;
|
const char *id;
|
||||||
int in_quotes = 0;
|
int in_quotes = 0;
|
||||||
|
|
||||||
Assert(s && n);
|
Assert(s && n);
|
||||||
@ -105,8 +103,8 @@ getid(char *s, char *n)
|
|||||||
* UID/GID, id type identifier and mode type values.
|
* UID/GID, id type identifier and mode type values.
|
||||||
* - loads 'modechg' with the mode change flag.
|
* - loads 'modechg' with the mode change flag.
|
||||||
*/
|
*/
|
||||||
static char *
|
const char *
|
||||||
aclparse(char *s, AclItem *aip, unsigned *modechg)
|
aclparse(const char *s, AclItem *aip, unsigned *modechg)
|
||||||
{
|
{
|
||||||
HeapTuple htup;
|
HeapTuple htup;
|
||||||
char name[NAMEDATALEN];
|
char name[NAMEDATALEN];
|
||||||
@ -245,7 +243,7 @@ makeacl(int n)
|
|||||||
Datum
|
Datum
|
||||||
aclitemin(PG_FUNCTION_ARGS)
|
aclitemin(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
char *s = PG_GETARG_CSTRING(0);
|
const char *s = PG_GETARG_CSTRING(0);
|
||||||
AclItem *aip;
|
AclItem *aip;
|
||||||
unsigned modechg;
|
unsigned modechg;
|
||||||
|
|
||||||
@ -351,13 +349,13 @@ aclitemout(PG_FUNCTION_ARGS)
|
|||||||
* a boolean value indicating = or >
|
* a boolean value indicating = or >
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
aclitemeq(AclItem *a1, AclItem *a2)
|
aclitemeq(const AclItem *a1, const AclItem *a2)
|
||||||
{
|
{
|
||||||
return a1->ai_idtype == a2->ai_idtype && a1->ai_id == a2->ai_id;
|
return a1->ai_idtype == a2->ai_idtype && a1->ai_id == a2->ai_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
aclitemgt(AclItem *a1, AclItem *a2)
|
aclitemgt(const AclItem *a1, const AclItem *a2)
|
||||||
{
|
{
|
||||||
return ((a1->ai_idtype > a2->ai_idtype) ||
|
return ((a1->ai_idtype > a2->ai_idtype) ||
|
||||||
(a1->ai_idtype == a2->ai_idtype && a1->ai_id > a2->ai_id));
|
(a1->ai_idtype == a2->ai_idtype && a1->ai_id > a2->ai_id));
|
||||||
@ -371,7 +369,7 @@ aclitemgt(AclItem *a1, AclItem *a2)
|
|||||||
* newly-created tables (or any table with a NULL acl entry in pg_class)
|
* newly-created tables (or any table with a NULL acl entry in pg_class)
|
||||||
*/
|
*/
|
||||||
Acl *
|
Acl *
|
||||||
acldefault(char *relname, AclId ownerid)
|
acldefault(const char *relname, AclId ownerid)
|
||||||
{
|
{
|
||||||
Acl *acl;
|
Acl *acl;
|
||||||
AclItem *aip;
|
AclItem *aip;
|
||||||
@ -398,7 +396,7 @@ acldefault(char *relname, AclId ownerid)
|
|||||||
* NB: caller is responsible for having detoasted the input ACL, if needed.
|
* NB: caller is responsible for having detoasted the input ACL, if needed.
|
||||||
*/
|
*/
|
||||||
Acl *
|
Acl *
|
||||||
aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
|
aclinsert3(const Acl *old_acl, const AclItem *mod_aip, unsigned modechg)
|
||||||
{
|
{
|
||||||
Acl *new_acl;
|
Acl *new_acl;
|
||||||
AclItem *old_aip,
|
AclItem *old_aip,
|
||||||
@ -595,41 +593,6 @@ aclcontains(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_BOOL(false);
|
PG_RETURN_BOOL(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* ExecuteChangeACLStmt
|
|
||||||
* Called to execute the utility command type ChangeACLStmt
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ExecuteChangeACLStmt(ChangeACLStmt *stmt)
|
|
||||||
{
|
|
||||||
AclItem aclitem;
|
|
||||||
unsigned modechg;
|
|
||||||
List *i;
|
|
||||||
|
|
||||||
/* see comment in pg_type.h */
|
|
||||||
Assert(ACLITEMSIZE == sizeof(AclItem));
|
|
||||||
|
|
||||||
/* Convert string ACL spec into internal form */
|
|
||||||
aclparse(stmt->aclString, &aclitem, &modechg);
|
|
||||||
|
|
||||||
foreach(i, stmt->relNames)
|
|
||||||
{
|
|
||||||
char *relname = strVal(lfirst(i));
|
|
||||||
Relation rel;
|
|
||||||
|
|
||||||
rel = heap_openr(relname, AccessExclusiveLock);
|
|
||||||
if (rel && rel->rd_rel->relkind == RELKIND_INDEX)
|
|
||||||
elog(ERROR, "\"%s\" is an index relation",
|
|
||||||
relname);
|
|
||||||
if (!pg_ownercheck(GetUserId(), relname, RELNAME))
|
|
||||||
elog(ERROR, "you do not own class \"%s\"",
|
|
||||||
relname);
|
|
||||||
ChangeAcl(relname, &aclitem, modechg);
|
|
||||||
/* close rel, but keep lock until end of xact */
|
|
||||||
heap_close(rel, NoLock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parser support routines for ACL-related statements.
|
* Parser support routines for ACL-related statements.
|
||||||
@ -648,7 +611,7 @@ ExecuteChangeACLStmt(ChangeACLStmt *stmt)
|
|||||||
* does not add duplicate privileges
|
* does not add duplicate privileges
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
aclmakepriv(char *old_privlist, char new_priv)
|
aclmakepriv(const char *old_privlist, char new_priv)
|
||||||
{
|
{
|
||||||
char *priv;
|
char *priv;
|
||||||
int i;
|
int i;
|
||||||
@ -698,7 +661,7 @@ aclmakepriv(char *old_privlist, char new_priv)
|
|||||||
* Per above comments, we can't try to resolve a user or group name here.
|
* Per above comments, we can't try to resolve a user or group name here.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
aclmakeuser(char *user_type, char *user)
|
aclmakeuser(const char *user_type, const char *user)
|
||||||
{
|
{
|
||||||
char *user_list;
|
char *user_list;
|
||||||
|
|
||||||
@ -707,22 +670,20 @@ aclmakeuser(char *user_type, char *user)
|
|||||||
return user_list;
|
return user_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* makeAclStmt:
|
* makeAclString: We take in the privileges and grantee as well as a
|
||||||
* create a ChangeACLStmt at parse time.
|
* single character '+' or '-' to indicate grant or revoke.
|
||||||
* we take in the privileges, relation_name_list, and grantee
|
|
||||||
* as well as a single character '+' or '-' to indicate grant or revoke
|
|
||||||
*
|
*
|
||||||
* We convert the information to the same external form recognized by
|
* We convert the information to the same external form recognized by
|
||||||
* aclitemin (see aclparse), and save that string in the ChangeACLStmt.
|
* aclitemin (see aclparse) and return that string. Conversion to
|
||||||
* Conversion to internal form happens when the statement is executed.
|
* internal form happens when the statement is executed.
|
||||||
*/
|
*/
|
||||||
ChangeACLStmt *
|
char *
|
||||||
makeAclStmt(char *privileges, List *rel_list, char *grantee,
|
makeAclString(const char *privileges, const char *grantee, char grant_or_revoke)
|
||||||
char grant_or_revoke)
|
|
||||||
{
|
{
|
||||||
ChangeACLStmt *n = makeNode(ChangeACLStmt);
|
|
||||||
StringInfoData str;
|
StringInfoData str;
|
||||||
|
char *ret;
|
||||||
|
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
@ -745,9 +706,7 @@ makeAclStmt(char *privileges, List *rel_list, char *grantee,
|
|||||||
appendStringInfo(&str, "%c%s",
|
appendStringInfo(&str, "%c%s",
|
||||||
grant_or_revoke, privileges);
|
grant_or_revoke, privileges);
|
||||||
}
|
}
|
||||||
n->relNames = rel_list;
|
ret = pstrdup(str.data);
|
||||||
n->aclString = pstrdup(str.data);
|
|
||||||
|
|
||||||
pfree(str.data);
|
pfree(str.data);
|
||||||
return n;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.79 2001/06/01 17:49:16 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.80 2001/06/09 23:21:55 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -17,7 +17,7 @@
|
|||||||
#include "access/hash.h"
|
#include "access/hash.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "utils/acl.h"
|
#include "utils/array.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
|
|
||||||
|
@ -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: nodes.h,v 1.89 2001/04/24 00:08:38 tgl Exp $
|
* $Id: nodes.h,v 1.90 2001/06/09 23:21:55 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -148,7 +148,7 @@ typedef enum NodeTag
|
|||||||
T_SelectStmt,
|
T_SelectStmt,
|
||||||
T_AlterTableStmt,
|
T_AlterTableStmt,
|
||||||
T_SetOperationStmt,
|
T_SetOperationStmt,
|
||||||
T_ChangeACLStmt,
|
T_GrantStmt,
|
||||||
T_ClosePortalStmt,
|
T_ClosePortalStmt,
|
||||||
T_ClusterStmt,
|
T_ClusterStmt,
|
||||||
T_CopyStmt,
|
T_CopyStmt,
|
||||||
@ -224,6 +224,7 @@ typedef enum NodeTag
|
|||||||
T_CaseWhen,
|
T_CaseWhen,
|
||||||
T_RowMarkXXX, /* not used anymore; tag# available */
|
T_RowMarkXXX, /* not used anymore; tag# available */
|
||||||
T_FkConstraint,
|
T_FkConstraint,
|
||||||
|
T_PrivGrantee,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TAGS FOR FUNCTION-CALL CONTEXT AND RESULTINFO NODES (see fmgr.h)
|
* TAGS FOR FUNCTION-CALL CONTEXT AND RESULTINFO NODES (see fmgr.h)
|
||||||
|
@ -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: parsenodes.h,v 1.130 2001/06/04 23:27:23 momjian Exp $
|
* $Id: parsenodes.h,v 1.131 2001/06/09 23:21:55 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -137,15 +137,27 @@ typedef struct AlterTableStmt
|
|||||||
} AlterTableStmt;
|
} AlterTableStmt;
|
||||||
|
|
||||||
/* ----------------------
|
/* ----------------------
|
||||||
* Change ACL Statement
|
* Grant Statement
|
||||||
* ----------------------
|
* ----------------------
|
||||||
*/
|
*/
|
||||||
typedef struct ChangeACLStmt
|
|
||||||
|
typedef struct GrantStmt
|
||||||
{
|
{
|
||||||
NodeTag type;
|
NodeTag type;
|
||||||
List *relNames;
|
bool is_grant; /* not revoke */
|
||||||
char *aclString;
|
List *relnames;
|
||||||
} ChangeACLStmt;
|
char *privileges;
|
||||||
|
List *grantees;
|
||||||
|
} GrantStmt;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct PrivGrantee
|
||||||
|
{
|
||||||
|
NodeTag type;
|
||||||
|
char *username; /* if both are NULL then PUBLIC */
|
||||||
|
char *groupname;
|
||||||
|
} PrivGrantee;
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------
|
/* ----------------------
|
||||||
* Close Portal Statement
|
* Close Portal Statement
|
||||||
|
@ -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.33 2001/06/05 19:34:56 tgl Exp $
|
* $Id: acl.h,v 1.34 2001/06/09 23:21:55 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* For backward-compatibility purposes we have to allow there
|
* For backward-compatibility purposes we have to allow there
|
||||||
@ -170,17 +170,14 @@ extern char *aclcheck_error_strings[];
|
|||||||
/*
|
/*
|
||||||
* routines used internally
|
* routines used internally
|
||||||
*/
|
*/
|
||||||
extern Acl *acldefault(char *relname, AclId ownerid);
|
extern Acl *acldefault(const char *relname, AclId ownerid);
|
||||||
|
extern Acl *aclinsert3(const Acl *old_acl, const AclItem *mod_aip, unsigned modechg);
|
||||||
extern Acl *aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* routines used by the parser
|
* routines used by the parser
|
||||||
*/
|
*/
|
||||||
extern char *aclmakepriv(char *old_privlist, char new_priv);
|
extern char *aclmakepriv(const char *old_privlist, char new_priv);
|
||||||
extern char *aclmakeuser(char *user_type, char *user);
|
extern char *aclmakeuser(const char *user_type, const char *user);
|
||||||
extern ChangeACLStmt *makeAclStmt(char *privs, List *rel_list, char *grantee,
|
|
||||||
char grant_or_revoke);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* exported routines (from acl.c)
|
* exported routines (from acl.c)
|
||||||
@ -191,12 +188,13 @@ extern Datum aclitemout(PG_FUNCTION_ARGS);
|
|||||||
extern Datum aclinsert(PG_FUNCTION_ARGS);
|
extern Datum aclinsert(PG_FUNCTION_ARGS);
|
||||||
extern Datum aclremove(PG_FUNCTION_ARGS);
|
extern Datum aclremove(PG_FUNCTION_ARGS);
|
||||||
extern Datum aclcontains(PG_FUNCTION_ARGS);
|
extern Datum aclcontains(PG_FUNCTION_ARGS);
|
||||||
extern void ExecuteChangeACLStmt(ChangeACLStmt *stmt);
|
extern const char *aclparse(const char *s, AclItem *aip, unsigned *modechg);
|
||||||
|
extern char *makeAclString(const char *privileges, const char *grantee, char grant_or_revoke);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* prototypes for functions in aclchk.c
|
* prototypes for functions in aclchk.c
|
||||||
*/
|
*/
|
||||||
extern void ChangeAcl(char *relname, AclItem *mod_aip, unsigned modechg);
|
extern void ExecuteGrantStmt(GrantStmt *stmt);
|
||||||
extern AclId get_grosysid(char *groname);
|
extern AclId get_grosysid(char *groname);
|
||||||
extern char *get_groname(AclId grosysid);
|
extern char *get_groname(AclId grosysid);
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ SELECT * FROM atest1;
|
|||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
GRANT ALL ON atest1 TO regressuser2;
|
GRANT ALL ON atest1 TO regressuser2;
|
||||||
GRANT SELECT ON atest1 TO regressuser3;
|
GRANT SELECT ON atest1 TO regressuser3, regressuser4;
|
||||||
SELECT * FROM atest1;
|
SELECT * FROM atest1;
|
||||||
a | b
|
a | b
|
||||||
---+---
|
---+---
|
||||||
@ -90,7 +90,7 @@ ERROR: LOCK TABLE: permission denied
|
|||||||
COPY atest2 FROM stdin; -- fail
|
COPY atest2 FROM stdin; -- fail
|
||||||
ERROR: atest2: Permission denied.
|
ERROR: atest2: Permission denied.
|
||||||
GRANT ALL ON atest1 TO PUBLIC; -- fail
|
GRANT ALL ON atest1 TO PUBLIC; -- fail
|
||||||
ERROR: you do not own class "atest1"
|
ERROR: permission denied
|
||||||
-- checks in subquery, both ok
|
-- checks in subquery, both ok
|
||||||
SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
|
SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
|
||||||
a | b
|
a | b
|
||||||
@ -146,6 +146,13 @@ SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) );
|
|||||||
ERROR: atest2: Permission denied.
|
ERROR: atest2: Permission denied.
|
||||||
SET SESSION AUTHORIZATION regressuser4;
|
SET SESSION AUTHORIZATION regressuser4;
|
||||||
COPY atest2 FROM stdin; -- ok
|
COPY atest2 FROM stdin; -- ok
|
||||||
|
SELECT * FROM atest1; -- ok
|
||||||
|
a | b
|
||||||
|
---+-----
|
||||||
|
1 | two
|
||||||
|
1 | two
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
-- groups
|
-- groups
|
||||||
SET SESSION AUTHORIZATION regressuser3;
|
SET SESSION AUTHORIZATION regressuser3;
|
||||||
CREATE TABLE atest3 (one int, two int, three int);
|
CREATE TABLE atest3 (one int, two int, three int);
|
||||||
@ -167,8 +174,7 @@ SELECT * FROM atestv1; -- ok
|
|||||||
1 | two
|
1 | two
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
GRANT SELECT ON atestv1 TO regressuser4;
|
GRANT SELECT ON atestv1, atestv3 TO regressuser4;
|
||||||
GRANT SELECT ON atestv3 TO regressuser4;
|
|
||||||
SET SESSION AUTHORIZATION regressuser4;
|
SET SESSION AUTHORIZATION regressuser4;
|
||||||
SELECT * FROM atestv1; -- ok
|
SELECT * FROM atestv1; -- ok
|
||||||
a | b
|
a | b
|
||||||
|
@ -34,7 +34,7 @@ REVOKE ALL ON atest1 FROM PUBLIC;
|
|||||||
SELECT * FROM atest1;
|
SELECT * FROM atest1;
|
||||||
|
|
||||||
GRANT ALL ON atest1 TO regressuser2;
|
GRANT ALL ON atest1 TO regressuser2;
|
||||||
GRANT SELECT ON atest1 TO regressuser3;
|
GRANT SELECT ON atest1 TO regressuser3, regressuser4;
|
||||||
SELECT * FROM atest1;
|
SELECT * FROM atest1;
|
||||||
|
|
||||||
CREATE TABLE atest2 (col1 varchar(10), col2 boolean);
|
CREATE TABLE atest2 (col1 varchar(10), col2 boolean);
|
||||||
@ -93,6 +93,7 @@ SET SESSION AUTHORIZATION regressuser4;
|
|||||||
COPY atest2 FROM stdin; -- ok
|
COPY atest2 FROM stdin; -- ok
|
||||||
bar true
|
bar true
|
||||||
\.
|
\.
|
||||||
|
SELECT * FROM atest1; -- ok
|
||||||
|
|
||||||
|
|
||||||
-- groups
|
-- groups
|
||||||
@ -117,8 +118,7 @@ CREATE VIEW atestv2 AS SELECT * FROM atest2;
|
|||||||
CREATE VIEW atestv3 AS SELECT * FROM atest3; -- ok
|
CREATE VIEW atestv3 AS SELECT * FROM atest3; -- ok
|
||||||
|
|
||||||
SELECT * FROM atestv1; -- ok
|
SELECT * FROM atestv1; -- ok
|
||||||
GRANT SELECT ON atestv1 TO regressuser4;
|
GRANT SELECT ON atestv1, atestv3 TO regressuser4;
|
||||||
GRANT SELECT ON atestv3 TO regressuser4;
|
|
||||||
|
|
||||||
SET SESSION AUTHORIZATION regressuser4;
|
SET SESSION AUTHORIZATION regressuser4;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user