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

Reply via email to