--- a/components/pflogd/patches/002-smf.patch Wed Mar 09 08:20:13 2016 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1217 +0,0 @@
-# This patch comes from Oracle. It turns the component into
-# a well-behaving SMF service. It adds code manipulating service
-# properties, service instances, and also provides security
-# in cooperation with the service manifest (especially, extra
-# privileges are dropped when not needed).
-#
-# This patch is not going to upstream, the changes are Solaris-specific.
-
-diff -Naur pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/Makefile pflogd-OPENBSD_5_5-OPENBSD_5_5/Makefile
---- pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/Makefile 2016-02-17 02:08:53.410106245 -0800
-+++ pflogd-OPENBSD_5_5-OPENBSD_5_5/Makefile 2016-02-16 05:02:32.489035397 -0800
-@@ -3,7 +3,7 @@
- CFLAGS+= -m64 -errwarn
-
- PROG=pflogd
--SRCS=pflogd.c privsep.c privsep_fdpass.c
-+SRCS=pflogd.c privsep.c privsep_fdpass.c smf-config.c
- OBJS=$(SRCS:.c=.o)
- MAN=pflogd.8
-
-diff -Naur pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/pflogd.8 pflogd-OPENBSD_5_5-OPENBSD_5_5/pflogd.8
---- pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/pflogd.8 2016-02-17 02:32:29.857912548 -0800
-+++ pflogd-OPENBSD_5_5-OPENBSD_5_5/pflogd.8 2016-02-24 21:24:27.453116577 -0800
-@@ -33,7 +33,7 @@
- .Sh SYNOPSIS
- .Nm pflogd
- .Bk -words
--.Op Fl "Dx"
-+.Op Fl C Ar new-pflog-instance-name | Fl c Ar pflog-instance-name
- .Op Fl d Ar delay
- .Op Fl f Ar filename
- .Op Fl i Ar interface
-@@ -60,6 +60,7 @@
- hopefully offline in case there are bugs in the packet parsing code of
- .Xr tcpdump 8 .
- .Pp
-+
- .Nm
- closes and then re-opens the log file when it receives
- .Dv SIGHUP ,
-@@ -101,22 +102,52 @@
- .Pp
- The options are as follows:
- .Bl -tag -width Ds
--.It Fl D
--Debugging mode.
-+.It Fl C Ar new-pflog-instance-name
-+Creates a new
- .Nm
--does not disassociate from the controlling terminal.
-+instance with the specified name. If additional options are used to specify
-+configuration, it is stored into the
-+.Xr smf 5
-+repository. Default values are used for
-+.Xr smf 5
-+properties unless overriden by a command-line option. The exception is
-+pflog/interface (set to equal the instance name) and pflog/logfile
-+(set to a file with name equal to the instance name followed by the
-+.Pa .pkt
-+extension located inside the
-+.Pa /var/log/firewall/pflog/
-+directory) if the service instance name forms a valid linkname. If the
-+service instance name is not a valid linkname, the values must be
-+given explicitly.
-+.It Fl c Ar pflog-instance-name
-+Shows/changes the configuration of the given
-+.Nm
-+instance in
-+.Xr smf 5
-+repository. Attributes specified by additional options are placed into the
-+.Xr smf 5
-+repository.
- .It Fl d Ar delay
- Time in seconds to delay between automatic flushes of the file.
- This may be specified with a value between 5 and 3600 seconds.
- If not specified, the default is 60 seconds.
- .It Fl f Ar filename
--Log output filename.
-+Log output filename. When neither
-+.Fl C
-+nor
-+.Fl c
-+is used, the default value
-+.Pa pflog.pkt
-+is used.
- .It Fl i Ar interface
- Specifies the capture link interface to use.
--By default,
--.Nm
--will use
--.Pa pflog0 .
-+When neither
-+.Fl C
-+nor
-+.Fl c
-+is used, the default value
-+.Pa pflog0
-+is assumed.
- .It Fl s Ar snaplen
- Analyze at most the first
- .Ar snaplen
-@@ -124,8 +155,6 @@
- The default of 160 is adequate for IP, ICMP, TCP, and UDP headers but may
- truncate protocol information for other protocols.
- Other file parsers may desire a higher snaplen.
--.It Fl x
--Check the integrity of an existing log file, and return.
- .It Ar expression
- Selects which packets will be dumped, using the regular language of
- .Xr tcpdump 8 .
-@@ -164,11 +193,59 @@
- The direction was outbound.
- .El
- .El
--.Sh FILES
--.Bl -tag -width /var/run/pflogd.pid -compact
--.It Pa /var/log/firewall/pflog/pflog0.pkt
--Default log file.
-+.Sh SOLARIS
-+The
-+.Nm
-+daemon runs as an
-+.Xr smf 5
-+service with the following FMRI:
-+.Bd -literal -offset indent
-+svc:/network/firewall/pflog
-+.Ed
-+.Pp
-+Command line options described above are set via the following
-+.Xr smf 5
-+properties.
-+.Bl -tag -width "pflog/interface" -offset 3n -compact
-+.It pflog/delay
-+Automatic flush interval.
-+The default value is 60.
-+Used as the argument for the
-+.Fl d
-+option.
-+.It pflog/filter
-+Packet filter expression in
-+.Xr tcpdump 8
-+format.
-+No expression is defined by default.
-+.It pflog/interface
-+The capture link name from which to read packets.
-+Used as the argument for the
-+.Fl i
-+option.
-+.It pflog/logfile
-+Path to the logfile (for security reasons, only paths starting by the
-+.Pa /var/log/firewall/
-+directory are allowed.
-+Used as the argument for the
-+.Fl f
-+option.
-+.It pflog/snaplen
-+An upper bound on how many bytes from each packet to analyze.
-+The default value is 160.
-+Used as the argument for the
-+.Fl s
-+option.
- .El
-+.Pp
-+The start method creates a (temporal) capture link the particular
-+instance is using.
-+.Pp
-+The refresh method sends
-+.Dv SIGHUP
-+to
-+.Nm
-+owned by particular service instance.
- .Sh EXAMPLES
- Log specific TCP packets to a different log file with a large snaplen
- (useful with a
-@@ -202,6 +279,32 @@
- .Bd -literal -offset indent
- # tcpdump -n -e -ttt -i pflog0 inbound and action block and on wi0
- .Ed
-+.Sh SECURITY
-+The
-+.Nm
-+daemon is a privilege-aware application which runs as the
-+.Dq daemon
-+user possessing
-+.Sy PRIV_NET_OBSERVABILITY
-+privilege that is required for using
-+.Xr bpf 7d
-+to read packets. See
-+.Xr privileges 5
-+for details.
-+The service start method uses
-+.Xr dladm 1M
-+to create capture link if it does not exist already.
-+.Pp
-+To configure the
-+.Nm
-+service one has to obtain the
-+.Sy solaris.smf.value.network.firewall
-+authorization.
-+To manage the service (disable/enable/refresh) one must have the
-+.Sy solaris.smf.manage.network.firewall
-+authorization.
-+Both authorizations are granted through the Network Firewall Management profile.
-+To create new service instances, you need the solaris.smf.modify authorization.
- .Sh SEE ALSO
- .Xr pcap 3 ,
- .Xr pf.conf 5 ,
-diff -Naur pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/pflogd.c pflogd-OPENBSD_5_5-OPENBSD_5_5/pflogd.c
---- pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/pflogd.c 2016-02-18 12:05:03.256562087 -0800
-+++ pflogd-OPENBSD_5_5-OPENBSD_5_5/pflogd.c 2016-02-18 12:01:49.900876863 -0800
-@@ -54,6 +54,7 @@
- #include <strings.h>
- #include <zone.h>
- #include <libuutil.h>
-+#include "smf-config.h"
- #else /* !_SOLARIS_ */
- #include <util.h>
- #endif /* _SOLARIS_ */
-@@ -63,7 +64,7 @@
- static FILE *dpcap;
-
- int Debug = 0;
--static int snaplen = DEF_SNAPLEN;
-+static int64_t snaplen = DEF_SNAPLEN;
- static int cur_snaplen = DEF_SNAPLEN;
-
- volatile sig_atomic_t gotsig_close, gotsig_alrm, gotsig_hup, gotsig_usr1;
-@@ -75,7 +76,7 @@
- char errbuf[PCAP_ERRBUF_SIZE];
-
- int log_debug = 0;
--unsigned int delay = FLUSH_DELAY;
-+int64_t delay = FLUSH_DELAY;
-
- char *copy_argv(char * const *);
- void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
-@@ -124,6 +125,15 @@
-
- #endif /* _SOLARIS_ */
-
-+#ifdef _SOLARIS_
-+#define PFLOGD_GETOPTS "c:C:Dd:f:i:s:"
-+#define CFG_SETFLAG(_flags_, _f_) ((_flags_) |= (_f_))
-+#define SKIP_CHK(_x_) ((_x_) == NULL)
-+#else /* !_SOLARIS_ */
-+#define PFLOGD_GETOPTS "Dxd:f:i:s:"
-+#define CFG_SETFLAG(_flags_, _f_)
-+#define SKIP_CHK(_x_) (1)
-+#endif /* _SOLARIS_ */
- static int try_reset_dump(int);
-
- /* buffer must always be greater than snaplen */
-@@ -290,6 +300,8 @@
- init_pcap(void)
- {
- hpcap = pcap_open_live(interface, snaplen, 1, PCAP_TO_MS, errbuf);
-+ DROP_PRIV(PRIV_NET_OBSERVABILITY);
-+
- if (hpcap == NULL) {
- logmsg(LOG_ERR, "Failed to initialize: %s", errbuf);
- return (-1);
-@@ -690,12 +702,20 @@
- int ch, np, ret, Xflag = 0;
- pcap_handler phandler = dump_packet;
- const char *errstr = NULL;
-+#ifdef _SOLARIS_
-+ unsigned int create = 0;
-+ unsigned int cfg_flags = 0;
-+ const char *smf_instance = NULL;
-+#endif /* _SOLARIS_ */
-+
-+ DROP_PRIV(PRIV_SYS_IP_CONFIG);
-+ DROP_PRIV(PRIV_PROC_EXEC);
-
- ret = 0;
-
- closefrom(STDERR_FILENO + 1);
-
-- while ((ch = getopt(argc, argv, "Dxd:f:i:s:")) != -1) {
-+ while ((ch = getopt(argc, argv, PFLOGD_GETOPTS)) != -1) {
- switch (ch) {
- case 'D':
- Debug = 1;
-@@ -704,12 +724,15 @@
- delay = strtonum(optarg, 5, 60*60, &errstr);
- if (errstr)
- usage();
-+ CFG_SETFLAG(cfg_flags, SMF_CFG_DELAY_SET);
- break;
- case 'f':
- filename = optarg;
-+ CFG_SETFLAG(cfg_flags, SMF_CFG_LOGFILE_SET);
- break;
- case 'i':
- interface = optarg;
-+ CFG_SETFLAG(cfg_flags, SMF_CFG_INTERFACE_SET);
- break;
- case 's':
- snaplen = strtonum(optarg, 0, PFLOGD_MAXSNAPLEN,
-@@ -718,10 +741,27 @@
- snaplen = DEF_SNAPLEN;
- if (errstr)
- snaplen = PFLOGD_MAXSNAPLEN;
-+ CFG_SETFLAG(cfg_flags, SMF_CFG_SNAPLEN_SET);
- break;
-+#ifndef _SOLARIS_
-+ /*
-+ * This option requires a special securing on Solaris as
-+ * pflogd will be started manually in the case it is used.
-+ * Also, some polishing is needed so that the response
-+ * from 'pflogd -x' is shown to the user and not put into
-+ * a logfile.
-+ */
- case 'x':
- Xflag++;
- break;
-+#endif /* !_SOLARIS_ */
-+#ifdef _SOLARIS_
-+ case 'C':
-+ create = 1; /* FALLTHRU */
-+ case 'c':
-+ smf_instance = optarg;
-+ break;
-+#endif /* _SOLARIS_ */
- default:
- usage();
- }
-@@ -732,14 +772,14 @@
- argv += optind;
-
- /* does interface exist */
-- if (!if_exists(interface)) {
-+ if (SKIP_CHK(smf_instance) && !if_exists(interface)) {
- warn("Failed to initialize: %s", interface);
- logmsg(LOG_ERR, "Failed to initialize: %s", interface);
- logmsg(LOG_ERR, "Exiting, init failure");
- exit(1);
- }
-
-- if (!Debug) {
-+ if (SKIP_CHK(smf_instance) && !Debug) {
- openlog("pflogd", LOG_PID | LOG_CONS, LOG_DAEMON);
- if (daemon(0, 0)) {
- logmsg(LOG_WARNING, "Failed to become daemon: %s",
-@@ -757,6 +797,31 @@
- logmsg(LOG_NOTICE, "Failed to form filter expression");
- }
-
-+#ifdef _SOLARIS_
-+ if (smf_instance != NULL) {
-+ if (filter != NULL) {
-+ CFG_SETFLAG(cfg_flags, SMF_CFG_EXPRESSION_SET);
-+ } else {
-+ filter = "";
-+ }
-+ if ((cfg_flags == 0) && (create == 0)) {
-+ if (smf_print_pflogcfg(smf_instance)) {
-+ exit (-1);
-+ }
-+ } else {
-+ smf_pflogd_cfg.cfg_set = cfg_flags;
-+ smf_pflogd_cfg.cfg_expression = strdup(filter);
-+ smf_pflogd_cfg.cfg_interface = strdup(interface);
-+ smf_pflogd_cfg.cfg_logfile = strdup(filename);
-+ smf_pflogd_cfg.cfg_delay = delay;
-+ smf_pflogd_cfg.cfg_snaplen = snaplen;
-+
-+ smf_write_pflogcfg(smf_instance, create);
-+ }
-+ exit(0);
-+ }
-+#endif /* _SOLARIS_ */
-+
- /* initialize pcap before dropping privileges */
- if (init_pcap()) {
- logmsg(LOG_ERR, "Exiting, init failure");
-@@ -768,7 +833,6 @@
- logmsg(LOG_ERR, "unable to privsep");
- exit(1);
- }
--
- setproctitle("[initializing]");
- /* Process is now unprivileged and inside a chroot */
- #ifdef _SOLARIS_
-diff -Naur pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/pflogd.h pflogd-OPENBSD_5_5-OPENBSD_5_5/pflogd.h
---- pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/pflogd.h 2016-02-18 12:08:42.414919276 -0800
-+++ pflogd-OPENBSD_5_5-OPENBSD_5_5/pflogd.h 2016-02-18 12:09:18.796727948 -0800
-@@ -18,6 +18,8 @@
-
- #ifdef _SOLARIS_
- #include <limits.h>
-+#include <sys/types.h>
-+#include <priv.h>
- #else /* !_SOLARIS_ */
- #include <sys/limits.h>
- #endif /* _SOLARIS_ */
-@@ -55,3 +57,27 @@
- int receive_fd(int);
-
- extern int Debug;
-+
-+#ifdef _SOLARIS_
-+#define DROP_PRIV(priv) \
-+ do { \
-+ if (priv_set(PRIV_OFF, PRIV_PERMITTED, (priv), \
-+ NULL) != 0) { \
-+ fprintf(stderr, \
-+ "Unable to drop privileges.\n"); \
-+ exit (-1); \
-+ } \
-+ } while (0)
-+
-+#define DROP_PFLAG(flag) \
-+ do { \
-+ if (setpflags((flag), 0) != 0) { \
-+ fprintf(stderr, \
-+ "Unable to drop pflag.\n"); \
-+ exit (-1); \
-+ } \
-+} while (0)
-+#else /* !_SOLARIS_ */
-+#define DROP_PRIV(priv)
-+#define DROP_PFLAG(flag)
-+#endif /* _SOLARIS_ */
-diff -Naur pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/privsep.c pflogd-OPENBSD_5_5-OPENBSD_5_5/privsep.c
---- pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/privsep.c 2016-02-18 12:07:34.219667793 -0800
-+++ pflogd-OPENBSD_5_5-OPENBSD_5_5/privsep.c 2016-02-18 11:55:14.949135348 -0800
-@@ -112,6 +112,7 @@
- #endif /* !_SOLARIS_ */
-
- child_pid = fork();
-+ DROP_PRIV(PRIV_PROC_FORK);
- if (child_pid < 0)
- err(1, "fork() failed");
-
-@@ -133,6 +134,7 @@
- if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
- err(1, "setresuid() failed");
- #endif /* !_SOLARIS_ */
-+ DROP_PFLAG(PRIV_XPOLICY);
-
- close(socks[0]);
- priv_fd = socks[1];
-diff -Naur pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/smf-config.c pflogd-OPENBSD_5_5-OPENBSD_5_5/smf-config.c
---- pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/smf-config.c 1969-12-31 16:00:00.000000000 -0800
-+++ pflogd-OPENBSD_5_5-OPENBSD_5_5/smf-config.c 2016-02-24 08:24:57.408744180 -0800
-@@ -0,0 +1,713 @@
-+/*
-+ * CDDL HEADER START
-+ *
-+ * The contents of this file are subject to the terms of the
-+ * Common Development and Distribution License (the "License").
-+ * You may not use this file except in compliance with the License.
-+ *
-+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-+ * or http://www.opensolaris.org/os/licensing.
-+ * See the License for the specific language governing permissions
-+ * and limitations under the License.
-+ *
-+ * When distributing Covered Code, include this CDDL HEADER in each
-+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-+ * If applicable, add the following below this CDDL HEADER, with the
-+ * fields enclosed by brackets "[]" replaced with your own identifying
-+ * information: Portions Copyright [yyyy] [name of copyright owner]
-+ *
-+ * CDDL HEADER END
-+ *
-+ */
-+
-+/*
-+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
-+ */
-+
-+#include <string.h>
-+#include <strings.h>
-+#include <stdlib.h>
-+#include <err.h>
-+#include <stdarg.h>
-+#include <stdio.h>
-+#include <libscf.h>
-+#include <stddef.h>
-+#include <libscf_priv.h>
-+
-+#include "pflogd.h"
-+#include "smf-config.h"
-+
-+#define PFLOGD_PG "pflog"
-+#define PFLOGD_PROP_VALUE_AUTH "value_authorization"
-+#define PFLOGD_PROP_ACTION_AUTH "action_authorization"
-+#define PFLOGD_VALUE_AUTH "solaris.smf.value.network.firewall"
-+#define PFLOGD_MANAGE_AUTH "solaris.smf.manage.network.firewall"
-+
-+#define SKIP_PROP(_pv_) \
-+ ((strcmp((_pv_)->pv_prop, "action_authorization") == 0) || \
-+ (strcmp((_pv_)->pv_prop, "value_authorization") == 0))
-+
-+#define STRIP_SVC(_x_) ((_x_) + (sizeof ("svc:/") - 1))
-+
-+/*
-+ * smf_pflogd_cfg
-+ * FTP proxy configuration container.
-+ */
-+smf_pflogd_cfg_t smf_pflogd_cfg;
-+
-+#define SMF_OPT_OPTIONAL 0
-+#define SMF_OPT_MANDATORY 1
-+/*
-+ * X-macro table.
-+ * Columns are as follows:
-+ * value key/index
-+ * SMF property name name
-+ * member in smf_pflogd_cfg_t structure
-+ * function which converts ASCIIZ to member type in smf_pflogd_cfg_t
-+ * function which converts member in smf_pflogd_cfg_t to ASCIIZ
-+ * optional/mandatory status
-+ * property type
-+ */
-+#define X_CFG_PROPS \
-+ X(SMF_LOGFILE, "logfile", cfg_logfile, nop_in, nop_out, \
-+ SMF_OPT_MANDATORY, SCF_TYPE_ASTRING) \
-+ X(SMF_SNAPLEN, "snaplen", cfg_snaplen, int_in, int_out, \
-+ SMF_OPT_MANDATORY, SCF_TYPE_INTEGER) \
-+ X(SMF_INTERFACE, "interface", cfg_interface, nop_in, nop_out, \
-+ SMF_OPT_MANDATORY, SCF_TYPE_ASTRING) \
-+ X(SMF_DELAY, "delay", cfg_delay, int_in, int_out, \
-+ SMF_OPT_OPTIONAL, SCF_TYPE_INTEGER) \
-+ X(SMF_EXPRESSION, "filter", cfg_expression, nop_in, nop_out, \
-+ SMF_OPT_OPTIONAL, SCF_TYPE_ASTRING)
-+
-+static void nop_in(void *, void *);
-+static void nop_out(void *, void *);
-+static void int_in(void *, void *);
-+static void int_out(void *, void *);
-+
-+/*
-+ * smf_keys
-+ * Keys (indexes) to `smf_propnames` dictionary.
-+ */
-+#define X(_const_, _propname_, _decl_, _conv_in_, _conv_out_, _mandatory_, \
-+ _type_) _const_,
-+enum smf_keys {
-+ X_CFG_PROPS
-+ SMF_CFG_PROP_COUNT
-+};
-+#undef X
-+
-+/*
-+ * smf_propnames
-+ * It's an array (dictionary), which translates property code (SMF_*) to
-+ * property value name found `ftp-proxy` property group.
-+ */
-+#define X(_const_, _propname_, _decl_, _conv_in_, _conv_out_, _mandatory_, \
-+ _type_) _propname_,
-+static const char *smf_propnames[] = {
-+ X_CFG_PROPS
-+ NULL
-+};
-+#undef X
-+
-+/*
-+ * smf_cfg_offsets
-+ * Table of smf_pflogd_cfg_t members.
-+ */
-+#define X(_const_, _propname_, _decl_, _conv_in_, _conv_out_, _mandatory_, \
-+ _type_) offsetof(smf_pflogd_cfg_t, _decl_),
-+static size_t smf_cfg_offsets[] = {
-+ X_CFG_PROPS
-+ sizeof (smf_pflogd_cfg_t)
-+};
-+#undef X
-+
-+typedef void(*conv_in_f)(void *, void *);
-+typedef void(*conv_out_f)(void *, void *);
-+/*
-+ * smf_convert_in
-+ * Table of conversion functions, which convert particular smf_pflogd_cfg_t
-+ * member into ASCIIZ.
-+ */
-+#define X(_const_, _propname_, _decl_, _conv_in_, _conv_out_, _mandatory_, \
-+ _type_) _conv_in_,
-+static conv_in_f smf_conv_in[] = {
-+ X_CFG_PROPS
-+ NULL
-+};
-+#undef X
-+
-+/*
-+ * smf_conv_out
-+ * Table of conversion functions, which convert ASCIIZ fetched from smf(5)
-+ * repository to member of smf_pflogd_cfg_t structure.
-+ */
-+#define X(_const_, _propname_, _decl_, _conv_in_, _conv_out_, _mandatory_, \
-+ _type_) _conv_out_,
-+static conv_out_f smf_conv_out[] = {
-+ X_CFG_PROPS
-+ NULL
-+};
-+#undef X
-+
-+/*
-+ * smf_mandatory
-+ * Table marks configuration parameters, which must be defined by admin,
-+ * before the service is enabled for the first time.
-+ */
-+#define X(_const_, _propname_, _decl_, _conv_in_, _conv_out_, _mandatory_, \
-+ _type_) _mandatory_,
-+static int smf_mandatory[] = {
-+ X_CFG_PROPS
-+ 0
-+};
-+#undef X
-+
-+/*
-+ * smf_type
-+ * Table of types of SMF properties.
-+ */
-+#define X(_const_, _propname_, _decl_, _conv_in_, _conv_out_, _mandatory_, \
-+ _type_) _type_,
-+static int smf_type[] = {
-+ X_CFG_PROPS
-+ 0
-+};
-+#undef X
-+
-+/*
-+ * pflogd property group properties
-+ * +1 for NULL termination.
-+ * +1 for value_authorization
-+ */
-+static scf_propvec_t prop_vec[SMF_CFG_PROP_COUNT + 1 + 1];
-+
-+/*
-+ * general property group properties
-+ * +1 for NULL termination.
-+ * +2 for value_authorization/action_authorization
-+ */
-+static scf_propvec_t gen_prop_vec[1 + 2];
-+
-+static int atexit_set = 0;
-+static int complete_pflogdcfg(const char *);
-+
-+/*
-+ * nop_in()
-+ * Dummy conversion ASCIIZ to ASCIIZ, no allocation happens. Used when
-+ * configuration is from smf(5).
-+ */
-+static void
-+nop_in(void *asciiz, void *result)
-+{
-+ *((char **)result) = (char *)asciiz;
-+}
-+
-+/*
-+ * nop_out()
-+ * Dummy conversion ASCIIZ to ASCIIZ, function allocates memory for result by
-+ * strdup(3C). Used when configuration is written to smf(5) repository.
-+ */
-+static void
-+nop_out(void *asciiz, void *val)
-+{
-+ *((char **)asciiz) = strdup(*(char **)val);
-+}
-+
-+/*
-+ * int_in()
-+ * Dummy conversion of int64_t. No allocation happens. Used when reading
-+ * values from smf.
-+ */
-+static void
-+int_in(void *in, void *out) {
-+ *((int64_t *)out) = *((int64_t *)in);
-+}
-+
-+/*
-+ * int_out()
-+ * Dummy conversion of int64_t, storing into a newly allocated memory.
-+ * Used when storing values to smf repository.
-+ */
-+static void
-+int_out(void *out, void *in) {
-+ int64_t **out_ = (int64_t **)out;
-+
-+ *out_ = malloc(sizeof (int64_t));
-+ if (*out_ != NULL)
-+ **out_ = *((int64_t *)in);
-+}
-+
-+static void
-+clear_prop_vec2(scf_propvec_t *prop_vec_ptr, int count)
-+{
-+ while (count--) {
-+ prop_vec_ptr->pv_prop = NULL;
-+ prop_vec_ptr->pv_desc = NULL;
-+ prop_vec_ptr->pv_type = 0;
-+ prop_vec_ptr->pv_aux = 0;
-+ prop_vec_ptr->pv_mval = 0;
-+
-+ if (prop_vec_ptr->pv_ptr != NULL) {
-+ free(prop_vec_ptr->pv_ptr);
-+ prop_vec_ptr->pv_ptr = NULL;
-+ }
-+
-+ prop_vec_ptr++;
-+ }
-+}
-+
-+/*
-+ * clear_prop_vec()
-+ * Function clears global variables `prop_vec` and `gen_prop_vec`,
-+ * which are vectors of properties.
-+ */
-+static void
-+clear_prop_vec()
-+{
-+ clear_prop_vec2(prop_vec,
-+ sizeof (prop_vec) / sizeof (scf_propvec_t));
-+ clear_prop_vec2(gen_prop_vec,
-+ sizeof (gen_prop_vec) / sizeof (scf_propvec_t));
-+}
-+
-+/*
-+ * cfg_to_prop_vec()
-+ * Function converts smf_pflogd_cfg global variable, which holds configuration
-+ * parsed from command line arguments, to prop_vec, which is a smf(5) friendly
-+ * representation of pflogd configuration.
-+ *
-+ * Additionally, it populates gen_prop_vec to specify needed authorizations.
-+ *
-+ * Returns 0 on success, -1 on out of memory error.
-+ */
-+static int
-+cfg_to_prop_vec(void)
-+{
-+ int cfg_bit = 1;
-+ int i;
-+ scf_propvec_t *prop_vec_ptr = prop_vec;
-+ conv_out_f conv_func;
-+
-+ clear_prop_vec();
-+
-+ for (i = 0; i < SMF_CFG_PROP_COUNT; i++) {
-+ if ((smf_pflogd_cfg.cfg_set & cfg_bit) != 0) {
-+ prop_vec_ptr->pv_prop = smf_propnames[i];
-+ conv_func = smf_conv_out[i];
-+
-+ conv_func(&prop_vec_ptr->pv_ptr,
-+ ((char *)&smf_pflogd_cfg + smf_cfg_offsets[i]));
-+ if (prop_vec_ptr->pv_ptr == NULL)
-+ return (-1);
-+ prop_vec_ptr->pv_type = smf_type[i];
-+ prop_vec_ptr++;
-+ }
-+ cfg_bit = cfg_bit << 1;
-+ }
-+ prop_vec_ptr->pv_type = SCF_TYPE_ASTRING;
-+ prop_vec_ptr->pv_prop = PFLOGD_PROP_VALUE_AUTH;
-+ prop_vec_ptr->pv_ptr = strdup(PFLOGD_VALUE_AUTH);
-+ prop_vec_ptr++;
-+
-+ gen_prop_vec[0].pv_type = SCF_TYPE_ASTRING;
-+ gen_prop_vec[0].pv_prop = PFLOGD_PROP_VALUE_AUTH;
-+ gen_prop_vec[0].pv_ptr = strdup(PFLOGD_MANAGE_AUTH);
-+ gen_prop_vec[1].pv_type = SCF_TYPE_ASTRING;
-+ gen_prop_vec[1].pv_prop = PFLOGD_PROP_ACTION_AUTH;
-+ gen_prop_vec[1].pv_ptr = strdup(PFLOGD_MANAGE_AUTH);
-+
-+ return (0);
-+}
-+
-+/*
-+ * prop_vec_to_cfg()
-+ * Converts global variable `prop_vec` to `smf_pflogd_cfg` global variable,
-+ * which is understood by main().
-+ */
-+static void
-+prop_vec_to_cfg(void)
-+{
-+ int i;
-+ scf_propvec_t *prop_vec_ptr = prop_vec;
-+ conv_in_f conv_func;
-+
-+ for (i = 0; i < SMF_CFG_PROP_COUNT; i++, prop_vec_ptr++) {
-+ if (SKIP_PROP(prop_vec_ptr)) {
-+ /*
-+ * We have `hidden` properties: action/value smf
-+ * authorization. Those two are not kept in
-+ * smf_ftp_cfg.
-+ *
-+ * So we must to skip to next property in vector
-+ * without letting for loop to advance its counter, so
-+ * we compensate here by doing `i--`.
-+ */
-+ i--;
-+ continue;
-+ };
-+ conv_func = smf_conv_in[i];
-+ conv_func(prop_vec_ptr->pv_ptr,
-+ ((char *)&smf_pflogd_cfg + smf_cfg_offsets[i]));
-+ }
-+}
-+
-+/*
-+ * smf_print_pflogcfg()
-+ * Function loads pflogdcfg from smf(5) repository and prints configuration to
-+ * standard output. We use `scf_simple_prop_get(3SCF)`.
-+ *
-+ * Returns 0 on success, -1 on error.
-+ */
-+int
-+smf_print_pflogcfg(const char *smf_instance)
-+{
-+ scf_simple_prop_t *prop;
-+ char *propval;
-+ int i;
-+ scf_propvec_t *prop_vec_ptr = prop_vec;
-+ int cfg_undefined = 0;
-+ char *fmri;
-+
-+ if (atexit_set == 0) {
-+ atexit(clear_prop_vec);
-+ bzero(&smf_pflogd_cfg, sizeof (smf_pflogd_cfg_t));
-+ atexit_set = 1;
-+ }
-+
-+ (void) asprintf(&fmri, "%s:%s", BASE_FMRI, smf_instance);
-+ if (fmri == NULL) {
-+ fprintf(stderr, "Out of memory.\n");
-+ return (-1);
-+ }
-+
-+ clear_prop_vec();
-+
-+ for (i = 0; i < SMF_CFG_PROP_COUNT; i++) {
-+ prop = scf_simple_prop_get(NULL, fmri, PFLOGD_PG,
-+ smf_propnames[i]);
-+ prop_vec_ptr->pv_prop = smf_propnames[i];
-+
-+ if (prop == NULL) {
-+ /*
-+ * Property not defined, so we create a kind of
-+ * 'placeholder' with empty value.
-+ *
-+ * calloc() works well for both astring and integer.
-+ */
-+ prop_vec_ptr->pv_type = smf_type[i];
-+ prop_vec_ptr->pv_ptr = calloc(1, sizeof (int64_t));
-+ cfg_undefined |= smf_mandatory[i];
-+ } else {
-+ prop_vec_ptr->pv_type = scf_simple_prop_type(prop);
-+ if (prop_vec_ptr->pv_type == -1) {
-+ free(fmri);
-+ fprintf(stderr,
-+ "Failed to get property type.\n");
-+ return (-1);
-+ }
-+ if (prop_vec_ptr->pv_type != smf_type[i]) {
-+ free(fmri);
-+ fprintf(stderr,
-+ "Property %s has unexpected type.\n",
-+ smf_propnames[i]);
-+ return (-1);
-+ }
-+
-+ if (smf_type[i] == SCF_TYPE_ASTRING) {
-+ char *propval;
-+ propval = scf_simple_prop_next_astring(prop);
-+ if (propval == NULL) {
-+ propval = "";
-+ }
-+ prop_vec_ptr->pv_ptr = strdup(propval);
-+
-+ if (propval[0] == 0) {
-+ cfg_undefined |= smf_mandatory[i];
-+ }
-+ } else {
-+ /* smf_type[i] == SCF_TYPE_INTEGER */
-+ int64_t *propval;
-+ int64_t propval_;
-+
-+ propval = scf_simple_prop_next_integer(prop);
-+ propval_ = (propval == NULL) ? (0) : (*propval);
-+
-+ prop_vec_ptr->pv_ptr = malloc(sizeof (int64_t));
-+ if (prop_vec_ptr->pv_ptr != NULL) {
-+ *((int64_t *)prop_vec_ptr->pv_ptr) =
-+ propval_;
-+ }
-+ if (propval_ == 0) {
-+ cfg_undefined |= smf_mandatory[i];
-+ }
-+ }
-+ scf_simple_prop_free(prop);
-+ }
-+ if (prop_vec_ptr->pv_ptr == NULL) {
-+ free(fmri);
-+ fprintf(stderr, "Out of memory.\n");
-+ return (-1);
-+ }
-+
-+ prop_vec_ptr++;
-+ }
-+
-+ printf("PF pflogd configuration:\n");
-+
-+ prop_vec_ptr = prop_vec;
-+ for (i = 0; i < SMF_CFG_PROP_COUNT; i++) {
-+ if (smf_type[i] == SCF_TYPE_ASTRING) {
-+ const char *val = (const char *)prop_vec_ptr->pv_ptr;
-+ printf("\t- %s:\n\t\t%s\n", prop_vec_ptr->pv_prop,
-+ ((val[0] == '\0') ? "?? undefined ??" : val));
-+ } else {
-+ /* smf_type[i] == SCF_TYPE_INTEGER */
-+ int64_t val = *((int64_t *)prop_vec_ptr->pv_ptr);
-+ if (val == 0) {
-+ printf("\t- %s:\n\t\t%s\n", prop_vec_ptr->pv_prop,
-+ "?? undefined ??");
-+ } else {
-+ printf("\t- %s:\n\t\t%d\n", prop_vec_ptr->pv_prop,
-+ (int)val);
-+ }
-+ }
-+ prop_vec_ptr++;
-+ }
-+ if (cfg_undefined) {
-+ printf("\n\nConfiguration for %s is incomplete."
-+ " Service will not run.\n\n", fmri);
-+ } else {
-+ prop_vec_to_cfg();
-+ printf(
-+ "\n\n%s service is being launched using cmd line below\n",
-+ fmri);
-+ printf("pflogd -d %d -i %s -s %d -f %s %s\n\n",
-+ (int)smf_pflogd_cfg.cfg_delay, smf_pflogd_cfg.cfg_interface,
-+ (int)smf_pflogd_cfg.cfg_snaplen, smf_pflogd_cfg.cfg_logfile,
-+ smf_pflogd_cfg.cfg_expression);
-+ }
-+
-+ free(fmri);
-+
-+ return (0);
-+}
-+
-+/*
-+ * smf_create_pflogd_instance()
-+ * Function creates a new instance in smf(5) repository.
-+ */
-+static int
-+smf_create_pflogd_instance(const char *smf_instance)
-+{
-+ scf_handle_t *h_scf = NULL;
-+ scf_scope_t *scp_scf = NULL;
-+ scf_service_t *svc_scf = NULL;
-+ scf_instance_t *sin_scf = NULL;
-+ int rv = -1;
-+
-+ h_scf = scf_handle_create(SCF_VERSION);
-+ if ((h_scf == NULL) || (scf_handle_bind(h_scf) == -1)) {
-+ (void) fprintf(stderr, "scf_handle_bind() failed - %s\n",
-+ scf_strerror(scf_error()));
-+ if (h_scf != NULL) {
-+ scf_handle_destroy(h_scf);
-+ }
-+ return (-1);
-+ }
-+
-+ if ((scp_scf = scf_scope_create(h_scf)) == NULL) {
-+ (void) fprintf(stderr, "could not create scope - %s\n",
-+ scf_strerror(scf_error()));
-+ goto unbind;
-+ }
-+
-+ if (scf_handle_get_local_scope(h_scf, scp_scf) != 0) {
-+ (void) fprintf(stderr, "could not get scope - %s\n",
-+ scf_strerror(scf_error()));
-+ goto scope_destroy;
-+ }
-+
-+ if ((svc_scf = scf_service_create(h_scf)) == NULL) {
-+ (void) fprintf(stderr, "could not create service - %s\n",
-+ scf_strerror(scf_error()));
-+ goto scope_destroy;
-+ }
-+
-+ if ((sin_scf = scf_instance_create(h_scf)) == NULL) {
-+ (void) fprintf(stderr, "could not get instance handle - %s\n",
-+ scf_strerror(scf_error()));
-+ goto service_destroy;
-+ }
-+
-+ if (scf_scope_get_service(scp_scf, STRIP_SVC(BASE_FMRI), svc_scf) !=
-+ SCF_SUCCESS) {
-+ (void) fprintf(stderr, "could not select service (%s)\n",
-+ scf_strerror(scf_error()));
-+ goto instance_destroy;
-+ }
-+
-+ if (scf_service_add_instance(svc_scf, smf_instance, sin_scf) != 0) {
-+ (void) fprintf(stderr, "could not add %s instance - %s\n",
-+ smf_instance, scf_strerror(scf_error()));
-+ goto instance_destroy;
-+ }
-+
-+ if (scf_instance_add_pg(sin_scf, "general", "framework", 0,
-+ NULL) != SCF_SUCCESS) {
-+ (void) fprintf(stderr,
-+ "could not create property group - %s\n",
-+ scf_strerror(scf_error()));
-+ goto instance_delete;
-+ }
-+
-+ if (scf_instance_add_pg(sin_scf, PFLOGD_PG, "application", 0,
-+ NULL) != SCF_SUCCESS) {
-+ (void) fprintf(stderr,
-+ "could not create property group - %s\n",
-+ scf_strerror(scf_error()));
-+ goto instance_delete;
-+ }
-+
-+ rv = 0;
-+ goto instance_destroy;
-+
-+instance_delete:
-+ if (scf_instance_delete(sin_scf) != 0) {
-+ fprintf(stderr, "Can't delete the newly created instance:");
-+ fprintf(stderr, "\t%s\n", scf_strerror(scf_error()));
-+ }
-+instance_destroy:
-+ scf_instance_destroy(sin_scf);
-+service_destroy:
-+ scf_service_destroy(svc_scf);
-+scope_destroy:
-+ scf_scope_destroy(scp_scf);
-+unbind:
-+ scf_handle_unbind(h_scf);
-+ scf_handle_destroy(h_scf);
-+
-+ return (rv);
-+}
-+
-+/*
-+ * smf_write_pflogcfg()
-+ * Function writes pflogd configuration to smf(5) repository.
-+ */
-+int
-+smf_write_pflogcfg(const char *smf_instance, int create)
-+{
-+ int i;
-+ scf_propvec_t
-+ *bad_prop_vec = NULL;
-+ char *fmri;
-+
-+ if (atexit_set == 0) {
-+ atexit(clear_prop_vec);
-+ bzero(prop_vec, sizeof (prop_vec));
-+ atexit_set = 1;
-+ }
-+
-+ if (create && (complete_pflogdcfg(smf_instance) != 0)) {
-+ fprintf(stderr, "Out of memory.\n");
-+ return (-1);
-+ }
-+
-+ if (cfg_to_prop_vec() != 0) {
-+ fprintf(stderr, "Out of memory.\n");
-+ return (-1);
-+ }
-+
-+ (void) asprintf(&fmri, "%s:%s", BASE_FMRI, smf_instance);
-+ if (fmri == NULL) {
-+ fprintf(stderr, "Out of memory.\n");
-+ return (-1);
-+ }
-+
-+ if (create) {
-+ if (smf_create_pflogd_instance(smf_instance) != 0) {
-+ free(fmri);
-+ return (-1);
-+ }
-+ }
-+
-+ if (create && (scf_write_propvec(fmri, "general", gen_prop_vec,
-+ &bad_prop_vec) != SCF_SUCCESS)) {
-+ fprintf(stderr, "Can't update %s configuration:", fmri);
-+ fprintf(stderr, "\t%s\n", scf_strerror(scf_error()));
-+ if (bad_prop_vec != NULL) {
-+ fprintf(stderr, "Could not set %s\n",
-+ bad_prop_vec->pv_prop);
-+ }
-+ free(fmri);
-+ exit(1);
-+ }
-+
-+ bad_prop_vec = NULL;
-+ if (scf_write_propvec(fmri, PFLOGD_PG, prop_vec, &bad_prop_vec)
-+ != SCF_SUCCESS) {
-+ fprintf(stderr, "Can't update %s configuration:", fmri);
-+ fprintf(stderr, "\t%s\n", scf_strerror(scf_error()));
-+ if (bad_prop_vec != NULL) {
-+ fprintf(stderr, "Could not set %s\n",
-+ bad_prop_vec->pv_prop);
-+ }
-+ free(fmri);
-+ exit(1);
-+ }
-+
-+ free(fmri);
-+ return (0);
-+}
-+
-+/*
-+ * complete_pflogdcfg()
-+ * Function sets default values to properties, which are unset/undefined when
-+ * new smf(5) instance is being created.
-+ *
-+ * Returns 0 on success, -1 on out of memory error.
-+ */
-+static int
-+complete_pflogdcfg(const char *smf_instance)
-+{
-+ int i;
-+ int f = 1;
-+
-+ for (i = 0; i < SMF_CFG_PROP_COUNT; i++) {
-+ if ((smf_pflogd_cfg.cfg_set & f) == 0) {
-+ switch (i) {
-+ case SMF_LOGFILE:
-+ (void) asprintf(&smf_pflogd_cfg.cfg_logfile,
-+ "%s/%s", PFLOGD_LOG_DIR, smf_instance);
-+ if (smf_pflogd_cfg.cfg_logfile == NULL) {
-+ return (-1);
-+ }
-+ smf_pflogd_cfg.cfg_set |= SMF_CFG_LOGFILE_SET;
-+ break;
-+ case SMF_INTERFACE:
-+ smf_pflogd_cfg.cfg_interface = strdup(smf_instance);
-+ if (smf_pflogd_cfg.cfg_interface == NULL) {
-+ return (-1);
-+ }
-+ smf_pflogd_cfg.cfg_set |= SMF_CFG_INTERFACE_SET;
-+ break;
-+ case SMF_SNAPLEN:
-+ smf_pflogd_cfg.cfg_snaplen = DEF_SNAPLEN;
-+ smf_pflogd_cfg.cfg_set |= SMF_CFG_SNAPLEN_SET;
-+ break;
-+ case SMF_DELAY:
-+ smf_pflogd_cfg.cfg_delay = FLUSH_DELAY;
-+ smf_pflogd_cfg.cfg_set |= SMF_CFG_DELAY_SET;
-+ break;
-+ case SMF_EXPRESSION:
-+ smf_pflogd_cfg.cfg_expression = strdup("");
-+ smf_pflogd_cfg.cfg_set |= SMF_CFG_EXPRESSION_SET;
-+ break;
-+ default: ;
-+ }
-+ }
-+ f = f << 1;
-+ }
-+
-+ return (0);
-+}
-diff -Naur pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/smf-config.h pflogd-OPENBSD_5_5-OPENBSD_5_5/smf-config.h
---- pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/smf-config.h 1969-12-31 16:00:00.000000000 -0800
-+++ pflogd-OPENBSD_5_5-OPENBSD_5_5/smf-config.h 2016-02-17 01:17:14.520118386 -0800
-@@ -0,0 +1,53 @@
-+/*
-+ * CDDL HEADER START
-+ *
-+ * The contents of this file are subject to the terms of the
-+ * Common Development and Distribution License (the "License").
-+ * You may not use this file except in compliance with the License.
-+ *
-+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-+ * or http://www.opensolaris.org/os/licensing.
-+ * See the License for the specific language governing permissions
-+ * and limitations under the License.
-+ *
-+ * When distributing Covered Code, include this CDDL HEADER in each
-+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-+ * If applicable, add the following below this CDDL HEADER, with the
-+ * fields enclosed by brackets "[]" replaced with your own identifying
-+ * information: Portions Copyright [yyyy] [name of copyright owner]
-+ *
-+ * CDDL HEADER END
-+ *
-+ */
-+
-+/*
-+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
-+ */
-+
-+#ifndef _SMF_CONFIG_H_
-+#define _SMF_CONFIG_H_
-+
-+#define BASE_FMRI "svc:/network/firewall/pflog"
-+#define DEFAULT_INSTANCE "pflog0"
-+
-+#define SMF_CFG_LOGFILE_SET 0x00000001
-+#define SMF_CFG_SNAPLEN_SET 0x00000002
-+#define SMF_CFG_INTERFACE_SET 0x00000004
-+#define SMF_CFG_DELAY_SET 0x00000008
-+#define SMF_CFG_EXPRESSION_SET 0x00000010
-+
-+typedef struct smf_pflogd_cfg {
-+ unsigned int cfg_set; /* SMF_CFG_*_SET bit field */
-+ char *cfg_logfile;
-+ int64_t cfg_snaplen;
-+ char *cfg_interface;
-+ int64_t cfg_delay;
-+ char *cfg_expression;
-+} smf_pflogd_cfg_t;
-+
-+extern smf_pflogd_cfg_t smf_pflogd_cfg;
-+
-+extern int smf_print_pflogcfg(const char *);
-+extern int smf_write_pflogcfg(const char *, int);
-+
-+#endif /* !_SMF_CONFIG_H_ */