@@ -94,6 +94,7 @@ CreateRole(CreateRoleStmt *stmt)
9494bool createrole = false;/* Can this user create roles? */
9595bool createdb = false;/* Can the user create databases? */
9696bool canlogin = false;/* Can this user login? */
97+ bool isreplication = false;/* Is this a replication role? */
9798int connlimit = -1 ;/* maximum connections allowed */
9899List * addroleto = NIL ;/* roles to make this a member of */
99100List * rolemembers = NIL ;/* roles to be members of this role */
@@ -107,6 +108,7 @@ CreateRole(CreateRoleStmt *stmt)
107108DefElem * dcreaterole = NULL ;
108109DefElem * dcreatedb = NULL ;
109110DefElem * dcanlogin = NULL ;
111+ DefElem * disreplication = NULL ;
110112DefElem * dconnlimit = NULL ;
111113DefElem * daddroleto = NULL ;
112114DefElem * drolemembers = NULL ;
@@ -190,6 +192,14 @@ CreateRole(CreateRoleStmt *stmt)
190192errmsg ("conflicting or redundant options" )));
191193dcanlogin = 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+ }
193203else if (strcmp (defel -> defname ,"connectionlimit" )== 0 )
194204{
195205if (dconnlimit )
@@ -247,6 +257,8 @@ CreateRole(CreateRoleStmt *stmt)
247257createdb = intVal (dcreatedb -> arg )!= 0 ;
248258if (dcanlogin )
249259canlogin = intVal (dcanlogin -> arg )!= 0 ;
260+ if (disreplication )
261+ isreplication = intVal (disreplication -> arg )!= 0 ;
250262if (dconnlimit )
251263{
252264connlimit = intVal (dconnlimit -> arg );
@@ -272,6 +284,13 @@ CreateRole(CreateRoleStmt *stmt)
272284(errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
273285errmsg ("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+ }
275294else
276295{
277296if (!have_createrole_privilege ())
@@ -341,6 +360,7 @@ CreateRole(CreateRoleStmt *stmt)
341360/* superuser gets catupdate right by default */
342361new_record [Anum_pg_authid_rolcatupdate - 1 ]= BoolGetDatum (issuper );
343362new_record [Anum_pg_authid_rolcanlogin - 1 ]= BoolGetDatum (canlogin );
363+ new_record [Anum_pg_authid_rolreplication - 1 ]= BoolGetDatum (isreplication );
344364new_record [Anum_pg_authid_rolconnlimit - 1 ]= Int32GetDatum (connlimit );
345365
346366if (password )
@@ -439,6 +459,7 @@ AlterRole(AlterRoleStmt *stmt)
439459int createrole = -1 ;/* Can this user create roles? */
440460int createdb = -1 ;/* Can the user create databases? */
441461int canlogin = -1 ;/* Can this user login? */
462+ int isreplication = -1 ;/* Is this a replication role? */
442463int connlimit = -1 ;/* maximum connections allowed */
443464List * rolemembers = NIL ;/* roles to be added/removed */
444465char * validUntil = NULL ;/* time the login is valid until */
@@ -450,6 +471,7 @@ AlterRole(AlterRoleStmt *stmt)
450471DefElem * dcreaterole = NULL ;
451472DefElem * dcreatedb = NULL ;
452473DefElem * dcanlogin = NULL ;
474+ DefElem * disreplication = NULL ;
453475DefElem * dconnlimit = NULL ;
454476DefElem * drolemembers = NULL ;
455477DefElem * dvalidUntil = NULL ;
@@ -514,6 +536,14 @@ AlterRole(AlterRoleStmt *stmt)
514536errmsg ("conflicting or redundant options" )));
515537dcanlogin = 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+ }
517547else if (strcmp (defel -> defname ,"connectionlimit" )== 0 )
518548{
519549if (dconnlimit )
@@ -556,6 +586,8 @@ AlterRole(AlterRoleStmt *stmt)
556586createdb = intVal (dcreatedb -> arg );
557587if (dcanlogin )
558588canlogin = intVal (dcanlogin -> arg );
589+ if (disreplication )
590+ isreplication = intVal (disreplication -> arg );
559591if (dconnlimit )
560592{
561593connlimit = intVal (dconnlimit -> arg );
@@ -594,12 +626,20 @@ AlterRole(AlterRoleStmt *stmt)
594626(errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
595627errmsg ("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+ }
597636else if (!have_createrole_privilege ())
598637{
599638if (!(inherit < 0 &&
600639createrole < 0 &&
601640createdb < 0 &&
602641canlogin < 0 &&
642+ isreplication < 0 &&
603643 !dconnlimit &&
604644 !rolemembers &&
605645 !validUntil &&
@@ -685,6 +725,12 @@ AlterRole(AlterRoleStmt *stmt)
685725new_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+
688734if (dconnlimit )
689735{
690736new_record [Anum_pg_authid_rolconnlimit - 1 ]= Int32GetDatum (connlimit );