f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * CDDL HEADER START
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * The contents of this file are subject to the terms of the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Common Development and Distribution License (the "License").
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * You may not use this file except in compliance with the License.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * or http://www.opensolaris.org/os/licensing.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * See the License for the specific language governing permissions
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * and limitations under the License.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * When distributing Covered Code, include this CDDL HEADER in each
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * If applicable, add the following below this CDDL HEADER, with the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * fields enclosed by brackets "[]" replaced with your own identifying
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * information: Portions Copyright [yyyy] [name of copyright owner]
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * CDDL HEADER END
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <stdio.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <stdlib.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <string.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <alloca.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <errno.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <fcntl.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <libscf.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <priv_utils.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <netdb.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <signal.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <strings.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <time.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <unistd.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <zone.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <sys/types.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <sys/stat.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <fm/fmd_msg.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <fm/libfmevent.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include "libfmnotify.h"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define SENDMAIL "/usr/sbin/sendmail"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define SVCNAME "system/fm/smtp-notify"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define XHDR_HOSTNAME "X-FMEV-HOSTNAME"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define XHDR_CLASS "X-FMEV-CLASS"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define XHDR_UUID "X-FMEV-UUID"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define XHDR_MSGID "X-FMEV-CODE"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define XHDR_SEVERITY "X-FMEV-SEVERITY"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define XHDR_FMRI "X-FMEV-FMRI"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define XHDR_FROM_STATE "X-FMEV-FROM-STATE"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define XHDR_TO_STATE "X-FMEV-TO-STATE"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Debug messages can be enabled by setting the debug property to true
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * # svccfg -s svc:/system/fm/smtp-notify setprop config/debug=true
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Debug messages will be spooled to the service log at:
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * <root>/var/svc/log/system-fm-smtp-notify:default.log
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define PP_SCRIPT "usr/lib/fm/notify/process_msg_template.sh"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbytypedef struct email_pref
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int ep_num_recips;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char **ep_recips;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *ep_reply_to;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *ep_template_path;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *ep_template;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby} email_pref_t;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic nd_hdl_t *nhdl;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic char hostname[MAXHOSTNAMELEN + 1];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic const char optstr[] = "dfR:";
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic const char DEF_SUBJ_TEMPLATE[] = "smtp-notify-subject-template";
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic const char SMF_SUBJ_TEMPLATE[] = "smtp-notify-smf-subject-template";
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic const char FM_SUBJ_TEMPLATE[] = "smtp-notify-fm-subject-template";
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic const char IREPORT_MSG_TEMPLATE[] = "ireport-msg-template";
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic const char SMF_MSG_TEMPLATE[] = "ireport.os.smf-msg-template";
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic int
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyusage(const char *pname)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fprintf(stderr, "Usage: %s [-df] [-R <altroot>]\n", pname);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fprintf(stderr,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "\t-d enable debug mode\n"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "\t-f stay in foreground\n"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "\t-R specify alternate root\n");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * This function simply reads the file specified by "template" into a buffer
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * and returns a pointer to that buffer (or NULL on failure). The caller is
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * responsible for free'ing the returned buffer.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic char *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyread_template(const char *template)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int fd;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby struct stat statb;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *buf;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (stat(template, &statb) != 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to stat %s (%s)", template,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby strerror(errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((fd = open(template, O_RDONLY)) < 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to open %s (%s)", template,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby strerror(errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((buf = malloc(statb.st_size + 1)) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to allocate %d bytes", statb.st_size);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) close(fd);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (read(fd, buf, statb.st_size) < 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to read in template (%s)",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby strerror(errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(buf);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) close(fd);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby buf[statb.st_size] = '\0';
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) close(fd);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (buf);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * This function runs a user-supplied message body template through a script
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * which replaces the "committed" expansion macros with actual libfmd_msg
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * expansion macros.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic int
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyprocess_template(nd_ev_info_t *ev_info, email_pref_t *eprefs)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char pp_script[PATH_MAX], tmpfile[PATH_MAX], pp_cli[PATH_MAX];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int ret = -1;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snprintf(pp_script, sizeof (pp_script), "%s%s",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_rootdir, PP_SCRIPT);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snprintf(tmpfile, sizeof (tmpfile), "%s%s",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_rootdir, tmpnam(NULL));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * If it's an SMF event, then the diagcode and severity won't be part
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * of the event payload and so libfmd_msg won't be able to expand them.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Therefore we pass the code and severity into the script and let the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * script do the expansion.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /* LINTED: E_SEC_SPRINTF_UNBOUNDED_COPY */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sprintf(pp_cli, "%s %s %s %s %s", pp_script,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby eprefs->ep_template_path, tmpfile, ev_info->ei_diagcode,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_severity);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Executing %s", pp_cli);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (system(pp_cli) != -1)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((eprefs->ep_template = read_template(tmpfile)) != NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ret = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) unlink(tmpfile);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (ret);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * If someone does an "svcadm refresh" on us, then this function gets called,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * which rereads our service configuration.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic void
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyget_svc_config()
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int s = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint8_t val;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby s = nd_get_boolean_prop(nhdl, SVCNAME, "config", "debug", &val);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_debug = val;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby s += nd_get_astring_prop(nhdl, SVCNAME, "config", "rootdir",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &(nhdl->nh_rootdir));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (s != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to read retrieve service "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "properties\n");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic void
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_sighandler(int sig)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (sig == SIGHUP)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby get_svc_config();
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby else
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_cleanup(nhdl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * This function constructs all the email headers and puts them into the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * "headers" buffer handle. The caller is responsible for free'ing this
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * buffer.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic int
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbybuild_headers(nd_hdl_t *nhdl, nd_ev_info_t *ev_info, email_pref_t *eprefs,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char **headers)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby const char *subj_key;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *subj_fmt, *subj = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby size_t len;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby boolean_t is_smf_event = B_FALSE, is_fm_event = B_FALSE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Fetch and format the email subject.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (strncmp(ev_info->ei_class, "list.", 5) == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby is_fm_event = B_TRUE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby subj_key = FM_SUBJ_TEMPLATE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else if (strncmp(ev_info->ei_class, "ireport.os.smf", 14) == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby is_smf_event = B_TRUE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby subj_key = SMF_SUBJ_TEMPLATE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby subj_key = DEF_SUBJ_TEMPLATE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((subj_fmt = fmd_msg_gettext_key(nhdl->nh_msghdl, NULL,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby FMNOTIFY_MSG_DOMAIN, subj_key)) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to contruct subject format");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1); /* libfmd_msg error */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (is_fm_event) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /* LINTED: E_SEC_PRINTF_VAR_FMT */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby len = snprintf(NULL, 0, subj_fmt, hostname,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_diagcode);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby subj = alloca(len + 1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /* LINTED: E_SEC_PRINTF_VAR_FMT */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snprintf(subj, len + 1, subj_fmt, hostname,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_diagcode);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else if (is_smf_event) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /* LINTED: E_SEC_PRINTF_VAR_FMT */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby len = snprintf(NULL, 0, subj_fmt, hostname, ev_info->ei_fmri,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_from_state, ev_info->ei_to_state);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby subj = alloca(len + 1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /* LINTED: E_SEC_PRINTF_VAR_FMT */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snprintf(subj, len + 1, subj_fmt, hostname,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_fmri, ev_info->ei_from_state,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_to_state);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /* LINTED: E_SEC_PRINTF_VAR_FMT */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby len = snprintf(NULL, 0, subj_fmt, hostname);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby subj = alloca(len + 1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /* LINTED: E_SEC_PRINTF_VAR_FMT */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snprintf(subj, len + 1, subj_fmt, hostname);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Here we add some X-headers to our mail message for use by mail
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * filtering agents. We add headers for the following bits of event
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * data for all events
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * hostname
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * msg id (diagcode)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * event class
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * event severity
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * event uuid
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * For SMF transition events, we'll have the following add'l X-headers
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * from-state
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * to-state
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * service fmri
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * We follow the X-headers with standard Reply-To and Subject headers.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (is_fm_event) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby len = snprintf(NULL, 0, "%s: %s\n%s: %s\n%s: %s\n%s: %s\n"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "%s: %s\nReply-To: %s\nSubject: %s\n\n", XHDR_HOSTNAME,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby hostname, XHDR_CLASS, ev_info->ei_class, XHDR_UUID,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_uuid, XHDR_MSGID, ev_info->ei_diagcode,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby XHDR_SEVERITY, ev_info->ei_severity, eprefs->ep_reply_to,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby subj);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *headers = calloc(len + 1, sizeof (char));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snprintf(*headers, len + 1, "%s: %s\n%s: %s\n%s: %s\n"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "%s: %s\n%s: %s\nReply-To: %s\nSubject: %s\n\n",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby XHDR_HOSTNAME, hostname, XHDR_CLASS, ev_info->ei_class,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby XHDR_UUID, ev_info->ei_uuid, XHDR_MSGID,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_diagcode, XHDR_SEVERITY, ev_info->ei_severity,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby eprefs->ep_reply_to, subj);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else if (is_smf_event) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby len = snprintf(NULL, 0, "%s: %s\n%s: %s\n%s: %s\n%s: %s\n"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "%s: %s\n%s: %s\n%s: %s\nReply-To: %s\n"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "Subject: %s\n\n", XHDR_HOSTNAME, hostname, XHDR_CLASS,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_class, XHDR_MSGID, ev_info->ei_diagcode,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby XHDR_SEVERITY, ev_info->ei_severity, XHDR_FMRI,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_fmri, XHDR_FROM_STATE, ev_info->ei_from_state,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby XHDR_TO_STATE, ev_info->ei_to_state, eprefs->ep_reply_to,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby subj);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *headers = calloc(len + 1, sizeof (char));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snprintf(*headers, len + 1, "%s: %s\n%s: %s\n%s: %s\n"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "%s: %s\n%s: %s\n%s: %s\n%s: %s\nReply-To: %s\n"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "Subject: %s\n\n", XHDR_HOSTNAME, hostname, XHDR_CLASS,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_class, XHDR_MSGID, ev_info->ei_diagcode,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby XHDR_SEVERITY, ev_info->ei_severity, XHDR_FMRI,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_fmri, XHDR_FROM_STATE, ev_info->ei_from_state,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby XHDR_TO_STATE, ev_info->ei_to_state, eprefs->ep_reply_to,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby subj);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby len = snprintf(NULL, 0, "%s: %s\n%s: %s\n%s: %s\n%s: %s\n"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "Reply-To: %s\nSubject: %s\n\n", XHDR_HOSTNAME,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby hostname, XHDR_CLASS, ev_info->ei_class, XHDR_MSGID,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_diagcode, XHDR_SEVERITY, ev_info->ei_severity,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby eprefs->ep_reply_to, subj);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *headers = calloc(len + 1, sizeof (char));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snprintf(*headers, len + 1, "%s: %s\n%s: %s\n%s: %s\n"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "%s: %s\nReply-To: %s\nSubject: %s\n\n",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby XHDR_HOSTNAME, hostname, XHDR_CLASS, ev_info->ei_class,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby XHDR_MSGID, ev_info->ei_diagcode, XHDR_SEVERITY,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_severity, eprefs->ep_reply_to, subj);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic void
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbysend_email(nd_hdl_t *nhdl, const char *headers, const char *body,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby const char *recip)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby FILE *mp;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char sm_cli[PATH_MAX];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Open a pipe to sendmail and pump out the email message
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snprintf(sm_cli, PATH_MAX, "%s -t %s", SENDMAIL, recip);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Sending email notification to %s", recip);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((mp = popen(sm_cli, "w")) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to open pipe to %s (%s)", SENDMAIL,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby strerror(errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (fprintf(mp, "%s", headers) < 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to write to pipe (%s)", strerror(errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (fprintf(mp, "%s\n.\n", body) < 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to write to pipe (%s)",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby strerror(errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) pclose(mp);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic void
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbysend_email_template(nd_hdl_t *nhdl, nd_ev_info_t *ev_info, email_pref_t *eprefs)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *msg, *headers;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (build_headers(nhdl, ev_info, eprefs, &headers) != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * If the user specified a message body template, then we pass it
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * through a private interface in libfmd_msg, which will return a string
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * with any expansion tokens decoded.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((msg = fmd_msg_decode_tokens(ev_info->ei_payload,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby eprefs->ep_template, ev_info->ei_url)) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to parse msg template");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(headers);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (int i = 0; i < eprefs->ep_num_recips; i++)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby send_email(nhdl, headers, msg, eprefs->ep_recips[i]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(msg);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(headers);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic int
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyget_email_prefs(nd_hdl_t *nhdl, fmev_t ev, email_pref_t **eprefs)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_t **p_nvl = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby email_pref_t *ep;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint_t npref, tn1 = 0, tn2 = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char **tmparr1, **tmparr2;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int r, ret = -1;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby r = nd_get_notify_prefs(nhdl, "smtp", ev, &p_nvl, &npref);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (r == SCF_ERROR_NOT_FOUND) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * No email notification preferences specified for this type of
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * event, so we're done
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else if (r != 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to retrieve notification preferences "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "for this event");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((ep = malloc(sizeof (email_pref_t))) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to allocate space for email preferences "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "(%s)", strerror(errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto eprefs_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) memset(ep, 0, sizeof (email_pref_t));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * For SMF state transition events, pref_nvl may contain two sets of
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * preferences, which will have to be merged.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * The "smtp" nvlist can contain up to four members:
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * "active" - boolean - used to toggle notfications
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * "to" - a string array of email recipients
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * "reply-to" - a string array containing the reply-to addresses
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * - this is optional and defaults to root@localhost
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * "msg_template" - the pathname of a user-supplied message body
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * template
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * In the case that we have two sets of preferences, we will merge them
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * using the following rules:
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * "active" will be set to true, if it is true in either set
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * The "reply-to" and "to" lists will be merged, with duplicate email
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * addresses removed.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (npref == 2) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby boolean_t *act1, *act2;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char **arr1, **arr2, **strarr, **reparr1, **reparr2;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint_t n1, n2, arrsz, repsz;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby r = nvlist_lookup_boolean_array(p_nvl[0], "active", &act1, &n1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby r += nvlist_lookup_boolean_array(p_nvl[1], "active", &act2,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &n2);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby r += nvlist_lookup_string_array(p_nvl[0], "to", &arr1, &n1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby r += nvlist_lookup_string_array(p_nvl[1], "to", &arr2, &n2);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (r != 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Malformed email notification "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "preferences");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_dump_nvlist(nhdl, p_nvl[0]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_dump_nvlist(nhdl, p_nvl[1]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto eprefs_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else if (!act1[0] && !act2[0]) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Email notification is disabled");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto eprefs_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nd_split_list(nhdl, arr1[0], ",", &tmparr1, &tn1) != 0 ||
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_split_list(nhdl, arr2[0], ",", &tmparr2, &tn2) != 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Error parsing \"to\" lists");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_dump_nvlist(nhdl, p_nvl[0]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_dump_nvlist(nhdl, p_nvl[1]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto eprefs_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((ep->ep_num_recips = nd_merge_strarray(nhdl, tmparr1, tn1,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby tmparr2, tn2, &ep->ep_recips)) < 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Error merging email recipient lists");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto eprefs_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby r = nvlist_lookup_string_array(p_nvl[0], "reply-to", &arr1,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &n1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby r += nvlist_lookup_string_array(p_nvl[1], "reply-to", &arr2,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &n2);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby repsz = n1 = n2 = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (!r &&
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_split_list(nhdl, arr1[0], ",", &reparr1, &n1) != 0 ||
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_split_list(nhdl, arr2[0], ",", &reparr2, &n2) != 0 ||
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (repsz = nd_merge_strarray(nhdl, tmparr1, n1, tmparr2, n2,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &strarr)) != 0 ||
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_join_strarray(nhdl, strarr, repsz, &ep->ep_reply_to)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby != 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ep->ep_reply_to = strdup("root@localhost");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (n1)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_strarray(reparr1, n1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (n2)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_strarray(reparr2, n2);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (repsz > 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_strarray(strarr, repsz);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_string_array(p_nvl[0], "msg_template",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &strarr, &arrsz) == 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ep->ep_template_path = strdup(strarr[0]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char **strarr, **tmparr;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint_t arrsz;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby boolean_t *active;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Both the "active" and "to" notification preferences are
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * required, so if we have trouble looking either of these up
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * we return an error. We will also return an error if "active"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * is set to false. Returning an error will cause us to not
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * send a notification for this event.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby r = nvlist_lookup_boolean_array(p_nvl[0], "active", &active,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &arrsz);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby r += nvlist_lookup_string_array(p_nvl[0], "to", &strarr,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &arrsz);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (r != 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Malformed email notification "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "preferences");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_dump_nvlist(nhdl, p_nvl[0]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto eprefs_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else if (!active[0]) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Email notification is disabled");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto eprefs_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nd_split_list(nhdl, strarr[0], ",", &tmparr, &arrsz)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby != 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Error parsing \"to\" list");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto eprefs_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ep->ep_num_recips = arrsz;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ep->ep_recips = tmparr;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_string_array(p_nvl[0], "msg_template",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &strarr, &arrsz) == 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ep->ep_template_path = strdup(strarr[0]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_string_array(p_nvl[0], "reply-to", &strarr,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &arrsz) == 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ep->ep_reply_to = strdup(strarr[0]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby else
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ep->ep_reply_to = strdup("root@localhost");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ret = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *eprefs = ep;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyeprefs_done:
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (ret != 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (ep->ep_recips)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_strarray(ep->ep_recips, ep->ep_num_recips);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (ep->ep_reply_to)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(ep->ep_reply_to);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(ep);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (tn1)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_strarray(tmparr1, tn1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (tn2)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_strarray(tmparr2, tn2);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_nvlarray(p_nvl, npref);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (ret);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*ARGSUSED*/
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic void
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyirpt_cbfunc(fmev_t ev, const char *class, nvlist_t *nvl, void *arg)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *body_fmt, *headers = NULL, *body = NULL, tstamp[32];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby struct tm ts;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby size_t len;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_ev_info_t *ev_info = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby email_pref_t *eprefs;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Received event of class %s", class);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (get_email_prefs(nhdl, ev, &eprefs) < 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nd_get_event_info(nhdl, class, ev, &ev_info) != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto irpt_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * If the user specified a template, then we pass it through a script,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * which post-processes any expansion macros. Then we attempt to read
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * it in and then send the message. Otherwise we carry on with the rest
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * of this function which will contruct the message body from one of the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * default templates.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (eprefs->ep_template != NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(eprefs->ep_template);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (eprefs->ep_template_path != NULL &&
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby process_template(ev_info, eprefs) == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby send_email_template(nhdl, ev_info, eprefs);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto irpt_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Fetch and format the event timestamp
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (fmev_localtime(ev, &ts) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Malformed event: failed to retrieve "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "timestamp");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto irpt_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) strftime(tstamp, sizeof (tstamp), NULL, &ts);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * We have two message body templates to choose from. One for SMF
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * service transition events and a generic one for any other
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * uncommitted ireport.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (strncmp(class, "ireport.os.smf", 14) == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * For SMF state transition events we have a standard message
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * template that we fill in based on the payload of the event.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((body_fmt = fmd_msg_gettext_key(nhdl->nh_msghdl, NULL,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby FMNOTIFY_MSG_DOMAIN, SMF_MSG_TEMPLATE)) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to format message body");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto irpt_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /* LINTED: E_SEC_PRINTF_VAR_FMT */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby len = snprintf(NULL, 0, body_fmt, hostname, tstamp,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_fmri, ev_info->ei_from_state,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_to_state, ev_info->ei_descr,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_reason);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby body = calloc(len, sizeof (char));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /* LINTED: E_SEC_PRINTF_VAR_FMT */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snprintf(body, len, body_fmt, hostname, tstamp,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_fmri, ev_info->ei_from_state,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_to_state, ev_info->ei_descr,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_reason);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((body_fmt = fmd_msg_gettext_key(nhdl->nh_msghdl, NULL,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby FMNOTIFY_MSG_DOMAIN, IREPORT_MSG_TEMPLATE)) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to format message body");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto irpt_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /* LINTED: E_SEC_PRINTF_VAR_FMT */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby len = snprintf(NULL, 0, body_fmt, hostname, tstamp, class);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby body = calloc(len, sizeof (char));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /* LINTED: E_SEC_PRINTF_VAR_FMT */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snprintf(body, len, body_fmt, hostname, tstamp, class);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (build_headers(nhdl, ev_info, eprefs, &headers) != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto irpt_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Everything is ready, so now we just iterate through the list of
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * recipents, sending an email notification to each one.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (int i = 0; i < eprefs->ep_num_recips; i++)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby send_email(nhdl, headers, body, eprefs->ep_recips[i]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyirpt_done:
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(headers);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(body);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (ev_info)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_event_info(ev_info);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (eprefs->ep_recips)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_strarray(eprefs->ep_recips, eprefs->ep_num_recips);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (eprefs->ep_reply_to)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(eprefs->ep_reply_to);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(eprefs);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * There is a lack of uniformity in how the various entries in our diagnosis
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * are terminated. Some end with one newline, others with two. This makes the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * output look a bit ugly. Therefore we postprocess the message before sending
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * it, removing consecutive occurences of newlines.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic void
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbypostprocess_msg(char *msg)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int i = 0, j = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *buf;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((buf = malloc(strlen(msg) + 1)) == NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby buf[j++] = msg[i++];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (i = 1; i < strlen(msg); i++) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (!(msg[i] == '\n' && msg[i - 1] == '\n'))
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby buf[j++] = msg[i];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby buf[j] = '\0';
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) strncpy(msg, buf, j+1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(buf);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*ARGSUSED*/
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic void
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbylistev_cb(fmev_t ev, const char *class, nvlist_t *nvl, void *arg)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *body = NULL, *headers = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_ev_info_t *ev_info = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby boolean_t domsg;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby email_pref_t *eprefs;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Received event of class %s", class);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (get_email_prefs(nhdl, ev, &eprefs) < 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nd_get_event_info(nhdl, class, ev, &ev_info) != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto listcb_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * If the message payload member is set to 0, then it's an event we
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * typically suppress messaging on, so we won't send an email for it.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_boolean_value(ev_info->ei_payload, FM_SUSPECT_MESSAGE,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &domsg) == 0 && !domsg) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Messaging suppressed for this event");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto listcb_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * If the user specified a template, then we pass it through a script,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * which post-processes any expansion macros. Then we attempt to read
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * it in and then send the message. Otherwise we carry on with the rest
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * of this function which will contruct the message body from one of the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * default templates.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (eprefs->ep_template != NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(eprefs->ep_template);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (eprefs->ep_template_path != NULL &&
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby process_template(ev_info, eprefs) == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby send_email_template(nhdl, ev_info, eprefs);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto listcb_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Format the message body
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * For FMA list.* events we use the same message that the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * syslog-msgs agent would emit as the message body
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((body = fmd_msg_gettext_nv(nhdl->nh_msghdl, NULL,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_info->ei_payload)) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to format message body");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_dump_nvlist(nhdl, ev_info->ei_payload);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto listcb_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby postprocess_msg(body);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (build_headers(nhdl, ev_info, eprefs, &headers) != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto listcb_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Everything is ready, so now we just iterate through the list of
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * recipents, sending an email notification to each one.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (int i = 0; i < eprefs->ep_num_recips; i++)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby send_email(nhdl, headers, body, eprefs->ep_recips[i]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbylistcb_done:
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(headers);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(body);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (ev_info)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_event_info(ev_info);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (eprefs->ep_recips)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_strarray(eprefs->ep_recips, eprefs->ep_num_recips);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (eprefs->ep_reply_to)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(eprefs->ep_reply_to);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(eprefs);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyint
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbymain(int argc, char *argv[])
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby struct rlimit rlim;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby struct sigaction act;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sigset_t set;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char c;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby boolean_t run_fg = B_FALSE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((nhdl = malloc(sizeof (nd_hdl_t))) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fprintf(stderr, "Failed to allocate space for notifyd "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "handle (%s)", strerror(errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) memset(nhdl, 0, sizeof (nd_hdl_t));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_keep_running = B_TRUE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_log_fd = stderr;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_pname = argv[0];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby get_svc_config();
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * In the case where we get started outside of SMF, args passed on the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * command line override SMF property setting
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby while (optind < argc) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby while ((c = getopt(argc, argv, optstr)) != -1) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby switch (c) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby case 'd':
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_debug = B_TRUE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby break;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby case 'f':
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby run_fg = B_TRUE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby break;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby case 'R':
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_rootdir = strdup(optarg);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby break;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby default:
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(nhdl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (usage(nhdl->nh_pname));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Set up a signal handler for SIGTERM (and SIGINT if we'll
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * be running in the foreground) to ensure sure we get a chance to exit
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * in an orderly fashion. We also catch SIGHUP, which will be sent to
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * us by SMF if the service is refreshed.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigfillset(&set);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigfillset(&act.sa_mask);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby act.sa_handler = nd_sighandler;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby act.sa_flags = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigaction(SIGTERM, &act, NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigdelset(&set, SIGTERM);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigaction(SIGHUP, &act, NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigdelset(&set, SIGHUP);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (run_fg) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigaction(SIGINT, &act, NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigdelset(&set, SIGINT);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_daemonize(nhdl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby rlim.rlim_cur = RLIM_INFINITY;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby rlim.rlim_max = RLIM_INFINITY;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) setrlimit(RLIMIT_CORE, &rlim);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * We need to be root to initialize our libfmevent handle (because that
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * involves reading/writing to /dev/sysevent), so we do this before
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * calling __init_daemon_priv.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_evhdl = fmev_shdl_init(LIBFMEVENT_VERSION_2, NULL, NULL, NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nhdl->nh_evhdl == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sleep(5);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_abort(nhdl, "failed to initialize libfmevent: %s",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmev_strerror(fmev_errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * If we're in the global zone, reset all of our privilege sets to
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * the minimum set of required privileges. Since we've already
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * initialized our libmevent handle, we no no longer need to run as
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * root, so we change our uid/gid to noaccess (60002).
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * __init_daemon_priv will also set the process core path for us
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (getzoneid() == GLOBAL_ZONEID)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (__init_daemon_priv(
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby PU_RESETGROUPS | PU_LIMITPRIVS | PU_INHERITPRIVS,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby 60002, 60002, PRIV_PROC_SETID, NULL) != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_abort(nhdl, "additional privileges required to run");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_msghdl = fmd_msg_init(nhdl->nh_rootdir, FMD_MSG_VERSION);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nhdl->nh_msghdl == NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_abort(nhdl, "failed to initialize libfmd_msg");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) gethostname(hostname, MAXHOSTNAMELEN + 1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Set up our event subscriptions. We subscribe to everything and then
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * consult libscf when we receive an event to determine whether to send
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * an email notification.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Subscribing to ireport.* events");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (fmev_shdl_subscribe(nhdl->nh_evhdl, "ireport.*", irpt_cbfunc,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby NULL) != FMEV_SUCCESS) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_abort(nhdl, "fmev_shdl_subscribe failed: %s",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmev_strerror(fmev_errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Subscribing to list.* events");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (fmev_shdl_subscribe(nhdl->nh_evhdl, "list.*", listev_cb,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby NULL) != FMEV_SUCCESS) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_abort(nhdl, "fmev_shdl_subscribe failed: %s",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmev_strerror(fmev_errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * We run until someone kills us
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby while (nhdl->nh_keep_running)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigsuspend(&set);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(nhdl->nh_rootdir);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(nhdl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}