@@ -2119,6 +2119,102 @@ bool Security_context::set_user(char *user_arg)
21192119 return user == 0 ;
21202120}
21212121
2122+ #ifndef NO_EMBEDDED_ACCESS_CHECKS
2123+ /* *
2124+ Initialize this security context from the passed in credentials
2125+ and activate it in the current thread.
2126+
2127+ @param[out] backup Save a pointer to the current security context
2128+ in the thread. In case of success it points to the
2129+ saved old context, otherwise it points to NULL.
2130+
2131+
2132+ During execution of a statement, multiple security contexts may
2133+ be needed:
2134+ - the security context of the authenticated user, used as the
2135+ default security context for all top-level statements
2136+ - in case of a view or a stored program, possibly the security
2137+ context of the definer of the routine, if the object is
2138+ defined with SQL SECURITY DEFINER option.
2139+
2140+ The currently "active" security context is parameterized in THD
2141+ member security_ctx. By default, after a connection is
2142+ established, this member points at the "main" security context
2143+ - the credentials of the authenticated user.
2144+
2145+ Later, if we would like to execute some sub-statement or a part
2146+ of a statement under credentials of a different user, e.g.
2147+ definer of a procedure, we authenticate this user in a local
2148+ instance of Security_context by means of this method (and
2149+ ultimately by means of acl_getroot_no_password), and make the
2150+ local instance active in the thread by re-setting
2151+ thd->security_ctx pointer.
2152+
2153+ Note, that the life cycle and memory management of the "main" and
2154+ temporary security contexts are different.
2155+ For the main security context, the memory for user/host/ip is
2156+ allocated on system heap, and the THD class frees this memory in
2157+ its destructor. The only case when contents of the main security
2158+ context may change during its life time is when someone issued
2159+ CHANGE USER command.
2160+ Memory management of a "temporary" security context is
2161+ responsibility of the module that creates it.
2162+
2163+ @retval TRUE there is no user with the given credentials. The erro
2164+ is reported in the thread.
2165+ @retval FALSE success
2166+ */
2167+
2168+ bool
2169+ Security_context::
2170+ change_security_context (THD *thd,
2171+ LEX_STRING *definer_user,
2172+ LEX_STRING *definer_host,
2173+ LEX_STRING *db,
2174+ Security_context **backup)
2175+ {
2176+ bool needs_change;
2177+
2178+ DBUG_ENTER (" Security_context::change_security_context" );
2179+
2180+ DBUG_ASSERT (definer_user->str && definer_host->str );
2181+
2182+ *backup= NULL ;
2183+ /*
2184+ The current security context may have NULL members
2185+ if we have just started the thread and not authenticated
2186+ any user. This use case is currently in events worker thread.
2187+ */
2188+ needs_change= (thd->security_ctx ->priv_user == NULL ||
2189+ strcmp (definer_user->str , thd->security_ctx ->priv_user ) ||
2190+ thd->security_ctx ->priv_host == NULL ||
2191+ my_strcasecmp (system_charset_info, definer_host->str ,
2192+ thd->security_ctx ->priv_host ));
2193+ if (needs_change)
2194+ {
2195+ if (acl_getroot_no_password (this , definer_user->str , definer_host->str ,
2196+ definer_host->str , db->str ))
2197+ {
2198+ my_error (ER_NO_SUCH_USER, MYF (0 ), definer_user->str ,
2199+ definer_host->str );
2200+ DBUG_RETURN (TRUE );
2201+ }
2202+ *backup= thd->security_ctx ;
2203+ thd->security_ctx = this ;
2204+ }
2205+
2206+ DBUG_RETURN (FALSE );
2207+ }
2208+
2209+
2210+ void
2211+ Security_context::restore_security_context (THD *thd,
2212+ Security_context *backup)
2213+ {
2214+ if (backup)
2215+ thd->security_ctx = backup;
2216+ }
2217+ #endif
21222218
21232219/* ***************************************************************************
21242220 Handling of open and locked tables states.
0 commit comments