diff options
Diffstat (limited to 'src/backend/utils/init/miscinit.c')
-rw-r--r-- | src/backend/utils/init/miscinit.c | 69 |
1 files changed, 54 insertions, 15 deletions
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 2b9ab066185..dc8ae22851c 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.116 2003/09/26 15:27:37 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.116.2.1 2008/01/03 21:25:33 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -235,6 +235,9 @@ SetDataDir(const char *dir) * are implemented. Conceptually there is a stack, whose bottom * is the session user. You are yourself responsible to save and * restore the current user id if you need to change it. + * + * SecurityDefinerContext is TRUE if we are within a SECURITY DEFINER function + * or another context that temporarily changes CurrentUserId. * ---------------------------------------------------------------- */ static AclId AuthenticatedUserId = 0; @@ -243,8 +246,13 @@ static AclId CurrentUserId = 0; static bool AuthenticatedUserIsSuperuser = false; +static bool SecurityDefinerContext = false; + + /* - * This function is relevant for all privilege checks. + * GetUserId - get the current effective user ID. + * + * Note: there's no SetUserId() anymore; use SetUserIdAndContext(). */ AclId GetUserId(void) @@ -254,14 +262,6 @@ GetUserId(void) } -void -SetUserId(AclId newid) -{ - AssertArg(AclIdIsValid(newid)); - CurrentUserId = newid; -} - - /* * This value is only relevant for informational purposes. */ @@ -273,17 +273,57 @@ GetSessionUserId(void) } -void +static void SetSessionUserId(AclId newid) { + AssertState(!SecurityDefinerContext); AssertArg(AclIdIsValid(newid)); SessionUserId = newid; - /* Current user defaults to session user. */ - if (!AclIdIsValid(CurrentUserId)) - CurrentUserId = newid; + CurrentUserId = newid; } +/* + * GetUserIdAndContext/SetUserIdAndContext - get/set the current user ID + * and the SecurityDefinerContext flag. + * + * Unlike GetUserId, GetUserIdAndContext does *not* Assert that the current + * value of CurrentUserId is valid; nor does SetUserIdAndContext require + * the new value to be valid. In fact, these routines had better not + * ever throw any kind of error. This is because they are used by + * StartTransaction and AbortTransaction to save/restore the settings, + * and during the first transaction within a backend, the value to be saved + * and perhaps restored is indeed invalid. We have to be able to get + * through AbortTransaction without asserting in case InitPostgres fails. + */ +void +GetUserIdAndContext(AclId *userid, bool *sec_def_context) +{ + *userid = CurrentUserId; + *sec_def_context = SecurityDefinerContext; +} + +void +SetUserIdAndContext(AclId userid, bool sec_def_context) +{ + CurrentUserId = userid; + SecurityDefinerContext = sec_def_context; +} + + +/* + * InSecurityDefinerContext - are we inside a SECURITY DEFINER context? + */ +bool +InSecurityDefinerContext(void) +{ + return SecurityDefinerContext; +} + + +/* + * Initialize user identity during normal backend startup + */ void InitializeSessionUserId(const char *username) { @@ -378,7 +418,6 @@ SetSessionAuthorization(AclId userid, bool is_superuser) errmsg("permission denied to set session authorization"))); SetSessionUserId(userid); - SetUserId(userid); SetConfigOption("is_superuser", is_superuser ? "on" : "off", |