components/pflogd/patches/001-solaris.patch
changeset 5565 f678cc44b3d0
child 5826 9c90e4a8156c
equal deleted inserted replaced
5564:e533d5840fdd 5565:f678cc44b3d0
       
     1 # This patch comes from Oracle. It fixes issues preventing pflogd
       
     2 # from building and running on Solaris. Especially, we:
       
     3 # - make it read packets from Solaris-specific capture links instead
       
     4 #   of OpenBSD's pflog interfaces
       
     5 # - introduce our own pcap_pkthdr structure as the one used by
       
     6 #   upstream would result in corrupted packet dump files on Solaris
       
     7 # - use Solaris-specific random number generator
       
     8 #
       
     9 # This patch is not going to upstream, the changes are Solaris-specific.
       
    10 
       
    11 diff -Naur ORIGINAL/Makefile pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/Makefile
       
    12 --- ORIGINAL/Makefile	2013-06-18 20:51:30.000000000 -0700
       
    13 +++ pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/Makefile	2016-02-17 02:08:53.410106245 -0800
       
    14 @@ -1,15 +1,28 @@
       
    15  #	$OpenBSD: Makefile,v 1.9 2013/06/19 03:51:30 lteo Exp $
       
    16  
       
    17 -CFLAGS+=-Wall -Wmissing-prototypes -Wshadow
       
    18 +CFLAGS+= -m64 -errwarn
       
    19  
       
    20 -# for pcap-int.h
       
    21 -CFLAGS+=-I${.CURDIR}/../../lib/libpcap
       
    22 +PROG=pflogd
       
    23 +SRCS=pflogd.c privsep.c privsep_fdpass.c
       
    24 +OBJS=$(SRCS:.c=.o)
       
    25 +MAN=pflogd.8
       
    26  
       
    27 -LDADD+= -lpcap
       
    28 -DPADD+=	${LIBPCAP}
       
    29 +LDADD+=-lpcap -ldladm -luutil
       
    30  
       
    31 -PROG=	pflogd
       
    32 -SRCS=	pflogd.c privsep.c privsep_fdpass.c
       
    33 -MAN=	pflogd.8
       
    34 +all:	$(SRCS) $(PROG)
       
    35  
       
    36 -.include <bsd.prog.mk>
       
    37 +install: $(PROG)
       
    38 +	$(INSTALL) -d $(PREFIX)/sbin
       
    39 +	$(INSTALL) -m 755 $(PROG) $(PREFIX)/sbin
       
    40 +	$(INSTALL) -d $(MANDIR)/man8
       
    41 +	$(INSTALL) -m 644 $(MAN) $(MANDIR)/man8
       
    42 +
       
    43 +$(PROG):	$(OBJS)
       
    44 +	$(CC) $(CFLAGS) $(OBJS) -o $@ $(LDADD)
       
    45 +
       
    46 +.c.o:
       
    47 +	$(CC) $(CFLAGS) -c -o $@ $<
       
    48 +
       
    49 +clean:
       
    50 +	rm -rf *.o
       
    51 +	rm -rf $(PROG)
       
    52 diff -Naur ORIGINAL/pflogd.8 pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/pflogd.8
       
    53 --- ORIGINAL/pflogd.8	2014-01-20 19:15:45.000000000 -0800
       
    54 +++ pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/pflogd.8	2016-02-17 02:32:29.857912548 -0800
       
    55 @@ -44,15 +44,15 @@
       
    56  .Nm
       
    57  is a background daemon which reads packets logged by
       
    58  .Xr pf 4
       
    59 -to a
       
    60 -.Xr pflog 4
       
    61 -interface, normally
       
    62 +to a dedicated capture link interface (see
       
    63 +.Xr dladm 1M
       
    64 +for details), normally
       
    65  .Pa pflog0 ,
       
    66  and writes the packets to a logfile (normally
       
    67 -.Pa /var/log/pflog )
       
    68 -in
       
    69 -.Xr tcpdump 8
       
    70 -binary format.
       
    71 +.Pa /var/log/firewall/pflog/pflog0.pkt )
       
    72 +in libpcap format (see
       
    73 +.Xr PCAP 3pcap
       
    74 +for details).
       
    75  These logs can be reviewed later using the
       
    76  .Fl r
       
    77  option of
       
    78 @@ -63,9 +63,7 @@
       
    79  .Nm
       
    80  closes and then re-opens the log file when it receives
       
    81  .Dv SIGHUP ,
       
    82 -permitting
       
    83 -.Xr newsyslog 8
       
    84 -to rotate logfiles automatically.
       
    85 +permitting convenient log rotation.
       
    86  .Dv SIGALRM
       
    87  causes
       
    88  .Nm
       
    89 @@ -96,7 +94,7 @@
       
    90  .Pp
       
    91  .Nm
       
    92  will also log the pcap statistics for the
       
    93 -.Xr pflog 4
       
    94 +capture link
       
    95  interface to syslog when a
       
    96  .Dv SIGUSR1
       
    97  is received.
       
    98 @@ -113,12 +111,8 @@
       
    99  If not specified, the default is 60 seconds.
       
   100  .It Fl f Ar filename
       
   101  Log output filename.
       
   102 -Default is
       
   103 -.Pa /var/log/pflog .
       
   104  .It Fl i Ar interface
       
   105 -Specifies the
       
   106 -.Xr pflog 4
       
   107 -interface to use.
       
   108 +Specifies the capture link interface to use.
       
   109  By default,
       
   110  .Nm
       
   111  will use
       
   112 @@ -172,7 +166,7 @@
       
   113  .El
       
   114  .Sh FILES
       
   115  .Bl -tag -width /var/run/pflogd.pid -compact
       
   116 -.It Pa /var/log/pflog
       
   117 +.It Pa /var/log/firewall/pflog/pflog0.pkt
       
   118  Default log file.
       
   119  .El
       
   120  .Sh EXAMPLES
       
   121 @@ -185,7 +179,7 @@
       
   122  .Ed
       
   123  .Pp
       
   124  Log from another
       
   125 -.Xr pflog 4
       
   126 +capture link
       
   127  interface, excluding specific packets:
       
   128  .Bd -literal -offset indent
       
   129  # pflogd -i pflog3 -f network3.log "not (tcp and port 23)"
       
   130 @@ -193,7 +187,7 @@
       
   131  .Pp
       
   132  Display binary logs:
       
   133  .Bd -literal -offset indent
       
   134 -# tcpdump -n -e -ttt -r /var/log/pflog
       
   135 +# tcpdump -n -e -ttt -r /var/log/firewall/pflog/pflog3.pkt
       
   136  .Ed
       
   137  .Pp
       
   138  Display the logs in real time (this does not interfere with the
       
   139 @@ -210,16 +204,18 @@
       
   140  .Ed
       
   141  .Sh SEE ALSO
       
   142  .Xr pcap 3 ,
       
   143 -.Xr pf 4 ,
       
   144 -.Xr pflog 4 ,
       
   145  .Xr pf.conf 5 ,
       
   146 -.Xr newsyslog 8 ,
       
   147 +.Xr privileges 5 ,
       
   148 +.Xr smf 5 ,
       
   149  .Xr tcpdump 8
       
   150  .Sh HISTORY
       
   151  The
       
   152  .Nm
       
   153  command appeared in
       
   154  .Ox 3.0 .
       
   155 +The Solaris version is based on
       
   156 +.Nm
       
   157 +found in OpenBSD 5.5.
       
   158  .Sh AUTHORS
       
   159  .Nm
       
   160  was written by
       
   161 diff -Naur ORIGINAL/pflogd.c pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/pflogd.c
       
   162 --- ORIGINAL/pflogd.c	2012-11-05 18:50:47.000000000 -0800
       
   163 +++ pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/pflogd.c	2016-02-18 12:05:03.256562087 -0800
       
   164 @@ -48,7 +48,15 @@
       
   165  #include <errno.h>
       
   166  #include <stdarg.h>
       
   167  #include <fcntl.h>
       
   168 +#ifdef	_SOLARIS_
       
   169 +#include <libdladm.h>
       
   170 +#include <libnetcfg.h>
       
   171 +#include <strings.h>
       
   172 +#include <zone.h>
       
   173 +#include <libuutil.h>
       
   174 +#else /* !_SOLARIS_ */
       
   175  #include <util.h>
       
   176 +#endif	/* _SOLARIS_ */
       
   177  #include "pflogd.h"
       
   178  
       
   179  pcap_t *hpcap;
       
   180 @@ -88,6 +96,34 @@
       
   181  void  sig_hup(int);
       
   182  void  usage(void);
       
   183  
       
   184 +#ifdef	_SOLARIS_
       
   185 +/*
       
   186 + * setproctitle() is found in libc on OpenBSD. It allows program to update its
       
   187 + * process name. It will be an empty macro on Solaris.
       
   188 + */
       
   189 +#define	setproctitle(...)
       
   190 +
       
   191 +/*
       
   192 + * __dead attribute will be an empty macro on Solaris.
       
   193 + */
       
   194 +#define	__dead
       
   195 +
       
   196 +/*
       
   197 + * We must define our own pcap_pkthdr to ensure timeval structure will be
       
   198 + * defined in 32-bit version. Not doing so will result in corrupted packet dump
       
   199 + * file produced by pflogd on Solaris.
       
   200 + */
       
   201 +typedef struct pcap_pkthdr_file {
       
   202 +	struct {
       
   203 +		uint32_t	tv_sec;
       
   204 +		uint32_t	tv_usec;
       
   205 +	} ts;
       
   206 +	uint32_t	caplen;
       
   207 +	uint32_t	len;
       
   208 +} pcap_pkthdr_file_t;
       
   209 +
       
   210 +#endif	/* _SOLARIS_ */
       
   211 +
       
   212  static int try_reset_dump(int);
       
   213  
       
   214  /* buffer must always be greater than snaplen */
       
   215 @@ -191,11 +227,13 @@
       
   216  {
       
   217  	struct bpf_program bprog;
       
   218  
       
   219 -	if (pcap_compile(hpcap, &bprog, filter, PCAP_OPT_FIL, 0) < 0)
       
   220 +	if (pcap_compile(hpcap, &bprog, filter, PCAP_OPT_FIL, 0) < 0) {
       
   221  		logmsg(LOG_WARNING, "%s", pcap_geterr(hpcap));
       
   222 -	else {
       
   223 +		logmsg(LOG_WARNING, "for filter:\n\t%s\nNo filter set.\n", filter);
       
   224 +	} else {
       
   225  		if (pcap_setfilter(hpcap, &bprog) < 0)
       
   226 -			logmsg(LOG_WARNING, "%s", pcap_geterr(hpcap));
       
   227 +			logmsg(LOG_WARNING, "%s\nNo filter set.\n",
       
   228 +			    pcap_geterr(hpcap));
       
   229  		pcap_freecode(&bprog);
       
   230  	}
       
   231  }
       
   232 @@ -203,6 +241,31 @@
       
   233  int
       
   234  if_exists(char *ifname)
       
   235  {
       
   236 +#ifdef	_SOLARIS_
       
   237 +	dladm_handle_t	dlh;
       
   238 +	datalink_id_t	linkid;
       
   239 +	zoneid_t	zid = getzoneid();
       
   240 +	dladm_status_t	dls;
       
   241 +	int		rv = 0;
       
   242 +
       
   243 +	if (!dladm_valid_linkname(ifname) ||
       
   244 +	    (dladm_open(&dlh) != DLADM_STATUS_OK)) {
       
   245 +		errno = ENXIO;
       
   246 +		return (rv);
       
   247 +	}
       
   248 +
       
   249 +	dls = dladm_apply_linknamefilters(dlh, ifname, &linkid, 1, &zid,
       
   250 +	    DLADM_OPT_ACTIVE, zid, NULL);
       
   251 +	if ((dls == DLADM_STATUS_OK) && (linkid != DATALINK_INVALID_LINKID)) {
       
   252 +		rv = 1;
       
   253 +	}
       
   254 +
       
   255 +	dladm_close(dlh);
       
   256 +
       
   257 +	errno = (rv == 1) ? 0 : ENXIO;
       
   258 +
       
   259 +	return (rv);
       
   260 +#else /* !_SOLARIS_ */
       
   261  	int s, ret = 1;
       
   262  	struct ifreq ifr;
       
   263  	struct if_data ifrdat;
       
   264 @@ -220,6 +283,7 @@
       
   265  		err(1, "close");
       
   266  
       
   267  	return (ret);
       
   268 +#endif	/* _SOLARIS_ */
       
   269  }
       
   270  
       
   271  int
       
   272 @@ -243,10 +307,15 @@
       
   273  	cur_snaplen = snaplen = pcap_snapshot(hpcap);
       
   274  
       
   275  	/* lock */
       
   276 +/*
       
   277 + * BIOCLOCK operation is not implmented on Solaris. 
       
   278 + */
       
   279 +#ifndef	_SOLARIS_
       
   280  	if (ioctl(pcap_fileno(hpcap), BIOCLOCK) < 0) {
       
   281  		logmsg(LOG_ERR, "BIOCLOCK: %s", strerror(errno));
       
   282  		return (-1);
       
   283  	}
       
   284 +#endif	/* !_SOLARIS_ */
       
   285  
       
   286  	return (0);
       
   287  }
       
   288 @@ -371,7 +440,11 @@
       
   289  scan_dump(FILE *fp, off_t size)
       
   290  {
       
   291  	struct pcap_file_header hdr;
       
   292 +#ifdef	_SOLARIS_
       
   293 +	struct pcap_pkthdr_file	ph;
       
   294 +#else /* !_SOLARIS_ */
       
   295  	struct pcap_pkthdr ph;
       
   296 +#endif	/* _SOLARIS_ */
       
   297  	off_t pos;
       
   298  
       
   299  	/*
       
   300 @@ -440,13 +513,26 @@
       
   301  dump_packet_nobuf(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
       
   302  {
       
   303  	FILE *f = (FILE *)user;
       
   304 +#ifdef	_SOLARIS_
       
   305 +	struct pcap_pkthdr_file	h_file;
       
   306 +#endif	/* _SOLARIS_ */
       
   307  
       
   308  	if (suspended) {
       
   309  		packets_dropped++;
       
   310  		return;
       
   311  	}
       
   312  
       
   313 -	if (fwrite((char *)h, sizeof(*h), 1, f) != 1) {
       
   314 +#ifdef	_SOLARIS_
       
   315 +	h_file.ts.tv_sec = (uint32_t)h->ts.tv_sec;
       
   316 +	h_file.ts.tv_usec = (uint32_t)h->ts.tv_usec;
       
   317 +	h_file.caplen = h->caplen;
       
   318 +	h_file.len = h->len;
       
   319 +	if (fwrite((char *)&h_file, sizeof (h_file), 1, f) != 1)
       
   320 +#else	/* !_SOLARIS_ */
       
   321 +	if (fwrite((char *)h, sizeof(*h), 1, f) != 1)
       
   322 +#endif	/* _SOLARIS_ */
       
   323 +
       
   324 +	{
       
   325  		off_t pos = ftello(f);
       
   326  
       
   327  		/* try to undo header to prevent corruption */
       
   328 @@ -520,9 +606,32 @@
       
   329  dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
       
   330  {
       
   331  	FILE *f = (FILE *)user;
       
   332 +#ifdef	_SOLARIS_
       
   333 +	struct pcap_pkthdr_file	h_file;
       
   334 +	size_t len = sizeof (h_file) + h->caplen;
       
   335 +#else	/* !_SOLARIS_ */
       
   336  	size_t len = sizeof(*h) + h->caplen;
       
   337 +#endif	/* _SOLARIS_ */
       
   338  
       
   339 -	if (len < sizeof(*h) || h->caplen > (size_t)cur_snaplen) {
       
   340 +#ifdef	_SOLARIS_
       
   341 +	/*
       
   342 +	 * Member ts is struct timeval defined in sys/time.h. Solaris uses
       
   343 +	 * 64-bit version for tv_sec, tv_usec. 64-bit members are not
       
   344 +	 * compatible with pcap file format, hence we must convert them to
       
   345 +	 * 32-bits.
       
   346 +	 */
       
   347 +	h_file.ts.tv_sec = (uint32_t)h->ts.tv_sec;
       
   348 +	h_file.ts.tv_usec = (uint32_t)h->ts.tv_usec;
       
   349 +	h_file.caplen = h->caplen;
       
   350 +	h_file.len = h->len;
       
   351 +#endif	/* _SOLARIS_ */
       
   352 +
       
   353 +#ifdef	_SOLARIS_
       
   354 +	if (len < sizeof(h_file) || h_file.caplen > (size_t)cur_snaplen)
       
   355 +#else	/* !_SOLARIS_ */
       
   356 +	if (len < sizeof(*h) || h->caplen > (size_t)cur_snaplen)
       
   357 +#endif	/* _SOLARIS_ */
       
   358 +	{
       
   359  		logmsg(LOG_NOTICE, "invalid size %zu (%d/%d), packet dropped",
       
   360  		       len, cur_snaplen, snaplen);
       
   361  		packets_dropped++;
       
   362 @@ -548,8 +657,13 @@
       
   363  	}
       
   364  
       
   365   append:
       
   366 +#ifdef	_SOLARIS_
       
   367 +	(void) memcpy(bufpos, &h_file, sizeof (h_file));
       
   368 +	(void) memcpy(bufpos + sizeof (h_file), sp, h->caplen);
       
   369 +#else	/* !_SOLARIS_ */
       
   370  	memcpy(bufpos, h, sizeof(*h));
       
   371  	memcpy(bufpos + sizeof(*h), sp, h->caplen);
       
   372 +#endif	/* _SOLARIS_ */
       
   373  
       
   374  	bufpos += len;
       
   375  	bufleft -= len;
       
   376 @@ -611,7 +725,6 @@
       
   377  		default:
       
   378  			usage();
       
   379  		}
       
   380 -
       
   381  	}
       
   382  
       
   383  	log_debug = Debug;
       
   384 @@ -658,12 +771,25 @@
       
   385  
       
   386  	setproctitle("[initializing]");
       
   387  	/* Process is now unprivileged and inside a chroot */
       
   388 +#ifdef	_SOLARIS_
       
   389 +	/*
       
   390 +	 * We have to use sigset() on Solaris, since signal() resets sig.
       
   391 +	 * handler to default as soon as particular signal is delivered.
       
   392 +	 */
       
   393 +	sigset(SIGTERM, sig_close);
       
   394 +	sigset(SIGINT, sig_close);
       
   395 +	sigset(SIGQUIT, sig_close);
       
   396 +	sigset(SIGALRM, sig_alrm);
       
   397 +	sigset(SIGUSR1, sig_usr1);
       
   398 +	sigset(SIGHUP, sig_hup);
       
   399 +#else /* !_SOLARIS_ */
       
   400  	signal(SIGTERM, sig_close);
       
   401  	signal(SIGINT, sig_close);
       
   402  	signal(SIGQUIT, sig_close);
       
   403  	signal(SIGALRM, sig_alrm);
       
   404  	signal(SIGUSR1, sig_usr1);
       
   405  	signal(SIGHUP, sig_hup);
       
   406 +#endif	/* _SOLARIS_ */
       
   407  	alarm(delay);
       
   408  
       
   409  	buffer = malloc(PFLOGD_BUFSIZE);
       
   410 @@ -696,7 +822,7 @@
       
   411  				ret = -1;
       
   412  				break;
       
   413  			}
       
   414 -			logmsg(LOG_NOTICE, "%s", pcap_geterr(hpcap));
       
   415 +			logmsg(LOG_NOTICE, "pcap says: %s", pcap_geterr(hpcap));
       
   416  		}
       
   417  
       
   418  		if (gotsig_close)
       
   419 diff -Naur ORIGINAL/pflogd.h pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/pflogd.h
       
   420 --- ORIGINAL/pflogd.h	2010-09-20 22:56:58.000000000 -0700
       
   421 +++ pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/pflogd.h	2016-02-18 12:08:42.414919276 -0800
       
   422 @@ -16,7 +16,11 @@
       
   423   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
       
   424   */
       
   425  
       
   426 +#ifdef	_SOLARIS_
       
   427 +#include <limits.h>
       
   428 +#else /* !_SOLARIS_ */
       
   429  #include <sys/limits.h>
       
   430 +#endif	/* _SOLARIS_ */
       
   431  #include <pcap.h>
       
   432  
       
   433  #define DEF_SNAPLEN 160		/* pfloghdr + ip hdr + proto hdr fit usually */
       
   434 @@ -25,7 +29,12 @@
       
   435  #define PCAP_OPT_FIL 1		/* filter optimization */
       
   436  #define FLUSH_DELAY 60		/* flush delay */
       
   437  
       
   438 +#ifdef	_SOLARIS_
       
   439 +#define	PFLOGD_LOG_DIR		"/var/log/firewall/pflog"
       
   440 +#define PFLOGD_LOG_FILE		"pflog.pkt"
       
   441 +#else /* !_SOLARIS_ */
       
   442  #define PFLOGD_LOG_FILE		"/var/log/pflog"
       
   443 +#endif	/* _SOLARIS_ */
       
   444  #define PFLOGD_DEFAULT_IF	"pflog0"
       
   445  
       
   446  #define PFLOGD_MAXSNAPLEN	INT_MAX
       
   447 diff -Naur ORIGINAL/privsep.c pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/privsep.c
       
   448 --- ORIGINAL/privsep.c	2013-09-13 01:49:17.000000000 -0700
       
   449 +++ pflogd-OPENBSD_5_5-OPENBSD_5_5.pre-smf/privsep.c	2016-02-18 12:07:34.219667793 -0800
       
   450 @@ -28,8 +28,6 @@
       
   451  #include <errno.h>
       
   452  #include <fcntl.h>
       
   453  #include <limits.h>
       
   454 -#include <pcap.h>
       
   455 -#include <pcap-int.h>
       
   456  #include <pwd.h>
       
   457  #include <signal.h>
       
   458  #include <stdio.h>
       
   459 @@ -38,6 +36,34 @@
       
   460  #include <syslog.h>
       
   461  #include <unistd.h>
       
   462  #include "pflogd.h"
       
   463 +#ifdef	_SOLARIS_
       
   464 +#include <priv.h>
       
   465 +#include <stdlib.h>
       
   466 +#include <sys/types.h>
       
   467 +#include <time.h>
       
   468 +#include <sys/random.h>
       
   469 +#endif	/* _SOLARIS_ */
       
   470 +/*
       
   471 + * It's better to include these after other header files.
       
   472 + * pcap-int.h defines strlcpy() as macro if it is undefined.
       
   473 + * In our case strlcpy() comes from string.h.
       
   474 + */
       
   475 +#define	HAVE_SNPRINTF	1
       
   476 +#include <pcap.h>
       
   477 +#include <pcap-int.h>
       
   478 +
       
   479 +#ifdef	_SOLARIS_
       
   480 +#define	_NSIG	27
       
   481 +
       
   482 +/*
       
   483 + * setproctitle() is found in libc on OpenBSD. It allows program to update its
       
   484 + * process name. It will empty macro on Solaris.
       
   485 + */
       
   486 +#define	setproctitle(...)
       
   487 +
       
   488 +#else /* !_SOLARIS_ */
       
   489 +#define	PFLOGD_USER	"_pflogd"
       
   490 +#endif	/* _SOLARIS_ */
       
   491  
       
   492  enum cmd_types {
       
   493  	PRIV_SET_SNAPLEN,	/* set the snaplength */
       
   494 @@ -67,7 +93,9 @@
       
   495  {
       
   496  	int i, fd, socks[2], cmd;
       
   497  	int snaplen, ret, olderrno;
       
   498 +#ifndef	_SOLARIS_
       
   499  	struct passwd *pw;
       
   500 +#endif	/* !_SOLARIS_ */
       
   501  
       
   502  	for (i = 1; i < _NSIG; i++)
       
   503  		signal(i, SIG_DFL);
       
   504 @@ -76,16 +104,19 @@
       
   505  	if (socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, socks) == -1)
       
   506  		err(1, "socketpair() failed");
       
   507  
       
   508 +#ifndef	_SOLARIS_
       
   509  	pw = getpwnam("_pflogd");
       
   510  	if (pw == NULL)
       
   511  		errx(1, "unknown user _pflogd");
       
   512  	endpwent();
       
   513 +#endif	/* !_SOLARIS_ */
       
   514  
       
   515  	child_pid = fork();
       
   516  	if (child_pid < 0)
       
   517  		err(1, "fork() failed");
       
   518  
       
   519  	if (!child_pid) {
       
   520 +#ifndef	_SOLARIS_
       
   521  		gid_t gidset[1];
       
   522  
       
   523  		/* Child - drop privileges and return */
       
   524 @@ -101,6 +132,8 @@
       
   525  			err(1, "setgroups() failed");
       
   526  		if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
       
   527  			err(1, "setresuid() failed");
       
   528 +#endif	/* !_SOLARIS_ */
       
   529 +
       
   530  		close(socks[0]);
       
   531  		priv_fd = socks[1];
       
   532  		return 0;
       
   533 @@ -108,19 +141,34 @@
       
   534  
       
   535  	/* Father */
       
   536  	/* Pass ALRM/TERM/HUP/INT/QUIT through to child, and accept CHLD */
       
   537 +#ifdef	_SOLARIS_
       
   538 +	/*
       
   539 +	 * We have to use sigset() on Solaris, since signal() resets sig.
       
   540 +	 * handler to default as soon as particular signal is delivered.
       
   541 +	 */
       
   542 +	sigset(SIGALRM, sig_pass_to_chld);
       
   543 +	sigset(SIGTERM, sig_pass_to_chld);
       
   544 +	sigset(SIGHUP,  sig_pass_to_chld);
       
   545 +	sigset(SIGINT,  sig_pass_to_chld);
       
   546 +	sigset(SIGQUIT,  sig_pass_to_chld);
       
   547 +	sigset(SIGCHLD, sig_chld);
       
   548 +#else /* !_SOLARIS_ */
       
   549  	signal(SIGALRM, sig_pass_to_chld);
       
   550  	signal(SIGTERM, sig_pass_to_chld);
       
   551  	signal(SIGHUP,  sig_pass_to_chld);
       
   552  	signal(SIGINT,  sig_pass_to_chld);
       
   553  	signal(SIGQUIT,  sig_pass_to_chld);
       
   554  	signal(SIGCHLD, sig_chld);
       
   555 +#endif	/* _SOLARIS_ */
       
   556  
       
   557  	setproctitle("[priv]");
       
   558  	close(socks[1]);
       
   559  
       
   560  	while (!gotsig_chld) {
       
   561 -		if (may_read(socks[0], &cmd, sizeof(int)))
       
   562 +		if (may_read(socks[0], &cmd, sizeof(int))) {
       
   563 +			logmsg(LOG_ERR, "may_read: fails\n");
       
   564  			break;
       
   565 +		}
       
   566  		switch (cmd) {
       
   567  		case PRIV_SET_SNAPLEN:
       
   568  			logmsg(LOG_DEBUG,
       
   569 @@ -192,9 +240,20 @@
       
   570  
       
   571  	for (;;) {
       
   572  		int fd;
       
   573 +#ifdef _SOLARIS_
       
   574 +		uint32_t rand;
       
   575  
       
   576 +		if (getrandom(&rand, sizeof (rand), GRND_NONBLOCK) !=
       
   577 +		    sizeof (rand)) {
       
   578 +			logmsg(LOG_ERR, "getrandom() failed");
       
   579 +			return 1;
       
   580 +		}
       
   581 +		len = snprintf(ren, sizeof(ren), "%s.bad.%08x",
       
   582 +		    name, rand);
       
   583 +#else /* !_SOLARIS_ */
       
   584  		len = snprintf(ren, sizeof(ren), "%s.bad.%08x",
       
   585  		    name, arc4random());
       
   586 +#endif /* _SOLARIS_ */
       
   587  		if (len >= sizeof(ren)) {
       
   588  			logmsg(LOG_ERR, "[priv] new name too long");
       
   589  			return (1);