monitor.c revision 632fc5d8991d167eea20769c823163551c3f1d8c
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/*
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher SSSD
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher Service monitor
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher Copyright (C) Simo Sorce 2008
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher This program is free software; you can redistribute it and/or modify
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher it under the terms of the GNU General Public License as published by
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher the Free Software Foundation; either version 3 of the License, or
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher (at your option) any later version.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher This program is distributed in the hope that it will be useful,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher but WITHOUT ANY WARRANTY; without even the implied warranty of
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher GNU General Public License for more details.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher You should have received a copy of the GNU General Public License
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher along with this program. If not, see <http://www.gnu.org/licenses/>.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher*/
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include "util/util.h"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include "util/child_common.h"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <sys/types.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <sys/wait.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <sys/time.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <sys/param.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <time.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <string.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#ifdef HAVE_SYS_INOTIFY_H
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <sys/inotify.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#endif
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <sys/types.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <sys/stat.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <unistd.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <fcntl.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <popt.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <tevent.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <dbus/dbus.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* Needed for res_init() */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <netinet/in.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <arpa/nameser.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <resolv.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include "confdb/confdb.h"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include "confdb/confdb_setup.h"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include "db/sysdb.h"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include "monitor/monitor.h"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include "sbus/sssd_dbus.h"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include "monitor/monitor_interfaces.h"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include "responder/common/responder_sbus.h"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#ifdef USE_KEYRING
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include <keyutils.h>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#endif
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* terminate the child after this interval by default if it
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * doesn't shutdown on receiving SIGTERM */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#define MONITOR_DEF_FORCE_TIME 60
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* TODO: get the restart related values from config */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#define MONITOR_RESTART_CNT_INTERVAL_RESET 30
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* maximum allowed number of service restarts if the restarts
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * were less than MONITOR_RESTART_CNT_INTERVAL_RESET apart, which would
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * indicate a crash after startup or after every request */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#define MONITOR_MAX_SVC_RESTARTS 2
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* The services are restarted with a delay in case the restart was
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * hitting a race condition where the DP is not ready yet either.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * The MONITOR_MAX_RESTART_DELAY defines the maximum delay between
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * restarts.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#define MONITOR_MAX_RESTART_DELAY 4
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* name of the monitor server instance */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#define MONITOR_NAME "sssd"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* Special value to leave the Kerberos Replay Cache set to use
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * the libkrb5 defaults
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#define KRB5_RCACHE_DIR_DISABLE "__LIBKRB5_DEFAULTS__"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* Warning messages */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#define CONF_FILE_PERM_ERROR_MSG "Cannot read config file %s. Please check "\
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "that the file is accessible only by the "\
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "owner and owned by root.root.\n"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint cmdline_debug_level;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint cmdline_debug_timestamps;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint cmdline_debug_microseconds;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstruct svc_spy;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherenum mt_svc_type {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher MT_SVC_SERVICE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher MT_SVC_PROVIDER
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher};
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstruct mt_svc {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *prev;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *next;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher enum mt_svc_type type;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct sbus_connection *conn;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct svc_spy *conn_spy;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *mt_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *provider;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *command;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *name;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *identity;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher pid_t pid;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int kill_time;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher bool svc_started;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int restarts;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher time_t last_restart;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DBusPendingCall *pending;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int debug_level;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct sss_child_ctx *child_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher};
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstruct config_file_callback {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int wd;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int retries;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor_reconf_fn fn;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *filename;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher time_t modified;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct config_file_callback *next;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct config_file_callback *prev;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher};
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstruct config_file_ctx {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher TALLOC_CTX *parent_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *timer;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher bool needs_update;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *mt_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct config_file_callback *callbacks;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher};
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstruct mt_ctx {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_context *ev;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct confdb_ctx *cdb;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct sss_domain_info *domains;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char **services;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int num_services;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int started_services;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *svc_list;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct sbus_connection *sbus_srv;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct config_file_ctx *file_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int inotify_fd;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int service_id_timeout;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher bool check_children;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher bool services_started;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct netlink_ctx *nlctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const char *conf_path;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct sss_sigchild_ctx *sigchld_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher bool is_daemon;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher pid_t parent_pid;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* For running unprivileged services */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher uid_t uid;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher gid_t gid;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher};
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int start_service(struct mt_svc *mt_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int monitor_service_init(struct sbus_connection *conn, void *data);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int service_signal_reset_offline(struct mt_svc *svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int get_service_config(struct mt_ctx *ctx, const char *name,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc **svc_cfg);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int get_provider_config(struct mt_ctx *ctx, const char *name,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc **svc_cfg);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int add_new_service(struct mt_ctx *ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const char *name,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int restarts);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int add_new_provider(struct mt_ctx *ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const char *name,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int restarts);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int mark_service_as_started(struct mt_svc *svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int monitor_cleanup(void);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void network_status_change_cb(void *cb_data)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *iter;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *ctx = (struct mt_ctx *) cb_data;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_TRACE_INTERNAL, "A networking status change detected "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "signaling providers to reset offline status\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for (iter = ctx->svc_list; iter; iter = iter->next) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Don't signal services, only providers */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (iter->provider) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher service_signal_reset_offline(iter);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* dbus_get_monitor_version
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * Return the monitor version over D-BUS */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int get_monitor_version(struct sbus_request *dbus_req, void *data)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dbus_uint16_t version = MONITOR_VERSION;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return sbus_request_return_and_finish(dbus_req,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DBUS_TYPE_UINT16, &version,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DBUS_TYPE_INVALID);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstruct mon_init_conn {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct sbus_connection *conn;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *timeout;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher};
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int add_svc_conn_spy(struct mt_svc *svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* registers a new client.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * if operation is successful also sends back the Monitor version */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int client_registration(struct sbus_request *dbus_req, void *data)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dbus_uint16_t version = MONITOR_VERSION;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mon_init_conn *mini;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DBusError dbus_error;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dbus_uint16_t svc_ver;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *svc_name;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dbus_bool_t dbret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher mini = talloc_get_type(data, struct mon_init_conn);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!mini) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "Connection holds no valid init data\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EINVAL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* First thing, cancel the timeout */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_zfree(mini->timeout);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dbus_error_init(&dbus_error);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dbret = dbus_message_get_args(dbus_req->message, &dbus_error,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DBUS_TYPE_STRING, &svc_name,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DBUS_TYPE_UINT16, &svc_ver,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DBUS_TYPE_INVALID);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!dbret) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Failed to parse message, killing connection\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sbus_disconnect(dbus_req->conn);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sbus_request_finish(dbus_req, NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* FIXME: should we just talloc_zfree(conn) ? */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CONF_SETTINGS,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Received ID registration: (%s,%d)\n", svc_name, svc_ver);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* search this service in the list */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc = mini->ctx->svc_list;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher while (svc) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = strcasecmp(svc->identity, svc_name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret == 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher break;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc = svc->next;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Unable to find peer [%s] in list of services,"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher " killing connection!\n", svc_name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sbus_disconnect(dbus_req->conn);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sbus_request_finish(dbus_req, NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* FIXME: should we just talloc_zfree(conn) ? */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Fill in svc structure with connection data */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->conn = mini->conn;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = mark_service_as_started(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "Failed to mark service [%s]!\n", svc_name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* reply that all is ok */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sbus_request_return_and_finish(dbus_req,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DBUS_TYPE_UINT16, &version,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DBUS_TYPE_INVALID);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherdone:
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* init complete, get rid of temp init context */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_zfree(mini);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstruct svc_spy {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher};
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int svc_destructor(void *mem)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *svc = talloc_get_type(mem, struct mt_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* ?!?!? */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* try to delist service */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (svc->mt_ctx) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DLIST_REMOVE(svc->mt_ctx->svc_list, svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Cancel any pending calls */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (svc->pending) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dbus_pending_call_cancel(svc->pending);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* svc is being freed, neutralize the spy */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (svc->conn_spy) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_set_destructor((TALLOC_CTX *)svc->conn_spy, NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_zfree(svc->conn_spy);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (svc->type == MT_SVC_SERVICE && svc->svc_started
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher && svc->mt_ctx != NULL && svc->mt_ctx->started_services > 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->mt_ctx->started_services--;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int svc_spy_destructor(void *mem)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct svc_spy *spy = talloc_get_type(mem, struct svc_spy);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!spy) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* ?!?!? */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* svc->conn has been freed, NULL the pointer in svc */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher spy->svc->conn_spy = NULL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher spy->svc->conn = NULL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int add_svc_conn_spy(struct mt_svc *svc)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct svc_spy *spy;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher spy = talloc(svc->conn, struct svc_spy);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!spy) return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher spy->svc = svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_set_destructor((TALLOC_CTX *)spy, svc_spy_destructor);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->conn_spy = spy;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void svc_child_info(struct mt_svc *svc, int wait_status)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (WIFEXITED(wait_status)) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_OP_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Child [%d] exited with code [%d]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->pid, WEXITSTATUS(wait_status));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else if (WIFSIGNALED(wait_status)) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_OP_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Child [%d] terminated with signal [%d]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->pid, WTERMSIG(wait_status));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Child [%d] did not exit cleanly\n", svc->pid);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Forcibly kill this child, just in case */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher kill(svc->pid, SIGKILL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Let us get caught by another
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * call to the SIGCHLD handler
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int mark_service_as_started(struct mt_svc *svc)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *ctx = svc->mt_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *iter;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int i;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FUNC_DATA, "Marking %s as started.\n", svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->svc_started = true;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* we need to attach a spy to the connection structure so that if some code
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * frees it we can zero it out in the service structure. Otherwise we may
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * try to access or even free, freed memory. */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = add_svc_conn_spy(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "Failed to attch spy\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!ctx->services_started) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* check if all providers are up */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for (iter = ctx->svc_list; iter; iter = iter->next) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (iter->provider && !iter->svc_started) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FUNC_DATA,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Still waiting on %s provider.\n", iter->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher break;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (iter) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* there are still unstarted providers */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx->services_started = true;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CONF_SETTINGS, "Now starting services!\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* then start all services */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for (i = 0; ctx->services[i]; i++) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher add_new_service(ctx, ctx->services[i], 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (svc->type == MT_SVC_SERVICE) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx->started_services++;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ctx->started_services == ctx->num_services) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Initialization is complete, terminate parent process if in daemon
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * mode. Make sure we send the signal to the right process */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ctx->is_daemon) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ctx->parent_pid <= 1 || ctx->parent_pid != getppid()) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* the parent process was already terminated */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_MINOR_FAILURE, "Invalid parent pid: %d\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx->parent_pid);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_TRACE_FUNC, "SSSD is initialized, "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "terminating parent process\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher errno = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = kill(ctx->parent_pid, SIGTERM);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = errno;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "Unable to terminate parent "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "process [%d]: %s\n", ret, strerror(ret));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherdone:
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void services_startup_timeout(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *te,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval t, void *ptr)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *ctx = talloc_get_type(ptr, struct mt_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int i;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_TRACE_FUNC, "Handling timeout\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!ctx->services_started) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "Providers did not start in time, "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "forcing services startup!\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx->services_started = true;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CONF_SETTINGS, "Now starting services!\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* then start all services */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for (i = 0; ctx->services[i]; i++) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher add_new_service(ctx, ctx->services[i], 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int add_services_startup_timeout(struct mt_ctx *ctx)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *to;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval tv;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* 5 seconds should be plenty */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tv = tevent_timeval_current_ofs(5, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher to = tevent_add_timer(ctx->ev, ctx, tv, services_startup_timeout, ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!to) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstruct mon_srv_iface monitor_methods = {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher { &mon_srv_iface_meta, 0 },
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher .getVersion = get_monitor_version,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher .RegisterService = client_registration,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher};
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* monitor_dbus_init
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * Set up the monitor service as a D-BUS Server */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int monitor_dbus_init(struct mt_ctx *ctx)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *monitor_address;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = monitor_get_sbus_address(ctx, &monitor_address);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* If a service is running as unprivileged user, we need to make sure this
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * user can access the monitor sbus server. root is still king, so we don't
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * lose any access.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sbus_new_server(ctx, ctx->ev, monitor_address, ctx->uid, ctx->gid,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher false, &ctx->sbus_srv, monitor_service_init, ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(monitor_address);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void monitor_restart_service(struct mt_svc *svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void reload_reply(DBusPendingCall *pending, void *data)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DBusMessage *reply;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *svc = talloc_get_type(data, struct mt_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher reply = dbus_pending_call_steal_reply(pending);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!reply) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* reply should never be null. This function shouldn't be called
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * until reply is valid or timeout has occurred. If reply is NULL
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * here, something is seriously wrong and we should bail out.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "A reply callback was called but no reply was received"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher " and no timeout occurred\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Destroy this connection */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sbus_disconnect(svc->conn);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dbus_pending_call_unref(pending);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* TODO: Handle cases where the call has timed out or returned
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * with an error.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dbus_pending_call_unref(pending);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dbus_message_unref(reply);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int service_signal_dns_reload(struct mt_svc *svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int monitor_update_resolv(struct config_file_ctx *file_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const char *filename)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *cur_svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "Resolv.conf has been updated. Reloading.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = res_init();
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if(ret != 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EIO;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Signal all services to reload their DNS configuration */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for(cur_svc = file_ctx->mt_ctx->svc_list; cur_svc; cur_svc = cur_svc->next) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher service_signal_dns_reload(cur_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int service_signal(struct mt_svc *svc, const char *svc_signal)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DBusMessage *msg;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (svc->provider && strcasecmp(svc->provider, "local") == 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* The local provider requires no signaling */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->conn) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Avoid a race condition where we are trying to
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * order a service to reload that hasn't started
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * yet.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not signal service [%s].\n", svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EIO;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher msg = dbus_message_new_method_call(NULL,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher MONITOR_PATH,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher MON_CLI_IFACE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc_signal);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (msg == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Out of memory trying to allocate memory to invoke: %s\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc_signal);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sbus_conn_send(svc->conn, msg,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->mt_ctx->service_id_timeout,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher reload_reply, svc, NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dbus_message_unref(msg);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int service_signal_dns_reload(struct mt_svc *svc)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return service_signal(svc, MON_CLI_IFACE_RESINIT);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int service_signal_offline(struct mt_svc *svc)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return service_signal(svc, MON_CLI_IFACE_GOOFFLINE);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int service_signal_reset_offline(struct mt_svc *svc)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return service_signal(svc, MON_CLI_IFACE_RESETOFFLINE);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int service_signal_rotate(struct mt_svc *svc)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return service_signal(svc, MON_CLI_IFACE_ROTATELOGS);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int service_signal_clear_memcache(struct mt_svc *svc)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return service_signal(svc, MON_CLI_IFACE_CLEARMEMCACHE);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int service_signal_clear_enum_cache(struct mt_svc *svc)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return service_signal(svc, MON_CLI_IFACE_CLEARENUMCACHE);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int service_signal_sysbus_reconnect(struct mt_svc *svc)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return service_signal(svc, MON_CLI_IFACE_SYSBUSRECONNECT);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int check_domain_ranges(struct sss_domain_info *domains)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct sss_domain_info *dom = domains, *other = NULL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher uint32_t id_min, id_max;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher while (dom) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher other = get_next_domain(dom, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (dom->id_max && dom->id_min > dom->id_max) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Domain '%s' does not have a valid ID range\n", dom->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EINVAL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher while (other) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher id_min = MAX(dom->id_min, other->id_min);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher id_max = MIN((dom->id_max ? dom->id_max : UINT32_MAX),
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher (other->id_max ? other->id_max : UINT32_MAX));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (id_min <= id_max) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_MINOR_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Domains '%s' and '%s' overlap in range %u - %u\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dom->name, other->name, id_min, id_max);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher other = get_next_domain(other, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dom = get_next_domain(dom, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int check_local_domain_unique(struct sss_domain_info *domains)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher uint8_t count = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct sss_domain_info *dom = domains;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher while (dom) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (strcasecmp(dom->provider, "local") == 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher count++;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (count > 1) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher break;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dom = get_next_domain(dom, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (count > 1) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EINVAL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic errno_t add_implicit_services(struct confdb_ctx *cdb, TALLOC_CTX *mem_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char ***_services)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char **domain_names;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher TALLOC_CTX *tmp_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher size_t c;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *conf_path;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *id_provider;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher bool add_pac = false;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tmp_ctx = talloc_new(NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (tmp_ctx == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = confdb_get_string_as_list(cdb, tmp_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_MONITOR_CONF_ENTRY,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_MONITOR_ACTIVE_DOMAINS,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher &domain_names);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret == ENOENT) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "No domains configured!\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for (c = 0; domain_names[c] != NULL; c++) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher conf_path = talloc_asprintf(tmp_ctx, CONFDB_DOMAIN_PATH_TMPL,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher domain_names[c]);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (conf_path == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = confdb_get_string(cdb, tmp_ctx, conf_path,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_DOMAIN_ID_PROVIDER, NULL, &id_provider);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret == EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (id_provider == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "id_provider is not set for "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "domain [%s], trying next domain.\n", domain_names[c]);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher continue;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (strcasecmp(id_provider, "IPA") == 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher add_pac = true;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "Failed to get id_provider for " \
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "domain [%s], trying next domain.\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher domain_names[c]);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (BUILD_WITH_PAC_RESPONDER && add_pac &&
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher !string_in_list("pac", *_services, false)) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = add_string_to_list(mem_ctx, "pac", _services);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "add_string_to_list failed.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherdone:
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(tmp_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic char *check_services(char **services)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const char * const *known_services = get_known_services();
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int i;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ii;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Check if services we are about to start are in the list if known */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for (i = 0; services[i]; i++) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for (ii=0; known_services[ii]; ii++) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (strcasecmp(services[i], known_services[ii]) == 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher break;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (known_services[ii] == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return services[i];
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return NULL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int get_service_user(struct mt_ctx *ctx)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher errno_t ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *user_str;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = confdb_get_string(ctx->cdb, ctx, CONFDB_MONITOR_CONF_ENTRY,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_MONITOR_USER_RUNAS,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher SSSD_USER, &user_str);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get the user to run as\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sss_user_by_name_or_uid(user_str, &ctx->uid, &ctx->gid);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(user_str);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set allowed UIDs.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int get_monitor_config(struct mt_ctx *ctx)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int timeout_seconds;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *badsrv = NULL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int i;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = confdb_get_int(ctx->cdb,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_MONITOR_CONF_ENTRY,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_MONITOR_SBUS_TIMEOUT,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher 10, &timeout_seconds);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx->service_id_timeout = timeout_seconds * 1000; /* service_id_timeout is in ms */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = confdb_get_string_as_list(ctx->cdb, ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_MONITOR_CONF_ENTRY,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_MONITOR_ACTIVE_SERVICES,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher &ctx->services);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "No services configured!\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EINVAL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = add_implicit_services(ctx->cdb, ctx, &ctx->services);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "Failed to add implicit configured "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "services. Some functionality might "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "be missing\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher badsrv = check_services(ctx->services);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (badsrv != NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "Invalid service %s\n", badsrv);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EINVAL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx->started_services = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx->num_services = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for (i = 0; ctx->services[i] != NULL; i++) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx->num_services++;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = get_service_user(ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get the unprivileged user\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = confdb_get_domains(ctx->cdb, &ctx->domains);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "No domains configured.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = check_local_domain_unique(ctx->domains);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "More than one local domain configured.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Check UID/GID overlaps */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = check_domain_ranges(ctx->domains);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* This is a temporary function that returns false if the service
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * being started was only tested when running as root.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic bool svc_supported_as_nonroot(const char *svc_name)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if ((strcmp(svc_name, "nss") == 0)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher || (strcmp(svc_name, "pam") == 0)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher || (strcmp(svc_name, "autofs") == 0)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher || (strcmp(svc_name, "pac") == 0)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher || (strcmp(svc_name, "sudo") == 0)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher || (strcmp(svc_name, "ssh") == 0)) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return true;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return false;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int get_service_config(struct mt_ctx *ctx, const char *name,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc **svc_cfg)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *path;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher time_t now = time(NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher uid_t uid = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher gid_t gid = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher *svc_cfg = NULL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc = talloc_zero(ctx, struct mt_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->mt_ctx = ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->type = MT_SVC_SERVICE;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_set_destructor((TALLOC_CTX *)svc, svc_destructor);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->name = talloc_strdup(svc, name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->name) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->identity = talloc_strdup(svc, name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->identity) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher path = talloc_asprintf(svc, CONFDB_SERVICE_PATH_TMPL, svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!path) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = confdb_get_string(ctx->cdb, svc, path,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_SERVICE_COMMAND,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher NULL, &svc->command);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,"Failed to start service '%s'\n", svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (svc_supported_as_nonroot(svc->name)) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher uid = ctx->uid;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher gid = ctx->gid;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->command) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command = talloc_asprintf(
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc, "%s/sssd_%s", SSSD_LIBEXEC_PATH, svc->name
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher );
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->command) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command = talloc_asprintf_append(svc->command,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher " --uid %"SPRIuid" --gid %"SPRIgid,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher uid, gid);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->command) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (cmdline_debug_level != SSSDBG_UNRESOLVED) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command = talloc_asprintf_append(
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command, " -d %#.4x", cmdline_debug_level
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher );
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->command) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (cmdline_debug_timestamps != SSSDBG_TIMESTAMP_UNRESOLVED) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command = talloc_asprintf_append(
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command, " --debug-timestamps=%d", cmdline_debug_timestamps
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher );
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->command) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (cmdline_debug_microseconds != SSSDBG_MICROSECONDS_UNRESOLVED) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command = talloc_asprintf_append(
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command, " --debug-microseconds=%d",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cmdline_debug_microseconds
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher );
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->command) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (debug_to_file) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command = talloc_strdup_append(
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command, " --debug-to-files"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher );
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->command) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else if (ctx->is_daemon == false) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command = talloc_strdup_append(
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command, " --debug-to-stderr"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher );
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->command) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->last_restart = now;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher *svc_cfg = svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(path);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int add_new_service(struct mt_ctx *ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const char *name,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int restarts)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = get_service_config(ctx, name, &svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->restarts = restarts;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = start_service(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,"Failed to start service '%s'\n", svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int get_provider_config(struct mt_ctx *ctx, const char *name,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc **svc_cfg)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *path;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher time_t now = time(NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher *svc_cfg = NULL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc = talloc_zero(ctx, struct mt_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->mt_ctx = ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->type = MT_SVC_PROVIDER;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_set_destructor((TALLOC_CTX *)svc, svc_destructor);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->name = talloc_strdup(svc, name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->name) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->identity = talloc_asprintf(svc, "%%BE_%s", svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->identity) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher path = talloc_asprintf(svc, CONFDB_DOMAIN_PATH_TMPL, name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!path) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = confdb_get_string(ctx->cdb, svc, path,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_DOMAIN_ID_PROVIDER,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher NULL, &svc->provider);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Failed to find ID provider from [%s] configuration\n", name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = confdb_get_string(ctx->cdb, svc, path,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_DOMAIN_COMMAND,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher NULL, &svc->command);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Failed to find command from [%s] configuration\n", name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(path);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* if no provider is present do not run the domain */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->provider) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EIO;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* if there are no custom commands, build a default one */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->command) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command = talloc_asprintf(
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc, "%s/sssd_be --domain %s", SSSD_LIBEXEC_PATH, svc->name
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher );
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->command) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command = talloc_asprintf_append(svc->command,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher " --uid %"SPRIuid" --gid %"SPRIgid,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx->uid, ctx->gid);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->command) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (cmdline_debug_level != SSSDBG_UNRESOLVED) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command = talloc_asprintf_append(
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command, " -d %#.4x", cmdline_debug_level
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher );
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->command) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (cmdline_debug_timestamps != SSSDBG_TIMESTAMP_UNRESOLVED) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command = talloc_asprintf_append(
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command, " --debug-timestamps=%d", cmdline_debug_timestamps
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher );
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->command) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (cmdline_debug_microseconds != SSSDBG_MICROSECONDS_UNRESOLVED) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command = talloc_asprintf_append(
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command, " --debug-microseconds=%d",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cmdline_debug_microseconds
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher );
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->command) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (debug_to_file) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command = talloc_strdup_append(
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command, " --debug-to-files"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher );
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->command) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else if (ctx->is_daemon == false) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command = talloc_strdup_append(
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->command, " --debug-to-stderr"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher );
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!svc->command) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->last_restart = now;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher *svc_cfg = svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int add_new_provider(struct mt_ctx *ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const char *name,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int restarts)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = get_provider_config(ctx, name, &svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not get provider configuration for [%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->restarts = restarts;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (strcasecmp(svc->provider, "local") == 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* The LOCAL provider requires no back-end currently
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * We'll add it to the service list, but we don't need
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * to poll it.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->svc_started = true;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DLIST_ADD(ctx->svc_list, svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOENT;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = start_service(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,"Failed to start service '%s'\n", svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void monitor_hup(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_signal *se,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int signum,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int count,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher void *siginfo,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher void *private_data)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *ctx = talloc_get_type(private_data, struct mt_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *cur_svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "Received SIGHUP.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Send D-Bus message to other services to rotate their logs.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * NSS service receives also message to clear memory caches. */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for(cur_svc = ctx->svc_list; cur_svc; cur_svc = cur_svc->next) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher service_signal_rotate(cur_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!strcmp(NSS_SBUS_SERVICE_NAME, cur_svc->name)) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher service_signal_clear_memcache(cur_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher service_signal_clear_enum_cache(cur_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!strcmp(SSS_AUTOFS_SBUS_SERVICE_NAME, cur_svc->name)) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher service_signal_clear_enum_cache(cur_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int monitor_cleanup(void)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher errno = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = unlink(SSSD_PIDFILE);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret == -1) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = errno;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Error removing pidfile! (%d [%s])\n", ret, strerror(ret));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void monitor_quit(struct mt_ctx *mt_ctx, int ret)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher pid_t pid;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int status;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher errno_t error;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int kret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher bool killed;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_IMPORTANT_INFO, "Returned with: %d\n", ret);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Kill all of our known children manually */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DLIST_FOR_EACH(svc, mt_ctx->svc_list) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (svc->pid == 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* The local provider has no PID */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher continue;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher killed = false;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Terminating [%s][%d]\n", svc->name, svc->pid);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher do {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher errno = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher kret = kill(svc->pid, SIGTERM);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (kret < 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher error = errno;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "Couldn't kill [%s][%d]: [%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->name, svc->pid, strerror(error));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher error = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher do {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher errno = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher pid = waitpid(svc->pid, &status, WNOHANG);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (pid == -1) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* An error occurred while waiting */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher error = errno;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (error == ECHILD) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher killed = true;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else if (error != EINTR) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "[%d][%s] while waiting for [%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher error, strerror(error), svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Forcibly kill this child */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher kill(svc->pid, SIGKILL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher break;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else if (pid != 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher error = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (WIFEXITED(status)) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Child [%s] exited gracefully\n", svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else if (WIFSIGNALED(status)) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Child [%s] terminated with a signal\n", svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Child [%s] did not exit cleanly\n", svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Forcibly kill this child */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher kill(svc->pid, SIGKILL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher killed = true;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } while (error == EINTR);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!killed) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Sleep 10ms and try again */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher usleep(10000);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } while (!killed);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#if HAVE_GETPGRP
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Kill any remaining children in our process group, just in case
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * we have any leftover children we don't expect. For example, if
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * a krb5_child or ldap_child is running at the same moment.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher error = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (getpgrp() == getpid()) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher kill(-getpgrp(), SIGTERM);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher do {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher errno = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher pid = waitpid(0, &status, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (pid == -1) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher error = errno;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } while (error == EINTR || pid > 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#endif
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor_cleanup();
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher exit(ret);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void monitor_quit_signal(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_signal *se,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int signum,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int count,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher void *siginfo,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher void *private_data)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *mt_ctx = talloc_get_type(private_data, struct mt_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_TRACE_INTERNAL, "Received shutdown command\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_IMPORTANT_INFO, "Monitor received %s: terminating "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "children\n", strsignal(signum));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor_quit(mt_ctx, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void signal_res_init(struct mt_ctx *monitor)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *cur_svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "Reloading Resolv.conf.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = res_init();
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret == 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for(cur_svc = monitor->svc_list; cur_svc; cur_svc = cur_svc->next) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher service_signal_dns_reload(cur_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void signal_offline(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_signal *se,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int signum,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int count,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher void *siginfo,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher void *private_data)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *monitor;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *cur_svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor = talloc_get_type(private_data, struct mt_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_TRACE_INTERNAL,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Signaling providers to go offline immediately.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Signal all providers to immediately go offline */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for(cur_svc = monitor->svc_list; cur_svc; cur_svc = cur_svc->next) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Don't signal services, only providers */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (cur_svc->provider) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher service_signal_offline(cur_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void signal_offline_reset(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_signal *se,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int signum,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int count,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher void *siginfo,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher void *private_data)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *monitor;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *cur_svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor = talloc_get_type(private_data, struct mt_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_TRACE_INTERNAL,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Signaling providers to reset offline immediately.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for(cur_svc = monitor->svc_list; cur_svc; cur_svc = cur_svc->next) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (cur_svc->provider) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher service_signal_reset_offline(cur_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (strcmp(SSS_IFP_SBUS_SERVICE_NAME, cur_svc->name) == 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher service_signal_sysbus_reconnect(cur_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher signal_res_init(monitor);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int monitor_ctx_destructor(void *mem)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *mon = talloc_get_type(mem, struct mt_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* zero out references in svcs so that they don't try
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * to access the monitor context on process shutdown */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for (svc = mon->svc_list; svc; svc = svc->next) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->mt_ctx = NULL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/*
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * This function should not be static otherwise gcc does some special kind of
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * optimisations which should not happen according to code: chown (unlink)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * failed (return -1) but errno was zero.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * As a result of this * warning is printed ‘monitor’ may be used
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * uninitialized in this function. Instead of checking errno for 0
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * it's better to disable optimisation(in-lining) of this function.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghererrno_t load_configuration(TALLOC_CTX *mem_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const char *config_file,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const char *config_dir,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx **monitor)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher errno_t ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *cdb_file = NULL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx = talloc_zero(mem_ctx, struct mt_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if(!ctx) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_set_destructor((TALLOC_CTX *)ctx, monitor_ctx_destructor);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cdb_file = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (cdb_file == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory, aborting!\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = confdb_setup(ctx, cdb_file, config_file, config_dir, &ctx->cdb);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "Unable to setup ConfDB [%d]: %s\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret, sss_strerror(ret));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Validate the configuration in the database */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Read in the monitor's configuration */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = get_monitor_config(ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Allow configuration database to be accessible
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * when SSSD runs as nonroot */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = chown(cdb_file, ctx->uid, ctx->gid);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = errno;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "chown failed for [%s]: [%d][%s].\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cdb_file, ret, sss_strerror(ret));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher *monitor = ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherdone:
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(cdb_file);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic errno_t monitor_config_file_fallback(TALLOC_CTX *mem_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const char *file,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor_reconf_fn fn,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher bool ignore_missing);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#ifdef HAVE_INOTIFY
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void process_config_file(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *te,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval t, void *ptr);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void config_file_changed(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_fd *fde,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher uint16_t flags, void *data)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *te = NULL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval tv;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct config_file_ctx *file_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher file_ctx = talloc_get_type(data, struct config_file_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (file_ctx->needs_update) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Skip updating. It's already queued for update.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* We will queue the file for update in one second.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * This way, if there is a script writing to the file
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * repeatedly, we won't be attempting to update multiple
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * times.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher gettimeofday(&tv, NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tv.tv_sec += 1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher te = tevent_add_timer(ev, ev, tv, process_config_file, file_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!te) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Unable to queue config file update! Exiting.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher kill(getpid(), SIGTERM);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher file_ctx->needs_update = 1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstruct rewatch_ctx {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct config_file_callback *cb;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct config_file_ctx *file_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher};
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void rewatch_config_file(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *te,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval t, void *ptr);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void process_config_file(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *te,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval t, void *ptr)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher TALLOC_CTX *tmp_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct inotify_event *in_event;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *name;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ssize_t len;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct config_file_ctx *file_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct config_file_callback *cb;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct rewatch_ctx *rw_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher errno_t ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher file_ctx = talloc_get_type(ptr, struct config_file_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "Processing config file changes\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tmp_ctx = talloc_new(NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!tmp_ctx) return;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher in_event = talloc(tmp_ctx, struct inotify_event);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!in_event) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher errno = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher len = sss_atomic_read_s(file_ctx->mt_ctx->inotify_fd, in_event,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sizeof(struct inotify_event));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (len == -1) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = errno;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Critical error reading inotify file descriptor [%d]: %s\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret, strerror(ret));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (in_event->len > 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Read in the name, even though we don't use it,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * so that read ptr is in the right place
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher name = talloc_size(tmp_ctx, in_event->len);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!name) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher errno = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher len = sss_atomic_read_s(file_ctx->mt_ctx->inotify_fd, name, in_event->len);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (len == -1) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = errno;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Critical error reading inotify file descriptor [%d]: %s\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret, strerror(ret));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for (cb = file_ctx->callbacks; cb; cb = cb->next) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (cb->wd == in_event->wd) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher break;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!cb) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "Unknown watch descriptor\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (in_event->mask & IN_IGNORED) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Some text editors will move a new file on top of the
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * existing one instead of modifying it. In this case,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * the kernel will send us an IN_IGNORE signal.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * We will try to open a new watch descriptor on the
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * new file.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval tv;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *tev;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tv.tv_sec = t.tv_sec+5;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tv.tv_usec = t.tv_usec;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FUNC_DATA, "Restoring inotify watch.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->retries = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher rw_ctx = talloc(file_ctx, struct rewatch_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if(!rw_ctx) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not restore inotify watch. Quitting!\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher close(file_ctx->mt_ctx->inotify_fd);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher kill(getpid(), SIGTERM);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher rw_ctx->cb = cb;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher rw_ctx->file_ctx = file_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tev = tevent_add_timer(ev, rw_ctx, tv, rewatch_config_file, rw_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (tev == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not restore inotify watch. Quitting!\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher close(file_ctx->mt_ctx->inotify_fd);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher kill(getpid(), SIGTERM);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Tell the monitor to signal the children */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->fn(file_ctx, cb->filename);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher file_ctx->needs_update = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherdone:
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(tmp_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void rewatch_config_file(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *te,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval t, void *ptr)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int err;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *tev = NULL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval tv;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct config_file_callback *cb;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct rewatch_ctx *rw_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct config_file_ctx *file_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher rw_ctx = talloc_get_type(ptr, struct rewatch_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb = rw_ctx->cb;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher file_ctx = rw_ctx->file_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Retry six times at five-second intervals before giving up */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->retries++;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (cb->retries > 6) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not restore inotify watch. Switching to polling!\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher close(file_ctx->mt_ctx->inotify_fd);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher err = monitor_config_file_fallback(file_ctx->parent_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher file_ctx->mt_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->filename,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->fn,true);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (err != EOK)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher kill(getpid(), SIGTERM);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->fn(file_ctx, cb->filename);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(rw_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* A new callback was created in monitor_config_file_fallback()*/
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DLIST_REMOVE(file_ctx->callbacks, cb);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(cb);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->wd = inotify_add_watch(file_ctx->mt_ctx->inotify_fd,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->filename, IN_MODIFY);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (cb->wd < 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher err = errno;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tv.tv_sec = t.tv_sec+5;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tv.tv_usec = t.tv_usec;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not add inotify watch for file [%s]. Error [%d:%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->filename, err, strerror(err));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tev = tevent_add_timer(ev, ev, tv, rewatch_config_file, rw_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (tev == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not restore inotify watch. Quitting!\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher close(file_ctx->mt_ctx->inotify_fd);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher kill(getpid(), SIGTERM);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->retries = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Tell the monitor to signal the children */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->fn(file_ctx, cb->filename);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(rw_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher file_ctx->needs_update = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#endif /* HAVE_INOTIFY */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void poll_config_file(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *te,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval t, void *ptr)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret, err;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct stat file_stat;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval tv;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct config_file_ctx *file_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct config_file_callback *cb;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher file_ctx = talloc_get_type(ptr,struct config_file_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for (cb = file_ctx->callbacks; cb; cb = cb->next) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = stat(cb->filename, &file_stat);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret < 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher err = errno;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not stat file [%s]. Error [%d:%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->filename, err, strerror(err));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* TODO: If the config file is missing, should we shut down? */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (file_stat.st_mtime != cb->modified) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Parse the configuration file and signal the children */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Note: this will fire if the modification time changes into the past
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * as well as the future.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "Config file changed\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->modified = file_stat.st_mtime;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Tell the monitor to signal the children */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->fn(file_ctx, cb->filename);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher gettimeofday(&tv, NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tv.tv_sec += CONFIG_FILE_POLL_INTERVAL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tv.tv_usec = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher file_ctx->timer = tevent_add_timer(ev, file_ctx->parent_ctx, tv,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher poll_config_file, file_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!file_ctx->timer) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Error: Config file no longer monitored for changes!\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int try_inotify(struct config_file_ctx *file_ctx, const char *filename,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor_reconf_fn fn)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#ifdef HAVE_INOTIFY
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int err, fd_args, ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_fd *tfd;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct config_file_callback *cb;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Monitoring the file descriptor should be global */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!file_ctx->mt_ctx->inotify_fd) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Set up inotify to monitor the config file for changes */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher file_ctx->mt_ctx->inotify_fd = inotify_init();
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (file_ctx->mt_ctx->inotify_fd < 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher err = errno;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not initialize inotify, error [%d:%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher err, strerror(err));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return err;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher fd_args = fcntl(file_ctx->mt_ctx->inotify_fd, F_GETFL, NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (fd_args < 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Could not set nonblocking */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher close(file_ctx->mt_ctx->inotify_fd);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EINVAL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher fd_args |= O_NONBLOCK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = fcntl(file_ctx->mt_ctx->inotify_fd, F_SETFL, fd_args);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret < 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Could not set nonblocking */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher close(file_ctx->mt_ctx->inotify_fd);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EINVAL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Add the inotify file descriptor to the TEvent context */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tfd = tevent_add_fd(file_ctx->mt_ctx->ev, file_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher file_ctx->mt_ctx->inotify_fd,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher TEVENT_FD_READ, config_file_changed,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher file_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!tfd) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher close(file_ctx->mt_ctx->inotify_fd);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EIO;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb = talloc_zero(file_ctx, struct config_file_callback);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if(!cb) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher close(file_ctx->mt_ctx->inotify_fd);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->filename = talloc_strdup(cb, filename);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!cb->filename) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher close(file_ctx->mt_ctx->inotify_fd);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->wd = inotify_add_watch(file_ctx->mt_ctx->inotify_fd,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->filename, IN_MODIFY);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (cb->wd < 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher err = errno;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not add inotify watch for file [%s]. Error [%d:%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->filename, err, strerror(err));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher close(file_ctx->mt_ctx->inotify_fd);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return err;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->fn = fn;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DLIST_ADD(file_ctx->callbacks, cb);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#else
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EINVAL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#endif /* HAVE_INOTIFY */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int monitor_config_file(TALLOC_CTX *mem_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const char *file,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor_reconf_fn fn,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher bool ignore_missing)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret, err;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher bool use_inotify;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct stat file_stat;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = stat(file, &file_stat);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret < 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher err = errno;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (err == ENOENT && ignore_missing) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_MINOR_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "file [%s] is missing. Will not update online status "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "based on watching the file\n", file);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_MINOR_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not stat file [%s]. Error [%d:%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher file, err, strerror(err));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return err;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!ctx->file_ctx) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx->file_ctx = talloc_zero(mem_ctx, struct config_file_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!ctx->file_ctx) return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx->file_ctx->parent_ctx = mem_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx->file_ctx->mt_ctx = ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = confdb_get_bool(ctx->cdb,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_MONITOR_CONF_ENTRY,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_MONITOR_TRY_INOTIFY,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher true, &use_inotify);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(ctx->file_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (use_inotify) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = try_inotify(ctx->file_ctx, file, fn);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher use_inotify = false;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!use_inotify) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Could not monitor file with inotify, fall back to polling */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = monitor_config_file_fallback(mem_ctx, ctx, file, fn, true);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic errno_t monitor_config_file_fallback(TALLOC_CTX *mem_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const char *file,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor_reconf_fn fn,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher bool ignore_missing)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct config_file_callback *cb = NULL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct stat file_stat;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret, err;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval tv;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = stat(file, &file_stat);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret < 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher err = errno;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (err == ENOENT && ignore_missing) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_MINOR_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "file [%s] is missing. Will not update online status "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "based on watching the file\n", file);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not stat file [%s]. Error [%d:%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher file, err, strerror(err));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return err;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb = talloc_zero(ctx->file_ctx, struct config_file_callback);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!cb) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(ctx->file_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->filename = talloc_strdup(cb, file);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!cb->filename) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(ctx->file_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->fn = fn;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cb->modified = file_stat.st_mtime;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DLIST_ADD(ctx->file_ctx->callbacks, cb);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if(!ctx->file_ctx->timer) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher gettimeofday(&tv, NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tv.tv_sec += CONFIG_FILE_POLL_INTERVAL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tv.tv_usec = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx->file_ctx->timer = tevent_add_timer(ctx->ev, mem_ctx, tv,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher poll_config_file, ctx->file_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!ctx->file_ctx->timer) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(ctx->file_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EIO;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#define MISSING_RESOLV_CONF_POLL_TIME 10
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void missing_resolv_conf(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *te,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval tv, void *data)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *ctx = talloc_get_type(data, struct mt_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = monitor_config_file(ctx, ctx, RESOLV_CONF_PATH,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor_update_resolv, false);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret == EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher signal_res_init(ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else if (ret == ENOENT) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tv = tevent_timeval_current_ofs(MISSING_RESOLV_CONF_POLL_TIME, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher te = tevent_add_timer(ctx->ev, ctx, tv, missing_resolv_conf, ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (te == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "tevent_add_timer failed. resolv.conf will be ignored.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Monitor_config_file failed. resolv.conf will be ignored.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int monitor_process_init(struct mt_ctx *ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const char *config_file)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher TALLOC_CTX *tmp_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_signal *tes;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval tv;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *te;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct sss_domain_info *dom;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *rcachedir;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int num_providers;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int error;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct sysdb_upgrade_ctx db_up_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Set up the environment variable for the Kerberos Replay Cache */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = confdb_get_string(ctx->cdb, ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_MONITOR_CONF_ENTRY,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_MONITOR_KRB5_RCACHEDIR,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher KRB5_RCACHE_DIR,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher &rcachedir);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (strcmp(rcachedir, KRB5_RCACHE_DIR_DISABLE) != 0)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher errno = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = setenv("KRB5RCACHEDIR", rcachedir, 1);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret < 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher error = errno;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Unable to set KRB5RCACHEDIR: %s."
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Will attempt to use libkrb5 defaults\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher strerror(error));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_zfree(rcachedir);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Set up an event handler for a SIGHUP */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tes = tevent_add_signal(ctx->ev, ctx, SIGHUP, 0,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor_hup, ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (tes == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EIO;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Set up an event handler for a SIGINT */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher BlockSignals(false, SIGINT);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tes = tevent_add_signal(ctx->ev, ctx, SIGINT, 0,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor_quit_signal, ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (tes == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EIO;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Set up an event handler for a SIGTERM */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tes = tevent_add_signal(ctx->ev, ctx, SIGTERM, 0,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor_quit_signal, ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (tes == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EIO;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Handle SIGUSR1 (tell all providers to go offline) */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher BlockSignals(false, SIGUSR1);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tes = tevent_add_signal(ctx->ev, ctx, SIGUSR1, 0,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher signal_offline, ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (tes == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EIO;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Handle SIGUSR2 (tell all providers to go reset offline) */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher BlockSignals(false, SIGUSR2);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tes = tevent_add_signal(ctx->ev, ctx, SIGUSR2, 0,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher signal_offline_reset, ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (tes == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EIO;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Set up the SIGCHLD handler */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sss_sigchld_init(ctx, ctx->ev, &ctx->sigchld_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#if 0
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher This feature is incomplete and can leave the SSSD in a bad state if the
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher config file is changed while the SSSD is running.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher Uncomment this once the backends are honoring reloadConfig()
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Watch for changes to the confdb config file */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = monitor_config_file(ctx, ctx, config_file, monitor_signal_reconf,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher true);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#endif
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Watch for changes to the DNS resolv.conf */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = monitor_config_file(ctx, ctx, RESOLV_CONF_PATH,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor_update_resolv, false);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret == ENOENT) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tv = tevent_timeval_current_ofs(MISSING_RESOLV_CONF_POLL_TIME, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher te = tevent_add_timer(ctx->ev, ctx, tv, missing_resolv_conf, ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (te == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "resolv.conf will be ignored\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Avoid a startup race condition between process.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * We need to handle DB upgrades or DB creation only
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * in one process before all other start.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tmp_ctx = talloc_new(NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!tmp_ctx) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher db_up_ctx.cdb = ctx->cdb;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sysdb_init_ext(tmp_ctx, ctx->domains, &db_up_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher true, ctx->uid, ctx->gid);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher SYSDB_VERSION_ERROR_DAEMON(ret);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_zfree(tmp_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Initialize D-BUS Server
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * The monitor will act as a D-BUS server for all
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * SSSD processes */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = monitor_dbus_init(ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = setup_netlink(ctx, ctx->ev, network_status_change_cb,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx, &ctx->nlctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_OP_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Cannot set up listening for network notifications\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* start providers */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher num_providers = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for (dom = ctx->domains; dom; dom = get_next_domain(dom, 0)) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = add_new_provider(ctx, dom->name, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK && ret != ENOENT) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != ENOENT) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher num_providers++;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (num_providers > 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* now set the services stratup timeout *
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * (responders will be started automatically when all
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * providers are up and running or when the tomeout
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * expires) */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = add_services_startup_timeout(ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int i;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx->services_started = true;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* No providers start services immediately
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * Normally this means only LOCAL is configured */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for (i = 0; ctx->services[i]; i++) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher add_new_service(ctx, ctx->services[i], 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void init_timeout(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *te,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval t, void *ptr)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mon_init_conn *mini;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "Client timed out before Identification!\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher mini = talloc_get_type(ptr, struct mon_init_conn);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sbus_disconnect(mini->conn);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_zfree(mini);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/*
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * monitor_service_init
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * Set up a timeout function and temporary connection structure.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * If the client does not identify before the timeout kicks in,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * the client is forcibly disconnected.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int monitor_service_init(struct sbus_connection *conn, void *data)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mon_init_conn *mini;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval tv;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_TRACE_FUNC, "Initializing D-BUS Service\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ctx = talloc_get_type(data, struct mt_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher mini = talloc(conn, struct mon_init_conn);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!mini) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_zfree(conn);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher mini->ctx = ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher mini->conn = conn;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Allow access from the SSSD user */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sbus_allow_uid(conn, &ctx->uid);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* 10 seconds should be plenty */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tv = tevent_timeval_current_ofs(10, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher mini->timeout = tevent_add_timer(ctx->ev, mini, tv, init_timeout, mini);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!mini->timeout) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_zfree(conn);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return sbus_conn_register_iface(conn, &monitor_methods.vtable,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher MON_SRV_PATH, mini);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void service_startup_handler(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *te,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval t, void *ptr);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic int start_service(struct mt_svc *svc)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *te;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval tv;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CONF_SETTINGS,"Queueing service %s for startup\n", svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tv = tevent_timeval_current();
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Add a timed event to start up the service.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * We have to do this in order to avoid a race
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * condition where the service being started forks
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * and attempts to connect to the SBUS before
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * the monitor is serving it.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher te = tevent_add_timer(svc->mt_ctx->ev, svc, tv,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher service_startup_handler, svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (te == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Unable to queue service %s for startup\n", svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void mt_svc_exit_handler(int pid, int wait_status, void *pvt);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void service_startup_handler(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *te,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval t, void *ptr)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher errno_t ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *mt_svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char **args;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher mt_svc = talloc_get_type(ptr, struct mt_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (mt_svc == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher mt_svc->pid = fork();
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (mt_svc->pid != 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (mt_svc->pid == -1) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not fork child to start service [%s]. "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Continuing.\n", mt_svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Parent */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher mt_svc->mt_ctx->check_children = true;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Handle process exit */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sss_child_register(mt_svc,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher mt_svc->mt_ctx->sigchld_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher mt_svc->pid,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher mt_svc_exit_handler,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher mt_svc,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher &mt_svc->child_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not register sigchld handler.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Should we exit here? For now, we'll hope this
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * child never dies, because we can't restart it.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DLIST_ADD(mt_svc->mt_ctx->svc_list, mt_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* child */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher args = parse_args(mt_svc->command);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher execvp(args[0], args);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* If we are here, exec() has failed
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * Print errno and abort quickly */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not exec %s, reason: %s\n", mt_svc->command, strerror(errno));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* We have to call _exit() instead of exit() here
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * because a bug in D-BUS will cause the server to
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * close its socket at exit() */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher _exit(1);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void mt_svc_restart(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *te,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval t, void *ptr)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *svc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc = talloc_get_type(ptr, struct mt_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (svc == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_TRACE_FUNC, "Scheduling service %s for restart %d\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->name, svc->restarts+1);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (svc->type == MT_SVC_SERVICE) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher add_new_service(svc->mt_ctx, svc->name, svc->restarts + 1);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else if (svc->type == MT_SVC_PROVIDER) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher add_new_provider(svc->mt_ctx, svc->name, svc->restarts + 1);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Invalid type? */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "BUG: Invalid child process type [%d]\n", svc->type);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Free the old service (which will also remove it
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * from the child list)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void mt_svc_exit_handler(int pid, int wait_status, void *pvt)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_svc *svc = talloc_get_type(pvt, struct mt_svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_TRACE_LIBS,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "SIGCHLD handler of service %s called\n", svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc_child_info(svc, wait_status);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Check the number of restart tries and relaunch the service */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor_restart_service(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void monitor_restart_service(struct mt_svc *svc)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *mt_ctx = svc->mt_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int restart_delay;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher time_t now = time(NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct tevent_timer *te;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct timeval tv;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Handle the actual checks for how many times to restart this
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * service before giving up.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if ((now - svc->last_restart) > MONITOR_RESTART_CNT_INTERVAL_RESET) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->restarts = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Restart the service */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (svc->restarts > MONITOR_MAX_SVC_RESTARTS) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Process [%s], definitely stopped!\n", svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sss_log(SSS_LOG_ERR,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Exiting the SSSD. Could not restart critical service [%s].",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svc->name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* exit the SSSD with an error, shutting down all
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * services and domains.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * We do this because if one of the responders is down
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * and can't come back up, this is the only way to
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * guarantee admin intervention.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor_quit(mt_ctx, 1);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* restarts are schedule after 0, 2, 4 seconds */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher restart_delay = svc->restarts << 1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (restart_delay > MONITOR_MAX_RESTART_DELAY) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher restart_delay = MONITOR_MAX_RESTART_DELAY;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tv = tevent_timeval_current_ofs(restart_delay, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher te = tevent_add_timer(svc->mt_ctx->ev, svc, tv, mt_svc_restart, svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (te == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Nothing much we can do */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Failed to allocate timed event: mt_svc_restart.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(svc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint main(int argc, const char *argv[])
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher{
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int opt;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher poptContext pc;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int opt_daemon = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int opt_interactive = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int opt_genconf = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int opt_version = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int opt_netlinkoff = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *opt_config_file = NULL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *config_file = NULL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int flags = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct main_context *main_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher TALLOC_CTX *tmp_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mt_ctx *monitor;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int ret;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher uid_t uid;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct poptOption long_options[] = {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher POPT_AUTOHELP
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher SSSD_MAIN_OPTS
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher {"daemon", 'D', POPT_ARG_NONE, &opt_daemon, 0, \
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher _("Become a daemon (default)"), NULL }, \
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher {"interactive", 'i', POPT_ARG_NONE, &opt_interactive, 0, \
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher _("Run interactive (not a daemon)"), NULL}, \
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher {"disable-netlink", '\0', POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher &opt_netlinkoff, 0, \
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher _("Disable netlink interface"), NULL}, \
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher {"config", 'c', POPT_ARG_STRING, &opt_config_file, 0, \
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher _("Specify a non-default config file"), NULL}, \
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher {"genconf", 'g', POPT_ARG_NONE, &opt_genconf, 0, \
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher _("Refresh the configuration database, then exit"), \
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher NULL}, \
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher {"version", '\0', POPT_ARG_NONE, &opt_version, 0, \
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher _("Print version number and exit"), NULL }, \
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher POPT_TABLEEND
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher };
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Set debug level to invalid value so we can deside if -d 0 was used. */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher debug_level = SSSDBG_INVALID;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher pc = poptGetContext(argv[0], argc, argv, long_options, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher while((opt = poptGetNextOpt(pc)) != -1) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher switch(opt) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher default:
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher fprintf(stderr, "\nInvalid option %s: %s\n\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher poptBadOption(pc, 0), poptStrerror(opt));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher poptPrintUsage(pc, stderr, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return 1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG_INIT(debug_level);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (opt_version) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher puts(VERSION""PRERELEASE_VERSION);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return EXIT_SUCCESS;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* If the level or timestamps was passed at the command-line, we want
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * to save it and pass it to the children later.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cmdline_debug_level = debug_level;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cmdline_debug_timestamps = debug_timestamps;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cmdline_debug_microseconds = debug_microseconds;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (opt_daemon && opt_interactive) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher fprintf(stderr, "Option -i|--interactive is not allowed together with -D|--daemon\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher poptPrintUsage(pc, stderr, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return 1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (opt_genconf && (opt_daemon || opt_interactive)) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher fprintf(stderr, "Option -g is incompatible with -D or -i\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher poptPrintUsage(pc, stderr, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return 1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!opt_daemon && !opt_interactive && !opt_genconf) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher opt_daemon = 1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher poptFreeContext(pc);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher uid = getuid();
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (uid != 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Running under %"SPRIuid", must be root\n", uid);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sss_log(SSS_LOG_ALERT, "sssd must be run as root");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return 8;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tmp_ctx = talloc_new(NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!tmp_ctx) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return 7;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (opt_daemon) flags |= FLAGS_DAEMON;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (opt_interactive) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher flags |= FLAGS_INTERACTIVE;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher debug_to_stderr = 1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (opt_genconf) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher flags |= FLAGS_GEN_CONF;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher debug_to_stderr = 1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (opt_config_file) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher config_file = talloc_strdup(tmp_ctx, opt_config_file);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher config_file = talloc_strdup(tmp_ctx, SSSD_CONFIG_FILE);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (opt_netlinkoff) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_MINOR_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Option --disable-netlink has been removed and "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "replaced as a monitor option in sssd.conf\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sss_log(SSS_LOG_ALERT,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "--disable-netlink has been deprecated, tunable option "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "disable_netlink available as replacement(man sssd.conf)");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!config_file) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return 6;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* we want a pid file check */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher flags |= FLAGS_PID_FILE;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Open before server_setup() does to have logging
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * during configuration checking */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (debug_to_file) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = open_debug_file();
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return 7;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#ifdef USE_KEYRING
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Do this before all the forks, it sets the session key ring so all
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * keys are private to the daemon and cannot be read by any other process
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * tree */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* make a new session */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = keyctl_join_session_keyring(NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret == -1) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sss_log(SSS_LOG_ALERT,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not create private keyring session. "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "If you store password there they may be easily accessible "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "to the root user. (%d, %s)", errno, strerror(errno));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = keyctl_setperm(KEY_SPEC_SESSION_KEYRING, KEY_POS_ALL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret == -1) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sss_log(SSS_LOG_ALERT,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Could not set permissions on private keyring. "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "If you store password there they may be easily accessible "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "to the root user. (%d, %s)", errno, strerror(errno));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#endif
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Warn if nscd seems to be running */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = check_file(NSCD_SOCKET_PATH,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher -1, -1, S_IFSOCK, S_IFMT, NULL, false);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret == EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sss_nscd_parse_conf(NSCD_CONF_PATH);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher switch (ret) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher case ENOENT:
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sss_log(SSS_LOG_NOTICE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "NSCD socket was detected. NSCD caching capabilities "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "may conflict with SSSD for users and groups. It is "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "recommended not to run NSCD in parallel with SSSD, "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "unless NSCD is configured not to cache the passwd, "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "group, netgroup and services nsswitch maps.");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher break;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher case EEXIST:
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sss_log(SSS_LOG_NOTICE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "NSCD socket was detected and seems to be configured "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "to cache some of the databases controlled by "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "SSSD [passwd,group,netgroup,services]. It is "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "recommended not to run NSCD in parallel with SSSD, "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "unless NSCD is configured not to cache these.");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher break;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher case EOK:
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_TRACE_FUNC, "NSCD socket was detected and it "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "seems to be configured not to interfere with "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "SSSD's caching capabilities\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Parse config file, fail if cannot be done */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = load_configuration(tmp_ctx, config_file, CONFDB_DEFAULT_CONFIG_DIR,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher &monitor);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher switch (ret) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher case ERR_MISSING_CONF:
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Configuration file: %s does not exist.\n", config_file);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sss_log(SSS_LOG_ALERT,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Configuration file: %s does not exist.\n", config_file);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher break;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher case EPERM:
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher case EACCES:
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONF_FILE_PERM_ERROR_MSG, config_file);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sss_log(SSS_LOG_ALERT, CONF_FILE_PERM_ERROR_MSG, config_file);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher break;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher default:
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "SSSD couldn't load the configuration database.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sss_log(SSS_LOG_ALERT,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "SSSD couldn't load the configuration database [%d]: %s.\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret, strerror(ret));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher break;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return 4;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* at this point we are done generating the config file, we may exit
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * if that's all we were asked to do */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (opt_genconf) return 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* set up things like debug , signals, daemonization, etc... */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor->conf_path = CONFDB_MONITOR_CONF_ENTRY;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = close(STDIN_FILENO);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) return 6;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = server_setup(MONITOR_NAME, flags, 0, 0,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor->conf_path, &main_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) return 2;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor->is_daemon = !opt_interactive;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor->parent_pid = main_ctx->parent_pid;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher monitor->ev = main_ctx->event_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_steal(main_ctx, monitor);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = monitor_process_init(monitor, config_file);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) return 3;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_free(tmp_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* loop on main */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher server_loop(main_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = monitor_cleanup();
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK) return 5;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher