diff --git a/contrib/babelfishpg_tsql/runtime/functions.c b/contrib/babelfishpg_tsql/runtime/functions.c index ac90df0786..e57eeeda2a 100644 --- a/contrib/babelfishpg_tsql/runtime/functions.c +++ b/contrib/babelfishpg_tsql/runtime/functions.c @@ -1303,11 +1303,13 @@ schema_id(PG_FUNCTION_ARGS) { char *db_name = get_cur_db_name(); const char *user = get_user_for_database(db_name); - const char *guest_role_name = get_guest_role_name(db_name); + char *guest_role_name = get_guest_role_name(db_name); if (!user) { pfree(db_name); + pfree(guest_role_name); + PG_RETURN_NULL(); } else if ((guest_role_name && strcmp(user, guest_role_name) == 0)) @@ -1320,6 +1322,7 @@ schema_id(PG_FUNCTION_ARGS) physical_name = get_physical_schema_name(db_name, name); } pfree(db_name); + pfree(guest_role_name); } else { @@ -2224,15 +2227,18 @@ object_id(PG_FUNCTION_ARGS) * name */ const char *user = get_user_for_database(db_name); - const char *guest_role_name = get_guest_role_name(db_name); + char *guest_role_name = get_guest_role_name(db_name); if (!user) { pfree(db_name); pfree(schema_name); pfree(object_name); + pfree(guest_role_name); + if (object_type) pfree(object_type); + PG_RETURN_NULL(); } else if ((guest_role_name && strcmp(user, guest_role_name) == 0)) @@ -2245,6 +2251,8 @@ object_id(PG_FUNCTION_ARGS) schema_name = get_authid_user_ext_schema_name((const char *) db_name, user); physical_schema_name = get_physical_schema_name(db_name, schema_name); } + + pfree(guest_role_name); } else { @@ -2677,14 +2685,16 @@ type_id(PG_FUNCTION_ARGS) if (!OidIsValid(result)) { /* find the default schema for current user and get physical schema name */ - const char *user = get_user_for_database(db_name); - const char *guest_role_name = get_guest_role_name(db_name); + const char *user = get_user_for_database(db_name); + char *guest_role_name = get_guest_role_name(db_name); if (!user) { pfree(db_name); pfree(schema_name); pfree(object_name); + pfree(guest_role_name); + PG_RETURN_NULL(); } else if ((guest_role_name && strcmp(user, guest_role_name) == 0)) @@ -2697,6 +2707,8 @@ type_id(PG_FUNCTION_ARGS) schema_name = get_authid_user_ext_schema_name((const char *) db_name, user); physical_schema_name = get_physical_schema_name(db_name, schema_name); } + + pfree(guest_role_name); } else { @@ -2826,20 +2838,20 @@ replace_special_chars_fts(PG_FUNCTION_ARGS) Datum has_dbaccess(PG_FUNCTION_ARGS) { - char *db_name = text_to_cstring(PG_GETARG_TEXT_P(0)); + char *db_name = text_to_cstring(PG_GETARG_TEXT_P(0)); /* * Ensure the database name input argument is lower-case, as all Babel * table names are lower-case */ - char *lowercase_db_name = lowerstr(db_name); + char *lowercase_db_name = lowerstr(db_name); /* Also strip trailing whitespace to mimic SQL Server behaviour */ - int i; - const char *user = NULL; - const char *login; - int16 db_id; - bool login_is_db_owner; + int i; + char *user = NULL; + const char *login; + int16 db_id; + bool login_is_db_owner; i = strlen(lowercase_db_name); while (i > 0 && isspace((unsigned char) lowercase_db_name[i - 1])) @@ -2885,7 +2897,10 @@ has_dbaccess(PG_FUNCTION_ARGS) if (!user) PG_RETURN_INT32(0); else + { + pfree(user); PG_RETURN_INT32(1); + } } Datum diff --git a/contrib/babelfishpg_tsql/src/catalog.c b/contrib/babelfishpg_tsql/src/catalog.c index 1c2db7f299..f016db8041 100644 --- a/contrib/babelfishpg_tsql/src/catalog.c +++ b/contrib/babelfishpg_tsql/src/catalog.c @@ -3041,7 +3041,7 @@ update_user_catalog_for_guest(PG_FUNCTION_ARGS) bool guest_role_exists_for_db(const char *dbname) { - const char *guest_role = get_guest_role_name(dbname); + char *guest_role = get_guest_role_name(dbname); bool role_exists = false; HeapTuple tuple; @@ -3053,6 +3053,8 @@ guest_role_exists_for_db(const char *dbname) ReleaseSysCache(tuple); } + pfree(guest_role); + return role_exists; } @@ -3109,7 +3111,7 @@ get_login_for_user(Oid user_id, const char *physical_schema_name) static void create_guest_role_for_db(const char *dbname) { - const char *guest = get_guest_role_name(dbname); + char *guest = get_guest_role_name(dbname); const char *db_owner_role = get_db_owner_role_name(dbname); List *logins = NIL; List *res; @@ -3195,6 +3197,8 @@ create_guest_role_for_db(const char *dbname) set_cur_db(old_dbid, old_dbname); } PG_END_TRY(); + + pfree(guest); } /* @@ -4659,7 +4663,7 @@ update_babelfish_authid_user_ext_rename_db( Anum_bbf_authid_user_ext_orig_username, bbf_authid_user_ext_dsc, &isNull)); NameData rolename_namedata; - namestrcpy(&rolename_namedata, get_physical_user_name((char *)new_db_name, role_name, true)); + namestrcpy(&rolename_namedata, get_physical_user_name((char *)new_db_name, role_name, true, true)); list_of_roles_to_rename = lappend(list_of_roles_to_rename, pstrdup(role_name)); /* update rolname */ @@ -4938,9 +4942,12 @@ rename_tsql_db(char *old_db_name, char *new_db_name) (strlen(role) == 8 && strncmp(role, "db_owner", 8) == 0))) continue; - old_role_name = get_physical_user_name(old_db_name, role, true); - new_role_name = get_physical_user_name(new_db_name, role, true); + old_role_name = get_physical_user_name(old_db_name, role, true, true); + new_role_name = get_physical_user_name(new_db_name, role, true, true); exec_rename_db_util(old_role_name, new_role_name, false); + + pfree(old_role_name); + pfree(new_role_name); } /* Update the default_database field in babelfish_authid_login_ext. */ @@ -4977,6 +4984,38 @@ rename_tsql_db(char *old_db_name, char *new_db_name) CommitTransactionCommand(); } +/* + * Returns true if the user/role exists in the sys.babelfish_authid_user_ext catalog, + * false otherwise. + */ +bool +user_exists_for_db(const char *db_name, const char *user_name) +{ + HeapTuple tuple_cache; + NameData rolname; + bool user_exists = false; + + namestrcpy(&rolname, user_name); + + tuple_cache = SearchSysCache1(AUTHIDUSEREXTROLENAME, NameGetDatum(&rolname)); + + if (HeapTupleIsValid(tuple_cache)) + { + bool isnull; + char *db_name_from_cache = TextDatumGetCString(SysCacheGetAttr(AUTHIDUSEREXTROLENAME, tuple_cache, + Anum_bbf_authid_user_ext_database_name, &isnull)); + + Assert(!isnull); + + if (strcmp(db_name_from_cache, db_name) == 0) + user_exists = true; + + pfree(db_name_from_cache); + } + + return user_exists; +} + /* * partition_function_id_exists * Returns true if provided function id is in use, false otherwise. diff --git a/contrib/babelfishpg_tsql/src/catalog.h b/contrib/babelfishpg_tsql/src/catalog.h index 2125582eec..ff0248c9fb 100644 --- a/contrib/babelfishpg_tsql/src/catalog.h +++ b/contrib/babelfishpg_tsql/src/catalog.h @@ -162,6 +162,7 @@ extern List *update_babelfish_namespace_ext_nsp_name(int16 db_id, char *new_db_n extern List *update_babelfish_authid_user_ext_db_name(const char *old_db_name, const char *new_db_name); extern void rename_tsql_db(char *old_db_name, char *new_db_name); extern Oid get_login_for_user(Oid user_id, const char *physical_schema_name); +extern bool user_exists_for_db(const char *db_name, const char *user_name); /* MUST comply with babelfish_authid_user_ext table */ typedef struct FormData_authid_user_ext diff --git a/contrib/babelfishpg_tsql/src/dbcmds.c b/contrib/babelfishpg_tsql/src/dbcmds.c index 32369d2d18..4a8f39637e 100644 --- a/contrib/babelfishpg_tsql/src/dbcmds.c +++ b/contrib/babelfishpg_tsql/src/dbcmds.c @@ -450,25 +450,25 @@ check_database_collation_name(const char *database_collation_name) static void create_bbf_db_internal(ParseState *pstate, const char *dbname, List *options, const char *owner, int16 dbid) { - int16 old_dbid; - char *old_dbname; - Oid datdba; - Datum *new_record; - bool *new_record_nulls; - Relation sysdatabase_rel; - HeapTuple tuple; - List *parsetree_list; - ListCell *parsetree_item; - const char *dbo_role; - NameData default_collation; - NameData owner_namedata; - int stmt_number = 0; - int save_sec_context; - bool is_set_userid = false; - Oid save_userid; - const char *old_createrole_self_grant; - ListCell *option; - const char *database_collation_name = NULL; + int16 old_dbid; + char *old_dbname; + Oid datdba; + Datum *new_record; + bool *new_record_nulls; + Relation sysdatabase_rel; + HeapTuple tuple; + List *parsetree_list; + ListCell *parsetree_item; + char *dbo_role; + NameData default_collation; + NameData owner_namedata; + int stmt_number = 0; + int save_sec_context; + bool is_set_userid = false; + Oid save_userid; + const char *old_createrole_self_grant; + ListCell *option; + const char *database_collation_name = NULL; /* Check options */ foreach(option, options) @@ -636,23 +636,25 @@ create_bbf_db_internal(ParseState *pstate, const char *dbname, List *options, co set_cur_db(old_dbid, old_dbname); } PG_END_TRY(); + + pfree(dbo_role); } void drop_bbf_db(const char *dbname, bool missing_ok, bool force_drop) { - volatile Relation sysdatabase_rel; - HeapTuple tuple; - Form_sysdatabases bbf_db; - int16 dbid; - const char *dbo_role; - List *db_users_list; - List *parsetree_list; - ListCell *parsetree_item; - const char *prev_current_user; - int save_sec_context; - bool is_set_userid = false; - Oid save_userid; + volatile Relation sysdatabase_rel; + HeapTuple tuple; + Form_sysdatabases bbf_db; + int16 dbid; + char *dbo_role; + List *db_users_list; + List *parsetree_list; + ListCell *parsetree_item; + const char *prev_current_user; + int save_sec_context; + bool is_set_userid = false; + Oid save_userid; if ((strlen(dbname) == 6 && (strncmp(dbname, "master", 6) == 0)) || ((strlen(dbname) == 6 && strncmp(dbname, "tempdb", 6) == 0)) || @@ -808,6 +810,8 @@ drop_bbf_db(const char *dbname, bool missing_ok, bool force_drop) } PG_END_TRY(); + pfree(dbo_role); + /* Set current user back to previous user */ bbf_set_current_user(prev_current_user); } @@ -1064,8 +1068,8 @@ create_schema_if_not_exists(const uint16 dbid, const char *prev_current_user; uint16 old_dbid; const char *old_dbname, - *phys_schema_name, - *phys_role; + *phys_schema_name; + char *phys_role; /* * During upgrade, the migration mode is reset to single-db so we cannot @@ -1089,7 +1093,7 @@ create_schema_if_not_exists(const uint16 dbid, * some reason guest role does not exist, then that is a bigger problem. * We skip creating the guest schema entirely instead of crashing though. */ - phys_role = get_physical_user_name((char *) dbname, (char *) owner_role, false); + phys_role = get_physical_user_name((char *) dbname, (char *) owner_role, false, true); if (!OidIsValid(get_role_oid(phys_role, true))) { ereport(LOG, @@ -1148,6 +1152,8 @@ create_schema_if_not_exists(const uint16 dbid, } PG_END_TRY(); + pfree(phys_role); + bbf_set_current_user(prev_current_user); set_cur_db(old_dbid, old_dbname); diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 06195b0761..54f3676666 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -5022,8 +5022,8 @@ get_local_schema_for_bbf_functions(Oid proc_nsp_oid) HeapTuple tuple; char *func_schema_name = NULL, *new_search_path = NULL; - const char *func_dbo_schema, - *cur_dbname = get_cur_db_name(); + char *func_dbo_schema; + const char *cur_dbname = get_cur_db_name(); tuple = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(proc_nsp_oid)); @@ -5039,7 +5039,10 @@ get_local_schema_for_bbf_functions(Oid proc_nsp_oid) quote_identifier(func_dbo_schema)); ReleaseSysCache(tuple); + + pfree(func_dbo_schema); } + return new_search_path; } diff --git a/contrib/babelfishpg_tsql/src/multidb.c b/contrib/babelfishpg_tsql/src/multidb.c index 033f2627f4..46e8c6dfab 100644 --- a/contrib/babelfishpg_tsql/src/multidb.c +++ b/contrib/babelfishpg_tsql/src/multidb.c @@ -254,7 +254,7 @@ rewrite_object_refs(Node *stmt) * Try to get physical granted role name, see if it's an * existing db role */ - physical_role_name = get_physical_user_name(db_name, role_name, false); + physical_role_name = get_physical_user_name(db_name, role_name, false, true); if (get_role_oid(physical_role_name, true) == InvalidOid) break; @@ -273,7 +273,7 @@ rewrite_object_refs(Node *stmt) pfree(granted->priv_name); granted->priv_name = physical_role_name; - physical_principal_name = get_physical_user_name(db_name, principal_name, false); + physical_principal_name = get_physical_user_name(db_name, principal_name, false, true); pfree(grantee->rolename); grantee->rolename = physical_principal_name; @@ -343,7 +343,7 @@ rewrite_object_refs(Node *stmt) char *user_name; char *db_name = get_cur_db_name(); - user_name = get_physical_user_name(db_name, create_role->role, false); + user_name = get_physical_user_name(db_name, create_role->role, false, true); pfree(create_role->role); create_role->role = user_name; @@ -394,7 +394,7 @@ rewrite_object_refs(Node *stmt) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("Cannot alter the user %s", user_name))); - physical_user_name = get_physical_user_name(db_name, user_name, false); + physical_user_name = get_physical_user_name(db_name, user_name, false, false); pfree(alter_role->role->rolename); alter_role->role->rolename = physical_user_name; } @@ -1034,8 +1034,11 @@ static void rewrite_role_name(RoleSpec *role) { char *cur_db = get_cur_db_name(); + char *temp_rolename = get_physical_user_name(cur_db, role->rolename, false, false); - role->rolename = get_physical_user_name(cur_db, role->rolename, false); + pfree(role->rolename); + role->rolename = temp_rolename; + pfree(cur_db); } bool @@ -1271,12 +1274,14 @@ get_physical_schema_name(char *db_name, const char *schema_name) * Map the logical user name to its physical name in the database. */ char * -get_physical_user_name(char *db_name, char *user_name, bool suppress_error) +get_physical_user_name(char *db_name, char *user_name, bool suppress_db_error, bool suppress_role_error) { char *new_user_name; char *result; int len; + Assert(db_name != NULL); + if (!user_name) return NULL; @@ -1284,7 +1289,7 @@ get_physical_user_name(char *db_name, char *user_name, bool suppress_error) if (len == 0) return NULL; - if (!DbidIsValid(get_db_id(db_name)) && !suppress_error) + if (!suppress_db_error && !DbidIsValid(get_db_id(db_name))) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("database \"%s\" does not exist.", db_name))); @@ -1309,8 +1314,9 @@ get_physical_user_name(char *db_name, char *user_name, bool suppress_error) (strlen(db_name) != 6 || (strncmp(db_name, "tempdb", 6) != 0)) && (strlen(db_name) != 4 || (strncmp(db_name, "msdb", 4) != 0))) { - if ((strlen(user_name) == 3 && strncmp(user_name, "dbo", 3) == 0) || - (strlen(user_name) == 8 && strncmp(user_name, "db_owner", 8) == 0)) + if (((strlen(user_name) == 3 && strncmp(user_name, "dbo", 3) == 0) || + (strlen(user_name) == 8 && strncmp(user_name, "db_owner", 8) == 0)) + && (suppress_role_error || user_exists_for_db(db_name, new_user_name))) { return new_user_name; } @@ -1324,116 +1330,117 @@ get_physical_user_name(char *db_name, char *user_name, bool suppress_error) /* Truncate final result to 64 bytes */ truncate_tsql_identifier(result); + /* + * If the user or role is not found in the sys.babelfish_authid_user_ext + * catalog, then an error is thrown. The 'suppress_role_error' flag indicates if + * it is ok for the user or role to be absent from the catalog. + */ + if(!suppress_role_error && !user_exists_for_db(db_name, result)) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("User or role \"%s\" does not exist", new_user_name))); + } + + pfree(new_user_name); + return result; } -const char * +char * get_dbo_schema_name(const char *dbname) { - if (0 == strcmp(dbname, "master")) - return "master_dbo"; - if (0 == strcmp(dbname, "tempdb")) - return "tempdb_dbo"; - if (0 == strcmp(dbname, "msdb")) - return "msdb_dbo"; - if (SINGLE_DB == get_migration_mode()) - return "dbo"; + char *name = palloc0(MAX_BBF_NAMEDATALEND); + + Assert(dbname != NULL); + + if (SINGLE_DB == get_migration_mode() && 0 != strcmp(dbname, "master") + && 0 != strcmp(dbname, "tempdb") && 0 != strcmp(dbname, "msdb")) + { + snprintf(name, MAX_BBF_NAMEDATALEND, "%s", "dbo"); + } else { - char *name = palloc0(MAX_BBF_NAMEDATALEND); - snprintf(name, MAX_BBF_NAMEDATALEND, "%s_dbo", dbname); truncate_identifier(name, strlen(name), false); - return name; } + return name; } -const char * +char * get_dbo_role_name(const char *dbname) { - if (0 == strcmp(dbname, "master")) - return "master_dbo"; - if (0 == strcmp(dbname, "tempdb")) - return "tempdb_dbo"; - if (0 == strcmp(dbname, "msdb")) - return "msdb_dbo"; - if (SINGLE_DB == get_migration_mode()) - return "dbo"; + char *name = palloc0(MAX_BBF_NAMEDATALEND); + + Assert(dbname != NULL); + + if (SINGLE_DB == get_migration_mode() && 0 != strcmp(dbname, "master") + && 0 != strcmp(dbname, "tempdb") && 0 != strcmp(dbname, "msdb")) + { + snprintf(name, MAX_BBF_NAMEDATALEND, "%s", "dbo"); + } else { - char *name = palloc0(MAX_BBF_NAMEDATALEND); - snprintf(name, MAX_BBF_NAMEDATALEND, "%s_dbo", dbname); truncate_identifier(name, strlen(name), false); - return name; } + return name; } -const char * +char * get_db_owner_name(const char *dbname) { - if (0 == strcmp(dbname, "master")) - return "master_db_owner"; - if (0 == strcmp(dbname, "tempdb")) - return "tempdb_db_owner"; - if (0 == strcmp(dbname, "msdb")) - return "msdb_db_owner"; - if (SINGLE_DB == get_migration_mode()) - return "db_owner"; + char *name = palloc0(MAX_BBF_NAMEDATALEND); + + Assert(dbname != NULL); + + if (SINGLE_DB == get_migration_mode() && 0 != strcmp(dbname, "master") + && 0 != strcmp(dbname, "tempdb") && 0 != strcmp(dbname, "msdb")) + { + snprintf(name, MAX_BBF_NAMEDATALEND, "%s", "db_owner"); + } else { - char *name = palloc0(MAX_BBF_NAMEDATALEND); - snprintf(name, MAX_BBF_NAMEDATALEND, "%s_db_owner", dbname); truncate_identifier(name, strlen(name), false); - return name; } + return name; } -const char * +char * get_guest_role_name(const char *dbname) { - if (0 == strcmp(dbname, "master")) - return "master_guest"; - if (0 == strcmp(dbname, "tempdb")) - return "tempdb_guest"; - if (0 == strcmp(dbname, "msdb")) - return "msdb_guest"; + char *name = palloc0(MAX_BBF_NAMEDATALEND); + + Assert(dbname != NULL); /* * Always prefix with dbname regardless if single or multidb. Note that * dbo is an exception. */ - else - { - char *name = palloc0(MAX_BBF_NAMEDATALEND); - - snprintf(name, MAX_BBF_NAMEDATALEND, "%s_guest", dbname); - truncate_identifier(name, strlen(name), false); - return name; - } + snprintf(name, MAX_BBF_NAMEDATALEND, "%s_guest", dbname); + truncate_identifier(name, strlen(name), false); + return name; } -const char * +char * get_guest_schema_name(const char *dbname) { - if (0 == strcmp(dbname, "master")) - return "master_guest"; - if (0 == strcmp(dbname, "tempdb")) - return "tempdb_guest"; - if (0 == strcmp(dbname, "msdb")) - return "msdb_guest"; + char *name = palloc0(MAX_BBF_NAMEDATALEND); - if (SINGLE_DB == get_migration_mode()) - return "guest"; + Assert(dbname != NULL); + + if (SINGLE_DB == get_migration_mode() && 0 != strcmp(dbname, "master") + && 0 != strcmp(dbname, "tempdb") && 0 != strcmp(dbname, "msdb")) + { + snprintf(name, MAX_BBF_NAMEDATALEND, "%s", "guest"); + } else { - char *name = palloc0(MAX_BBF_NAMEDATALEND); - snprintf(name, MAX_BBF_NAMEDATALEND, "%s_guest", dbname); truncate_identifier(name, strlen(name), false); - return name; } + return name; } bool diff --git a/contrib/babelfishpg_tsql/src/multidb.h b/contrib/babelfishpg_tsql/src/multidb.h index 8312f9ade6..51d7a87456 100644 --- a/contrib/babelfishpg_tsql/src/multidb.h +++ b/contrib/babelfishpg_tsql/src/multidb.h @@ -17,14 +17,14 @@ extern void rewrite_object_refs(Node *stmt); extern List* rewrite_plain_name(List *name); /* Value Strings */ /* helper functions */ -extern char *get_physical_user_name(char *db_name, char *user_name, bool suppress_error); +extern char *get_physical_user_name(char *db_name, char *user_name, bool suppress_db_error, bool suppress_role_error); extern char *get_physical_schema_name(char *db_name, const char *schema_name); extern char *get_physical_schema_name_by_mode(char *db_name, const char *schema_name, MigrationMode mode); -extern const char *get_dbo_schema_name(const char *dbname); -extern const char *get_dbo_role_name(const char *dbname); -extern const char *get_db_owner_name(const char *dbname); -extern const char *get_guest_role_name(const char *dbname); -extern const char *get_guest_schema_name(const char *dbname); +extern char *get_dbo_schema_name(const char *dbname); +extern char *get_dbo_role_name(const char *dbname); +extern char *get_db_owner_name(const char *dbname); +extern char *get_guest_role_name(const char *dbname); +extern char *get_guest_schema_name(const char *dbname); extern bool is_shared_schema(const char *name); extern void truncate_tsql_identifier(char *ident); extern bool physical_schema_name_exists(char *phys_schema_name); diff --git a/contrib/babelfishpg_tsql/src/pl_exec-2.c b/contrib/babelfishpg_tsql/src/pl_exec-2.c index 43b4ae8ddc..59f0069736 100644 --- a/contrib/babelfishpg_tsql/src/pl_exec-2.c +++ b/contrib/babelfishpg_tsql/src/pl_exec-2.c @@ -3212,31 +3212,29 @@ void exec_stmt_dbcc_checkident(PLtsql_stmt_dbcc *stmt) struct dbcc_checkident dbcc_stmt = stmt->dbcc_stmt_data.dbcc_checkident; Relation rel; TupleDesc tupdesc; - char *db_name = NULL; - char *max_identity_value_str = NULL; - char *query = NULL; - char *attname; - char *token; + char *db_name = NULL; + char *max_identity_value_str = NULL; + char *query = NULL; + char *attname; + char *token; const char *schema_name; - const char *nsp_name; + char *nsp_name; const char *user; - const char *guest_role_name; - const char *dbo_role_name; const char *login; - int64 max_identity_value = 0; - int64 cur_identity_value = 0; - int attnum; - int rc = 0; - int64 reseed_value = 0; - Oid nsp_oid; - Oid table_oid; - Oid seqid = InvalidOid; - Oid current_user_id = GetUserId(); - volatile bool cur_value_is_null = true; - bool login_is_db_owner; + int64 max_identity_value = 0; + int64 cur_identity_value = 0; + int attnum; + int rc = 0; + int64 reseed_value = 0; + Oid nsp_oid; + Oid table_oid; + Oid seqid = InvalidOid; + Oid current_user_id = GetUserId(); + volatile bool cur_value_is_null = true; + bool login_is_db_owner; StringInfoData msg; - bool is_float_value; - bool is_cross_db = false; + bool is_float_value; + bool is_cross_db = false; if(dbcc_stmt.new_reseed_value) @@ -3310,8 +3308,8 @@ void exec_stmt_dbcc_checkident(PLtsql_stmt_dbcc *stmt) * If schema_name is not provided, find default schema for current user * and get physical schema name */ - guest_role_name = get_guest_role_name(db_name); - dbo_role_name = get_dbo_role_name(db_name); + char *guest_role_name = get_guest_role_name(db_name); + char *dbo_role_name = get_dbo_role_name(db_name); /* user will never be null here as cross-db calls are already handled */ Assert(user != NULL); @@ -3329,6 +3327,9 @@ void exec_stmt_dbcc_checkident(PLtsql_stmt_dbcc *stmt) { nsp_name = get_physical_schema_name(db_name, schema_name); } + + pfree(guest_role_name); + pfree(dbo_role_name); } pfree(db_name); @@ -3384,6 +3385,8 @@ void exec_stmt_dbcc_checkident(PLtsql_stmt_dbcc *stmt) errmsg("'%s.%s' does not contain an identity column.", nsp_name, dbcc_stmt.table_name))); } + + pfree(nsp_name); PG_TRY(); { @@ -3760,7 +3763,7 @@ exec_stmt_grantschema(PLtsql_execstate *estate, PLtsql_stmt_grantschema *stmt) Oid role_oid; bool is_public = 0 == strcmp(grantee_name, PUBLIC_ROLE_NAME); if (!is_public) - rolname = get_physical_user_name(dbname, grantee_name, false); + rolname = get_physical_user_name(dbname, grantee_name, false, true); else rolname = pstrdup(PUBLIC_ROLE_NAME); role_oid = get_role_oid(rolname, true); diff --git a/contrib/babelfishpg_tsql/src/pl_exec.c b/contrib/babelfishpg_tsql/src/pl_exec.c index e23ad310ea..d0a0673112 100644 --- a/contrib/babelfishpg_tsql/src/pl_exec.c +++ b/contrib/babelfishpg_tsql/src/pl_exec.c @@ -10227,7 +10227,7 @@ reset_search_path(PLtsql_stmt_execsql *stmt, char **old_search_path, bool *reset char *cur_dbname = get_cur_db_name(); char *new_search_path; char *physical_schema; - const char *dbo_schema; + char *dbo_schema = NULL; top_es_entry = exec_state_call_stack->next; @@ -10291,7 +10291,10 @@ reset_search_path(PLtsql_stmt_execsql *stmt, char **old_search_path, bool *reset (void) set_config_option("search_path", new_search_path, PGC_USERSET, PGC_S_SESSION, GUC_ACTION_SAVE, true, 0, false); + pfree(new_search_path); + pfree(dbo_schema); + return true; } else if (top_es_entry->estate->db_name != NULL && stmt->is_ddl) @@ -10343,6 +10346,8 @@ reset_search_path(PLtsql_stmt_execsql *stmt, char **old_search_path, bool *reset PGC_USERSET, PGC_S_SESSION, GUC_ACTION_SAVE, true, 0, false); pfree(new_search_path); + pfree(dbo_schema); + return true; } } @@ -10374,10 +10379,13 @@ reset_search_path(PLtsql_stmt_execsql *stmt, char **old_search_path, bool *reset PGC_USERSET, PGC_S_SESSION, GUC_ACTION_SAVE, true, 0, false); pfree(new_search_path); + pfree(dbo_schema); + return true; } pfree(cur_dbname); + return false; } diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 3d64d0d3d6..62fe5f6a9d 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -2924,13 +2924,15 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } else if (isuser || isrole) { - const char *db_owner_name; + char *db_owner_name; db_owner_name = get_db_owner_name(get_cur_db_name()); if (!has_privs_of_role(GetUserId(),get_role_oid(db_owner_name, false))) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("User does not have permission to perform this action."))); + + pfree(db_owner_name); } /* @@ -3202,7 +3204,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } else if (isuser || isrole) { - const char *dbo_name; + char *dbo_name; char *db_name; char *user_name; char *cur_user; @@ -3283,6 +3285,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, set_session_properties(db_name); pfree(cur_user); pfree(db_name); + pfree(dbo_name); return; } @@ -3331,17 +3334,17 @@ bbf_ProcessUtility(PlannedStmt *pstmt, { foreach(item, stmt->roles) { - RoleSpec *rolspec = lfirst(item); - char *user_name; - const char *db_principal_type = drop_user ? "user" : "role"; - const char *db_owner_name; - int role_oid; - int rolename_len; + RoleSpec *rolspec = lfirst(item); + char *user_name; + const char *db_principal_type = drop_user ? "user" : "role"; + char *db_owner_name; + int role_oid; + int rolename_len; bool is_tsql_db_principal = false; bool is_psql_db_principal = false; - Oid dbowner; + Oid dbowner; - user_name = get_physical_user_name(db_name, rolspec->rolename, false); + user_name = get_physical_user_name(db_name, rolspec->rolename, false, true); db_owner_name = get_db_owner_name(db_name); dbowner = get_role_oid(db_owner_name, false); role_oid = get_role_oid(user_name, true); @@ -3397,6 +3400,9 @@ bbf_ProcessUtility(PlannedStmt *pstmt, errmsg("Cannot disable access to the guest user in master or tempdb."))); alter_user_can_connect(false, rolspec->rolename, db_name); + + pfree(db_owner_name); + return; } else @@ -3407,6 +3413,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } pfree(rolspec->rolename); + pfree(db_owner_name); + rolspec->rolename = user_name; } } diff --git a/contrib/babelfishpg_tsql/src/pltsql_utils.c b/contrib/babelfishpg_tsql/src/pltsql_utils.c index 53dfc7ccf5..ccb5440b44 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_utils.c +++ b/contrib/babelfishpg_tsql/src/pltsql_utils.c @@ -46,7 +46,7 @@ extern bool babelfish_dump_restore; extern char *get_cur_db_name(void); extern char *construct_unique_index_name(char *index_name, char *relation_name); extern char *get_physical_schema_name(char *db_name, const char *schema_name); -extern const char *get_dbo_schema_name(const char *dbname); +extern char *get_dbo_schema_name(const char *dbname); PG_FUNCTION_INFO_V1(split_identifier_internal); /* To cache oid of sys.varchar */ diff --git a/contrib/babelfishpg_tsql/src/procedures.c b/contrib/babelfishpg_tsql/src/procedures.c index e814546869..6d95de49f8 100644 --- a/contrib/babelfishpg_tsql/src/procedures.c +++ b/contrib/babelfishpg_tsql/src/procedures.c @@ -1705,13 +1705,12 @@ create_xp_qv_in_master_dbo_internal(PG_FUNCTION_ARGS) char *tempq = "CREATE OR REPLACE PROCEDURE %s.xp_qv(IN SYS.NVARCHAR(256), IN SYS.NVARCHAR(256))" "AS \'babelfishpg_tsql\', \'xp_qv_internal\' LANGUAGE C"; - const char *dbo_scm = get_dbo_schema_name("master"); - - if (dbo_scm == NULL) - elog(ERROR, "Failed to retrieve dbo schema name"); + char *dbo_scm = get_dbo_schema_name("master"); query = psprintf(tempq, dbo_scm); + pfree(dbo_scm); + PG_TRY(); { if ((rc = SPI_connect()) != SPI_OK_CONNECT) @@ -1795,14 +1794,13 @@ create_xp_instance_regread_in_master_dbo_internal(PG_FUNCTION_ARGS) char *tempq2 = "CREATE OR REPLACE PROCEDURE %s.xp_instance_regread(IN p1 sys.nvarchar(512), IN p2 sys.sysname, IN p3 sys.nvarchar(512), INOUT out_param sys.nvarchar(512))" "AS \'babelfishpg_tsql\', \'xp_instance_regread_internal\' LANGUAGE C"; - const char *dbo_scm = get_dbo_schema_name("master"); - - if (dbo_scm == NULL) - elog(ERROR, "Failed to retrieve dbo schema name"); + char *dbo_scm = get_dbo_schema_name("master"); query = psprintf(tempq, dbo_scm); query2 = psprintf(tempq2, dbo_scm); + pfree(dbo_scm); + PG_TRY(); { if ((rc = SPI_connect()) != SPI_OK_CONNECT) @@ -2137,8 +2135,9 @@ sp_addrole(PG_FUNCTION_ARGS) errmsg("'%s' is not a valid name because it contains invalid characters.", rolname))); /* Map the logical role name to its physical name in the database. */ - physical_role_name = get_physical_user_name(get_cur_db_name(), lowercase_rolname, false); + physical_role_name = get_physical_user_name(get_cur_db_name(), lowercase_rolname, false, true); role_oid = get_role_oid(physical_role_name, true); + pfree(physical_role_name); /* Check if the user, group or role already exists */ if (role_oid) @@ -2280,8 +2279,9 @@ sp_droprole(PG_FUNCTION_ARGS) errmsg("Name cannot be NULL."))); /* Map the logical role name to its physical name in the database. */ - physical_role_name = get_physical_user_name(get_cur_db_name(), lowercase_rolname, false); + physical_role_name = get_physical_user_name(get_cur_db_name(), lowercase_rolname, false, true); role_oid = get_role_oid(physical_role_name, true); + pfree(physical_role_name); /* Check if the role does not exists */ if (role_oid == InvalidOid || !is_role(role_oid)) @@ -2430,7 +2430,7 @@ sp_addrolemember(PG_FUNCTION_ARGS) errmsg("Cannot make a role a member of itself."))); /* Map the logical member name to its physical name in the database. */ - physical_member_name = get_physical_user_name(get_cur_db_name(), lowercase_membername, false); + physical_member_name = get_physical_user_name(get_cur_db_name(), lowercase_membername, false, true); member_oid = get_role_oid(physical_member_name, true); /* @@ -2443,7 +2443,7 @@ sp_addrolemember(PG_FUNCTION_ARGS) errmsg("User or role '%s' does not exist in this database.", membername))); /* Map the logical role name to its physical name in the database. */ - physical_role_name = get_physical_user_name(get_cur_db_name(), lowercase_rolname, false); + physical_role_name = get_physical_user_name(get_cur_db_name(), lowercase_rolname, false, true); role_oid = get_role_oid(physical_role_name, true); /* Check if the role does not exists and given role name is an role */ @@ -2502,6 +2502,8 @@ sp_addrolemember(PG_FUNCTION_ARGS) set_config_option("babelfishpg_tsql.sql_dialect", saved_dialect, GUC_CONTEXT_CONFIG, PGC_S_SESSION, GUC_ACTION_SAVE, true, 0, false); + pfree(physical_member_name); + pfree(physical_role_name); PG_RETURN_VOID(); } @@ -2595,7 +2597,7 @@ sp_droprolemember(PG_FUNCTION_ARGS) errmsg("Name cannot be NULL."))); /* Map the logical role name to its physical name in the database. */ - physical_name = get_physical_user_name(get_cur_db_name(), lowercase_rolname, false); + physical_name = get_physical_user_name(get_cur_db_name(), lowercase_rolname, false, true); role_oid = get_role_oid(physical_name, true); /* Throw an error id the given role name doesn't exist or isn't a role */ @@ -2605,7 +2607,8 @@ sp_droprolemember(PG_FUNCTION_ARGS) errmsg("Cannot alter the role '%s', because it does not exist or you do not have permission.", rolname))); /* Map the logical member name to its physical name in the database. */ - physical_name = get_physical_user_name(get_cur_db_name(), lowercase_membername, false); + pfree(physical_name); + physical_name = get_physical_user_name(get_cur_db_name(), lowercase_membername, false, true); role_oid = get_role_oid(physical_name, true); /* @@ -2661,6 +2664,7 @@ sp_droprolemember(PG_FUNCTION_ARGS) set_config_option("babelfishpg_tsql.sql_dialect", saved_dialect, GUC_CONTEXT_CONFIG, PGC_S_SESSION, GUC_ACTION_SAVE, true, 0, false); + pfree(physical_name); PG_RETURN_VOID(); } @@ -3358,7 +3362,7 @@ sp_babelfish_volatility(PG_FUNCTION_ARGS) if (!strcmp(logical_schema_name, "")) { const char *user = get_user_for_database(db_name); - const char *guest_role_name = get_guest_role_name(db_name); + char *guest_role_name = get_guest_role_name(db_name); if (!user) ereport(ERROR, @@ -3376,6 +3380,8 @@ sp_babelfish_volatility(PG_FUNCTION_ARGS) physical_schema_name = get_physical_schema_name(db_name, logical_schema_name); pfree(logical_schema_name); } + + pfree(guest_role_name); } else { diff --git a/contrib/babelfishpg_tsql/src/rolecmds.c b/contrib/babelfishpg_tsql/src/rolecmds.c index aab521f3cf..136a97b1a4 100644 --- a/contrib/babelfishpg_tsql/src/rolecmds.c +++ b/contrib/babelfishpg_tsql/src/rolecmds.c @@ -518,13 +518,16 @@ grant_guests_to_login(const char *login) &is_null); const char *db_name = TextDatumGetCString(db_name_datum); - const char *guest_name = NULL; + char *guest_name = NULL; if (guest_role_exists_for_db(db_name)) guest_name = get_guest_role_name(db_name); if (guest_name) + { guests = lappend(guests, make_accesspriv_node(guest_name)); + pfree(guest_name); + } tuple = heap_getnext(scan, ForwardScanDirection); } @@ -587,7 +590,7 @@ grant_revoke_dbo_to_login(const char* login, const char* db_name, bool is_grant) Node *stmt; PlannedStmt *wrapper; - const char *dbo_role_name = get_dbo_role_name(db_name); + char *dbo_role_name = get_dbo_role_name(db_name); /* * If login i.e old_owner/new_owner is master user @@ -647,6 +650,7 @@ grant_revoke_dbo_to_login(const char* login, const char* db_name, bool is_grant) CommandCounterIncrement(); pfree(query.data); + pfree(dbo_role_name); } static List * @@ -825,7 +829,7 @@ user_id(PG_FUNCTION_ARGS) if (!db_name) PG_RETURN_NULL(); - user_name = get_physical_user_name(db_name, user_input, false); + user_name = get_physical_user_name(db_name, user_input, false, true); if (!user_name) PG_RETURN_NULL(); @@ -842,6 +846,7 @@ user_id(PG_FUNCTION_ARGS) } auth_tuple = SearchSysCache1(AUTHNAME, CStringGetDatum(user_name)); + pfree(user_name); if (!HeapTupleIsValid(auth_tuple)) PG_RETURN_NULL(); @@ -1319,10 +1324,10 @@ add_existing_users_to_catalog(PG_FUNCTION_ARGS) while (HeapTupleIsValid(tuple)) { Datum db_name_datum; - const char *db_name; - const char *dbo_role; - const char *db_owner_role; - const char *guest; + const char *db_name; + char *dbo_role; + char *db_owner_role; + char *guest; db_name_datum = heap_getattr(tuple, Anum_sysdatabases_name, @@ -1339,9 +1344,13 @@ add_existing_users_to_catalog(PG_FUNCTION_ARGS) { dbo_list = lappend(dbo_list, make_rolespec_node(dbo_role)); add_to_bbf_authid_user_ext(dbo_role, "dbo", db_name, "dbo", NULL, false, true, false); + pfree(dbo_role); } if (db_owner_role) + { add_to_bbf_authid_user_ext(db_owner_role, "db_owner", db_name, NULL, NULL, true, true, false); + pfree(db_owner_role); + } if (guest) { /* @@ -1352,6 +1361,8 @@ add_existing_users_to_catalog(PG_FUNCTION_ARGS) add_to_bbf_authid_user_ext(guest, "guest", db_name, NULL, NULL, false, true, false); else add_to_bbf_authid_user_ext(guest, "guest", db_name, NULL, NULL, false, false, false); + + pfree(guest); } tuple = heap_getnext(scan, ForwardScanDirection); @@ -1519,7 +1530,7 @@ alter_bbf_authid_user_ext(AlterRoleStmt *stmt) /* update user name */ if (new_user_name) { - physical_name = get_physical_user_name(get_cur_db_name(), new_user_name, false); + physical_name = get_physical_user_name(get_cur_db_name(), new_user_name, false, true); namestrcpy(&physical_name_namedata, physical_name); new_record_user_ext[USER_EXT_ROLNAME] = NameGetDatum(&physical_name_namedata); @@ -1612,6 +1623,7 @@ alter_bbf_authid_user_ext(AlterRoleStmt *stmt) NULL); pfree(query.data); + pfree(physical_name); } } @@ -1869,9 +1881,10 @@ role_id(PG_FUNCTION_ARGS) if (!get_cur_db_name()) PG_RETURN_NULL(); - role_name = get_physical_user_name(get_cur_db_name(), user_input, false); + role_name = get_physical_user_name(get_cur_db_name(), user_input, false, true); result = get_role_oid(role_name, true); + pfree(role_name); if (result == InvalidOid) PG_RETURN_NULL(); @@ -1891,14 +1904,14 @@ is_rolemember(PG_FUNCTION_ARGS) Oid cur_user_oid = GetUserId(); Oid db_owner_oid; Oid dbo_role_oid; - char *role; - char *dc_role; - char *dc_principal = NULL; - char *physical_role_name; - char *physical_principal_name; - char *cur_db_name; - const char *db_owner_name; - const char *dbo_role_name; + char *role; + char *dc_role; + char *dc_principal = NULL; + char *physical_role_name; + char *physical_principal_name; + char *cur_db_name; + char *db_owner_name; + char *dbo_role_name; int idx; if (PG_ARGISNULL(0)) @@ -1910,8 +1923,9 @@ is_rolemember(PG_FUNCTION_ARGS) while (idx > 0 && isspace((unsigned char) role[idx - 1])) role[--idx] = '\0'; dc_role = downcase_identifier(role, strlen(role), false, false); - physical_role_name = get_physical_user_name(get_cur_db_name(), dc_role, false); + physical_role_name = get_physical_user_name(get_cur_db_name(), dc_role, false, true); role_oid = get_role_oid(physical_role_name, true); + pfree(physical_role_name); /* If principal name is NULL, take current user instead */ if (PG_ARGISNULL(1)) @@ -1925,8 +1939,9 @@ is_rolemember(PG_FUNCTION_ARGS) while (idx > 0 && isspace((unsigned char) principal[idx - 1])) principal[--idx] = '\0'; dc_principal = downcase_identifier(principal, strlen(principal), false, false); - physical_principal_name = get_physical_user_name(get_cur_db_name(), dc_principal, false); + physical_principal_name = get_physical_user_name(get_cur_db_name(), dc_principal, false, true); principal_oid = get_role_oid(physical_principal_name, true); + pfree(physical_principal_name); } /* Return 1 if given role is PUBLIC */ @@ -1963,6 +1978,10 @@ is_rolemember(PG_FUNCTION_ARGS) dbo_role_name = get_dbo_role_name(cur_db_name); db_owner_oid = get_role_oid(db_owner_name, false); dbo_role_oid = get_role_oid(dbo_role_name, false); + + pfree(db_owner_name); + pfree(dbo_role_name); + if ((principal_oid == db_owner_oid) || (principal_oid == dbo_role_oid)) PG_RETURN_INT32(0); else if (is_member_of_role_nosuper(principal_oid, role_oid)) diff --git a/contrib/babelfishpg_tsql/src/session.c b/contrib/babelfishpg_tsql/src/session.c index 4b10ce4de8..0470d0d0cd 100644 --- a/contrib/babelfishpg_tsql/src/session.c +++ b/contrib/babelfishpg_tsql/src/session.c @@ -165,11 +165,11 @@ set_cur_user_db_and_path(const char *db_name) static void set_search_path_for_user_schema(const char *db_name, const char *user) { - const char *path; - const char *buffer = "%s, \"$user\", sys, pg_catalog"; - const char *physical_schema; - const char *dbo_role_name = get_dbo_role_name(db_name); - const char *guest_role_name = get_guest_role_name(db_name); + const char *path; + const char *buffer = "%s, \"$user\", sys, pg_catalog"; + char *physical_schema; + char *dbo_role_name = get_dbo_role_name(db_name); + char *guest_role_name = get_guest_role_name(db_name); if ((dbo_role_name && strcmp(user, dbo_role_name) == 0)) { @@ -196,6 +196,10 @@ set_search_path_for_user_schema(const char *db_name, const char *user) path, PGC_SUSET, PGC_S_DATABASE_USER); + + pfree(dbo_role_name); + pfree(guest_role_name); + pfree(physical_schema); } /*