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

📄 user.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/*------------------------------------------------------------------------- * * user.c *	  Commands for manipulating roles (formerly called users). * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.164 2005/11/04 17:25:15 tgl Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "access/genam.h"#include "access/heapam.h"#include "catalog/dependency.h"#include "catalog/indexing.h"#include "catalog/pg_auth_members.h"#include "catalog/pg_authid.h"#include "commands/user.h"#include "libpq/crypt.h"#include "miscadmin.h"#include "utils/acl.h"#include "utils/builtins.h"#include "utils/flatfiles.h"#include "utils/fmgroids.h"#include "utils/guc.h"#include "utils/lsyscache.h"#include "utils/syscache.h"extern bool Password_encryption;static List *roleNamesToIds(List *memberNames);static void AddRoleMems(const char *rolename, Oid roleid,			List *memberNames, List *memberIds,			Oid grantorId, bool admin_opt);static void DelRoleMems(const char *rolename, Oid roleid,			List *memberNames, List *memberIds,			bool admin_opt);/* Check if current user has createrole privileges */static boolhave_createrole_privilege(void){	bool		result = false;	HeapTuple	utup;	/* Superusers can always do everything */	if (superuser())		return true;	utup = SearchSysCache(AUTHOID,						  ObjectIdGetDatum(GetUserId()),						  0, 0, 0);	if (HeapTupleIsValid(utup))	{		result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;		ReleaseSysCache(utup);	}	return result;}/* * CREATE ROLE */voidCreateRole(CreateRoleStmt *stmt){	Relation	pg_authid_rel;	TupleDesc	pg_authid_dsc;	HeapTuple	tuple;	Datum		new_record[Natts_pg_authid];	char		new_record_nulls[Natts_pg_authid];	Oid			roleid;	ListCell   *item;	ListCell   *option;	char	   *password = NULL;	/* user password */	bool		encrypt_password = Password_encryption; /* encrypt password? */	char		encrypted_password[MD5_PASSWD_LEN + 1];	bool		issuper = false;	/* Make the user a superuser? */	bool		inherit = true; /* Auto inherit privileges? */	bool		createrole = false;		/* Can this user create roles? */	bool		createdb = false;		/* Can the user create databases? */	bool		canlogin = false;		/* Can this user login? */	int			connlimit = -1; /* maximum connections allowed */	List	   *addroleto = NIL;	/* roles to make this a member of */	List	   *rolemembers = NIL;		/* roles to be members of this role */	List	   *adminmembers = NIL;		/* roles to be admins of this role */	char	   *validUntil = NULL;		/* time the login is valid until */	DefElem    *dpassword = NULL;	DefElem    *dissuper = NULL;	DefElem    *dinherit = NULL;	DefElem    *dcreaterole = NULL;	DefElem    *dcreatedb = NULL;	DefElem    *dcanlogin = NULL;	DefElem    *dconnlimit = NULL;	DefElem    *daddroleto = NULL;	DefElem    *drolemembers = NULL;	DefElem    *dadminmembers = NULL;	DefElem    *dvalidUntil = NULL;	/* The defaults can vary depending on the original statement type */	switch (stmt->stmt_type)	{		case ROLESTMT_ROLE:			break;		case ROLESTMT_USER:			canlogin = true;			/* may eventually want inherit to default to false here */			break;		case ROLESTMT_GROUP:			break;	}	/* Extract options from the statement node tree */	foreach(option, stmt->options)	{		DefElem    *defel = (DefElem *) lfirst(option);		if (strcmp(defel->defname, "password") == 0 ||			strcmp(defel->defname, "encryptedPassword") == 0 ||			strcmp(defel->defname, "unencryptedPassword") == 0)		{			if (dpassword)				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("conflicting or redundant options")));			dpassword = defel;			if (strcmp(defel->defname, "encryptedPassword") == 0)				encrypt_password = true;			else if (strcmp(defel->defname, "unencryptedPassword") == 0)				encrypt_password = false;		}		else if (strcmp(defel->defname, "sysid") == 0)		{			ereport(NOTICE,					(errmsg("SYSID can no longer be specified")));		}		else if (strcmp(defel->defname, "superuser") == 0)		{			if (dissuper)				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("conflicting or redundant options")));			dissuper = defel;		}		else if (strcmp(defel->defname, "inherit") == 0)		{			if (dinherit)				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("conflicting or redundant options")));			dinherit = defel;		}		else if (strcmp(defel->defname, "createrole") == 0)		{			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, "addroleto") == 0)		{			if (daddroleto)				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("conflicting or redundant options")));			daddroleto = defel;		}		else if (strcmp(defel->defname, "rolemembers") == 0)		{			if (drolemembers)				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("conflicting or redundant options")));			drolemembers = defel;		}		else if (strcmp(defel->defname, "adminmembers") == 0)		{			if (dadminmembers)				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("conflicting or redundant options")));			dadminmembers = 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) != 0;	if (dinherit)		inherit = intVal(dinherit->arg) != 0;	if (dcreaterole)		createrole = intVal(dcreaterole->arg) != 0;	if (dcreatedb)		createdb = intVal(dcreatedb->arg) != 0;	if (dcanlogin)		canlogin = intVal(dcanlogin->arg) != 0;	if (dconnlimit)		connlimit = intVal(dconnlimit->arg);	if (daddroleto)		addroleto = (List *) daddroleto->arg;	if (drolemembers)		rolemembers = (List *) drolemembers->arg;	if (dadminmembers)		adminmembers = (List *) dadminmembers->arg;	if (dvalidUntil)		validUntil = strVal(dvalidUntil->arg);	/* Check some permissions first */	if (issuper)	{		if (!superuser())			ereport(ERROR,					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),					 errmsg("must be superuser to create superusers")));	}	else	{		if (!have_createrole_privilege())			ereport(ERROR,					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),					 errmsg("permission denied to create role")));	}	if (strcmp(stmt->role, "public") == 0 ||		strcmp(stmt->role, "none") == 0)		ereport(ERROR,				(errcode(ERRCODE_RESERVED_NAME),				 errmsg("role name \"%s\" is reserved",						stmt->role)));	/*	 * Check the pg_authid relation to be certain the role doesn't already	 * exist.  Note we secure exclusive lock because we need to protect our	 * eventual 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_DUPLICATE_OBJECT),				 errmsg("role \"%s\" already exists",						stmt->role)));	/*	 * Build a tuple to insert	 */	MemSet(new_record, 0, sizeof(new_record));	MemSet(new_record_nulls, ' ', sizeof(new_record_nulls));	new_record[Anum_pg_authid_rolname - 1] =		DirectFunctionCall1(namein, CStringGetDatum(stmt->role));	new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper);	new_record[Anum_pg_authid_rolinherit - 1] = BoolGetDatum(inherit);	new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole);	new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(createdb);	/* superuser gets catupdate right by default */	new_record[Anum_pg_authid_rolcatupdate - 1] = BoolGetDatum(issuper);	new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(canlogin);	new_record[Anum_pg_authid_rolconnlimit - 1] = Int32GetDatum(connlimit);	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));		}	}	else		new_record_nulls[Anum_pg_authid_rolpassword - 1] = 'n';	if (validUntil)		new_record[Anum_pg_authid_rolvaliduntil - 1] =			DirectFunctionCall3(timestamptz_in,								CStringGetDatum(validUntil),								ObjectIdGetDatum(InvalidOid),								Int32GetDatum(-1));	else		new_record_nulls[Anum_pg_authid_rolvaliduntil - 1] = 'n';	new_record_nulls[Anum_pg_authid_rolconfig - 1] = 'n';	tuple = heap_formtuple(pg_authid_dsc, new_record, new_record_nulls);	/*	 * Insert new record in the pg_authid table	 */	roleid = simple_heap_insert(pg_authid_rel, tuple);	CatalogUpdateIndexes(pg_authid_rel, tuple);	/*	 * Advance command counter so we can see new record; else tests in	 * AddRoleMems may fail.	 */	if (addroleto || adminmembers || rolemembers)		CommandCounterIncrement();	/*	 * Add the new role to the specified existing roles.	 */	foreach(item, addroleto)	{		char	   *oldrolename = strVal(lfirst(item));		Oid			oldroleid = get_roleid_checked(oldrolename);		AddRoleMems(oldrolename, oldroleid,					list_make1(makeString(stmt->role)),					list_make1_oid(roleid),					GetUserId(), false);	}	/*	 * Add the specified members to this new role. adminmembers get the admin	 * option, rolemembers don't.	 */	AddRoleMems(stmt->role, roleid,				adminmembers, roleNamesToIds(adminmembers),				GetUserId(), true);	AddRoleMems(stmt->role, roleid,				rolemembers, roleNamesToIds(rolemembers),				GetUserId(), 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 * * Note: the rolemembers option accepted here is intended to support the * backwards-compatible ALTER GROUP syntax.  Although it will work to say * "ALTER ROLE role ROLE rolenames", we don't document it. */voidAlterRole(AlterRoleStmt *stmt){	Datum		new_record[Natts_pg_authid];	char		new_record_nulls[Natts_pg_authid];	char		new_record_repl[Natts_pg_authid];	Relation	pg_authid_rel;	TupleDesc	pg_authid_dsc;	HeapTuple	tuple,				new_tuple;	ListCell   *option;	char	   *password = NULL;	/* user password */	bool		encrypt_password = Password_encryption; /* encrypt password? */	char		encrypted_password[MD5_PASSWD_LEN + 1];	int			issuper = -1;	/* Make the user a superuser? */	int			inherit = -1;	/* Auto inherit privileges? */	int			createrole = -1;	/* Can this user create roles? */	int			createdb = -1;	/* Can the user create databases? */	int			canlogin = -1;	/* Can this user login? */	int			connlimit = -1; /* maximum connections allowed */	List	   *rolemembers = NIL;		/* roles to be added/removed */	char	   *validUntil = NULL;		/* time the login is valid until */	DefElem    *dpassword = NULL;	DefElem    *dissuper = NULL;	DefElem    *dinherit = NULL;	DefElem    *dcreaterole = NULL;	DefElem    *dcreatedb = NULL;	DefElem    *dcanlogin = NULL;	DefElem    *dconnlimit = NULL;	DefElem    *drolemembers = NULL;	DefElem    *dvalidUntil = NULL;	Oid			roleid;	/* Extract options from the statement node tree */	foreach(option, stmt->options)	{		DefElem    *defel = (DefElem *) lfirst(option);		if (strcmp(defel->defname, "password") == 0 ||			strcmp(defel->defname, "encryptedPassword") == 0 ||			strcmp(defel->defname, "unencryptedPassword") == 0)		{			if (dpassword)				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("conflicting or redundant options")));			dpassword = defel;			if (strcmp(defel->defname, "encryptedPassword") == 0)				encrypt_password = true;			else if (strcmp(defel->defname, "unencryptedPassword") == 0)				encrypt_password = false;		}		else if (strcmp(defel->defname, "superuser") == 0)		{			if (dissuper)				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("conflicting or redundant options")));			dissuper = defel;		}		else if (strcmp(defel->defname, "inherit") == 0)		{			if (dinherit)				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("conflicting or redundant options")));			dinherit = defel;		}		else if (strcmp(defel->defname, "createrole") == 0)		{

⌨️ 快捷键说明

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