From 81ae6f9b243e6cf80d4025a17eb48e966812b52e Mon Sep 17 00:00:00 2001
From: Vladimir Davydov <vdavydov.dev@gmail.com>
Date: Mon, 15 Jan 2018 15:28:34 +0300
Subject: [PATCH] session: make access_check_universe usable from C code

Replace tnt_raise() with diag_set() and add a wrapper that raises
exception in case of error to be used in C++ code.

While we are at it, let's also move access_check_session_xc() to
the header file, because it's a trivial wrapper.
---
 src/box/box.cc     |  4 ++--
 src/box/call.cc    |  2 +-
 src/box/session.cc | 31 +++++++++++++++++--------------
 src/box/session.h  | 21 +++++++++++++++++----
 4 files changed, 37 insertions(+), 21 deletions(-)

diff --git a/src/box/box.cc b/src/box/box.cc
index 9019315afa..a253d4cdcd 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -1217,7 +1217,7 @@ box_process_join(struct ev_io *io, struct xrow_header *header)
 		tnt_raise(ClientError, ER_CONNECTION_TO_SELF);
 
 	/* Check permissions */
-	access_check_universe(PRIV_R);
+	access_check_universe_xc(PRIV_R);
 	access_check_space_xc(space_cache_find_xc(BOX_CLUSTER_ID), PRIV_W);
 
 	/* Check that we actually can register a new replica */
@@ -1320,7 +1320,7 @@ box_process_subscribe(struct ev_io *io, struct xrow_header *header)
 		tnt_raise(ClientError, ER_CONNECTION_TO_SELF);
 
 	/* Check permissions */
-	access_check_universe(PRIV_R);
+	access_check_universe_xc(PRIV_R);
 
 	/**
 	 * Check that the given UUID matches the UUID of the
diff --git a/src/box/call.cc b/src/box/call.cc
index b597dac3ba..ed7c833ab6 100644
--- a/src/box/call.cc
+++ b/src/box/call.cc
@@ -248,7 +248,7 @@ box_process_eval(struct call_request *request, struct obuf *out)
 {
 	rmean_collect(rmean_box, IPROTO_EVAL, 1);
 	/* Check permissions */
-	access_check_universe(PRIV_X);
+	access_check_universe_xc(PRIV_X);
 	if (box_lua_eval(request, out) != 0) {
 		txn_rollback();
 		diag_raise();
diff --git a/src/box/session.cc b/src/box/session.cc
index cb31cc5fd6..d0a57d12b2 100644
--- a/src/box/session.cc
+++ b/src/box/session.cc
@@ -249,15 +249,7 @@ access_check_session(struct user *user)
 	return 0;
 }
 
-void
-access_check_session_xc(struct user *user)
-{
-	if (access_check_session(user) < 0) {
-		diag_raise();
-	}
-}
-
-void
+int
 access_check_universe(user_access_t access)
 {
 	struct credentials *credentials = effective_user();
@@ -268,12 +260,23 @@ access_check_universe(user_access_t access)
 		 * The user may not exist already, if deleted
 		 * from a different connection.
 		 */
-		struct user *user = user_find_xc(credentials->uid);
 		int denied_access = access & ((credentials->universal_access
 					       & access) ^ access);
-		tnt_raise(AccessDeniedError,
-			 priv_name(denied_access),
-			 schema_object_name(SC_UNIVERSE), "",
-			 user->def->name);
+		struct user *user = user_find(credentials->uid);
+		if (user != NULL) {
+			diag_set(AccessDeniedError,
+				 priv_name(denied_access),
+				 schema_object_name(SC_UNIVERSE), "",
+				 user->def->name);
+		} else {
+			/*
+			 * The user may have been dropped, in
+			 * which case user_find() will set the
+			 * error.
+			 */
+			assert(!diag_is_empty(&fiber()->diag));
+		}
+		return -1;
 	}
+	return 0;
 }
diff --git a/src/box/session.h b/src/box/session.h
index cc3e5f5e90..4f9235ea83 100644
--- a/src/box/session.h
+++ b/src/box/session.h
@@ -248,19 +248,32 @@ session_run_on_auth_triggers(const struct on_auth_trigger_ctx *result);
 int
 access_check_session(struct user *user);
 
-void
-access_check_session_xc(struct user *user);
-
 /**
  * Check whether or not the current user can be granted
  * the requested access to the universe.
  */
-void
+int
 access_check_universe(user_access_t access);
 
 #if defined(__cplusplus)
 } /* extern "C" */
 
+#include "diag.h"
+
+static inline void
+access_check_session_xc(struct user *user)
+{
+	if (access_check_session(user) != 0)
+		diag_raise();
+}
+
+static inline void
+access_check_universe_xc(user_access_t access)
+{
+	if (access_check_universe(access) != 0)
+		diag_raise();
+}
+
 #endif /* defined(__cplusplus) */
 
 #endif /* INCLUDES_TARANTOOL_SESSION_H */
-- 
GitLab