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