📄 aclchk.c
字号:
/* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return mask; /* * Get the language's ACL from pg_language */ tuple = SearchSysCache(LANGOID, ObjectIdGetDatum(lang_oid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("language with OID %u does not exist", lang_oid))); /* XXX pg_language should have an owner column, but doesn't */ ownerId = BOOTSTRAP_SUPERUSERID; aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ acl = acldefault(ACL_OBJECT_LANGUAGE, ownerId); aclDatum = (Datum) 0; } else { /* detoast ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); ReleaseSysCache(tuple); return result;}/* * Exported routine for examining a user's privileges for a namespace */AclModepg_namespace_aclmask(Oid nsp_oid, Oid roleid, AclMode mask, AclMaskHow how){ AclMode result; HeapTuple tuple; Datum aclDatum; bool isNull; Acl *acl; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return mask; /* * If we have been assigned this namespace as a temp namespace, check to * make sure we have CREATE TEMP permission on the database, and if so act * as though we have all standard (but not GRANT OPTION) permissions on * the namespace. If we don't have CREATE TEMP, act as though we have * only USAGE (and not CREATE) rights. * * This may seem redundant given the check in InitTempTableNamespace, but * it really isn't since current user ID may have changed since then. The * upshot of this behavior is that a SECURITY DEFINER function can create * temp tables that can then be accessed (if permission is granted) by * code in the same session that doesn't have permissions to create temp * tables. * * XXX Would it be safe to ereport a special error message as * InitTempTableNamespace does? Returning zero here means we'll get a * generic "permission denied for schema pg_temp_N" message, which is not * remarkably user-friendly. */ if (isTempNamespace(nsp_oid)) { if (pg_database_aclcheck(MyDatabaseId, GetUserId(), ACL_CREATE_TEMP) == ACLCHECK_OK) return mask & ACL_ALL_RIGHTS_NAMESPACE; else return mask & ACL_USAGE; } /* * Get the schema's ACL from pg_namespace */ tuple = SearchSysCache(NAMESPACEOID, ObjectIdGetDatum(nsp_oid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_SCHEMA), errmsg("schema with OID %u does not exist", nsp_oid))); ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner; aclDatum = SysCacheGetAttr(NAMESPACEOID, tuple, Anum_pg_namespace_nspacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ acl = acldefault(ACL_OBJECT_NAMESPACE, ownerId); aclDatum = (Datum) 0; } else { /* detoast ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); ReleaseSysCache(tuple); return result;}/* * Exported routine for examining a user's privileges for a tablespace */AclModepg_tablespace_aclmask(Oid spc_oid, Oid roleid, AclMode mask, AclMaskHow how){ AclMode result; Relation pg_tablespace; ScanKeyData entry[1]; HeapScanDesc scan; HeapTuple tuple; Datum aclDatum; bool isNull; Acl *acl; Oid ownerId; /* * Only shared relations can be stored in global space; don't let even * superusers override this */ if (spc_oid == GLOBALTABLESPACE_OID && !IsBootstrapProcessingMode()) return 0; /* Otherwise, superusers bypass all permission checking. */ if (superuser_arg(roleid)) return mask; /* * Get the tablespace's ACL from pg_tablespace * * There's no syscache for pg_tablespace, so must look the hard way */ pg_tablespace = heap_open(TableSpaceRelationId, AccessShareLock); ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(spc_oid)); scan = heap_beginscan(pg_tablespace, SnapshotNow, 1, entry); tuple = heap_getnext(scan, ForwardScanDirection); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("tablespace with OID %u does not exist", spc_oid))); ownerId = ((Form_pg_tablespace) GETSTRUCT(tuple))->spcowner; aclDatum = heap_getattr(tuple, Anum_pg_tablespace_spcacl, RelationGetDescr(pg_tablespace), &isNull); if (isNull) { /* No ACL, so build default ACL */ acl = acldefault(ACL_OBJECT_TABLESPACE, ownerId); aclDatum = (Datum) 0; } else { /* detoast ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); heap_endscan(scan); heap_close(pg_tablespace, AccessShareLock); return result;}/* * Exported routine for checking a user's access privileges to a table * * Returns ACLCHECK_OK if the user has any of the privileges identified by * 'mode'; otherwise returns a suitable error code (in practice, always * ACLCHECK_NO_PRIV). */AclResultpg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode){ if (pg_class_aclmask(table_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV;}/* * Exported routine for checking a user's access privileges to a database */AclResultpg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode){ if (pg_database_aclmask(db_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV;}/* * Exported routine for checking a user's access privileges to a function */AclResultpg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode){ if (pg_proc_aclmask(proc_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV;}/* * Exported routine for checking a user's access privileges to a language */AclResultpg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode){ if (pg_language_aclmask(lang_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV;}/* * Exported routine for checking a user's access privileges to a namespace */AclResultpg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode){ if (pg_namespace_aclmask(nsp_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV;}/* * Exported routine for checking a user's access privileges to a tablespace */AclResultpg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode){ if (pg_tablespace_aclmask(spc_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV;}/* * Ownership check for a relation (specified by OID). */boolpg_class_ownercheck(Oid class_oid, Oid roleid){ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache(RELOID, ObjectIdGetDatum(class_oid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), errmsg("relation with OID %u does not exist", class_oid))); ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId);}/* * Ownership check for a type (specified by OID). */boolpg_type_ownercheck(Oid type_oid, Oid roleid){ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache(TYPEOID, ObjectIdGetDatum(type_oid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("type with OID %u does not exist", type_oid))); ownerId = ((Form_pg_type) GETSTRUCT(tuple))->typowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId);}/* * Ownership check for an operator (specified by OID). */boolpg_oper_ownercheck(Oid oper_oid, Oid roleid){ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache(OPEROID, ObjectIdGetDatum(oper_oid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("operator with OID %u does not exist", oper_oid))); ownerId = ((Form_pg_operator) GETSTRUCT(tuple))->oprowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId);}/* * Ownership check for a function (specified by OID). */boolpg_proc_ownercheck(Oid proc_oid, Oid roleid){ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache(PROCOID, ObjectIdGetDatum(proc_oid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("function with OID %u does not exist", proc_oid))); ownerId = ((Form_pg_proc) GETSTRUCT(tuple))->proowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId);}/* * Ownership check for a namespace (specified by OID). */boolpg_namespace_ownercheck(Oid nsp_oid, Oid roleid){ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache(NAMESPACEOID, ObjectIdGetDatum(nsp_oid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_SCHEMA), errmsg("schema with OID %u does not exist", nsp_oid))); ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId);}/* * Ownership check for a tablespace (specified by OID). */boolpg_tablespace_ownercheck(Oid spc_oid, Oid roleid){ Relation pg_tablespace; ScanKeyData entry[1]; HeapScanDesc scan; HeapTuple spctuple; Oid spcowner; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; /* There's no syscache for pg_tablespace, so must look the hard way */ pg_tablespace = heap_open(TableSpaceRelationId, AccessShareLock); ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(spc_oid)); scan = heap_beginscan(pg_tablespace, SnapshotNow, 1, entry); spctuple = heap_getnext(scan, ForwardScanDirection); if (!HeapTupleIsValid(spctuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("tablespace with OID %u does not exist", spc_oid))); spcowner = ((Form_pg_tablespace) GETSTRUCT(spctuple))->spcowner; heap_endscan(scan); heap_close(pg_tablespace, AccessShareLock); return has_privs_of_role(roleid, spcowner);}/* * Ownership check for an operator class (specified by OID). */boolpg_opclass_ownercheck(Oid opc_oid, Oid roleid){ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache(CLAOID, ObjectIdGetDatum(opc_oid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("operator class with OID %u does not exist", opc_oid))); ownerId = ((Form_pg_opclass) GETSTRUCT(tuple))->opcowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId);}/* * Ownership check for a database (specified by OID). */boolpg_database_ownercheck(Oid db_oid, Oid roleid){ Relation pg_database; ScanKeyData entry[1]; HeapScanDesc scan; HeapTuple dbtuple; Oid dba; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; /* There's no syscache for pg_database, so must look the hard way */ pg_database = heap_open(DatabaseRelationId, AccessShareLock); ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(db_oid)); scan = heap_beginscan(pg_database, SnapshotNow, 1, entry); dbtuple = heap_getnext(scan, ForwardScanDirection); if (!HeapTupleIsValid(dbtuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("database with OID %u does not exist", db_oid))); dba = ((Form_pg_database) GETSTRUCT(dbtuple))->datdba; heap_endscan(scan); heap_close(pg_database, AccessShareLock); return has_privs_of_role(roleid, dba);}/* * Ownership check for a conversion (specified by OID). */boolpg_conversion_ownercheck(Oid conv_oid, Oid roleid){ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache(CONOID, ObjectIdGetDatum(conv_oid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("conversion with OID %u does not exist", conv_oid))); ownerId = ((Form_pg_conversion) GETSTRUCT(tuple))->conowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -