00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "postgres_fe.h"
00014 #include "common.h"
00015 #include "dumputils.h"
00016
00017
00018 static void help(const char *progname);
00019
00020 int
00021 main(int argc, char *argv[])
00022 {
00023 static struct option long_options[] = {
00024 {"host", required_argument, NULL, 'h'},
00025 {"port", required_argument, NULL, 'p'},
00026 {"username", required_argument, NULL, 'U'},
00027 {"no-password", no_argument, NULL, 'w'},
00028 {"password", no_argument, NULL, 'W'},
00029 {"echo", no_argument, NULL, 'e'},
00030 {"createdb", no_argument, NULL, 'd'},
00031 {"no-createdb", no_argument, NULL, 'D'},
00032 {"superuser", no_argument, NULL, 's'},
00033 {"no-superuser", no_argument, NULL, 'S'},
00034 {"createrole", no_argument, NULL, 'r'},
00035 {"no-createrole", no_argument, NULL, 'R'},
00036 {"inherit", no_argument, NULL, 'i'},
00037 {"no-inherit", no_argument, NULL, 'I'},
00038 {"login", no_argument, NULL, 'l'},
00039 {"no-login", no_argument, NULL, 'L'},
00040 {"replication", no_argument, NULL, 1},
00041 {"no-replication", no_argument, NULL, 2},
00042 {"interactive", no_argument, NULL, 3},
00043
00044 {"adduser", no_argument, NULL, 'a'},
00045 {"no-adduser", no_argument, NULL, 'A'},
00046 {"connection-limit", required_argument, NULL, 'c'},
00047 {"pwprompt", no_argument, NULL, 'P'},
00048 {"encrypted", no_argument, NULL, 'E'},
00049 {"unencrypted", no_argument, NULL, 'N'},
00050 {NULL, 0, NULL, 0}
00051 };
00052
00053 const char *progname;
00054 int optindex;
00055 int c;
00056 const char *newuser = NULL;
00057 char *host = NULL;
00058 char *port = NULL;
00059 char *username = NULL;
00060 enum trivalue prompt_password = TRI_DEFAULT;
00061 bool echo = false;
00062 bool interactive = false;
00063 char *conn_limit = NULL;
00064 bool pwprompt = false;
00065 char *newpassword = NULL;
00066
00067
00068 enum trivalue createdb = TRI_DEFAULT,
00069 superuser = TRI_DEFAULT,
00070 createrole = TRI_DEFAULT,
00071 inherit = TRI_DEFAULT,
00072 login = TRI_DEFAULT,
00073 replication = TRI_DEFAULT,
00074 encrypted = TRI_DEFAULT;
00075
00076 PQExpBufferData sql;
00077
00078 PGconn *conn;
00079 PGresult *result;
00080
00081 progname = get_progname(argv[0]);
00082 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
00083
00084 handle_help_version_opts(argc, argv, "createuser", help);
00085
00086 while ((c = getopt_long(argc, argv, "h:p:U:wWedDsSaArRiIlLc:PEN",
00087 long_options, &optindex)) != -1)
00088 {
00089 switch (c)
00090 {
00091 case 'h':
00092 host = pg_strdup(optarg);
00093 break;
00094 case 'p':
00095 port = pg_strdup(optarg);
00096 break;
00097 case 'U':
00098 username = pg_strdup(optarg);
00099 break;
00100 case 'w':
00101 prompt_password = TRI_NO;
00102 break;
00103 case 'W':
00104 prompt_password = TRI_YES;
00105 break;
00106 case 'e':
00107 echo = true;
00108 break;
00109 case 'd':
00110 createdb = TRI_YES;
00111 break;
00112 case 'D':
00113 createdb = TRI_NO;
00114 break;
00115 case 's':
00116 case 'a':
00117 superuser = TRI_YES;
00118 break;
00119 case 'S':
00120 case 'A':
00121 superuser = TRI_NO;
00122 break;
00123 case 'r':
00124 createrole = TRI_YES;
00125 break;
00126 case 'R':
00127 createrole = TRI_NO;
00128 break;
00129 case 'i':
00130 inherit = TRI_YES;
00131 break;
00132 case 'I':
00133 inherit = TRI_NO;
00134 break;
00135 case 'l':
00136 login = TRI_YES;
00137 break;
00138 case 'L':
00139 login = TRI_NO;
00140 break;
00141 case 'c':
00142 conn_limit = pg_strdup(optarg);
00143 break;
00144 case 'P':
00145 pwprompt = true;
00146 break;
00147 case 'E':
00148 encrypted = TRI_YES;
00149 break;
00150 case 'N':
00151 encrypted = TRI_NO;
00152 break;
00153 case 1:
00154 replication = TRI_YES;
00155 break;
00156 case 2:
00157 replication = TRI_NO;
00158 break;
00159 case 3:
00160 interactive = true;
00161 break;
00162 default:
00163 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
00164 exit(1);
00165 }
00166 }
00167
00168 switch (argc - optind)
00169 {
00170 case 0:
00171 break;
00172 case 1:
00173 newuser = argv[optind];
00174 break;
00175 default:
00176 fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
00177 progname, argv[optind + 1]);
00178 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
00179 exit(1);
00180 }
00181
00182 if (newuser == NULL)
00183 {
00184 if (interactive)
00185 newuser = simple_prompt("Enter name of role to add: ", 128, true);
00186 else
00187 {
00188 if (getenv("PGUSER"))
00189 newuser = getenv("PGUSER");
00190 else
00191 newuser = get_user_name(progname);
00192 }
00193 }
00194
00195 if (pwprompt)
00196 {
00197 char *pw1,
00198 *pw2;
00199
00200 pw1 = simple_prompt("Enter password for new role: ", 100, false);
00201 pw2 = simple_prompt("Enter it again: ", 100, false);
00202 if (strcmp(pw1, pw2) != 0)
00203 {
00204 fprintf(stderr, _("Passwords didn't match.\n"));
00205 exit(1);
00206 }
00207 newpassword = pw1;
00208 free(pw2);
00209 }
00210
00211 if (superuser == 0)
00212 {
00213 if (interactive && yesno_prompt("Shall the new role be a superuser?"))
00214 superuser = TRI_YES;
00215 else
00216 superuser = TRI_NO;
00217 }
00218
00219 if (superuser == TRI_YES)
00220 {
00221
00222 createdb = TRI_YES;
00223 createrole = TRI_YES;
00224 }
00225
00226 if (createdb == 0)
00227 {
00228 if (interactive && yesno_prompt("Shall the new role be allowed to create databases?"))
00229 createdb = TRI_YES;
00230 else
00231 createdb = TRI_NO;
00232 }
00233
00234 if (createrole == 0)
00235 {
00236 if (interactive && yesno_prompt("Shall the new role be allowed to create more new roles?"))
00237 createrole = TRI_YES;
00238 else
00239 createrole = TRI_NO;
00240 }
00241
00242 if (inherit == 0)
00243 inherit = TRI_YES;
00244
00245 if (login == 0)
00246 login = TRI_YES;
00247
00248 conn = connectDatabase("postgres", host, port, username, prompt_password,
00249 progname, false);
00250
00251 initPQExpBuffer(&sql);
00252
00253 printfPQExpBuffer(&sql, "CREATE ROLE %s", fmtId(newuser));
00254 if (newpassword)
00255 {
00256 if (encrypted == TRI_YES)
00257 appendPQExpBuffer(&sql, " ENCRYPTED");
00258 if (encrypted == TRI_NO)
00259 appendPQExpBuffer(&sql, " UNENCRYPTED");
00260 appendPQExpBuffer(&sql, " PASSWORD ");
00261
00262 if (encrypted != TRI_NO)
00263 {
00264 char *encrypted_password;
00265
00266 encrypted_password = PQencryptPassword(newpassword,
00267 newuser);
00268 if (!encrypted_password)
00269 {
00270 fprintf(stderr, _("Password encryption failed.\n"));
00271 exit(1);
00272 }
00273 appendStringLiteralConn(&sql, encrypted_password, conn);
00274 PQfreemem(encrypted_password);
00275 }
00276 else
00277 appendStringLiteralConn(&sql, newpassword, conn);
00278 }
00279 if (superuser == TRI_YES)
00280 appendPQExpBuffer(&sql, " SUPERUSER");
00281 if (superuser == TRI_NO)
00282 appendPQExpBuffer(&sql, " NOSUPERUSER");
00283 if (createdb == TRI_YES)
00284 appendPQExpBuffer(&sql, " CREATEDB");
00285 if (createdb == TRI_NO)
00286 appendPQExpBuffer(&sql, " NOCREATEDB");
00287 if (createrole == TRI_YES)
00288 appendPQExpBuffer(&sql, " CREATEROLE");
00289 if (createrole == TRI_NO)
00290 appendPQExpBuffer(&sql, " NOCREATEROLE");
00291 if (inherit == TRI_YES)
00292 appendPQExpBuffer(&sql, " INHERIT");
00293 if (inherit == TRI_NO)
00294 appendPQExpBuffer(&sql, " NOINHERIT");
00295 if (login == TRI_YES)
00296 appendPQExpBuffer(&sql, " LOGIN");
00297 if (login == TRI_NO)
00298 appendPQExpBuffer(&sql, " NOLOGIN");
00299 if (replication == TRI_YES)
00300 appendPQExpBuffer(&sql, " REPLICATION");
00301 if (replication == TRI_NO)
00302 appendPQExpBuffer(&sql, " NOREPLICATION");
00303 if (conn_limit != NULL)
00304 appendPQExpBuffer(&sql, " CONNECTION LIMIT %s", conn_limit);
00305 appendPQExpBuffer(&sql, ";\n");
00306
00307 if (echo)
00308 printf("%s", sql.data);
00309 result = PQexec(conn, sql.data);
00310
00311 if (PQresultStatus(result) != PGRES_COMMAND_OK)
00312 {
00313 fprintf(stderr, _("%s: creation of new role failed: %s"),
00314 progname, PQerrorMessage(conn));
00315 PQfinish(conn);
00316 exit(1);
00317 }
00318
00319 PQclear(result);
00320 PQfinish(conn);
00321 exit(0);
00322 }
00323
00324
00325 static void
00326 help(const char *progname)
00327 {
00328 printf(_("%s creates a new PostgreSQL role.\n\n"), progname);
00329 printf(_("Usage:\n"));
00330 printf(_(" %s [OPTION]... [ROLENAME]\n"), progname);
00331 printf(_("\nOptions:\n"));
00332 printf(_(" -c, --connection-limit=N connection limit for role (default: no limit)\n"));
00333 printf(_(" -d, --createdb role can create new databases\n"));
00334 printf(_(" -D, --no-createdb role cannot create databases (default)\n"));
00335 printf(_(" -e, --echo show the commands being sent to the server\n"));
00336 printf(_(" -E, --encrypted encrypt stored password\n"));
00337 printf(_(" -i, --inherit role inherits privileges of roles it is a\n"
00338 " member of (default)\n"));
00339 printf(_(" -I, --no-inherit role does not inherit privileges\n"));
00340 printf(_(" -l, --login role can login (default)\n"));
00341 printf(_(" -L, --no-login role cannot login\n"));
00342 printf(_(" -N, --unencrypted do not encrypt stored password\n"));
00343 printf(_(" -P, --pwprompt assign a password to new role\n"));
00344 printf(_(" -r, --createrole role can create new roles\n"));
00345 printf(_(" -R, --no-createrole role cannot create roles (default)\n"));
00346 printf(_(" -s, --superuser role will be superuser\n"));
00347 printf(_(" -S, --no-superuser role will not be superuser (default)\n"));
00348 printf(_(" -V, --version output version information, then exit\n"));
00349 printf(_(" --interactive prompt for missing role name and attributes rather\n"
00350 " than using defaults\n"));
00351 printf(_(" --replication role can initiate replication\n"));
00352 printf(_(" --no-replication role cannot initiate replication\n"));
00353 printf(_(" -?, --help show this help, then exit\n"));
00354 printf(_("\nConnection options:\n"));
00355 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
00356 printf(_(" -p, --port=PORT database server port\n"));
00357 printf(_(" -U, --username=USERNAME user name to connect as (not the one to create)\n"));
00358 printf(_(" -w, --no-password never prompt for password\n"));
00359 printf(_(" -W, --password force password prompt\n"));
00360 printf(_("\nReport bugs to <[email protected]>.\n"));
00361 }