⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aclchk.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (stmt->privileges == NIL)	{		all_privs = true;		privileges = ACL_ALL_RIGHTS_FUNCTION;	}	else	{		all_privs = false;		privileges = ACL_NO_RIGHTS;		foreach(i, stmt->privileges)		{			char	   *privname = strVal(lfirst(i));			AclMode		priv = string_to_privilege(privname);			if (priv & ~((AclMode) ACL_ALL_RIGHTS_FUNCTION))				ereport(ERROR,						(errcode(ERRCODE_INVALID_GRANT_OPERATION),						 errmsg("invalid privilege type %s for function",								privilege_to_string(priv))));			privileges |= priv;		}	}	foreach(i, stmt->objects)	{		FuncWithArgs *func = (FuncWithArgs *) lfirst(i);		Oid			oid;		Relation	relation;		HeapTuple	tuple;		Form_pg_proc pg_proc_tuple;		Datum		aclDatum;		bool		isNull;		AclMode		avail_goptions;		AclMode		this_privileges;		Acl		   *old_acl;		Acl		   *new_acl;		Oid			grantorId;		Oid			ownerId;		HeapTuple	newtuple;		Datum		values[Natts_pg_proc];		char		nulls[Natts_pg_proc];		char		replaces[Natts_pg_proc];		int			noldmembers;		int			nnewmembers;		Oid		   *oldmembers;		Oid		   *newmembers;		oid = LookupFuncNameTypeNames(func->funcname, func->funcargs, false);		relation = heap_open(ProcedureRelationId, RowExclusiveLock);		tuple = SearchSysCache(PROCOID,							   ObjectIdGetDatum(oid),							   0, 0, 0);		if (!HeapTupleIsValid(tuple))			elog(ERROR, "cache lookup failed for function %u", oid);		pg_proc_tuple = (Form_pg_proc) GETSTRUCT(tuple);		/*		 * Get owner ID and working copy of existing ACL. If there's no ACL,		 * substitute the proper default.		 */		ownerId = pg_proc_tuple->proowner;		aclDatum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proacl,								   &isNull);		if (isNull)			old_acl = acldefault(ACL_OBJECT_FUNCTION, ownerId);		else			old_acl = DatumGetAclPCopy(aclDatum);		/* Determine ID to do the grant as, and available grant options */		select_best_grantor(GetUserId(), privileges,							old_acl, ownerId,							&grantorId, &avail_goptions);		/*		 * If we found no grant options, consider whether to issue a hard		 * error.  Per spec, having any privilege at all on the object will		 * get you by here.		 */		if (avail_goptions == ACL_NO_RIGHTS)		{			if (pg_proc_aclmask(oid,								grantorId,								ACL_ALL_RIGHTS_FUNCTION | ACL_GRANT_OPTION_FOR(ACL_ALL_RIGHTS_FUNCTION),								ACLMASK_ANY) == ACL_NO_RIGHTS)				aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_PROC,							   NameStr(pg_proc_tuple->proname));		}		/*		 * Restrict the operation to what we can actually grant or revoke, and		 * issue a warning if appropriate.	(For REVOKE this isn't quite what		 * the spec says to do: the spec seems to want a warning only if no		 * privilege bits actually change in the ACL. In practice that		 * behavior seems much too noisy, as well as inconsistent with the		 * GRANT case.)		 */		this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions);		if (stmt->is_grant)		{			if (this_privileges == 0)				ereport(WARNING,						(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),						 errmsg("no privileges were granted")));			else if (!all_privs && this_privileges != privileges)				ereport(WARNING,						(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),						 errmsg("not all privileges were granted")));		}		else		{			if (this_privileges == 0)				ereport(WARNING,						(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),						 errmsg("no privileges could be revoked")));			else if (!all_privs && this_privileges != privileges)				ereport(WARNING,						(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),						 errmsg("not all privileges could be revoked")));		}		/*		 * Generate new ACL.		 *		 * We need the members of both old and new ACLs so we can correct the		 * shared dependency information.		 */		noldmembers = aclmembers(old_acl, &oldmembers);		new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,									   stmt->grant_option, stmt->behavior,									   stmt->grantees, this_privileges,									   grantorId, ownerId);		nnewmembers = aclmembers(new_acl, &newmembers);		/* finished building new ACL value, now insert it */		MemSet(values, 0, sizeof(values));		MemSet(nulls, ' ', sizeof(nulls));		MemSet(replaces, ' ', sizeof(replaces));		replaces[Anum_pg_proc_proacl - 1] = 'r';		values[Anum_pg_proc_proacl - 1] = PointerGetDatum(new_acl);		newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces);		simple_heap_update(relation, &newtuple->t_self, newtuple);		/* keep the catalog indexes up to date */		CatalogUpdateIndexes(relation, newtuple);		/* Update the shared dependency ACL info */		updateAclDependencies(ProcedureRelationId, oid,							  ownerId, stmt->is_grant,							  noldmembers, oldmembers,							  nnewmembers, newmembers);		ReleaseSysCache(tuple);		pfree(new_acl);		heap_close(relation, RowExclusiveLock);		/* prevent error when processing duplicate objects */		CommandCounterIncrement();	}}static voidExecuteGrantStmt_Language(GrantStmt *stmt){	AclMode		privileges;	bool		all_privs;	ListCell   *i;	if (stmt->privileges == NIL)	{		all_privs = true;		privileges = ACL_ALL_RIGHTS_LANGUAGE;	}	else	{		all_privs = false;		privileges = ACL_NO_RIGHTS;		foreach(i, stmt->privileges)		{			char	   *privname = strVal(lfirst(i));			AclMode		priv = string_to_privilege(privname);			if (priv & ~((AclMode) ACL_ALL_RIGHTS_LANGUAGE))				ereport(ERROR,						(errcode(ERRCODE_INVALID_GRANT_OPERATION),						 errmsg("invalid privilege type %s for language",								privilege_to_string(priv))));			privileges |= priv;		}	}	foreach(i, stmt->objects)	{		char	   *langname = strVal(lfirst(i));		Relation	relation;		HeapTuple	tuple;		Form_pg_language pg_language_tuple;		Datum		aclDatum;		bool		isNull;		AclMode		avail_goptions;		AclMode		this_privileges;		Acl		   *old_acl;		Acl		   *new_acl;		Oid			grantorId;		Oid			ownerId;		HeapTuple	newtuple;		Datum		values[Natts_pg_language];		char		nulls[Natts_pg_language];		char		replaces[Natts_pg_language];		int			noldmembers;		int			nnewmembers;		Oid		   *oldmembers;		Oid		   *newmembers;		relation = heap_open(LanguageRelationId, RowExclusiveLock);		tuple = SearchSysCache(LANGNAME,							   PointerGetDatum(langname),							   0, 0, 0);		if (!HeapTupleIsValid(tuple))			ereport(ERROR,					(errcode(ERRCODE_UNDEFINED_OBJECT),					 errmsg("language \"%s\" does not exist", langname)));		pg_language_tuple = (Form_pg_language) GETSTRUCT(tuple);		if (!pg_language_tuple->lanpltrusted)			ereport(ERROR,					(errcode(ERRCODE_WRONG_OBJECT_TYPE),					 errmsg("language \"%s\" is not trusted", langname),				   errhint("Only superusers may use untrusted languages.")));		/*		 * Get owner ID and working copy of existing ACL. If there's no ACL,		 * substitute the proper default.		 *		 * Note: for now, languages are treated as owned by the bootstrap		 * user. We should add an owner column to pg_language instead.		 */		ownerId = BOOTSTRAP_SUPERUSERID;		aclDatum = SysCacheGetAttr(LANGNAME, tuple, Anum_pg_language_lanacl,								   &isNull);		if (isNull)			old_acl = acldefault(ACL_OBJECT_LANGUAGE, ownerId);		else			old_acl = DatumGetAclPCopy(aclDatum);		/* Determine ID to do the grant as, and available grant options */		select_best_grantor(GetUserId(), privileges,							old_acl, ownerId,							&grantorId, &avail_goptions);		/*		 * If we found no grant options, consider whether to issue a hard		 * error.  Per spec, having any privilege at all on the object will		 * get you by here.		 */		if (avail_goptions == ACL_NO_RIGHTS)		{			if (pg_language_aclmask(HeapTupleGetOid(tuple),									grantorId,									ACL_ALL_RIGHTS_LANGUAGE | ACL_GRANT_OPTION_FOR(ACL_ALL_RIGHTS_LANGUAGE),									ACLMASK_ANY) == ACL_NO_RIGHTS)				aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_LANGUAGE,							   NameStr(pg_language_tuple->lanname));		}		/*		 * Restrict the operation to what we can actually grant or revoke, and		 * issue a warning if appropriate.	(For REVOKE this isn't quite what		 * the spec says to do: the spec seems to want a warning only if no		 * privilege bits actually change in the ACL. In practice that		 * behavior seems much too noisy, as well as inconsistent with the		 * GRANT case.)		 */		this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions);		if (stmt->is_grant)		{			if (this_privileges == 0)				ereport(WARNING,						(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),						 errmsg("no privileges were granted")));			else if (!all_privs && this_privileges != privileges)				ereport(WARNING,						(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),						 errmsg("not all privileges were granted")));		}		else		{			if (this_privileges == 0)				ereport(WARNING,						(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),						 errmsg("no privileges could be revoked")));			else if (!all_privs && this_privileges != privileges)				ereport(WARNING,						(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),						 errmsg("not all privileges could be revoked")));		}		/*		 * Generate new ACL.		 *		 * We need the members of both old and new ACLs so we can correct the		 * shared dependency information.		 */		noldmembers = aclmembers(old_acl, &oldmembers);		new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,									   stmt->grant_option, stmt->behavior,									   stmt->grantees, this_privileges,									   grantorId, ownerId);		nnewmembers = aclmembers(new_acl, &newmembers);		/* finished building new ACL value, now insert it */		MemSet(values, 0, sizeof(values));		MemSet(nulls, ' ', sizeof(nulls));		MemSet(replaces, ' ', sizeof(replaces));		replaces[Anum_pg_language_lanacl - 1] = 'r';		values[Anum_pg_language_lanacl - 1] = PointerGetDatum(new_acl);		newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces);		simple_heap_update(relation, &newtuple->t_self, newtuple);		/* keep the catalog indexes up to date */		CatalogUpdateIndexes(relation, newtuple);		/* Update the shared dependency ACL info */		updateAclDependencies(LanguageRelationId, HeapTupleGetOid(tuple),							  ownerId, stmt->is_grant,							  noldmembers, oldmembers,							  nnewmembers, newmembers);		ReleaseSysCache(tuple);		pfree(new_acl);		heap_close(relation, RowExclusiveLock);		/* prevent error when processing duplicate objects */		CommandCounterIncrement();	}}static voidExecuteGrantStmt_Namespace(GrantStmt *stmt){	AclMode		privileges;	bool		all_privs;	ListCell   *i;	if (stmt->privileges == NIL)	{		all_privs = true;		privileges = ACL_ALL_RIGHTS_NAMESPACE;	}	else	{		all_privs = false;		privileges = ACL_NO_RIGHTS;		foreach(i, stmt->privileges)		{			char	   *privname = strVal(lfirst(i));			AclMode		priv = string_to_privilege(privname);			if (priv & ~((AclMode) ACL_ALL_RIGHTS_NAMESPACE))				ereport(ERROR,						(errcode(ERRCODE_INVALID_GRANT_OPERATION),						 errmsg("invalid privilege type %s for schema",								privilege_to_string(priv))));			privileges |= priv;		}	}	foreach(i, stmt->objects)	{		char	   *nspname = strVal(lfirst(i));		Relation	relation;		HeapTuple	tuple;		Form_pg_namespace pg_namespace_tuple;		Datum		aclDatum;		bool		isNull;		AclMode		avail_goptions;		AclMode		this_privileges;		Acl		   *old_acl;		Acl		   *new_acl;		Oid			grantorId;		Oid			ownerId;		HeapTuple	newtuple;		Datum		values[Natts_pg_namespace];		char		nulls[Natts_pg_namespace];		char		replaces[Natts_pg_namespace];		int			noldmembers;		int			nnewmembers;		Oid		   *oldmembers;		Oid		   *newmembers;		relation = heap_open(NamespaceRelationId, RowExclusiveLock);		tuple = SearchSysCache(NAMESPACENAME,							   CStringGetDatum(nspname),							   0, 0, 0);		if (!HeapTupleIsValid(tuple))			ereport(ERROR,					(errcode(ERRCODE_UNDEFINED_SCHEMA),					 errmsg("schema \"%s\" does not exist", nspname)));		pg_namespace_tuple = (Form_pg_namespace) GETSTRUCT(tuple);		/*		 * Get owner ID and working copy of existing ACL. If there's no ACL,		 * substitute the proper default.		 */		ownerId = pg_namespace_tuple->nspowner;		aclDatum = SysCacheGetAttr(NAMESPACENAME, tuple,								   Anum_pg_namespace_nspacl,								   &isNull);		if (isNull)			old_acl = acldefault(ACL_OBJECT_NAMESPACE, ownerId);		else			old_acl = DatumGetAclPCopy(aclDatum);		/* Determine ID to do the grant as, and available grant options */		select_best_grantor(GetUserId(), privileges,							old_acl, ownerId,							&grantorId, &avail_goptions);		/*		 * If we found no grant options, consider whether to issue a hard		 * error.  Per spec, having any privilege at all on the object will		 * get you by here.		 */		if (avail_goptions == ACL_NO_RIGHTS)		{			if (pg_namespace_aclmask(HeapTupleGetOid(tuple),									 grantorId,									 ACL_ALL_RIGHTS_NAMESPACE | ACL_GRANT_OPTION_FOR(ACL_ALL_RIGHTS_NAMESPACE),									 ACLMASK_ANY) == ACL_NO_RIGHTS)				aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_NAMESPACE,							   nspname);		}		/*		 * Restrict the operation to what we can actually grant or revoke, and		 * issue a warning if appropriate.	(For REVOKE this isn't quite what		 * the spec says to do: the spec seems to want a warning only if no		 * privilege bits actually change in the ACL. In practice that		 * behavior seems much too noisy, as well as inconsistent with the		 * GRANT case.)		 */		this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions);		if (stmt->is_grant)		{			if (this_privileges == 0)				ereport(WARNING,						(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),						 errmsg("no privileges were granted")));			else if (!all_privs && this_privileges != privileges)				ereport(WARNING,						(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),						 errmsg("not all privileges were granted")));		}		else		{			if (this_privileges == 0)				ereport(WARNING,						(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),						 errmsg("no privileges could be revoked")));			else if (!all_privs && this_privileges != privileges)				ereport(WARNING,						(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),						 errmsg("not all privileges could be revoked")));		}		/*		 * Generate new ACL.		 *		 * We need the members of both old and new ACLs so we can correct the		 * shared dependency information.		 */		noldmembers = aclmembers(old_acl, &oldmembers);		new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,									   stmt->grant_option, stmt->behavior,									   stmt->grantees, this_privileges,									   grantorId, ownerId);		nnewmembers = aclmembers(new_acl, &newmembers);		/* finished building new ACL value, now insert it */		MemSet(values, 0, sizeof(values));		MemSet(nulls, ' ', sizeof(nulls));		MemSet(replaces, ' ', sizeof(replaces));		replaces[Anum_pg_namespace_nspacl - 1] = 'r';		values[Anum_pg_namespace_nspacl - 1] = PointerGetDatum(new_acl);		newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces);		simple_heap_update(relation, &newtuple->t_self, newtuple);		/* keep the catalog indexes up to date */		CatalogUpdateIndexes(relation, newtuple);		/* Update the shared dependency ACL info */		updateAclDependencies(NamespaceRelationId, HeapTupleGetOid(tuple),							  ownerId, stmt->is_grant,							  noldmembers, oldmembers,							  nnewmembers, newmembers);		ReleaseSysCache(tuple);		pfree(new_acl);		heap_close(relation, RowExclusiveLock);		/* prevent error when processing duplicate objects */		CommandCounterIncrement();	}}static voidExecuteGrantStmt_Tablespace(GrantStmt *stmt){	AclMode		privileges;	bool		all_privs;	ListCell   *i;	if (stmt->privileges == NIL)	{		all_privs = true;		privileges = ACL_ALL_RIGHTS_TABLESPACE;	}	else	{		all_privs = false;		privileges = ACL_NO_RIGHTS;		foreach(i, stmt->privileges)		{			char	   *privname = strVal(lfirst(i));			AclMode		priv = string_to_privilege(privname);			if (priv & ~((AclMode) ACL_ALL_RIGHTS_TABLESPACE))				ereport(ERROR,						(errcode(ERRCODE_INVALID_GRANT_OPERATION),						 errmsg("invalid privilege type %s for tablespace",								privilege_to_string(priv))));			privileges |= priv;		}	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -