Repository: incubator-hawq
Updated Branches:
  refs/heads/ranger 9de76890c -> 64ae1a875 (forced update)


Package oids inside one query to request RPS: ExecCheckRTPerms entry.


Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/64ae1a87
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/64ae1a87
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/64ae1a87

Branch: refs/heads/ranger
Commit: 64ae1a8758e8ae27b042c3a3adafae60ef32da75
Parents: b22d208
Author: xunzhang <[email protected]>
Authored: Mon Dec 5 19:12:18 2016 +0800
Committer: xunzhang <[email protected]>
Committed: Sun Dec 11 13:59:48 2016 +0800

----------------------------------------------------------------------
 src/backend/catalog/aclchk.c        |  68 ++++++++++++-
 src/backend/libpq/rangerrest.c      | 164 ++++++++++++++++++++++++++++++-
 src/backend/libpq/rangerrest.h      |  39 --------
 src/backend/parser/parse_relation.c |  81 ++++++++++++++-
 src/include/parser/parse_relation.h |   1 +
 src/include/utils/acl.h             |  25 +++++
 src/include/utils/rangerrest.h      |  39 ++++++++
 7 files changed, 371 insertions(+), 46 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/64ae1a87/src/backend/catalog/aclchk.c
----------------------------------------------------------------------
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 06f20f3..2837331 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -2664,6 +2664,72 @@ List *getActionName(AclMode mask)
   return actions;
 }
 
+/*
+ * return: List of RangerPrivilegeResults 
+ * arg_list: List of RangerPrivilegeArgs
+ */
+List *pg_rangercheck_batch(List *arg_list)
+{
+  List *aclresults = NIL;
+  List *requestargs = NIL;
+  ListCell *arg;
+  foreach(arg, arg_list) {
+    RangerPrivilegeArgs *arg_ptr = (RangerPrivilegeArgs *) lfirst(arg);
+    AclObjectKind objkind = arg_ptr->objkind;
+    Oid object_oid = arg_ptr->object_oid;
+    char *objectname = getNameFromOid(objkind, object_oid);
+    char *rolename = getRoleName(arg_ptr->roleid);
+    List* actions = getActionName(arg_ptr->mask);
+    bool isAll = (arg_ptr->how == ACLMASK_ALL) ? true: false;
+    RangerPrivilegeResults *aclresult = (RangerPrivilegeResults *) 
palloc(sizeof(RangerPrivilegeResults));
+    aclresult->result = -1; //check_privilege_from_ranger(rolename, objkind, 
objectname, actions, isAll);
+    aclresult->relOid = object_oid; 
+    aclresults = lappend(aclresults, aclresult);
+
+    RangerRequestJsonArgs *requestarg = (RangerRequestJsonArgs *) 
palloc(sizeof(RangerRequestJsonArgs));
+    requestarg->user = rolename;
+    requestarg->kind = objkind;
+    requestarg->object = objectname;
+    requestarg->actions = actions;
+    requestarg->how = isAll;
+    requestargs = lappend(requestargs, requestarg);
+    
+    if (objectname)
+    {
+      pfree(objectname);
+      objectname = NULL;
+    }
+    if(rolename)
+    {
+      pfree(rolename);
+      rolename = NULL;
+    }
+    if(actions)
+    {
+      list_free_deep(actions);
+      actions = NIL;
+    }
+  } // foreach
+
+  RangerACLResult ret = check_privilege_from_ranger_batch(requestargs);
+
+  ListCell *result;
+  int k = 0;
+  foreach(result, aclresults) {
+    RangerPrivilegeResults *result_ptr = (RangerPrivilegeResults *) 
lfirst(result);
+    result_ptr->result = ret;
+    ++k;
+  }
+  
+  if(requestargs) {
+    list_free_deep(requestargs);
+    requestargs = NULL;
+  }
+
+  elog(LOG, "oids%d\n", arg_list->length);
+  return aclresults;
+}
+
 AclResult
 pg_rangercheck(AclObjectKind objkind, Oid object_oid, Oid roleid,
          AclMode mask, AclMaskHow how)
@@ -2687,11 +2753,9 @@ pg_rangercheck(AclObjectKind objkind, Oid object_oid, 
Oid roleid,
     list_free_deep(actions);
     actions = NIL;
   }
-
   return ACLCHECK_OK;
 }
 
-
 /*
  * Relay for the various pg_*_mask routines depending on object kind
  */

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/64ae1a87/src/backend/libpq/rangerrest.c
----------------------------------------------------------------------
diff --git a/src/backend/libpq/rangerrest.c b/src/backend/libpq/rangerrest.c
index 032a6c0..2a9625e 100644
--- a/src/backend/libpq/rangerrest.c
+++ b/src/backend/libpq/rangerrest.c
@@ -25,7 +25,7 @@
  *-------------------------------------------------------------------------
  */
 #include <json-c/json.h>
-#include "rangerrest.h"
+#include "utils/rangerrest.h"
 #include "utils/elog.h"
 #include "utils/palloc.h"
 #include "postgres.h"
@@ -95,6 +95,133 @@ char* AclObjectKindStr[] =
     "none"               /* MUST BE LAST */
 };
 
+/*
+ * args: List of RangerRequestJsonArgs
+ */
+json_object *create_ranger_request_json_batch(List *args)
+{
+  json_object *juser = NULL;
+  json_object *jaccess = json_object_new_array();
+  json_object *jrequest = json_object_new_object();
+  char *user = NULL;
+  ListCell *arg;
+  
+  foreach(arg, args)
+  {
+    RangerRequestJsonArgs *arg_ptr = (RangerRequestJsonArgs *) lfirst(arg);
+    if (user == NULL)
+    {
+      user = arg_ptr->user;
+      juser = json_object_new_string(user);
+    }
+    AclObjectKind kind = arg_ptr->kind;
+    char* object = arg_ptr->object;
+    char* how = arg_ptr->how;
+    Assert(user != NULL && object != NULL && privilege != NULL && how != NULL);
+    elog(LOG, "build json for ranger request, user:%s, kind:%s, object:%s",
+         user, AclObjectKindStr[kind], object);
+    
+    json_object *jresource = json_object_new_object();
+    json_object *jelement = json_object_new_object();
+    json_object *jactions = json_object_new_array();
+
+    switch(kind)
+    {
+        case ACL_KIND_CLASS:
+        case ACL_KIND_SEQUENCE:
+        case ACL_KIND_PROC:
+        case ACL_KIND_NAMESPACE:
+        case ACL_KIND_LANGUAGE:
+        {
+            char *ptr = NULL; char *name = NULL;
+            char *first = NULL; // could be a database or protocol or 
tablespace
+            char *second = NULL; // could be a schema or language
+            char *third = NULL; // could be a table or sequence or function
+            int idx = 0;
+            for (name = strtok_r(object, ".", &ptr);
+                 name;
+                 name = strtok_r(NULL, ".", &ptr), idx++)
+            {
+                if (idx == 0)
+                {
+                    first = pstrdup(name);
+                }
+                else if (idx == 1)
+                {
+                    second = pstrdup(name);
+                }
+                else
+                {
+                    third = pstrdup(name);
+                }
+            }
+
+            if (first != NULL)
+            {
+                json_object *jfirst = json_object_new_string(first);
+                json_object_object_add(jresource, "database", jfirst);
+            }
+            if (second != NULL)
+            {
+                json_object *jsecond = json_object_new_string(second);
+                json_object_object_add(jresource,
+                        (kind == ACL_KIND_LANGUAGE) ? "language" : "schema", 
jsecond);
+            }
+            if (third != NULL)
+            {
+                json_object *jthird = json_object_new_string(third);
+                elog(LOG, "JTHIRD %s\n", jthird);
+                json_object_object_add(jresource,
+                         (kind == ACL_KIND_CLASS) ? "table" :
+                         (kind == ACL_KIND_SEQUENCE) ? "sequence" : 
"function", jthird);
+            }
+
+            if (first != NULL)
+                pfree(first);
+            if (second != NULL)
+                pfree(second);
+            if (third != NULL)
+                pfree(third);
+            break;
+        }
+        case ACL_KIND_OPER:
+        case ACL_KIND_CONVERSION:
+        case ACL_KIND_DATABASE:
+        case ACL_KIND_TABLESPACE:
+        case ACL_KIND_TYPE:
+        case ACL_KIND_FILESYSTEM:
+        case ACL_KIND_FDW:
+        case ACL_KIND_FOREIGN_SERVER:
+        case ACL_KIND_EXTPROTOCOL:
+        {
+            json_object *jobject = json_object_new_string(object);
+            json_object_object_add(jresource, AclObjectKindStr[kind], jobject);
+            break;
+        }
+        default:
+            elog(ERROR, "unrecognized objkind: %d", (int) kind);
+    } // switch
+
+    json_object_object_add(jelement, "resource", jresource);
+    
+    //ListCell *cell;
+    //foreach(cell, arg_ptr->actions)
+    //{
+      char tmp[7] = "select";
+      json_object* jaction = json_object_new_string((char *)tmp);
+      //json_object* jaction = json_object_new_string((char 
*)cell->data.ptr_value);
+      json_object_array_add(jactions, jaction);
+    //}
+    json_object_object_add(jelement, "privileges", jactions);
+    json_object_array_add(jaccess, jelement);
+
+  } // foreach
+
+  json_object_object_add(jrequest, "user", juser);
+  json_object_object_add(jrequest, "access", jaccess);
+  return jrequest;
+}
+
 /**
  * Create a JSON object for Ranger request given some parameters.
  *
@@ -130,7 +257,7 @@ json_object* create_ranger_request_json(char* user, 
AclObjectKind kind, char* ob
 {
     Assert(user != NULL && object != NULL && privilege != NULL
                     && how != NULL);
-    ListCell *cell = NULL;
+    ListCell *cell;
 
     elog(LOG, "build json for ranger request, user:%s, kind:%s, object:%s",
               user, AclObjectKindStr[kind], object);
@@ -309,13 +436,44 @@ _exit:
 }
 
 /*
+ * arg_list: List of RangerRequestJsonArgs
+ */
+int check_privilege_from_ranger_batch(List *arg_list)
+{
+  json_object* jrequest = create_ranger_request_json_batch(arg_list);
+  Assert(jrequest != NULL);
+  char *request = json_object_to_json_string(jrequest);
+  elog(LOG, "Send JSON request to Ranger: %s", request);
+  Assert(request != NULL);
+  struct curl_context_t curl_context;
+  memset(&curl_context, 0, sizeof(struct curl_context_t));
+
+  /* call GET method to send request*/
+  call_ranger_rest(&curl_context, request);
+  
+  /* free the JSON object */
+  json_object_put(jrequest);
+  
+  /* parse the JSON-format result */
+  RangerACLResult ret = parse_ranger_response(curl_context.response.buffer);
+  
+  /* free response buffer */
+  if (curl_context.response.buffer != NULL)
+  {
+    pfree(curl_context.response.buffer);
+  }
+
+  return ret;
+}
+
+/*
  * Check the privilege from Ranger for one role
  */
 int check_privilege_from_ranger(char* user, AclObjectKind kind, char* object,
         List* actions, char* how)
 {
     json_object* jrequest = create_ranger_request_json(user, kind, object,
-            actions, how);
+                                                       actions, how);
 
     Assert(jrequest != NULL);
     char* request = json_object_to_json_string(jrequest);

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/64ae1a87/src/backend/libpq/rangerrest.h
----------------------------------------------------------------------
diff --git a/src/backend/libpq/rangerrest.h b/src/backend/libpq/rangerrest.h
deleted file mode 100644
index 4b73f46..0000000
--- a/src/backend/libpq/rangerrest.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*-------------------------------------------------------------------------
- *
- * rangerrest.h
- *     routines to interact with Ranger REST API
- *
- *-------------------------------------------------------------------------
- */
-#ifndef RANGERREST_H
-#define RANGERREST_H
-
-#include <curl/curl.h>
-
-typedef enum
-{
-    RANGERCHECK_OK = 0,
-    RANGERCHECK_NO_PRIV,
-    RANGERCHECK_UNKNOWN
-} RangerACLResult;
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/64ae1a87/src/backend/parser/parse_relation.c
----------------------------------------------------------------------
diff --git a/src/backend/parser/parse_relation.c 
b/src/backend/parser/parse_relation.c
index 811d2e2..0c6e0fb 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -2712,12 +2712,88 @@ warnAutoRange(ParseState *pstate, RangeVar *relation, 
int location)
 void
 ExecCheckRTPerms(List *rangeTable)
 {
+  if (enable_ranger)
+  {
+    ExecCheckRTPermsWithRanger(rangeTable);
+    return;
+  }
+  /*
        ListCell   *l;
-
        foreach(l, rangeTable)
        {
                ExecCheckRTEPerms((RangeTblEntry *) lfirst(l));
        }
+       */
+}
+
+/*
+ * ExecCheckRTPerms
+ *   Batch implementation: Check access permissions for all relations listed 
in a range table with enable_ranger is true.
+ */
+void
+ExecCheckRTPermsWithRanger(List *rangeTable)
+{
+  List *ranger_check_args = NIL;
+  ListCell *l;
+  foreach(l, rangeTable)
+  {
+
+    AclMode requiredPerms;
+    Oid relOid;
+    Oid userid;
+    RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
+
+    if (rte->rtekind != RTE_RELATION)
+      return;
+    requiredPerms = rte->requiredPerms;
+    if (requiredPerms == 0)
+      return;
+    
+    relOid = rte->relid;
+    userid = rte->checkAsUser ? rte->checkAsUser : GetUserId();
+
+    RangerPrivilegeArgs *ranger_check_arg = (RangerPrivilegeArgs *) 
palloc(sizeof(RangerPrivilegeArgs));
+    ranger_check_arg->objkind = ACL_KIND_CLASS;
+    ranger_check_arg->object_oid = relOid;
+    ranger_check_arg->roleid = userid;
+    ranger_check_arg->mask = requiredPerms;
+    ranger_check_arg->how = ACLMASK_ALL;
+    ranger_check_args = lappend(ranger_check_args, ranger_check_arg);
+
+  } // foreach
+
+  // ranger ACL check with package Oids
+  List *aclresults = NIL;
+  aclresults = pg_rangercheck_batch(ranger_check_args);
+  if (aclresults == NIL)
+  {
+    elog(ERROR, "ERROR\n");
+    return;
+  }
+
+  // check result
+  ListCell *result;
+  foreach(result, aclresults)
+  {
+    RangerPrivilegeResults *result_ptr = (RangerPrivilegeResults *) 
lfirst(result);
+    if(result_ptr->result != RANGERCHECK_OK)
+    {
+      Oid relOid = result_ptr->relOid;
+      const char *rel_name = get_rel_name_partition(relOid);
+      aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_CLASS, rel_name);
+    }
+  }
+  
+  if (ranger_check_args)
+  {
+    list_free_deep(ranger_check_args);
+    ranger_check_args = NIL;
+  }
+  if (aclresults)
+  {
+    list_free_deep(aclresults);
+    aclresults = NIL;
+  }
 }
 
 /*
@@ -2763,9 +2839,10 @@ ExecCheckRTEPerms(RangeTblEntry *rte)
         */
        if (enable_ranger)
        {
+         elog(LOG, "ExecCheckRTEPerms: here");
          /* ranger check required permission should all be approved.*/
     if (pg_rangercheck(ACL_KIND_CLASS, relOid, userid, requiredPerms, 
ACLMASK_ALL)
-        != ACLCHECK_OK)
+        != RANGERCHECK_OK)
     {
       /*
        * If the table is a partition, return an error message that includes

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/64ae1a87/src/include/parser/parse_relation.h
----------------------------------------------------------------------
diff --git a/src/include/parser/parse_relation.h 
b/src/include/parser/parse_relation.h
index 4c13a79..3af717f 100644
--- a/src/include/parser/parse_relation.h
+++ b/src/include/parser/parse_relation.h
@@ -101,6 +101,7 @@ extern Name attnumAttName(Relation rd, int attid);
 extern Oid     attnumTypeId(Relation rd, int attid);
 
 extern void ExecCheckRTPerms(List *rangeTable);
+extern void ExecCheckRTPermsWithRanger(List *);
 extern void ExecCheckRTEPerms(RangeTblEntry *rte);
 
 #endif   /* PARSE_RELATION_H */

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/64ae1a87/src/include/utils/acl.h
----------------------------------------------------------------------
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index b0ddde9..0fb9ca3 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -26,6 +26,7 @@
 
 #include "nodes/parsenodes.h"
 #include "utils/array.h"
+#include "utils/rangerrest.h"
 
 
 /*
@@ -299,6 +300,7 @@ extern AclResult pg_foreign_server_nativecheck(Oid srv_oid, 
Oid roleid, AclMode
 extern AclResult pg_extprotocol_nativecheck(Oid ptc_oid, Oid roleid, AclMode 
mode);
 extern AclResult pg_filesystem_nativecheck(Oid fsys_oid, Oid roleid, AclMode 
mode);
 
+extern List *pg_rangercheck_batch(List *);
 extern AclResult
 pg_rangercheck(AclObjectKind objkind, Oid table_oid, Oid roleid,
          AclMode mask, AclMaskHow how);
@@ -339,4 +341,27 @@ extern bool pg_conversion_ownercheck(Oid conv_oid, Oid 
roleid);
 extern bool pg_foreign_server_ownercheck(Oid srv_oid, Oid roleid);
 extern bool pg_extprotocol_ownercheck(Oid ptc_oid, Oid roleid);
 
+typedef struct RangerPrivilegeArgs
+{
+  AclObjectKind objkind;
+  Oid        object_oid;
+  Oid            roleid;
+  AclMode          mask;
+  AclMaskHow        how;
+} RangerPrivilegeArgs;
+
+typedef struct RangerPrivilegeResults
+{
+  RangerACLResult result;
+  Oid relOid;
+} RangerPrivilegeResults;
+
+typedef struct RangerRequestJsonArgs {
+  char* user;
+  AclObjectKind kind;
+  char* object;
+  List* actions;
+  char* how;
+} RangerRequestJsonArgs;
+
 #endif   /* ACL_H */

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/64ae1a87/src/include/utils/rangerrest.h
----------------------------------------------------------------------
diff --git a/src/include/utils/rangerrest.h b/src/include/utils/rangerrest.h
new file mode 100644
index 0000000..4b73f46
--- /dev/null
+++ b/src/include/utils/rangerrest.h
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*-------------------------------------------------------------------------
+ *
+ * rangerrest.h
+ *     routines to interact with Ranger REST API
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef RANGERREST_H
+#define RANGERREST_H
+
+#include <curl/curl.h>
+
+typedef enum
+{
+    RANGERCHECK_OK = 0,
+    RANGERCHECK_NO_PRIV,
+    RANGERCHECK_UNKNOWN
+} RangerACLResult;
+
+#endif

Reply via email to