diff --git a/server/core/config.c b/server/core/config.c index 9330d1665..f86f97949 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -92,7 +92,7 @@ static void global_defaults(); static void feedback_defaults(); static void check_config_objects(CONFIG_CONTEXT *context); int config_truth_value(char *str); -int internalService(char *router); +int isInternalService(char *router); int config_get_ifaddr(unsigned char *output); int config_get_release_string(char* release); FEEDBACK_CONF * config_get_feedback_data(); @@ -898,7 +898,7 @@ process_config_context(CONFIG_CONTEXT *context) s = strtok_r(NULL, ",", &lasts); } } - else if (servers == NULL && internalService(router) == 0) + else if (servers == NULL && isInternalService(router) == 0) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, @@ -1107,7 +1107,7 @@ process_config_context(CONFIG_CONTEXT *context) monitorAddUser(obj->element, user, passwd); - valid_monitor_permissions(obj->element); + check_monitor_permissions(obj->element); } else if (obj->element && user) { @@ -2231,7 +2231,7 @@ static char *InternalRouters[] = { * @return Non-zero if the router is in the InternalRouters table */ int -internalService(char *router) +isInternalService(char *router) { int i; diff --git a/server/core/dbusers.c b/server/core/dbusers.c index c4b41259f..724381313 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -2323,30 +2323,32 @@ int add_wildcard_users(USERS *users, char* name, char* host, char* password, cha * is logged. * @param service Service to inspect */ -void valid_service_permissions(SERVICE* service) +bool check_service_permissions(SERVICE* service) { MYSQL* mysql; MYSQL_RES* res; char *user,*password,*dpasswd; SERVER_REF* server; int conn_timeout = 1; + bool rval = true; - if(internalService(service->routerModule)) - return; + if(isInternalService(service->routerModule)) + return true; if(service->dbref == NULL) { - skygw_log_write(LE,"[%s] Error: Service is missing the servers parameter.",service->name); - return; + skygw_log_write(LE,"%s: Error: Service is missing the servers parameter.",service->name); + return false; } server = service->dbref; if (serviceGetUser(service, &user, &password) == 0) { - skygw_log_write(LE,"[%s] Error: Service %s is missing the user credentials for authentication.", - __FUNCTION__,service->name); - return; + skygw_log_write(LE, + "%s: Error: Service is missing the user credentials for authentication.", + service->name); + return false; } dpasswd = decryptPassword(password); @@ -2355,7 +2357,7 @@ void valid_service_permissions(SERVICE* service) { skygw_log_write(LE,"[%s] Error: MySQL connection initialization failed.",__FUNCTION__); free(dpasswd); - return; + return false; } mysql_options(mysql,MYSQL_OPT_USE_REMOTE_CONNECTION,NULL); @@ -2365,7 +2367,7 @@ void valid_service_permissions(SERVICE* service) if(mysql_real_connect(mysql,server->server->name,user,dpasswd,NULL,server->server->port,NULL,0) == NULL) { - skygw_log_write(LE,"[%s] Error: Failed to connect to server %s(%s:%d) when" + skygw_log_write(LE,"%s: Error: Failed to connect to server %s(%s:%d) when" " checking authentication user credentials and permissions.", service->name, server->server->unique_name, @@ -2373,46 +2375,64 @@ void valid_service_permissions(SERVICE* service) server->server->port); mysql_close(mysql); free(dpasswd); - return; + return false; } if(mysql_query(mysql,"SELECT user, host, password,Select_priv FROM mysql.user limit 1") != 0) { if(mysql_errno(mysql) == ER_TABLEACCESS_DENIED_ERROR) { - skygw_log_write(LE,"[%s] Error: User '%s' is missing SELECT privileges on mysql.user table. MySQL error message: %s", + skygw_log_write(LE,"%s: Error: User '%s' is missing SELECT privileges" + " on mysql.user table. MySQL error message: %s", service->name,user,mysql_error(mysql)); + rval = false; } else { - skygw_log_write(LE,"[%s] Error: Failed to query from mysql.user table. MySQL error message: %s", + skygw_log_write(LE,"%s: Error: Failed to query from mysql.user table." + " MySQL error message: %s", service->name,mysql_error(mysql)); } - mysql_close(mysql); - free(dpasswd); - return; } - mysql_free_result(mysql_use_result(mysql)); + if((res = mysql_use_result(mysql)) == NULL) + { + skygw_log_write(LE,"%s: Error: Result retrieval failed when checking for" + " permissions to the mysql.user table: %s", + service->name,mysql_error(mysql)); + mysql_close(mysql); + free(dpasswd); + return rval; + } + + mysql_free_result(res); if(mysql_query(mysql,"SELECT user, host, db FROM mysql.db limit 1") != 0) { if(mysql_errno(mysql) == ER_TABLEACCESS_DENIED_ERROR) { - skygw_log_write(LE,"[%s] Error: User '%s' is missing SELECT privileges on mysql.db table. MySQL error message: %s", + skygw_log_write(LE,"%s: Error: User '%s' is missing SELECT privileges on mysql.db table. MySQL error message: %s", service->name,user,mysql_error(mysql)); + rval = false; } else { - skygw_log_write(LE,"[%s] Error: Failed to query from mysql.user table. MySQL error message: %s", + skygw_log_write(LE,"%s: Error: Failed to query from mysql.db table. MySQL error message: %s", service->name,mysql_error(mysql)); } - mysql_close(mysql); - free(dpasswd); - return; } - mysql_free_result(mysql_use_result(mysql)); + if((res = mysql_use_result(mysql)) == NULL) + { + skygw_log_write(LE,"%s: Error: Result retrieval failed when checking for permissions to the mysql.db table: %s", + service->name,mysql_error(mysql)); + } + else + { + mysql_free_result(res); + } + mysql_close(mysql); free(dpasswd); + return rval; } \ No newline at end of file diff --git a/server/core/monitor.c b/server/core/monitor.c index ae1dd250b..f0a004086 100644 --- a/server/core/monitor.c +++ b/server/core/monitor.c @@ -51,8 +51,6 @@ extern __thread log_info_t tls_log_info; static MONITOR *allMonitors = NULL; static SPINLOCK monLock = SPINLOCK_INIT; -void valid_monitor_permissions(MONITOR* monitor); - /** * Allocate a new monitor, load the associated module for the monitor * and start execution on the monitor. @@ -458,13 +456,14 @@ int *data; * this checks for REPLICATION CLIENT permissions * @param service Monitor to inspect */ -void valid_monitor_permissions(MONITOR* monitor) +bool check_monitor_permissions(MONITOR* monitor) { MYSQL* mysql; MYSQL_RES* res; char *user,*dpasswd; SERVER* server; int conn_timeout = 1; + bool rval = true; user = monitor->user; dpasswd = decryptPassword(monitor->password); @@ -473,7 +472,7 @@ void valid_monitor_permissions(MONITOR* monitor) { skygw_log_write(LE,"[%s] Error: MySQL connection initialization failed.",__FUNCTION__); free(dpasswd); - return; + return false; } server = monitor->databases->server; @@ -484,7 +483,7 @@ void valid_monitor_permissions(MONITOR* monitor) * user permissions. */ if(mysql_real_connect(mysql,server->name,user,dpasswd,NULL,server->port,NULL,0) == NULL) { - skygw_log_write(LE,"[%s] Error: Failed to connect to server %s(%s:%d) when" + skygw_log_write(LE,"%s: Error: Failed to connect to server %s(%s:%d) when" " checking monitor user credentials and permissions.", monitor->name, server->unique_name, @@ -492,27 +491,36 @@ void valid_monitor_permissions(MONITOR* monitor) server->port); mysql_close(mysql); free(dpasswd); - return; + return true; } if(mysql_query(mysql,"show slave status") != 0) { if(mysql_errno(mysql) == ER_SPECIFIC_ACCESS_DENIED_ERROR) { - skygw_log_write(LE,"[%s] Error: User '%s' is missing REPLICATION CLIENT privileges. MySQL error message: %s", + skygw_log_write(LE,"%s: Error: User '%s' is missing REPLICATION CLIENT privileges. MySQL error message: %s", monitor->name,mysql_error(mysql)); + rval = false; } else { - skygw_log_write(LE,"[%s] Error: Monitor failed to query for slave status. MySQL error message: %s", + skygw_log_write(LE,"%s: Error: Monitor failed to query for slave status. MySQL error message: %s", monitor->name,mysql_error(mysql)); } - mysql_close(mysql); - free(dpasswd); - return; } - - mysql_free_result(mysql_use_result(mysql)); + else + { + if((res = mysql_use_result(mysql)) == NULL) + { + skygw_log_write(LE,"%s: Error: Result retrieval failed when checking for REPLICATION CLIENT permissions: %s", + monitor->name,mysql_error(mysql)); + free(dpasswd); + mysql_close(mysql); + return rval; + } + mysql_free_result(res); + } mysql_close(mysql); free(dpasswd); + return rval; } \ No newline at end of file diff --git a/server/core/service.c b/server/core/service.c index 7ba249c44..b5a0066e5 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -417,6 +417,16 @@ serviceStart(SERVICE *service) SERV_PROTOCOL *port; int listeners = 0; + +if(!check_service_permissions(service)) +{ + skygw_log_write_flush(LE, + "%s: Inadequate user permissions for service. Service not started.", + service->name); + service->state = SERVICE_STATE_FAILED; + return 0; +} + if(service->ssl_mode != SSL_DISABLED) { if(serviceInitSSL(service) != 0) @@ -438,8 +448,6 @@ if(service->ssl_mode != SSL_DISABLED) return 0; } - valid_service_permissions(service); - port = service->ports; while (!service->svc_do_shutdown && port) { diff --git a/server/include/dbusers.h b/server/include/dbusers.h index 0d78cd548..4f2d2c787 100644 --- a/server/include/dbusers.h +++ b/server/include/dbusers.h @@ -68,5 +68,5 @@ extern char *mysql_users_fetch(USERS *users, MYSQL_USER_HOST *key); extern int replace_mysql_users(SERVICE *service); extern int dbusers_save(USERS *, char *); extern int dbusers_load(USERS *, char *); -void valid_service_permissions(SERVICE* service); +bool check_service_permissions(SERVICE* service); #endif diff --git a/server/include/maxconfig.h b/server/include/maxconfig.h index 6cfa1cb1a..58d9a7ac5 100644 --- a/server/include/maxconfig.h +++ b/server/include/maxconfig.h @@ -146,5 +146,5 @@ void config_enable_feedback_task(void); void config_disable_feedback_task(void); unsigned long config_get_gateway_id(void); GATEWAY_CONF* config_get_global_options(); -int internalService(char *router); +int isInternalService(char *router); #endif diff --git a/server/include/monitor.h b/server/include/monitor.h index e3a46cffc..1841112ca 100644 --- a/server/include/monitor.h +++ b/server/include/monitor.h @@ -169,5 +169,5 @@ extern void monitorList(DCB *); extern void monitorSetInterval (MONITOR *, unsigned long); extern void monitorSetNetworkTimeout(MONITOR *, int, int); extern RESULTSET *monitorGetList(); -void valid_monitor_permissions(MONITOR* monitor); +bool check_monitor_permissions(MONITOR* monitor); #endif