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

📄 acl.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
	num = ACL_NUM(acl);	aidat = ACL_DAT(acl);	/*	 * Check privileges granted directly to roleid or to public	 */	for (i = 0; i < num; i++)	{		AclItem    *aidata = &aidat[i];		if (aidata->ai_grantee == ACL_ID_PUBLIC ||			aidata->ai_grantee == roleid)		{			result |= aidata->ai_privs & mask;			if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))				return result;		}	}	/*	 * Check privileges granted indirectly via role memberships. We do this in	 * a separate pass to minimize expensive indirect membership tests.  In	 * particular, it's worth testing whether a given ACL entry grants any	 * privileges still of interest before we perform the has_privs_of_role	 * test.	 */	remaining = mask & ~result;	for (i = 0; i < num; i++)	{		AclItem    *aidata = &aidat[i];		if (aidata->ai_grantee == ACL_ID_PUBLIC ||			aidata->ai_grantee == roleid)			continue;			/* already checked it */		if ((aidata->ai_privs & remaining) &&			has_privs_of_role(roleid, aidata->ai_grantee))		{			result |= aidata->ai_privs & mask;			if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))				return result;			remaining = mask & ~result;		}	}	return result;}/* * aclmask_direct --- compute bitmask of all privileges held by roleid. * * This is exactly like aclmask() except that we consider only privileges * held *directly* by roleid, not those inherited via role membership. */static AclModeaclmask_direct(const Acl *acl, Oid roleid, Oid ownerId,			   AclMode mask, AclMaskHow how){	AclMode		result;	AclItem    *aidat;	int			i,				num;	/*	 * Null ACL should not happen, since caller should have inserted	 * appropriate default	 */	if (acl == NULL)		elog(ERROR, "null ACL");	/* Quick exit for mask == 0 */	if (mask == 0)		return 0;	result = 0;	/* Owner always implicitly has all grant options */	if ((mask & ACLITEM_ALL_GOPTION_BITS) &&		roleid == ownerId)	{		result = mask & ACLITEM_ALL_GOPTION_BITS;		if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))			return result;	}	num = ACL_NUM(acl);	aidat = ACL_DAT(acl);	/*	 * Check privileges granted directly to roleid (and not to public)	 */	for (i = 0; i < num; i++)	{		AclItem    *aidata = &aidat[i];		if (aidata->ai_grantee == roleid)		{			result |= aidata->ai_privs & mask;			if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))				return result;		}	}	return result;}/* * aclmembers *		Find out all the roleids mentioned in an Acl. *		Note that we do not distinguish grantors from grantees. * * *roleids is set to point to a palloc'd array containing distinct OIDs * in sorted order.  The length of the array is the function result. */intaclmembers(const Acl *acl, Oid **roleids){	Oid		   *list;	const AclItem *acldat;	int			i,				j,				k;	if (acl == NULL || ACL_NUM(acl) == 0)	{		*roleids = NULL;		return 0;	}	/* Allocate the worst-case space requirement */	list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid));	acldat = ACL_DAT(acl);	/*	 * Walk the ACL collecting mentioned RoleIds.	 */	j = 0;	for (i = 0; i < ACL_NUM(acl); i++)	{		const AclItem *ai = &acldat[i];		if (ai->ai_grantee != ACL_ID_PUBLIC)			list[j++] = ai->ai_grantee;		/* grantor is currently never PUBLIC, but let's check anyway */		if (ai->ai_grantor != ACL_ID_PUBLIC)			list[j++] = ai->ai_grantor;	}	/* Sort the array */	qsort(list, j, sizeof(Oid), oidComparator);	/* Remove duplicates from the array */	k = 0;	for (i = 1; i < j; i++)	{		if (list[k] != list[i])			list[++k] = list[i];	}	/*	 * We could repalloc the array down to minimum size, but it's hardly worth	 * it since it's only transient memory.	 */	*roleids = list;	return k + 1;}/* * oidComparator *		qsort comparison function for Oids */static intoidComparator(const void *arg1, const void *arg2){	Oid			oid1 = *(const Oid *) arg1;	Oid			oid2 = *(const Oid *) arg2;	if (oid1 > oid2)		return 1;	if (oid1 < oid2)		return -1;	return 0;}/* * aclinsert (exported function) */Datumaclinsert(PG_FUNCTION_ARGS){	ereport(ERROR,			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),			 errmsg("aclinsert is no longer supported")));	PG_RETURN_NULL();			/* keep compiler quiet */}Datumaclremove(PG_FUNCTION_ARGS){	ereport(ERROR,			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),			 errmsg("aclremove is no longer supported")));	PG_RETURN_NULL();			/* keep compiler quiet */}Datumaclcontains(PG_FUNCTION_ARGS){	Acl		   *acl = PG_GETARG_ACL_P(0);	AclItem    *aip = PG_GETARG_ACLITEM_P(1);	AclItem    *aidat;	int			i,				num;	num = ACL_NUM(acl);	aidat = ACL_DAT(acl);	for (i = 0; i < num; ++i)	{		if (aip->ai_grantee == aidat[i].ai_grantee &&			aip->ai_grantor == aidat[i].ai_grantor &&			(ACLITEM_GET_RIGHTS(*aip) & ACLITEM_GET_RIGHTS(aidat[i])) == ACLITEM_GET_RIGHTS(*aip))			PG_RETURN_BOOL(true);	}	PG_RETURN_BOOL(false);}Datummakeaclitem(PG_FUNCTION_ARGS){	Oid			grantee = PG_GETARG_OID(0);	Oid			grantor = PG_GETARG_OID(1);	text	   *privtext = PG_GETARG_TEXT_P(2);	bool		goption = PG_GETARG_BOOL(3);	AclItem    *result;	AclMode		priv;	priv = convert_priv_string(privtext);	result = (AclItem *) palloc(sizeof(AclItem));	result->ai_grantee = grantee;	result->ai_grantor = grantor;	ACLITEM_SET_PRIVS_GOPTIONS(*result, priv,							   (goption ? priv : ACL_NO_RIGHTS));	PG_RETURN_ACLITEM_P(result);}static AclModeconvert_priv_string(text *priv_type_text){	char	   *priv_type;	priv_type = DatumGetCString(DirectFunctionCall1(textout,										   PointerGetDatum(priv_type_text)));	if (pg_strcasecmp(priv_type, "SELECT") == 0)		return ACL_SELECT;	if (pg_strcasecmp(priv_type, "INSERT") == 0)		return ACL_INSERT;	if (pg_strcasecmp(priv_type, "UPDATE") == 0)		return ACL_UPDATE;	if (pg_strcasecmp(priv_type, "DELETE") == 0)		return ACL_DELETE;	if (pg_strcasecmp(priv_type, "RULE") == 0)		return ACL_RULE;	if (pg_strcasecmp(priv_type, "REFERENCES") == 0)		return ACL_REFERENCES;	if (pg_strcasecmp(priv_type, "TRIGGER") == 0)		return ACL_TRIGGER;	if (pg_strcasecmp(priv_type, "EXECUTE") == 0)		return ACL_EXECUTE;	if (pg_strcasecmp(priv_type, "USAGE") == 0)		return ACL_USAGE;	if (pg_strcasecmp(priv_type, "CREATE") == 0)		return ACL_CREATE;	if (pg_strcasecmp(priv_type, "TEMP") == 0)		return ACL_CREATE_TEMP;	if (pg_strcasecmp(priv_type, "TEMPORARY") == 0)		return ACL_CREATE_TEMP;	ereport(ERROR,			(errcode(ERRCODE_INVALID_PARAMETER_VALUE),			 errmsg("unrecognized privilege type: \"%s\"", priv_type)));	return ACL_NO_RIGHTS;		/* keep compiler quiet */}/* * has_table_privilege variants *		These are all named "has_table_privilege" at the SQL level. *		They take various combinations of relation name, relation OID, *		user name, user OID, or implicit user = current_user. * *		The result is a boolean value: true if user has the indicated *		privilege, false if not. *//* * has_table_privilege_name_name *		Check user privileges on a table given *		name username, text tablename, and text priv name. */Datumhas_table_privilege_name_name(PG_FUNCTION_ARGS){	Name		rolename = PG_GETARG_NAME(0);	text	   *tablename = PG_GETARG_TEXT_P(1);	text	   *priv_type_text = PG_GETARG_TEXT_P(2);	Oid			roleid;	Oid			tableoid;	AclMode		mode;	AclResult	aclresult;	roleid = get_roleid_checked(NameStr(*rolename));	tableoid = convert_table_name(tablename);	mode = convert_table_priv_string(priv_type_text);	aclresult = pg_class_aclcheck(tableoid, roleid, mode);	PG_RETURN_BOOL(aclresult == ACLCHECK_OK);}/* * has_table_privilege_name *		Check user privileges on a table given *		text tablename and text priv name. *		current_user is assumed */Datumhas_table_privilege_name(PG_FUNCTION_ARGS){	text	   *tablename = PG_GETARG_TEXT_P(0);	text	   *priv_type_text = PG_GETARG_TEXT_P(1);	Oid			roleid;	Oid			tableoid;	AclMode		mode;	AclResult	aclresult;	roleid = GetUserId();	tableoid = convert_table_name(tablename);	mode = convert_table_priv_string(priv_type_text);	aclresult = pg_class_aclcheck(tableoid, roleid, mode);	PG_RETURN_BOOL(aclresult == ACLCHECK_OK);}/* * has_table_privilege_name_id *		Check user privileges on a table given *		name usename, table oid, and text priv name. */Datumhas_table_privilege_name_id(PG_FUNCTION_ARGS){	Name		username = PG_GETARG_NAME(0);	Oid			tableoid = PG_GETARG_OID(1);	text	   *priv_type_text = PG_GETARG_TEXT_P(2);	Oid			roleid;	AclMode		mode;	AclResult	aclresult;	roleid = get_roleid_checked(NameStr(*username));	mode = convert_table_priv_string(priv_type_text);	aclresult = pg_class_aclcheck(tableoid, roleid, mode);	PG_RETURN_BOOL(aclresult == ACLCHECK_OK);}/* * has_table_privilege_id *		Check user privileges on a table given *		table oid, and text priv name. *		current_user is assumed */Datumhas_table_privilege_id(PG_FUNCTION_ARGS){	Oid			tableoid = PG_GETARG_OID(0);	text	   *priv_type_text = PG_GETARG_TEXT_P(1);	Oid			roleid;	AclMode		mode;	AclResult	aclresult;	roleid = GetUserId();	mode = convert_table_priv_string(priv_type_text);	aclresult = pg_class_aclcheck(tableoid, roleid, mode);	PG_RETURN_BOOL(aclresult == ACLCHECK_OK);}/* * has_table_privilege_id_name *		Check user privileges on a table given *		roleid, text tablename, and text priv name. */Datumhas_table_privilege_id_name(PG_FUNCTION_ARGS){	Oid			roleid = PG_GETARG_OID(0);	text	   *tablename = PG_GETARG_TEXT_P(1);	text	   *priv_type_text = PG_GETARG_TEXT_P(2);	Oid			tableoid;	AclMode		mode;	AclResult	aclresult;	tableoid = convert_table_name(tablename);	mode = convert_table_priv_string(priv_type_text);	aclresult = pg_class_aclcheck(tableoid, roleid, mode);	PG_RETURN_BOOL(aclresult == ACLCHECK_OK);}/* * has_table_privilege_id_id *		Check user privileges on a table given *		roleid, table oid, and text priv name. */Datumhas_table_privilege_id_id(PG_FUNCTION_ARGS){	Oid			roleid = PG_GETARG_OID(0);	Oid			tableoid = PG_GETARG_OID(1);	text	   *priv_type_text = PG_GETARG_TEXT_P(2);	AclMode		mode;	AclResult	aclresult;	mode = convert_table_priv_string(priv_type_text);	aclresult = pg_class_aclcheck(tableoid, roleid, mode);	PG_RETURN_BOOL(aclresult == ACLCHECK_OK);}/* *		Support routines for has_table_privilege family. *//* * Given a table name expressed as a string, look it up and return Oid */static Oidconvert_table_name(text *tablename){	RangeVar   *relrv;	relrv = makeRangeVarFromNameList(textToQualifiedNameList(tablename));	return RangeVarGetRelid(relrv, false);}/* * convert_table_priv_string *		Convert text string to AclMode value. */static AclModeconvert_table_priv_string(text *priv_type_text){	char	   *priv_type;	priv_type = DatumGetCString(DirectFunctionCall1(textout,										   PointerGetDatum(priv_type_text)));	/*	 * Return mode from priv_type string	 */	if (pg_strcasecmp(priv_type, "SELECT") == 0)		return ACL_SELECT;	if (pg_strcasecmp(priv_type, "SELECT WITH GRANT OPTION") == 0)		return ACL_GRANT_OPTION_FOR(ACL_SELECT);	if (pg_strcasecmp(priv_type, "INSERT") == 0)		return ACL_INSERT;	if (pg_strcasecmp(priv_type, "INSERT WITH GRANT OPTION") == 0)		return ACL_GRANT_OPTION_FOR(ACL_INSERT);	if (pg_strcasecmp(priv_type, "UPDATE") == 0)		return ACL_UPDATE;	if (pg_strcasecmp(priv_type, "UPDATE WITH GRANT OPTION") == 0)		return ACL_GRANT_OPTION_FOR(ACL_UPDATE);	if (pg_strcasecmp(priv_type, "DELETE") == 0)		return ACL_DELETE;	if (pg_strcasecmp(priv_type, "DELETE WITH GRANT OPTION") == 0)		return ACL_GRANT_OPTION_FOR(ACL_DELETE);	if (pg_strcasecmp(priv_type, "RULE") == 0)		return ACL_RULE;	if (pg_strcasecmp(priv_type, "RULE WITH GRANT OPTION") == 0)		return ACL_GRANT_OPTION_FOR(ACL_RULE);	if (pg_strcasecmp(priv_type, "REFERENCES") == 0)		return ACL_REFERENCES;	if (pg_strcasecmp(priv_type, "REFERENCES WITH GRANT OPTION") == 0)		return ACL_GRANT_OPTION_FOR(ACL_REFERENCES);	if (pg_strcasecmp(priv_type, "TRIGGER") == 0)		return ACL_TRIGGER;	if (pg_strcasecmp(priv_type, "TRIGGER WITH GRANT OPTION") == 0)		return ACL_GRANT_OPTION_FOR(ACL_TRIGGER);

⌨️ 快捷键说明

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