mirror of
https://github.com/postgres/postgres.git
synced 2025-07-03 20:02:46 +03:00
Here's the Create/Alter/Drop Group stuff that's been really overdue. I
didn't have time for documentation yet, but I'll write some. There are still some things to work out what happens when you alter or drop users, but the group stuff in and by itself is done. -- Peter Eisentraut Sernanders väg 10:115
This commit is contained in:
@ -5,7 +5,7 @@
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: user.c,v 1.44 1999/12/14 00:17:33 momjian Exp $
|
||||
* $Id: user.c,v 1.45 1999/12/16 17:24:13 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -20,12 +20,16 @@
|
||||
#include "catalog/catname.h"
|
||||
#include "catalog/pg_database.h"
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "catalog/pg_group.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "commands/copy.h"
|
||||
#include "commands/user.h"
|
||||
#include "libpq/crypt.h"
|
||||
#include "miscadmin.h"
|
||||
#include "nodes/pg_list.h"
|
||||
#include "tcop/tcopprot.h"
|
||||
#include "utils/acl.h"
|
||||
#include "utils/array.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
static void CheckPgUserAclNotNull(void);
|
||||
@ -118,6 +122,7 @@ DefineUser(CreateUserStmt *stmt, CommandDest dest)
|
||||
havepassword,
|
||||
havevaluntil;
|
||||
int max_id = -1;
|
||||
List *item;
|
||||
|
||||
havesysid = stmt->sysid >= 0;
|
||||
havepassword = stmt->password && stmt->password[0];
|
||||
@ -218,8 +223,18 @@ DefineUser(CreateUserStmt *stmt, CommandDest dest)
|
||||
pg_exec_query_dest(sql, dest, false);
|
||||
|
||||
/*
|
||||
* Add stuff here for groups?
|
||||
* Add the user to the groups specified. We'll just call the below
|
||||
* AlterGroup for this.
|
||||
*/
|
||||
foreach(item, stmt->groupElts)
|
||||
{
|
||||
AlterGroupStmt ags;
|
||||
|
||||
ags.name = strVal(lfirst(item));
|
||||
ags.action = +1;
|
||||
ags.listUsers = lcons((void*)makeString(stmt->user), NIL);
|
||||
AlterGroup(&ags, dest);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the updated pg_shadow data to the flat password file.
|
||||
@ -367,6 +382,8 @@ AlterUser(AlterUserStmt *stmt, CommandDest dest)
|
||||
/*
|
||||
* Add stuff here for groups?
|
||||
*/
|
||||
if (stmt->groupElts)
|
||||
elog(NOTICE, "IN GROUP is not implemented for ALTER USER.");
|
||||
|
||||
/*
|
||||
* Write the updated pg_shadow data to the flat password file.
|
||||
@ -546,3 +563,511 @@ CheckPgUserAclNotNull()
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*** GROUP THINGS ***/
|
||||
|
||||
void
|
||||
CreateGroup(CreateGroupStmt *stmt, CommandDest dest)
|
||||
{
|
||||
Relation pg_group_rel;
|
||||
HeapScanDesc scan;
|
||||
HeapTuple tuple;
|
||||
TupleDesc pg_group_dsc;
|
||||
bool inblock;
|
||||
bool group_exists = false,
|
||||
sysid_exists = false;
|
||||
int max_id = -1;
|
||||
Datum new_record[Natts_pg_group];
|
||||
char new_record_nulls[Natts_pg_group];
|
||||
List *item, *newlist=NULL;
|
||||
ArrayType *userarray;
|
||||
|
||||
|
||||
if (!(inblock = IsTransactionBlock()))
|
||||
BeginTransactionBlock();
|
||||
|
||||
/*
|
||||
* Make sure the user can do this.
|
||||
*/
|
||||
if (pg_aclcheck(GroupRelationName, GetPgUserName(), ACL_RD | ACL_AP) != ACLCHECK_OK)
|
||||
{
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "CreateGroup: Permission denied.");
|
||||
}
|
||||
|
||||
pg_group_rel = heap_openr(GroupRelationName, AccessExclusiveLock);
|
||||
pg_group_dsc = RelationGetDescr(pg_group_rel);
|
||||
|
||||
scan = heap_beginscan(pg_group_rel, false, SnapshotNow, 0, NULL);
|
||||
while (!group_exists && !sysid_exists && HeapTupleIsValid(tuple = heap_getnext(scan, false)))
|
||||
{
|
||||
Datum datum;
|
||||
bool null;
|
||||
|
||||
datum = heap_getattr(tuple, Anum_pg_group_groname, pg_group_dsc, &null);
|
||||
group_exists = datum && !null && (strcmp((char *) datum, stmt->name) == 0);
|
||||
|
||||
datum = heap_getattr(tuple, Anum_pg_group_grosysid, pg_group_dsc, &null);
|
||||
if (stmt->sysid >= 0) /* customized id wanted */
|
||||
sysid_exists = datum && !null && ((int)datum == stmt->sysid);
|
||||
else /* pick 1 + max */
|
||||
{
|
||||
if ((int) datum > max_id)
|
||||
max_id = (int) datum;
|
||||
}
|
||||
}
|
||||
heap_endscan(scan);
|
||||
|
||||
if (group_exists || sysid_exists)
|
||||
{
|
||||
heap_close(pg_group_rel, AccessExclusiveLock);
|
||||
UserAbortTransactionBlock();
|
||||
if (group_exists)
|
||||
elog(ERROR, "CreateGroup: Group name \"%s\" already exists.", stmt->name);
|
||||
else
|
||||
elog(ERROR, "CreateGroup: Group sysid %d is already assigned.", stmt->sysid);
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate the given user names to ids
|
||||
*/
|
||||
|
||||
foreach(item, stmt->initUsers)
|
||||
{
|
||||
const char * groupuser = strVal(lfirst(item));
|
||||
Value *v;
|
||||
|
||||
tuple = SearchSysCacheTuple(SHADOWNAME,
|
||||
PointerGetDatum(groupuser),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
{
|
||||
heap_close(pg_group_rel, AccessExclusiveLock);
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "CreateGroup: User \"%s\" does not exist.", groupuser);
|
||||
}
|
||||
|
||||
v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid);
|
||||
if (!member(v, newlist))
|
||||
newlist = lcons(v, newlist);
|
||||
}
|
||||
|
||||
/* build an array to insert */
|
||||
if (newlist)
|
||||
{
|
||||
int i;
|
||||
|
||||
userarray = palloc(ARR_OVERHEAD(1) + length(newlist) * sizeof(int32));
|
||||
ARR_SIZE(userarray) = ARR_OVERHEAD(1) + length(newlist) * sizeof(int32);
|
||||
ARR_FLAGS(userarray) = 0x0;
|
||||
ARR_NDIM(userarray) = 1; /* one dimensional array */
|
||||
ARR_LBOUND(userarray)[0] = 1; /* axis starts at one */
|
||||
ARR_DIMS(userarray)[0] = length(newlist); /* axis is this long */
|
||||
/* fill the array */
|
||||
i = 0;
|
||||
foreach(item, newlist)
|
||||
{
|
||||
((int*)ARR_DATA_PTR(userarray))[i++] = intVal(lfirst(item));
|
||||
}
|
||||
}
|
||||
else
|
||||
userarray = NULL;
|
||||
|
||||
/*
|
||||
* Form a tuple to insert
|
||||
*/
|
||||
if (stmt->sysid >=0)
|
||||
max_id = stmt->sysid;
|
||||
else
|
||||
max_id++;
|
||||
|
||||
new_record[Anum_pg_group_groname-1] = (Datum)(stmt->name);
|
||||
new_record[Anum_pg_group_grosysid-1] = (Datum)(max_id);
|
||||
new_record[Anum_pg_group_grolist-1] = (Datum)userarray;
|
||||
|
||||
new_record_nulls[Anum_pg_group_groname-1] = ' ';
|
||||
new_record_nulls[Anum_pg_group_grosysid-1] = ' ';
|
||||
new_record_nulls[Anum_pg_group_grolist-1] = userarray ? ' ' : 'n';
|
||||
|
||||
tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls);
|
||||
|
||||
/*
|
||||
* Insert a new record in the pg_group_table
|
||||
*/
|
||||
heap_insert(pg_group_rel, tuple);
|
||||
|
||||
/*
|
||||
* Update indexes
|
||||
*/
|
||||
if (RelationGetForm(pg_group_rel)->relhasindex) {
|
||||
Relation idescs[Num_pg_group_indices];
|
||||
|
||||
CatalogOpenIndices(Num_pg_group_indices,
|
||||
Name_pg_group_indices, idescs);
|
||||
CatalogIndexInsert(idescs, Num_pg_group_indices, pg_group_rel,
|
||||
tuple);
|
||||
CatalogCloseIndices(Num_pg_group_indices, idescs);
|
||||
}
|
||||
|
||||
heap_close(pg_group_rel, NoLock);
|
||||
|
||||
if (IsTransactionBlock() && !inblock)
|
||||
EndTransactionBlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
AlterGroup(AlterGroupStmt *stmt, CommandDest dest)
|
||||
{
|
||||
Relation pg_group_rel;
|
||||
TupleDesc pg_group_dsc;
|
||||
bool inblock;
|
||||
HeapTuple group_tuple;
|
||||
|
||||
if (!(inblock = IsTransactionBlock()))
|
||||
BeginTransactionBlock();
|
||||
|
||||
/*
|
||||
* Make sure the user can do this.
|
||||
*/
|
||||
if (pg_aclcheck(GroupRelationName, GetPgUserName(), ACL_RD | ACL_WR) != ACLCHECK_OK)
|
||||
{
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "AlterGroup: Permission denied.");
|
||||
}
|
||||
|
||||
pg_group_rel = heap_openr(GroupRelationName, AccessExclusiveLock);
|
||||
pg_group_dsc = RelationGetDescr(pg_group_rel);
|
||||
|
||||
/*
|
||||
* Verify that group exists.
|
||||
* If we find a tuple, will take that the rest of the way and make our
|
||||
* modifications on it.
|
||||
*/
|
||||
if (!HeapTupleIsValid(group_tuple = SearchSysCacheTupleCopy(GRONAME, PointerGetDatum(stmt->name), 0, 0, 0)))
|
||||
{
|
||||
heap_close(pg_group_rel, AccessExclusiveLock);
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "AlterGroup: Group \"%s\" does not exist.", stmt->name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now decide what to do.
|
||||
*/
|
||||
if (stmt->action == 0) /* change sysid */
|
||||
{
|
||||
bool sysid_exists = false;
|
||||
ScanKeyData keys[2];
|
||||
HeapTuple tuple;
|
||||
HeapScanDesc scan;
|
||||
Datum new_record[Natts_pg_group];
|
||||
char new_record_nulls[Natts_pg_group];
|
||||
bool null;
|
||||
|
||||
/*
|
||||
* First check if the id is already assigned.
|
||||
*/
|
||||
ScanKeyEntryInitialize(&keys[0], 0x0, Anum_pg_group_grosysid, F_INT4EQ,
|
||||
Int32GetDatum(stmt->sysid));
|
||||
ScanKeyEntryInitialize(&keys[1], 0x0, Anum_pg_group_groname, F_NAMENE,
|
||||
PointerGetDatum(stmt->name));
|
||||
scan = heap_beginscan(pg_group_rel, false, SnapshotNow, 2, keys);
|
||||
|
||||
if (HeapTupleIsValid(heap_getnext(scan, false)))
|
||||
{
|
||||
heap_endscan(scan);
|
||||
heap_close(pg_group_rel, AccessExclusiveLock);
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "AlterGroup: Group sysid %d is already assigned.", stmt->sysid);
|
||||
}
|
||||
heap_endscan(scan);
|
||||
|
||||
/*
|
||||
* Insert the new tuple with the updated sysid
|
||||
*/
|
||||
new_record[Anum_pg_group_groname-1] = (Datum)(stmt->name);
|
||||
new_record[Anum_pg_group_grosysid-1] = (Datum)(stmt->sysid);
|
||||
new_record[Anum_pg_group_grolist-1] = heap_getattr(group_tuple, Anum_pg_group_grolist, pg_group_dsc, &null);
|
||||
new_record_nulls[Anum_pg_group_groname-1] = ' ';
|
||||
new_record_nulls[Anum_pg_group_grosysid-1] = ' ';
|
||||
new_record_nulls[Anum_pg_group_grolist-1] = null ? 'n' : ' ';
|
||||
|
||||
tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls);
|
||||
heap_update(pg_group_rel, &group_tuple->t_self, tuple, NULL);
|
||||
|
||||
/* Update indexes */
|
||||
if (RelationGetForm(pg_group_rel)->relhasindex) {
|
||||
Relation idescs[Num_pg_group_indices];
|
||||
|
||||
CatalogOpenIndices(Num_pg_group_indices,
|
||||
Name_pg_group_indices, idescs);
|
||||
CatalogIndexInsert(idescs, Num_pg_group_indices, pg_group_rel,
|
||||
tuple);
|
||||
CatalogCloseIndices(Num_pg_group_indices, idescs);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* add users to group
|
||||
*/
|
||||
else if (stmt->action > 0)
|
||||
{
|
||||
Datum new_record[Natts_pg_group];
|
||||
char new_record_nulls[Natts_pg_group] = { ' ', ' ', ' '};
|
||||
ArrayType *newarray, *oldarray;
|
||||
List * newlist = NULL, *item;
|
||||
HeapTuple tuple;
|
||||
bool null = false;
|
||||
Datum datum = heap_getattr(group_tuple, Anum_pg_group_grolist, pg_group_dsc, &null);
|
||||
int i;
|
||||
|
||||
oldarray = (ArrayType*)datum;
|
||||
Assert(null || ARR_NDIM(oldarray) == 1);
|
||||
/* first add the old array to the hitherto empty list */
|
||||
if (!null)
|
||||
for (i = ARR_LBOUND(oldarray)[0]; i < ARR_LBOUND(oldarray)[0] + ARR_DIMS(oldarray)[0]; i++)
|
||||
{
|
||||
int index, arrval;
|
||||
Value *v;
|
||||
bool valueNull;
|
||||
index = i;
|
||||
arrval = DatumGetInt32(array_ref(oldarray, 1, &index, true/*by value*/,
|
||||
sizeof(int), 0, &valueNull));
|
||||
v = makeInteger(arrval);
|
||||
/* filter out duplicates */
|
||||
if (!member(v, newlist))
|
||||
newlist = lcons(v, newlist);
|
||||
}
|
||||
|
||||
/*
|
||||
* now convert the to be added usernames to sysids and add them
|
||||
* to the list
|
||||
*/
|
||||
foreach(item, stmt->listUsers)
|
||||
{
|
||||
Value *v;
|
||||
/* Get the uid of the proposed user to add. */
|
||||
tuple = SearchSysCacheTuple(SHADOWNAME,
|
||||
PointerGetDatum(strVal(lfirst(item))),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
{
|
||||
heap_close(pg_group_rel, AccessExclusiveLock);
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "AlterGroup: User \"%s\" does not exist.", strVal(lfirst(item)));
|
||||
}
|
||||
|
||||
v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid);
|
||||
if (!member(v, newlist))
|
||||
newlist = lcons(v, newlist);
|
||||
else
|
||||
elog(NOTICE, "AlterGroup: User \"%s\" is already in group \"%s\".", strVal(lfirst(item)), stmt->name);
|
||||
}
|
||||
|
||||
newarray = palloc(ARR_OVERHEAD(1) + length(newlist) * sizeof(int32));
|
||||
ARR_SIZE(newarray) = ARR_OVERHEAD(1) + length(newlist) * sizeof(int32);
|
||||
ARR_FLAGS(newarray) = 0x0;
|
||||
ARR_NDIM(newarray) = 1; /* one dimensional array */
|
||||
ARR_LBOUND(newarray)[0] = 1; /* axis starts at one */
|
||||
ARR_DIMS(newarray)[0] = length(newlist); /* axis is this long */
|
||||
/* fill the array */
|
||||
i = 0;
|
||||
foreach(item, newlist)
|
||||
{
|
||||
((int*)ARR_DATA_PTR(newarray))[i++] = intVal(lfirst(item));
|
||||
}
|
||||
|
||||
/*
|
||||
* Form a tuple with the new array and write it back.
|
||||
*/
|
||||
new_record[Anum_pg_group_groname-1] = (Datum)(stmt->name);
|
||||
new_record[Anum_pg_group_grosysid-1] = heap_getattr(group_tuple, Anum_pg_group_grosysid, pg_group_dsc, &null);
|
||||
new_record[Anum_pg_group_grolist-1] = PointerGetDatum(newarray);
|
||||
|
||||
tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls);
|
||||
heap_update(pg_group_rel, &group_tuple->t_self, tuple, NULL);
|
||||
|
||||
/* Update indexes */
|
||||
if (RelationGetForm(pg_group_rel)->relhasindex) {
|
||||
Relation idescs[Num_pg_group_indices];
|
||||
|
||||
CatalogOpenIndices(Num_pg_group_indices,
|
||||
Name_pg_group_indices, idescs);
|
||||
CatalogIndexInsert(idescs, Num_pg_group_indices, pg_group_rel,
|
||||
tuple);
|
||||
CatalogCloseIndices(Num_pg_group_indices, idescs);
|
||||
}
|
||||
} /* endif alter group add user */
|
||||
|
||||
/*
|
||||
* drop users from group
|
||||
*/
|
||||
else if (stmt->action < 0)
|
||||
{
|
||||
Datum datum;
|
||||
bool null;
|
||||
|
||||
datum = heap_getattr(group_tuple, Anum_pg_group_grolist, pg_group_dsc, &null);
|
||||
if (null)
|
||||
elog(NOTICE, "AlterGroup: Group \"%s\"'s membership is NULL.", stmt->name);
|
||||
else
|
||||
{
|
||||
HeapTuple tuple;
|
||||
Datum new_record[Natts_pg_group];
|
||||
char new_record_nulls[Natts_pg_group] = { ' ', ' ', ' '};
|
||||
ArrayType *oldarray, *newarray;
|
||||
List * newlist = NULL, *item;
|
||||
int i;
|
||||
|
||||
oldarray = (ArrayType*)datum;
|
||||
Assert(ARR_NDIM(oldarray) == 1);
|
||||
/* first add the old array to the hitherto empty list */
|
||||
for (i = ARR_LBOUND(oldarray)[0]; i < ARR_LBOUND(oldarray)[0] + ARR_DIMS(oldarray)[0]; i++)
|
||||
{
|
||||
int index, arrval;
|
||||
Value *v;
|
||||
bool valueNull;
|
||||
index = i;
|
||||
arrval = DatumGetInt32(array_ref(oldarray, 1, &index, true/*by value*/,
|
||||
sizeof(int), 0, &valueNull));
|
||||
v = makeInteger(arrval);
|
||||
/* filter out duplicates */
|
||||
if (!member(v, newlist))
|
||||
newlist = lcons(v, newlist);
|
||||
}
|
||||
|
||||
/*
|
||||
* now convert the to be dropped usernames to sysids and remove
|
||||
* them from the list
|
||||
*/
|
||||
foreach(item, stmt->listUsers)
|
||||
{
|
||||
Value *v;
|
||||
/* Get the uid of the proposed user to drop. */
|
||||
tuple = SearchSysCacheTuple(SHADOWNAME,
|
||||
PointerGetDatum(strVal(lfirst(item))),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
{
|
||||
heap_close(pg_group_rel, AccessExclusiveLock);
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "AlterGroup: User \"%s\" does not exist.", strVal(lfirst(item)));
|
||||
}
|
||||
|
||||
v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid);
|
||||
if (member(v, newlist))
|
||||
newlist = LispRemove(v, newlist);
|
||||
else
|
||||
elog(NOTICE, "AlterGroup: User \"%s\" is not in group \"%s\".", strVal(lfirst(item)), stmt->name);
|
||||
}
|
||||
|
||||
newarray = palloc(ARR_OVERHEAD(1) + length(newlist) * sizeof(int32));
|
||||
ARR_SIZE(newarray) = ARR_OVERHEAD(1) + length(newlist) * sizeof(int32);
|
||||
ARR_FLAGS(newarray) = 0x0;
|
||||
ARR_NDIM(newarray) = 1; /* one dimensional array */
|
||||
ARR_LBOUND(newarray)[0] = 1; /* axis starts at one */
|
||||
ARR_DIMS(newarray)[0] = length(newlist); /* axis is this long */
|
||||
/* fill the array */
|
||||
i = 0;
|
||||
foreach(item, newlist)
|
||||
{
|
||||
((int*)ARR_DATA_PTR(newarray))[i++] = intVal(lfirst(item));
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert the new tuple with the updated user list
|
||||
*/
|
||||
new_record[Anum_pg_group_groname-1] = (Datum)(stmt->name);
|
||||
new_record[Anum_pg_group_grosysid-1] = heap_getattr(group_tuple, Anum_pg_group_grosysid, pg_group_dsc, &null);
|
||||
new_record[Anum_pg_group_grolist-1] = PointerGetDatum(newarray);
|
||||
|
||||
tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls);
|
||||
heap_update(pg_group_rel, &group_tuple->t_self, tuple, NULL);
|
||||
|
||||
/* Update indexes */
|
||||
if (RelationGetForm(pg_group_rel)->relhasindex) {
|
||||
Relation idescs[Num_pg_group_indices];
|
||||
|
||||
CatalogOpenIndices(Num_pg_group_indices,
|
||||
Name_pg_group_indices, idescs);
|
||||
CatalogIndexInsert(idescs, Num_pg_group_indices, pg_group_rel,
|
||||
tuple);
|
||||
CatalogCloseIndices(Num_pg_group_indices, idescs);
|
||||
}
|
||||
|
||||
} /* endif group not null */
|
||||
} /* endif alter group drop user */
|
||||
|
||||
heap_close(pg_group_rel, NoLock);
|
||||
|
||||
pfree(group_tuple);
|
||||
|
||||
if (IsTransactionBlock() && !inblock)
|
||||
EndTransactionBlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
DropGroup(DropGroupStmt *stmt, CommandDest dest)
|
||||
{
|
||||
Relation pg_group_rel;
|
||||
HeapScanDesc scan;
|
||||
HeapTuple tuple;
|
||||
TupleDesc pg_group_dsc;
|
||||
bool inblock;
|
||||
bool gro_exists = false;
|
||||
|
||||
if (!(inblock = IsTransactionBlock()))
|
||||
BeginTransactionBlock();
|
||||
|
||||
/*
|
||||
* Make sure the user can do this.
|
||||
*/
|
||||
if (pg_aclcheck(GroupRelationName, GetPgUserName(), ACL_RD | ACL_WR) != ACLCHECK_OK)
|
||||
{
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "DropGroup: Permission denied.");
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan the pg_group table and delete all matching users.
|
||||
*/
|
||||
pg_group_rel = heap_openr(GroupRelationName, AccessExclusiveLock);
|
||||
pg_group_dsc = RelationGetDescr(pg_group_rel);
|
||||
scan = heap_beginscan(pg_group_rel, false, SnapshotNow, 0, NULL);
|
||||
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, false)))
|
||||
{
|
||||
Datum datum;
|
||||
bool null;
|
||||
|
||||
datum = heap_getattr(tuple, Anum_pg_group_groname, pg_group_dsc, &null);
|
||||
if (datum && !null && strcmp((char*)datum, stmt->name)==0)
|
||||
{
|
||||
gro_exists = true;
|
||||
heap_delete(pg_group_rel, &tuple->t_self, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
heap_endscan(scan);
|
||||
|
||||
/*
|
||||
* Did we find any?
|
||||
*/
|
||||
if (!gro_exists)
|
||||
{
|
||||
heap_close(pg_group_rel, AccessExclusiveLock);
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "DropGroup: Group \"%s\" does not exist.", stmt->name);
|
||||
}
|
||||
|
||||
heap_close(pg_group_rel, NoLock);
|
||||
|
||||
if (IsTransactionBlock() && !inblock)
|
||||
EndTransactionBlock();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user