diff --git a/src/box/alter.cc b/src/box/alter.cc
index 76bbcaa3ce8d19334fe16b23fd304adde765b863..5e3bb4c6756b40693fa69d2a05976dce0a1bbd17 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -3751,12 +3751,13 @@ priv_def_create_from_tuple(struct priv_def *priv, struct tuple *tuple)
 	case MP_STR:
 		if (mp_decode_strl(&data) == 0) {
 			/* Entity-wide privilege. */
+			priv->is_entity_access = true;
 			priv->object_id = 0;
-			priv->object_type = schema_entity_type(priv->object_type);
 			break;
 		}
 		FALLTHROUGH;
 	default:
+		priv->is_entity_access = false;
 		if (tuple_field_u32(tuple,
 		    BOX_PRIV_FIELD_OBJECT_ID, &(priv->object_id)) != 0)
 			return -1;
@@ -3799,18 +3800,10 @@ priv_def_check(struct priv_def *priv, enum priv_type priv_type)
 	const char *name = "";
 	struct access *object = NULL;
 	switch (priv->object_type) {
-	case SC_UNIVERSE:
-		if (grantor->def->uid != ADMIN) {
-			diag_set(AccessDeniedError,
-				  priv_name(priv_type),
-				  schema_object_name(SC_UNIVERSE),
-				  name,
-				  grantor->def->name);
-			return -1;
-		}
-		break;
 	case SC_SPACE:
 	{
+		if (priv->is_entity_access)
+			break;
 		struct space *space = space_cache_find(priv->object_id);
 		if (space == NULL)
 			return -1;
@@ -3828,6 +3821,8 @@ priv_def_check(struct priv_def *priv, enum priv_type priv_type)
 	}
 	case SC_FUNCTION:
 	{
+		if (priv->is_entity_access)
+			break;
 		struct func *func = func_by_id(priv->object_id);
 		if (func == NULL) {
 			diag_set(ClientError, ER_NO_SUCH_FUNCTION, int2str(priv->object_id));
@@ -3847,6 +3842,8 @@ priv_def_check(struct priv_def *priv, enum priv_type priv_type)
 	}
 	case SC_SEQUENCE:
 	{
+		if (priv->is_entity_access)
+			break;
 		struct sequence *seq = sequence_by_id(priv->object_id);
 		if (seq == NULL) {
 			diag_set(ClientError, ER_NO_SUCH_SEQUENCE, int2str(priv->object_id));
@@ -3866,6 +3863,8 @@ priv_def_check(struct priv_def *priv, enum priv_type priv_type)
 	}
 	case SC_ROLE:
 	{
+		if (priv->is_entity_access)
+			break;
 		struct user *role = user_by_id(priv->object_id);
 		if (role == NULL || role->def->type != SC_ROLE) {
 			diag_set(ClientError, ER_NO_SUCH_ROLE,
@@ -3895,6 +3894,8 @@ priv_def_check(struct priv_def *priv, enum priv_type priv_type)
 	}
 	case SC_USER:
 	{
+		if (priv->is_entity_access)
+			break;
 		struct user *user = user_by_id(priv->object_id);
 		if (user == NULL || user->def->type != SC_USER) {
 			diag_set(ClientError, ER_NO_SUCH_USER,
@@ -3914,23 +3915,16 @@ priv_def_check(struct priv_def *priv, enum priv_type priv_type)
 		}
 		break;
 	}
-	case SC_ENTITY_SPACE:
-	case SC_ENTITY_FUNCTION:
-	case SC_ENTITY_SEQUENCE:
-	case SC_ENTITY_ROLE:
-	case SC_ENTITY_USER:
-	{
-		/* Only admin may grant privileges on an entire entity. */
-		if (grantor->def->uid != ADMIN) {
-			diag_set(AccessDeniedError, priv_name(priv_type),
-				 schema_entity_name(priv->object_type), name,
-				  grantor->def->name);
-			return -1;
-		}
-	}
 	default:
 		break;
 	}
+	/* Only admin may grant privileges on an entire entity. */
+	if (object == NULL && grantor->def->uid != ADMIN) {
+		diag_set(AccessDeniedError, priv_name(priv_type),
+			 schema_object_name(priv->object_type), name,
+			 grantor->def->name);
+		return -1;
+	}
 	if (access_check_ddl(name, grantor->def->uid, object,
 			     priv->object_type, priv_type) != 0)
 		return -1;
diff --git a/src/box/schema.h b/src/box/schema.h
index 95ee598e98b8f515bb196611164201b6fad0aa4f..5e16a7d40aa7fd0ca4dc64a425db4afd68844e77 100644
--- a/src/box/schema.h
+++ b/src/box/schema.h
@@ -177,19 +177,14 @@ entity_access_get(enum schema_object_type type)
 {
 	switch (type) {
 	case SC_SPACE:
-	case SC_ENTITY_SPACE:
 		return entity_access.space;
 	case SC_FUNCTION:
-	case SC_ENTITY_FUNCTION:
 		return entity_access.function;
 	case SC_USER:
-	case SC_ENTITY_USER:
 		return entity_access.user;
 	case SC_ROLE:
-	case SC_ENTITY_ROLE:
 		return entity_access.role;
 	case SC_SEQUENCE:
-	case SC_ENTITY_SEQUENCE:
 		return entity_access.sequence;
 	default:
 		return NULL;
diff --git a/src/box/schema_def.c b/src/box/schema_def.c
index f028efe4a8c1809907f30774e22796cdc0d239e6..cbfad479ac1c22767e14952cb9e869e86199ca4e 100644
--- a/src/box/schema_def.c
+++ b/src/box/schema_def.c
@@ -46,32 +46,6 @@ static const char *object_type_strs[] = {
 	/* [SC_COLLATION]       = */ "collation",
 };
 
-/** Given object type @type, return corresponding entity type. */
-static enum schema_object_type
-schema_object_type_to_entity(enum schema_object_type type)
-{
-	assert(type >= SC_SPACE);
-	assert((int) type < (int) schema_object_type_MAX);
-	return type + schema_object_type_MAX - 1;
-}
-
-/** Given entity type @type, return corresponding object type. */
-static enum schema_object_type
-schema_entity_type_to_object(enum schema_object_type type)
-{
-	assert((int) type > (int) schema_object_type_MAX);
-	assert((int) type < (int) schema_entity_type_MAX);
-	return (type % (schema_object_type_MAX)) + 1;
-}
-
-enum schema_object_type
-schema_entity_type(enum schema_object_type type)
-{
-	if (type <= SC_UNIVERSE || type >= schema_object_type_MAX)
-		return SC_UNKNOWN;
-	return schema_object_type_to_entity(type);
-}
-
 enum schema_object_type
 schema_object_type(const char *name)
 {
@@ -91,9 +65,3 @@ schema_object_name(enum schema_object_type type)
 	assert((int) type < (int) schema_object_type_MAX);
 	return object_type_strs[type];
 }
-
-const char *
-schema_entity_name(enum schema_object_type type)
-{
-	return object_type_strs[schema_entity_type_to_object(type)];
-}
diff --git a/src/box/schema_def.h b/src/box/schema_def.h
index cb8faca2dde4dea40ad9315c7347e2a002c4dfe5..60d2340015f3e4c6f93242492a51bb34403924b0 100644
--- a/src/box/schema_def.h
+++ b/src/box/schema_def.h
@@ -302,25 +302,14 @@ enum {
  */
 enum schema_object_type {
 	SC_UNKNOWN = 0,
-	SC_UNIVERSE = 1,
-	SC_SPACE = 2,
-	SC_FUNCTION = 3,
-	SC_USER = 4,
-	SC_ROLE = 5,
-	SC_SEQUENCE = 6,
-	SC_COLLATION = 7,
-	/*
-	 * All object types are supposed to be above this point,
-	 * all entity types - below.
-	 */
-	schema_object_type_MAX = 8,
-	SC_ENTITY_SPACE,
-	SC_ENTITY_FUNCTION,
-	SC_ENTITY_USER,
-	SC_ENTITY_ROLE,
-	SC_ENTITY_SEQUENCE,
-	SC_ENTITY_COLLATION,
-	schema_entity_type_MAX = 15
+	SC_UNIVERSE,
+	SC_SPACE,
+	SC_FUNCTION,
+	SC_USER,
+	SC_ROLE,
+	SC_SEQUENCE,
+	SC_COLLATION,
+	schema_object_type_MAX,
 };
 
 /** SQL Storage engine. */
@@ -332,21 +321,12 @@ enum sql_storage_engine {
 
 extern const char *sql_storage_engine_strs[];
 
-/**
- * Given a object type, return an entity type it belongs to.
- */
-enum schema_object_type
-schema_entity_type(enum schema_object_type type);
-
 enum schema_object_type
 schema_object_type(const char *name);
 
 const char *
 schema_object_name(enum schema_object_type type);
 
-const char *
-schema_entity_name(enum schema_object_type type);
-
 /**
  * Check that the space id corresponds to a system space, which means that is
  * has a special meaning for tarantool and has predefined insert/remove
diff --git a/src/box/user.cc b/src/box/user.cc
index e5b33598da996055d2caae0c37e897c1118d4485..5510f902171e9ab1fbbcd6f1f1abbf117672da6c 100644
--- a/src/box/user.cc
+++ b/src/box/user.cc
@@ -208,83 +208,52 @@ user_grant_priv(struct user *user, struct priv_def *def)
 }
 
 /**
- * Find the corresponding access structure
- * given object type and object id.
+ * Find the corresponding access structure for the given privilege.
  */
 static struct access *
-access_find(enum schema_object_type object_type, uint32_t object_id)
+access_find(const struct priv_def *priv)
 {
-	struct access *access = NULL;
-	switch (object_type) {
+	switch (priv->object_type) {
 	case SC_UNIVERSE:
-	{
-		access = universe.access;
-		break;
-	}
-	case SC_ENTITY_SPACE:
-	{
-		access = entity_access.space;
-		break;
-	}
-	case SC_ENTITY_FUNCTION:
-	{
-		access = entity_access.function;
-		break;
-	}
-	case SC_ENTITY_USER:
-	{
-		access = entity_access.user;
-		break;
-	}
-	case SC_ENTITY_ROLE:
-	{
-		access = entity_access.role;
-		break;
-	}
-	case SC_ENTITY_SEQUENCE:
-	{
-		access = entity_access.sequence;
-		break;
-	}
+		return universe.access;
 	case SC_SPACE:
 	{
-		struct space *space = space_by_id(object_id);
-		if (space)
-			access = space->access;
-		break;
+		if (priv->is_entity_access)
+			return entity_access.space;
+		struct space *space = space_by_id(priv->object_id);
+		return space != NULL ? space->access : NULL;
 	}
 	case SC_FUNCTION:
 	{
-		struct func *func = func_by_id(object_id);
-		if (func)
-			access = func->access;
-		break;
+		if (priv->is_entity_access)
+			return entity_access.function;
+		struct func *func = func_by_id(priv->object_id);
+		return func != NULL ? func->access : NULL;
 	}
 	case SC_USER:
 	{
-		struct user *user = user_by_id(object_id);
-		if (user)
-			access = user->access;
-		break;
+		if (priv->is_entity_access)
+			return entity_access.user;
+		struct user *user = user_by_id(priv->object_id);
+		return user != NULL ? user->access : NULL;
 	}
 	case SC_ROLE:
 	{
-		struct user *role = user_by_id(object_id);
-		if (role)
-			access = role->access;
-		break;
+		if (priv->is_entity_access)
+			return entity_access.role;
+		struct user *role = user_by_id(priv->object_id);
+		return role != NULL ? role->access : NULL;
 	}
 	case SC_SEQUENCE:
 	{
-		struct sequence *seq = sequence_by_id(object_id);
-		if (seq)
-			access = seq->access;
-		break;
+		if (priv->is_entity_access)
+			return entity_access.sequence;
+		struct sequence *seq = sequence_by_id(priv->object_id);
+		return seq != NULL ? seq->access : NULL;
 	}
 	default:
-		break;
+		return NULL;
 	}
-	return access;
 }
 
 
@@ -299,8 +268,7 @@ user_set_effective_access(struct user *user)
 	privset_ifirst(&user->privs, &it);
 	struct priv_def *priv;
 	while ((priv = privset_inext(&it)) != NULL) {
-		struct access *object = access_find(priv->object_type,
-						    priv->object_id);
+		struct access *object = access_find(priv);
 		 /* Protect against a concurrent drop. */
 		if (object == NULL)
 			continue;
@@ -759,7 +727,7 @@ role_revoke(struct user *grantee, struct user *role)
 int
 priv_grant(struct user *grantee, struct priv_def *priv)
 {
-	struct access *object = access_find(priv->object_type, priv->object_id);
+	struct access *object = access_find(priv);
 	if (object == NULL)
 		return 0;
 	if (grantee->auth_token == ADMIN && priv->object_type == SC_UNIVERSE &&
diff --git a/src/box/user_def.h b/src/box/user_def.h
index 7acc525b6af7b0e7a5eee3a0a8ca6b7d42cda82d..d4b3a7638383173841795b5e09c070fc2e68aa27 100644
--- a/src/box/user_def.h
+++ b/src/box/user_def.h
@@ -88,6 +88,11 @@ struct priv_def {
 	uint32_t grantee_id;
 	/* Object id - is only defined for object type */
 	uint32_t object_id;
+	/**
+	 * If this flag is set, the object id is unused and the privilege
+	 * should be applied to the whole object class.
+	 */
+	bool is_entity_access;
 	/* Object type - function, space, universe */
 	enum schema_object_type object_type;
 	/**