monitor.c revision 0887c35bdb85adf0a4376dc8963294ea5a9d6da6
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher Service monitor
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher Copyright (C) Simo Sorce 2008
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher This program is free software; you can redistribute it and/or modify
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher it under the terms of the GNU General Public License as published by
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher the Free Software Foundation; either version 3 of the License, or
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher (at your option) any later version.
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher This program is distributed in the hope that it will be useful,
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher but WITHOUT ANY WARRANTY; without even the implied warranty of
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher GNU General Public License for more details.
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher You should have received a copy of the GNU General Public License
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher along with this program. If not, see <http://www.gnu.org/licenses/>.
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher/* Needed for res_init() */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher#include "responder/common/responder_sbus.h"
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher/* ping time cannot be less then once every few seconds or the
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher * monitor will get crazy hammering children with messages */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher/* terminate the child after this interval by default if it
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher * doesn't shutdown on receiving SIGTERM */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher/* TODO: get the restart related values from config */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher#define MONITOR_RESTART_CNT_INTERVAL_RESET 30
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher/* maximum allowed number of service restarts if the restarts
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher * were less than MONITOR_RESTART_CNT_INTERVAL_RESET apart, which would
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher * indicate a crash after startup or after every request */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher/* The services are restarted with a delay in case the restart was
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher * hitting a race condition where the DP is not ready yet either.
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher * The MONITOR_MAX_RESTART_DELAY defines the maximum delay between
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher/* name of the monitor server instance */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher#define SSSD_PIDFILE_PATH PID_PATH"/"MONITOR_NAME".pid"
e0404de84c31d2387bb244d018a5cac8d01f8b19Simo Sorce/* Special value to leave the Kerberos Replay Cache set to use
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher * the libkrb5 defaults
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher#define KRB5_RCACHE_DIR_DISABLE "__LIBKRB5_DEFAULTS__"
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher/* Warning messages */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher#define CONF_FILE_PERM_ERROR_MSG "Cannot read config file %s. Please check "\
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "that the file is accessible only by the "\
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "owner and owned by root.root.\n"
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* For running unprivileged services */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int start_service(struct mt_svc *mt_svc);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int monitor_service_init(struct sbus_connection *conn, void *data);
3d8a87081a6cd197acbd355b5a39111669ec2aa6Jakub Hrozekstatic int service_send_ping(struct mt_svc *svc);
3d8a87081a6cd197acbd355b5a39111669ec2aa6Jakub Hrozekstatic int service_signal_reset_offline(struct mt_svc *svc);
3d8a87081a6cd197acbd355b5a39111669ec2aa6Jakub Hrozekstatic void ping_check(DBusPendingCall *pending, void *data);
3d8a87081a6cd197acbd355b5a39111669ec2aa6Jakub Hrozekstatic void set_tasks_checker(struct mt_svc *srv);
3d8a87081a6cd197acbd355b5a39111669ec2aa6Jakub Hrozekstatic int monitor_kill_service (struct mt_svc *svc);
3d8a87081a6cd197acbd355b5a39111669ec2aa6Jakub Hrozekstatic int get_service_config(struct mt_ctx *ctx, const char *name,
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int get_provider_config(struct mt_ctx *ctx, const char *name,
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int add_new_service(struct mt_ctx *ctx,
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int add_new_provider(struct mt_ctx *ctx,
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int mark_service_as_started(struct mt_svc *svc);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int monitor_cleanup(void);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic void network_status_change_cb(void *cb_data)
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher struct mt_ctx *ctx = (struct mt_ctx *) cb_data;
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher DEBUG(SSSDBG_TRACE_INTERNAL, "A networking status change detected "
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "signaling providers to reset offline status\n");
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher for (iter = ctx->svc_list; iter; iter = iter->next) {
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* Don't signal services, only providers */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher/* dbus_get_monitor_version
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher * Return the monitor version over D-BUS */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int get_monitor_version(struct sbus_request *dbus_req, void *data)
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher return sbus_request_return_and_finish(dbus_req,
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int add_svc_conn_spy(struct mt_svc *svc);
4a6a5421113ab662a665c62ed6a24b61a5a36950Jakub Hrozek/* registers a new client.
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher * if operation is successful also sends back the Monitor version */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int client_registration(struct sbus_request *dbus_req, void *data)
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher mini = talloc_get_type(data, struct mon_init_conn);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "Connection holds no valid init data\n");
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* First thing, cancel the timeout */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher dbret = dbus_message_get_args(dbus_req->message, &dbus_error,
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "Failed to parse message, killing connection\n");
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* FIXME: should we just talloc_zfree(conn) ? */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "Received ID registration: (%s,%d)\n", svc_name, svc_ver);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* search this service in the list */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher ret = strcasecmp(svc->identity, svc_name);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "Unable to find peer [%s] in list of services,"
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* FIXME: should we just talloc_zfree(conn) ? */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* Fill in svc structure with connection data */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "Failed to mark service [%s]!\n", svc_name);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* reply that all is ok */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* init complete, get rid of temp init context */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher struct mt_svc *svc = talloc_get_type(mem, struct mt_svc);
03abdaa21ecf562b714f204ca42379ff08626f75Simo Sorce /* try to delist service */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* Cancel any pending pings */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* svc is beeing freed, neutralize the spy */
03abdaa21ecf562b714f204ca42379ff08626f75Simo Sorce talloc_set_destructor((TALLOC_CTX *)svc->conn_spy, NULL);
6fb75e297bf7fc83e3db1f5ae8560624656ef319Jan Zeleny if (svc->type == MT_SVC_SERVICE && svc->svc_started
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher && svc->mt_ctx != NULL && svc->mt_ctx->started_services > 0) {
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher struct svc_spy *spy = talloc_get_type(mem, struct svc_spy);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* svc->conn has been freed, NULL the pointer in svc */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int add_svc_conn_spy(struct mt_svc *svc)
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher talloc_set_destructor((TALLOC_CTX *)spy, svc_spy_destructor);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int mark_service_as_started(struct mt_svc *svc)
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher DEBUG(SSSDBG_FUNC_DATA, "Marking %s as started.\n", svc->name);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* we need to attach a spy to the connection structure so that if some code
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher * frees it we can zero it out in the service structure. Otherwise we may
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher * try to access or even free, freed memory. */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "Failed to attch spy\n");
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* check if all providers are up */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher for (iter = ctx->svc_list; iter; iter = iter->next) {
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher if (iter->provider && !iter->svc_started) {
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "Still waiting on %s provider.\n", iter->name);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* there are still unstarted providers */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher DEBUG(SSSDBG_CONF_SETTINGS, "Now starting services!\n");
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* then start all services */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher add_new_service(ctx, ctx->services[i], 0);
03abdaa21ecf562b714f204ca42379ff08626f75Simo Sorce if (ctx->started_services == ctx->num_services) {
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* Initialization is complete, terminate parent process if in daemon
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher * mode. Make sure we send the signal to the right process */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher if (ctx->parent_pid <= 1 || ctx->parent_pid != getppid()) {
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* the parent process was already terminated */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher DEBUG(SSSDBG_MINOR_FAILURE, "Invalid parent pid: %d\n",
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher DEBUG(SSSDBG_TRACE_FUNC, "SSSD is initialized, "
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "terminating parent process\n");
94a66f84bd3c28fcabffeb84c682dccf89d89c2bSumit Bose DEBUG(SSSDBG_FATAL_FAILURE, "Unable to terminate parent "
b860f8b6b6b03982c80268e9f6fd35f6455b6b37Simo Sorcestatic void services_startup_timeout(struct tevent_context *ev,
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher struct mt_ctx *ctx = talloc_get_type(ptr, struct mt_ctx);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher DEBUG(SSSDBG_TRACE_FUNC, "Handling timeout\n");
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "Providers did not start in time, "
9b72b00ebcfd6225a4e139619c8e18d44a448f87Stephen Gallagher "forcing services startup!\n");
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher DEBUG(SSSDBG_CONF_SETTINGS, "Now starting services!\n");
9b72b00ebcfd6225a4e139619c8e18d44a448f87Stephen Gallagher /* then start all services */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher add_new_service(ctx, ctx->services[i], 0);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int add_services_startup_timeout(struct mt_ctx *ctx)
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* 5 seconds should be plenty */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher to = tevent_add_timer(ctx->ev, ctx, tv, services_startup_timeout, ctx);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n");
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher/* monitor_dbus_init
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher * Set up the monitor service as a D-BUS Server */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int monitor_dbus_init(struct mt_ctx *ctx)
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher ret = monitor_get_sbus_address(ctx, &monitor_address);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* If a service is running as unprivileged user, we need to make sure this
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher * user can access the monitor sbus server. root is still king, so we don't
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher * lose any access.
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher ret = sbus_new_server(ctx, ctx->ev, monitor_address, ctx->uid, ctx->gid,
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher false, &ctx->sbus_srv, monitor_service_init, ctx);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic void tasks_check_handler(struct tevent_context *ev,
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher struct mt_svc *svc = talloc_get_type(ptr, struct mt_svc);
4c08db0fb0dda3d27b1184248ca5c800d7ce23f0Michal Zidek /* all fine */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "Child (%s) not responding! (yet)\n", svc->name);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* TODO: should we tear it down ? */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "Sending a message to service (%s) failed!!\n", svc->name);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* too long since we last heard of this process */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "Killing service [%s], not responding to pings!\n",
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "Killing service [%s], not responding to pings!\n",
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* Kill the service. The SIGCHLD handler will restart it */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* all fine, set up the task checker again */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic void set_tasks_checker(struct mt_svc *svc)
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher te = tevent_add_timer(svc->mt_ctx->ev, svc, tv, tasks_check_handler, svc);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "failed to add event, monitor offline for [%s]!\n",
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* FIXME: shutdown ? */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic void mt_svc_sigkill(struct tevent_context *ev,
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int monitor_kill_service (struct mt_svc *svc)
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "Sending signal to child (%s:%d) failed: [%d]: %s! "
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "Ignore and pretend child is dead.\n",
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* Set up a timer to send SIGKILL if this process
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagher * doesn't exit within sixty seconds
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagher tv = tevent_timeval_current_ofs(svc->kill_time, 0);
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagher te = tevent_add_timer(svc->mt_ctx->ev, svc, tv, mt_svc_sigkill, svc);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* Nothing much we can do */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "Failed to allocate timed event: mt_svc_sigkill.\n");
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic void mt_svc_sigkill(struct tevent_context *ev,
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagher struct mt_svc *svc = talloc_get_type(ptr, struct mt_svc);
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagher "[%s][%d] is not responding to SIGTERM. Sending SIGKILL.\n",
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagher "[%s][%d] is not responding to SIGTERM. Sending SIGKILL.\n",
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagher "Sending signal to child (%s:%d) failed! "
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagher "Ignore and pretend child is dead.\n",
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagherstatic void reload_reply(DBusPendingCall *pending, void *data)
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagher struct mt_svc *svc = talloc_get_type(data, struct mt_svc);
c3d09c0095a45de1973f320ce2045ac74d4e4f83Jakub Hrozek reply = dbus_pending_call_steal_reply(pending);
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagher /* reply should never be null. This function shouldn't be called
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagher * until reply is valid or timeout has occurred. If reply is NULL
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagher * here, something is seriously wrong and we should bail out.
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "A reply callback was called but no reply was received"
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher " and no timeout occurred\n");
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* Destroy this connection */
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagher /* TODO: Handle cases where the call has timed out or returned
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagher * with an error.
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagherstatic int service_signal_dns_reload(struct mt_svc *svc);
f5e22261a2ff95f2a61f4f199fffb8de79668110Stephen Gallagherstatic int monitor_update_resolv(struct config_file_ctx *file_ctx,
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "Resolv.conf has been updated. Reloading.\n");
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* Signal all services to reload their DNS configuration */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher for(cur_svc = file_ctx->mt_ctx->svc_list; cur_svc; cur_svc = cur_svc->next) {
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int service_signal(struct mt_svc *svc, const char *svc_signal)
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher if (svc->provider && strcasecmp(svc->provider, "local") == 0) {
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* The local provider requires no signaling */
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher /* Avoid a race condition where we are trying to
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher * order a service to reload that hasn't started
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher "Could not signal service [%s].\n", svc->name);
9b72b00ebcfd6225a4e139619c8e18d44a448f87Stephen Gallagher "Out of memory trying to allocate memory to invoke: %s\n",
c1fcc832ccfc237caac8b99be238cf2d598f908cStephen Gallagherstatic int service_signal_dns_reload(struct mt_svc *svc)
c1fcc832ccfc237caac8b99be238cf2d598f908cStephen Gallagher return service_signal(svc, MON_CLI_IFACE_RESINIT);
c1fcc832ccfc237caac8b99be238cf2d598f908cStephen Gallagherstatic int service_signal_offline(struct mt_svc *svc)
c1fcc832ccfc237caac8b99be238cf2d598f908cStephen Gallagher return service_signal(svc, MON_CLI_IFACE_GOOFFLINE);
3d8a87081a6cd197acbd355b5a39111669ec2aa6Jakub Hrozekstatic int service_signal_reset_offline(struct mt_svc *svc)
c1fcc832ccfc237caac8b99be238cf2d598f908cStephen Gallagher return service_signal(svc, MON_CLI_IFACE_RESETOFFLINE);
c1fcc832ccfc237caac8b99be238cf2d598f908cStephen Gallagherstatic int service_signal_rotate(struct mt_svc *svc)
c1fcc832ccfc237caac8b99be238cf2d598f908cStephen Gallagher return service_signal(svc, MON_CLI_IFACE_ROTATELOGS);
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int service_signal_clear_memcache(struct mt_svc *svc)
c1fcc832ccfc237caac8b99be238cf2d598f908cStephen Gallagher return service_signal(svc, MON_CLI_IFACE_CLEARMEMCACHE);
c1fcc832ccfc237caac8b99be238cf2d598f908cStephen Gallagherstatic int service_signal_clear_enum_cache(struct mt_svc *svc)
c1fcc832ccfc237caac8b99be238cf2d598f908cStephen Gallagher return service_signal(svc, MON_CLI_IFACE_CLEARENUMCACHE);
3d8a87081a6cd197acbd355b5a39111669ec2aa6Jakub Hrozekstatic int service_signal_sysbus_reconnect(struct mt_svc *svc)
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher return service_signal(svc, MON_CLI_IFACE_SYSBUSRECONNECT);
c1fcc832ccfc237caac8b99be238cf2d598f908cStephen Gallagherstatic int check_domain_ranges(struct sss_domain_info *domains)
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagher struct sss_domain_info *dom = domains, *other = NULL;
c1fcc832ccfc237caac8b99be238cf2d598f908cStephen Gallagher if (dom->id_max && dom->id_min > dom->id_max) {
c1fcc832ccfc237caac8b99be238cf2d598f908cStephen Gallagher "Domain '%s' does not have a valid ID range\n", dom->name);
c1fcc832ccfc237caac8b99be238cf2d598f908cStephen Gallagher id_max = MIN((dom->id_max ? dom->id_max : UINT32_MAX),
c1fcc832ccfc237caac8b99be238cf2d598f908cStephen Gallagher (other->id_max ? other->id_max : UINT32_MAX));
c1fcc832ccfc237caac8b99be238cf2d598f908cStephen Gallagher "Domains '%s' and '%s' overlap in range %u - %u\n",
e134a6af42102c8d865e82bf89e0b8c5a40fb5faStephen Gallagherstatic int check_local_domain_unique(struct sss_domain_info *domains)
while (dom) {
count++;
return EINVAL;
return EOK;
char ***_services)
int ret;
char **domain_names;
size_t c;
char *conf_path;
char *id_provider;
bool add_pac = false;
return ENOMEM;
&domain_names);
goto done;
domain_names[c]);
goto done;
add_pac = true;
domain_names[c]);
goto done;
done:
return ret;
int ii;
for (i = 0; services[i]; i++) {
return services[i];
return NULL;
char *user_str;
return ret;
return ret;
return EOK;
int ret;
int timeout_seconds;
return ret;
return EINVAL;
return EINVAL;
return ret;
return ret;
return ret;
return ret;
return EOK;
return ret;
return ret;
return EOK;
int ret;
char *path;
if (!svc) {
return ENOMEM;
return ENOMEM;
return ENOMEM;
if (!path) {
return ENOMEM;
return ret;
return ENOMEM;
return ENOMEM;
return ENOMEM;
return ENOMEM;
return ENOMEM;
if (debug_to_file) {
return ENOMEM;
return ENOMEM;
return ret;
return EOK;
const char *name,
int restarts)
int ret;
return ret;
return ret;
int ret;
char *path;
if (!svc) {
return ENOMEM;
return ENOMEM;
return ENOMEM;
if (!path) {
return ENOMEM;
return ret;
return ret;
return ret;
return EIO;
return ENOMEM;
return ENOMEM;
return ENOMEM;
return ENOMEM;
return ENOMEM;
if (debug_to_file) {
return ENOMEM;
return ENOMEM;
return EOK;
const char *name,
int restarts)
int ret;
name);
return ret;
return ENOENT;
return ret;
int signum,
int count,
void *siginfo,
void *private_data)
static int monitor_cleanup(void)
int ret;
errno = 0;
return ret;
return EOK;
int status;
int kret;
bool killed;
killed = false;
errno = 0;
if (kret < 0) {
error = 0;
errno = 0;
killed = true;
} else if (pid != 0) {
error = 0;
killed = true;
if (!killed) {
} while (!killed);
#if HAVE_GETPGRP
error = 0;
errno = 0;
int signum,
int count,
void *siginfo,
void *private_data)
int ret;
if (ret == 0) {
int signum,
int count,
void *siginfo,
void *private_data)
int signum,
int count,
void *siginfo,
void *private_data)
const char *config_file,
if(!ctx) {
return ENOMEM;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
if (ret != 0) {
goto done;
done:
return ret;
const char *file,
bool ignore_missing);
#ifdef HAVE_INOTIFY
if (!te) {
struct rewatch_ctx {
char *name;
if (!tmp_ctx) return;
if (!in_event) {
goto done;
errno = 0;
sizeof(struct inotify_event));
goto done;
if (!name) {
goto done;
errno = 0;
goto done;
if (!cb) {
goto done;
if(!rw_ctx) {
goto done;
goto done;
done:
int err;
if (ret < 0) {
#ifdef HAVE_INOTIFY
return err;
if (fd_args < 0) {
return EINVAL;
if (ret < 0) {
return EINVAL;
file_ctx);
if (!tfd) {
return EIO;
if(!cb) {
return ENOMEM;
return ENOMEM;
return err;
return EOK;
return EINVAL;
const char *file,
bool ignore_missing)
bool use_inotify;
if (ret < 0) {
return EOK;
return err;
true, &use_inotify);
return ret;
if (use_inotify) {
use_inotify = false;
if (!use_inotify) {
return ret;
const char *file,
bool ignore_missing)
if (ret < 0) {
return EOK;
return err;
if (!cb) {
return ENOMEM;
return ENOMEM;
return EIO;
return EOK;
const char *config_file)
char *rcachedir;
int num_providers;
int ret;
int error;
&rcachedir);
return ret;
errno = 0;
if (ret < 0) {
return EIO;
return EIO;
return EIO;
return EIO;
return EIO;
return ret;
/* Watch for changes to the DNS resolv.conf */
monitor_update_resolv,true);
return ret;
if (!tmp_ctx) {
return ENOMEM;
return ret;
return ret;
return ret;
num_providers = 0;
return ret;
if (num_providers > 0) {
return ret;
return EOK;
if (!mini) {
return ENOMEM;
return ENOMEM;
if (!intf) {
return ENOMEM;
int ret;
return ENXIO;
if (!msg) {
return ENOMEM;
return ret;
const char *dbus_error_name;
int type;
if (!svc) {
if (!reply) {
goto done;
switch (type) {
case DBUS_MESSAGE_TYPE_ERROR:
if (!dbus_error_name) {
done:
return ENOMEM;
return EOK;
char **args;
int restart_delay;
int opt;
int opt_daemon = 0;
int opt_interactive = 0;
int opt_version = 0;
int flags = 0;
int ret;
switch(opt) {
if (opt_version) {
return EXIT_SUCCESS;
if (uid != 0) {
if (!tmp_ctx) {
if (opt_interactive) {
if (opt_config_file) {
if (!config_file) {
if (debug_to_file) {
if (ret) {
#ifdef USE_KEYRING
switch (ret) {
case ENOENT:
case EEXIST:
case EOK:
switch (ret) {
case ERR_MISSING_CONF:
case EPERM:
case EACCES: