diff options
Diffstat (limited to 'src/backend/commands/user.c')
-rw-r--r-- | src/backend/commands/user.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 2634ca10e64..df83cdea2cf 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -94,6 +94,7 @@ CreateRole(CreateRoleStmt *stmt) 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? */ 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 */ @@ -107,6 +108,7 @@ CreateRole(CreateRoleStmt *stmt) DefElem *dcreaterole = NULL; DefElem *dcreatedb = NULL; DefElem *dcanlogin = NULL; + DefElem *disreplication = NULL; DefElem *dconnlimit = NULL; DefElem *daddroleto = NULL; DefElem *drolemembers = NULL; @@ -190,6 +192,14 @@ CreateRole(CreateRoleStmt *stmt) errmsg("conflicting or redundant options"))); dcanlogin = defel; } + else if (strcmp(defel->defname, "isreplication") == 0) + { + if (disreplication) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"))); + disreplication = defel; + } else if (strcmp(defel->defname, "connectionlimit") == 0) { if (dconnlimit) @@ -247,6 +257,8 @@ CreateRole(CreateRoleStmt *stmt) createdb = intVal(dcreatedb->arg) != 0; if (dcanlogin) canlogin = intVal(dcanlogin->arg) != 0; + if (disreplication) + isreplication = intVal(disreplication->arg) != 0; if (dconnlimit) { connlimit = intVal(dconnlimit->arg); @@ -272,6 +284,13 @@ CreateRole(CreateRoleStmt *stmt) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to create superusers"))); } + else if (isreplication) + { + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to create replication users"))); + } else { if (!have_createrole_privilege()) @@ -341,6 +360,7 @@ CreateRole(CreateRoleStmt *stmt) /* 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_rolreplication - 1] = BoolGetDatum(isreplication); new_record[Anum_pg_authid_rolconnlimit - 1] = Int32GetDatum(connlimit); if (password) @@ -439,6 +459,7 @@ AlterRole(AlterRoleStmt *stmt) int createrole = -1; /* Can this user create roles? */ int createdb = -1; /* Can the user create databases? */ int canlogin = -1; /* Can this user login? */ + int isreplication = -1; /* Is this a replication role? */ int connlimit = -1; /* maximum connections allowed */ List *rolemembers = NIL; /* roles to be added/removed */ char *validUntil = NULL; /* time the login is valid until */ @@ -450,6 +471,7 @@ AlterRole(AlterRoleStmt *stmt) DefElem *dcreaterole = NULL; DefElem *dcreatedb = NULL; DefElem *dcanlogin = NULL; + DefElem *disreplication = NULL; DefElem *dconnlimit = NULL; DefElem *drolemembers = NULL; DefElem *dvalidUntil = NULL; @@ -514,6 +536,14 @@ AlterRole(AlterRoleStmt *stmt) errmsg("conflicting or redundant options"))); dcanlogin = defel; } + else if (strcmp(defel->defname, "isreplication") == 0) + { + if (disreplication) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"))); + disreplication = defel; + } else if (strcmp(defel->defname, "connectionlimit") == 0) { if (dconnlimit) @@ -556,6 +586,8 @@ AlterRole(AlterRoleStmt *stmt) createdb = intVal(dcreatedb->arg); if (dcanlogin) canlogin = intVal(dcanlogin->arg); + if (disreplication) + isreplication = intVal(disreplication->arg); if (dconnlimit) { connlimit = intVal(dconnlimit->arg); @@ -594,12 +626,20 @@ AlterRole(AlterRoleStmt *stmt) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to alter superusers"))); } + else if (((Form_pg_authid) GETSTRUCT(tuple))->rolreplication || isreplication >= 0) + { + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to alter replication users"))); + } else if (!have_createrole_privilege()) { if (!(inherit < 0 && createrole < 0 && createdb < 0 && canlogin < 0 && + isreplication < 0 && !dconnlimit && !rolemembers && !validUntil && @@ -685,6 +725,12 @@ AlterRole(AlterRoleStmt *stmt) new_record_repl[Anum_pg_authid_rolcanlogin - 1] = true; } + if (isreplication >= 0) + { + new_record[Anum_pg_authid_rolreplication - 1] = BoolGetDatum(isreplication > 0); + new_record_repl[Anum_pg_authid_rolreplication - 1] = true; + } + if (dconnlimit) { new_record[Anum_pg_authid_rolconnlimit - 1] = Int32GetDatum(connlimit); |