Skip to content

Commit b16566d

Browse files
committed
Add new psql command \password for changing role password with client-side
password encryption. Also alter createuser command to the same effect.
1 parent ea77174 commit b16566d

File tree

10 files changed

+163
-50
lines changed

10 files changed

+163
-50
lines changed

doc/src/sgml/ref/alter_role.sgml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_role.sgml,v 1.2 2005/07/31 17:19:17 tgl Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_role.sgml,v 1.3 2005/12/18 02:17:16 petere Exp $
33
PostgreSQL documentation
44
-->
55

@@ -182,6 +182,16 @@ ALTER ROLE <replaceable class="PARAMETER">name</replaceable> RESET <replaceable>
182182
to do that.
183183
</para>
184184

185+
<para>
186+
Caution must be exercised when specifying an unencrypted password
187+
with this command. The password will be transmitted to the server
188+
in cleartext, and it might also be logged in the client's command
189+
history or the server log. <xref linkend="app-psql"
190+
endterm="app-psql-title"> contains a command
191+
<command>\password</command> that can be used to safely change a
192+
role's password.
193+
</para>
194+
185195
<para>
186196
It is also possible to tie a
187197
session default to a specific database rather than to a role; see

doc/src/sgml/ref/create_role.sgml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/create_role.sgml,v 1.4 2005/11/03 00:51:43 neilc Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/create_role.sgml,v 1.5 2005/12/18 02:17:16 petere Exp $
33
PostgreSQL documentation
44
-->
55

@@ -357,6 +357,18 @@ where <replaceable class="PARAMETER">option</replaceable> can be:
357357
connection <quote>slot</> remains for the role, it is possible that
358358
both will fail. Also, the limit is never enforced for superusers.
359359
</para>
360+
361+
<para>
362+
Caution must be exercised when specifying an unencrypted password
363+
with this command. The password will be transmitted to the server
364+
in cleartext, and it might also be logged in the client's command
365+
history or the server log. The command <xref
366+
linkend="APP-CREATEUSER" endterm="APP-CREATEUSER-title">, however, transmits
367+
the password encrypted. Also, <xref linkend="app-psql"
368+
endterm="app-psql-title"> contains a command
369+
<command>\password</command> that can be used to safely change the
370+
password later.
371+
</para>
360372
</refsect1>
361373

362374
<refsect1>

doc/src/sgml/ref/psql-ref.sgml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.155 2005/12/09 19:19:17 momjian Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.156 2005/12/18 02:17:16 petere Exp $
33
PostgreSQL documentation
44
-->
55

@@ -1379,6 +1379,19 @@ lo_import 152801
13791379
</varlistentry>
13801380

13811381

1382+
<varlistentry>
1383+
<term><literal>\password [ <replaceable class=parameter>username</replaceable> ]</literal>
1384+
<listitem>
1385+
<para>
1386+
Changes the password of the specified user or by default the
1387+
current user. This command prompts for the new password,
1388+
encrypts it, and sends it to the server. This makes sure that
1389+
the new password does not appear in the command history, the
1390+
server log, or elsewhere in cleartext.
1391+
</para>
1392+
</listitem>
1393+
</varlistentry>
1394+
13821395
<varlistentry>
13831396
<term><literal>\pset <replaceable class="parameter">parameter</replaceable> [ <replaceable class="parameter">value</replaceable> ]</literal></term>
13841397

src/bin/psql/Makefile

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
66
# Portions Copyright (c) 1994, Regents of the University of California
77
#
8-
# $PostgreSQL: pgsql/src/bin/psql/Makefile,v 1.55 2005/12/09 21:19:35 petere Exp $
8+
# $PostgreSQL: pgsql/src/bin/psql/Makefile,v 1.56 2005/12/18 02:17:16 petere Exp $
99
#
1010
#-------------------------------------------------------------------------
1111

@@ -17,22 +17,27 @@ include $(top_builddir)/src/Makefile.global
1717

1818
REFDOCDIR= $(top_srcdir)/doc/src/sgml/ref
1919

20-
override CPPFLAGS := -DFRONTEND -I$(srcdir) -I$(libpq_srcdir) $(CPPFLAGS)
20+
override CPPFLAGS := -DFRONTEND -I$(srcdir) -I$(libpq_srcdir) -I$(top_srcdir)/src/bin/pg_dump $(CPPFLAGS)
2121

2222
OBJS= command.o common.o help.o input.o stringutils.o mainloop.o copy.o \
2323
startup.o prompt.o variables.o large_obj.o print.o describe.o \
24-
psqlscan.o tab-complete.o mbprint.o $(WIN32RES)
24+
psqlscan.o tab-complete.o mbprint.o dumputils.o $(WIN32RES)
25+
26+
EXTRA_OBJS = $(top_builddir)/src/backend/parser/keywords.o
2527

2628
FLEXFLAGS = -Cfe
2729

2830

29-
all: submake-libpq submake-libpgport psql
31+
all: submake-libpq submake-libpgport submake-backend psql
3032

3133
psql: $(OBJS) $(libpq_builddir)/libpq.a
32-
$(CC) $(CFLAGS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LIBS) -o $@$(X)
34+
$(CC) $(CFLAGS) $(OBJS) $(EXTRA_OBJS) $(libpq_pgport) $(LDFLAGS) $(LIBS) -o $@$(X)
3335

3436
help.o: $(srcdir)/sql_help.h
3537

38+
dumputils.c: % : $(top_srcdir)/src/bin/pg_dump/%
39+
rm -f $@ && $(LN_S) $< .
40+
3641
ifdef PERL
3742
$(srcdir)/sql_help.h: create_help.pl $(wildcard $(REFDOCDIR)/*.sgml)
3843
$(PERL) $< $(REFDOCDIR) $@
@@ -48,6 +53,10 @@ else
4853
@$(missing) flex $< $@
4954
endif
5055

56+
.PHONY: submake-backend
57+
submake-backend:
58+
$(MAKE) -C $(top_builddir)/src/backend/parser keywords.o
59+
5160
distprep: $(srcdir)/sql_help.h $(srcdir)/psqlscan.c
5261

5362
install: all installdirs
@@ -62,7 +71,7 @@ uninstall:
6271

6372
# psqlscan.c is in the distribution tarball, so is not cleaned here
6473
clean distclean:
65-
rm -f psql$(X) $(OBJS)
74+
rm -f psql$(X) $(OBJS) dumputils.c
6675

6776
maintainer-clean: distclean
6877
rm -f $(srcdir)/sql_help.h $(srcdir)/psqlscan.c

src/bin/psql/command.c

Lines changed: 70 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* Copyright (c) 2000-2005, PostgreSQL Global Development Group
55
*
6-
* $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.155 2005/12/08 21:18:22 petere Exp $
6+
* $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.156 2005/12/18 02:17:16 petere Exp $
77
*/
88
#include "postgres_fe.h"
99
#include "command.h"
@@ -35,6 +35,8 @@
3535

3636
#include "libpq-fe.h"
3737
#include "pqexpbuffer.h"
38+
#include "libpq/crypt.h"
39+
#include "dumputils.h"
3840

3941
#include "common.h"
4042
#include "copy.h"
@@ -81,7 +83,7 @@ backslashResult
8183
HandleSlashCmds(PsqlScanState scan_state,
8284
PQExpBuffer query_buf)
8385
{
84-
backslashResult status = CMD_SKIP_LINE;
86+
backslashResult status = PSQL_CMD_SKIP_LINE;
8587
char *cmd;
8688
char *arg;
8789

@@ -93,7 +95,7 @@ HandleSlashCmds(PsqlScanState scan_state,
9395
/* And try to execute it */
9496
status = exec_command(cmd, scan_state, query_buf);
9597

96-
if (status == CMD_UNKNOWN && strlen(cmd) > 1)
98+
if (status == PSQL_CMD_UNKNOWN && strlen(cmd) > 1)
9799
{
98100
/*
99101
* If the command was not recognized, try to parse it as a one-letter
@@ -110,23 +112,23 @@ HandleSlashCmds(PsqlScanState scan_state,
110112

111113
status = exec_command(new_cmd, scan_state, query_buf);
112114

113-
if (status != CMD_UNKNOWN)
115+
if (status != PSQL_CMD_UNKNOWN)
114116
{
115117
/* adjust cmd for possible messages below */
116118
cmd[1] = '\0';
117119
}
118120
}
119121

120-
if (status == CMD_UNKNOWN)
122+
if (status == PSQL_CMD_UNKNOWN)
121123
{
122124
if (pset.cur_cmd_interactive)
123125
fprintf(stderr, _("Invalid command \\%s. Try \\? for help.\n"), cmd);
124126
else
125127
psql_error("invalid command \\%s\n", cmd);
126-
status = CMD_ERROR;
128+
status = PSQL_CMD_ERROR;
127129
}
128130

129-
if (status != CMD_ERROR)
131+
if (status != PSQL_CMD_ERROR)
130132
{
131133
/* eat any remaining arguments after a valid command */
132134
/* note we suppress evaluation of backticks here */
@@ -164,7 +166,7 @@ exec_command(const char *cmd,
164166
bool success = true; /* indicate here if the command ran ok or
165167
* failed */
166168
bool quiet = QUIET();
167-
backslashResult status = CMD_SKIP_LINE;
169+
backslashResult status = PSQL_CMD_SKIP_LINE;
168170

169171
/*
170172
* \a -- toggle field alignment This makes little sense but we keep it
@@ -368,7 +370,7 @@ exec_command(const char *cmd,
368370
break;
369371

370372
default:
371-
status = CMD_UNKNOWN;
373+
status = PSQL_CMD_UNKNOWN;
372374
}
373375

374376
if (pattern)
@@ -387,7 +389,7 @@ exec_command(const char *cmd,
387389
if (!query_buf)
388390
{
389391
psql_error("no query buffer\n");
390-
status = CMD_ERROR;
392+
status = PSQL_CMD_ERROR;
391393
}
392394
else
393395
{
@@ -396,7 +398,7 @@ exec_command(const char *cmd,
396398
expand_tilde(&fname);
397399
if (fname)
398400
canonicalize_path(fname);
399-
status = do_edit(fname, query_buf) ? CMD_NEWEDIT : CMD_ERROR;
401+
status = do_edit(fname, query_buf) ? PSQL_CMD_NEWEDIT : PSQL_CMD_ERROR;
400402
free(fname);
401403
}
402404
}
@@ -486,7 +488,7 @@ exec_command(const char *cmd,
486488
pset.gfname = pg_strdup(fname);
487489
}
488490
free(fname);
489-
status = CMD_SEND;
491+
status = PSQL_CMD_SEND;
490492
}
491493

492494
/* help */
@@ -590,7 +592,7 @@ exec_command(const char *cmd,
590592
}
591593

592594
else
593-
status = CMD_UNKNOWN;
595+
status = PSQL_CMD_UNKNOWN;
594596

595597
free(opt1);
596598
free(opt2);
@@ -618,6 +620,57 @@ exec_command(const char *cmd,
618620
fflush(stdout);
619621
}
620622

623+
/* \password -- set user password */
624+
else if (strcmp(cmd, "password") == 0)
625+
{
626+
char *pw1;
627+
char *pw2;
628+
629+
pw1 = simple_prompt("Enter new password: ", 100, false);
630+
pw2 = simple_prompt("Enter it again: ", 100, false);
631+
632+
if (strcmp(pw1, pw2) != 0)
633+
{
634+
fprintf(stderr, _("Passwords didn't match.\n"));
635+
success = false;
636+
}
637+
else
638+
{
639+
char *opt0 = psql_scan_slash_option(scan_state, OT_SQLID, NULL, true);
640+
char *user;
641+
char encrypted_password[MD5_PASSWD_LEN + 1];
642+
643+
if (opt0)
644+
user = opt0;
645+
else
646+
user = PQuser(pset.db);
647+
648+
if (!pg_md5_encrypt(pw1, user, strlen(user), encrypted_password))
649+
{
650+
fprintf(stderr, _("Password encryption failed.\n"));
651+
success = false;
652+
}
653+
else
654+
{
655+
PQExpBufferData buf;
656+
PGresult *res;
657+
658+
initPQExpBuffer(&buf);
659+
printfPQExpBuffer(&buf, "ALTER ROLE %s PASSWORD '%s';",
660+
fmtId(user), encrypted_password);
661+
res = PSQLexec(buf.data, false);
662+
termPQExpBuffer(&buf);
663+
if (!res)
664+
success = false;
665+
else
666+
PQclear(res);
667+
}
668+
}
669+
670+
free(pw1);
671+
free(pw2);
672+
}
673+
621674
/* \pset -- set printing parameters */
622675
else if (strcmp(cmd, "pset") == 0)
623676
{
@@ -640,7 +693,7 @@ exec_command(const char *cmd,
640693

641694
/* \q or \quit */
642695
else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
643-
status = CMD_TERMINATE;
696+
status = PSQL_CMD_TERMINATE;
644697

645698
/* reset(clear) the buffer */
646699
else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
@@ -780,7 +833,7 @@ exec_command(const char *cmd,
780833
if (!query_buf)
781834
{
782835
psql_error("no query buffer\n");
783-
status = CMD_ERROR;
836+
status = PSQL_CMD_ERROR;
784837
}
785838
else
786839
{
@@ -884,10 +937,10 @@ exec_command(const char *cmd,
884937
#endif
885938

886939
else
887-
status = CMD_UNKNOWN;
940+
status = PSQL_CMD_UNKNOWN;
888941

889942
if (!success)
890-
status = CMD_ERROR;
943+
status = PSQL_CMD_ERROR;
891944

892945
return status;
893946
}

src/bin/psql/command.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* Copyright (c) 2000-2005, PostgreSQL Global Development Group
55
*
6-
* $PostgreSQL: pgsql/src/bin/psql/command.h,v 1.22 2005/01/01 05:43:08 momjian Exp $
6+
* $PostgreSQL: pgsql/src/bin/psql/command.h,v 1.23 2005/12/18 02:17:16 petere Exp $
77
*/
88
#ifndef COMMAND_H
99
#define COMMAND_H
@@ -15,12 +15,12 @@
1515

1616
typedef enum _backslashResult
1717
{
18-
CMD_UNKNOWN = 0, /* not done parsing yet (internal only) */
19-
CMD_SEND, /* query complete; send off */
20-
CMD_SKIP_LINE, /* keep building query */
21-
CMD_TERMINATE, /* quit program */
22-
CMD_NEWEDIT, /* query buffer was changed (e.g., via \e) */
23-
CMD_ERROR /* the execution of the backslash command
18+
PSQL_CMD_UNKNOWN = 0, /* not done parsing yet (internal only) */
19+
PSQL_CMD_SEND, /* query complete; send off */
20+
PSQL_CMD_SKIP_LINE, /* keep building query */
21+
PSQL_CMD_TERMINATE, /* quit program */
22+
PSQL_CMD_NEWEDIT, /* query buffer was changed (e.g., via \e) */
23+
PSQL_CMD_ERROR /* the execution of the backslash command
2424
* resulted in an error */
2525
} backslashResult;
2626

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy