You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hawq.apache.org by hu...@apache.org on 2019/03/14 14:03:03 UTC

[hawq] branch huor_cloud updated (b56084d -> 46847b5)

This is an automated email from the ASF dual-hosted git repository.

huor pushed a change to branch huor_cloud
in repository https://gitbox.apache.org/repos/asf/hawq.git.


    from b56084d  HAWQ-1677. Disable orc compilation until it is available
     new dcbc5ec  HAWQ-1681. Support manage user in cloud
     new 20d8b1f  HAWQ-1682. Remove useless log for cloud authentication
     new 1bb460b  HAWQ-1683. Using DEBUG3 instead INFO log in cloudrest.c
     new 073fa07  HAWQ-1684. Add connection close in header for cloud rest
     new 46847b5  HAWQ-1685. Fix bug in CheckUserExistOnCloud

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/backend/commands/user.c         | 504 +++++++++++++++++++++++++++++++++++-
 src/backend/commands/variable.c     |  14 +-
 src/backend/libpq/Makefile          |   2 +-
 src/backend/libpq/auth.c            |  68 +++++
 src/backend/libpq/cloudrest.c       | 447 ++++++++++++++++++++++++++++++++
 src/backend/libpq/hba.c             |  15 ++
 src/backend/tcop/postgres.c         |   1 +
 src/backend/utils/cache/lsyscache.c |   3 +-
 src/backend/utils/init/miscinit.c   |   8 +-
 src/backend/utils/misc/guc.c        |  24 ++
 src/include/commands/user.h         |   3 +
 src/include/libpq/hba.h             |   4 +-
 src/include/utils/cloudrest.h       |  88 +++++++
 src/include/utils/guc.h             |   6 +
 14 files changed, 1171 insertions(+), 16 deletions(-)
 create mode 100644 src/backend/libpq/cloudrest.c
 create mode 100644 src/include/utils/cloudrest.h


[hawq] 04/05: HAWQ-1684. Add connection close in header for cloud rest

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

huor pushed a commit to branch huor_cloud
in repository https://gitbox.apache.org/repos/asf/hawq.git

commit 073fa07c4f710a3ac3ac02af1c9c0d09818827d6
Author: wcl14 <wa...@126.com>
AuthorDate: Fri Jun 29 11:18:36 2018 +0800

    HAWQ-1684. Add connection close in header for cloud rest
---
 src/backend/libpq/cloudrest.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/backend/libpq/cloudrest.c b/src/backend/libpq/cloudrest.c
index 3d0eb08..dec2548 100644
--- a/src/backend/libpq/cloudrest.c
+++ b/src/backend/libpq/cloudrest.c
@@ -142,6 +142,7 @@ static int call_cloud_rest(CURL_HANDLE curl_handle, const char* request, char *a
 		elog(DEBUG3, "in call_cloud_rest: %s", buf);
 		headers = curl_slist_append(headers, buf);
 	}
+	headers = curl_slist_append(headers, "connection:close");
 	curl_easy_setopt(curl_handle->curl_handle, CURLOPT_HTTPHEADER, headers);
 
 	curl_easy_setopt(curl_handle->curl_handle, CURLOPT_POSTFIELDS, request);


[hawq] 01/05: HAWQ-1681. Support manage user in cloud

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

huor pushed a commit to branch huor_cloud
in repository https://gitbox.apache.org/repos/asf/hawq.git

commit dcbc5ec1bd4157d14f214bc4588c7df63dfcaadc
Author: wcl14 <wa...@126.com>
AuthorDate: Tue May 29 16:26:22 2018 +0800

    HAWQ-1681. Support manage user in cloud
---
 src/backend/commands/user.c         | 503 +++++++++++++++++++++++++++++++++++-
 src/backend/commands/variable.c     |  12 +-
 src/backend/libpq/Makefile          |   2 +-
 src/backend/libpq/auth.c            |  69 +++++
 src/backend/libpq/cloudrest.c       | 446 ++++++++++++++++++++++++++++++++
 src/backend/libpq/hba.c             |  15 ++
 src/backend/tcop/postgres.c         |   1 +
 src/backend/utils/cache/lsyscache.c |   3 +-
 src/backend/utils/init/miscinit.c   |   7 +-
 src/backend/utils/misc/guc.c        |  24 ++
 src/include/commands/user.h         |   3 +
 src/include/libpq/hba.h             |   4 +-
 src/include/utils/cloudrest.h       |  88 +++++++
 src/include/utils/guc.h             |   6 +
 14 files changed, 1167 insertions(+), 16 deletions(-)

diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index f8fc301..d1da5a5 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -58,6 +58,7 @@
 #include "utils/lsyscache.h"
 
 #include "executor/execdesc.h"
+#include "utils/cloudrest.h"
 #include "utils/resscheduler.h"
 #include "utils/syscache.h"
 
@@ -112,6 +113,7 @@ static void AddRoleDenials(const char *rolename, Oid roleid,
 static void DelRoleDenials(const char *rolename, Oid roleid, 
 			List *dropintervals);
 static bool resourceQueueIsBranch(Oid queueid);
+static Oid CreateNoPrivligeRole(char *rolename);
 
 /* Check if current user has createrole privileges */
 static bool
@@ -121,6 +123,11 @@ have_createrole_privilege(void)
 	cqContext  *pcqCtx, cqc;
 	HeapTuple	utup;
 
+	if (pg_cloud_auth)
+	{
+		return pg_cloud_createrole;
+	}
+
 	/* Superusers can always do everything */
 	if (superuser())
 		return true;
@@ -547,6 +554,52 @@ CreateRole(CreateRoleStmt *stmt)
 	else
 		new_record_nulls[Anum_pg_authid_rolpassword - 1] = true;
 
+	if (pg_cloud_auth)
+	{
+		char *errormsg;
+		int ret = check_authentication_from_cloud(stmt->role, password,
+				&createrole, USER_SYNC, "create", &errormsg);
+		elog(INFO, "in CreateRole, ret=%d", ret);
+		if (ret)
+		{
+			/*
+			 * role exists in cloud, create it in database but without any authorities
+			 */
+			if (ret == CLOUDSYNC_USEREXIST)
+			{
+				new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(
+						false);
+				new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(
+						false);
+				new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(
+						false);
+				new_record[Anum_pg_authid_rolcatupdate - 1] = BoolGetDatum(
+						false);
+				new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(
+						false);
+				new_record[Anum_pg_authid_rolcreaterextgpfd - 1] =
+						BoolGetDatum(false);
+				new_record[Anum_pg_authid_rolcreaterexthttp - 1] =
+						BoolGetDatum(false);
+				new_record[Anum_pg_authid_rolcreatewextgpfd - 1] =
+						BoolGetDatum(false);
+				new_record[Anum_pg_authid_rolcreaterexthdfs - 1] =
+						BoolGetDatum(false);
+				new_record[Anum_pg_authid_rolcreatewexthdfs - 1] =
+						BoolGetDatum(false);
+			}
+			else
+			{
+				elog(ERROR, "%s", errormsg);
+				if (errormsg)
+				{
+					pfree(errormsg);
+					errormsg = NULL;
+				}
+			}
+		}
+	}
+
 	if (validUntil)
 		new_record[Anum_pg_authid_rolvaliduntil - 1] =
 			DirectFunctionCall3(timestamptz_in,
@@ -1011,11 +1064,13 @@ AlterRole(AlterRoleStmt *stmt)
 
 	tuple = caql_getnext(pcqCtx);
 
-	if (!HeapTupleIsValid(tuple)) {
+	if (!HeapTupleIsValid(tuple)
+			&& !CheckUserExistOnCloud(pcqCtx, pg_authid_rel, stmt->role, &tuple,
+					true))
+	{
 		releaseResourceContextWithErrorReport(resourceid);
 		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("role \"%s\" does not exist", stmt->role)));
+				(errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("role \"%s\" does not exist", stmt->role)));
 	}
 
 	roleid = HeapTupleGetOid(tuple);
@@ -1095,6 +1150,24 @@ AlterRole(AlterRoleStmt *stmt)
 	{
 		new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole > 0);
 		new_record_repl[Anum_pg_authid_rolcreaterole - 1] = true;
+
+		if (pg_cloud_auth)
+		{
+			char *errormsg;
+			int ret;
+			ret = check_authentication_from_cloud(stmt->role, NULL,
+					&new_record[Anum_pg_authid_rolcreaterole - 1], USER_SYNC,
+					"alter", &errormsg);
+			elog(INFO, "in AlterRole, ret=%d", ret);
+			if (ret)
+			{
+				elog(ERROR, "%s", errormsg);
+				if (errormsg) {
+					pfree(errormsg);
+					errormsg = NULL;
+				}
+			}
+		}
 	}
 
 	if (createdb >= 0)
@@ -1132,6 +1205,23 @@ AlterRole(AlterRoleStmt *stmt)
 				CStringGetTextDatum(encrypted_password);
 		}
 		new_record_repl[Anum_pg_authid_rolpassword - 1] = true;
+
+		if (pg_cloud_auth)
+		{
+			char *errormsg;
+			int ret;
+			ret = check_authentication_from_cloud(stmt->role, password, NULL,
+					USER_SYNC, "alter", &errormsg);
+			elog(INFO, "in AlterRole, ret=%d", ret);
+			if (ret)
+			{
+				elog(ERROR, "%s", errormsg);
+				if (errormsg) {
+					pfree(errormsg);
+					errormsg = NULL;
+				}
+			}
+		}
 	}
 
 	/* unset password */
@@ -1549,6 +1639,25 @@ DropRole(DropRoleStmt *stmt)
 		cqContext	cqc;
 		cqContext  *pcqCtx;
 
+		if (pg_cloud_auth)
+		{
+			char *errormsg;
+			int ret = check_authentication_from_cloud(role, NULL, NULL,
+					USER_SYNC, "drop", &errormsg);
+			if (ret)
+			{
+				elog(ERROR, "%s", errormsg);
+				ereport(ERROR,
+						(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+						 errmsg("%s", errormsg),
+								   errOmitLocation(true)));
+				if (errormsg) {
+					pfree(errormsg);
+					errormsg = NULL;
+				}
+			}
+		}
+
 		pcqCtx = caql_beginscan(
 				caql_addrel(cqclr(&cqc), pg_authid_rel),
 				cql("SELECT * FROM pg_authid "
@@ -1768,6 +1877,12 @@ RenameRole(const char *oldname, const char *newname)
 	cqContext	cqc2;
 	cqContext  *pcqCtx;
 
+	if (pg_cloud_auth)
+	{
+		ereport(ERROR,
+				(errcode(ERRCODE_CDB_FEATURE_NOT_YET), errmsg("Cannot support rename role name when using cloud auth yet") ));
+	}
+
 	rel = heap_open(AuthIdRelationId, RowExclusiveLock);
 	dsc = RelationGetDescr(rel);
 
@@ -2911,3 +3026,385 @@ DelRoleDenials(const char *rolename, Oid roleid, List *dropintervals)
 	 */
 	auth_time_file_update_needed();
 }
+
+static Oid
+CreateNoPrivligeRole(char *rolename)
+{
+	Relation	pg_authid_rel;
+	HeapTuple	tuple;
+	Datum		new_record[Natts_pg_authid];
+	bool		new_record_nulls[Natts_pg_authid];
+	Oid			roleid;
+	ListCell   *item;
+	ListCell   *option;
+	char	   *password = NULL;	/* user password */
+	bool		encrypt_password = Password_encryption; /* encrypt password? */
+	char		encrypted_password[MAX_PASSWD_HASH_LEN + 1];
+	bool		issuper = false;	/* Make the user a superuser? */
+	bool		inherit = true; /* Auto inherit privileges? */
+	bool		createrole = false;		/* Can this user create roles? */
+	bool		createdb = false;		/* Can the user create databases? */
+	bool		canlogin = false;		/* Can this user login? */
+	bool		createrextgpfd = false; /* Can create readable gpfdist exttab? */
+	bool		createrexthttp = false; /* Can create readable http exttab? */
+	bool		createwextgpfd = false; /* Can create writable gpfdist exttab? */
+	bool		createrexthdfs = false; /* Can create readable hdfs exttab? */
+	bool		createwexthdfs = false; /* Can create writable hdfs exttab? */
+	int			connlimit = -1; /* maximum connections allowed */
+	List	   *addroleto = NIL;	/* roles to make this a member of */
+	List	   *rolemembers = NIL;		/* roles to be members of this role */
+	List	   *adminmembers = NIL;		/* roles to be admins of this role */
+	List	   *exttabcreate = NIL;		/* external table create privileges being added  */
+	List	   *exttabnocreate = NIL;	/* external table create privileges being removed */
+	char	   *validUntil = NULL;		/* time the login is valid until */
+	char	   *resqueue = NULL;		/* resource queue for this role */
+	List	   *addintervals = NIL;	/* list of time intervals for which login should be denied */
+	cqContext	cqc;
+	cqContext	cqc2;
+	cqContext  *pcqCtx;
+	Oid		queueid = InvalidOid;
+	int  		res 		= FUNC_RETURN_OK;
+	static char errorbuf[1024] = "";
+
+	/* Create a new resource context to manipulate role in resource manager. */
+	int resourceid = 0;
+	res = createNewResourceContext(&resourceid);
+	if (res != FUNC_RETURN_OK) {
+		Assert( res == COMM2RM_CLIENT_FULL_RESOURCECONTEXT );
+		ereport(ERROR,
+				(errcode(ERRCODE_INTERNAL_ERROR),
+						 errmsg("Can not apply CREATE ROLE. "
+								"Because too many resource contexts were created.")));
+	}
+
+	/* Here, using user oid is more convenient. */
+	res = registerConnectionInRMByOID(resourceid,
+									  BOOTSTRAP_SUPERUSERID,
+									  errorbuf,
+									  sizeof(errorbuf));
+	if (res != FUNC_RETURN_OK)
+	{
+		releaseResourceContextWithErrorReport(resourceid);
+		ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("%s", errorbuf)));
+	}
+
+	/*
+	 * Check the pg_authid relation to be certain the role doesn't already
+	 * exist.
+	 */
+	pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock);
+
+	pcqCtx =
+			caql_beginscan(
+					caql_addrel(cqclr(&cqc), pg_authid_rel),
+					cql("INSERT INTO pg_authid ",
+						NULL));
+
+	if (caql_getcount(
+				caql_addrel(cqclr(&cqc2), pg_authid_rel),
+				cql("SELECT COUNT(*) FROM pg_authid "
+					" WHERE rolname = :1 ",
+					PointerGetDatum(rolename)))) {
+		unregisterConnectionInRMWithErrorReport(resourceid);
+		releaseResourceContextWithErrorReport(resourceid);
+		ereport(ERROR,
+				(errcode(ERRCODE_DUPLICATE_OBJECT),
+				 errmsg("role \"%s\" already exists",
+						rolename)));
+	}
+
+	/*
+	 * Build a tuple to insert
+	 */
+	MemSet(new_record, 0, sizeof(new_record));
+	MemSet(new_record_nulls, false, sizeof(new_record_nulls));
+
+	new_record[Anum_pg_authid_rolname - 1] =
+		DirectFunctionCall1(namein, CStringGetDatum(rolename));
+
+	new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper);
+	new_record[Anum_pg_authid_rolinherit - 1] = BoolGetDatum(inherit);
+	new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole);
+	new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(createdb);
+	/* superuser gets catupdate right by default */
+	new_record[Anum_pg_authid_rolcatupdate - 1] = BoolGetDatum(issuper);
+	new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(canlogin);
+	new_record[Anum_pg_authid_rolconnlimit - 1] = Int32GetDatum(connlimit);
+
+	/* Set the CREATE EXTERNAL TABLE permissions for this role */
+	if (exttabcreate || exttabnocreate)
+		SetCreateExtTableForRole(exttabcreate, exttabnocreate, &createrextgpfd,
+								 &createrexthttp, &createwextgpfd,
+								 &createrexthdfs, &createwexthdfs);
+
+	new_record[Anum_pg_authid_rolcreaterextgpfd - 1] = BoolGetDatum(createrextgpfd);
+	new_record[Anum_pg_authid_rolcreaterexthttp - 1] = BoolGetDatum(createrexthttp);
+	new_record[Anum_pg_authid_rolcreatewextgpfd - 1] = BoolGetDatum(createwextgpfd);
+	new_record[Anum_pg_authid_rolcreaterexthdfs - 1] = BoolGetDatum(createrexthdfs);
+	new_record[Anum_pg_authid_rolcreatewexthdfs - 1] = BoolGetDatum(createwexthdfs);
+
+	if (password)
+	{
+		if (!encrypt_password || isHashedPasswd(password))
+			new_record[Anum_pg_authid_rolpassword - 1] =
+				CStringGetTextDatum(password);
+		else
+		{
+			if (!hash_password(password, rolename, strlen(rolename),
+							   encrypted_password))
+			{
+				elog(ERROR, "password encryption failed");
+			}
+
+			new_record[Anum_pg_authid_rolpassword - 1] =
+				CStringGetTextDatum(encrypted_password);
+		}
+	}
+	else
+		new_record_nulls[Anum_pg_authid_rolpassword - 1] = true;
+
+	if (validUntil)
+		new_record[Anum_pg_authid_rolvaliduntil - 1] =
+			DirectFunctionCall3(timestamptz_in,
+								CStringGetDatum(validUntil),
+								ObjectIdGetDatum(InvalidOid),
+								Int32GetDatum(-1));
+
+	else
+		new_record_nulls[Anum_pg_authid_rolvaliduntil - 1] = true;
+
+	resqueue = pstrdup(GP_DEFAULT_RESOURCE_QUEUE_NAME);
+	if (resqueue)
+	{
+		if (strcmp(resqueue, "none") == 0)
+		{
+			unregisterConnectionInRMWithErrorReport(resourceid);
+			releaseResourceContextWithErrorReport(resourceid);
+			ereport(ERROR,
+					(errcode(ERRCODE_RESERVED_NAME),
+					 errmsg("resource queue name \"%s\" is reserved",
+							resqueue), errOmitLocation(true)));
+		}
+
+		queueid = GetResQueueIdForName(resqueue);
+		if (queueid == InvalidOid)
+		{
+			unregisterConnectionInRMWithErrorReport(resourceid);
+			releaseResourceContextWithErrorReport(resourceid);
+			ereport(ERROR,
+					(errcode(ERRCODE_UNDEFINED_OBJECT),
+					 errmsg("resource queue \"%s\" does not exist",
+							resqueue), errOmitLocation(true)));
+		}
+
+		if(resourceQueueIsBranch(queueid))
+		{
+			unregisterConnectionInRMWithErrorReport(resourceid);
+			releaseResourceContextWithErrorReport(resourceid);
+			ereport(ERROR,
+					(errcode(ERRCODE_UNDEFINED_OBJECT),
+					 errmsg("cannot assign non-leaf resource queue \"%s\" to role",
+							resqueue), errOmitLocation(true)));
+		}
+
+		new_record[Anum_pg_authid_rolresqueue - 1] =
+		ObjectIdGetDatum(queueid);
+	}
+	else
+		new_record_nulls[Anum_pg_authid_rolresqueue - 1] = true;
+
+	new_record_nulls[Anum_pg_authid_rolconfig - 1] = true;
+
+	tuple = caql_form_tuple(pcqCtx, new_record, new_record_nulls);
+
+
+	/*
+	 * Insert new record in the pg_authid table
+	 */
+	roleid = caql_insert(pcqCtx, tuple); /* implicit update of index as well */
+
+	/*
+	 * send RPC: notify RM to update
+	 */
+	if (resqueue && queueid != InvalidOid)
+	{
+		res = manipulateRoleForResourceQueue(resourceid,
+											 roleid,
+											 queueid,
+											 MANIPULATE_ROLE_RESQUEUE_CREATE,
+											 issuper,
+											 rolename,
+											 errorbuf,
+											 sizeof(errorbuf));
+	}
+
+	/* We always unregister connection. */
+	unregisterConnectionInRMWithErrorReport(resourceid);
+
+	/* We always release resource context. */
+	releaseResourceContextWithErrorReport(resourceid);
+
+	if (resqueue && queueid != InvalidOid)
+	{
+		if ( res != FUNC_RETURN_OK )
+		{
+			ereport(ERROR,
+					(errcode(IS_TO_RM_RPC_ERROR(res) ?
+							 ERRCODE_INTERNAL_ERROR :
+							 ERRCODE_INVALID_OBJECT_DEFINITION),
+					 errmsg("cannot apply CREATE ROLE because of %s", errorbuf)));
+		}
+	}
+
+	/*
+	 * Advance command counter so we can see new record; else tests in
+	 * AddRoleMems may fail.
+	 */
+	if (addroleto || adminmembers || rolemembers)
+		CommandCounterIncrement();
+
+	/*
+	 * Add the new role to the specified existing roles.
+	 */
+	foreach(item, addroleto)
+	{
+		char	   *oldrolename = strVal(lfirst(item));
+		Oid			oldroleid = get_roleid_checked(oldrolename);
+
+		AddRoleMems(oldrolename, oldroleid,
+					list_make1(makeString(rolename)),
+					list_make1_oid(roleid),
+					BOOTSTRAP_SUPERUSERID, false);
+	}
+
+	/*
+	 * Add the specified members to this new role. adminmembers get the admin
+	 * option, rolemembers don't.
+	 */
+	AddRoleMems(rolename, roleid,
+				adminmembers, roleNamesToIds(adminmembers),
+				BOOTSTRAP_SUPERUSERID, true);
+	AddRoleMems(rolename, roleid,
+				rolemembers, roleNamesToIds(rolemembers),
+				BOOTSTRAP_SUPERUSERID, false);
+
+	/*
+	 * Populate pg_auth_time_constraint with intervals for which this
+	 * particular role should be denied access.
+	 */
+	if (addintervals)
+	{
+		if (issuper)
+			ereport(ERROR,
+					(errmsg("cannot create superuser with DENY rules")));
+		AddRoleDenials(rolename, roleid, addintervals);
+	}
+
+	/*
+	 * Close pg_authid, but keep lock till commit (this is important to
+	 * prevent any risk of deadlock failure while updating flat file)
+	 */
+	caql_endscan(pcqCtx);
+	heap_close(pg_authid_rel, NoLock);
+	CommitTransaction();
+	StartTransaction();
+	pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock);
+	pcqCtx =
+			caql_beginscan(
+					caql_addrel(cqclr(&cqc), pg_authid_rel),
+					cql("SELECT * FROM pg_authid "
+						" WHERE oid = :1 ",
+						PointerGetDatum(BOOTSTRAP_SUPERUSERID)));
+	tuple = caql_getnext(pcqCtx);
+	caql_endscan(pcqCtx);
+	heap_close(pg_authid_rel, NoLock);
+
+	/*
+	 * Set flag to update flat auth file at commit.
+	 */
+	auth_file_update_needed();
+
+	if (Gp_role == GP_ROLE_DISPATCH)
+	{
+		/* GPSQL: no dispatch to segments */
+		/* CdbDispatchUtilityStatement((Node *) stmt, "CreateRole"); */
+
+		/* MPP-6929: metadata tracking */
+		MetaTrackAddObject(AuthIdRelationId,
+						   roleid,
+						   BOOTSTRAP_SUPERUSERID,
+						   "CREATE", "ROLE"
+				);
+	}
+
+	return roleid;
+}
+
+bool
+CheckUserExistOnCloudSimple(char *rolename, Oid *roleid)
+{
+	if (!pg_cloud_auth)
+		return false;
+
+	char *errormsg;
+	int ret = check_authentication_from_cloud(rolename, NULL, NULL, USER_EXIST,
+			"", &errormsg);
+	if (ret)
+	{
+		ereport(LOG,
+				(errmsg("%s", errormsg)));
+		if (errormsg) {
+			pfree(errormsg);
+			errormsg = NULL;
+		}
+		return false;
+	}
+	HeapTuple tuple;
+	*roleid = CreateNoPrivligeRole(rolename);
+	return true;
+}
+
+bool CheckUserExistOnCloud(cqContext *pcqCtx, Relation pg_authid_rel,
+		char *rolename, HeapTuple *tuple, bool forUpdate)
+{
+	if (!pg_cloud_auth)
+		return false;
+
+	char *errormsg;
+	int ret = check_authentication_from_cloud(rolename, NULL, NULL, USER_EXIST,
+			"", &errormsg);
+	if (ret)
+	{
+		ereport(LOG, (errmsg("%s", errormsg)));
+		if (errormsg)
+		{
+			pfree(errormsg);
+			errormsg = NULL;
+		}
+		return false;
+	}
+	caql_endscan(pcqCtx);
+	if (pg_authid_rel)
+	{
+		heap_close(pg_authid_rel, NoLock);
+	}
+	Oid roleid = CreateNoPrivligeRole(rolename);
+	cqContext cqc;
+	if (forUpdate)
+	{
+		pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock);
+		pcqCtx = caql_beginscan(caql_addrel(cqclr(&cqc), pg_authid_rel),
+				cql("SELECT * FROM pg_authid "
+						" WHERE oid = :1 "
+						" FOR UPDATE ", ObjectIdGetDatum(roleid)));
+	}
+	else
+	{
+		pcqCtx = caql_beginscan(
+		NULL, cql("SELECT * FROM pg_authid "
+				" WHERE oid = :1 ", ObjectIdGetDatum(roleid)));
+	}
+
+	*tuple = caql_getnext(pcqCtx);
+	return true;
+}
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index b431228..6c801ee 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -776,12 +776,12 @@ assign_session_authorization(const char *value, bool doit, GucSource source)
 					PointerGetDatum((char *) value)));
 
 		roleTup = caql_getnext(pcqCtx);
-		if (!HeapTupleIsValid(roleTup))
+		if (!HeapTupleIsValid(roleTup)
+				&& !CheckUserExistOnCloud(pcqCtx, NULL, value, &roleTup, false))
 		{
 			if (source >= PGC_S_INTERACTIVE)
 				ereport(ERROR,
-						(errcode(ERRCODE_UNDEFINED_OBJECT),
-						 errmsg("role \"%s\" does not exist", value)));
+						(errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("role \"%s\" does not exist", value)));
 			return NULL;
 		}
 
@@ -922,12 +922,12 @@ assign_role(const char *value, bool doit, GucSource source)
 					PointerGetDatum((char *) value)));
 
 		roleTup = caql_getnext(pcqCtx);
-		if (!HeapTupleIsValid(roleTup))
+		if (!HeapTupleIsValid(roleTup)
+				&& !CheckUserExistOnCloud(pcqCtx, NULL, value, &roleTup, false))
 		{
 			if (source >= PGC_S_INTERACTIVE)
 				ereport(ERROR,
-						(errcode(ERRCODE_UNDEFINED_OBJECT),
-						 errmsg("role \"%s\" does not exist", value)));
+						(errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("role \"%s\" does not exist", value)));
 			return NULL;
 		}
 
diff --git a/src/backend/libpq/Makefile b/src/backend/libpq/Makefile
index 16124c7..a55f694 100644
--- a/src/backend/libpq/Makefile
+++ b/src/backend/libpq/Makefile
@@ -15,6 +15,6 @@ include $(top_builddir)/src/Makefile.global
 # be-fsstubs is here for historical reasons, probably belongs elsewhere
 
 OBJS = be-fsstubs.o be-secure.o auth.o crypt.o hba.o ip.o md5.o pqcomm.o \
-       pqformat.o pqsignal.o sha2.o pg_sha2.o rangerrest.o
+       pqformat.o pqsignal.o sha2.o pg_sha2.o rangerrest.o cloudrest.o
 
 include $(top_srcdir)/src/backend/common.mk
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index fbd2b32..1e0e888 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -40,6 +40,7 @@
 #include "pgtime.h"
 #include "postmaster/postmaster.h"
 #include "utils/builtins.h"
+#include "utils/cloudrest.h"
 #include "utils/datetime.h"
 #include "utils/guc.h"
 #include "utils/timestamp.h"
@@ -213,6 +214,12 @@ static int pg_SSPI_recvauth(Port *port);
 #endif
 static int	CheckRADIUSAuth(Port *port);
 
+/*----------------------------------------------------------------
+ * Cloud Authentication
+ *----------------------------------------------------------------
+ */
+static int CheckCloudAuth(Port *port);
+
 /*
  * Maximum accepted size of GSS and SSPI authentication tokens.
  *
@@ -313,6 +320,9 @@ auth_failed(Port *port, int status)
 			case uaRADIUS:
 				errstr = gettext_noop("RADIUS authentication failed for user \"%s\"");
 				break;
+			case uaCloud:
+				errstr = gettext_noop("Cloud authentication failed for user \"%s\"");
+				break;
 			default:
 				errstr = gettext_noop("authentication failed for user \"%s\": invalid authentication method");
 				break;
@@ -711,6 +721,9 @@ ClientAuthentication(Port *port)
 		case uaRADIUS:
 			status = CheckRADIUSAuth(port);
 			break;
+		case uaCloud:
+			status = CheckCloudAuth(port);
+			break;
 		case uaTrust:
 			status = STATUS_OK;
 			break;
@@ -2696,6 +2709,62 @@ CheckCertAuth(Port *port)
 }
 #endif
 
+/*
+ * Called when we have sent an authorization request for a password.
+ * Get the response and check it.
+ */
+static int
+CheckCloudAuth(Port *port)
+{
+	char	   *passwd;
+	int			result;
+
+	pg_cloud_auth = true;
+
+	elog(LOG, "in CheckCloudAuth, port->hba->cloudserver=%s, pg_cloud_clustername=%s", port->hba->cloudserver, pg_cloud_clustername);
+	if (!port->hba->cloudserver || port->hba->cloudserver[0] == '\0')
+	{
+		ereport(LOG,
+				(errmsg("cloud server not specified")));
+		return STATUS_ERROR;
+	}
+
+	sendAuthRequest(port, AUTH_REQ_PASSWORD);
+
+	passwd = recv_password_packet(port);
+	if (passwd == NULL)
+		return STATUS_EOF;		/* client wouldn't send password */
+
+	if (strlen(passwd) == 0)
+	{
+		ereport(LOG,
+				(errmsg("empty password returned by client")));
+		return STATUS_ERROR;
+	}
+
+	elog(LOG, "in CheckCloudAuth, before init_cloud_curl");
+	init_cloud_curl();
+
+	char *errormsg;
+	elog(LOG, "in CheckCloudAuth, before check_authentication_from_cloud");
+	result = check_authentication_from_cloud(port->user_name, passwd, NULL,
+			AUTHENTICATION_CHECK, "", &errormsg);
+	if (result)
+	{
+		ereport(LOG,
+				(errmsg("%s", errormsg)));
+		if (errormsg) {
+			pfree(errormsg);
+			errormsg = NULL;
+		}
+	}
+
+	pfree(passwd);
+
+	return result;
+
+}
+
 
 /*----------------------------------------------------------------
  * RADIUS authentication
diff --git a/src/backend/libpq/cloudrest.c b/src/backend/libpq/cloudrest.c
new file mode 100644
index 0000000..4ef0412
--- /dev/null
+++ b/src/backend/libpq/cloudrest.c
@@ -0,0 +1,446 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2016, Oushu Inc.
+// All rights reserved.
+//
+// Author:
+///////////////////////////////////////////////////////////////////////////////
+
+#include "utils/cloudrest.h"
+
+#include <string.h>
+
+#include "utils/elog.h"
+
+char	   *pg_cloud_server = NULL;
+char	   *pg_cloud_token = NULL;
+bool		pg_cloud_createrole;
+bool		pg_cloud_auth = false;
+
+static void finalize_cloud_curl();
+
+static json_object *create_cloud_authentication_request_json(char *username, char *password)
+{
+	json_object *jrequest = json_object_new_object();
+
+	json_object *jusername = json_object_new_string(username);
+	json_object_object_add(jrequest, "username", jusername);
+	json_object *jpassword = json_object_new_string(password);
+	json_object_object_add(jrequest, "password", jpassword);
+	json_object *jclustername = json_object_new_string(pg_cloud_clustername);
+	json_object_object_add(jrequest, "clustername", jclustername);
+
+	return jrequest;
+}
+
+static json_object *create_cloud_usersync_request_json(char *username, char *password, bool *createuser, char *action)
+{
+	json_object *jrequest = json_object_new_object();
+
+	json_object *jaction = json_object_new_string(action);
+	json_object_object_add(jrequest, "action", jaction);
+	json_object *jtoken = json_object_new_string(pg_cloud_token);
+	json_object_object_add(jrequest, "token", jtoken);
+	json_object *jusername = json_object_new_string(username);
+	json_object_object_add(jrequest, "username", jusername);
+	if (password)
+	{
+		json_object *jpassword = json_object_new_string(password);
+		json_object_object_add(jrequest, "password", jpassword);
+	}
+	json_object *jclustername = json_object_new_string(pg_cloud_clustername);
+	json_object_object_add(jrequest, "clustername", jclustername);
+	if (createuser)
+	{
+		json_object *jcreateuser = json_object_new_boolean(*createuser);
+		json_object_object_add(jrequest, "cancreateuser", jcreateuser);
+	}
+
+	return jrequest;
+}
+
+static json_object *create_cloud_userexist_request_json(char *username)
+{
+	json_object *jrequest = json_object_new_object();
+
+	json_object *jusername = json_object_new_string(username);
+	json_object_object_add(jrequest, "username", jusername);
+	json_object *jclustername = json_object_new_string(pg_cloud_clustername);
+	json_object_object_add(jrequest, "clustername", jclustername);
+
+	return jrequest;
+}
+
+static size_t write_callback(char *contents, size_t size, size_t nitems,
+	void *userp)
+{
+	size_t realsize = size * nitems;
+	CURL_HANDLE curl = (CURL_HANDLE) userp;
+	Assert(curl != NULL);
+
+	elog(DEBUG3, "cloud restful response size is %d. response buffer size is %d.", curl->response.response_size, curl->response.buffer_size);
+	int original_size = curl->response.buffer_size;
+	while(curl->response.response_size + realsize >= curl->response.buffer_size)
+	{
+		/* double the buffer size if the buffer is not enough.*/
+		curl->response.buffer_size = curl->response.buffer_size * 2;
+	}
+	if(original_size < curl->response.buffer_size)
+	{
+		/* repalloc is not same as realloc, repalloc's first parameter cannot be NULL */
+		curl->response.buffer = repalloc(curl->response.buffer, curl->response.buffer_size);
+	}
+	elog(DEBUG3, "cloud restful response size is %d. response buffer size is %d.", curl->response.response_size, curl->response.buffer_size);
+	if (curl->response.buffer == NULL)
+	{
+		/* allocate memory failed. probably out of memory */
+		elog(WARNING, "cannot allocate memory for cloud response");
+		return 0;
+	}
+	memcpy(curl->response.buffer + curl->response.response_size, contents, realsize);
+	curl->response.response_size += realsize;
+	curl->response.buffer[curl->response.response_size] = '\0';
+	elog(DEBUG3, "read from cloud restful response: %s", curl->response.buffer);
+	return realsize;
+}
+
+/**
+ * @return	0 curl success; -1 curl failed
+ */
+static int call_cloud_rest(CURL_HANDLE curl_handle, const char* request, char *action)
+{
+	int ret = -1;
+	CURLcode res;
+	Assert(request != NULL);
+
+	/*
+	 * Re-initializes all options previously set on a specified CURL handle
+	 * to the default values. This puts back the handle to the same state as
+	 * it was in when it was just created with curl_easy_init.It does not
+	 * change the following information kept in the handle: live connections,
+	 * the Session ID cache, the DNS cache, the cookies and shares.
+	 */
+	curl_easy_reset(curl_handle->curl_handle);
+	/* timeout: hard-coded temporarily and maybe should be a guc in future */
+	curl_easy_setopt(curl_handle->curl_handle, CURLOPT_TIMEOUT, 30L);
+
+	/* specify URL to get */
+	StringInfoData tname;
+	initStringInfo(&tname);
+	appendStringInfo(&tname, "%s", pg_cloud_server);
+	appendStringInfo(&tname, "/");
+	appendStringInfo(&tname, "%s", action);
+	curl_easy_setopt(curl_handle->curl_handle, CURLOPT_URL, tname.data);
+	elog(INFO, "in call_cloud_rest: %s", tname.data);
+	pfree(tname.data);
+
+	struct curl_slist *headers = NULL;
+	headers = curl_slist_append(headers, "Content-Type:application/json");
+	if (pg_cloud_token) {
+		char buf[512];
+		memset(buf, 0, sizeof(buf));
+		sprintf(buf, "token:%s", pg_cloud_token);
+		elog(INFO, "in call_cloud_rest: %s", buf);
+		headers = curl_slist_append(headers, buf);
+	}
+	curl_easy_setopt(curl_handle->curl_handle, CURLOPT_HTTPHEADER, headers);
+
+	curl_easy_setopt(curl_handle->curl_handle, CURLOPT_POSTFIELDS, request);
+	/* send all data to this function  */
+	curl_easy_setopt(curl_handle->curl_handle, CURLOPT_WRITEFUNCTION,
+			write_callback);
+	curl_easy_setopt(curl_handle->curl_handle, CURLOPT_WRITEDATA,
+			(void * )curl_handle);
+
+	res = curl_easy_perform(curl_handle->curl_handle);
+	/* check for errors */
+	if (res != CURLE_OK)
+	{
+		elog(ERROR, "cloud server from %s/%s is unavailable : %s.\n",
+		pg_cloud_server, action, curl_easy_strerror(res));
+	}
+	else
+	{
+		ret = 0;
+		elog(DEBUG3, "retrieved %d bytes data from cloud restful response.",
+		curl_handle->response.response_size);
+	}
+
+	return ret;
+}
+
+static int parse_cloud_auth_response(char* buffer, int *result, char **errormsg)
+{
+	if (buffer == NULL || strlen(buffer) == 0)
+		return -1;
+
+	elog(DEBUG3, "parse cloud restful response content : %s", buffer);
+
+	struct json_object *response = json_tokener_parse(buffer);
+	if (response == NULL)
+	{
+		elog(WARNING, "failed to parse json tokener.");
+		return -1;
+	}
+
+	struct json_object *jtoken = NULL;
+	if (!json_object_object_get_ex(response, "token", &jtoken))
+	{
+		elog(WARNING, "failed to get json \"token\" field.");
+		return -1;
+	}
+	char *token = json_object_get_string(jtoken);
+	size_t len = strlen(token);
+	MemoryContext old;
+	old = MemoryContextSwitchTo(TopMemoryContext);
+	pg_cloud_token = (char *)palloc0(len + 1);
+	memcpy(pg_cloud_token, token, len);
+	MemoryContextSwitchTo(old);
+	elog(INFO, "in parse_cloud_auth_response, token(%p): %s", pg_cloud_token, pg_cloud_token);
+
+	struct json_object *jcreaterole = NULL;
+	if (!json_object_object_get_ex(response, "cancreateuser", &jcreaterole))
+	{
+		elog(WARNING, "failed to get json \"cancreateuser\" field.");
+		return -1;
+	}
+	pg_cloud_createrole = json_object_get_boolean(jcreaterole);
+	elog(INFO, "pg_cloud_createrole=%d", pg_cloud_createrole);
+
+	struct json_object *jresult = NULL;
+	if (!json_object_object_get_ex(response, "result", &jresult))
+	{
+		elog(WARNING, "failed to get json \"result\" field.");
+		return -1;
+	}
+
+	json_bool ok = json_object_get_int(jresult);
+	if (ok == 1)
+	{
+		*result = CLOUDCHECK_OK;
+	}
+	else
+	{
+		struct json_object *jerror = NULL;
+		if (!json_object_object_get_ex(response, "error", &jerror))
+		{
+			elog(WARNING, "failed to get json \"token\" field.");
+			return -1;
+		}
+		char *err = json_object_get_string(jerror);
+		size_t len = strlen(err);
+		*errormsg = (char *)palloc0(len + 1);
+		memcpy(*errormsg, err, len);
+		(*errormsg)[len] = '\0';
+		*result = CLOUDCHECK_NO_PRIV;
+		elog(INFO, "errmsg=%s, size=%d", *errormsg, strlen(*errormsg));
+	}
+
+	return 0;
+}
+
+static int parse_cloud_sync_response(char* buffer, int *result, char **errormsg)
+{
+	if (buffer == NULL || strlen(buffer) == 0)
+		return -1;
+
+	elog(DEBUG3, "parse cloud restful response content : %s", buffer);
+
+	struct json_object *response = json_tokener_parse(buffer);
+	if (response == NULL)
+	{
+		elog(WARNING, "failed to parse json tokener.");
+		return -1;
+	}
+
+	struct json_object *jresult = NULL;
+	if (!json_object_object_get_ex(response, "result", &jresult))
+	{
+		elog(WARNING, "failed to get json \"result\" field.");
+		return -1;
+	}
+
+	int ok = json_object_get_boolean(jresult);
+	elog(INFO, "in parse_cloud_sync_response, ret=%d", ok);
+	if (ok == 0)
+	{
+		*result = CLOUDSYNC_OK;
+	}
+	else
+	{
+		struct json_object *jerror = NULL;
+		if (!json_object_object_get_ex(response, "error", &jerror))
+		{
+			elog(WARNING, "failed to get json \"token\" field.");
+			return -1;
+		}
+		char *err = json_object_get_string(jerror);
+		size_t len = strlen(err);
+		*errormsg = (char *)palloc0(len + 1);
+		memcpy(*errormsg, err, len);
+		(*errormsg)[len] = '\0';
+		if (ok == 1)
+			*result = CLOUDSYNC_USEREXIST;
+		else
+			*result = CLOUDSYNC_FAIL;
+	}
+
+	return 0;
+}
+
+static int parse_cloud_exist_response(char* buffer, int *result, char **errormsg)
+{
+	if (buffer == NULL || strlen(buffer) == 0)
+		return -1;
+
+	elog(DEBUG3, "parse cloud restful response content : %s", buffer);
+
+	struct json_object *response = json_tokener_parse(buffer);
+	if (response == NULL)
+	{
+		elog(WARNING, "failed to parse json tokener.");
+		return -1;
+	}
+
+	struct json_object *jresult = NULL;
+	if (!json_object_object_get_ex(response, "result", &jresult))
+	{
+		elog(WARNING, "failed to get json \"result\" field.");
+		return -1;
+	}
+
+	json_bool ok = json_object_get_boolean(jresult);
+	if (ok == 1)
+	{
+		*result = CLOUDUSER_EXIST;
+	}
+	else
+	{
+		*result = CLOUDUSER_NOTEXIST;
+	}
+
+	return 0;
+}
+
+void init_cloud_curl() {
+	memset(&curl_context_cloud, 0, sizeof(curl_context_t));
+	curl_global_init(CURL_GLOBAL_ALL);
+	/* init the curl session */
+	curl_context_cloud.curl_handle = curl_easy_init();
+	if (curl_context_cloud.curl_handle == NULL) {
+		/* cleanup curl stuff */
+		/* no need to cleanup curl_handle since it's null. just cleanup curl global.*/
+		curl_global_cleanup();
+		elog(ERROR, "initialize global curl context failed.");
+	}
+	curl_context_cloud.hasInited = true;
+	curl_context_cloud.response.buffer = palloc0(CURL_RES_BUFFER_SIZE);
+	curl_context_cloud.response.buffer_size = CURL_RES_BUFFER_SIZE;
+	elog(DEBUG3, "initialize global curl context for privileges check.");
+	on_proc_exit(finalize_cloud_curl, 0);
+}
+
+void finalize_cloud_curl() {
+	if (curl_context_cloud.response.buffer != NULL) {
+		pfree(curl_context_cloud.response.buffer);
+	}
+	/* cleanup curl stuff */
+	if (curl_context_cloud.curl_handle) {
+		curl_easy_cleanup(curl_context_cloud.curl_handle);
+	}
+	/* we're done with libcurl, so clean it up */
+	curl_global_cleanup();
+	curl_context_cloud.hasInited = false;
+	elog(DEBUG3, "finalize the global struct for curl handle context.");
+}
+
+int check_authentication_from_cloud(char *username, char *password,
+		bool *createuser, CouldAuthAction authAction, char * action,
+		char **errormsg)
+{
+	json_object* jrequest;
+	switch (authAction)
+	{
+		case AUTHENTICATION_CHECK:
+			jrequest = create_cloud_authentication_request_json(username, password);
+			break;
+		case USER_SYNC:
+			jrequest = create_cloud_usersync_request_json(username, password,
+					createuser, action);
+			break;
+		case USER_EXIST:
+			jrequest = create_cloud_userexist_request_json(username);
+			break;
+		default:
+			elog(ERROR, "Invalid cloud authentication action:%d", authAction);
+	}
+	Assert(jrequest != NULL);
+
+	const char *request = json_object_to_json_string(jrequest);
+	Assert(request != NULL);
+	elog(
+			DEBUG3, "send json request to cloud : %s", request);
+
+			/* call GET method to send request*/
+			Assert(curl_context_cloud.hasInited);
+			switch (authAction)
+			{
+				case AUTHENTICATION_CHECK:
+					if (call_cloud_rest(&curl_context_cloud, request, "cloudauthenticate") < 0)
+					{
+						return -1;
+					}
+					break;
+				case USER_SYNC:
+					if (call_cloud_rest(&curl_context_cloud, request, "syncuser") < 0)
+					{
+						return -1;
+					}
+					break;
+				case USER_EXIST:
+					if (call_cloud_rest(&curl_context_cloud, request, "userexist") < 0)
+					{
+						return -1;
+					}
+					break;
+				default:
+					elog(ERROR, "Invalid cloud authentication action:%d", authAction);
+			}
+
+			/* free the JSON object */
+			json_object_put(jrequest);
+
+			/* parse the JSON-format result */
+			int result,
+	ret;
+	switch (authAction)
+	{
+		case AUTHENTICATION_CHECK:
+			ret = parse_cloud_auth_response(curl_context_cloud.response.buffer,
+					&result, errormsg);
+			break;
+		case USER_SYNC:
+			ret = parse_cloud_sync_response(curl_context_cloud.response.buffer,
+					&result, errormsg);
+			break;
+		case USER_EXIST:
+			ret = parse_cloud_exist_response(curl_context_cloud.response.buffer,
+					&result, errormsg);
+			break;
+		default:
+			elog(ERROR, "Invalid cloud authentication action:%d", authAction);
+	}
+	if (ret < 0)
+	{
+		elog(
+				ERROR, "parse cloud response failed, cloud response content is %s",
+				curl_context_cloud.response.buffer == NULL? "empty.":curl_context_cloud.response.buffer);
+	}
+	if (curl_context_cloud.response.buffer != NULL)
+	{
+		/* reset response size to reuse the buffer. */
+		curl_context_cloud.response.response_size = 0;
+	}
+
+	elog(INFO, "in check_authentication_from_cloud: ret=%d", result);
+	return result;
+}
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index d430335..6f89133 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -25,12 +25,14 @@
 #include <arpa/inet.h>
 #include <unistd.h>
 
+#include "libpq/auth.h"
 #include "libpq/ip.h"
 #include "libpq/libpq.h"
 #include "regex/regex.h"
 #include "storage/fd.h"
 #include "utils/flatfiles.h"
 #include "utils/acl.h"
+#include "utils/cloudrest.h"
 #include "utils/guc.h"
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
@@ -1087,6 +1089,8 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
 #endif
 	else if (strcmp(token, "radius") == 0)
 		parsedline->auth_method = uaRADIUS;
+	else if (strcmp(token, "cloud") == 0)
+		parsedline->auth_method = uaCloud;
 	else
 	{
 		ereport(LOG,
@@ -1373,6 +1377,17 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
 				REQUIRE_AUTH_OPTION(uaRADIUS, "radiusidentifier", "radius");
 				parsedline->radiusidentifier = pstrdup(c);
 			}
+			else if (strcmp(token, "cloudserver") == 0)
+			{
+				REQUIRE_AUTH_OPTION(uaCloud, "cloudserver", "cloud");
+				parsedline->cloudserver = pstrdup(c);
+				size_t len = strlen(parsedline->cloudserver);
+				MemoryContext old;
+				old = MemoryContextSwitchTo(TopMemoryContext);
+				pg_cloud_server = (char *)palloc0(len + 1);
+				memcpy(pg_cloud_server, parsedline->cloudserver, len);
+				MemoryContextSwitchTo(old);
+			}
 			else
 			{
 				ereport(LOG,
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 4928ce2..cf0123e 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -137,6 +137,7 @@ extern char *savedSeqServerHost;
 extern int savedSeqServerPort;
 
 struct curl_context_t curl_context_ranger;
+struct curl_context_t curl_context_cloud;
 /* ----------------
  *		global variables
  * ----------------
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 2bd929f..d2a09c3 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -54,6 +54,7 @@
 #include "cdb/cdbpartition.h"
 #include "commands/tablecmds.h"
 #include "commands/trigger.h"
+#include "commands/user.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "parser/parse_clause.h"			/* for sort_op_can_sort() */
@@ -3366,7 +3367,7 @@ get_roleid_checked(const char *rolname)
 	Oid			roleid;
 
 	roleid = get_roleid(rolname);
-	if (!OidIsValid(roleid))
+	if (!OidIsValid(roleid) && !(CheckUserExistOnCloudSimple(rolname, &roleid)))
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("role \"%s\" does not exist", rolname),
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 640cafa..c5384f9 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -444,11 +444,10 @@ InitializeSessionUserId(const char *rolename)
 
 	roleTup = caql_getnext(pcqCtx);
 
-	if (!HeapTupleIsValid(roleTup))
+	if (!HeapTupleIsValid(roleTup)
+			&& !CheckUserExistOnCloud(pcqCtx, NULL, rolename, &roleTup, false))
 		ereport(FATAL,
-				(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
-				 errmsg("role \"%s\" does not exist", rolename),
-				 errOmitLocation(true), errSendAlert(false)));
+				(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), errmsg("role \"%s\" does not exist", rolename), errOmitLocation(true), errSendAlert(false)));
 
 	rform = (Form_pg_authid) GETSTRUCT(roleTup);
 	roleid = HeapTupleGetOid(roleTup);
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 6577b4c..0cf51df 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -790,6 +790,21 @@ char   *acl_type;
 int    rps_addr_port;
 int    rps_check_local_interval;
 
+char   *rps_addr_host;
+char   *rps_addr_suffix;
+int     rps_addr_port;
+
+char	   *pg_cloud_clustername = NULL;
+
+/*auto-switch service*/
+bool enable_master_auto_ha = false;
+
+/* 
+ * zookeeper_server hostlist
+ * "host1:port1,host2:port2,...,hostx:postx"
+ */
+char *ha_zookeeper_quorum = "localhost:2181";
+
 /*
  * Displayable names for context types (enum GucContext)
  *
@@ -8228,6 +8243,15 @@ static struct config_string ConfigureNamesString[] =
 	},
 
 	{
+		{"clusterName", PGC_POSTMASTER, PRESET_OPTIONS,
+			gettext_noop("Corresponding identifier for this hawq cluster in oushu cloud system."),
+			NULL
+		},
+		&pg_cloud_clustername,
+		"", NULL, NULL
+	},
+
+	{
 		{"hawq_standby_address_host", PGC_POSTMASTER, PRESET_OPTIONS,
 			gettext_noop("standby server address hostname"),
 			NULL
diff --git a/src/include/commands/user.h b/src/include/commands/user.h
index 01fb92c..c71b6a7 100644
--- a/src/include/commands/user.h
+++ b/src/include/commands/user.h
@@ -11,6 +11,7 @@
 #ifndef USER_H
 #define USER_H
 
+#include "catalog/catquery.h"
 #include "nodes/parsenodes.h"
 
 
@@ -22,5 +23,7 @@ extern void GrantRole(GrantRoleStmt *stmt);
 extern void RenameRole(const char *oldname, const char *newname);
 extern void DropOwnedObjects(DropOwnedStmt *stmt);
 extern void ReassignOwnedObjects(ReassignOwnedStmt *stmt);
+extern bool CheckUserExistOnCloudSimple(char *rolename, Oid *roleid);
+extern bool CheckUserExistOnCloud(cqContext *pcqCtx, Relation pg_authid_rel, char *rolename, HeapTuple *tuple, bool forUpdate);
 
 #endif   /* USER_H */
diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h
index bc81f9d..9779c62 100644
--- a/src/include/libpq/hba.h
+++ b/src/include/libpq/hba.h
@@ -29,7 +29,8 @@ typedef enum UserAuth
 	uaPAM,
 	uaLDAP,
 	uaCert,
-	uaRADIUS
+	uaRADIUS,
+	uaCloud
 } UserAuth;
 
 typedef enum IPCompareMethod
@@ -77,6 +78,7 @@ typedef struct
 	char	   *radiussecret;
 	char	   *radiusidentifier;
 	int			radiusport;
+	char	   *cloudserver;
 } HbaLine;
 
 /* kluge to avoid including libpq/libpq-be.h here */
diff --git a/src/include/utils/cloudrest.h b/src/include/utils/cloudrest.h
new file mode 100644
index 0000000..e4e3cc8
--- /dev/null
+++ b/src/include/utils/cloudrest.h
@@ -0,0 +1,88 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2016, Oushu Inc.
+// All rights reserved.
+//
+// Author:
+///////////////////////////////////////////////////////////////////////////////
+#ifndef SRC_INCLUDE_UTILS_CLOUDREST_H_
+#define SRC_INCLUDE_UTILS_CLOUDREST_H_
+
+#include <json-c/json.h>
+#include <curl/curl.h>
+
+#include "postgres.h"
+#include "utils/guc.h"
+#include "miscadmin.h"
+#include "libpq/auth.h"
+#include "libpq/libpq-be.h"
+#include "tcop/tcopprot.h"
+
+#define HOST_BUFFER_SIZE 1025
+#define CURL_RES_BUFFER_SIZE 1024
+
+typedef enum
+{
+	AUTHENTICATION_CHECK = 0,
+	USER_SYNC,
+	USER_EXIST
+} CouldAuthAction;
+
+typedef enum
+{
+	CLOUDCHECK_OK = 0,
+	CLOUDCHECK_NO_PRIV,
+	CLOUDCHECK_UNKNOWN
+} CouldAuthResult;
+
+typedef enum
+{
+	CLOUDSYNC_OK = 0,
+	CLOUDSYNC_USEREXIST,
+	CLOUDSYNC_FAIL,
+	CLOUDSYNC_UNKNOWN
+} CouldSyncResult;
+
+typedef enum
+{
+	CLOUDUSER_EXIST = 0,
+	CLOUDUSER_NOTEXIST,
+} CouldExistResult;
+
+/*
+ * Internal buffer for libcurl context
+ */
+typedef struct curl_context_t
+{
+  CURL* curl_handle;
+
+  char curl_error_buffer[CURL_ERROR_SIZE];
+
+  int curl_still_running;
+
+  struct
+  {
+    char* buffer;
+    int response_size;
+    int buffer_size;
+  } response;
+
+  char* last_http_reponse;
+
+  bool hasInited;
+} curl_context_t;
+
+typedef curl_context_t* CURL_HANDLE;
+
+extern struct curl_context_t curl_context_cloud;
+
+extern void init_cloud_curl();
+extern int check_authentication_from_cloud(char *username, char *password,
+		bool *createuser, CouldAuthAction authAction, char * action,
+		char **errmsg);
+
+extern char	   *pg_cloud_server;
+extern char	   *pg_cloud_token;
+extern bool		pg_cloud_createrole;
+extern bool		pg_cloud_auth;
+
+#endif /* SRC_INCLUDE_UTILS_CLOUDREST_H_ */
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 38b217a..d1698a7 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -465,6 +465,12 @@ extern int     rps_addr_port;
 
 /* interval of checking local RPS */
 extern int     rps_check_local_interval;
+
+/*
+ * cloud authenticate
+ */
+extern char	   *pg_cloud_clustername;
+
 /*
  * During insertion in a table with parquet partitions,
  * require tuples to be sorted by partition key.


[hawq] 05/05: HAWQ-1685. Fix bug in CheckUserExistOnCloud

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

huor pushed a commit to branch huor_cloud
in repository https://gitbox.apache.org/repos/asf/hawq.git

commit 46847b580db05b08d2628e3e90f67342465ea291
Author: wcl14 <wa...@126.com>
AuthorDate: Mon Jul 2 11:45:48 2018 +0800

    HAWQ-1685. Fix bug in CheckUserExistOnCloud
---
 src/backend/commands/user.c       | 18 +++++++++---------
 src/backend/commands/variable.c   |  6 ++++--
 src/backend/utils/init/miscinit.c |  3 ++-
 src/include/commands/user.h       |  2 +-
 4 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 7252918..5896af8 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -1065,8 +1065,8 @@ AlterRole(AlterRoleStmt *stmt)
 	tuple = caql_getnext(pcqCtx);
 
 	if (!HeapTupleIsValid(tuple)
-			&& !CheckUserExistOnCloud(pcqCtx, pg_authid_rel, stmt->role, &tuple,
-					true))
+			&& !CheckUserExistOnCloud(&pcqCtx, &cqc, pg_authid_rel, stmt->role,
+					&tuple, true))
 	{
 		releaseResourceContextWithErrorReport(resourceid);
 		ereport(ERROR,
@@ -3365,8 +3365,9 @@ CheckUserExistOnCloudSimple(char *rolename, Oid *roleid)
 	return true;
 }
 
-bool CheckUserExistOnCloud(cqContext *pcqCtx, Relation pg_authid_rel,
-		char *rolename, HeapTuple *tuple, bool forUpdate)
+bool CheckUserExistOnCloud(cqContext **pcqCtx, cqContext *cqc,
+		Relation pg_authid_rel, char *rolename, HeapTuple *tuple,
+		bool forUpdate)
 {
 	if (!pg_cloud_auth)
 		return false;
@@ -3384,28 +3385,27 @@ bool CheckUserExistOnCloud(cqContext *pcqCtx, Relation pg_authid_rel,
 		}
 		return false;
 	}
-	caql_endscan(pcqCtx);
+	caql_endscan(*pcqCtx);
 	if (pg_authid_rel)
 	{
 		heap_close(pg_authid_rel, NoLock);
 	}
 	Oid roleid = CreateNoPrivligeRole(rolename);
-	cqContext cqc;
 	if (forUpdate)
 	{
 		pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock);
-		pcqCtx = caql_beginscan(caql_addrel(cqclr(&cqc), pg_authid_rel),
+		*pcqCtx = caql_beginscan(caql_addrel(cqclr(cqc), pg_authid_rel),
 				cql("SELECT * FROM pg_authid "
 						" WHERE oid = :1 "
 						" FOR UPDATE ", ObjectIdGetDatum(roleid)));
 	}
 	else
 	{
-		pcqCtx = caql_beginscan(
+		*pcqCtx = caql_beginscan(
 		NULL, cql("SELECT * FROM pg_authid "
 				" WHERE oid = :1 ", ObjectIdGetDatum(roleid)));
 	}
 
-	*tuple = caql_getnext(pcqCtx);
+	*tuple = caql_getnext(*pcqCtx);
 	return true;
 }
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index 6c801ee..d9643e1 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -777,7 +777,8 @@ assign_session_authorization(const char *value, bool doit, GucSource source)
 
 		roleTup = caql_getnext(pcqCtx);
 		if (!HeapTupleIsValid(roleTup)
-				&& !CheckUserExistOnCloud(pcqCtx, NULL, value, &roleTup, false))
+				&& !CheckUserExistOnCloud(&pcqCtx, NULL, NULL, value, &roleTup,
+						false))
 		{
 			if (source >= PGC_S_INTERACTIVE)
 				ereport(ERROR,
@@ -923,7 +924,8 @@ assign_role(const char *value, bool doit, GucSource source)
 
 		roleTup = caql_getnext(pcqCtx);
 		if (!HeapTupleIsValid(roleTup)
-				&& !CheckUserExistOnCloud(pcqCtx, NULL, value, &roleTup, false))
+				&& !CheckUserExistOnCloud(&pcqCtx, NULL, NULL, value, &roleTup,
+						false))
 		{
 			if (source >= PGC_S_INTERACTIVE)
 				ereport(ERROR,
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index c5384f9..1987c7f 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -445,7 +445,8 @@ InitializeSessionUserId(const char *rolename)
 	roleTup = caql_getnext(pcqCtx);
 
 	if (!HeapTupleIsValid(roleTup)
-			&& !CheckUserExistOnCloud(pcqCtx, NULL, rolename, &roleTup, false))
+			&& !CheckUserExistOnCloud(&pcqCtx, NULL, NULL, rolename, &roleTup,
+					false))
 		ereport(FATAL,
 				(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), errmsg("role \"%s\" does not exist", rolename), errOmitLocation(true), errSendAlert(false)));
 
diff --git a/src/include/commands/user.h b/src/include/commands/user.h
index c71b6a7..b4f5320 100644
--- a/src/include/commands/user.h
+++ b/src/include/commands/user.h
@@ -24,6 +24,6 @@ extern void RenameRole(const char *oldname, const char *newname);
 extern void DropOwnedObjects(DropOwnedStmt *stmt);
 extern void ReassignOwnedObjects(ReassignOwnedStmt *stmt);
 extern bool CheckUserExistOnCloudSimple(char *rolename, Oid *roleid);
-extern bool CheckUserExistOnCloud(cqContext *pcqCtx, Relation pg_authid_rel, char *rolename, HeapTuple *tuple, bool forUpdate);
+extern bool CheckUserExistOnCloud(cqContext **pcqCtx, cqContext *cqc, Relation pg_authid_rel, char *rolename, HeapTuple *tuple, bool forUpdate);
 
 #endif   /* USER_H */


[hawq] 03/05: HAWQ-1683. Using DEBUG3 instead INFO log in cloudrest.c

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

huor pushed a commit to branch huor_cloud
in repository https://gitbox.apache.org/repos/asf/hawq.git

commit 1bb460b65e36b8353021e5405920ab01c24e0c6c
Author: wcl14 <wa...@126.com>
AuthorDate: Thu Jun 28 11:24:48 2018 +0800

    HAWQ-1683. Using DEBUG3 instead INFO log in cloudrest.c
---
 src/backend/libpq/cloudrest.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/backend/libpq/cloudrest.c b/src/backend/libpq/cloudrest.c
index 4ef0412..3d0eb08 100644
--- a/src/backend/libpq/cloudrest.c
+++ b/src/backend/libpq/cloudrest.c
@@ -130,7 +130,7 @@ static int call_cloud_rest(CURL_HANDLE curl_handle, const char* request, char *a
 	appendStringInfo(&tname, "/");
 	appendStringInfo(&tname, "%s", action);
 	curl_easy_setopt(curl_handle->curl_handle, CURLOPT_URL, tname.data);
-	elog(INFO, "in call_cloud_rest: %s", tname.data);
+	elog(DEBUG3, "in call_cloud_rest: %s", tname.data);
 	pfree(tname.data);
 
 	struct curl_slist *headers = NULL;
@@ -139,7 +139,7 @@ static int call_cloud_rest(CURL_HANDLE curl_handle, const char* request, char *a
 		char buf[512];
 		memset(buf, 0, sizeof(buf));
 		sprintf(buf, "token:%s", pg_cloud_token);
-		elog(INFO, "in call_cloud_rest: %s", buf);
+		elog(DEBUG3, "in call_cloud_rest: %s", buf);
 		headers = curl_slist_append(headers, buf);
 	}
 	curl_easy_setopt(curl_handle->curl_handle, CURLOPT_HTTPHEADER, headers);
@@ -195,7 +195,7 @@ static int parse_cloud_auth_response(char* buffer, int *result, char **errormsg)
 	pg_cloud_token = (char *)palloc0(len + 1);
 	memcpy(pg_cloud_token, token, len);
 	MemoryContextSwitchTo(old);
-	elog(INFO, "in parse_cloud_auth_response, token(%p): %s", pg_cloud_token, pg_cloud_token);
+	elog(DEBUG3, "in parse_cloud_auth_response, token(%p): %s", pg_cloud_token, pg_cloud_token);
 
 	struct json_object *jcreaterole = NULL;
 	if (!json_object_object_get_ex(response, "cancreateuser", &jcreaterole))
@@ -204,7 +204,7 @@ static int parse_cloud_auth_response(char* buffer, int *result, char **errormsg)
 		return -1;
 	}
 	pg_cloud_createrole = json_object_get_boolean(jcreaterole);
-	elog(INFO, "pg_cloud_createrole=%d", pg_cloud_createrole);
+	elog(DEBUG3, "pg_cloud_createrole=%d", pg_cloud_createrole);
 
 	struct json_object *jresult = NULL;
 	if (!json_object_object_get_ex(response, "result", &jresult))
@@ -260,7 +260,7 @@ static int parse_cloud_sync_response(char* buffer, int *result, char **errormsg)
 	}
 
 	int ok = json_object_get_boolean(jresult);
-	elog(INFO, "in parse_cloud_sync_response, ret=%d", ok);
+	elog(DEBUG3, "in parse_cloud_sync_response, ret=%d", ok);
 	if (ok == 0)
 	{
 		*result = CLOUDSYNC_OK;
@@ -441,6 +441,6 @@ int check_authentication_from_cloud(char *username, char *password,
 		curl_context_cloud.response.response_size = 0;
 	}
 
-	elog(INFO, "in check_authentication_from_cloud: ret=%d", result);
+	elog(DEBUG3, "in check_authentication_from_cloud: ret=%d", result);
 	return result;
 }


[hawq] 02/05: HAWQ-1682. Remove useless log for cloud authentication

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

huor pushed a commit to branch huor_cloud
in repository https://gitbox.apache.org/repos/asf/hawq.git

commit 20d8b1f3dd8db2d967a5e0d2716729be0e9a3695
Author: wcl14 <wa...@126.com>
AuthorDate: Tue May 29 16:46:53 2018 +0800

    HAWQ-1682. Remove useless log for cloud authentication
---
 src/backend/commands/user.c | 7 ++++---
 src/backend/libpq/auth.c    | 5 ++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index d1da5a5..7252918 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -559,7 +559,7 @@ CreateRole(CreateRoleStmt *stmt)
 		char *errormsg;
 		int ret = check_authentication_from_cloud(stmt->role, password,
 				&createrole, USER_SYNC, "create", &errormsg);
-		elog(INFO, "in CreateRole, ret=%d", ret);
+		elog(DEBUG3, "in CreateRole, ret=%d", ret);
 		if (ret)
 		{
 			/*
@@ -1158,7 +1158,7 @@ AlterRole(AlterRoleStmt *stmt)
 			ret = check_authentication_from_cloud(stmt->role, NULL,
 					&new_record[Anum_pg_authid_rolcreaterole - 1], USER_SYNC,
 					"alter", &errormsg);
-			elog(INFO, "in AlterRole, ret=%d", ret);
+			elog(DEBUG3, "in AlterRole, ret=%d", ret);
 			if (ret)
 			{
 				elog(ERROR, "%s", errormsg);
@@ -1212,7 +1212,7 @@ AlterRole(AlterRoleStmt *stmt)
 			int ret;
 			ret = check_authentication_from_cloud(stmt->role, password, NULL,
 					USER_SYNC, "alter", &errormsg);
-			elog(INFO, "in AlterRole, ret=%d", ret);
+			elog(DEBUG3, "in AlterRole, ret=%d", ret);
 			if (ret)
 			{
 				elog(ERROR, "%s", errormsg);
@@ -1644,6 +1644,7 @@ DropRole(DropRoleStmt *stmt)
 			char *errormsg;
 			int ret = check_authentication_from_cloud(role, NULL, NULL,
 					USER_SYNC, "drop", &errormsg);
+			elog(DEBUG3, "in DropRole, ret=%d", ret);
 			if (ret)
 			{
 				elog(ERROR, "%s", errormsg);
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 1e0e888..1475ca0 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -2721,7 +2721,8 @@ CheckCloudAuth(Port *port)
 
 	pg_cloud_auth = true;
 
-	elog(LOG, "in CheckCloudAuth, port->hba->cloudserver=%s, pg_cloud_clustername=%s", port->hba->cloudserver, pg_cloud_clustername);
+	elog(
+			DEBUG3, "in CheckCloudAuth, port->hba->cloudserver=%s, pg_cloud_clustername=%s", port->hba->cloudserver, pg_cloud_clustername);
 	if (!port->hba->cloudserver || port->hba->cloudserver[0] == '\0')
 	{
 		ereport(LOG,
@@ -2742,11 +2743,9 @@ CheckCloudAuth(Port *port)
 		return STATUS_ERROR;
 	}
 
-	elog(LOG, "in CheckCloudAuth, before init_cloud_curl");
 	init_cloud_curl();
 
 	char *errormsg;
-	elog(LOG, "in CheckCloudAuth, before check_authentication_from_cloud");
 	result = check_authentication_from_cloud(port->user_name, passwd, NULL,
 			AUTHENTICATION_CHECK, "", &errormsg);
 	if (result)