]> granicus.if.org Git - postgresql/blob - src/bin/scripts/createuser.c
Empty search_path in Autovacuum and non-psql/pgbench clients.
[postgresql] / src / bin / scripts / createuser.c
1 /*-------------------------------------------------------------------------
2  *
3  * createuser
4  *
5  * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
6  * Portions Copyright (c) 1994, Regents of the University of California
7  *
8  * src/bin/scripts/createuser.c
9  *
10  *-------------------------------------------------------------------------
11  */
12
13 #include "postgres_fe.h"
14 #include "common.h"
15 #include "fe_utils/simple_list.h"
16 #include "fe_utils/string_utils.h"
17
18
19 static void help(const char *progname);
20
21 int
22 main(int argc, char *argv[])
23 {
24         static struct option long_options[] = {
25                 {"host", required_argument, NULL, 'h'},
26                 {"port", required_argument, NULL, 'p'},
27                 {"username", required_argument, NULL, 'U'},
28                 {"role", required_argument, NULL, 'g'},
29                 {"no-password", no_argument, NULL, 'w'},
30                 {"password", no_argument, NULL, 'W'},
31                 {"echo", no_argument, NULL, 'e'},
32                 {"createdb", no_argument, NULL, 'd'},
33                 {"no-createdb", no_argument, NULL, 'D'},
34                 {"superuser", no_argument, NULL, 's'},
35                 {"no-superuser", no_argument, NULL, 'S'},
36                 {"createrole", no_argument, NULL, 'r'},
37                 {"no-createrole", no_argument, NULL, 'R'},
38                 {"inherit", no_argument, NULL, 'i'},
39                 {"no-inherit", no_argument, NULL, 'I'},
40                 {"login", no_argument, NULL, 'l'},
41                 {"no-login", no_argument, NULL, 'L'},
42                 {"replication", no_argument, NULL, 1},
43                 {"no-replication", no_argument, NULL, 2},
44                 {"interactive", no_argument, NULL, 3},
45                 /* adduser is obsolete, undocumented spelling of superuser */
46                 {"adduser", no_argument, NULL, 'a'},
47                 {"no-adduser", no_argument, NULL, 'A'},
48                 {"connection-limit", required_argument, NULL, 'c'},
49                 {"pwprompt", no_argument, NULL, 'P'},
50                 {"encrypted", no_argument, NULL, 'E'},
51                 {NULL, 0, NULL, 0}
52         };
53
54         const char *progname;
55         int                     optindex;
56         int                     c;
57         const char *newuser = NULL;
58         char       *host = NULL;
59         char       *port = NULL;
60         char       *username = NULL;
61         SimpleStringList roles = {NULL, NULL};
62         enum trivalue prompt_password = TRI_DEFAULT;
63         bool            echo = false;
64         bool            interactive = false;
65         char       *conn_limit = NULL;
66         bool            pwprompt = false;
67         char       *newpassword = NULL;
68         char            newuser_buf[128];
69         char            newpassword_buf[100];
70
71         /* Tri-valued variables.  */
72         enum trivalue createdb = TRI_DEFAULT,
73                                 superuser = TRI_DEFAULT,
74                                 createrole = TRI_DEFAULT,
75                                 inherit = TRI_DEFAULT,
76                                 login = TRI_DEFAULT,
77                                 replication = TRI_DEFAULT;
78
79         PQExpBufferData sql;
80
81         PGconn     *conn;
82         PGresult   *result;
83
84         progname = get_progname(argv[0]);
85         set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
86
87         handle_help_version_opts(argc, argv, "createuser", help);
88
89         while ((c = getopt_long(argc, argv, "h:p:U:g:wWedDsSaArRiIlLc:PE",
90                                                         long_options, &optindex)) != -1)
91         {
92                 switch (c)
93                 {
94                         case 'h':
95                                 host = pg_strdup(optarg);
96                                 break;
97                         case 'p':
98                                 port = pg_strdup(optarg);
99                                 break;
100                         case 'U':
101                                 username = pg_strdup(optarg);
102                                 break;
103                         case 'g':
104                                 simple_string_list_append(&roles, optarg);
105                                 break;
106                         case 'w':
107                                 prompt_password = TRI_NO;
108                                 break;
109                         case 'W':
110                                 prompt_password = TRI_YES;
111                                 break;
112                         case 'e':
113                                 echo = true;
114                                 break;
115                         case 'd':
116                                 createdb = TRI_YES;
117                                 break;
118                         case 'D':
119                                 createdb = TRI_NO;
120                                 break;
121                         case 's':
122                         case 'a':
123                                 superuser = TRI_YES;
124                                 break;
125                         case 'S':
126                         case 'A':
127                                 superuser = TRI_NO;
128                                 break;
129                         case 'r':
130                                 createrole = TRI_YES;
131                                 break;
132                         case 'R':
133                                 createrole = TRI_NO;
134                                 break;
135                         case 'i':
136                                 inherit = TRI_YES;
137                                 break;
138                         case 'I':
139                                 inherit = TRI_NO;
140                                 break;
141                         case 'l':
142                                 login = TRI_YES;
143                                 break;
144                         case 'L':
145                                 login = TRI_NO;
146                                 break;
147                         case 'c':
148                                 conn_limit = pg_strdup(optarg);
149                                 break;
150                         case 'P':
151                                 pwprompt = true;
152                                 break;
153                         case 'E':
154                                 /* no-op, accepted for backward compatibility */
155                                 break;
156                         case 1:
157                                 replication = TRI_YES;
158                                 break;
159                         case 2:
160                                 replication = TRI_NO;
161                                 break;
162                         case 3:
163                                 interactive = true;
164                                 break;
165                         default:
166                                 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
167                                 exit(1);
168                 }
169         }
170
171         switch (argc - optind)
172         {
173                 case 0:
174                         break;
175                 case 1:
176                         newuser = argv[optind];
177                         break;
178                 default:
179                         fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
180                                         progname, argv[optind + 1]);
181                         fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
182                         exit(1);
183         }
184
185         if (newuser == NULL)
186         {
187                 if (interactive)
188                 {
189                         simple_prompt("Enter name of role to add: ",
190                                                   newuser_buf, sizeof(newuser_buf), true);
191                         newuser = newuser_buf;
192                 }
193                 else
194                 {
195                         if (getenv("PGUSER"))
196                                 newuser = getenv("PGUSER");
197                         else
198                                 newuser = get_user_name_or_exit(progname);
199                 }
200         }
201
202         if (pwprompt)
203         {
204                 char            pw2[100];
205
206                 simple_prompt("Enter password for new role: ",
207                                           newpassword_buf, sizeof(newpassword_buf), false);
208                 simple_prompt("Enter it again: ", pw2, sizeof(pw2), false);
209                 if (strcmp(newpassword_buf, pw2) != 0)
210                 {
211                         fprintf(stderr, _("Passwords didn't match.\n"));
212                         exit(1);
213                 }
214                 newpassword = newpassword_buf;
215         }
216
217         if (superuser == 0)
218         {
219                 if (interactive && yesno_prompt("Shall the new role be a superuser?"))
220                         superuser = TRI_YES;
221                 else
222                         superuser = TRI_NO;
223         }
224
225         if (superuser == TRI_YES)
226         {
227                 /* Not much point in trying to restrict a superuser */
228                 createdb = TRI_YES;
229                 createrole = TRI_YES;
230         }
231
232         if (createdb == 0)
233         {
234                 if (interactive && yesno_prompt("Shall the new role be allowed to create databases?"))
235                         createdb = TRI_YES;
236                 else
237                         createdb = TRI_NO;
238         }
239
240         if (createrole == 0)
241         {
242                 if (interactive && yesno_prompt("Shall the new role be allowed to create more new roles?"))
243                         createrole = TRI_YES;
244                 else
245                         createrole = TRI_NO;
246         }
247
248         if (inherit == 0)
249                 inherit = TRI_YES;
250
251         if (login == 0)
252                 login = TRI_YES;
253
254         conn = connectDatabase("postgres", host, port, username, prompt_password,
255                                                    progname, echo, false, false);
256
257         initPQExpBuffer(&sql);
258
259         printfPQExpBuffer(&sql, "CREATE ROLE %s", fmtId(newuser));
260         if (newpassword)
261         {
262                 char       *encrypted_password;
263
264                 appendPQExpBufferStr(&sql, " PASSWORD ");
265
266                 encrypted_password = PQencryptPasswordConn(conn,
267                                                                                                    newpassword,
268                                                                                                    newuser,
269                                                                                                    NULL);
270                 if (!encrypted_password)
271                 {
272                         fprintf(stderr, _("%s: password encryption failed: %s"),
273                                         progname, PQerrorMessage(conn));
274                         exit(1);
275                 }
276                 appendStringLiteralConn(&sql, encrypted_password, conn);
277                 PQfreemem(encrypted_password);
278         }
279         if (superuser == TRI_YES)
280                 appendPQExpBufferStr(&sql, " SUPERUSER");
281         if (superuser == TRI_NO)
282                 appendPQExpBufferStr(&sql, " NOSUPERUSER");
283         if (createdb == TRI_YES)
284                 appendPQExpBufferStr(&sql, " CREATEDB");
285         if (createdb == TRI_NO)
286                 appendPQExpBufferStr(&sql, " NOCREATEDB");
287         if (createrole == TRI_YES)
288                 appendPQExpBufferStr(&sql, " CREATEROLE");
289         if (createrole == TRI_NO)
290                 appendPQExpBufferStr(&sql, " NOCREATEROLE");
291         if (inherit == TRI_YES)
292                 appendPQExpBufferStr(&sql, " INHERIT");
293         if (inherit == TRI_NO)
294                 appendPQExpBufferStr(&sql, " NOINHERIT");
295         if (login == TRI_YES)
296                 appendPQExpBufferStr(&sql, " LOGIN");
297         if (login == TRI_NO)
298                 appendPQExpBufferStr(&sql, " NOLOGIN");
299         if (replication == TRI_YES)
300                 appendPQExpBufferStr(&sql, " REPLICATION");
301         if (replication == TRI_NO)
302                 appendPQExpBufferStr(&sql, " NOREPLICATION");
303         if (conn_limit != NULL)
304                 appendPQExpBuffer(&sql, " CONNECTION LIMIT %s", conn_limit);
305         if (roles.head != NULL)
306         {
307                 SimpleStringListCell *cell;
308
309                 appendPQExpBufferStr(&sql, " IN ROLE ");
310
311                 for (cell = roles.head; cell; cell = cell->next)
312                 {
313                         if (cell->next)
314                                 appendPQExpBuffer(&sql, "%s,", fmtId(cell->val));
315                         else
316                                 appendPQExpBufferStr(&sql, fmtId(cell->val));
317                 }
318         }
319         appendPQExpBufferChar(&sql, ';');
320
321         if (echo)
322                 printf("%s\n", sql.data);
323         result = PQexec(conn, sql.data);
324
325         if (PQresultStatus(result) != PGRES_COMMAND_OK)
326         {
327                 fprintf(stderr, _("%s: creation of new role failed: %s"),
328                                 progname, PQerrorMessage(conn));
329                 PQfinish(conn);
330                 exit(1);
331         }
332
333         PQclear(result);
334         PQfinish(conn);
335         exit(0);
336 }
337
338
339 static void
340 help(const char *progname)
341 {
342         printf(_("%s creates a new PostgreSQL role.\n\n"), progname);
343         printf(_("Usage:\n"));
344         printf(_("  %s [OPTION]... [ROLENAME]\n"), progname);
345         printf(_("\nOptions:\n"));
346         printf(_("  -c, --connection-limit=N  connection limit for role (default: no limit)\n"));
347         printf(_("  -d, --createdb            role can create new databases\n"));
348         printf(_("  -D, --no-createdb         role cannot create databases (default)\n"));
349         printf(_("  -e, --echo                show the commands being sent to the server\n"));
350         printf(_("  -g, --role=ROLE           new role will be a member of this role\n"));
351         printf(_("  -i, --inherit             role inherits privileges of roles it is a\n"
352                          "                            member of (default)\n"));
353         printf(_("  -I, --no-inherit          role does not inherit privileges\n"));
354         printf(_("  -l, --login               role can login (default)\n"));
355         printf(_("  -L, --no-login            role cannot login\n"));
356         printf(_("  -P, --pwprompt            assign a password to new role\n"));
357         printf(_("  -r, --createrole          role can create new roles\n"));
358         printf(_("  -R, --no-createrole       role cannot create roles (default)\n"));
359         printf(_("  -s, --superuser           role will be superuser\n"));
360         printf(_("  -S, --no-superuser        role will not be superuser (default)\n"));
361         printf(_("  -V, --version             output version information, then exit\n"));
362         printf(_("  --interactive             prompt for missing role name and attributes rather\n"
363                          "                            than using defaults\n"));
364         printf(_("  --replication             role can initiate replication\n"));
365         printf(_("  --no-replication          role cannot initiate replication\n"));
366         printf(_("  -?, --help                show this help, then exit\n"));
367         printf(_("\nConnection options:\n"));
368         printf(_("  -h, --host=HOSTNAME       database server host or socket directory\n"));
369         printf(_("  -p, --port=PORT           database server port\n"));
370         printf(_("  -U, --username=USERNAME   user name to connect as (not the one to create)\n"));
371         printf(_("  -w, --no-password         never prompt for password\n"));
372         printf(_("  -W, --password            force password prompt\n"));
373         printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
374 }