On Tue, Nov 19, 2013 at 11:54 PM, Amit Kapila <amit.kapil...@gmail.com> wrote:
> On further tests, I found inconsistency in behavior when some special
> characters are used in role names.
>
> 1. Test for role name containing quotes
> a. In psql, create a role containing quotes in role name.
>        create role amitk in role "test_ro'le_3";
>
> b. Now if we try to make a new role member of this role using
> createuser utility, it gives error
>     try-1
>     createuser.exe -g test_ro'le_3 -p 5446 amitk_2
> createuser: creation of new role failed: ERROR:  unterminated quoted
> string at or near "'le_3;"
> LINE 1: ... NOCREATEDB NOCREATEROLE INHERIT LOGIN IN ROLE test_ro'le_3;
>     try-2
>     createuser.exe -g "test_ro'le_3" -p 5446 amitk
> createuser: creation of new role failed: ERROR:  unterminated quoted
> string at or near "'le_3;"
> LINE 1: ... NOCREATEDB NOCREATEROLE INHERIT LOGIN IN ROLE test_ro'le_3;
>
> c. If I try quoted string in new role to be created, it works fine.
>     createuser.exe -p 5446 am'itk_2
>
> As quoted strings work well for role names, I think it should work
> with -g option as well.
>
> 2. Test for role name containing special character ';' (semicolon)
> a. create role "test;_1";
>
> b. Now if we try to make a new role member of this role using
> createuser utility, it gives error
>     try-1
> createuser.exe -g test;_1 -p 5446 amitk_4
> createuser: creation of new role failed: ERROR:  syntax error at or near "_1"
> LINE 1: ...RUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN IN ROLE test;_1;
>     try-2                                                                ^
> createuser.exe -g "test;_1" -p 5446 amitk_4
> createuser: creation of new role failed: ERROR:  syntax error at or near "_1"
> LINE 1: ...RUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN IN ROLE test;_1;
>                                                                     ^
>     try-3
> createuser.exe -g 'test;_1' -p 5446 amitk_4
> createuser: creation of new role failed: ERROR:  syntax error at or
> near "'test;_1'"
> LINE 1: ...SER NOCREATEDB NOCREATEROLE INHERIT LOGIN IN ROLE 'test;_1';
>
> c. If I try semicolon in new role to be created, it works fine.
> createuser.exe -p 5446 amit;k_3
>
> As semicolon work well for role names, I think it should work with -g
> option as well.

I was not unconscious of there being the potential for issue here; there is an
easy answer of double quoting the string, thus:

diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c
index 88b8f2a..04ec324 100644
--- a/src/bin/scripts/createuser.c
+++ b/src/bin/scripts/createuser.c
@@ -308,7 +308,7 @@ main(int argc, char *argv[])
        if (conn_limit != NULL)
                appendPQExpBuffer(&sql, " CONNECTION LIMIT %s", conn_limit);
        if (roles != NULL)
-               appendPQExpBuffer(&sql, " IN ROLE %s", roles);
+               appendPQExpBuffer(&sql, " IN ROLE \"%s\"", roles);
        appendPQExpBufferStr(&sql, ";\n");

        if (echo)
(END)

I was conscious of not quoting it.  Note that other parameters are not quoted
either, so I imagined I was being consistent with that.

I have added the above change, as well as rebasing, per Peter's recommendation.
-- 
When confronted by a difficult problem, solve it by reducing it to the
question, "How would the Lone Ranger handle this?"
diff --git a/doc/src/sgml/ref/createuser.sgml b/doc/src/sgml/ref/createuser.sgml
index 2f1ea2f..5a38d2e 100644
--- a/doc/src/sgml/ref/createuser.sgml
+++ b/doc/src/sgml/ref/createuser.sgml
@@ -131,6 +131,16 @@ PostgreSQL documentation
      </varlistentry>
 
      <varlistentry>
+      <term><option>-g <replaceable 
class="parameter">roles</replaceable></></term>
+      <term><option>--roles=<replaceable 
class="parameter">roles</replaceable></></term>
+      <listitem>
+       <para>
+        Indicates roles to which this role will be added immediately as a new 
member.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
       <term><option>-i</></term>
       <term><option>--inherit</></term>
       <listitem>
diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c
index 83623ea..04ec324 100644
--- a/src/bin/scripts/createuser.c
+++ b/src/bin/scripts/createuser.c
@@ -24,6 +24,7 @@ main(int argc, char *argv[])
                {"host", required_argument, NULL, 'h'},
                {"port", required_argument, NULL, 'p'},
                {"username", required_argument, NULL, 'U'},
+               {"roles", required_argument, NULL, 'g'},
                {"no-password", no_argument, NULL, 'w'},
                {"password", no_argument, NULL, 'W'},
                {"echo", no_argument, NULL, 'e'},
@@ -57,6 +58,7 @@ main(int argc, char *argv[])
        char       *host = NULL;
        char       *port = NULL;
        char       *username = NULL;
+       char       *roles = NULL;
        enum trivalue prompt_password = TRI_DEFAULT;
        bool            echo = false;
        bool            interactive = false;
@@ -83,7 +85,7 @@ main(int argc, char *argv[])
 
        handle_help_version_opts(argc, argv, "createuser", help);
 
-       while ((c = getopt_long(argc, argv, "h:p:U:wWedDsSaArRiIlLc:PEN",
+       while ((c = getopt_long(argc, argv, "h:p:U:g:wWedDsSaArRiIlLc:PEN",
                                                        long_options, 
&optindex)) != -1)
        {
                switch (c)
@@ -97,6 +99,9 @@ main(int argc, char *argv[])
                        case 'U':
                                username = pg_strdup(optarg);
                                break;
+                       case 'g':
+                               roles = pg_strdup(optarg);
+                               break;
                        case 'w':
                                prompt_password = TRI_NO;
                                break;
@@ -302,6 +307,8 @@ main(int argc, char *argv[])
                appendPQExpBufferStr(&sql, " NOREPLICATION");
        if (conn_limit != NULL)
                appendPQExpBuffer(&sql, " CONNECTION LIMIT %s", conn_limit);
+       if (roles != NULL)
+               appendPQExpBuffer(&sql, " IN ROLE \"%s\"", roles);
        appendPQExpBufferStr(&sql, ";\n");
 
        if (echo)
@@ -334,6 +341,7 @@ help(const char *progname)
        printf(_("  -D, --no-createdb         role cannot create databases 
(default)\n"));
        printf(_("  -e, --echo                show the commands being sent to 
the server\n"));
        printf(_("  -E, --encrypted           encrypt stored password\n"));
+       printf(_("  -g, --roles               roles to associate with this new 
role\n"));
        printf(_("  -i, --inherit             role inherits privileges of roles 
it is a\n"
                         "                            member of (default)\n"));
        printf(_("  -I, --no-inherit          role does not inherit 
privileges\n"));
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to