mirror of
https://github.com/postgres/postgres.git
synced 2025-11-12 05:01:15 +03:00
Code cleanup of user name and user id handling in the backend. The current
user is now defined in terms of the user id, the user name is only computed upon request (for display purposes). This is kind of the opposite of the previous state, which would maintain the user name and compute the user id for permission checks. Besides perhaps saving a few cycles (integer vs string), this now creates a single point of attack for changing the user id during a connection, for purposes of "setuid" functions, etc.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.45 2000/05/31 00:28:32 petere Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.46 2000/09/06 14:15:22 petere Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Globals used all over the place should be declared here and not
|
||||
@@ -54,7 +54,6 @@ char OutputFileName[MAXPGPATH] = "";
|
||||
BackendId MyBackendId;
|
||||
BackendTag MyBackendTag;
|
||||
|
||||
char *UserName = NULL;
|
||||
char *DatabaseName = NULL;
|
||||
char *DatabasePath = NULL;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.53 2000/08/03 16:34:24 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.54 2000/09/06 14:15:22 petere Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -273,44 +273,24 @@ convertstr(unsigned char *buff, int len, int dest)
|
||||
#endif
|
||||
|
||||
/* ----------------
|
||||
* GetPgUserName and SetPgUserName
|
||||
*
|
||||
* SetPgUserName must be called before InitPostgres, since the setuid()
|
||||
* is done there.
|
||||
* GetPgUserName
|
||||
* ----------------
|
||||
*/
|
||||
char *
|
||||
GetPgUserName(void)
|
||||
{
|
||||
return UserName;
|
||||
HeapTuple tuple;
|
||||
Oid userid;
|
||||
|
||||
userid = GetUserId();
|
||||
|
||||
tuple = SearchSysCacheTuple(SHADOWSYSID, ObjectIdGetDatum(userid), 0, 0, 0);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
elog(ERROR, "invalid user id %u", (unsigned) userid);
|
||||
|
||||
return pstrdup( NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename) );
|
||||
}
|
||||
|
||||
void
|
||||
SetPgUserName(void)
|
||||
{
|
||||
#ifndef NO_SECURITY
|
||||
char *p;
|
||||
struct passwd *pw;
|
||||
|
||||
if (IsUnderPostmaster)
|
||||
{
|
||||
/* use the (possibly) authenticated name that's provided */
|
||||
if (!(p = getenv("PG_USER")))
|
||||
elog(FATAL, "SetPgUserName: PG_USER environment variable is unset");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* setuid() has not yet been done, see above comment */
|
||||
if (!(pw = getpwuid(geteuid())))
|
||||
elog(FATAL, "SetPgUserName: no entry in host passwd file");
|
||||
p = pw->pw_name;
|
||||
}
|
||||
if (UserName)
|
||||
free(UserName);
|
||||
UserName = malloc(strlen(p) + 1);
|
||||
strcpy(UserName, p);
|
||||
#endif /* NO_SECURITY */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* GetUserId and SetUserId
|
||||
@@ -318,42 +298,42 @@ SetPgUserName(void)
|
||||
*/
|
||||
static Oid UserId = InvalidOid;
|
||||
|
||||
int
|
||||
|
||||
Oid
|
||||
GetUserId()
|
||||
{
|
||||
AssertState(OidIsValid(UserId));
|
||||
return UserId;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SetUserId()
|
||||
SetUserId(Oid newid)
|
||||
{
|
||||
UserId = newid;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SetUserIdFromUserName(const char *username)
|
||||
{
|
||||
HeapTuple userTup;
|
||||
char *userName;
|
||||
|
||||
AssertState(!OidIsValid(UserId)); /* only once */
|
||||
|
||||
/*
|
||||
* Don't do scans if we're bootstrapping, none of the system catalogs
|
||||
* exist yet, and they should be owned by postgres anyway.
|
||||
*/
|
||||
if (IsBootstrapProcessingMode())
|
||||
{
|
||||
UserId = geteuid();
|
||||
return;
|
||||
}
|
||||
AssertState(!IsBootstrapProcessingMode());
|
||||
|
||||
userName = GetPgUserName();
|
||||
userTup = SearchSysCacheTuple(SHADOWNAME,
|
||||
PointerGetDatum(userName),
|
||||
PointerGetDatum(username),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(userTup))
|
||||
elog(FATAL, "SetUserId: user '%s' is not in '%s'",
|
||||
userName,
|
||||
ShadowRelationName);
|
||||
UserId = (Oid) ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
|
||||
elog(FATAL, "user \"%s\" does not exist", username);
|
||||
SetUserId( ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid );
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* posmaster pid file stuffs. $DATADIR/postmaster.pid is created when:
|
||||
|
||||
@@ -8,19 +8,19 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.64 2000/08/06 04:39:10 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.65 2000/09/06 14:15:22 petere Exp $
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/types.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "access/heapam.h"
|
||||
#include "catalog/catname.h"
|
||||
#include "catalog/pg_database.h"
|
||||
@@ -223,7 +223,7 @@ int lockingOff = 0; /* backend -L switch */
|
||||
/*
|
||||
*/
|
||||
void
|
||||
InitPostgres(const char *dbname)
|
||||
InitPostgres(const char *dbname, const char *username)
|
||||
{
|
||||
bool bootstrap = IsBootstrapProcessingMode();
|
||||
|
||||
@@ -366,17 +366,20 @@ InitPostgres(const char *dbname)
|
||||
/* replace faked-up relcache entries with the real info */
|
||||
RelationCacheInitializePhase2();
|
||||
|
||||
/*
|
||||
* Set ourselves to the proper user id and figure out our postgres
|
||||
* user id. If we ever add security so that we check for valid
|
||||
* postgres users, we might do it here.
|
||||
*/
|
||||
setuid(geteuid());
|
||||
SetUserId();
|
||||
|
||||
if (lockingOff)
|
||||
LockDisable(true);
|
||||
|
||||
/*
|
||||
* Set ourselves to the proper user id and figure out our postgres
|
||||
* user id.
|
||||
*/
|
||||
if (bootstrap)
|
||||
SetUserId(geteuid());
|
||||
else
|
||||
SetUserIdFromUserName(username);
|
||||
|
||||
setuid(geteuid());
|
||||
|
||||
/*
|
||||
* Unless we are bootstrapping, double-check that InitMyDatabaseInfo()
|
||||
* got a correct result. We can't do this until essentially all the
|
||||
|
||||
Reference in New Issue
Block a user