Skip to content

Commit

Permalink
Support for DROP LOGIN for windows user
Browse files Browse the repository at this point in the history
  • Loading branch information
Dipesh Dhameliya committed Jan 6, 2023
1 parent 085ab16 commit 0437ab0
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 1 deletion.
2 changes: 2 additions & 0 deletions contrib/babelfishpg_tsql/src/catalog.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ extern int16 get_dbid_from_physical_schema_name(const char *physical_schema_name
#define BBF_AUTHID_LOGIN_EXT_TABLE_NAME "babelfish_authid_login_ext"
#define BBF_AUTHID_LOGIN_EXT_IDX_NAME "babelfish_authid_login_ext_pkey"
#define Anum_bbf_authid_login_ext_rolname 1
#define Anum_bbf_authid_login_ext_type 3
#define Anum_bbf_authid_login_ext_orig_loginname 9
extern Oid bbf_authid_login_ext_oid;
extern Oid bbf_authid_login_ext_idx_oid;

Expand Down
19 changes: 18 additions & 1 deletion contrib/babelfishpg_tsql/src/pl_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -2833,7 +2833,24 @@ static void bbf_ProcessUtility(PlannedStmt *pstmt,
if (HeapTupleIsValid(tuple))
roleform = (Form_pg_authid) GETSTRUCT(tuple);
else
continue;
{
/* Supplied login name might be in windows format i.e, domain\user form */
tuple = get_roleform_ext(role_name);
if (HeapTupleIsValid(tuple))
{
roleform = (Form_pg_authid) GETSTRUCT(tuple);
/*
* This means that provided login name is in windows format
* so let's update role_name with UPN format.
* TODO: Should we also update rolspec->rolename here?
*/
role_name = pstrdup((roleform->rolname).data);
pfree(rolspec->rolename);
rolspec->rolename = role_name;
}
else
continue;
}

if (is_login(roleform->oid))
all_logins = true;
Expand Down
95 changes: 95 additions & 0 deletions contrib/babelfishpg_tsql/src/rolecmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "utils/catcache.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/formatting.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "utils/timestamp.h"
Expand Down Expand Up @@ -1665,3 +1666,97 @@ is_active_login(Oid role_oid)
return true;
}

/*
* This function is called to convert domain\user to user@DOMAIN
*/
char *
convertToUPN(char* input)
{
char *output = "";
char *pos_slash = NULL;

if ((pos_slash = strchr(input, '\\')) != NULL)
{
/*
* collation aware lower casing and upper casing should be done.
* But which collation should be used?
*/
output = psprintf("%s@%s",
str_tolower(pos_slash + 1, strlen(pos_slash + 1), C_COLLATION_OID),
str_toupper(input, (pos_slash - input), C_COLLATION_OID));
}
return output;
}

/*
* get_roleform_ext - Useful when someone tries to drop login and that login is in
* the form of windows formate i.e, domain\user
*/
HeapTuple
get_roleform_ext(char *login)
{
Relation bbf_authid_login_ext_rel;
HeapTuple tuple;
ScanKeyData scanKey;
SysScanDesc scan;
char *upn_login;
TupleDesc dsc;

if (!strchr(login, '\\'))
return NULL;

upn_login = convertToUPN(login);

/*
* There are two ways to lookup provided windows user in babelfish_authid_login_ext catalog
* 1. Using rolname column - we need to conver provided login to UPN form
* 2. Using orig_loginname column - this is newly added column but
* 1. we need to think upgrade scenario as well.
* 2. Need to create index on that column to have a fast lookup. Alternative is to do
* whole catalog search which can be quite expansive.
*/
// Trying 1st approach in this POC.

/* Fetch the relation sys.babelfish_authid_login_ext */
bbf_authid_login_ext_rel = table_open(get_authid_login_ext_oid(),
RowExclusiveLock);
dsc = RelationGetDescr(bbf_authid_login_ext_rel);

/* Search and drop on the role */
ScanKeyInit(&scanKey,
Anum_bbf_authid_login_ext_rolname,
BTEqualStrategyNumber, F_NAMEEQ,
CStringGetDatum(upn_login));

scan = systable_beginscan(bbf_authid_login_ext_rel,
get_authid_login_ext_idx_oid(),
true, NULL, 1, &scanKey);

tuple = systable_getnext(scan);

if (HeapTupleIsValid(tuple))
{
char *type;
bool isnull = true;
Datum datum = heap_getattr(tuple, Anum_bbf_authid_login_ext_type, dsc, &isnull);
if (isnull)
tuple = NULL;
type = pstrdup(TextDatumGetCString(datum));
/* Not a windows login */
if (strcasecmp(type, "U") != 0)
tuple = NULL;
pfree(type);
}

systable_endscan(scan);
table_close(bbf_authid_login_ext_rel, AccessShareLock);

if (!HeapTupleIsValid(tuple))
return tuple;

/* It is proven that this rolename is indeed windows login */
tuple = SearchSysCache1(AUTHNAME, PointerGetDatum(upn_login));

/* Return tuple even if it is invalid tuple */
return tuple;
}
2 changes: 2 additions & 0 deletions contrib/babelfishpg_tsql/src/rolecmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,7 @@ extern void add_to_bbf_authid_user_ext(const char *user_name,
extern void drop_related_bbf_users(List *db_users);
extern void alter_bbf_authid_user_ext(AlterRoleStmt *stmt);
extern bool is_active_login(Oid role_oid);
extern char *convertToUPN(char* input);
extern HeapTuple get_roleform_ext(char *login);

#endif

0 comments on commit 0437ab0

Please sign in to comment.