Repository: incubator-hawq Updated Branches: refs/heads/master 94239f5ed -> 60f093372
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/master Commit: 60f093372888fdead70ffea1d2b035c7d2bc343d Parents: 94239f5 Author: stanlyxiang <[email protected]> Authored: Thu Dec 22 10:28:17 2016 +0800 Committer: hzhang2 <[email protected]> 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
