Changeset: d29fe1016b59 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d29fe1016b59 Modified Files: monetdb5/mal/mal_authorize.c sql/server/rel_distribute.c sql/server/rel_schema.c Branch: remote_auth Log Message:
Implementation of credentials registration in the vault diffs (288 lines): diff --git a/monetdb5/mal/mal_authorize.c b/monetdb5/mal/mal_authorize.c --- a/monetdb5/mal/mal_authorize.c +++ b/monetdb5/mal/mal_authorize.c @@ -42,16 +42,16 @@ static str AUTHdecypherValue(str *ret, const char *value); static str AUTHcypherValue(str *ret, const char *value); static str AUTHverifyPassword(const char *passwd); +static BUN lookupRemoteTableKey(const char *key); static BAT *user = NULL; static BAT *pass = NULL; static BAT *duser = NULL; /* Remote table bats */ -static BAT *rt_uri = NULL; -static BAT *rt_localuser = NULL; +static BAT *rt_key = NULL; static BAT *rt_remoteuser = NULL; -static BAT *rt_pass = NULL; +static BAT *rt_hashedpwd = NULL; static BAT *rt_deleted = NULL; /* yep, the vault key is just stored in memory */ static str vaultKey = NULL; @@ -241,50 +241,43 @@ AUTHinitTables(const char *passwd) { } assert(duser); - /* Remote table authorization columns */ + /* Remote table authorization table. + * + * This table holds the remote tabe authorization credentials + * (username and hashed password). At the creation of a remote + * table, two entries with two different keys are inserted in the + * auth table. + * + * 1. local user name'|'URI, remote username, hashed remote password + * 2. local schema'|'URI, remote username, hashed remote password + * + * The lookup routine will actually do two lookups: first we try + * to match the user requesting access with the user that created + * the table or an administrator. If that fails try to see if the + * user requesting access has access to the local schema where the + * remote table is defined. + */ /* load/create remote table URI BAT */ - bid = BBPindex("M5system_auth_rt_uri"); + bid = BBPindex("M5system_auth_rt_key"); if (!bid) { - rt_uri = COLnew(0, TYPE_str, 256, PERSISTENT); - if (rt_uri == NULL) - throw(MAL, "initTables.rt_uri", SQLSTATE(HY001) MAL_MALLOC_FAIL " remote table uri bat"); + rt_key = COLnew(0, TYPE_str, 256, PERSISTENT); + if (rt_key == NULL) + throw(MAL, "initTables.rt_key", SQLSTATE(HY001) MAL_MALLOC_FAIL " remote table uri bat"); - if (BBPrename(BBPcacheid(rt_uri), "M5system_auth_rt_uri") != 0 || - BATmode(rt_uri, PERSISTENT) != GDK_SUCCEED) - throw(MAL, "initTables.rt_uri", GDK_EXCEPTION); + if (BBPrename(BBPcacheid(rt_key), "M5system_auth_rt_key") != 0 || + BATmode(rt_key, PERSISTENT) != GDK_SUCCEED) + throw(MAL, "initTables.rt_key", GDK_EXCEPTION); if (!isNew) AUTHcommit(); } else { - rt_uri = BATdescriptor(bid); - if (rt_uri == NULL) { - throw(MAL, "initTables.rt_uri", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); + rt_key = BATdescriptor(bid); + if (rt_key == NULL) { + throw(MAL, "initTables.rt_key", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); } isNew = 0; } - assert(rt_uri); - - /* load/create remote table local user name BAT */ - bid = BBPindex("M5system_auth_rt_localuser"); - if (!bid) { - rt_localuser = COLnew(0, TYPE_str, 256, PERSISTENT); - if (rt_localuser == NULL) - throw(MAL, "initTables.rt_localuser", SQLSTATE(HY001) MAL_MALLOC_FAIL " remote table local user bat"); - - if (BBPrename(BBPcacheid(rt_localuser), "M5system_auth_rt_localuser") != 0 || - BATmode(rt_localuser, PERSISTENT) != GDK_SUCCEED) - throw(MAL, "initTables.rt_localuser", GDK_EXCEPTION); - if (!isNew) - AUTHcommit(); - } - else { - rt_localuser = BATdescriptor(bid); - if (rt_localuser == NULL) { - throw(MAL, "initTables.rt_localuser", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); - } - isNew = 0; - } - assert(rt_localuser); + assert(rt_key); /* load/create remote table remote user name BAT */ bid = BBPindex("M5system_auth_rt_remoteuser"); @@ -309,26 +302,26 @@ AUTHinitTables(const char *passwd) { assert(rt_remoteuser); /* load/create remote table password BAT */ - bid = BBPindex("M5system_auth_rt_pass"); + bid = BBPindex("M5system_auth_rt_hashedpwd"); if (!bid) { - rt_pass = COLnew(0, TYPE_str, 256, PERSISTENT); - if (rt_pass == NULL) - throw(MAL, "initTables.rt_pass", SQLSTATE(HY001) MAL_MALLOC_FAIL " remote table local user bat"); + rt_hashedpwd = COLnew(0, TYPE_str, 256, PERSISTENT); + if (rt_hashedpwd == NULL) + throw(MAL, "initTables.rt_hashedpwd", SQLSTATE(HY001) MAL_MALLOC_FAIL " remote table local user bat"); - if (BBPrename(BBPcacheid(rt_pass), "M5system_auth_rt_pass") != 0 || - BATmode(rt_pass, PERSISTENT) != GDK_SUCCEED) - throw(MAL, "initTables.rt_pass", GDK_EXCEPTION); + if (BBPrename(BBPcacheid(rt_hashedpwd), "M5system_auth_rt_hashedpwd") != 0 || + BATmode(rt_hashedpwd, PERSISTENT) != GDK_SUCCEED) + throw(MAL, "initTables.rt_hashedpwd", GDK_EXCEPTION); if (!isNew) AUTHcommit(); } else { - rt_pass = BATdescriptor(bid); - if (rt_pass == NULL) { - throw(MAL, "initTables.rt_pass", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); + rt_hashedpwd = BATdescriptor(bid); + if (rt_hashedpwd == NULL) { + throw(MAL, "initTables.rt_hashedpwd", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); } isNew = 0; } - assert(rt_pass); + assert(rt_hashedpwd); /* load/create remote table deleted entries BAT */ bid = BBPindex("M5system_auth_rt_deleted"); @@ -941,6 +934,24 @@ AUTHverifyPassword(const char *passwd) #endif } +static BUN +lookupRemoteTableKey(const char *key) +{ + BATiter cni = bat_iterator(rt_key); + BUN p = BUN_NONE; + + if (BAThash(rt_key, 0) == GDK_SUCCEED) { + HASHloop_str(cni, cni.b->thash, p, key) { + oid pos = p; + if (BUNfnd(rt_deleted, &pos) == BUN_NONE) + return p; + } + } + + return BUN_NONE; + +} + str AUTHgetRemoteTableCredentials(const char *local_table, Client cntxt, str *uri, str *username, str *password) { @@ -979,6 +990,7 @@ AUTHgetRemoteTableCredentials(const char // rethrow("checkCredentials", tmp, AUTHrequireAdminOrUser(cntxt, localuser)); if (strcmp(local_table, ltbl)) { GDKfree(ltbl); + abort(); throw(MAL, "getRemoteTableCredentials", SQLSTATE(HY001) "URIs do not match"); } @@ -989,39 +1001,64 @@ AUTHgetRemoteTableCredentials(const char } str -AUTHaddRemoteTableCredentials(const char *local_table, const char *localuser, const char *uri, const char *remoteuser, const char *pass, bool pw_encrypted) +AUTHaddRemoteTableCredentials(const char *local_table, const char *local_user, const char *uri, const char *remoteuser, const char *pass, bool pw_encrypted) { - /* Work in Progress */ - FILE *fp = fopen("/tmp/remote_table_auth.txt", "w"); - char *password = NULL; + char *pwhash = NULL; bool free_pw = false; str tmp; + BUN p; if (uri == NULL || strNil(uri)) throw(ILLARG, "addRemoteTableCredentials", "URI cannot be nil"); - if (localuser == NULL || strNil(localuser)) + if (local_user == NULL || strNil(local_user)) throw(ILLARG, "addRemoteTableCredentials", "local user name cannot be nil"); + p = lookupRemoteTableKey(local_table); + + if (p != BUN_NONE) { + /* key already in, just return */ + return MAL_SUCCEED; + } + if (pass == NULL) { /* NOTE: Is having the client == NULL safe? */ - AUTHgetPasswordHash(&password, NULL, localuser); + AUTHgetPasswordHash(&pwhash, NULL, local_user); } else { free_pw = true; if (pw_encrypted) { - password = strdup(pass); + pwhash = strdup(pass); } else { - password = mcrypt_BackendSum(pass, strlen(pass)); + /* Note: the remote server might have used a different + * algorithm to hash the pwhash. + */ + pwhash = mcrypt_BackendSum(pass, strlen(pass)); } } - rethrow("addUser", tmp, AUTHverifyPassword(password)); + rethrow("addRemoteTableCredentials", tmp, AUTHverifyPassword(pwhash)); - fprintf(fp, "%s,%s,%s,%s\n", local_table, uri, remoteuser, password); + /* Until lookup is implemented properly we need the following 3 lines */ + FILE *fp = fopen("/tmp/remote_table_auth.txt", "w"); + fprintf(fp, "%s,%s,%s,%s\n", local_table, uri, remoteuser, pwhash); fclose(fp); + /* Add entry */ + bool table_entry = (BUNappend(rt_key, local_table, TRUE) == GDK_SUCCEED || + BUNappend(rt_remoteuser, remoteuser, TRUE) == GDK_SUCCEED || + BUNappend(rt_hashedpwd, pwhash, TRUE) == GDK_SUCCEED); + + if (!table_entry) { + if (free_pw) { + free(pwhash); + } + throw(MAL, "addRemoteTableCredentials", SQLSTATE(HY001) MAL_MALLOC_FAIL); + } + + AUTHcommit(); + if (free_pw) { - free(password); + free(pwhash); } return MAL_SUCCEED; } diff --git a/sql/server/rel_distribute.c b/sql/server/rel_distribute.c --- a/sql/server/rel_distribute.c +++ b/sql/server/rel_distribute.c @@ -285,14 +285,11 @@ distribute(mvc *sql, sql_rel *rel) /* set_remote() */ if (t && isRemote(t)) { - //char *uri = t->query; + //TODO: check for allocation failure char *local_name = sa_strconcat(sql->sa, sa_strconcat(sql->sa, t->s->base.name, "."), t->base.name); + p = rel->p = prop_create(sql->sa, PROP_REMOTE, rel->p); p->value = local_name; - - //p = rel->p = prop_create(sql->sa, PROP_REMOTE2, rel->p); - //p->value = local_name; - } break; } diff --git a/sql/server/rel_schema.c b/sql/server/rel_schema.c --- a/sql/server/rel_schema.c +++ b/sql/server/rel_schema.c @@ -940,7 +940,7 @@ rel_create_table(mvc *sql, sql_schema *s } } else if (temp != SQL_DECLARED_TABLE && (!mvc_schema_privs(sql, s) && !(isTempSchema(s) && temp == SQL_LOCAL_TEMP))){ return sql_error(sql, 02, SQLSTATE(42000) "CREATE TABLE: insufficient privileges for user '%s' in schema '%s'", stack_get_string(sql, "current_user"), s->base.name); - } else if (table_elements_or_subquery->token == SQL_CREATE_TABLE) { + } else if (table_elements_or_subquery->token == SQL_CREATE_TABLE) { /* table element list */ dnode *n; dlist *columns = table_elements_or_subquery->data.lval; @@ -951,7 +951,6 @@ rel_create_table(mvc *sql, sql_schema *s char *local_table = sa_strconcat(sql->sa, sa_strconcat(sql->sa, sname, "."), name); if (!mapiuri_valid(loc)) return sql_error(sql, 02, SQLSTATE(42000) "CREATE TABLE: incorrect uri '%s' for remote table '%s'", loc, name); - char *reg_credentials = AUTHaddRemoteTableCredentials(local_table, local_user, mapiuri_uri(loc, sql->sa), username, password, pw_encrypted); if (reg_credentials != 0) { return sql_error(sql, 02, SQLSTATE(42000) "CREATE TABLE: cannot register credentials for remote table '%s' in vault: %s", name, reg_credentials); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list