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 ),
960960errmsg ("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 ()))
964964ereport (ERROR ,
965965(errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
966966errmsg ("permission denied" )));
@@ -1157,16 +1157,25 @@ DropUser(DropUserStmt *stmt)
11571157void
11581158RenameUser (const char * oldname ,const char * newname )
11591159{
1160- HeapTuple tup ;
1160+ HeapTuple oldtuple ,
1161+ newtuple ;
1162+ TupleDesc dsc ;
11611163Relation 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 */
11641172rel = heap_openr (ShadowRelationName ,ExclusiveLock );
1173+ dsc = RelationGetDescr (rel );
11651174
1166- tup = SearchSysCacheCopy (SHADOWNAME ,
1175+ oldtuple = SearchSysCache (SHADOWNAME ,
11671176CStringGetDatum (oldname ),
116811770 ,0 ,0 );
1169- if (!HeapTupleIsValid (tup ))
1178+ if (!HeapTupleIsValid (oldtuple ))
11701179ereport (ERROR ,
11711180(errcode (ERRCODE_UNDEFINED_OBJECT ),
11721181errmsg ("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 ())
11811190ereport (ERROR ,
11821191(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
11831192errmsg ("session user may not be renamed" )));
@@ -1196,13 +1205,33 @@ RenameUser(const char *oldname, const char *newname)
11961205(errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
11971206errmsg ("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 );
12041234heap_close (rel ,NoLock );
1205- heap_freetuple (tup );
12061235
12071236user_file_update_needed = true;
12081237}