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

📄 user.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 3 页
字号:
			if (dcreaterole)				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("conflicting or redundant options")));			dcreaterole = defel;		}		else if (strcmp(defel->defname, "createdb") == 0)		{			if (dcreatedb)				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("conflicting or redundant options")));			dcreatedb = defel;		}		else if (strcmp(defel->defname, "canlogin") == 0)		{			if (dcanlogin)				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("conflicting or redundant options")));			dcanlogin = defel;		}		else if (strcmp(defel->defname, "connectionlimit") == 0)		{			if (dconnlimit)				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("conflicting or redundant options")));			dconnlimit = defel;		}		else if (strcmp(defel->defname, "rolemembers") == 0 &&				 stmt->action != 0)		{			if (drolemembers)				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("conflicting or redundant options")));			drolemembers = defel;		}		else if (strcmp(defel->defname, "validUntil") == 0)		{			if (dvalidUntil)				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("conflicting or redundant options")));			dvalidUntil = defel;		}		else			elog(ERROR, "option \"%s\" not recognized",				 defel->defname);	}	if (dpassword)		password = strVal(dpassword->arg);	if (dissuper)		issuper = intVal(dissuper->arg);	if (dinherit)		inherit = intVal(dinherit->arg);	if (dcreaterole)		createrole = intVal(dcreaterole->arg);	if (dcreatedb)		createdb = intVal(dcreatedb->arg);	if (dcanlogin)		canlogin = intVal(dcanlogin->arg);	if (dconnlimit)		connlimit = intVal(dconnlimit->arg);	if (drolemembers)		rolemembers = (List *) drolemembers->arg;	if (dvalidUntil)		validUntil = strVal(dvalidUntil->arg);	/*	 * Scan the pg_authid relation to be certain the user exists. Note we	 * secure exclusive lock to protect our update of the flat auth file.	 */	pg_authid_rel = heap_open(AuthIdRelationId, ExclusiveLock);	pg_authid_dsc = RelationGetDescr(pg_authid_rel);	tuple = SearchSysCache(AUTHNAME,						   PointerGetDatum(stmt->role),						   0, 0, 0);	if (!HeapTupleIsValid(tuple))		ereport(ERROR,				(errcode(ERRCODE_UNDEFINED_OBJECT),				 errmsg("role \"%s\" does not exist", stmt->role)));	roleid = HeapTupleGetOid(tuple);	/*	 * To mess with a superuser you gotta be superuser; else you need	 * createrole, or just want to change your own password	 */	if (((Form_pg_authid) GETSTRUCT(tuple))->rolsuper || issuper >= 0)	{		if (!superuser())			ereport(ERROR,					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),					 errmsg("must be superuser to alter superusers")));	}	else if (!have_createrole_privilege())	{		if (!(inherit < 0 &&			  createrole < 0 &&			  createdb < 0 &&			  canlogin < 0 &&			  !dconnlimit &&			  !rolemembers &&			  !validUntil &&			  password &&			  roleid == GetUserId()))			ereport(ERROR,					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),					 errmsg("permission denied")));	}	/*	 * Build an updated tuple, perusing the information just obtained	 */	MemSet(new_record, 0, sizeof(new_record));	MemSet(new_record_nulls, ' ', sizeof(new_record_nulls));	MemSet(new_record_repl, ' ', sizeof(new_record_repl));	/*	 * issuper/createrole/catupdate/etc	 *	 * XXX It's rather unclear how to handle catupdate.  It's probably best to	 * keep it equal to the superuser status, otherwise you could end up with	 * a situation where no existing superuser can alter the catalogs,	 * including pg_authid!	 */	if (issuper >= 0)	{		new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper > 0);		new_record_repl[Anum_pg_authid_rolsuper - 1] = 'r';		new_record[Anum_pg_authid_rolcatupdate - 1] = BoolGetDatum(issuper > 0);		new_record_repl[Anum_pg_authid_rolcatupdate - 1] = 'r';	}	if (inherit >= 0)	{		new_record[Anum_pg_authid_rolinherit - 1] = BoolGetDatum(inherit > 0);		new_record_repl[Anum_pg_authid_rolinherit - 1] = 'r';	}	if (createrole >= 0)	{		new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole > 0);		new_record_repl[Anum_pg_authid_rolcreaterole - 1] = 'r';	}	if (createdb >= 0)	{		new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(createdb > 0);		new_record_repl[Anum_pg_authid_rolcreatedb - 1] = 'r';	}	if (canlogin >= 0)	{		new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(canlogin > 0);		new_record_repl[Anum_pg_authid_rolcanlogin - 1] = 'r';	}	if (dconnlimit)	{		new_record[Anum_pg_authid_rolconnlimit - 1] = Int32GetDatum(connlimit);		new_record_repl[Anum_pg_authid_rolconnlimit - 1] = 'r';	}	/* password */	if (password)	{		if (!encrypt_password || isMD5(password))			new_record[Anum_pg_authid_rolpassword - 1] =				DirectFunctionCall1(textin, CStringGetDatum(password));		else		{			if (!pg_md5_encrypt(password, stmt->role, strlen(stmt->role),								encrypted_password))				elog(ERROR, "password encryption failed");			new_record[Anum_pg_authid_rolpassword - 1] =				DirectFunctionCall1(textin, CStringGetDatum(encrypted_password));		}		new_record_repl[Anum_pg_authid_rolpassword - 1] = 'r';	}	/* valid until */	if (validUntil)	{		new_record[Anum_pg_authid_rolvaliduntil - 1] =			DirectFunctionCall3(timestamptz_in,								CStringGetDatum(validUntil),								ObjectIdGetDatum(InvalidOid),								Int32GetDatum(-1));		new_record_repl[Anum_pg_authid_rolvaliduntil - 1] = 'r';	}	new_tuple = heap_modifytuple(tuple, pg_authid_dsc, new_record,								 new_record_nulls, new_record_repl);	simple_heap_update(pg_authid_rel, &tuple->t_self, new_tuple);	/* Update indexes */	CatalogUpdateIndexes(pg_authid_rel, new_tuple);	ReleaseSysCache(tuple);	heap_freetuple(new_tuple);	/*	 * Advance command counter so we can see new record; else tests in	 * AddRoleMems may fail.	 */	if (rolemembers)		CommandCounterIncrement();	if (stmt->action == +1)		/* add members to role */		AddRoleMems(stmt->role, roleid,					rolemembers, roleNamesToIds(rolemembers),					GetUserId(), false);	else if (stmt->action == -1)	/* drop members from role */		DelRoleMems(stmt->role, roleid,					rolemembers, roleNamesToIds(rolemembers),					false);	/*	 * Now we can clean up; but keep lock until commit (to avoid possible	 * deadlock when commit code tries to acquire lock).	 */	heap_close(pg_authid_rel, NoLock);	/*	 * Set flag to update flat auth file at commit.	 */	auth_file_update_needed();}/* * ALTER ROLE ... SET */voidAlterRoleSet(AlterRoleSetStmt *stmt){	char	   *valuestr;	HeapTuple	oldtuple,				newtuple;	Relation	rel;	Datum		repl_val[Natts_pg_authid];	char		repl_null[Natts_pg_authid];	char		repl_repl[Natts_pg_authid];	int			i;	valuestr = flatten_set_variable_args(stmt->variable, stmt->value);	/*	 * RowExclusiveLock is sufficient, because we don't need to update the	 * flat auth file.	 */	rel = heap_open(AuthIdRelationId, RowExclusiveLock);	oldtuple = SearchSysCache(AUTHNAME,							  PointerGetDatum(stmt->role),							  0, 0, 0);	if (!HeapTupleIsValid(oldtuple))		ereport(ERROR,				(errcode(ERRCODE_UNDEFINED_OBJECT),				 errmsg("role \"%s\" does not exist", stmt->role)));	/*	 * To mess with a superuser you gotta be superuser; else you need	 * createrole, or just want to change your own settings	 */	if (((Form_pg_authid) GETSTRUCT(oldtuple))->rolsuper)	{		if (!superuser())			ereport(ERROR,					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),					 errmsg("must be superuser to alter superusers")));	}	else	{		if (!have_createrole_privilege() &&			HeapTupleGetOid(oldtuple) != GetUserId())			ereport(ERROR,					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),					 errmsg("permission denied")));	}	for (i = 0; i < Natts_pg_authid; i++)		repl_repl[i] = ' ';	repl_repl[Anum_pg_authid_rolconfig - 1] = 'r';	if (strcmp(stmt->variable, "all") == 0 && valuestr == NULL)	{		/* RESET ALL */		repl_null[Anum_pg_authid_rolconfig - 1] = 'n';	}	else	{		Datum		datum;		bool		isnull;		ArrayType  *array;		repl_null[Anum_pg_authid_rolconfig - 1] = ' ';		datum = SysCacheGetAttr(AUTHNAME, oldtuple,								Anum_pg_authid_rolconfig, &isnull);		array = isnull ? NULL : DatumGetArrayTypeP(datum);		if (valuestr)			array = GUCArrayAdd(array, stmt->variable, valuestr);		else			array = GUCArrayDelete(array, stmt->variable);		if (array)			repl_val[Anum_pg_authid_rolconfig - 1] = PointerGetDatum(array);		else			repl_null[Anum_pg_authid_rolconfig - 1] = 'n';	}	newtuple = heap_modifytuple(oldtuple, RelationGetDescr(rel),								repl_val, repl_null, repl_repl);	simple_heap_update(rel, &oldtuple->t_self, newtuple);	CatalogUpdateIndexes(rel, newtuple);	ReleaseSysCache(oldtuple);	heap_close(rel, RowExclusiveLock);}/* * DROP ROLE */voidDropRole(DropRoleStmt *stmt){	Relation	pg_authid_rel,				pg_auth_members_rel;	ListCell   *item;	if (!have_createrole_privilege())		ereport(ERROR,				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),				 errmsg("permission denied to drop role")));	/*	 * Scan the pg_authid relation to find the Oid of the role(s) to be	 * deleted.  Note we secure exclusive lock on pg_authid, because we need	 * to protect our update of the flat auth file.  A regular writer's lock	 * on pg_auth_members is sufficient though.	 */	pg_authid_rel = heap_open(AuthIdRelationId, ExclusiveLock);	pg_auth_members_rel = heap_open(AuthMemRelationId, RowExclusiveLock);	foreach(item, stmt->roles)	{		const char *role = strVal(lfirst(item));		HeapTuple	tuple,					tmp_tuple;		ScanKeyData scankey;		char	   *detail;		SysScanDesc sscan;		Oid			roleid;		tuple = SearchSysCache(AUTHNAME,							   PointerGetDatum(role),							   0, 0, 0);		if (!HeapTupleIsValid(tuple))			ereport(ERROR,					(errcode(ERRCODE_UNDEFINED_OBJECT),					 errmsg("role \"%s\" does not exist", role)));		roleid = HeapTupleGetOid(tuple);		if (roleid == GetUserId())			ereport(ERROR,					(errcode(ERRCODE_OBJECT_IN_USE),					 errmsg("current user cannot be dropped")));		if (roleid == GetOuterUserId())			ereport(ERROR,					(errcode(ERRCODE_OBJECT_IN_USE),					 errmsg("current user cannot be dropped")));		if (roleid == GetSessionUserId())			ereport(ERROR,					(errcode(ERRCODE_OBJECT_IN_USE),					 errmsg("session user cannot be dropped")));		/*		 * For safety's sake, we allow createrole holders to drop ordinary		 * roles but not superuser roles.  This is mainly to avoid the		 * scenario where you accidentally drop the last superuser.		 */		if (((Form_pg_authid) GETSTRUCT(tuple))->rolsuper &&			!superuser())			ereport(ERROR,					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),					 errmsg("must be superuser to drop superusers")));		/*		 * Lock the role, so nobody can add dependencies to her while we drop		 * her.  We keep the lock until the end of transaction.		 */		LockSharedObject(AuthIdRelationId, roleid, 0, AccessExclusiveLock);		/* Check for pg_shdepend entries depending on this role */		if ((detail = checkSharedDependencies(AuthIdRelationId, roleid)) != NULL)			ereport(ERROR,					(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),					 errmsg("role \"%s\" cannot be dropped because some objects depend on it",							role),					 errdetail("%s", detail)));		/*		 * Remove the role from the pg_authid table		 */		simple_heap_delete(pg_authid_rel, &tuple->t_self);		ReleaseSysCache(tuple);		/*		 * Remove role from the pg_auth_members table.	We have to remove all		 * tuples that show it as either a role or a member.		 *		 * XXX what about grantor entries?	Maybe we should do one heap scan.		 */		ScanKeyInit(&scankey,					Anum_pg_auth_members_roleid,					BTEqualStrategyNumber, F_OIDEQ,					ObjectIdGetDatum(roleid));		sscan = systable_beginscan(pg_auth_members_rel, AuthMemRoleMemIndexId,								   true, SnapshotNow, 1, &scankey);		while (HeapTupleIsValid(tmp_tuple = systable_getnext(sscan)))		{			simple_heap_delete(pg_auth_members_rel, &tmp_tuple->t_self);		}		systable_endscan(sscan);		ScanKeyInit(&scankey,					Anum_pg_auth_members_member,					BTEqualStrategyNumber, F_OIDEQ,					ObjectIdGetDatum(roleid));		sscan = systable_beginscan(pg_auth_members_rel, AuthMemMemRoleIndexId,								   true, SnapshotNow, 1, &scankey);		while (HeapTupleIsValid(tmp_tuple = systable_getnext(sscan)))		{			simple_heap_delete(pg_auth_members_rel, &tmp_tuple->t_self);		}		systable_endscan(sscan);		/*		 * Advance command counter so that later iterations of this loop will		 * see the changes already made.  This is essential if, for example,		 * we are trying to drop both a role and one of its direct members ---		 * we'll get an error if we try to delete the linking pg_auth_members		 * tuple twice.  (We do not need a CCI between the two delete loops		 * above, because it's not allowed for a role to directly contain		 * itself.)		 */		CommandCounterIncrement();	}

⌨️ 快捷键说明

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