aclchk.c
来自「PostgreSQL7.4.6 for Linux」· C语言 代码 · 共 1,557 行 · 第 1/3 页
C
1,557 行
* Now get the relation's tuple from pg_class */ tuple = SearchSysCache(RELOID, ObjectIdGetDatum(table_oid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), errmsg("relation with OID %u does not exist", table_oid))); classForm = (Form_pg_class) GETSTRUCT(tuple); /* * Deny anyone permission to update a system catalog unless * pg_shadow.usecatupd is set. (This is to let superusers protect * themselves from themselves.) Also allow it if allowSystemTableMods. * * As of 7.4 we have some updatable system views; those shouldn't * be protected in this way. Assume the view rules can take care * of themselves. */ if ((mode & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) && IsSystemClass(classForm) && classForm->relkind != RELKIND_VIEW && !usecatupd && !allowSystemTableMods) {#ifdef ACLDEBUG elog(DEBUG2, "permission denied for system catalog update");#endif ReleaseSysCache(tuple); return ACLCHECK_NO_PRIV; } /* * Otherwise, superusers bypass all permission-checking. */ if (usesuper) {#ifdef ACLDEBUG elog(DEBUG2, "%u is superuser, home free", userid);#endif ReleaseSysCache(tuple); return ACLCHECK_OK; } /* * Normal case: get the relation's ACL from pg_class */ aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ AclId ownerId = classForm->relowner; acl = acldefault(ACL_OBJECT_RELATION, ownerId); aclDatum = (Datum) 0; } else { /* detoast rel's ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclcheck(acl, userid, mode); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); ReleaseSysCache(tuple); return result;}/* * Exported routine for checking a user's access privileges to a database */AclResultpg_database_aclcheck(Oid db_oid, AclId userid, AclMode mode){ AclResult result; Relation pg_database; ScanKeyData entry[1]; HeapScanDesc scan; HeapTuple tuple; Datum aclDatum; bool isNull; Acl *acl; /* Superusers bypass all permission checking. */ if (superuser_arg(userid)) return ACLCHECK_OK; /* * Get the database's ACL from pg_database * * There's no syscache for pg_database, so must look the hard way */ pg_database = heap_openr(DatabaseRelationName, AccessShareLock); ScanKeyEntryInitialize(&entry[0], 0x0, ObjectIdAttributeNumber, F_OIDEQ, ObjectIdGetDatum(db_oid)); scan = heap_beginscan(pg_database, SnapshotNow, 1, entry); tuple = heap_getnext(scan, ForwardScanDirection); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("database with OID %u does not exist", db_oid))); aclDatum = heap_getattr(tuple, Anum_pg_database_datacl, RelationGetDescr(pg_database), &isNull); if (isNull) { /* No ACL, so build default ACL */ AclId ownerId; ownerId = ((Form_pg_database) GETSTRUCT(tuple))->datdba; acl = acldefault(ACL_OBJECT_DATABASE, ownerId); aclDatum = (Datum) 0; } else { /* detoast ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclcheck(acl, userid, mode); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); heap_endscan(scan); heap_close(pg_database, AccessShareLock); return result;}/* * Exported routine for checking a user's access privileges to a function */AclResultpg_proc_aclcheck(Oid proc_oid, AclId userid, AclMode mode){ AclResult result; HeapTuple tuple; Datum aclDatum; bool isNull; Acl *acl; /* Superusers bypass all permission checking. */ if (superuser_arg(userid)) return ACLCHECK_OK; /* * Get the function's ACL from pg_proc */ 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))); aclDatum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ AclId ownerId; ownerId = ((Form_pg_proc) GETSTRUCT(tuple))->proowner; acl = acldefault(ACL_OBJECT_FUNCTION, ownerId); aclDatum = (Datum) 0; } else { /* detoast ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclcheck(acl, userid, mode); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); ReleaseSysCache(tuple); return result;}/* * Exported routine for checking a user's access privileges to a language */AclResultpg_language_aclcheck(Oid lang_oid, AclId userid, AclMode mode){ AclResult result; HeapTuple tuple; Datum aclDatum; bool isNull; Acl *acl; /* Superusers bypass all permission checking. */ if (superuser_arg(userid)) return ACLCHECK_OK; /* * 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))); aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ /* XXX pg_language should have an owner column, but doesn't */ acl = acldefault(ACL_OBJECT_LANGUAGE, BOOTSTRAP_USESYSID); aclDatum = (Datum) 0; } else { /* detoast ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclcheck(acl, userid, mode); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); ReleaseSysCache(tuple); return result;}/* * Exported routine for checking a user's access privileges to a namespace */AclResultpg_namespace_aclcheck(Oid nsp_oid, AclId userid, AclMode mode){ AclResult result; HeapTuple tuple; Datum aclDatum; bool isNull; Acl *acl; /* * If we have been assigned this namespace as a temp namespace, assume * we have all grantable privileges on it. */ if (isTempNamespace(nsp_oid)) return ACLCHECK_OK; /* Superusers bypass all permission checking. */ if (superuser_arg(userid)) return ACLCHECK_OK; /* * 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))); aclDatum = SysCacheGetAttr(NAMESPACEOID, tuple, Anum_pg_namespace_nspacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ AclId ownerId; ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner; acl = acldefault(ACL_OBJECT_NAMESPACE, ownerId); aclDatum = (Datum) 0; } else { /* detoast ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclcheck(acl, userid, mode); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); ReleaseSysCache(tuple); return result;}/* * Ownership check for a relation (specified by OID). */boolpg_class_ownercheck(Oid class_oid, AclId userid){ HeapTuple tuple; AclId owner_id; /* Superusers bypass all permission checking. */ if (superuser_arg(userid)) 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))); owner_id = ((Form_pg_class) GETSTRUCT(tuple))->relowner; ReleaseSysCache(tuple); return userid == owner_id;}/* * Ownership check for a type (specified by OID). */boolpg_type_ownercheck(Oid type_oid, AclId userid){ HeapTuple tuple; AclId owner_id; /* Superusers bypass all permission checking. */ if (superuser_arg(userid)) 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))); owner_id = ((Form_pg_type) GETSTRUCT(tuple))->typowner; ReleaseSysCache(tuple); return userid == owner_id;}/* * Ownership check for an operator (specified by OID). */boolpg_oper_ownercheck(Oid oper_oid, AclId userid){ HeapTuple tuple; AclId owner_id; /* Superusers bypass all permission checking. */ if (superuser_arg(userid)) 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))); owner_id = ((Form_pg_operator) GETSTRUCT(tuple))->oprowner; ReleaseSysCache(tuple); return userid == owner_id;}/* * Ownership check for a function (specified by OID). */boolpg_proc_ownercheck(Oid proc_oid, AclId userid){ HeapTuple tuple; AclId owner_id; /* Superusers bypass all permission checking. */ if (superuser_arg(userid)) 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))); owner_id = ((Form_pg_proc) GETSTRUCT(tuple))->proowner; ReleaseSysCache(tuple); return userid == owner_id;}/* * Ownership check for a namespace (specified by OID). */boolpg_namespace_ownercheck(Oid nsp_oid, AclId userid){ HeapTuple tuple; AclId owner_id; /* Superusers bypass all permission checking. */ if (superuser_arg(userid)) 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))); owner_id = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner; ReleaseSysCache(tuple); return userid == owner_id;}/* * Ownership check for an operator class (specified by OID). */boolpg_opclass_ownercheck(Oid opc_oid, AclId userid){ HeapTuple tuple; AclId owner_id; /* Superusers bypass all permission checking. */ if (superuser_arg(userid)) 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))); owner_id = ((Form_pg_opclass) GETSTRUCT(tuple))->opcowner; ReleaseSysCache(tuple); return userid == owner_id;}/* * Ownership check for database (specified as OID) */boolpg_database_ownercheck(Oid db_oid, AclId userid){ Relation pg_database; ScanKeyData entry[1]; HeapScanDesc scan; HeapTuple dbtuple; int32 dba; /* Superusers bypass all permission checking. */ if (superuser_arg(userid)) return true; /* There's no syscache for pg_database, so must look the hard way */ pg_database = heap_openr(DatabaseRelationName, AccessShareLock); ScanKeyEntryInitialize(&entry[0], 0x0, ObjectIdAttributeNumber, 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 userid == dba;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?