diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/bootstrap/bootstrap.c | 2 | ||||
-rw-r--r-- | src/backend/catalog/dependency.c | 10 | ||||
-rw-r--r-- | src/backend/catalog/objectaddress.c | 20 | ||||
-rw-r--r-- | src/backend/utils/adt/acl.c | 2 | ||||
-rw-r--r-- | src/backend/utils/adt/name.c | 4 | ||||
-rw-r--r-- | src/backend/utils/adt/regproc.c | 104 | ||||
-rw-r--r-- | src/backend/utils/adt/selfuncs.c | 2 | ||||
-rw-r--r-- | src/backend/utils/cache/catcache.c | 1 | ||||
-rw-r--r-- | src/backend/utils/init/miscinit.c | 24 |
9 files changed, 147 insertions, 22 deletions
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 6866d92238f..66028d5877e 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -113,6 +113,8 @@ static const struct typinfo TypInfo[] = { F_REGPROCIN, F_REGPROCOUT}, {"regtype", REGTYPEOID, 0, 4, true, 'i', 'p', InvalidOid, F_REGTYPEIN, F_REGTYPEOUT}, + {"regrole", REGROLEOID, 0, 4, true, 'i', 'p', InvalidOid, + F_REGROLEIN, F_REGROLEOUT}, {"text", TEXTOID, 0, -1, false, 'i', 'x', DEFAULT_COLLATION_OID, F_TEXTIN, F_TEXTOUT}, {"oid", OIDOID, 0, 4, true, 'i', 'p', InvalidOid, diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index 6271f8f5a03..0ab57322f35 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -1602,6 +1602,16 @@ find_expr_references_walker(Node *node, add_object_address(OCLASS_TSDICT, objoid, 0, context->addrs); break; + + /* + * Dependencies for regrole should be shared among all + * databases, so explicitly inhibit to have dependencies. + */ + case REGROLEOID: + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("constant of the type \'regrole\' cannot be used here"))); + break; } } return false; diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index 10f0396561b..a1f8ada8337 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -2818,7 +2818,7 @@ getObjectDescription(const ObjectAddress *object) case OCLASS_ROLE: { appendStringInfo(&buffer, _("role %s"), - GetUserNameFromId(object->objectId)); + GetUserNameFromId(object->objectId, false)); break; } @@ -2884,7 +2884,7 @@ getObjectDescription(const ObjectAddress *object) ReleaseSysCache(tup); if (OidIsValid(useid)) - usename = GetUserNameFromId(useid); + usename = GetUserNameFromId(useid, false); else usename = "public"; @@ -2924,28 +2924,28 @@ getObjectDescription(const ObjectAddress *object) case DEFACLOBJ_RELATION: appendStringInfo(&buffer, _("default privileges on new relations belonging to role %s"), - GetUserNameFromId(defacl->defaclrole)); + GetUserNameFromId(defacl->defaclrole, false)); break; case DEFACLOBJ_SEQUENCE: appendStringInfo(&buffer, _("default privileges on new sequences belonging to role %s"), - GetUserNameFromId(defacl->defaclrole)); + GetUserNameFromId(defacl->defaclrole, false)); break; case DEFACLOBJ_FUNCTION: appendStringInfo(&buffer, _("default privileges on new functions belonging to role %s"), - GetUserNameFromId(defacl->defaclrole)); + GetUserNameFromId(defacl->defaclrole, false)); break; case DEFACLOBJ_TYPE: appendStringInfo(&buffer, _("default privileges on new types belonging to role %s"), - GetUserNameFromId(defacl->defaclrole)); + GetUserNameFromId(defacl->defaclrole, false)); break; default: /* shouldn't get here */ appendStringInfo(&buffer, _("default privileges belonging to role %s"), - GetUserNameFromId(defacl->defaclrole)); + GetUserNameFromId(defacl->defaclrole, false)); break; } @@ -4214,7 +4214,7 @@ getObjectIdentityParts(const ObjectAddress *object, { char *username; - username = GetUserNameFromId(object->objectId); + username = GetUserNameFromId(object->objectId, false); if (objname) *objname = list_make1(username); appendStringInfoString(&buffer, @@ -4295,7 +4295,7 @@ getObjectIdentityParts(const ObjectAddress *object, ReleaseSysCache(tup); if (OidIsValid(useid)) - usename = GetUserNameFromId(useid); + usename = GetUserNameFromId(useid, false); else usename = "public"; @@ -4339,7 +4339,7 @@ getObjectIdentityParts(const ObjectAddress *object, defacl = (Form_pg_default_acl) GETSTRUCT(tup); - username = GetUserNameFromId(defacl->defaclrole); + username = GetUserNameFromId(defacl->defaclrole, false); appendStringInfo(&buffer, "for role %s", quote_identifier(username)); diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 7701fc5ac07..e7aecc95c97 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -4878,7 +4878,7 @@ check_is_member_of_role(Oid member, Oid role) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be member of role \"%s\"", - GetUserNameFromId(role)))); + GetUserNameFromId(role, false)))); } /* diff --git a/src/backend/utils/adt/name.c b/src/backend/utils/adt/name.c index b6c6e393358..58261275614 100644 --- a/src/backend/utils/adt/name.c +++ b/src/backend/utils/adt/name.c @@ -263,13 +263,13 @@ namestrcmp(Name name, const char *str) Datum current_user(PG_FUNCTION_ARGS) { - PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetUserId())))); + PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetUserId(), false)))); } Datum session_user(PG_FUNCTION_ARGS) { - PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetSessionUserId())))); + PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetSessionUserId(), false)))); } diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c index 11d663b295d..8b5672875c2 100644 --- a/src/backend/utils/adt/regproc.c +++ b/src/backend/utils/adt/regproc.c @@ -40,6 +40,7 @@ #include "utils/lsyscache.h" #include "utils/syscache.h" #include "utils/tqual.h" +#include "utils/acl.h" static char *format_operator_internal(Oid operator_oid, bool force_qualify); static char *format_procedure_internal(Oid procedure_oid, bool force_qualify); @@ -1553,6 +1554,109 @@ regdictionarysend(PG_FUNCTION_ARGS) return oidsend(fcinfo); } +/* + * regrolein - converts "rolename" to role OID + * + * We also accept a numeric OID, for symmetry with the output routine. + * + * '-' signifies unknown (OID 0). In all other cases, the input must + * match an existing pg_authid entry. + * + * This function is not needed in bootstrap mode, so we don't worry about + * making it work then. + */ +Datum +regrolein(PG_FUNCTION_ARGS) +{ + char *role_name_or_oid = PG_GETARG_CSTRING(0); + Oid result; + + /* '-' ? */ + if (strcmp(role_name_or_oid, "-") == 0) + PG_RETURN_OID(InvalidOid); + + /* Numeric OID? */ + if (role_name_or_oid[0] >= '0' && + role_name_or_oid[0] <= '9' && + strspn(role_name_or_oid, "0123456789") == strlen(role_name_or_oid)) + { + result = DatumGetObjectId(DirectFunctionCall1(oidin, + CStringGetDatum(role_name_or_oid))); + PG_RETURN_OID(result); + } + + /* Normal case: see if the name matches any pg_authid entry. */ + result = get_role_oid(role_name_or_oid, false); + + PG_RETURN_OID(result); +} + +/* + * to_regrole - converts "rolename" to role OID + * + * If the name is not found, we return NULL. + */ +Datum +to_regrole(PG_FUNCTION_ARGS) +{ + char *role_name = PG_GETARG_CSTRING(0); + Oid result; + + result = get_role_oid(role_name, true); + + if (OidIsValid(result)) + PG_RETURN_OID(result); + else + PG_RETURN_NULL(); +} + +/* + * regroleout - converts role OID to "role_name" + */ +Datum +regroleout(PG_FUNCTION_ARGS) +{ + Oid roleoid = PG_GETARG_OID(0); + char *result; + + + if (roleoid == InvalidOid) + { + result = pstrdup("-"); + PG_RETURN_CSTRING(result); + } + + result = GetUserNameFromId(roleoid, true); + if (!result) + { + /* If OID doesn't match any role, return it numerically */ + result = (char *) palloc(NAMEDATALEN); + snprintf(result, NAMEDATALEN, "%u", roleoid); + } + PG_RETURN_CSTRING(result); +} + +/* + * regrolerecv - converts external binary format to regrole + */ +Datum +regrolerecv(PG_FUNCTION_ARGS) +{ + /* Exactly the same as oidrecv, so share code */ + return oidrecv(fcinfo); +} + +/* + * regrolesend - converts regrole to binary format + */ +Datum +regrolesend(PG_FUNCTION_ARGS) +{ + /* Exactly the same as oidsend, so share code */ + return oidsend(fcinfo); +} + + /* * text_regclass: convert text to regclass diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 4dd3f9fbce1..a28868c3130 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -3619,6 +3619,7 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue, case REGTYPEOID: case REGCONFIGOID: case REGDICTIONARYOID: + case REGROLEOID: *scaledvalue = convert_numeric_to_scalar(value, valuetypid); *scaledlobound = convert_numeric_to_scalar(lobound, boundstypid); *scaledhibound = convert_numeric_to_scalar(hibound, boundstypid); @@ -3724,6 +3725,7 @@ convert_numeric_to_scalar(Datum value, Oid typid) case REGTYPEOID: case REGCONFIGOID: case REGDICTIONARYOID: + case REGROLEOID: /* we can treat OIDs as integers... */ return (double) DatumGetObjectId(value); } diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 1af43c6de67..9b7cc5eb764 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -150,6 +150,7 @@ GetCCHashEqFuncs(Oid keytype, PGFunction *hashfunc, RegProcedure *eqfunc) case REGTYPEOID: case REGCONFIGOID: case REGDICTIONARYOID: + case REGROLEOID: *hashfunc = hashoid; *eqfunc = F_OIDEQ; diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 1dc31535fd6..b0d85af14db 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -648,23 +648,29 @@ SetCurrentRoleId(Oid roleid, bool is_superuser) /* - * Get user name from user oid + * Get user name from user oid, returns NULL for nonexistent roleid if noerr + * is true. */ char * -GetUserNameFromId(Oid roleid) +GetUserNameFromId(Oid roleid, bool noerr) { HeapTuple tuple; char *result; tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid)); if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("invalid role OID: %u", roleid))); - - result = pstrdup(NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname)); - - ReleaseSysCache(tuple); + { + if (!noerr) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("invalid role OID: %u", roleid))); + result = NULL; + } + else + { + result = pstrdup(NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname)); + ReleaseSysCache(tuple); + } return result; } |