初めに
初めてPostgreSQLに触れたときにユーザとロールの違いに困惑しました。
過去形にしてますが、この記事をまとめるまでなんとなく同じもんぐらいの認識でいました。
そんな曖昧な認識をこの記事で解消して下さい。
記事で得られること
- PostgreSQLについて詳しくなれる
- ユーザ・ロールについて理解できる
ユーザ・ロールとは?
ユーザ・ロールと呼び方があるが、PostgreSQLの内部的にはロールで統一されています。
ログイン権限があればユーザ。逆にログイン権限がなければロール。という分け方で覚えておけば大丈夫です。
ではなぜログイン権限の可否で呼び方が変わるのか?
CREATE ROLE
とCREATE USER
なぜログイン権限の可否で呼び方が変わるのかは
CREATE ROLE
とCREATE USER
についてソースコードを見たら納得ができます。
まずはCREATE ROLE
について、以下がソースコードです。
CreateRoleStmt:
CREATE ROLE RoleId opt_with OptRoleList
{
CreateRoleStmt *n = makeNode(CreateRoleStmt);
n->stmt_type = ROLESTMT_ROLE;
n->role = $3;
n->options = $5;
$$ = (Node *) n;
}
;
次にCREATE USER
のソースコードです。
/*****************************************************************************
*
* Create a new Postgres DBMS user (role with implied login ability)
*
*****************************************************************************/
CreateUserStmt:
CREATE USER RoleId opt_with OptRoleList
{
CreateRoleStmt *n = makeNode(CreateRoleStmt);
n->stmt_type = ROLESTMT_USER;
n->role = $3;
n->options = $5;
$$ = (Node *) n;
}
;
makeNode(CreateRoleStmt)
でCreateRoleStmtを利用しているので、CREATE USER
を利用しても内部的にはロールを作成するようになっています。
また、n->stmt_type
にROLESTMT_USER
を代入しているのも把握しておきます。
続いて、ログイン権限の可否について確認しましょう。
ログイン権限の可否はCreateRole()関数について読むと理解できます。
CreateRole()のソースコード
/*
* CREATE ROLE
*/
Oid
CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
{
Relation pg_authid_rel;
TupleDesc pg_authid_dsc;
HeapTuple tuple;
Datum new_record[Natts_pg_authid] = {0};
bool new_record_nulls[Natts_pg_authid] = {0};
Oid currentUserId = GetUserId();
Oid roleid;
ListCell *item;
ListCell *option;
char *password = NULL; /* user password */
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? */
bool isreplication = false; /* Is this a replication role? */
bool bypassrls = false; /* Is this a row security enabled role? */
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 */
Datum validUntil_datum; /* same, as timestamptz Datum */
bool validUntil_null;
DefElem *dpassword = NULL;
DefElem *dissuper = NULL;
DefElem *dinherit = NULL;
DefElem *dcreaterole = NULL;
DefElem *dcreatedb = NULL;
DefElem *dcanlogin = NULL;
DefElem *disreplication = NULL;
DefElem *dconnlimit = NULL;
DefElem *daddroleto = NULL;
DefElem *drolemembers = NULL;
DefElem *dadminmembers = NULL;
DefElem *dvalidUntil = NULL;
DefElem *dbypassRLS = NULL;
GrantRoleOptions popt;
/* 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;
}
bool canlogin = false;
としているのでCREATE ROLE
はデフォルトでログイン権限がありません。
そしてswitch文の箇所でROLESTMT_USER
であればログイン権限が付与されるように書かれています。
CREATE USER
のstmt_type
でROLESTMT_USER
が記載されていたのはこの箇所で利用されてました。
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;
}
以上の理由からログイン権限の可否でユーザ・ロールを分けていることが理解できます。
まとめ
ユーザ・ロールの違いについては以下の通り
- ユーザは作成時デフォルトでログイン権限がある
- ロールは作成時デフォルトでログイン権限がない
会話の中での使い分けを理由も知った上でできればちょいとできる人と思われるので有効活用して下さい(?)