summaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/alter.c2
-rw-r--r--src/backend/commands/extension.c2
-rw-r--r--src/backend/commands/foreigncmds.c58
-rw-r--r--src/backend/commands/policy.c18
-rw-r--r--src/backend/commands/schemacmds.c21
-rw-r--r--src/backend/commands/tablecmds.c4
-rw-r--r--src/backend/commands/tablespace.c2
-rw-r--r--src/backend/commands/user.c116
8 files changed, 115 insertions, 108 deletions
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index 59aacef7ea9..3ddd7ec4343 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -699,7 +699,7 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
ObjectAddress
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
{
- Oid newowner = get_role_oid(stmt->newowner, false);
+ Oid newowner = get_rolespec_oid(stmt->newowner, false);
switch (stmt->objectType)
{
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index aa733575e46..5cc74d03c11 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -1371,7 +1371,7 @@ CreateExtension(CreateExtensionStmt *stmt)
CreateSchemaStmt *csstmt = makeNode(CreateSchemaStmt);
csstmt->schemaname = schemaName;
- csstmt->authid = NULL; /* will be created by current user */
+ csstmt->authrole = NULL; /* will be created by current user */
csstmt->schemaElts = NIL;
csstmt->if_not_exists = false;
CreateSchemaCommand(csstmt, NULL);
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index bd4839189e6..3b85c2c017e 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -198,24 +198,6 @@ transformGenericOptions(Oid catalogId,
/*
- * Convert the user mapping user name to OID
- */
-static Oid
-GetUserOidFromMapping(const char *username, bool missing_ok)
-{
- if (!username)
- /* PUBLIC user mapping */
- return InvalidOid;
-
- if (strcmp(username, "current_user") == 0)
- /* map to the owner */
- return GetUserId();
-
- /* map to provided user */
- return get_role_oid(username, missing_ok);
-}
-
-/*
* Internal workhorse for changing a data wrapper's owner.
*
* Allow this only for superusers; also the new owner must be a
@@ -1156,10 +1138,14 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
ObjectAddress referenced;
ForeignServer *srv;
ForeignDataWrapper *fdw;
+ RoleSpec *role = (RoleSpec *) stmt->user;
rel = heap_open(UserMappingRelationId, RowExclusiveLock);
- useId = GetUserOidFromMapping(stmt->username, false);
+ if (role->roletype == ROLESPEC_PUBLIC)
+ useId = ACL_ID_PUBLIC;
+ else
+ useId = get_rolespec_oid(stmt->user, false);
/* Check that the server exists. */
srv = GetForeignServerByName(stmt->servername, false);
@@ -1252,10 +1238,15 @@ AlterUserMapping(AlterUserMappingStmt *stmt)
Oid umId;
ForeignServer *srv;
ObjectAddress address;
+ RoleSpec *role = (RoleSpec *) stmt->user;
rel = heap_open(UserMappingRelationId, RowExclusiveLock);
- useId = GetUserOidFromMapping(stmt->username, false);
+ if (role->roletype == ROLESPEC_PUBLIC)
+ useId = ACL_ID_PUBLIC;
+ else
+ useId = get_rolespec_oid(stmt->user, false);
+
srv = GetForeignServerByName(stmt->servername, false);
umId = GetSysCacheOid2(USERMAPPINGUSERSERVER,
@@ -1338,20 +1329,27 @@ RemoveUserMapping(DropUserMappingStmt *stmt)
Oid useId;
Oid umId;
ForeignServer *srv;
+ RoleSpec *role = (RoleSpec *) stmt->user;
- useId = GetUserOidFromMapping(stmt->username, stmt->missing_ok);
- srv = GetForeignServerByName(stmt->servername, true);
-
- if (stmt->username && !OidIsValid(useId))
+ if (role->roletype == ROLESPEC_PUBLIC)
+ useId = ACL_ID_PUBLIC;
+ else
{
- /*
- * IF EXISTS specified, role not found and not public. Notice this and
- * leave.
- */
- elog(NOTICE, "role \"%s\" does not exist, skipping", stmt->username);
- return InvalidOid;
+ useId = get_rolespec_oid(stmt->user, stmt->missing_ok);
+ if (!OidIsValid(useId))
+ {
+ /*
+ * IF EXISTS specified, role not found and not public. Notice this
+ * and leave.
+ */
+ elog(NOTICE, "role \"%s\" does not exist, skipping",
+ role->rolename);
+ return InvalidOid;
+ }
}
+ srv = GetForeignServerByName(stmt->servername, true);
+
if (!srv)
{
if (!stmt->missing_ok)
diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c
index e86299781f9..a3d840da5cf 100644
--- a/src/backend/commands/policy.c
+++ b/src/backend/commands/policy.c
@@ -129,13 +129,7 @@ parse_policy_command(const char *cmd_name)
/*
* policy_role_list_to_array
- * helper function to convert a list of role names in to an array of
- * role ids.
- *
- * Note: If PUBLIC is provided as a role name, then ACL_ID_PUBLIC is
- * used as the role id.
- *
- * roles - the list of role names to convert.
+ * helper function to convert a list of RoleSpecs to an array of role ids.
*/
static ArrayType *
policy_role_list_to_array(List *roles)
@@ -162,25 +156,25 @@ policy_role_list_to_array(List *roles)
foreach(cell, roles)
{
- Oid roleid = get_role_oid_or_public(strVal(lfirst(cell)));
+ RoleSpec *spec = lfirst(cell);
/*
* PUBLIC covers all roles, so it only makes sense alone.
*/
- if (roleid == ACL_ID_PUBLIC)
+ if (spec->roletype == ROLESPEC_PUBLIC)
{
if (num_roles != 1)
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("ignoring roles specified other than public"),
errhint("All roles are members of the public role.")));
-
- temp_array[0] = ObjectIdGetDatum(roleid);
+ temp_array[0] = ObjectIdGetDatum(ACL_ID_PUBLIC);
num_roles = 1;
break;
}
else
- temp_array[i++] = ObjectIdGetDatum(roleid);
+ temp_array[i++] =
+ ObjectIdGetDatum(get_rolespec_oid((Node *) spec, false));
}
role_ids = construct_array(temp_array, num_roles, OIDOID, sizeof(Oid), true,
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index 722142e16ea..c090ed220f8 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -21,6 +21,7 @@
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
+#include "catalog/pg_authid.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_namespace.h"
#include "commands/dbcommands.h"
@@ -42,8 +43,7 @@ static void AlterSchemaOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerI
Oid
CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
{
- const char *schemaName = stmt->schemaname;
- const char *authId = stmt->authid;
+ const char *schemaName = stmt->schemaname;
Oid namespaceId;
OverrideSearchPath *overridePath;
List *parsetree_list;
@@ -58,11 +58,24 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
/*
* Who is supposed to own the new schema?
*/
- if (authId)
- owner_uid = get_role_oid(authId, false);
+ if (stmt->authrole)
+ owner_uid = get_rolespec_oid(stmt->authrole, false);
else
owner_uid = saved_uid;
+ /* fill schema name with the user name if not specified */
+ if (!schemaName)
+ {
+ HeapTuple tuple;
+
+ tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(owner_uid));
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for role %u", owner_uid);
+ schemaName =
+ pstrdup(NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname));
+ ReleaseSysCache(tuple);
+ }
+
/*
* To create a schema, must have schema-create privilege on the current
* database and must be able to become the target role (this does not
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 653677892de..623e6bfba81 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -3507,7 +3507,7 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
break;
case AT_ChangeOwner: /* ALTER OWNER */
ATExecChangeOwner(RelationGetRelid(rel),
- get_role_oid(cmd->name, false),
+ get_rolespec_oid(cmd->newowner, false),
false, lockmode);
break;
case AT_ClusterOn: /* CLUSTER ON */
@@ -9388,7 +9388,7 @@ AlterTableMoveAll(AlterTableMoveAllStmt *stmt)
HeapTuple tuple;
Oid orig_tablespaceoid;
Oid new_tablespaceoid;
- List *role_oids = roleNamesToIds(stmt->roles);
+ List *role_oids = roleSpecsToIds(stmt->roles);
/* Ensure we were not asked to move something we can't */
if (stmt->objtype != OBJECT_TABLE && stmt->objtype != OBJECT_INDEX &&
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index 68b6917df5d..fd226125a93 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -252,7 +252,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
/* However, the eventual owner of the tablespace need not be */
if (stmt->owner)
- ownerId = get_role_oid(stmt->owner, false);
+ ownerId = get_rolespec_oid(stmt->owner, false);
else
ownerId = GetUserId();
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 0ba7ba0c20f..c14465eb87b 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -49,10 +49,10 @@ extern bool Password_encryption;
check_password_hook_type check_password_hook = NULL;
static void AddRoleMems(const char *rolename, Oid roleid,
- List *memberNames, List *memberIds,
+ List *memberSpecs, List *memberIds,
Oid grantorId, bool admin_opt);
static void DelRoleMems(const char *rolename, Oid roleid,
- List *memberNames, List *memberIds,
+ List *memberSpecs, List *memberIds,
bool admin_opt);
@@ -443,10 +443,10 @@ CreateRole(CreateRoleStmt *stmt)
* option, rolemembers don't.
*/
AddRoleMems(stmt->role, roleid,
- adminmembers, roleNamesToIds(adminmembers),
+ adminmembers, roleSpecsToIds(adminmembers),
GetUserId(), true);
AddRoleMems(stmt->role, roleid,
- rolemembers, roleNamesToIds(rolemembers),
+ rolemembers, roleSpecsToIds(rolemembers),
GetUserId(), false);
/* Post creation hook for new role */
@@ -478,7 +478,9 @@ AlterRole(AlterRoleStmt *stmt)
TupleDesc pg_authid_dsc;
HeapTuple tuple,
new_tuple;
+ Form_pg_authid authform;
ListCell *option;
+ char *rolename = NULL;
char *password = NULL; /* user password */
bool encrypt_password = Password_encryption; /* encrypt password? */
char encrypted_password[MD5_PASSWD_LEN + 1];
@@ -647,33 +649,30 @@ AlterRole(AlterRoleStmt *stmt)
pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock);
pg_authid_dsc = RelationGetDescr(pg_authid_rel);
- tuple = SearchSysCache1(AUTHNAME, PointerGetDatum(stmt->role));
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("role \"%s\" does not exist", stmt->role)));
-
+ tuple = get_rolespec_tuple(stmt->role);
+ authform = (Form_pg_authid) GETSTRUCT(tuple);
+ rolename = pstrdup(NameStr(authform->rolname));
roleid = HeapTupleGetOid(tuple);
/*
* To mess with a superuser you gotta be superuser; else you need
* createrole, or just want to change your own password
*/
- if (((Form_pg_authid) GETSTRUCT(tuple))->rolsuper || issuper >= 0)
+ if (authform->rolsuper || issuper >= 0)
{
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to alter superusers")));
}
- else if (((Form_pg_authid) GETSTRUCT(tuple))->rolreplication || isreplication >= 0)
+ else if (authform->rolreplication || isreplication >= 0)
{
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to alter replication users")));
}
- else if (((Form_pg_authid) GETSTRUCT(tuple))->rolbypassrls || bypassrls >= 0)
+ else if (authform->rolbypassrls || bypassrls >= 0)
{
if (!superuser())
ereport(ERROR,
@@ -718,11 +717,11 @@ AlterRole(AlterRoleStmt *stmt)
* Call the password checking hook if there is one defined
*/
if (check_password_hook && password)
- (*check_password_hook) (stmt->role,
- password,
- isMD5(password) ? PASSWORD_TYPE_MD5 : PASSWORD_TYPE_PLAINTEXT,
- validUntil_datum,
- validUntil_null);
+ (*check_password_hook)(rolename ,
+ password,
+ isMD5(password) ? PASSWORD_TYPE_MD5 : PASSWORD_TYPE_PLAINTEXT,
+ validUntil_datum,
+ validUntil_null);
/*
* Build an updated tuple, perusing the information just obtained
@@ -784,7 +783,7 @@ AlterRole(AlterRoleStmt *stmt)
CStringGetTextDatum(password);
else
{
- if (!pg_md5_encrypt(password, stmt->role, strlen(stmt->role),
+ if (!pg_md5_encrypt(password, rolename, strlen(rolename),
encrypted_password))
elog(ERROR, "password encryption failed");
new_record[Anum_pg_authid_rolpassword - 1] =
@@ -831,12 +830,12 @@ AlterRole(AlterRoleStmt *stmt)
CommandCounterIncrement();
if (stmt->action == +1) /* add members to role */
- AddRoleMems(stmt->role, roleid,
- rolemembers, roleNamesToIds(rolemembers),
+ AddRoleMems(rolename, roleid,
+ rolemembers, roleSpecsToIds(rolemembers),
GetUserId(), false);
else if (stmt->action == -1) /* drop members from role */
- DelRoleMems(stmt->role, roleid,
- rolemembers, roleNamesToIds(rolemembers),
+ DelRoleMems(rolename, roleid,
+ rolemembers, roleSpecsToIds(rolemembers),
false);
/*
@@ -860,13 +859,7 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
if (stmt->role)
{
- roletuple = SearchSysCache1(AUTHNAME, PointerGetDatum(stmt->role));
-
- if (!HeapTupleIsValid(roletuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("role \"%s\" does not exist", stmt->role)));
-
+ roletuple = get_rolespec_tuple(stmt->role);
roleid = HeapTupleGetOid(roletuple);
/*
@@ -955,7 +948,8 @@ DropRole(DropRoleStmt *stmt)
foreach(item, stmt->roles)
{
- const char *role = strVal(lfirst(item));
+ RoleSpec *rolspec = lfirst(item);
+ char *role;
HeapTuple tuple,
tmp_tuple;
ScanKeyData scankey;
@@ -964,6 +958,12 @@ DropRole(DropRoleStmt *stmt)
SysScanDesc sscan;
Oid roleid;
+ if (rolspec->roletype != ROLESPEC_CSTRING)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("cannot use special role specifier in \"%s\"", "DROP ROLE")));
+ role = rolspec->rolename;
+
tuple = SearchSysCache1(AUTHNAME, PointerGetDatum(role));
if (!HeapTupleIsValid(tuple))
{
@@ -1233,11 +1233,11 @@ GrantRole(GrantRoleStmt *stmt)
ListCell *item;
if (stmt->grantor)
- grantor = get_role_oid(stmt->grantor, false);
+ grantor = get_rolespec_oid(stmt->grantor, false);
else
grantor = GetUserId();
- grantee_ids = roleNamesToIds(stmt->grantee_roles);
+ grantee_ids = roleSpecsToIds(stmt->grantee_roles);
/* AccessShareLock is enough since we aren't modifying pg_authid */
pg_authid_rel = heap_open(AuthIdRelationId, AccessShareLock);
@@ -1286,7 +1286,7 @@ GrantRole(GrantRoleStmt *stmt)
void
DropOwnedObjects(DropOwnedStmt *stmt)
{
- List *role_ids = roleNamesToIds(stmt->roles);
+ List *role_ids = roleSpecsToIds(stmt->roles);
ListCell *cell;
/* Check privileges */
@@ -1312,7 +1312,7 @@ DropOwnedObjects(DropOwnedStmt *stmt)
void
ReassignOwnedObjects(ReassignOwnedStmt *stmt)
{
- List *role_ids = roleNamesToIds(stmt->roles);
+ List *role_ids = roleSpecsToIds(stmt->roles);
ListCell *cell;
Oid newrole;
@@ -1328,7 +1328,7 @@ ReassignOwnedObjects(ReassignOwnedStmt *stmt)
}
/* Must have privileges on the receiving side too */
- newrole = get_role_oid(stmt->newrole, false);
+ newrole = get_rolespec_oid(stmt->newrole, false);
if (!has_privs_of_role(GetUserId(), newrole))
ereport(ERROR,
@@ -1340,22 +1340,24 @@ ReassignOwnedObjects(ReassignOwnedStmt *stmt)
}
/*
- * roleNamesToIds
+ * roleSpecsToIds
+ *
+ * Given a list of RoleSpecs, generate a list of role OIDs in the same order.
*
- * Given a list of role names (as String nodes), generate a list of role OIDs
- * in the same order.
+ * ROLESPEC_PUBLIC is not allowed.
*/
List *
-roleNamesToIds(List *memberNames)
+roleSpecsToIds(List *memberNames)
{
List *result = NIL;
ListCell *l;
foreach(l, memberNames)
{
- char *rolename = strVal(lfirst(l));
- Oid roleid = get_role_oid(rolename, false);
+ Node *rolespec = (Node *) lfirst(l);
+ Oid roleid;
+ roleid = get_rolespec_oid(rolespec, false);
result = lappend_oid(result, roleid);
}
return result;
@@ -1366,7 +1368,7 @@ roleNamesToIds(List *memberNames)
*
* rolename: name of role to add to (used only for error messages)
* roleid: OID of role to add to
- * memberNames: list of names of roles to add (used only for error messages)
+ * memberSpecs: list of RoleSpec of roles to add (used only for error messages)
* memberIds: OIDs of roles to add
* grantorId: who is granting the membership
* admin_opt: granting admin option?
@@ -1375,15 +1377,15 @@ roleNamesToIds(List *memberNames)
*/
static void
AddRoleMems(const char *rolename, Oid roleid,
- List *memberNames, List *memberIds,
+ List *memberSpecs, List *memberIds,
Oid grantorId, bool admin_opt)
{
Relation pg_authmem_rel;
TupleDesc pg_authmem_dsc;
- ListCell *nameitem;
+ ListCell *specitem;
ListCell *iditem;
- Assert(list_length(memberNames) == list_length(memberIds));
+ Assert(list_length(memberSpecs) == list_length(memberIds));
/* Skip permission check if nothing to do */
if (!memberIds)
@@ -1428,9 +1430,9 @@ AddRoleMems(const char *rolename, Oid roleid,
pg_authmem_rel = heap_open(AuthMemRelationId, RowExclusiveLock);
pg_authmem_dsc = RelationGetDescr(pg_authmem_rel);
- forboth(nameitem, memberNames, iditem, memberIds)
+ forboth(specitem, memberSpecs, iditem, memberIds)
{
- const char *membername = strVal(lfirst(nameitem));
+ RoleSpec *memberRole = lfirst(specitem);
Oid memberid = lfirst_oid(iditem);
HeapTuple authmem_tuple;
HeapTuple tuple;
@@ -1449,7 +1451,7 @@ AddRoleMems(const char *rolename, Oid roleid,
ereport(ERROR,
(errcode(ERRCODE_INVALID_GRANT_OPERATION),
(errmsg("role \"%s\" is a member of role \"%s\"",
- rolename, membername))));
+ rolename, get_rolespec_name((Node *) memberRole)))));
/*
* Check if entry for this role/member already exists; if so, give
@@ -1464,7 +1466,7 @@ AddRoleMems(const char *rolename, Oid roleid,
{
ereport(NOTICE,
(errmsg("role \"%s\" is already a member of role \"%s\"",
- membername, rolename)));
+ get_rolespec_name((Node *) memberRole), rolename)));
ReleaseSysCache(authmem_tuple);
continue;
}
@@ -1513,7 +1515,7 @@ AddRoleMems(const char *rolename, Oid roleid,
*
* rolename: name of role to del from (used only for error messages)
* roleid: OID of role to del from
- * memberNames: list of names of roles to del (used only for error messages)
+ * memberSpecs: list of RoleSpec of roles to del (used only for error messages)
* memberIds: OIDs of roles to del
* admin_opt: remove admin option only?
*
@@ -1521,15 +1523,15 @@ AddRoleMems(const char *rolename, Oid roleid,
*/
static void
DelRoleMems(const char *rolename, Oid roleid,
- List *memberNames, List *memberIds,
+ List *memberSpecs, List *memberIds,
bool admin_opt)
{
Relation pg_authmem_rel;
TupleDesc pg_authmem_dsc;
- ListCell *nameitem;
+ ListCell *specitem;
ListCell *iditem;
- Assert(list_length(memberNames) == list_length(memberIds));
+ Assert(list_length(memberSpecs) == list_length(memberIds));
/* Skip permission check if nothing to do */
if (!memberIds)
@@ -1559,9 +1561,9 @@ DelRoleMems(const char *rolename, Oid roleid,
pg_authmem_rel = heap_open(AuthMemRelationId, RowExclusiveLock);
pg_authmem_dsc = RelationGetDescr(pg_authmem_rel);
- forboth(nameitem, memberNames, iditem, memberIds)
+ forboth(specitem, memberSpecs, iditem, memberIds)
{
- const char *membername = strVal(lfirst(nameitem));
+ RoleSpec *memberRole = lfirst(specitem);
Oid memberid = lfirst_oid(iditem);
HeapTuple authmem_tuple;
@@ -1575,7 +1577,7 @@ DelRoleMems(const char *rolename, Oid roleid,
{
ereport(WARNING,
(errmsg("role \"%s\" is not a member of role \"%s\"",
- membername, rolename)));
+ get_rolespec_name((Node *) memberRole), rolename)));
continue;
}