An untested patch to update the password file.
Something that bugged me a lot is that I tried to find the format of the
file for testing the patch, and I couldn't find anything anywhere in the
docs. Apparently the docs for the file were ripped with the docs for
the pg_passwd utility when it was ripped before the 7.3 release.
--
Alvaro Herrera (<alvherre[a]dcc.uchile.cl>)
"Some men are heterosexual, and some are bisexual, and some
men don't think about sex at all... they become lawyers" (Woody Allen)
Index: src/backend/commands/user.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql-server/src/backend/commands/user.c,v
retrieving revision 1.141
diff -c -r1.141 user.c
*** src/backend/commands/user.c 26 May 2004 04:41:12 -0000 1.141
--- src/backend/commands/user.c 27 Jun 2004 21:49:37 -0000
***************
*** 44,51 ****
extern bool Password_encryption;
! static bool user_file_update_needed = false;
! static bool group_file_update_needed = false;
static void CheckPgUserAclNotNull(void);
--- 44,63 ----
extern bool Password_encryption;
! /*
! * The need-to-update-files flags are a pair of TransactionId that show what
! * level of the transaction tree requested the update. To register an update,
! * the transaction saves its own TransactionId in the flag, unless the value
! * was already set to a valid TransactionId. If it aborts and the value is its
! * TransactionId, it resets the value to InvalidTransactionId. If it commits,
! * it changes the value to its parent's TransactionId. This way the value is
! * propagated up to the topmost transaction, which will update the files if a
! * valid TransactionId is detected.
! *
! * This is the same logic used for RelcacheInitFileInval in inval.c.
! */
! static TransactionId user_file_update_needed = InvalidTransactionId;
! static TransactionId group_file_update_needed = InvalidTransactionId;
static void CheckPgUserAclNotNull(void);
***************
*** 402,409 ****
Datum
update_pg_pwd_and_pg_group(PG_FUNCTION_ARGS)
{
! user_file_update_needed = true;
! group_file_update_needed = true;
return PointerGetDatum(NULL);
}
--- 414,424 ----
Datum
update_pg_pwd_and_pg_group(PG_FUNCTION_ARGS)
{
! if (user_file_update_needed == InvalidTransactionId)
! user_file_update_needed = GetCurrentTransactionId();
!
! if (group_file_update_needed == InvalidTransactionId)
! group_file_update_needed = GetCurrentTransactionId();
return PointerGetDatum(NULL);
}
***************
*** 429,441 ****
Relation urel = NULL;
Relation grel = NULL;
! if (!(user_file_update_needed || group_file_update_needed))
return;
if (!isCommit)
{
! user_file_update_needed = false;
! group_file_update_needed = false;
return;
}
--- 444,457 ----
Relation urel = NULL;
Relation grel = NULL;
! if (user_file_update_needed == InvalidTransactionId &&
! group_file_update_needed == InvalidTransactionId)
return;
if (!isCommit)
{
! user_file_update_needed = InvalidTransactionId;
! group_file_update_needed = InvalidTransactionId;
return;
}
***************
*** 447,468 ****
* pg_shadow or pg_group, which likely won't have gotten a strong
* enough lock), so get the locks we need before writing anything.
*/
! if (user_file_update_needed)
urel = heap_openr(ShadowRelationName, ExclusiveLock);
! if (group_file_update_needed)
grel = heap_openr(GroupRelationName, ExclusiveLock);
/* Okay to write the files */
! if (user_file_update_needed)
{
! user_file_update_needed = false;
write_user_file(urel);
heap_close(urel, NoLock);
}
! if (group_file_update_needed)
{
! group_file_update_needed = false;
write_group_file(grel);
heap_close(grel, NoLock);
}
--- 463,484 ----
* pg_shadow or pg_group, which likely won't have gotten a strong
* enough lock), so get the locks we need before writing anything.
*/
! if (user_file_update_needed != InvalidTransactionId)
urel = heap_openr(ShadowRelationName, ExclusiveLock);
! if (group_file_update_needed != InvalidTransactionId)
grel = heap_openr(GroupRelationName, ExclusiveLock);
/* Okay to write the files */
! if (user_file_update_needed != InvalidTransactionId)
{
! user_file_update_needed = InvalidTransactionId;
write_user_file(urel);
heap_close(urel, NoLock);
}
! if (group_file_update_needed != InvalidTransactionId)
{
! group_file_update_needed = InvalidTransactionId;
write_group_file(grel);
heap_close(grel, NoLock);
}
***************
*** 473,479 ****
--- 489,522 ----
SendPostmasterSignal(PMSIGNAL_PASSWORD_CHANGE);
}
+ /*
+ * AtEOSubXact_UpdatePasswordFile
+ *
+ * Called at subtransaction end, this routine resets or updates the
+ * need-to-update-files flags.
+ */
+ void
+ AtEOSubXact_UpdatePasswordFile(bool isCommit)
+ {
+ TransactionId myXid = GetCurrentTransactionId();
+ if (isCommit)
+ {
+ if (user_file_update_needed == myXid)
+ user_file_update_needed = GetParentTransactionId();
+
+ if (group_file_update_needed == myXid)
+ group_file_update_needed = GetParentTransactionId();
+ }
+ else
+ {
+ if (user_file_update_needed == myXid)
+ user_file_update_needed = InvalidTransactionId;
+
+ if (group_file_update_needed == myXid)
+ group_file_update_needed = InvalidTransactionId;
+ }
+ }
/*
* CREATE USER
***************
*** 728,734 ****
/*
* Set flag to update flat password file at commit.
*/
! user_file_update_needed = true;
}
--- 771,778 ----
/*
* Set flag to update flat password file at commit.
*/
! if (user_file_update_needed == InvalidTransactionId)
! user_file_update_needed = GetCurrentTransactionId();
}
***************
*** 925,931 ****
/*
* Set flag to update flat password file at commit.
*/
! user_file_update_needed = true;
}
--- 969,976 ----
/*
* Set flag to update flat password file at commit.
*/
! if (user_file_update_needed == InvalidTransactionId)
! user_file_update_needed = GetCurrentTransactionId();
}
***************
*** 1147,1153 ****
/*
* Set flag to update flat password file at commit.
*/
! user_file_update_needed = true;
}
--- 1192,1199 ----
/*
* Set flag to update flat password file at commit.
*/
! if (user_file_update_needed == InvalidTransactionId)
! user_file_update_needed = GetCurrentTransactionId();
}
***************
*** 1233,1239 ****
ReleaseSysCache(oldtuple);
heap_close(rel, NoLock);
! user_file_update_needed = true;
}
--- 1279,1286 ----
ReleaseSysCache(oldtuple);
heap_close(rel, NoLock);
! if (user_file_update_needed == InvalidTransactionId)
! user_file_update_needed = GetCurrentTransactionId();
}
***************
*** 1438,1444 ****
/*
* Set flag to update flat group file at commit.
*/
! group_file_update_needed = true;
}
--- 1485,1492 ----
/*
* Set flag to update flat group file at commit.
*/
! if (group_file_update_needed == InvalidTransactionId)
! group_file_update_needed = GetCurrentTransactionId();
}
***************
*** 1590,1596 ****
/*
* Set flag to update flat group file at commit.
*/
! group_file_update_needed = true;
}
/*
--- 1638,1645 ----
/*
* Set flag to update flat group file at commit.
*/
! if (group_file_update_needed == InvalidTransactionId)
! group_file_update_needed = GetCurrentTransactionId();
}
/*
***************
*** 1730,1736 ****
/*
* Set flag to update flat group file at commit.
*/
! group_file_update_needed = true;
}
--- 1779,1786 ----
/*
* Set flag to update flat group file at commit.
*/
! if (group_file_update_needed == InvalidTransactionId)
! group_file_update_needed = GetCurrentTransactionId();
}
***************
*** 1776,1780 ****
heap_close(rel, NoLock);
heap_freetuple(tup);
! group_file_update_needed = true;
}
--- 1826,1831 ----
heap_close(rel, NoLock);
heap_freetuple(tup);
! if (group_file_update_needed == InvalidTransactionId)
! group_file_update_needed = GetCurrentTransactionId();
}
Index: src/include/commands/user.h
===================================================================
RCS file: /home/alvherre/cvs/pgsql-server/src/include/commands/user.h,v
retrieving revision 1.22
diff -c -r1.22 user.h
*** src/include/commands/user.h 29 Nov 2003 22:40:59 -0000 1.22
--- src/include/commands/user.h 27 Jun 2004 21:33:02 -0000
***************
*** 32,36 ****
--- 32,37 ----
extern Datum update_pg_pwd_and_pg_group(PG_FUNCTION_ARGS);
extern void AtEOXact_UpdatePasswordFile(bool isCommit);
+ extern void AtEOSubXact_UpdatePasswordFile(bool isCommit);
#endif /* USER_H */
---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?
http://www.postgresql.org/docs/faqs/FAQ.html