@@ -94,6 +94,7 @@ CreateRole(CreateRoleStmt *stmt)
9494 bool createrole = false; /* Can this user create roles? */
9595 bool createdb = false; /* Can the user create databases? */
9696 bool canlogin = false; /* Can this user login? */
97+ bool isreplication = false; /* Is this a replication role? */
9798 int connlimit = -1 ; /* maximum connections allowed */
9899 List * addroleto = NIL ; /* roles to make this a member of */
99100 List * rolemembers = NIL ; /* roles to be members of this role */
@@ -107,6 +108,7 @@ CreateRole(CreateRoleStmt *stmt)
107108 DefElem * dcreaterole = NULL ;
108109 DefElem * dcreatedb = NULL ;
109110 DefElem * dcanlogin = NULL ;
111+ DefElem * disreplication = NULL ;
110112 DefElem * dconnlimit = NULL ;
111113 DefElem * daddroleto = NULL ;
112114 DefElem * drolemembers = NULL ;
@@ -190,6 +192,14 @@ CreateRole(CreateRoleStmt *stmt)
190192 errmsg ("conflicting or redundant options" )));
191193 dcanlogin = defel ;
192194 }
195+ else if (strcmp (defel -> defname , "isreplication" ) == 0 )
196+ {
197+ if (disreplication )
198+ ereport (ERROR ,
199+ (errcode (ERRCODE_SYNTAX_ERROR ),
200+ errmsg ("conflicting or redundant options" )));
201+ disreplication = defel ;
202+ }
193203 else if (strcmp (defel -> defname , "connectionlimit" ) == 0 )
194204 {
195205 if (dconnlimit )
@@ -247,6 +257,8 @@ CreateRole(CreateRoleStmt *stmt)
247257 createdb = intVal (dcreatedb -> arg ) != 0 ;
248258 if (dcanlogin )
249259 canlogin = intVal (dcanlogin -> arg ) != 0 ;
260+ if (disreplication )
261+ isreplication = intVal (disreplication -> arg ) != 0 ;
250262 if (dconnlimit )
251263 {
252264 connlimit = intVal (dconnlimit -> arg );
@@ -272,6 +284,13 @@ CreateRole(CreateRoleStmt *stmt)
272284 (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
273285 errmsg ("must be superuser to create superusers" )));
274286 }
287+ else if (isreplication )
288+ {
289+ if (!superuser ())
290+ ereport (ERROR ,
291+ (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
292+ errmsg ("must be superuser to create replication users" )));
293+ }
275294 else
276295 {
277296 if (!have_createrole_privilege ())
@@ -341,6 +360,7 @@ CreateRole(CreateRoleStmt *stmt)
341360 /* superuser gets catupdate right by default */
342361 new_record [Anum_pg_authid_rolcatupdate - 1 ] = BoolGetDatum (issuper );
343362 new_record [Anum_pg_authid_rolcanlogin - 1 ] = BoolGetDatum (canlogin );
363+ new_record [Anum_pg_authid_rolreplication - 1 ] = BoolGetDatum (isreplication );
344364 new_record [Anum_pg_authid_rolconnlimit - 1 ] = Int32GetDatum (connlimit );
345365
346366 if (password )
@@ -439,6 +459,7 @@ AlterRole(AlterRoleStmt *stmt)
439459 int createrole = -1 ; /* Can this user create roles? */
440460 int createdb = -1 ; /* Can the user create databases? */
441461 int canlogin = -1 ; /* Can this user login? */
462+ int isreplication = -1 ; /* Is this a replication role? */
442463 int connlimit = -1 ; /* maximum connections allowed */
443464 List * rolemembers = NIL ; /* roles to be added/removed */
444465 char * validUntil = NULL ; /* time the login is valid until */
@@ -450,6 +471,7 @@ AlterRole(AlterRoleStmt *stmt)
450471 DefElem * dcreaterole = NULL ;
451472 DefElem * dcreatedb = NULL ;
452473 DefElem * dcanlogin = NULL ;
474+ DefElem * disreplication = NULL ;
453475 DefElem * dconnlimit = NULL ;
454476 DefElem * drolemembers = NULL ;
455477 DefElem * dvalidUntil = NULL ;
@@ -514,6 +536,14 @@ AlterRole(AlterRoleStmt *stmt)
514536 errmsg ("conflicting or redundant options" )));
515537 dcanlogin = defel ;
516538 }
539+ else if (strcmp (defel -> defname , "isreplication" ) == 0 )
540+ {
541+ if (disreplication )
542+ ereport (ERROR ,
543+ (errcode (ERRCODE_SYNTAX_ERROR ),
544+ errmsg ("conflicting or redundant options" )));
545+ disreplication = defel ;
546+ }
517547 else if (strcmp (defel -> defname , "connectionlimit" ) == 0 )
518548 {
519549 if (dconnlimit )
@@ -556,6 +586,8 @@ AlterRole(AlterRoleStmt *stmt)
556586 createdb = intVal (dcreatedb -> arg );
557587 if (dcanlogin )
558588 canlogin = intVal (dcanlogin -> arg );
589+ if (disreplication )
590+ isreplication = intVal (disreplication -> arg );
559591 if (dconnlimit )
560592 {
561593 connlimit = intVal (dconnlimit -> arg );
@@ -594,12 +626,20 @@ AlterRole(AlterRoleStmt *stmt)
594626 (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
595627 errmsg ("must be superuser to alter superusers" )));
596628 }
629+ else if (((Form_pg_authid ) GETSTRUCT (tuple ))-> rolreplication || isreplication >= 0 )
630+ {
631+ if (!superuser ())
632+ ereport (ERROR ,
633+ (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
634+ errmsg ("must be superuser to alter replication users" )));
635+ }
597636 else if (!have_createrole_privilege ())
598637 {
599638 if (!(inherit < 0 &&
600639 createrole < 0 &&
601640 createdb < 0 &&
602641 canlogin < 0 &&
642+ isreplication < 0 &&
603643 !dconnlimit &&
604644 !rolemembers &&
605645 !validUntil &&
@@ -685,6 +725,12 @@ AlterRole(AlterRoleStmt *stmt)
685725 new_record_repl [Anum_pg_authid_rolcanlogin - 1 ] = true;
686726 }
687727
728+ if (isreplication >= 0 )
729+ {
730+ new_record [Anum_pg_authid_rolreplication - 1 ] = BoolGetDatum (isreplication > 0 );
731+ new_record_repl [Anum_pg_authid_rolreplication - 1 ] = true;
732+ }
733+
688734 if (dconnlimit )
689735 {
690736 new_record [Anum_pg_authid_rolconnlimit - 1 ] = Int32GetDatum (connlimit );
0 commit comments