You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hawq.apache.org by es...@apache.org on 2017/02/03 09:00:09 UTC

[07/50] [abbrv] incubator-hawq git commit: HAWQ-1246. Add generation of RequestID, ClientIP, queryContext(SQL Statement) and encapsulate these contents to JSON request to RPS.

HAWQ-1246. Add generation of RequestID, ClientIP, queryContext(SQL Statement) and encapsulate these contents to JSON request to RPS.


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

Branch: refs/heads/2.1.0.0-incubating
Commit: 60f093372888fdead70ffea1d2b035c7d2bc343d
Parents: 94239f5
Author: stanlyxiang <st...@gmail.com>
Authored: Thu Dec 22 10:28:17 2016 +0800
Committer: hzhang2 <zh...@163.com>
Committed: Tue Jan 3 10:39:51 2017 +0800

----------------------------------------------------------------------
 src/backend/catalog/aclchk.c   |  57 ++++---
 src/backend/libpq/rangerrest.c | 318 +++++++++++-------------------------
 src/include/utils/rangerrest.h |  11 +-
 3 files changed, 134 insertions(+), 252 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/60f09337/src/backend/catalog/aclchk.c
----------------------------------------------------------------------
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index d3e4b64..d19a045 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -2732,7 +2732,7 @@ List *pg_rangercheck_batch(List *arg_list)
 
   } // foreach
 
-  RangerACLResult ret = check_privilege_from_ranger_batch(requestargs);
+  RangerACLResult ret = check_privilege_from_ranger(requestargs);
 
   ListCell *result;
   int k = 0;
@@ -2752,7 +2752,7 @@ List *pg_rangercheck_batch(List *arg_list)
           (RangerRequestJsonArgs*)lfirst(tmp);
       pfree(requestarg->user);
       pfree(requestarg->object);
-      pfree(requestarg->actions);
+      list_free_deep(requestarg->actions);
     }
 
     list_free_deep(requestargs);
@@ -2770,27 +2770,38 @@ AclResult
 pg_rangercheck(AclObjectKind objkind, Oid object_oid, Oid roleid,
          AclMode mask, AclMaskHow how)
 {
-  char* objectname = getNameFromOid(objkind, object_oid);
-  char* rolename = getRoleName(roleid);
-  List* actions = getActionName(mask);
-  bool isAll = (how == ACLMASK_ALL) ? true: false;
-
-  elog(LOG, "rangeraclcheck kind:%d,objectname:%s,role:%s,mask:%u\n",objkind,objectname,rolename,mask);
-  int ret = check_privilege_from_ranger(rolename, objkind, objectname, actions, isAll);
-
-  if(objectname){
-    pfree(objectname);
-    objectname = NULL;
-  }
-  if(rolename){
-    pfree(rolename);
-    rolename = NULL;
-  }
-  if(actions){
-    list_free_deep(actions);
-    actions = NIL;
-  }
-  return ret;
+	char* objectname = getNameFromOid(objkind, object_oid);
+	char* rolename = getRoleName(roleid);
+	List* actions = getActionName(mask);
+	bool isAll = (how == ACLMASK_ALL) ? true: false;
+
+	elog(LOG, "rangeraclcheck kind:%d,objectname:%s,role:%s,mask:%u\n",objkind,objectname,rolename,mask);
+	List *requestargs = NIL;
+	RangerRequestJsonArgs *requestarg = (RangerRequestJsonArgs *) palloc(sizeof(RangerRequestJsonArgs));
+	requestarg->user = rolename;
+	requestarg->kind = objkind;
+	requestarg->object = objectname;
+	requestarg->actions = actions;
+	requestarg->isAll = isAll;
+	requestargs = lappend(requestargs, requestarg);
+	int ret = check_privilege_from_ranger(requestargs);
+
+	if (requestargs)
+	{
+		ListCell *cell = list_head(requestargs);
+		while (cell != NULL)
+		{
+			ListCell *tmp = cell;
+			cell = lnext(cell);
+			RangerRequestJsonArgs* requestarg = (RangerRequestJsonArgs*) lfirst(tmp);
+			pfree(requestarg->user);
+			pfree(requestarg->object);
+			list_free_deep(requestarg->actions);
+		}
+		list_free_deep(requestargs);
+		requestargs = NULL;
+	}
+	return ret;
 }
 
 /*

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/60f09337/src/backend/libpq/rangerrest.c
----------------------------------------------------------------------
diff --git a/src/backend/libpq/rangerrest.c b/src/backend/libpq/rangerrest.c
index 120f64f..56d30b5 100644
--- a/src/backend/libpq/rangerrest.c
+++ b/src/backend/libpq/rangerrest.c
@@ -49,10 +49,28 @@ char* AclObjectKindStr[] =
 	"none"               /* MUST BE LAST */
 };
 
+static int request_id = 1;
+
+static void getClientIP(char *remote_host)
+{
+	if( MyProcPort->remote_host == NULL || strlen(MyProcPort->remote_host) == 0 )
+	{
+		snprintf(remote_host, HOST_BUFFER_SIZE, "%s", "UNKNOWN");
+		return;
+	}
+	if (strcmp(MyProcPort->remote_host, "[local]") == 0)
+	{
+		snprintf(remote_host, HOST_BUFFER_SIZE, "%s", "127.0.0.1");
+	}
+	else
+	{
+		snprintf(remote_host, HOST_BUFFER_SIZE, "%s", MyProcPort->remote_host);
+	}
+}
+
 RangerACLResult parse_ranger_response(char* buffer)
 {
-	Assert(buffer != NULL);
-	if (strlen(buffer) == 0)
+	if (buffer == NULL || strlen(buffer) == 0)
 		return RANGERCHECK_UNKNOWN;
 
 	elog(LOG, "read from Ranger Restful API: %s", buffer);
@@ -92,15 +110,43 @@ RangerACLResult parse_ranger_response(char* buffer)
 	return RANGERCHECK_OK;
 
 }
-
-/*
- * args: List of RangerRequestJsonArgs
+/**
+ * Create a JSON object for Ranger request given some parameters.
+ *
+ *   {
+ *     "requestId": 1,
+ *     "user": "joe",
+ *     "groups": ["admin","us"],
+ *     "clientIp": "123.0.0.21",
+ *     "context": "SELECT * FROM sales",
+ *     "access":
+ *       [
+ *         {
+ *           "resource":
+ *           {
+ *             "database": "finance"
+ *           },
+ *           "privileges": ["connect"]
+ *         },
+ *         {
+ *           "resource":
+ *           {
+ *             "database": "finance",
+ *             "schema": "us",
+ *             "table": "sales"
+ *           },
+ *           "privileges": ["select", "insert"]
+ *         }
+ *       ]
+ *   }
+ *
+ *   args: List of RangerRequestJsonArgs
  */
-json_object *create_ranger_request_json_batch(List *args)
+json_object *create_ranger_request_json(List *args)
 {
+	json_object *jrequest = json_object_new_object();
 	json_object *juser = NULL;
 	json_object *jaccess = json_object_new_array();
-	json_object *jrequest = json_object_new_object();
 	char *user = NULL;
 	ListCell *arg;
 
@@ -116,28 +162,27 @@ json_object *create_ranger_request_json_batch(List *args)
 		char* object = arg_ptr->object;
 		Assert(user != NULL && object != NULL && privilege != NULL && arg_ptr->isAll);
 		elog(LOG, "build json for ranger request, user:%s, kind:%s, object:%s",
-			user, AclObjectKindStr[kind], object);
+				user, AclObjectKindStr[kind], object);
 
-		json_object *jresource = json_object_new_object();
 		json_object *jelement = json_object_new_object();
+		json_object *jresource = 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:
+			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 *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++)
+				for (name = strtok_r(object, ".", &ptr); name;
+						name = strtok_r(NULL, ".", &ptr), idx++)
 				{
 					if (idx == 0)
 					{
@@ -180,24 +225,23 @@ json_object *create_ranger_request_json_batch(List *args)
 					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:
+			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);
+			default:
+				elog(ERROR, "unrecognized objkind: %d", (int) kind);
 		} // switch
-
 		json_object_object_add(jelement, "resource", jresource);
 
 		ListCell *cell;
@@ -210,161 +254,22 @@ json_object *create_ranger_request_json_batch(List *args)
 		json_object_array_add(jaccess, jelement);
 
 	} // foreach
-
+	char str[32];
+	sprintf(str,"%d",request_id);
+	json_object *jreqid = json_object_new_string(str);
+	json_object_object_add(jrequest, "requestId", jreqid);
 	json_object_object_add(jrequest, "user", juser);
-	json_object_object_add(jrequest, "access", jaccess);
 
-	json_object *jreqid = json_object_new_string("1");
-	json_object_object_add(jrequest, "requestId", jreqid);
-	json_object *jclientip = json_object_new_string("123.0.0.21");
+	char remote_host[HOST_BUFFER_SIZE];
+	getClientIP(remote_host);
+	json_object *jclientip = json_object_new_string(remote_host);
 	json_object_object_add(jrequest, "clientIp", jclientip);
-	json_object *jcontext = json_object_new_string("SELECT * FROM DDDDDDD");
-	json_object_object_add(jrequest, "context", jcontext);
-
-	return jrequest;
-}
-
-/**
- * Create a JSON object for Ranger request given some parameters.
- *
- *   {
- *     "requestId": 1,
- *     "user": "joe",
- *     "groups": ["admin","us"],
- *     "clientIp": "123.0.0.21",
- *     "context": "SELECT * FROM sales",
- *     "access":
- *       [
- *         {
- *           "resource":
- *           {
- *             "database": "finance"
- *           },
- *           "privileges": ["connect"]
- *         },
- *         {
- *           "resource":
- *           {
- *             "database": "finance",
- *             "schema": "us",
- *             "table": "sales"
- *           },
- *           "privileges": ["select, insert"]
- *         }
- *       ]
- *   }
- */
-json_object* create_ranger_request_json(char* user, AclObjectKind kind, char* object,
-	List* actions, bool isAll)
-{
-	Assert(user != NULL && object != NULL && privilege != NULL
-		&& isAll);
-	ListCell *cell;
-
-	elog(LOG, "build json for ranger request, user:%s, kind:%s, object:%s",
-		user, AclObjectKindStr[kind], object);
-	json_object *jrequest = json_object_new_object();
-	json_object *juser = json_object_new_string(user);
-
-	json_object *jaccess = json_object_new_array();
-	json_object *jelement = json_object_new_object();
-
-	json_object *jresource = json_object_new_object();
-	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);
-				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);
-	}
-
-	json_object *jactions = json_object_new_array();
-	foreach(cell, actions)
-	{
-		json_object* jaction = json_object_new_string((char *)cell->data.ptr_value);
-		json_object_array_add(jactions, jaction);
-	}
-	json_object_object_add(jelement, "resource", jresource);
-	json_object_object_add(jelement, "privileges", jactions);
-	json_object_array_add(jaccess, jelement);
-
-	json_object_object_add(jrequest, "user", juser);
-	json_object_object_add(jrequest, "access", jaccess);
-	json_object *jreqid = json_object_new_string("1");
-	json_object_object_add(jrequest, "requestId", jreqid);
-	json_object *jclientip = json_object_new_string("123.0.0.21");
-	json_object_object_add(jrequest, "clientIp", jclientip);
-	json_object *jcontext = json_object_new_string("SELECT * FROM DDDDDDD");
+	json_object *jcontext = json_object_new_string(
+			(debug_query_string == NULL || strlen(debug_query_string) == 0)
+				? "connect to db" : debug_query_string);
 	json_object_object_add(jrequest, "context", jcontext);
-
+	json_object_object_add(jrequest, "access", jaccess);
 
 	return jrequest;
 }
@@ -435,11 +340,9 @@ int call_ranger_rest(CURL_HANDLE curl_handle, const char* request)
 	curl_easy_setopt(curl_handle->curl_handle, CURLOPT_URL, tname.data);
 
 	struct curl_slist *headers = NULL;
-	//curl_slist_append(headers, "Accept: application/json");
 	headers = curl_slist_append(headers, "Content-Type:application/json");
 	curl_easy_setopt(curl_handle->curl_handle, CURLOPT_HTTPHEADER, headers);
 
-	//curl_easy_setopt(curl_handle->curl_handle, CURLOPT_POST, 1L);
 	curl_easy_setopt(curl_handle->curl_handle, CURLOPT_POSTFIELDS,request);
 	//"{\"requestId\": 1,\"user\": \"hubert\",\"clientIp\":\"123.0.0.21\",\"context\": \"SELECT * FROM sales\",\"access\":[{\"resource\":{\"database\":\"a-database\",\"schema\":\"a-schema\",\"table\":\"sales\"},\"privileges\": [\"select\"]}]}");
 	/* send all data to this function  */
@@ -447,7 +350,11 @@ int call_ranger_rest(CURL_HANDLE curl_handle, const char* request)
 	curl_easy_setopt(curl_handle->curl_handle, CURLOPT_WRITEDATA, (void *)curl_handle);
 
 	res = curl_easy_perform(curl_handle->curl_handle);
-
+	if(request_id == INT_MAX)
+	{
+		request_id = 0;
+	}
+	request_id++;
 	/* check for errors */
 	if(res != CURLE_OK)
 	{
@@ -476,9 +383,9 @@ _exit:
 /*
  * arg_list: List of RangerRequestJsonArgs
  */
-int check_privilege_from_ranger_batch(List *arg_list)
+int check_privilege_from_ranger(List *arg_list)
 {
-	json_object* jrequest = create_ranger_request_json_batch(arg_list);
+	json_object* jrequest = create_ranger_request_json(arg_list);
 	Assert(jrequest != NULL);
 	const char *request = json_object_to_json_string(jrequest);
 	elog(LOG, "Send JSON request to Ranger: %s", request);
@@ -505,42 +412,3 @@ int check_privilege_from_ranger_batch(List *arg_list)
 
 	return ret;
 }
-
-/*
- * Check the privilege from Ranger for one role
- */
-int check_privilege_from_ranger(char* user, AclObjectKind kind, char* object,
-	List* actions, bool isAll)
-{
-	json_object* jrequest = create_ranger_request_json(user, kind, object,
-		actions, isAll);
-
-	Assert(jrequest != NULL);
-	const 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*/
-	if (call_ranger_rest(&curl_context, request) < 0)
-	{
-		return RANGERCHECK_NO_PRIV;
-	}
-
-	/* 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;
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/60f09337/src/include/utils/rangerrest.h
----------------------------------------------------------------------
diff --git a/src/include/utils/rangerrest.h b/src/include/utils/rangerrest.h
index 541bdbc..692c832 100644
--- a/src/include/utils/rangerrest.h
+++ b/src/include/utils/rangerrest.h
@@ -32,6 +32,11 @@
 #include "postgres.h"
 #include "utils/acl.h"
 #include "utils/guc.h"
+#include "miscadmin.h"
+#include "libpq/libpq-be.h"
+#include "tcop/tcopprot.h"
+
+#define HOST_BUFFER_SIZE 1025
 
 typedef enum
 {
@@ -86,10 +91,8 @@ typedef struct RangerRequestJsonArgs {
 } RangerRequestJsonArgs;
 
 RangerACLResult parse_ranger_response(char *);
-json_object *create_ranger_request_json_batch(List *);
-json_object *create_ranger_request_json(char *, AclObjectKind kind, char *, List *, bool);
+json_object *create_ranger_request_json(List *);
 int call_ranger_rest(CURL_HANDLE curl_handle, const char *request);
-extern int check_privilege_from_ranger_batch(List *);
-extern int check_privilege_from_ranger(char *, AclObjectKind kind, char *, List *, bool);
+extern int check_privilege_from_ranger(List *);
 
 #endif