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 + -
显示快捷键?