Extending MySQL using the Component Infrastructure – part 5: privileges

This post is the fifth post of a series of articles on extending MySQL with the Component Infrastructure, the list above will be updated as new articles are published:

We are back to our component and we will see how we can use the dynamic privilege component service to add a new privilege when we install our component.

This privilege will be checked later when we will create our functions.

Of course, when we uninstall our component, the privilege also needs to be removed.

In this article we will only register and “unregister” our privilege and add a message in error log.

As usual we start with our scan.h file:

/* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is also distributed with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#define LOG_COMPONENT_TAG "viruscan"
#include <mysql/components/component_implementation.h>
#include <mysql/components/services/log_builtins.h> /* LogComponentErr */
#include <mysqld_error.h> /* Errors */
#include <mysql/components/services/dynamic_privilege.h>
extern REQUIRES_SERVICE_PLACEHOLDER(log_builtins);
extern REQUIRES_SERVICE_PLACEHOLDER(log_builtins_string);
extern REQUIRES_SERVICE_PLACEHOLDER(dynamic_privilege_register);
extern SERVICE_TYPE(log_builtins) * log_bi;
extern SERVICE_TYPE(log_builtins_string) * log_bs;
view raw scan.h hosted with ❤ by GitHub

To create our privilege, we included the dynamic privilege component service header (line 24) and place holder (line 28).

We can now modify the code of scan.cc to register and unregister our new privilege:

/* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is also distributed with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#define LOG_COMPONENT_TAG "viruscan"
#define NO_SIGNATURE_CHANGE 0
#define SIGNATURE_CHANGE 1
#include <components/viruscan/scan.h>
REQUIRES_SERVICE_PLACEHOLDER(log_builtins);
REQUIRES_SERVICE_PLACEHOLDER(log_builtins_string);
REQUIRES_SERVICE_PLACEHOLDER(dynamic_privilege_register);
SERVICE_TYPE(log_builtins) * log_bi;
SERVICE_TYPE(log_builtins_string) * log_bs;
static const char *SCAN_PRIVILEGE_NAME = "VIRUS_SCAN";
static mysql_service_status_t viruscan_service_init() {
mysql_service_status_t result = 0;
log_bi = mysql_service_log_builtins;
log_bs = mysql_service_log_builtins_string;
LogComponentErr(INFORMATION_LEVEL, ER_LOG_PRINTF_MSG, "initializing…");
// Registration of the privilege
if (mysql_service_dynamic_privilege_register->register_privilege(SCAN_PRIVILEGE_NAME, strlen(SCAN_PRIVILEGE_NAME))) {
LogComponentErr(ERROR_LEVEL, ER_LOG_PRINTF_MSG,
"could not register privilege 'VIRUS_SCAN'.");
result = 1;
} else {
LogComponentErr(INFORMATION_LEVEL, ER_LOG_PRINTF_MSG,
"new privilege 'VIRUS_SCAN' has been registered successfully.");
}
return result;
}
static mysql_service_status_t viruscan_service_deinit() {
mysql_service_status_t result = 0;
if (mysql_service_dynamic_privilege_register->unregister_privilege(SCAN_PRIVILEGE_NAME, strlen(SCAN_PRIVILEGE_NAME))) {
LogComponentErr(ERROR_LEVEL, ER_LOG_PRINTF_MSG,
"could not unregister privilege 'VIRUS_SCAN'.");
result = 1;
} else {
LogComponentErr(INFORMATION_LEVEL, ER_LOG_PRINTF_MSG,
"privilege 'VIRUS_SCAN' has been unregistered successfully.");
}
LogComponentErr(INFORMATION_LEVEL, ER_LOG_PRINTF_MSG, "uninstalled.");
return result;
}
BEGIN_COMPONENT_PROVIDES(viruscan_service)
END_COMPONENT_PROVIDES();
BEGIN_COMPONENT_REQUIRES(viruscan_service)
REQUIRES_SERVICE(log_builtins),
REQUIRES_SERVICE(log_builtins_string),
REQUIRES_SERVICE(dynamic_privilege_register),
END_COMPONENT_REQUIRES();
/* A list of metadata to describe the Component. */
BEGIN_COMPONENT_METADATA(viruscan_service)
METADATA("mysql.author", "Oracle Corporation"),
METADATA("mysql.license", "GPL"), METADATA("mysql.dev", "lefred"),
END_COMPONENT_METADATA();
/* Declaration of the Component. */
DECLARE_COMPONENT(viruscan_service,
"mysql:viruscan_service")
viruscan_service_init,
viruscan_service_deinit END_DECLARE_COMPONENT();
/* Defines list of Components contained in this library. Note that for now
we assume that library will have exactly one Component. */
DECLARE_LIBRARY_COMPONENTS &COMPONENT_REF(viruscan_service)
END_DECLARE_LIBRARY_COMPONENTS
view raw scan.cc hosted with ❤ by GitHub

On line 32 we added the place holder and we require the service on line 86.

Lines 47 to 55 si the registration of the privilege with a message to error log. The “unregistration” is coded from line 60 to 75.

As you can see this is very easy when using the component infrastructure.

Let’s test it:

Great ! We can now create a component that adds new privileges to MySQL.

On the next article we will create our first function.

Stay tuned and enjoy MySQL coding !

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

11 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

As MySQL Community Manager, I am an employee of Oracle and the views expressed on this blog are my own and do not necessarily reflect the views of Oracle.

You can find articles I wrote on Oracle’s blog.