Skip to content

Commit 22a2c4b

Browse files
committed
Erase MD5 user passwords when a user is renamed because the username is
used as salt for the MD5 password.
1 parent d8f6973 commit 22a2c4b

File tree

2 files changed

+46
-14
lines changed

2 files changed

+46
-14
lines changed

doc/src/sgml/ref/alter_user.sgml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_user.sgml,v 1.32 2003/11/29 19:51:38 pgsql Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_user.sgml,v 1.33 2004/05/06 16:59:16 momjian Exp $
33
PostgreSQL documentation
44
-->
55

@@ -57,6 +57,9 @@ ALTER USER <replaceable class="PARAMETER">name</replaceable> RESET <replaceable>
5757
The second variant changes the name of the user. Only a database
5858
superuser can rename user accounts. The session user cannot be
5959
renamed. (Connect as a different user if you need to do that.)
60+
Because <literal>MD5</>-encrypted passwords use the username as
61+
cryptographic salt, renaming a user clears their <literal>MD5</>
62+
password.
6063
</para>
6164

6265
<para>

src/backend/commands/user.c

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.139 2004/03/16 05:05:57 momjian Exp $
9+
* $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.140 2004/05/06 16:59:16 momjian Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -959,8 +959,8 @@ AlterUserSet(AlterUserSetStmt *stmt)
959959
(errcode(ERRCODE_UNDEFINED_OBJECT),
960960
errmsg("user \"%s\" does not exist", stmt->user)));
961961

962-
if (!(superuser()
963-
|| ((Form_pg_shadow) GETSTRUCT(oldtuple))->usesysid == GetUserId()))
962+
if (!(superuser() ||
963+
((Form_pg_shadow) GETSTRUCT(oldtuple))->usesysid == GetUserId()))
964964
ereport(ERROR,
965965
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
966966
errmsg("permission denied")));
@@ -1157,16 +1157,25 @@ DropUser(DropUserStmt *stmt)
11571157
void
11581158
RenameUser(const char *oldname, const char *newname)
11591159
{
1160-
HeapTuple tup;
1160+
HeapTuple oldtuple,
1161+
newtuple;
1162+
TupleDesc dsc;
11611163
Relation rel;
1162-
1164+
Datum datum;
1165+
bool isnull;
1166+
Datum repl_val[Natts_pg_shadow];
1167+
char repl_null[Natts_pg_shadow];
1168+
char repl_repl[Natts_pg_shadow];
1169+
int i;
1170+
11631171
/* ExclusiveLock because we need to update the password file */
11641172
rel = heap_openr(ShadowRelationName, ExclusiveLock);
1173+
dsc = RelationGetDescr(rel);
11651174

1166-
tup = SearchSysCacheCopy(SHADOWNAME,
1175+
oldtuple = SearchSysCache(SHADOWNAME,
11671176
CStringGetDatum(oldname),
11681177
0, 0, 0);
1169-
if (!HeapTupleIsValid(tup))
1178+
if (!HeapTupleIsValid(oldtuple))
11701179
ereport(ERROR,
11711180
(errcode(ERRCODE_UNDEFINED_OBJECT),
11721181
errmsg("user \"%s\" does not exist", oldname)));
@@ -1177,7 +1186,7 @@ RenameUser(const char *oldname, const char *newname)
11771186
* not be an actual problem besides a little confusion, so think about
11781187
* this and decide.
11791188
*/
1180-
if (((Form_pg_shadow) GETSTRUCT(tup))->usesysid == GetSessionUserId())
1189+
if (((Form_pg_shadow) GETSTRUCT(oldtuple))->usesysid == GetSessionUserId())
11811190
ereport(ERROR,
11821191
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
11831192
errmsg("session user may not be renamed")));
@@ -1196,13 +1205,33 @@ RenameUser(const char *oldname, const char *newname)
11961205
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
11971206
errmsg("must be superuser to rename users")));
11981207

1199-
/* rename */
1200-
namestrcpy(&(((Form_pg_shadow) GETSTRUCT(tup))->usename), newname);
1201-
simple_heap_update(rel, &tup->t_self, tup);
1202-
CatalogUpdateIndexes(rel, tup);
1208+
for (i = 0; i < Natts_pg_shadow; i++)
1209+
repl_repl[i] = ' ';
1210+
1211+
repl_repl[Anum_pg_shadow_usename - 1] = 'r';
1212+
repl_val[Anum_pg_shadow_usename - 1] = DirectFunctionCall1(namein,
1213+
CStringGetDatum(newname));
1214+
repl_null[Anum_pg_shadow_usename - 1] = ' ';
12031215

1216+
datum = heap_getattr(oldtuple, Anum_pg_shadow_passwd, dsc, &isnull);
1217+
1218+
if (!isnull && isMD5(DatumGetCString(DirectFunctionCall1(textout, datum))))
1219+
{
1220+
/* MD5 uses the username as salt, so just clear it on a rename */
1221+
repl_repl[Anum_pg_shadow_passwd - 1] = 'r';
1222+
repl_null[Anum_pg_shadow_passwd - 1] = 'n';
1223+
1224+
ereport(NOTICE,
1225+
(errmsg("MD5 password cleared because of user rename")));
1226+
}
1227+
1228+
newtuple = heap_modifytuple(oldtuple, rel, repl_val, repl_null, repl_repl);
1229+
simple_heap_update(rel, &oldtuple->t_self, newtuple);
1230+
1231+
CatalogUpdateIndexes(rel, newtuple);
1232+
1233+
ReleaseSysCache(oldtuple);
12041234
heap_close(rel, NoLock);
1205-
heap_freetuple(tup);
12061235

12071236
user_file_update_needed = true;
12081237
}

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