1 /*-------------------------------------------------------------------------
2  *
3  * dropuser
4  *
5  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
6  * Portions Copyright (c) 1994, Regents of the University of California
7  *
8  * src/bin/scripts/dropuser.c
9  *
10  *-------------------------------------------------------------------------
11  */
12 
13 #include "postgres_fe.h"
14 #include "common.h"
15 #include "fe_utils/string_utils.h"
16 
17 
18 static void help(const char *progname);
19 
20 
21 int
main(int argc,char * argv[])22 main(int argc, char *argv[])
23 {
24 	static int	if_exists = 0;
25 
26 	static struct option long_options[] = {
27 		{"host", required_argument, NULL, 'h'},
28 		{"port", required_argument, NULL, 'p'},
29 		{"username", required_argument, NULL, 'U'},
30 		{"no-password", no_argument, NULL, 'w'},
31 		{"password", no_argument, NULL, 'W'},
32 		{"echo", no_argument, NULL, 'e'},
33 		{"interactive", no_argument, NULL, 'i'},
34 		{"if-exists", no_argument, &if_exists, 1},
35 		{NULL, 0, NULL, 0}
36 	};
37 
38 	const char *progname;
39 	int			optindex;
40 	int			c;
41 
42 	char	   *dropuser = NULL;
43 	char	   *host = NULL;
44 	char	   *port = NULL;
45 	char	   *username = NULL;
46 	enum trivalue prompt_password = TRI_DEFAULT;
47 	ConnParams	cparams;
48 	bool		echo = false;
49 	bool		interactive = false;
50 	char		dropuser_buf[128];
51 
52 	PQExpBufferData sql;
53 
54 	PGconn	   *conn;
55 	PGresult   *result;
56 
57 	progname = get_progname(argv[0]);
58 	set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
59 
60 	handle_help_version_opts(argc, argv, "dropuser", help);
61 
62 	while ((c = getopt_long(argc, argv, "h:p:U:wWei", long_options, &optindex)) != -1)
63 	{
64 		switch (c)
65 		{
66 			case 'h':
67 				host = pg_strdup(optarg);
68 				break;
69 			case 'p':
70 				port = pg_strdup(optarg);
71 				break;
72 			case 'U':
73 				username = pg_strdup(optarg);
74 				break;
75 			case 'w':
76 				prompt_password = TRI_NO;
77 				break;
78 			case 'W':
79 				prompt_password = TRI_YES;
80 				break;
81 			case 'e':
82 				echo = true;
83 				break;
84 			case 'i':
85 				interactive = true;
86 				break;
87 			case 0:
88 				/* this covers the long options */
89 				break;
90 			default:
91 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
92 				exit(1);
93 		}
94 	}
95 
96 	switch (argc - optind)
97 	{
98 		case 0:
99 			break;
100 		case 1:
101 			dropuser = argv[optind];
102 			break;
103 		default:
104 			fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
105 					progname, argv[optind + 1]);
106 			fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
107 			exit(1);
108 	}
109 
110 	if (dropuser == NULL)
111 	{
112 		if (interactive)
113 		{
114 			simple_prompt("Enter name of role to drop: ",
115 						  dropuser_buf, sizeof(dropuser_buf), true);
116 			dropuser = dropuser_buf;
117 		}
118 		else
119 		{
120 			fprintf(stderr, _("%s: missing required argument role name\n"), progname);
121 			fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
122 			exit(1);
123 		}
124 	}
125 
126 	if (interactive)
127 	{
128 		printf(_("Role \"%s\" will be permanently removed.\n"), dropuser);
129 		if (!yesno_prompt("Are you sure?"))
130 			exit(0);
131 	}
132 
133 	cparams.dbname = NULL;		/* this program lacks any dbname option... */
134 	cparams.pghost = host;
135 	cparams.pgport = port;
136 	cparams.pguser = username;
137 	cparams.prompt_password = prompt_password;
138 	cparams.override_dbname = NULL;
139 
140 	conn = connectMaintenanceDatabase(&cparams, progname, echo);
141 
142 	initPQExpBuffer(&sql);
143 	appendPQExpBuffer(&sql, "DROP ROLE %s%s;",
144 					  (if_exists ? "IF EXISTS " : ""), fmtId(dropuser));
145 
146 	if (echo)
147 		printf("%s\n", sql.data);
148 	result = PQexec(conn, sql.data);
149 
150 	if (PQresultStatus(result) != PGRES_COMMAND_OK)
151 	{
152 		fprintf(stderr, _("%s: removal of role \"%s\" failed: %s"),
153 				progname, dropuser, PQerrorMessage(conn));
154 		PQfinish(conn);
155 		exit(1);
156 	}
157 
158 	PQclear(result);
159 	PQfinish(conn);
160 	exit(0);
161 }
162 
163 
164 static void
help(const char * progname)165 help(const char *progname)
166 {
167 	printf(_("%s removes a PostgreSQL role.\n\n"), progname);
168 	printf(_("Usage:\n"));
169 	printf(_("  %s [OPTION]... [ROLENAME]\n"), progname);
170 	printf(_("\nOptions:\n"));
171 	printf(_("  -e, --echo                show the commands being sent to the server\n"));
172 	printf(_("  -i, --interactive         prompt before deleting anything, and prompt for\n"
173 			 "                            role name if not specified\n"));
174 	printf(_("  -V, --version             output version information, then exit\n"));
175 	printf(_("  --if-exists               don't report error if user doesn't exist\n"));
176 	printf(_("  -?, --help                show this help, then exit\n"));
177 	printf(_("\nConnection options:\n"));
178 	printf(_("  -h, --host=HOSTNAME       database server host or socket directory\n"));
179 	printf(_("  -p, --port=PORT           database server port\n"));
180 	printf(_("  -U, --username=USERNAME   user name to connect as (not the one to drop)\n"));
181 	printf(_("  -w, --no-password         never prompt for password\n"));
182 	printf(_("  -W, --password            force password prompt\n"));
183 	printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
184 }
185