Header And Logo

PostgreSQL
| The world's most advanced open source database.

createuser.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * createuser
00004  *
00005  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00006  * Portions Copyright (c) 1994, Regents of the University of California
00007  *
00008  * src/bin/scripts/createuser.c
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         /* adduser is obsolete, undocumented spelling of superuser */
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     /* Tri-valued variables.  */
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         /* Not much point in trying to restrict a superuser */
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 }