PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
createuser.c File Reference
#include "postgres_fe.h"
#include <limits.h>
#include "common.h"
#include "common/logging.h"
#include "common/string.h"
#include "fe_utils/option_utils.h"
#include "fe_utils/simple_list.h"
#include "fe_utils/string_utils.h"
Include dependency graph for createuser.c:

Go to the source code of this file.

Functions

static void help (const char *progname)
 
int main (int argc, char *argv[])
 

Function Documentation

◆ help()

static void help ( const char *  progname)
static

Definition at line 412 of file createuser.c.

413{
414 printf(_("%s creates a new PostgreSQL role.\n\n"), progname);
415 printf(_("Usage:\n"));
416 printf(_(" %s [OPTION]... [ROLENAME]\n"), progname);
417 printf(_("\nOptions:\n"));
418 printf(_(" -a, --with-admin=ROLE ROLE will be a member of new role with admin\n"
419 " option\n"));
420 printf(_(" -c, --connection-limit=N connection limit for role (default: no limit)\n"));
421 printf(_(" -d, --createdb role can create new databases\n"));
422 printf(_(" -D, --no-createdb role cannot create databases (default)\n"));
423 printf(_(" -e, --echo show the commands being sent to the server\n"));
424 printf(_(" -g, --member-of=ROLE new role will be a member of ROLE\n"));
425 printf(_(" --role=ROLE (same as --member-of, deprecated)\n"));
426 printf(_(" -i, --inherit role inherits privileges of roles it is a\n"
427 " member of (default)\n"));
428 printf(_(" -I, --no-inherit role does not inherit privileges\n"));
429 printf(_(" -l, --login role can login (default)\n"));
430 printf(_(" -L, --no-login role cannot login\n"));
431 printf(_(" -m, --with-member=ROLE ROLE will be a member of new role\n"));
432 printf(_(" -P, --pwprompt assign a password to new role\n"));
433 printf(_(" -r, --createrole role can create new roles\n"));
434 printf(_(" -R, --no-createrole role cannot create roles (default)\n"));
435 printf(_(" -s, --superuser role will be superuser\n"));
436 printf(_(" -S, --no-superuser role will not be superuser (default)\n"));
437 printf(_(" -v, --valid-until=TIMESTAMP\n"
438 " password expiration date and time for role\n"));
439 printf(_(" -V, --version output version information, then exit\n"));
440 printf(_(" --interactive prompt for missing role name and attributes rather\n"
441 " than using defaults\n"));
442 printf(_(" --bypassrls role can bypass row-level security (RLS) policy\n"));
443 printf(_(" --no-bypassrls role cannot bypass row-level security (RLS) policy\n"
444 " (default)\n"));
445 printf(_(" --replication role can initiate replication\n"));
446 printf(_(" --no-replication role cannot initiate replication (default)\n"));
447 printf(_(" -?, --help show this help, then exit\n"));
448 printf(_("\nConnection options:\n"));
449 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
450 printf(_(" -p, --port=PORT database server port\n"));
451 printf(_(" -U, --username=USERNAME user name to connect as (not the one to create)\n"));
452 printf(_(" -w, --no-password never prompt for password\n"));
453 printf(_(" -W, --password force password prompt\n"));
454 printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
455 printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
456}
#define _(x)
Definition: elog.c:90
const char * progname
Definition: main.c:44
#define printf(...)
Definition: port.h:244

References _, printf, and progname.

Referenced by main().

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 28 of file createuser.c.

29{
30 static struct option long_options[] = {
31 {"with-admin", required_argument, NULL, 'a'},
32 {"connection-limit", required_argument, NULL, 'c'},
33 {"createdb", no_argument, NULL, 'd'},
34 {"no-createdb", no_argument, NULL, 'D'},
35 {"echo", no_argument, NULL, 'e'},
36 {"encrypted", no_argument, NULL, 'E'},
37 {"role", required_argument, NULL, 'g'},
38 {"member-of", required_argument, NULL, 'g'},
39 {"host", required_argument, NULL, 'h'},
40 {"inherit", no_argument, NULL, 'i'},
41 {"no-inherit", no_argument, NULL, 'I'},
42 {"login", no_argument, NULL, 'l'},
43 {"no-login", no_argument, NULL, 'L'},
44 {"with-member", required_argument, NULL, 'm'},
45 {"port", required_argument, NULL, 'p'},
46 {"pwprompt", no_argument, NULL, 'P'},
47 {"createrole", no_argument, NULL, 'r'},
48 {"no-createrole", no_argument, NULL, 'R'},
49 {"superuser", no_argument, NULL, 's'},
50 {"no-superuser", no_argument, NULL, 'S'},
51 {"username", required_argument, NULL, 'U'},
52 {"valid-until", required_argument, NULL, 'v'},
53 {"no-password", no_argument, NULL, 'w'},
54 {"password", no_argument, NULL, 'W'},
55 {"replication", no_argument, NULL, 1},
56 {"no-replication", no_argument, NULL, 2},
57 {"interactive", no_argument, NULL, 3},
58 {"bypassrls", no_argument, NULL, 4},
59 {"no-bypassrls", no_argument, NULL, 5},
60 {NULL, 0, NULL, 0}
61 };
62
63 const char *progname;
64 int optindex;
65 int c;
66 const char *newuser = NULL;
67 char *host = NULL;
68 char *port = NULL;
69 char *username = NULL;
70 SimpleStringList roles = {NULL, NULL};
71 SimpleStringList members = {NULL, NULL};
72 SimpleStringList admins = {NULL, NULL};
73 enum trivalue prompt_password = TRI_DEFAULT;
74 ConnParams cparams;
75 bool echo = false;
76 bool interactive = false;
77 int conn_limit = -2; /* less than minimum valid value */
78 bool pwprompt = false;
79 char *newpassword = NULL;
80 char *pwexpiry = NULL;
81
82 /* Tri-valued variables. */
85 createrole = TRI_DEFAULT,
86 inherit = TRI_DEFAULT,
87 login = TRI_DEFAULT,
88 replication = TRI_DEFAULT,
89 bypassrls = TRI_DEFAULT;
90
92
93 PGconn *conn;
94 PGresult *result;
95
96 pg_logging_init(argv[0]);
97 progname = get_progname(argv[0]);
98 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
99
100 handle_help_version_opts(argc, argv, "createuser", help);
101
102 while ((c = getopt_long(argc, argv, "a:c:dDeEg:h:iIlLm:p:PrRsSU:v:wW",
103 long_options, &optindex)) != -1)
104 {
105 switch (c)
106 {
107 case 'a':
109 break;
110 case 'c':
111 if (!option_parse_int(optarg, "-c/--connection-limit",
112 -1, INT_MAX, &conn_limit))
113 exit(1);
114 break;
115 case 'd':
117 break;
118 case 'D':
120 break;
121 case 'e':
122 echo = true;
123 break;
124 case 'E':
125 /* no-op, accepted for backward compatibility */
126 break;
127 case 'g':
129 break;
130 case 'h':
131 host = pg_strdup(optarg);
132 break;
133 case 'i':
134 inherit = TRI_YES;
135 break;
136 case 'I':
137 inherit = TRI_NO;
138 break;
139 case 'l':
140 login = TRI_YES;
141 break;
142 case 'L':
143 login = TRI_NO;
144 break;
145 case 'm':
147 break;
148 case 'p':
150 break;
151 case 'P':
152 pwprompt = true;
153 break;
154 case 'r':
155 createrole = TRI_YES;
156 break;
157 case 'R':
158 createrole = TRI_NO;
159 break;
160 case 's':
162 break;
163 case 'S':
165 break;
166 case 'U':
168 break;
169 case 'v':
170 pwexpiry = pg_strdup(optarg);
171 break;
172 case 'w':
173 prompt_password = TRI_NO;
174 break;
175 case 'W':
176 prompt_password = TRI_YES;
177 break;
178 case 1:
179 replication = TRI_YES;
180 break;
181 case 2:
182 replication = TRI_NO;
183 break;
184 case 3:
185 interactive = true;
186 break;
187 case 4:
188 bypassrls = TRI_YES;
189 break;
190 case 5:
191 bypassrls = TRI_NO;
192 break;
193 default:
194 /* getopt_long already emitted a complaint */
195 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
196 exit(1);
197 }
198 }
199
200 switch (argc - optind)
201 {
202 case 0:
203 break;
204 case 1:
205 newuser = argv[optind];
206 break;
207 default:
208 pg_log_error("too many command-line arguments (first is \"%s\")",
209 argv[optind + 1]);
210 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
211 exit(1);
212 }
213
214 if (newuser == NULL)
215 {
216 if (interactive)
217 {
218 newuser = simple_prompt("Enter name of role to add: ", true);
219 }
220 else
221 {
222 if (getenv("PGUSER"))
223 newuser = getenv("PGUSER");
224 else
226 }
227 }
228
229 if (pwprompt)
230 {
231 char *pw2;
232
233 newpassword = simple_prompt("Enter password for new role: ", false);
234 pw2 = simple_prompt("Enter it again: ", false);
235 if (strcmp(newpassword, pw2) != 0)
236 {
237 fprintf(stderr, _("Passwords didn't match.\n"));
238 exit(1);
239 }
240 free(pw2);
241 }
242
243 if (superuser == TRI_DEFAULT)
244 {
245 if (interactive && yesno_prompt("Shall the new role be a superuser?"))
247 else
249 }
250
251 if (superuser == TRI_YES)
252 {
253 /* Not much point in trying to restrict a superuser */
255 createrole = TRI_YES;
256 }
257
258 if (createdb == TRI_DEFAULT)
259 {
260 if (interactive && yesno_prompt("Shall the new role be allowed to create databases?"))
262 else
264 }
265
266 if (createrole == TRI_DEFAULT)
267 {
268 if (interactive && yesno_prompt("Shall the new role be allowed to create more new roles?"))
269 createrole = TRI_YES;
270 else
271 createrole = TRI_NO;
272 }
273
274 if (bypassrls == TRI_DEFAULT)
275 bypassrls = TRI_NO;
276
277 if (replication == TRI_DEFAULT)
278 replication = TRI_NO;
279
280 if (inherit == TRI_DEFAULT)
281 inherit = TRI_YES;
282
283 if (login == TRI_DEFAULT)
284 login = TRI_YES;
285
286 cparams.dbname = NULL; /* this program lacks any dbname option... */
287 cparams.pghost = host;
288 cparams.pgport = port;
289 cparams.pguser = username;
290 cparams.prompt_password = prompt_password;
291 cparams.override_dbname = NULL;
292
293 conn = connectMaintenanceDatabase(&cparams, progname, echo);
294
295 initPQExpBuffer(&sql);
296
297 printfPQExpBuffer(&sql, "CREATE ROLE %s", fmtId(newuser));
298 if (newpassword)
299 {
300 char *encrypted_password;
301
302 appendPQExpBufferStr(&sql, " PASSWORD ");
303
304 encrypted_password = PQencryptPasswordConn(conn,
305 newpassword,
306 newuser,
307 NULL);
308 if (!encrypted_password)
309 pg_fatal("password encryption failed: %s",
311 appendStringLiteralConn(&sql, encrypted_password, conn);
312 PQfreemem(encrypted_password);
313 }
314 if (superuser == TRI_YES)
315 appendPQExpBufferStr(&sql, " SUPERUSER");
316 if (superuser == TRI_NO)
317 appendPQExpBufferStr(&sql, " NOSUPERUSER");
318 if (createdb == TRI_YES)
319 appendPQExpBufferStr(&sql, " CREATEDB");
320 if (createdb == TRI_NO)
321 appendPQExpBufferStr(&sql, " NOCREATEDB");
322 if (createrole == TRI_YES)
323 appendPQExpBufferStr(&sql, " CREATEROLE");
324 if (createrole == TRI_NO)
325 appendPQExpBufferStr(&sql, " NOCREATEROLE");
326 if (inherit == TRI_YES)
327 appendPQExpBufferStr(&sql, " INHERIT");
328 if (inherit == TRI_NO)
329 appendPQExpBufferStr(&sql, " NOINHERIT");
330 if (login == TRI_YES)
331 appendPQExpBufferStr(&sql, " LOGIN");
332 if (login == TRI_NO)
333 appendPQExpBufferStr(&sql, " NOLOGIN");
334 if (replication == TRI_YES)
335 appendPQExpBufferStr(&sql, " REPLICATION");
336 if (replication == TRI_NO)
337 appendPQExpBufferStr(&sql, " NOREPLICATION");
338 if (bypassrls == TRI_YES)
339 appendPQExpBufferStr(&sql, " BYPASSRLS");
340 if (bypassrls == TRI_NO)
341 appendPQExpBufferStr(&sql, " NOBYPASSRLS");
342 if (conn_limit >= -1)
343 appendPQExpBuffer(&sql, " CONNECTION LIMIT %d", conn_limit);
344 if (pwexpiry != NULL)
345 {
346 appendPQExpBufferStr(&sql, " VALID UNTIL ");
347 appendStringLiteralConn(&sql, pwexpiry, conn);
348 }
349 if (roles.head != NULL)
350 {
352
353 appendPQExpBufferStr(&sql, " IN ROLE ");
354
355 for (cell = roles.head; cell; cell = cell->next)
356 {
357 if (cell->next)
358 appendPQExpBuffer(&sql, "%s,", fmtId(cell->val));
359 else
360 appendPQExpBufferStr(&sql, fmtId(cell->val));
361 }
362 }
363 if (members.head != NULL)
364 {
366
367 appendPQExpBufferStr(&sql, " ROLE ");
368
369 for (cell = members.head; cell; cell = cell->next)
370 {
371 if (cell->next)
372 appendPQExpBuffer(&sql, "%s,", fmtId(cell->val));
373 else
374 appendPQExpBufferStr(&sql, fmtId(cell->val));
375 }
376 }
377 if (admins.head != NULL)
378 {
380
381 appendPQExpBufferStr(&sql, " ADMIN ");
382
383 for (cell = admins.head; cell; cell = cell->next)
384 {
385 if (cell->next)
386 appendPQExpBuffer(&sql, "%s,", fmtId(cell->val));
387 else
388 appendPQExpBufferStr(&sql, fmtId(cell->val));
389 }
390 }
391
392 appendPQExpBufferChar(&sql, ';');
393
394 if (echo)
395 printf("%s\n", sql.data);
396 result = PQexec(conn, sql.data);
397
398 if (PQresultStatus(result) != PGRES_COMMAND_OK)
399 {
400 pg_log_error("creation of new role failed: %s", PQerrorMessage(conn));
401 PQfinish(conn);
402 exit(1);
403 }
404
405 PQclear(result);
406 PQfinish(conn);
407 exit(0);
408}
bool yesno_prompt(const char *question)
Definition: common.c:135
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1171
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:429
PGconn * connectMaintenanceDatabase(ConnParams *cparams, const char *progname, bool echo)
static void help(const char *progname)
Definition: createuser.c:412
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
Oid createdb(ParseState *pstate, const CreatedbStmt *stmt)
Definition: dbcommands.c:683
char * PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, const char *algorithm)
Definition: fe-auth.c:1317
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4939
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:7268
void PQfreemem(void *ptr)
Definition: fe-exec.c:4032
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3411
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2262
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: getopt_long.c:60
#define no_argument
Definition: getopt_long.h:25
#define required_argument
Definition: getopt_long.h:26
#define free(a)
Definition: header.h:65
static char * username
Definition: initdb.c:153
static bool pwprompt
Definition: initdb.c:154
@ PGRES_COMMAND_OK
Definition: libpq-fe.h:120
exit(1)
void pg_logging_init(const char *argv0)
Definition: logging.c:83
#define pg_log_error(...)
Definition: logging.h:106
#define pg_log_error_hint(...)
Definition: logging.h:112
bool option_parse_int(const char *optarg, const char *optname, int min_range, int max_range, int *result)
Definition: option_utils.c:50
void handle_help_version_opts(int argc, char *argv[], const char *fixed_progname, help_handler hlp)
Definition: option_utils.c:24
#define pg_fatal(...)
PGDLLIMPORT int optind
Definition: getopt.c:51
PGDLLIMPORT char * optarg
Definition: getopt.c:53
static int port
Definition: pg_regress.c:115
const char * get_progname(const char *argv0)
Definition: path.c:575
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:235
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
char * c
void simple_string_list_append(SimpleStringList *list, const char *val)
Definition: simple_list.c:63
char * simple_prompt(const char *prompt, bool echo)
Definition: sprompt.c:38
PGconn * conn
Definition: streamutil.c:53
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
Definition: string_utils.c:293
char val[FLEXIBLE_ARRAY_MEMBER]
Definition: simple_list.h:37
struct SimpleStringListCell * next
Definition: simple_list.h:34
SimpleStringListCell * head
Definition: simple_list.h:42
const char * pguser
Definition: connect_utils.h:31
char * override_dbname
Definition: pg_backup.h:92
char * pgport
Definition: pg_backup.h:86
char * pghost
Definition: pg_backup.h:87
char * dbname
Definition: pg_backup.h:85
enum trivalue prompt_password
Definition: connect_utils.h:32
bool superuser(void)
Definition: superuser.c:46
const char * get_user_name_or_exit(const char *progname)
Definition: username.c:74
trivalue
Definition: vacuumlo.c:35
@ TRI_YES
Definition: vacuumlo.c:38
@ TRI_DEFAULT
Definition: vacuumlo.c:36
@ TRI_NO
Definition: vacuumlo.c:37

References _, appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendStringLiteralConn(), conn, connectMaintenanceDatabase(), createdb(), PQExpBufferData::data, _connParams::dbname, exit(), fmtId(), fprintf, free, get_progname(), get_user_name_or_exit(), getopt_long(), handle_help_version_opts(), SimpleStringList::head, help(), initPQExpBuffer(), SimpleStringListCell::next, no_argument, optarg, optind, option_parse_int(), _connParams::override_dbname, pg_fatal, pg_log_error, pg_log_error_hint, pg_logging_init(), pg_strdup(), PG_TEXTDOMAIN, _connParams::pghost, _connParams::pgport, PGRES_COMMAND_OK, _connParams::pguser, port, PQclear(), PQencryptPasswordConn(), PQerrorMessage(), PQexec(), PQfinish(), PQfreemem(), PQresultStatus(), printf, printfPQExpBuffer(), progname, _connParams::prompt_password, pwprompt, required_argument, set_pglocale_pgservice(), simple_prompt(), simple_string_list_append(), superuser(), TRI_DEFAULT, TRI_NO, TRI_YES, username, SimpleStringListCell::val, and yesno_prompt().