Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)