diff options
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/alter.c | 2 | ||||
-rw-r--r-- | src/backend/commands/extension.c | 2 | ||||
-rw-r--r-- | src/backend/commands/foreigncmds.c | 58 | ||||
-rw-r--r-- | src/backend/commands/policy.c | 18 | ||||
-rw-r--r-- | src/backend/commands/schemacmds.c | 21 | ||||
-rw-r--r-- | src/backend/commands/tablecmds.c | 4 | ||||
-rw-r--r-- | src/backend/commands/tablespace.c | 2 | ||||
-rw-r--r-- | src/backend/commands/user.c | 116 |
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; } |