1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1983, 1988, 1993, 1994 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #ifndef lint 33 static const char copyright[] = 34 "@(#) Copyright (c) 1983, 1988, 1993, 1994\n\ 35 The Regents of the University of California. All rights reserved.\n"; 36 #endif /* not lint */ 37 38 #ifndef lint 39 #if 0 40 static char sccsid[] = "@(#)syslogd.c 8.3 (Berkeley) 4/4/94"; 41 #endif 42 #endif /* not lint */ 43 44 #include <sys/cdefs.h> 45 __FBSDID("$FreeBSD$"); 46 47 /* 48 * syslogd -- log system messages 49 * 50 * This program implements a system log. It takes a series of lines. 51 * Each line may have a priority, signified as "<n>" as 52 * the first characters of the line. If this is 53 * not present, a default priority is used. 54 * 55 * To kill syslogd, send a signal 15 (terminate). A signal 1 (hup) will 56 * cause it to reread its configuration file. 57 * 58 * Defined Constants: 59 * 60 * MAXLINE -- the maximum line length that can be handled. 61 * DEFUPRI -- the default priority for user messages 62 * DEFSPRI -- the default priority for kernel messages 63 * 64 * Author: Eric Allman 65 * extensive changes by Ralph Campbell 66 * more extensive changes by Eric Allman (again) 67 * Extension to log by program name as well as facility and priority 68 * by Peter da Silva. 69 * -u and -v by Harlan Stenn. 70 * Priority comparison code by Harlan Stenn. 71 */ 72 73 /* Maximum number of characters in time of last occurrence */ 74 #define MAXDATELEN 16 75 #define MAXLINE 1024 /* maximum line length */ 76 #define MAXSVLINE MAXLINE /* maximum saved line length */ 77 #define DEFUPRI (LOG_USER|LOG_NOTICE) 78 #define DEFSPRI (LOG_KERN|LOG_CRIT) 79 #define TIMERINTVL 30 /* interval for checking flush, mark */ 80 #define TTYMSGTIME 1 /* timeout passed to ttymsg */ 81 #define RCVBUF_MINSIZE (80 * 1024) /* minimum size of dgram rcv buffer */ 82 83 #include <sys/param.h> 84 #include <sys/ioctl.h> 85 #include <sys/mman.h> 86 #include <sys/queue.h> 87 #include <sys/resource.h> 88 #include <sys/socket.h> 89 #include <sys/stat.h> 90 #include <sys/syslimits.h> 91 #include <sys/time.h> 92 #include <sys/uio.h> 93 #include <sys/un.h> 94 #include <sys/wait.h> 95 96 #if defined(INET) || defined(INET6) 97 #include <netinet/in.h> 98 #include <arpa/inet.h> 99 #endif 100 #include <netdb.h> 101 102 #include <ctype.h> 103 #include <dirent.h> 104 #include <err.h> 105 #include <errno.h> 106 #include <fcntl.h> 107 #include <fnmatch.h> 108 #include <libutil.h> 109 #include <limits.h> 110 #include <paths.h> 111 #include <signal.h> 112 #include <stdio.h> 113 #include <stdlib.h> 114 #include <string.h> 115 #include <sysexits.h> 116 #include <unistd.h> 117 #include <utmpx.h> 118 119 #include "pathnames.h" 120 #include "ttymsg.h" 121 122 #define SYSLOG_NAMES 123 #include <sys/syslog.h> 124 125 static const char *ConfFile = _PATH_LOGCONF; 126 static const char *PidFile = _PATH_LOGPID; 127 static const char ctty[] = _PATH_CONSOLE; 128 static const char include_str[] = "include"; 129 static const char include_ext[] = ".conf"; 130 131 #define dprintf if (Debug) printf 132 133 #define MAXUNAMES 20 /* maximum number of user names */ 134 135 #define sstosa(ss) ((struct sockaddr *)(ss)) 136 #ifdef INET 137 #define sstosin(ss) ((struct sockaddr_in *)(void *)(ss)) 138 #define satosin(sa) ((struct sockaddr_in *)(void *)(sa)) 139 #endif 140 #ifdef INET6 141 #define sstosin6(ss) ((struct sockaddr_in6 *)(void *)(ss)) 142 #define satosin6(sa) ((struct sockaddr_in6 *)(void *)(sa)) 143 #define s6_addr32 __u6_addr.__u6_addr32 144 #define IN6_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \ 145 (((d)->s6_addr32[0] ^ (a)->s6_addr32[0]) & (m)->s6_addr32[0]) == 0 && \ 146 (((d)->s6_addr32[1] ^ (a)->s6_addr32[1]) & (m)->s6_addr32[1]) == 0 && \ 147 (((d)->s6_addr32[2] ^ (a)->s6_addr32[2]) & (m)->s6_addr32[2]) == 0 && \ 148 (((d)->s6_addr32[3] ^ (a)->s6_addr32[3]) & (m)->s6_addr32[3]) == 0 ) 149 #endif 150 /* 151 * List of peers and sockets for binding. 152 */ 153 struct peer { 154 const char *pe_name; 155 const char *pe_serv; 156 mode_t pe_mode; 157 STAILQ_ENTRY(peer) next; 158 }; 159 static STAILQ_HEAD(, peer) pqueue = STAILQ_HEAD_INITIALIZER(pqueue); 160 161 struct socklist { 162 struct sockaddr_storage sl_ss; 163 int sl_socket; 164 struct peer *sl_peer; 165 int (*sl_recv)(struct socklist *); 166 STAILQ_ENTRY(socklist) next; 167 }; 168 static STAILQ_HEAD(, socklist) shead = STAILQ_HEAD_INITIALIZER(shead); 169 170 /* 171 * Flags to logmsg(). 172 */ 173 174 #define IGN_CONS 0x001 /* don't print on console */ 175 #define SYNC_FILE 0x002 /* do fsync on file after printing */ 176 #define MARK 0x008 /* this message is a mark */ 177 #define ISKERNEL 0x010 /* kernel generated message */ 178 179 /* 180 * This structure represents the files that will have log 181 * copies printed. 182 * We require f_file to be valid if f_type is F_FILE, F_CONSOLE, F_TTY 183 * or if f_type if F_PIPE and f_pid > 0. 184 */ 185 186 struct filed { 187 STAILQ_ENTRY(filed) next; /* next in linked list */ 188 short f_type; /* entry type, see below */ 189 short f_file; /* file descriptor */ 190 time_t f_time; /* time this was last written */ 191 char *f_host; /* host from which to recd. */ 192 u_char f_pmask[LOG_NFACILITIES+1]; /* priority mask */ 193 u_char f_pcmp[LOG_NFACILITIES+1]; /* compare priority */ 194 #define PRI_LT 0x1 195 #define PRI_EQ 0x2 196 #define PRI_GT 0x4 197 char *f_program; /* program this applies to */ 198 union { 199 char f_uname[MAXUNAMES][MAXLOGNAME]; 200 struct { 201 char f_hname[MAXHOSTNAMELEN]; 202 struct addrinfo *f_addr; 203 204 } f_forw; /* forwarding address */ 205 char f_fname[MAXPATHLEN]; 206 struct { 207 char f_pname[MAXPATHLEN]; 208 pid_t f_pid; 209 } f_pipe; 210 } f_un; 211 #define fu_uname f_un.f_uname 212 #define fu_forw_hname f_un.f_forw.f_hname 213 #define fu_forw_addr f_un.f_forw.f_addr 214 #define fu_fname f_un.f_fname 215 #define fu_pipe_pname f_un.f_pipe.f_pname 216 #define fu_pipe_pid f_un.f_pipe.f_pid 217 char f_prevline[MAXSVLINE]; /* last message logged */ 218 char f_lasttime[MAXDATELEN]; /* time of last occurrence */ 219 char f_prevhost[MAXHOSTNAMELEN]; /* host from which recd. */ 220 int f_prevpri; /* pri of f_prevline */ 221 int f_prevlen; /* length of f_prevline */ 222 int f_prevcount; /* repetition cnt of prevline */ 223 u_int f_repeatcount; /* number of "repeated" msgs */ 224 int f_flags; /* file-specific flags */ 225 #define FFLAG_SYNC 0x01 226 #define FFLAG_NEEDSYNC 0x02 227 }; 228 229 /* 230 * Queue of about-to-be dead processes we should watch out for. 231 */ 232 struct deadq_entry { 233 pid_t dq_pid; 234 int dq_timeout; 235 TAILQ_ENTRY(deadq_entry) dq_entries; 236 }; 237 static TAILQ_HEAD(, deadq_entry) deadq_head = 238 TAILQ_HEAD_INITIALIZER(deadq_head); 239 240 /* 241 * The timeout to apply to processes waiting on the dead queue. Unit 242 * of measure is `mark intervals', i.e. 20 minutes by default. 243 * Processes on the dead queue will be terminated after that time. 244 */ 245 246 #define DQ_TIMO_INIT 2 247 248 /* 249 * Struct to hold records of network addresses that are allowed to log 250 * to us. 251 */ 252 struct allowedpeer { 253 int isnumeric; 254 u_short port; 255 union { 256 struct { 257 struct sockaddr_storage addr; 258 struct sockaddr_storage mask; 259 } numeric; 260 char *name; 261 } u; 262 #define a_addr u.numeric.addr 263 #define a_mask u.numeric.mask 264 #define a_name u.name 265 STAILQ_ENTRY(allowedpeer) next; 266 }; 267 static STAILQ_HEAD(, allowedpeer) aphead = STAILQ_HEAD_INITIALIZER(aphead); 268 269 270 /* 271 * Intervals at which we flush out "message repeated" messages, 272 * in seconds after previous message is logged. After each flush, 273 * we move to the next interval until we reach the largest. 274 */ 275 static int repeatinterval[] = { 30, 120, 600 }; /* # of secs before flush */ 276 #define MAXREPEAT (nitems(repeatinterval) - 1) 277 #define REPEATTIME(f) ((f)->f_time + repeatinterval[(f)->f_repeatcount]) 278 #define BACKOFF(f) do { \ 279 if (++(f)->f_repeatcount > MAXREPEAT) \ 280 (f)->f_repeatcount = MAXREPEAT; \ 281 } while (0) 282 283 /* values for f_type */ 284 #define F_UNUSED 0 /* unused entry */ 285 #define F_FILE 1 /* regular file */ 286 #define F_TTY 2 /* terminal */ 287 #define F_CONSOLE 3 /* console terminal */ 288 #define F_FORW 4 /* remote machine */ 289 #define F_USERS 5 /* list of users */ 290 #define F_WALL 6 /* everyone logged on */ 291 #define F_PIPE 7 /* pipe to program */ 292 293 static const char *TypeNames[] = { 294 "UNUSED", "FILE", "TTY", "CONSOLE", 295 "FORW", "USERS", "WALL", "PIPE" 296 }; 297 298 static STAILQ_HEAD(, filed) fhead = 299 STAILQ_HEAD_INITIALIZER(fhead); /* Log files that we write to */ 300 static struct filed consfile; /* Console */ 301 302 static int Debug; /* debug flag */ 303 static int Foreground = 0; /* Run in foreground, instead of daemonizing */ 304 static int resolve = 1; /* resolve hostname */ 305 static char LocalHostName[MAXHOSTNAMELEN]; /* our hostname */ 306 static const char *LocalDomain; /* our local domain name */ 307 static int Initialized; /* set when we have initialized ourselves */ 308 static int MarkInterval = 20 * 60; /* interval between marks in seconds */ 309 static int MarkSeq; /* mark sequence number */ 310 static int NoBind; /* don't bind() as suggested by RFC 3164 */ 311 static int SecureMode; /* when true, receive only unix domain socks */ 312 #ifdef INET6 313 static int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both) */ 314 #else 315 static int family = PF_INET; /* protocol family (IPv4 only) */ 316 #endif 317 static int mask_C1 = 1; /* mask characters from 0x80 - 0x9F */ 318 static int send_to_all; /* send message to all IPv4/IPv6 addresses */ 319 static int use_bootfile; /* log entire bootfile for every kern msg */ 320 static int no_compress; /* don't compress messages (1=pipes, 2=all) */ 321 static int logflags = O_WRONLY|O_APPEND; /* flags used to open log files */ 322 323 static char bootfile[MAXLINE+1]; /* booted kernel file */ 324 325 static int RemoteAddDate; /* Always set the date on remote messages */ 326 static int RemoteHostname; /* Log remote hostname from the message */ 327 328 static int UniquePriority; /* Only log specified priority? */ 329 static int LogFacPri; /* Put facility and priority in log message: */ 330 /* 0=no, 1=numeric, 2=names */ 331 static int KeepKernFac; /* Keep remotely logged kernel facility */ 332 static int needdofsync = 0; /* Are any file(s) waiting to be fsynced? */ 333 static struct pidfh *pfh; 334 static int sigpipe[2]; /* Pipe to catch a signal during select(). */ 335 336 static volatile sig_atomic_t MarkSet, WantDie, WantInitialize, WantReapchild; 337 338 static int allowaddr(char *); 339 static int addfile(struct filed *); 340 static int addpeer(struct peer *); 341 static int addsock(struct sockaddr *, socklen_t, struct socklist *); 342 static struct filed *cfline(const char *, const char *, const char *); 343 static const char *cvthname(struct sockaddr *); 344 static void deadq_enter(pid_t, const char *); 345 static int deadq_remove(struct deadq_entry *); 346 static int deadq_removebypid(pid_t); 347 static int decode(const char *, const CODE *); 348 static void die(int) __dead2; 349 static void dodie(int); 350 static void dofsync(void); 351 static void domark(int); 352 static void fprintlog(struct filed *, int, const char *); 353 static void init(int); 354 static void logerror(const char *); 355 static void logmsg(int, const char *, const char *, const char *, int); 356 static void log_deadchild(pid_t, int, const char *); 357 static void markit(void); 358 static int socksetup(struct peer *); 359 static int socklist_recv_file(struct socklist *); 360 static int socklist_recv_sock(struct socklist *); 361 static int socklist_recv_signal(struct socklist *); 362 static void sighandler(int); 363 static int skip_message(const char *, const char *, int); 364 static void parsemsg(const char *, char *); 365 static void printsys(char *); 366 static int p_open(const char *, pid_t *); 367 static void reapchild(int); 368 static const char *ttymsg_check(struct iovec *, int, char *, int); 369 static void usage(void); 370 static int validate(struct sockaddr *, const char *); 371 static void unmapped(struct sockaddr *); 372 static void wallmsg(struct filed *, struct iovec *, const int iovlen); 373 static int waitdaemon(int); 374 static void timedout(int); 375 static void increase_rcvbuf(int); 376 377 static void 378 close_filed(struct filed *f) 379 { 380 381 if (f == NULL || f->f_file == -1) 382 return; 383 384 switch (f->f_type) { 385 case F_FILE: 386 case F_TTY: 387 case F_CONSOLE: 388 case F_FORW: 389 f->f_type = F_UNUSED; 390 break; 391 case F_PIPE: 392 f->fu_pipe_pid = 0; 393 break; 394 } 395 (void)close(f->f_file); 396 f->f_file = -1; 397 } 398 399 static int 400 addfile(struct filed *f0) 401 { 402 struct filed *f; 403 404 f = calloc(1, sizeof(*f)); 405 if (f == NULL) 406 err(1, "malloc failed"); 407 *f = *f0; 408 STAILQ_INSERT_TAIL(&fhead, f, next); 409 410 return (0); 411 } 412 413 static int 414 addpeer(struct peer *pe0) 415 { 416 struct peer *pe; 417 418 pe = calloc(1, sizeof(*pe)); 419 if (pe == NULL) 420 err(1, "malloc failed"); 421 *pe = *pe0; 422 STAILQ_INSERT_TAIL(&pqueue, pe, next); 423 424 return (0); 425 } 426 427 static int 428 addsock(struct sockaddr *sa, socklen_t sa_len, struct socklist *sl0) 429 { 430 struct socklist *sl; 431 432 sl = calloc(1, sizeof(*sl)); 433 if (sl == NULL) 434 err(1, "malloc failed"); 435 *sl = *sl0; 436 if (sa != NULL && sa_len > 0) 437 memcpy(&sl->sl_ss, sa, sa_len); 438 STAILQ_INSERT_TAIL(&shead, sl, next); 439 440 return (0); 441 } 442 443 int 444 main(int argc, char *argv[]) 445 { 446 int ch, i, s, fdsrmax = 0, bflag = 0, pflag = 0, Sflag = 0; 447 fd_set *fdsr = NULL; 448 struct timeval tv, *tvp; 449 struct peer *pe; 450 struct socklist *sl; 451 pid_t ppid = 1, spid; 452 char *p; 453 454 if (madvise(NULL, 0, MADV_PROTECT) != 0) 455 dprintf("madvise() failed: %s\n", strerror(errno)); 456 457 while ((ch = getopt(argc, argv, "468Aa:b:cCdf:FHkl:m:nNop:P:sS:Tuv")) 458 != -1) 459 switch (ch) { 460 #ifdef INET 461 case '4': 462 family = PF_INET; 463 break; 464 #endif 465 #ifdef INET6 466 case '6': 467 family = PF_INET6; 468 break; 469 #endif 470 case '8': 471 mask_C1 = 0; 472 break; 473 case 'A': 474 send_to_all++; 475 break; 476 case 'a': /* allow specific network addresses only */ 477 if (allowaddr(optarg) == -1) 478 usage(); 479 break; 480 case 'b': 481 bflag = 1; 482 p = strchr(optarg, ']'); 483 if (p != NULL) 484 p = strchr(p + 1, ':'); 485 else { 486 p = strchr(optarg, ':'); 487 if (p != NULL && strchr(p + 1, ':') != NULL) 488 p = NULL; /* backward compatibility */ 489 } 490 if (p == NULL) { 491 /* A hostname or filename only. */ 492 addpeer(&(struct peer){ 493 .pe_name = optarg, 494 .pe_serv = "syslog" 495 }); 496 } else { 497 /* The case of "name:service". */ 498 *p++ = '\0'; 499 addpeer(&(struct peer){ 500 .pe_serv = p, 501 .pe_name = (strlen(optarg) == 0) ? 502 NULL : optarg, 503 }); 504 } 505 break; 506 case 'c': 507 no_compress++; 508 break; 509 case 'C': 510 logflags |= O_CREAT; 511 break; 512 case 'd': /* debug */ 513 Debug++; 514 break; 515 case 'f': /* configuration file */ 516 ConfFile = optarg; 517 break; 518 case 'F': /* run in foreground instead of daemon */ 519 Foreground++; 520 break; 521 case 'H': 522 RemoteHostname = 1; 523 break; 524 case 'k': /* keep remote kern fac */ 525 KeepKernFac = 1; 526 break; 527 case 'l': 528 case 'p': 529 case 'S': 530 { 531 long perml; 532 mode_t mode; 533 char *name, *ep; 534 535 if (ch == 'l') 536 mode = DEFFILEMODE; 537 else if (ch == 'p') { 538 mode = DEFFILEMODE; 539 pflag = 1; 540 } else if (ch == 'S') { 541 mode = S_IRUSR | S_IWUSR; 542 Sflag = 1; 543 } 544 if (optarg[0] == '/') 545 name = optarg; 546 else if ((name = strchr(optarg, ':')) != NULL) { 547 *name++ = '\0'; 548 if (name[0] != '/') 549 errx(1, "socket name must be absolute " 550 "path"); 551 if (isdigit(*optarg)) { 552 perml = strtol(optarg, &ep, 8); 553 if (*ep || perml < 0 || 554 perml & ~(S_IRWXU|S_IRWXG|S_IRWXO)) 555 errx(1, "invalid mode %s, exiting", 556 optarg); 557 mode = (mode_t )perml; 558 } else 559 errx(1, "invalid mode %s, exiting", 560 optarg); 561 } else 562 errx(1, "invalid filename %s, exiting", 563 optarg); 564 addpeer(&(struct peer){ 565 .pe_name = name, 566 .pe_mode = mode 567 }); 568 break; 569 } 570 case 'm': /* mark interval */ 571 MarkInterval = atoi(optarg) * 60; 572 break; 573 case 'N': 574 NoBind = 1; 575 SecureMode = 1; 576 break; 577 case 'n': 578 resolve = 0; 579 break; 580 case 'o': 581 use_bootfile = 1; 582 break; 583 case 'P': /* path for alt. PID */ 584 PidFile = optarg; 585 break; 586 case 's': /* no network mode */ 587 SecureMode++; 588 break; 589 case 'T': 590 RemoteAddDate = 1; 591 break; 592 case 'u': /* only log specified priority */ 593 UniquePriority++; 594 break; 595 case 'v': /* log facility and priority */ 596 LogFacPri++; 597 break; 598 default: 599 usage(); 600 } 601 if ((argc -= optind) != 0) 602 usage(); 603 604 /* Pipe to catch a signal during select(). */ 605 s = pipe2(sigpipe, O_CLOEXEC); 606 if (s < 0) { 607 err(1, "cannot open a pipe for signals"); 608 } else { 609 addsock(NULL, 0, &(struct socklist){ 610 .sl_socket = sigpipe[0], 611 .sl_recv = socklist_recv_signal 612 }); 613 } 614 615 /* Listen by default: /dev/klog. */ 616 s = open(_PATH_KLOG, O_RDONLY | O_NONBLOCK | O_CLOEXEC, 0); 617 if (s < 0) { 618 dprintf("can't open %s (%d)\n", _PATH_KLOG, errno); 619 } else { 620 addsock(NULL, 0, &(struct socklist){ 621 .sl_socket = s, 622 .sl_recv = socklist_recv_file, 623 }); 624 } 625 /* Listen by default: *:514 if no -b flag. */ 626 if (bflag == 0) 627 addpeer(&(struct peer){ 628 .pe_serv = "syslog" 629 }); 630 /* Listen by default: /var/run/log if no -p flag. */ 631 if (pflag == 0) 632 addpeer(&(struct peer){ 633 .pe_name = _PATH_LOG, 634 .pe_mode = DEFFILEMODE, 635 }); 636 /* Listen by default: /var/run/logpriv if no -S flag. */ 637 if (Sflag == 0) 638 addpeer(&(struct peer){ 639 .pe_name = _PATH_LOG_PRIV, 640 .pe_mode = S_IRUSR | S_IWUSR, 641 }); 642 STAILQ_FOREACH(pe, &pqueue, next) 643 socksetup(pe); 644 645 pfh = pidfile_open(PidFile, 0600, &spid); 646 if (pfh == NULL) { 647 if (errno == EEXIST) 648 errx(1, "syslogd already running, pid: %d", spid); 649 warn("cannot open pid file"); 650 } 651 652 if ((!Foreground) && (!Debug)) { 653 ppid = waitdaemon(30); 654 if (ppid < 0) { 655 warn("could not become daemon"); 656 pidfile_remove(pfh); 657 exit(1); 658 } 659 } else if (Debug) 660 setlinebuf(stdout); 661 662 consfile.f_type = F_CONSOLE; 663 (void)strlcpy(consfile.fu_fname, ctty + sizeof _PATH_DEV - 1, 664 sizeof(consfile.fu_fname)); 665 (void)strlcpy(bootfile, getbootfile(), sizeof(bootfile)); 666 (void)signal(SIGTERM, dodie); 667 (void)signal(SIGINT, Debug ? dodie : SIG_IGN); 668 (void)signal(SIGQUIT, Debug ? dodie : SIG_IGN); 669 (void)signal(SIGHUP, sighandler); 670 (void)signal(SIGCHLD, sighandler); 671 (void)signal(SIGALRM, domark); 672 (void)signal(SIGPIPE, SIG_IGN); /* We'll catch EPIPE instead. */ 673 (void)alarm(TIMERINTVL); 674 675 /* tuck my process id away */ 676 pidfile_write(pfh); 677 678 dprintf("off & running....\n"); 679 680 tvp = &tv; 681 tv.tv_sec = tv.tv_usec = 0; 682 683 STAILQ_FOREACH(sl, &shead, next) { 684 if (sl->sl_socket > fdsrmax) 685 fdsrmax = sl->sl_socket; 686 } 687 fdsr = (fd_set *)calloc(howmany(fdsrmax+1, NFDBITS), 688 sizeof(fd_mask)); 689 if (fdsr == NULL) 690 errx(1, "calloc fd_set"); 691 692 for (;;) { 693 if (Initialized == 0) 694 init(0); 695 else if (WantInitialize) 696 init(WantInitialize); 697 if (WantReapchild) 698 reapchild(WantReapchild); 699 if (MarkSet) 700 markit(); 701 if (WantDie) { 702 free(fdsr); 703 die(WantDie); 704 } 705 706 bzero(fdsr, howmany(fdsrmax+1, NFDBITS) * 707 sizeof(fd_mask)); 708 709 STAILQ_FOREACH(sl, &shead, next) { 710 if (sl->sl_socket != -1 && sl->sl_recv != NULL) 711 FD_SET(sl->sl_socket, fdsr); 712 } 713 i = select(fdsrmax + 1, fdsr, NULL, NULL, 714 needdofsync ? &tv : tvp); 715 switch (i) { 716 case 0: 717 dofsync(); 718 needdofsync = 0; 719 if (tvp) { 720 tvp = NULL; 721 if (ppid != 1) 722 kill(ppid, SIGALRM); 723 } 724 continue; 725 case -1: 726 if (errno != EINTR) 727 logerror("select"); 728 continue; 729 } 730 STAILQ_FOREACH(sl, &shead, next) { 731 if (FD_ISSET(sl->sl_socket, fdsr)) 732 (*sl->sl_recv)(sl); 733 } 734 } 735 free(fdsr); 736 } 737 738 static int 739 socklist_recv_signal(struct socklist *sl __unused) 740 { 741 ssize_t len; 742 int i, nsig, signo; 743 744 if (ioctl(sigpipe[0], FIONREAD, &i) != 0) { 745 logerror("ioctl(FIONREAD)"); 746 err(1, "signal pipe read failed"); 747 } 748 nsig = i / sizeof(signo); 749 dprintf("# of received signals = %d\n", nsig); 750 for (i = 0; i < nsig; i++) { 751 len = read(sigpipe[0], &signo, sizeof(signo)); 752 if (len != sizeof(signo)) { 753 logerror("signal pipe read failed"); 754 err(1, "signal pipe read failed"); 755 } 756 dprintf("Received signal: %d from fd=%d\n", signo, 757 sigpipe[0]); 758 switch (signo) { 759 case SIGHUP: 760 WantInitialize = 1; 761 break; 762 case SIGCHLD: 763 WantReapchild = 1; 764 break; 765 } 766 } 767 return (0); 768 } 769 770 static int 771 socklist_recv_sock(struct socklist *sl) 772 { 773 struct sockaddr_storage ss; 774 struct sockaddr *sa = (struct sockaddr *)&ss; 775 socklen_t sslen; 776 const char *hname; 777 char line[MAXLINE + 1]; 778 int len; 779 780 sslen = sizeof(ss); 781 len = recvfrom(sl->sl_socket, line, sizeof(line) - 1, 0, sa, &sslen); 782 dprintf("received sa_len = %d\n", sslen); 783 if (len == 0) 784 return (-1); 785 if (len < 0) { 786 if (errno != EINTR) 787 logerror("recvfrom"); 788 return (-1); 789 } 790 /* Received valid data. */ 791 line[len] = '\0'; 792 if (sl->sl_ss.ss_family == AF_LOCAL) 793 hname = LocalHostName; 794 else { 795 hname = cvthname(sa); 796 unmapped(sa); 797 if (validate(sa, hname) == 0) { 798 dprintf("Message from %s was ignored.", hname); 799 return (-1); 800 } 801 } 802 parsemsg(hname, line); 803 804 return (0); 805 } 806 807 static void 808 unmapped(struct sockaddr *sa) 809 { 810 #if defined(INET) && defined(INET6) 811 struct sockaddr_in6 *sin6; 812 struct sockaddr_in sin; 813 814 if (sa == NULL || 815 sa->sa_family != AF_INET6 || 816 sa->sa_len != sizeof(*sin6)) 817 return; 818 sin6 = satosin6(sa); 819 if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) 820 return; 821 sin = (struct sockaddr_in){ 822 .sin_family = AF_INET, 823 .sin_len = sizeof(sin), 824 .sin_port = sin6->sin6_port 825 }; 826 memcpy(&sin.sin_addr, &sin6->sin6_addr.s6_addr[12], 827 sizeof(sin.sin_addr)); 828 memcpy(sa, &sin, sizeof(sin)); 829 #else 830 if (sa == NULL) 831 return; 832 #endif 833 } 834 835 static void 836 usage(void) 837 { 838 839 fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n", 840 "usage: syslogd [-468ACcdFHknosTuv] [-a allowed_peer]", 841 " [-b bind_address] [-f config_file]", 842 " [-l [mode:]path] [-m mark_interval]", 843 " [-P pid_file] [-p log_socket]", 844 " [-S logpriv_socket]"); 845 exit(1); 846 } 847 848 /* 849 * Take a raw input line, extract PRI, TIMESTAMP and HOSTNAME from the message, 850 * and print the message on the appropriate log files. 851 */ 852 static void 853 parsemsg(const char *from, char *msg) 854 { 855 const char *timestamp; 856 char *q; 857 long n; 858 int i, c, pri, msglen; 859 char line[MAXLINE + 1]; 860 861 /* Parse PRI. */ 862 if (msg[0] != '<' || !isdigit(msg[1])) { 863 dprintf("Invalid PRI from %s\n", from); 864 return; 865 } 866 for (i = 2; i <= 4; i++) { 867 if (msg[i] == '>') 868 break; 869 if (!isdigit(msg[i])) { 870 dprintf("Invalid PRI header from %s\n", from); 871 return; 872 } 873 } 874 if (msg[i] != '>') { 875 dprintf("Invalid PRI header from %s\n", from); 876 return; 877 } 878 errno = 0; 879 n = strtol(msg + 1, &q, 10); 880 if (errno != 0 || *q != msg[i] || n < 0 || n >= INT_MAX) { 881 dprintf("Invalid PRI %ld from %s: %s\n", 882 n, from, strerror(errno)); 883 return; 884 } 885 pri = n; 886 if (pri &~ (LOG_FACMASK|LOG_PRIMASK)) 887 pri = DEFUPRI; 888 889 /* 890 * Don't allow users to log kernel messages. 891 * NOTE: since LOG_KERN == 0 this will also match 892 * messages with no facility specified. 893 */ 894 if ((pri & LOG_FACMASK) == LOG_KERN && !KeepKernFac) 895 pri = LOG_MAKEPRI(LOG_USER, LOG_PRI(pri)); 896 897 /* 898 * The TIMESTAMP field is the local time and is in the format of 899 * "Mmm dd hh:mm:ss" (without the quote marks). 900 * A single space character MUST follow the TIMESTAMP field. 901 * 902 * XXXGL: the check can be improved. 903 */ 904 msg += i + 1; 905 msglen = strlen(msg); 906 if (msglen < MAXDATELEN || msg[3] != ' ' || msg[6] != ' ' || 907 msg[9] != ':' || msg[12] != ':' || msg[15] != ' ') { 908 dprintf("Invalid TIMESTAMP from %s: %s\n", from, msg); 909 return; 910 } 911 912 if (!RemoteAddDate) 913 timestamp = msg; 914 else 915 timestamp = NULL; 916 msg += MAXDATELEN; 917 msglen -= MAXDATELEN; 918 919 /* 920 * A single space character MUST also follow the HOSTNAME field. 921 */ 922 for (i = 0; i < MIN(MAXHOSTNAMELEN, msglen); i++) { 923 if (msg[i] == ' ') { 924 if (RemoteHostname) { 925 msg[i] = '\0'; 926 from = msg; 927 } 928 msg += i + 1; 929 break; 930 } 931 /* 932 * Support non RFC compliant messages, without hostname. 933 */ 934 if (msg[i] == ':') 935 break; 936 } 937 if (i == MIN(MAXHOSTNAMELEN, msglen)) { 938 dprintf("Invalid HOSTNAME from %s: %s\n", from, msg); 939 return; 940 } 941 942 q = line; 943 while ((c = (unsigned char)*msg++) != '\0' && 944 q < &line[sizeof(line) - 4]) { 945 if (mask_C1 && (c & 0x80) && c < 0xA0) { 946 c &= 0x7F; 947 *q++ = 'M'; 948 *q++ = '-'; 949 } 950 if (isascii(c) && iscntrl(c)) { 951 if (c == '\n') { 952 *q++ = ' '; 953 } else if (c == '\t') { 954 *q++ = '\t'; 955 } else { 956 *q++ = '^'; 957 *q++ = c ^ 0100; 958 } 959 } else { 960 *q++ = c; 961 } 962 } 963 *q = '\0'; 964 965 logmsg(pri, timestamp, line, from, 0); 966 } 967 968 /* 969 * Read /dev/klog while data are available, split into lines. 970 */ 971 static int 972 socklist_recv_file(struct socklist *sl) 973 { 974 char *p, *q, line[MAXLINE + 1]; 975 int len, i; 976 977 len = 0; 978 for (;;) { 979 i = read(sl->sl_socket, line + len, MAXLINE - 1 - len); 980 if (i > 0) { 981 line[i + len] = '\0'; 982 } else { 983 if (i < 0 && errno != EINTR && errno != EAGAIN) { 984 logerror("klog"); 985 close(sl->sl_socket); 986 sl->sl_socket = -1; 987 } 988 break; 989 } 990 991 for (p = line; (q = strchr(p, '\n')) != NULL; p = q + 1) { 992 *q = '\0'; 993 printsys(p); 994 } 995 len = strlen(p); 996 if (len >= MAXLINE - 1) { 997 printsys(p); 998 len = 0; 999 } 1000 if (len > 0) 1001 memmove(line, p, len + 1); 1002 } 1003 if (len > 0) 1004 printsys(line); 1005 1006 return (len); 1007 } 1008 1009 /* 1010 * Take a raw input line from /dev/klog, format similar to syslog(). 1011 */ 1012 static void 1013 printsys(char *msg) 1014 { 1015 char *p, *q; 1016 long n; 1017 int flags, isprintf, pri; 1018 1019 flags = ISKERNEL | SYNC_FILE; /* fsync after write */ 1020 p = msg; 1021 pri = DEFSPRI; 1022 isprintf = 1; 1023 if (*p == '<') { 1024 errno = 0; 1025 n = strtol(p + 1, &q, 10); 1026 if (*q == '>' && n >= 0 && n < INT_MAX && errno == 0) { 1027 p = q + 1; 1028 pri = n; 1029 isprintf = 0; 1030 } 1031 } 1032 /* 1033 * Kernel printf's and LOG_CONSOLE messages have been displayed 1034 * on the console already. 1035 */ 1036 if (isprintf || (pri & LOG_FACMASK) == LOG_CONSOLE) 1037 flags |= IGN_CONS; 1038 if (pri &~ (LOG_FACMASK|LOG_PRIMASK)) 1039 pri = DEFSPRI; 1040 logmsg(pri, NULL, p, LocalHostName, flags); 1041 } 1042 1043 static time_t now; 1044 1045 /* 1046 * Match a program or host name against a specification. 1047 * Return a non-0 value if the message must be ignored 1048 * based on the specification. 1049 */ 1050 static int 1051 skip_message(const char *name, const char *spec, int checkcase) 1052 { 1053 const char *s; 1054 char prev, next; 1055 int exclude = 0; 1056 /* Behaviour on explicit match */ 1057 1058 if (spec == NULL) 1059 return 0; 1060 switch (*spec) { 1061 case '-': 1062 exclude = 1; 1063 /*FALLTHROUGH*/ 1064 case '+': 1065 spec++; 1066 break; 1067 default: 1068 break; 1069 } 1070 if (checkcase) 1071 s = strstr (spec, name); 1072 else 1073 s = strcasestr (spec, name); 1074 1075 if (s != NULL) { 1076 prev = (s == spec ? ',' : *(s - 1)); 1077 next = *(s + strlen (name)); 1078 1079 if (prev == ',' && (next == '\0' || next == ',')) 1080 /* Explicit match: skip iff the spec is an 1081 exclusive one. */ 1082 return exclude; 1083 } 1084 1085 /* No explicit match for this name: skip the message iff 1086 the spec is an inclusive one. */ 1087 return !exclude; 1088 } 1089 1090 /* 1091 * Log a message to the appropriate log files, users, etc. based on 1092 * the priority. 1093 */ 1094 static void 1095 logmsg(int pri, const char *timestamp, const char *msg, const char *from, 1096 int flags) 1097 { 1098 struct filed *f; 1099 int i, fac, msglen, prilev; 1100 char prog[NAME_MAX+1]; 1101 char buf[MAXLINE+1]; 1102 1103 dprintf("logmsg: pri %o, flags %x, from %s, msg %s\n", 1104 pri, flags, from, msg); 1105 1106 (void)time(&now); 1107 if (timestamp == NULL) 1108 timestamp = ctime(&now) + 4; 1109 1110 /* extract facility and priority level */ 1111 if (flags & MARK) 1112 fac = LOG_NFACILITIES; 1113 else 1114 fac = LOG_FAC(pri); 1115 1116 /* Check maximum facility number. */ 1117 if (fac > LOG_NFACILITIES) 1118 return; 1119 1120 prilev = LOG_PRI(pri); 1121 1122 /* Extract TAG part of the message (usually program name). */ 1123 for (i = 0; i < NAME_MAX; i++) { 1124 if (!isprint(msg[i]) || msg[i] == ':' || msg[i] == '[' || 1125 msg[i] == '/' || isspace(msg[i])) 1126 break; 1127 prog[i] = msg[i]; 1128 } 1129 prog[i] = 0; 1130 1131 /* add kernel prefix for kernel messages */ 1132 if (flags & ISKERNEL) { 1133 snprintf(buf, sizeof(buf), "%s: %s", 1134 use_bootfile ? bootfile : "kernel", msg); 1135 msg = buf; 1136 } 1137 msglen = strlen(msg); 1138 1139 /* log the message to the particular outputs */ 1140 if (!Initialized) { 1141 f = &consfile; 1142 /* 1143 * Open in non-blocking mode to avoid hangs during open 1144 * and close(waiting for the port to drain). 1145 */ 1146 f->f_file = open(ctty, O_WRONLY | O_NONBLOCK, 0); 1147 1148 if (f->f_file >= 0) { 1149 (void)strlcpy(f->f_lasttime, timestamp, 1150 sizeof(f->f_lasttime)); 1151 fprintlog(f, flags, msg); 1152 close(f->f_file); 1153 f->f_file = -1; 1154 } 1155 return; 1156 } 1157 STAILQ_FOREACH(f, &fhead, next) { 1158 /* skip messages that are incorrect priority */ 1159 if (!(((f->f_pcmp[fac] & PRI_EQ) && (f->f_pmask[fac] == prilev)) 1160 ||((f->f_pcmp[fac] & PRI_LT) && (f->f_pmask[fac] < prilev)) 1161 ||((f->f_pcmp[fac] & PRI_GT) && (f->f_pmask[fac] > prilev)) 1162 ) 1163 || f->f_pmask[fac] == INTERNAL_NOPRI) 1164 continue; 1165 1166 /* skip messages with the incorrect hostname */ 1167 if (skip_message(from, f->f_host, 0)) 1168 continue; 1169 1170 /* skip messages with the incorrect program name */ 1171 if (skip_message(prog, f->f_program, 1)) 1172 continue; 1173 1174 /* skip message to console if it has already been printed */ 1175 if (f->f_type == F_CONSOLE && (flags & IGN_CONS)) 1176 continue; 1177 1178 /* don't output marks to recently written files */ 1179 if ((flags & MARK) && (now - f->f_time) < MarkInterval / 2) 1180 continue; 1181 1182 /* 1183 * suppress duplicate lines to this file 1184 */ 1185 if (no_compress - (f->f_type != F_PIPE) < 1 && 1186 (flags & MARK) == 0 && msglen == f->f_prevlen && 1187 !strcmp(msg, f->f_prevline) && 1188 !strcasecmp(from, f->f_prevhost)) { 1189 (void)strlcpy(f->f_lasttime, timestamp, 1190 sizeof(f->f_lasttime)); 1191 f->f_prevcount++; 1192 dprintf("msg repeated %d times, %ld sec of %d\n", 1193 f->f_prevcount, (long)(now - f->f_time), 1194 repeatinterval[f->f_repeatcount]); 1195 /* 1196 * If domark would have logged this by now, 1197 * flush it now (so we don't hold isolated messages), 1198 * but back off so we'll flush less often 1199 * in the future. 1200 */ 1201 if (now > REPEATTIME(f)) { 1202 fprintlog(f, flags, (char *)NULL); 1203 BACKOFF(f); 1204 } 1205 } else { 1206 /* new line, save it */ 1207 if (f->f_prevcount) 1208 fprintlog(f, 0, (char *)NULL); 1209 f->f_repeatcount = 0; 1210 f->f_prevpri = pri; 1211 (void)strlcpy(f->f_lasttime, timestamp, 1212 sizeof(f->f_lasttime)); 1213 (void)strlcpy(f->f_prevhost, from, 1214 sizeof(f->f_prevhost)); 1215 if (msglen < MAXSVLINE) { 1216 f->f_prevlen = msglen; 1217 (void)strlcpy(f->f_prevline, msg, sizeof(f->f_prevline)); 1218 fprintlog(f, flags, (char *)NULL); 1219 } else { 1220 f->f_prevline[0] = 0; 1221 f->f_prevlen = 0; 1222 fprintlog(f, flags, msg); 1223 } 1224 } 1225 } 1226 } 1227 1228 static void 1229 dofsync(void) 1230 { 1231 struct filed *f; 1232 1233 STAILQ_FOREACH(f, &fhead, next) { 1234 if ((f->f_type == F_FILE) && 1235 (f->f_flags & FFLAG_NEEDSYNC)) { 1236 f->f_flags &= ~FFLAG_NEEDSYNC; 1237 (void)fsync(f->f_file); 1238 } 1239 } 1240 } 1241 1242 #define IOV_SIZE 7 1243 static void 1244 fprintlog(struct filed *f, int flags, const char *msg) 1245 { 1246 struct iovec iov[IOV_SIZE]; 1247 struct addrinfo *r; 1248 int l, lsent = 0; 1249 char line[MAXLINE + 1], repbuf[80], greetings[200], *wmsg = NULL; 1250 char nul[] = "", space[] = " ", lf[] = "\n", crlf[] = "\r\n"; 1251 const char *msgret; 1252 1253 if (f->f_type == F_WALL) { 1254 /* The time displayed is not synchornized with the other log 1255 * destinations (like messages). Following fragment was using 1256 * ctime(&now), which was updating the time every 30 sec. 1257 * With f_lasttime, time is synchronized correctly. 1258 */ 1259 iov[0] = (struct iovec){ 1260 .iov_base = greetings, 1261 .iov_len = snprintf(greetings, sizeof(greetings), 1262 "\r\n\7Message from syslogd@%s " 1263 "at %.24s ...\r\n", 1264 f->f_prevhost, f->f_lasttime) 1265 }; 1266 if (iov[0].iov_len >= sizeof(greetings)) 1267 iov[0].iov_len = sizeof(greetings) - 1; 1268 iov[1] = (struct iovec){ 1269 .iov_base = nul, 1270 .iov_len = 0 1271 }; 1272 } else { 1273 iov[0] = (struct iovec){ 1274 .iov_base = f->f_lasttime, 1275 .iov_len = strlen(f->f_lasttime) 1276 }; 1277 iov[1] = (struct iovec){ 1278 .iov_base = space, 1279 .iov_len = 1 1280 }; 1281 } 1282 1283 if (LogFacPri) { 1284 static char fp_buf[30]; /* Hollow laugh */ 1285 int fac = f->f_prevpri & LOG_FACMASK; 1286 int pri = LOG_PRI(f->f_prevpri); 1287 const char *f_s = NULL; 1288 char f_n[5]; /* Hollow laugh */ 1289 const char *p_s = NULL; 1290 char p_n[5]; /* Hollow laugh */ 1291 1292 if (LogFacPri > 1) { 1293 const CODE *c; 1294 1295 for (c = facilitynames; c->c_name; c++) { 1296 if (c->c_val == fac) { 1297 f_s = c->c_name; 1298 break; 1299 } 1300 } 1301 for (c = prioritynames; c->c_name; c++) { 1302 if (c->c_val == pri) { 1303 p_s = c->c_name; 1304 break; 1305 } 1306 } 1307 } 1308 if (!f_s) { 1309 snprintf(f_n, sizeof f_n, "%d", LOG_FAC(fac)); 1310 f_s = f_n; 1311 } 1312 if (!p_s) { 1313 snprintf(p_n, sizeof p_n, "%d", pri); 1314 p_s = p_n; 1315 } 1316 snprintf(fp_buf, sizeof fp_buf, "<%s.%s> ", f_s, p_s); 1317 iov[2] = (struct iovec){ 1318 .iov_base = fp_buf, 1319 .iov_len = strlen(fp_buf) 1320 }; 1321 } else { 1322 iov[2] = (struct iovec){ 1323 .iov_base = nul, 1324 .iov_len = 0 1325 }; 1326 } 1327 iov[3] = (struct iovec){ 1328 .iov_base = f->f_prevhost, 1329 .iov_len = strlen(f->f_prevhost) 1330 }; 1331 iov[4] = (struct iovec){ 1332 .iov_base = space, 1333 .iov_len = 1 1334 }; 1335 if (msg) { 1336 wmsg = strdup(msg); /* XXX iov_base needs a `const' sibling. */ 1337 if (wmsg == NULL) { 1338 logerror("strdup"); 1339 exit(1); 1340 } 1341 iov[5] = (struct iovec){ 1342 .iov_base = wmsg, 1343 .iov_len = strlen(msg) 1344 }; 1345 } else if (f->f_prevcount > 1) { 1346 iov[5] = (struct iovec){ 1347 .iov_base = repbuf, 1348 .iov_len = snprintf(repbuf, sizeof(repbuf), 1349 "last message repeated %d times", f->f_prevcount) 1350 }; 1351 } else { 1352 iov[5] = (struct iovec){ 1353 .iov_base = f->f_prevline, 1354 .iov_len = f->f_prevlen 1355 }; 1356 } 1357 dprintf("Logging to %s", TypeNames[f->f_type]); 1358 f->f_time = now; 1359 1360 switch (f->f_type) { 1361 case F_UNUSED: 1362 dprintf("\n"); 1363 break; 1364 1365 case F_FORW: 1366 dprintf(" %s", f->fu_forw_hname); 1367 switch (f->fu_forw_addr->ai_addr->sa_family) { 1368 #ifdef INET 1369 case AF_INET: 1370 dprintf(":%d\n", 1371 ntohs(satosin(f->fu_forw_addr->ai_addr)->sin_port)); 1372 break; 1373 #endif 1374 #ifdef INET6 1375 case AF_INET6: 1376 dprintf(":%d\n", 1377 ntohs(satosin6(f->fu_forw_addr->ai_addr)->sin6_port)); 1378 break; 1379 #endif 1380 default: 1381 dprintf("\n"); 1382 } 1383 /* check for local vs remote messages */ 1384 if (strcasecmp(f->f_prevhost, LocalHostName)) 1385 l = snprintf(line, sizeof line - 1, 1386 "<%d>%.15s Forwarded from %s: %s", 1387 f->f_prevpri, (char *)iov[0].iov_base, 1388 f->f_prevhost, (char *)iov[5].iov_base); 1389 else 1390 l = snprintf(line, sizeof line - 1, "<%d>%.15s %s", 1391 f->f_prevpri, (char *)iov[0].iov_base, 1392 (char *)iov[5].iov_base); 1393 if (l < 0) 1394 l = 0; 1395 else if (l > MAXLINE) 1396 l = MAXLINE; 1397 1398 for (r = f->fu_forw_addr; r; r = r->ai_next) { 1399 struct socklist *sl; 1400 1401 STAILQ_FOREACH(sl, &shead, next) { 1402 if (sl->sl_ss.ss_family == AF_LOCAL || 1403 sl->sl_ss.ss_family == AF_UNSPEC || 1404 sl->sl_socket < 0) 1405 continue; 1406 lsent = sendto(sl->sl_socket, line, l, 0, 1407 r->ai_addr, r->ai_addrlen); 1408 if (lsent == l) 1409 break; 1410 } 1411 if (lsent == l && !send_to_all) 1412 break; 1413 } 1414 dprintf("lsent/l: %d/%d\n", lsent, l); 1415 if (lsent != l) { 1416 int e = errno; 1417 logerror("sendto"); 1418 errno = e; 1419 switch (errno) { 1420 case ENOBUFS: 1421 case ENETDOWN: 1422 case ENETUNREACH: 1423 case EHOSTUNREACH: 1424 case EHOSTDOWN: 1425 case EADDRNOTAVAIL: 1426 break; 1427 /* case EBADF: */ 1428 /* case EACCES: */ 1429 /* case ENOTSOCK: */ 1430 /* case EFAULT: */ 1431 /* case EMSGSIZE: */ 1432 /* case EAGAIN: */ 1433 /* case ENOBUFS: */ 1434 /* case ECONNREFUSED: */ 1435 default: 1436 dprintf("removing entry: errno=%d\n", e); 1437 f->f_type = F_UNUSED; 1438 break; 1439 } 1440 } 1441 break; 1442 1443 case F_FILE: 1444 dprintf(" %s\n", f->fu_fname); 1445 iov[6] = (struct iovec){ 1446 .iov_base = lf, 1447 .iov_len = 1 1448 }; 1449 if (writev(f->f_file, iov, nitems(iov)) < 0) { 1450 /* 1451 * If writev(2) fails for potentially transient errors 1452 * like the filesystem being full, ignore it. 1453 * Otherwise remove this logfile from the list. 1454 */ 1455 if (errno != ENOSPC) { 1456 int e = errno; 1457 close_filed(f); 1458 errno = e; 1459 logerror(f->fu_fname); 1460 } 1461 } else if ((flags & SYNC_FILE) && (f->f_flags & FFLAG_SYNC)) { 1462 f->f_flags |= FFLAG_NEEDSYNC; 1463 needdofsync = 1; 1464 } 1465 break; 1466 1467 case F_PIPE: 1468 dprintf(" %s\n", f->fu_pipe_pname); 1469 iov[6] = (struct iovec){ 1470 .iov_base = lf, 1471 .iov_len = 1 1472 }; 1473 if (f->fu_pipe_pid == 0) { 1474 if ((f->f_file = p_open(f->fu_pipe_pname, 1475 &f->fu_pipe_pid)) < 0) { 1476 logerror(f->fu_pipe_pname); 1477 break; 1478 } 1479 } 1480 if (writev(f->f_file, iov, nitems(iov)) < 0) { 1481 int e = errno; 1482 1483 deadq_enter(f->fu_pipe_pid, f->fu_pipe_pname); 1484 close_filed(f); 1485 errno = e; 1486 logerror(f->fu_pipe_pname); 1487 } 1488 break; 1489 1490 case F_CONSOLE: 1491 if (flags & IGN_CONS) { 1492 dprintf(" (ignored)\n"); 1493 break; 1494 } 1495 /* FALLTHROUGH */ 1496 1497 case F_TTY: 1498 dprintf(" %s%s\n", _PATH_DEV, f->fu_fname); 1499 iov[6] = (struct iovec){ 1500 .iov_base = crlf, 1501 .iov_len = 2 1502 }; 1503 errno = 0; /* ttymsg() only sometimes returns an errno */ 1504 if ((msgret = ttymsg(iov, nitems(iov), f->fu_fname, 10))) { 1505 f->f_type = F_UNUSED; 1506 logerror(msgret); 1507 } 1508 break; 1509 1510 case F_USERS: 1511 case F_WALL: 1512 dprintf("\n"); 1513 iov[6] = (struct iovec){ 1514 .iov_base = crlf, 1515 .iov_len = 2 1516 }; 1517 wallmsg(f, iov, nitems(iov)); 1518 break; 1519 } 1520 f->f_prevcount = 0; 1521 free(wmsg); 1522 } 1523 1524 /* 1525 * WALLMSG -- Write a message to the world at large 1526 * 1527 * Write the specified message to either the entire 1528 * world, or a list of approved users. 1529 */ 1530 static void 1531 wallmsg(struct filed *f, struct iovec *iov, const int iovlen) 1532 { 1533 static int reenter; /* avoid calling ourselves */ 1534 struct utmpx *ut; 1535 int i; 1536 const char *p; 1537 1538 if (reenter++) 1539 return; 1540 setutxent(); 1541 /* NOSTRICT */ 1542 while ((ut = getutxent()) != NULL) { 1543 if (ut->ut_type != USER_PROCESS) 1544 continue; 1545 if (f->f_type == F_WALL) { 1546 if ((p = ttymsg(iov, iovlen, ut->ut_line, 1547 TTYMSGTIME)) != NULL) { 1548 errno = 0; /* already in msg */ 1549 logerror(p); 1550 } 1551 continue; 1552 } 1553 /* should we send the message to this user? */ 1554 for (i = 0; i < MAXUNAMES; i++) { 1555 if (!f->fu_uname[i][0]) 1556 break; 1557 if (!strcmp(f->fu_uname[i], ut->ut_user)) { 1558 if ((p = ttymsg_check(iov, iovlen, ut->ut_line, 1559 TTYMSGTIME)) != NULL) { 1560 errno = 0; /* already in msg */ 1561 logerror(p); 1562 } 1563 break; 1564 } 1565 } 1566 } 1567 endutxent(); 1568 reenter = 0; 1569 } 1570 1571 /* 1572 * Wrapper routine for ttymsg() that checks the terminal for messages enabled. 1573 */ 1574 static const char * 1575 ttymsg_check(struct iovec *iov, int iovcnt, char *line, int tmout) 1576 { 1577 static char device[1024]; 1578 static char errbuf[1024]; 1579 struct stat sb; 1580 1581 (void) snprintf(device, sizeof(device), "%s%s", _PATH_DEV, line); 1582 1583 if (stat(device, &sb) < 0) { 1584 (void) snprintf(errbuf, sizeof(errbuf), 1585 "%s: %s", device, strerror(errno)); 1586 return (errbuf); 1587 } 1588 if ((sb.st_mode & S_IWGRP) == 0) 1589 /* Messages disabled. */ 1590 return (NULL); 1591 return ttymsg(iov, iovcnt, line, tmout); 1592 } 1593 1594 static void 1595 reapchild(int signo __unused) 1596 { 1597 int status; 1598 pid_t pid; 1599 struct filed *f; 1600 1601 while ((pid = wait3(&status, WNOHANG, (struct rusage *)NULL)) > 0) { 1602 /* First, look if it's a process from the dead queue. */ 1603 if (deadq_removebypid(pid)) 1604 continue; 1605 1606 /* Now, look in list of active processes. */ 1607 STAILQ_FOREACH(f, &fhead, next) { 1608 if (f->f_type == F_PIPE && 1609 f->fu_pipe_pid == pid) { 1610 close_filed(f); 1611 log_deadchild(pid, status, f->fu_pipe_pname); 1612 break; 1613 } 1614 } 1615 } 1616 WantReapchild = 0; 1617 } 1618 1619 /* 1620 * Return a printable representation of a host address. 1621 */ 1622 static const char * 1623 cvthname(struct sockaddr *f) 1624 { 1625 int error, hl; 1626 static char hname[NI_MAXHOST], ip[NI_MAXHOST]; 1627 1628 dprintf("cvthname(%d) len = %d\n", f->sa_family, f->sa_len); 1629 error = getnameinfo(f, f->sa_len, ip, sizeof(ip), NULL, 0, 1630 NI_NUMERICHOST); 1631 if (error) { 1632 dprintf("Malformed from address %s\n", gai_strerror(error)); 1633 return ("???"); 1634 } 1635 dprintf("cvthname(%s)\n", ip); 1636 1637 if (!resolve) 1638 return (ip); 1639 1640 error = getnameinfo(f, f->sa_len, hname, sizeof(hname), 1641 NULL, 0, NI_NAMEREQD); 1642 if (error) { 1643 dprintf("Host name for your address (%s) unknown\n", ip); 1644 return (ip); 1645 } 1646 hl = strlen(hname); 1647 if (hl > 0 && hname[hl-1] == '.') 1648 hname[--hl] = '\0'; 1649 trimdomain(hname, hl); 1650 return (hname); 1651 } 1652 1653 static void 1654 dodie(int signo) 1655 { 1656 1657 WantDie = signo; 1658 } 1659 1660 static void 1661 domark(int signo __unused) 1662 { 1663 1664 MarkSet = 1; 1665 } 1666 1667 /* 1668 * Print syslogd errors some place. 1669 */ 1670 static void 1671 logerror(const char *type) 1672 { 1673 char buf[512]; 1674 static int recursed = 0; 1675 1676 /* If there's an error while trying to log an error, give up. */ 1677 if (recursed) 1678 return; 1679 recursed++; 1680 if (errno) 1681 (void)snprintf(buf, 1682 sizeof buf, "syslogd: %s: %s", type, strerror(errno)); 1683 else 1684 (void)snprintf(buf, sizeof buf, "syslogd: %s", type); 1685 errno = 0; 1686 dprintf("%s\n", buf); 1687 logmsg(LOG_SYSLOG|LOG_ERR, NULL, buf, LocalHostName, 0); 1688 recursed--; 1689 } 1690 1691 static void 1692 die(int signo) 1693 { 1694 struct filed *f; 1695 struct socklist *sl; 1696 char buf[100]; 1697 1698 STAILQ_FOREACH(f, &fhead, next) { 1699 /* flush any pending output */ 1700 if (f->f_prevcount) 1701 fprintlog(f, 0, (char *)NULL); 1702 if (f->f_type == F_PIPE && f->fu_pipe_pid > 0) 1703 close_filed(f); 1704 } 1705 if (signo) { 1706 dprintf("syslogd: exiting on signal %d\n", signo); 1707 (void)snprintf(buf, sizeof(buf), "exiting on signal %d", signo); 1708 errno = 0; 1709 logerror(buf); 1710 } 1711 STAILQ_FOREACH(sl, &shead, next) { 1712 if (sl->sl_ss.ss_family == AF_LOCAL) 1713 unlink(sl->sl_peer->pe_name); 1714 } 1715 pidfile_remove(pfh); 1716 1717 exit(1); 1718 } 1719 1720 static int 1721 configfiles(const struct dirent *dp) 1722 { 1723 const char *p; 1724 size_t ext_len; 1725 1726 if (dp->d_name[0] == '.') 1727 return (0); 1728 1729 ext_len = sizeof(include_ext) -1; 1730 1731 if (dp->d_namlen <= ext_len) 1732 return (0); 1733 1734 p = &dp->d_name[dp->d_namlen - ext_len]; 1735 if (strcmp(p, include_ext) != 0) 1736 return (0); 1737 1738 return (1); 1739 } 1740 1741 static void 1742 readconfigfile(FILE *cf, int allow_includes) 1743 { 1744 FILE *cf2; 1745 struct filed *f; 1746 struct dirent **ent; 1747 char cline[LINE_MAX]; 1748 char host[MAXHOSTNAMELEN]; 1749 char prog[LINE_MAX]; 1750 char file[MAXPATHLEN]; 1751 char *p, *tmp; 1752 int i, nents; 1753 size_t include_len; 1754 1755 /* 1756 * Foreach line in the conf table, open that file. 1757 */ 1758 include_len = sizeof(include_str) -1; 1759 (void)strlcpy(host, "*", sizeof(host)); 1760 (void)strlcpy(prog, "*", sizeof(prog)); 1761 while (fgets(cline, sizeof(cline), cf) != NULL) { 1762 /* 1763 * check for end-of-section, comments, strip off trailing 1764 * spaces and newline character. #!prog is treated specially: 1765 * following lines apply only to that program. 1766 */ 1767 for (p = cline; isspace(*p); ++p) 1768 continue; 1769 if (*p == 0) 1770 continue; 1771 if (allow_includes && 1772 strncmp(p, include_str, include_len) == 0 && 1773 isspace(p[include_len])) { 1774 p += include_len; 1775 while (isspace(*p)) 1776 p++; 1777 tmp = p; 1778 while (*tmp != '\0' && !isspace(*tmp)) 1779 tmp++; 1780 *tmp = '\0'; 1781 dprintf("Trying to include files in '%s'\n", p); 1782 nents = scandir(p, &ent, configfiles, alphasort); 1783 if (nents == -1) { 1784 dprintf("Unable to open '%s': %s\n", p, 1785 strerror(errno)); 1786 continue; 1787 } 1788 for (i = 0; i < nents; i++) { 1789 if (snprintf(file, sizeof(file), "%s/%s", p, 1790 ent[i]->d_name) >= (int)sizeof(file)) { 1791 dprintf("ignoring path too long: " 1792 "'%s/%s'\n", p, ent[i]->d_name); 1793 free(ent[i]); 1794 continue; 1795 } 1796 free(ent[i]); 1797 cf2 = fopen(file, "r"); 1798 if (cf2 == NULL) 1799 continue; 1800 dprintf("reading %s\n", file); 1801 readconfigfile(cf2, 0); 1802 fclose(cf2); 1803 } 1804 free(ent); 1805 continue; 1806 } 1807 if (*p == '#') { 1808 p++; 1809 if (*p != '!' && *p != '+' && *p != '-') 1810 continue; 1811 } 1812 if (*p == '+' || *p == '-') { 1813 host[0] = *p++; 1814 while (isspace(*p)) 1815 p++; 1816 if ((!*p) || (*p == '*')) { 1817 (void)strlcpy(host, "*", sizeof(host)); 1818 continue; 1819 } 1820 if (*p == '@') 1821 p = LocalHostName; 1822 for (i = 1; i < MAXHOSTNAMELEN - 1; i++) { 1823 if (!isalnum(*p) && *p != '.' && *p != '-' 1824 && *p != ',' && *p != ':' && *p != '%') 1825 break; 1826 host[i] = *p++; 1827 } 1828 host[i] = '\0'; 1829 continue; 1830 } 1831 if (*p == '!') { 1832 p++; 1833 while (isspace(*p)) p++; 1834 if ((!*p) || (*p == '*')) { 1835 (void)strlcpy(prog, "*", sizeof(prog)); 1836 continue; 1837 } 1838 for (i = 0; i < LINE_MAX - 1; i++) { 1839 if (!isprint(p[i]) || isspace(p[i])) 1840 break; 1841 prog[i] = p[i]; 1842 } 1843 prog[i] = 0; 1844 continue; 1845 } 1846 for (p = cline + 1; *p != '\0'; p++) { 1847 if (*p != '#') 1848 continue; 1849 if (*(p - 1) == '\\') { 1850 strcpy(p - 1, p); 1851 p--; 1852 continue; 1853 } 1854 *p = '\0'; 1855 break; 1856 } 1857 for (i = strlen(cline) - 1; i >= 0 && isspace(cline[i]); i--) 1858 cline[i] = '\0'; 1859 f = cfline(cline, prog, host); 1860 if (f != NULL) 1861 addfile(f); 1862 } 1863 } 1864 1865 static void 1866 sighandler(int signo) 1867 { 1868 1869 /* Send an wake-up signal to the select() loop. */ 1870 write(sigpipe[1], &signo, sizeof(signo)); 1871 } 1872 1873 /* 1874 * INIT -- Initialize syslogd from configuration table 1875 */ 1876 static void 1877 init(int signo) 1878 { 1879 int i; 1880 FILE *cf; 1881 struct filed *f; 1882 char *p; 1883 char oldLocalHostName[MAXHOSTNAMELEN]; 1884 char hostMsg[2*MAXHOSTNAMELEN+40]; 1885 char bootfileMsg[LINE_MAX]; 1886 1887 dprintf("init\n"); 1888 WantInitialize = 0; 1889 1890 /* 1891 * Load hostname (may have changed). 1892 */ 1893 if (signo != 0) 1894 (void)strlcpy(oldLocalHostName, LocalHostName, 1895 sizeof(oldLocalHostName)); 1896 if (gethostname(LocalHostName, sizeof(LocalHostName))) 1897 err(EX_OSERR, "gethostname() failed"); 1898 if ((p = strchr(LocalHostName, '.')) != NULL) { 1899 *p++ = '\0'; 1900 LocalDomain = p; 1901 } else { 1902 LocalDomain = ""; 1903 } 1904 1905 /* 1906 * Load / reload timezone data (in case it changed). 1907 * 1908 * Just calling tzset() again does not work, the timezone code 1909 * caches the result. However, by setting the TZ variable, one 1910 * can defeat the caching and have the timezone code really 1911 * reload the timezone data. Respect any initial setting of 1912 * TZ, in case the system is configured specially. 1913 */ 1914 dprintf("loading timezone data via tzset()\n"); 1915 if (getenv("TZ")) { 1916 tzset(); 1917 } else { 1918 setenv("TZ", ":/etc/localtime", 1); 1919 tzset(); 1920 unsetenv("TZ"); 1921 } 1922 1923 /* 1924 * Close all open log files. 1925 */ 1926 Initialized = 0; 1927 STAILQ_FOREACH(f, &fhead, next) { 1928 /* flush any pending output */ 1929 if (f->f_prevcount) 1930 fprintlog(f, 0, (char *)NULL); 1931 1932 switch (f->f_type) { 1933 case F_FILE: 1934 case F_FORW: 1935 case F_CONSOLE: 1936 case F_TTY: 1937 close_filed(f); 1938 break; 1939 case F_PIPE: 1940 deadq_enter(f->fu_pipe_pid, f->fu_pipe_pname); 1941 close_filed(f); 1942 break; 1943 } 1944 } 1945 while(!STAILQ_EMPTY(&fhead)) { 1946 f = STAILQ_FIRST(&fhead); 1947 STAILQ_REMOVE_HEAD(&fhead, next); 1948 free(f->f_program); 1949 free(f->f_host); 1950 free(f); 1951 } 1952 1953 /* open the configuration file */ 1954 if ((cf = fopen(ConfFile, "r")) == NULL) { 1955 dprintf("cannot open %s\n", ConfFile); 1956 f = cfline("*.ERR\t/dev/console", "*", "*"); 1957 if (f != NULL) 1958 addfile(f); 1959 f = cfline("*.PANIC\t*", "*", "*"); 1960 if (f != NULL) 1961 addfile(f); 1962 Initialized = 1; 1963 1964 return; 1965 } 1966 1967 readconfigfile(cf, 1); 1968 1969 /* close the configuration file */ 1970 (void)fclose(cf); 1971 1972 Initialized = 1; 1973 1974 if (Debug) { 1975 int port; 1976 STAILQ_FOREACH(f, &fhead, next) { 1977 for (i = 0; i <= LOG_NFACILITIES; i++) 1978 if (f->f_pmask[i] == INTERNAL_NOPRI) 1979 printf("X "); 1980 else 1981 printf("%d ", f->f_pmask[i]); 1982 printf("%s: ", TypeNames[f->f_type]); 1983 switch (f->f_type) { 1984 case F_FILE: 1985 printf("%s", f->fu_fname); 1986 break; 1987 1988 case F_CONSOLE: 1989 case F_TTY: 1990 printf("%s%s", _PATH_DEV, f->fu_fname); 1991 break; 1992 1993 case F_FORW: 1994 switch (f->fu_forw_addr->ai_addr->sa_family) { 1995 #ifdef INET 1996 case AF_INET: 1997 port = ntohs(satosin(f->fu_forw_addr->ai_addr)->sin_port); 1998 break; 1999 #endif 2000 #ifdef INET6 2001 case AF_INET6: 2002 port = ntohs(satosin6(f->fu_forw_addr->ai_addr)->sin6_port); 2003 break; 2004 #endif 2005 default: 2006 port = 0; 2007 } 2008 if (port != 514) { 2009 printf("%s:%d", 2010 f->fu_forw_hname, port); 2011 } else { 2012 printf("%s", f->fu_forw_hname); 2013 } 2014 break; 2015 2016 case F_PIPE: 2017 printf("%s", f->fu_pipe_pname); 2018 break; 2019 2020 case F_USERS: 2021 for (i = 0; i < MAXUNAMES && *f->fu_uname[i]; i++) 2022 printf("%s, ", f->fu_uname[i]); 2023 break; 2024 } 2025 if (f->f_program) 2026 printf(" (%s)", f->f_program); 2027 printf("\n"); 2028 } 2029 } 2030 2031 logmsg(LOG_SYSLOG|LOG_INFO, NULL, "syslogd: restart", LocalHostName, 0); 2032 dprintf("syslogd: restarted\n"); 2033 /* 2034 * Log a change in hostname, but only on a restart. 2035 */ 2036 if (signo != 0 && strcmp(oldLocalHostName, LocalHostName) != 0) { 2037 (void)snprintf(hostMsg, sizeof(hostMsg), 2038 "syslogd: hostname changed, \"%s\" to \"%s\"", 2039 oldLocalHostName, LocalHostName); 2040 logmsg(LOG_SYSLOG|LOG_INFO, NULL, hostMsg, LocalHostName, 0); 2041 dprintf("%s\n", hostMsg); 2042 } 2043 /* 2044 * Log the kernel boot file if we aren't going to use it as 2045 * the prefix, and if this is *not* a restart. 2046 */ 2047 if (signo == 0 && !use_bootfile) { 2048 (void)snprintf(bootfileMsg, sizeof(bootfileMsg), 2049 "syslogd: kernel boot file is %s", bootfile); 2050 logmsg(LOG_KERN|LOG_INFO, NULL, bootfileMsg, LocalHostName, 0); 2051 dprintf("%s\n", bootfileMsg); 2052 } 2053 } 2054 2055 /* 2056 * Crack a configuration file line 2057 */ 2058 static struct filed * 2059 cfline(const char *line, const char *prog, const char *host) 2060 { 2061 struct filed *f; 2062 struct addrinfo hints, *res; 2063 int error, i, pri, syncfile; 2064 const char *p, *q; 2065 char *bp; 2066 char buf[MAXLINE], ebuf[100]; 2067 2068 dprintf("cfline(\"%s\", f, \"%s\", \"%s\")\n", line, prog, host); 2069 2070 f = calloc(1, sizeof(*f)); 2071 if (f == NULL) { 2072 logerror("malloc"); 2073 exit(1); 2074 } 2075 errno = 0; /* keep strerror() stuff out of logerror messages */ 2076 2077 for (i = 0; i <= LOG_NFACILITIES; i++) 2078 f->f_pmask[i] = INTERNAL_NOPRI; 2079 2080 /* save hostname if any */ 2081 if (host && *host == '*') 2082 host = NULL; 2083 if (host) { 2084 int hl; 2085 2086 f->f_host = strdup(host); 2087 if (f->f_host == NULL) { 2088 logerror("strdup"); 2089 exit(1); 2090 } 2091 hl = strlen(f->f_host); 2092 if (hl > 0 && f->f_host[hl-1] == '.') 2093 f->f_host[--hl] = '\0'; 2094 trimdomain(f->f_host, hl); 2095 } 2096 2097 /* save program name if any */ 2098 if (prog && *prog == '*') 2099 prog = NULL; 2100 if (prog) { 2101 f->f_program = strdup(prog); 2102 if (f->f_program == NULL) { 2103 logerror("strdup"); 2104 exit(1); 2105 } 2106 } 2107 2108 /* scan through the list of selectors */ 2109 for (p = line; *p && *p != '\t' && *p != ' ';) { 2110 int pri_done; 2111 int pri_cmp; 2112 int pri_invert; 2113 2114 /* find the end of this facility name list */ 2115 for (q = p; *q && *q != '\t' && *q != ' ' && *q++ != '.'; ) 2116 continue; 2117 2118 /* get the priority comparison */ 2119 pri_cmp = 0; 2120 pri_done = 0; 2121 pri_invert = 0; 2122 if (*q == '!') { 2123 pri_invert = 1; 2124 q++; 2125 } 2126 while (!pri_done) { 2127 switch (*q) { 2128 case '<': 2129 pri_cmp |= PRI_LT; 2130 q++; 2131 break; 2132 case '=': 2133 pri_cmp |= PRI_EQ; 2134 q++; 2135 break; 2136 case '>': 2137 pri_cmp |= PRI_GT; 2138 q++; 2139 break; 2140 default: 2141 pri_done++; 2142 break; 2143 } 2144 } 2145 2146 /* collect priority name */ 2147 for (bp = buf; *q && !strchr("\t,; ", *q); ) 2148 *bp++ = *q++; 2149 *bp = '\0'; 2150 2151 /* skip cruft */ 2152 while (strchr(",;", *q)) 2153 q++; 2154 2155 /* decode priority name */ 2156 if (*buf == '*') { 2157 pri = LOG_PRIMASK; 2158 pri_cmp = PRI_LT | PRI_EQ | PRI_GT; 2159 } else { 2160 /* Ignore trailing spaces. */ 2161 for (i = strlen(buf) - 1; i >= 0 && buf[i] == ' '; i--) 2162 buf[i] = '\0'; 2163 2164 pri = decode(buf, prioritynames); 2165 if (pri < 0) { 2166 errno = 0; 2167 (void)snprintf(ebuf, sizeof ebuf, 2168 "unknown priority name \"%s\"", buf); 2169 logerror(ebuf); 2170 free(f); 2171 return (NULL); 2172 } 2173 } 2174 if (!pri_cmp) 2175 pri_cmp = (UniquePriority) 2176 ? (PRI_EQ) 2177 : (PRI_EQ | PRI_GT) 2178 ; 2179 if (pri_invert) 2180 pri_cmp ^= PRI_LT | PRI_EQ | PRI_GT; 2181 2182 /* scan facilities */ 2183 while (*p && !strchr("\t.; ", *p)) { 2184 for (bp = buf; *p && !strchr("\t,;. ", *p); ) 2185 *bp++ = *p++; 2186 *bp = '\0'; 2187 2188 if (*buf == '*') { 2189 for (i = 0; i < LOG_NFACILITIES; i++) { 2190 f->f_pmask[i] = pri; 2191 f->f_pcmp[i] = pri_cmp; 2192 } 2193 } else { 2194 i = decode(buf, facilitynames); 2195 if (i < 0) { 2196 errno = 0; 2197 (void)snprintf(ebuf, sizeof ebuf, 2198 "unknown facility name \"%s\"", 2199 buf); 2200 logerror(ebuf); 2201 free(f); 2202 return (NULL); 2203 } 2204 f->f_pmask[i >> 3] = pri; 2205 f->f_pcmp[i >> 3] = pri_cmp; 2206 } 2207 while (*p == ',' || *p == ' ') 2208 p++; 2209 } 2210 2211 p = q; 2212 } 2213 2214 /* skip to action part */ 2215 while (*p == '\t' || *p == ' ') 2216 p++; 2217 2218 if (*p == '-') { 2219 syncfile = 0; 2220 p++; 2221 } else 2222 syncfile = 1; 2223 2224 switch (*p) { 2225 case '@': 2226 { 2227 char *tp; 2228 char endkey = ':'; 2229 /* 2230 * scan forward to see if there is a port defined. 2231 * so we can't use strlcpy.. 2232 */ 2233 i = sizeof(f->fu_forw_hname); 2234 tp = f->fu_forw_hname; 2235 p++; 2236 2237 /* 2238 * an ipv6 address should start with a '[' in that case 2239 * we should scan for a ']' 2240 */ 2241 if (*p == '[') { 2242 p++; 2243 endkey = ']'; 2244 } 2245 while (*p && (*p != endkey) && (i-- > 0)) { 2246 *tp++ = *p++; 2247 } 2248 if (endkey == ']' && *p == endkey) 2249 p++; 2250 *tp = '\0'; 2251 } 2252 /* See if we copied a domain and have a port */ 2253 if (*p == ':') 2254 p++; 2255 else 2256 p = NULL; 2257 2258 hints = (struct addrinfo){ 2259 .ai_family = family, 2260 .ai_socktype = SOCK_DGRAM 2261 }; 2262 error = getaddrinfo(f->fu_forw_hname, 2263 p ? p : "syslog", &hints, &res); 2264 if (error) { 2265 logerror(gai_strerror(error)); 2266 break; 2267 } 2268 f->fu_forw_addr = res; 2269 f->f_type = F_FORW; 2270 break; 2271 2272 case '/': 2273 if ((f->f_file = open(p, logflags, 0600)) < 0) { 2274 f->f_type = F_UNUSED; 2275 logerror(p); 2276 break; 2277 } 2278 if (syncfile) 2279 f->f_flags |= FFLAG_SYNC; 2280 if (isatty(f->f_file)) { 2281 if (strcmp(p, ctty) == 0) 2282 f->f_type = F_CONSOLE; 2283 else 2284 f->f_type = F_TTY; 2285 (void)strlcpy(f->fu_fname, p + sizeof(_PATH_DEV) - 1, 2286 sizeof(f->fu_fname)); 2287 } else { 2288 (void)strlcpy(f->fu_fname, p, sizeof(f->fu_fname)); 2289 f->f_type = F_FILE; 2290 } 2291 break; 2292 2293 case '|': 2294 f->fu_pipe_pid = 0; 2295 (void)strlcpy(f->fu_pipe_pname, p + 1, 2296 sizeof(f->fu_pipe_pname)); 2297 f->f_type = F_PIPE; 2298 break; 2299 2300 case '*': 2301 f->f_type = F_WALL; 2302 break; 2303 2304 default: 2305 for (i = 0; i < MAXUNAMES && *p; i++) { 2306 for (q = p; *q && *q != ','; ) 2307 q++; 2308 (void)strncpy(f->fu_uname[i], p, MAXLOGNAME - 1); 2309 if ((q - p) >= MAXLOGNAME) 2310 f->fu_uname[i][MAXLOGNAME - 1] = '\0'; 2311 else 2312 f->fu_uname[i][q - p] = '\0'; 2313 while (*q == ',' || *q == ' ') 2314 q++; 2315 p = q; 2316 } 2317 f->f_type = F_USERS; 2318 break; 2319 } 2320 return (f); 2321 } 2322 2323 2324 /* 2325 * Decode a symbolic name to a numeric value 2326 */ 2327 static int 2328 decode(const char *name, const CODE *codetab) 2329 { 2330 const CODE *c; 2331 char *p, buf[40]; 2332 2333 if (isdigit(*name)) 2334 return (atoi(name)); 2335 2336 for (p = buf; *name && p < &buf[sizeof(buf) - 1]; p++, name++) { 2337 if (isupper(*name)) 2338 *p = tolower(*name); 2339 else 2340 *p = *name; 2341 } 2342 *p = '\0'; 2343 for (c = codetab; c->c_name; c++) 2344 if (!strcmp(buf, c->c_name)) 2345 return (c->c_val); 2346 2347 return (-1); 2348 } 2349 2350 static void 2351 markit(void) 2352 { 2353 struct filed *f; 2354 struct deadq_entry *dq, *dq0; 2355 2356 now = time((time_t *)NULL); 2357 MarkSeq += TIMERINTVL; 2358 if (MarkSeq >= MarkInterval) { 2359 logmsg(LOG_INFO, NULL, "-- MARK --", LocalHostName, MARK); 2360 MarkSeq = 0; 2361 } 2362 2363 STAILQ_FOREACH(f, &fhead, next) { 2364 if (f->f_prevcount && now >= REPEATTIME(f)) { 2365 dprintf("flush %s: repeated %d times, %d sec.\n", 2366 TypeNames[f->f_type], f->f_prevcount, 2367 repeatinterval[f->f_repeatcount]); 2368 fprintlog(f, 0, (char *)NULL); 2369 BACKOFF(f); 2370 } 2371 } 2372 2373 /* Walk the dead queue, and see if we should signal somebody. */ 2374 TAILQ_FOREACH_SAFE(dq, &deadq_head, dq_entries, dq0) { 2375 switch (dq->dq_timeout) { 2376 case 0: 2377 /* Already signalled once, try harder now. */ 2378 if (kill(dq->dq_pid, SIGKILL) != 0) 2379 (void)deadq_remove(dq); 2380 break; 2381 2382 case 1: 2383 /* 2384 * Timed out on dead queue, send terminate 2385 * signal. Note that we leave the removal 2386 * from the dead queue to reapchild(), which 2387 * will also log the event (unless the process 2388 * didn't even really exist, in case we simply 2389 * drop it from the dead queue). 2390 */ 2391 if (kill(dq->dq_pid, SIGTERM) != 0) 2392 (void)deadq_remove(dq); 2393 else 2394 dq->dq_timeout--; 2395 break; 2396 default: 2397 dq->dq_timeout--; 2398 } 2399 } 2400 MarkSet = 0; 2401 (void)alarm(TIMERINTVL); 2402 } 2403 2404 /* 2405 * fork off and become a daemon, but wait for the child to come online 2406 * before returning to the parent, or we get disk thrashing at boot etc. 2407 * Set a timer so we don't hang forever if it wedges. 2408 */ 2409 static int 2410 waitdaemon(int maxwait) 2411 { 2412 int fd; 2413 int status; 2414 pid_t pid, childpid; 2415 2416 switch (childpid = fork()) { 2417 case -1: 2418 return (-1); 2419 case 0: 2420 break; 2421 default: 2422 signal(SIGALRM, timedout); 2423 alarm(maxwait); 2424 while ((pid = wait3(&status, 0, NULL)) != -1) { 2425 if (WIFEXITED(status)) 2426 errx(1, "child pid %d exited with return code %d", 2427 pid, WEXITSTATUS(status)); 2428 if (WIFSIGNALED(status)) 2429 errx(1, "child pid %d exited on signal %d%s", 2430 pid, WTERMSIG(status), 2431 WCOREDUMP(status) ? " (core dumped)" : 2432 ""); 2433 if (pid == childpid) /* it's gone... */ 2434 break; 2435 } 2436 exit(0); 2437 } 2438 2439 if (setsid() == -1) 2440 return (-1); 2441 2442 (void)chdir("/"); 2443 if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { 2444 (void)dup2(fd, STDIN_FILENO); 2445 (void)dup2(fd, STDOUT_FILENO); 2446 (void)dup2(fd, STDERR_FILENO); 2447 if (fd > STDERR_FILENO) 2448 (void)close(fd); 2449 } 2450 return (getppid()); 2451 } 2452 2453 /* 2454 * We get a SIGALRM from the child when it's running and finished doing it's 2455 * fsync()'s or O_SYNC writes for all the boot messages. 2456 * 2457 * We also get a signal from the kernel if the timer expires, so check to 2458 * see what happened. 2459 */ 2460 static void 2461 timedout(int sig __unused) 2462 { 2463 int left; 2464 left = alarm(0); 2465 signal(SIGALRM, SIG_DFL); 2466 if (left == 0) 2467 errx(1, "timed out waiting for child"); 2468 else 2469 _exit(0); 2470 } 2471 2472 /* 2473 * Add `s' to the list of allowable peer addresses to accept messages 2474 * from. 2475 * 2476 * `s' is a string in the form: 2477 * 2478 * [*]domainname[:{servicename|portnumber|*}] 2479 * 2480 * or 2481 * 2482 * netaddr/maskbits[:{servicename|portnumber|*}] 2483 * 2484 * Returns -1 on error, 0 if the argument was valid. 2485 */ 2486 static int 2487 allowaddr(char *s) 2488 { 2489 #if defined(INET) || defined(INET6) 2490 char *cp1, *cp2; 2491 struct allowedpeer *ap; 2492 struct servent *se; 2493 int masklen = -1; 2494 struct addrinfo hints, *res = NULL; 2495 #ifdef INET 2496 in_addr_t *addrp, *maskp; 2497 #endif 2498 #ifdef INET6 2499 uint32_t *addr6p, *mask6p; 2500 #endif 2501 char ip[NI_MAXHOST]; 2502 2503 ap = calloc(1, sizeof(*ap)); 2504 if (ap == NULL) 2505 err(1, "malloc failed"); 2506 2507 #ifdef INET6 2508 if (*s != '[' || (cp1 = strchr(s + 1, ']')) == NULL) 2509 #endif 2510 cp1 = s; 2511 if ((cp1 = strrchr(cp1, ':'))) { 2512 /* service/port provided */ 2513 *cp1++ = '\0'; 2514 if (strlen(cp1) == 1 && *cp1 == '*') 2515 /* any port allowed */ 2516 ap->port = 0; 2517 else if ((se = getservbyname(cp1, "udp"))) { 2518 ap->port = ntohs(se->s_port); 2519 } else { 2520 ap->port = strtol(cp1, &cp2, 0); 2521 /* port not numeric */ 2522 if (*cp2 != '\0') 2523 goto err; 2524 } 2525 } else { 2526 if ((se = getservbyname("syslog", "udp"))) 2527 ap->port = ntohs(se->s_port); 2528 else 2529 /* sanity, should not happen */ 2530 ap->port = 514; 2531 } 2532 2533 if ((cp1 = strchr(s, '/')) != NULL && 2534 strspn(cp1 + 1, "0123456789") == strlen(cp1 + 1)) { 2535 *cp1 = '\0'; 2536 if ((masklen = atoi(cp1 + 1)) < 0) 2537 goto err; 2538 } 2539 #ifdef INET6 2540 if (*s == '[') { 2541 cp2 = s + strlen(s) - 1; 2542 if (*cp2 == ']') { 2543 ++s; 2544 *cp2 = '\0'; 2545 } else { 2546 cp2 = NULL; 2547 } 2548 } else { 2549 cp2 = NULL; 2550 } 2551 #endif 2552 hints = (struct addrinfo){ 2553 .ai_family = PF_UNSPEC, 2554 .ai_socktype = SOCK_DGRAM, 2555 .ai_flags = AI_PASSIVE | AI_NUMERICHOST 2556 }; 2557 if (getaddrinfo(s, NULL, &hints, &res) == 0) { 2558 ap->isnumeric = 1; 2559 memcpy(&ap->a_addr, res->ai_addr, res->ai_addrlen); 2560 ap->a_mask = (struct sockaddr_storage){ 2561 .ss_family = res->ai_family, 2562 .ss_len = res->ai_addrlen 2563 }; 2564 switch (res->ai_family) { 2565 #ifdef INET 2566 case AF_INET: 2567 maskp = &sstosin(&ap->a_mask)->sin_addr.s_addr; 2568 addrp = &sstosin(&ap->a_addr)->sin_addr.s_addr; 2569 if (masklen < 0) { 2570 /* use default netmask */ 2571 if (IN_CLASSA(ntohl(*addrp))) 2572 *maskp = htonl(IN_CLASSA_NET); 2573 else if (IN_CLASSB(ntohl(*addrp))) 2574 *maskp = htonl(IN_CLASSB_NET); 2575 else 2576 *maskp = htonl(IN_CLASSC_NET); 2577 } else if (masklen == 0) { 2578 *maskp = 0; 2579 } else if (masklen <= 32) { 2580 /* convert masklen to netmask */ 2581 *maskp = htonl(~((1 << (32 - masklen)) - 1)); 2582 } else { 2583 goto err; 2584 } 2585 /* Lose any host bits in the network number. */ 2586 *addrp &= *maskp; 2587 break; 2588 #endif 2589 #ifdef INET6 2590 case AF_INET6: 2591 if (masklen > 128) 2592 goto err; 2593 2594 if (masklen < 0) 2595 masklen = 128; 2596 mask6p = (uint32_t *)&sstosin6(&ap->a_mask)->sin6_addr.s6_addr32[0]; 2597 addr6p = (uint32_t *)&sstosin6(&ap->a_addr)->sin6_addr.s6_addr32[0]; 2598 /* convert masklen to netmask */ 2599 while (masklen > 0) { 2600 if (masklen < 32) { 2601 *mask6p = 2602 htonl(~(0xffffffff >> masklen)); 2603 *addr6p &= *mask6p; 2604 break; 2605 } else { 2606 *mask6p++ = 0xffffffff; 2607 addr6p++; 2608 masklen -= 32; 2609 } 2610 } 2611 break; 2612 #endif 2613 default: 2614 goto err; 2615 } 2616 freeaddrinfo(res); 2617 } else { 2618 /* arg `s' is domain name */ 2619 ap->isnumeric = 0; 2620 ap->a_name = s; 2621 if (cp1) 2622 *cp1 = '/'; 2623 #ifdef INET6 2624 if (cp2) { 2625 *cp2 = ']'; 2626 --s; 2627 } 2628 #endif 2629 } 2630 STAILQ_INSERT_TAIL(&aphead, ap, next); 2631 2632 if (Debug) { 2633 printf("allowaddr: rule "); 2634 if (ap->isnumeric) { 2635 printf("numeric, "); 2636 getnameinfo(sstosa(&ap->a_addr), 2637 (sstosa(&ap->a_addr))->sa_len, 2638 ip, sizeof ip, NULL, 0, NI_NUMERICHOST); 2639 printf("addr = %s, ", ip); 2640 getnameinfo(sstosa(&ap->a_mask), 2641 (sstosa(&ap->a_mask))->sa_len, 2642 ip, sizeof ip, NULL, 0, NI_NUMERICHOST); 2643 printf("mask = %s; ", ip); 2644 } else { 2645 printf("domainname = %s; ", ap->a_name); 2646 } 2647 printf("port = %d\n", ap->port); 2648 } 2649 #endif 2650 2651 return (0); 2652 err: 2653 if (res != NULL) 2654 freeaddrinfo(res); 2655 free(ap); 2656 return (-1); 2657 } 2658 2659 /* 2660 * Validate that the remote peer has permission to log to us. 2661 */ 2662 static int 2663 validate(struct sockaddr *sa, const char *hname) 2664 { 2665 int i; 2666 char name[NI_MAXHOST], ip[NI_MAXHOST], port[NI_MAXSERV]; 2667 struct allowedpeer *ap; 2668 #ifdef INET 2669 struct sockaddr_in *sin4, *a4p = NULL, *m4p = NULL; 2670 #endif 2671 #ifdef INET6 2672 struct sockaddr_in6 *sin6, *a6p = NULL, *m6p = NULL; 2673 #endif 2674 struct addrinfo hints, *res; 2675 u_short sport; 2676 int num = 0; 2677 2678 STAILQ_FOREACH(ap, &aphead, next) { 2679 num++; 2680 } 2681 dprintf("# of validation rule: %d\n", num); 2682 if (num == 0) 2683 /* traditional behaviour, allow everything */ 2684 return (1); 2685 2686 (void)strlcpy(name, hname, sizeof(name)); 2687 hints = (struct addrinfo){ 2688 .ai_family = PF_UNSPEC, 2689 .ai_socktype = SOCK_DGRAM, 2690 .ai_flags = AI_PASSIVE | AI_NUMERICHOST 2691 }; 2692 if (getaddrinfo(name, NULL, &hints, &res) == 0) 2693 freeaddrinfo(res); 2694 else if (strchr(name, '.') == NULL) { 2695 strlcat(name, ".", sizeof name); 2696 strlcat(name, LocalDomain, sizeof name); 2697 } 2698 if (getnameinfo(sa, sa->sa_len, ip, sizeof(ip), port, sizeof(port), 2699 NI_NUMERICHOST | NI_NUMERICSERV) != 0) 2700 return (0); /* for safety, should not occur */ 2701 dprintf("validate: dgram from IP %s, port %s, name %s;\n", 2702 ip, port, name); 2703 sport = atoi(port); 2704 2705 /* now, walk down the list */ 2706 i = 0; 2707 STAILQ_FOREACH(ap, &aphead, next) { 2708 i++; 2709 if (ap->port != 0 && ap->port != sport) { 2710 dprintf("rejected in rule %d due to port mismatch.\n", 2711 i); 2712 continue; 2713 } 2714 2715 if (ap->isnumeric) { 2716 if (ap->a_addr.ss_family != sa->sa_family) { 2717 dprintf("rejected in rule %d due to address family mismatch.\n", i); 2718 continue; 2719 } 2720 #ifdef INET 2721 else if (ap->a_addr.ss_family == AF_INET) { 2722 sin4 = satosin(sa); 2723 a4p = satosin(&ap->a_addr); 2724 m4p = satosin(&ap->a_mask); 2725 if ((sin4->sin_addr.s_addr & m4p->sin_addr.s_addr) 2726 != a4p->sin_addr.s_addr) { 2727 dprintf("rejected in rule %d due to IP mismatch.\n", i); 2728 continue; 2729 } 2730 } 2731 #endif 2732 #ifdef INET6 2733 else if (ap->a_addr.ss_family == AF_INET6) { 2734 sin6 = satosin6(sa); 2735 a6p = satosin6(&ap->a_addr); 2736 m6p = satosin6(&ap->a_mask); 2737 if (a6p->sin6_scope_id != 0 && 2738 sin6->sin6_scope_id != a6p->sin6_scope_id) { 2739 dprintf("rejected in rule %d due to scope mismatch.\n", i); 2740 continue; 2741 } 2742 if (IN6_ARE_MASKED_ADDR_EQUAL(&sin6->sin6_addr, 2743 &a6p->sin6_addr, &m6p->sin6_addr) != 0) { 2744 dprintf("rejected in rule %d due to IP mismatch.\n", i); 2745 continue; 2746 } 2747 } 2748 #endif 2749 else 2750 continue; 2751 } else { 2752 if (fnmatch(ap->a_name, name, FNM_NOESCAPE) == 2753 FNM_NOMATCH) { 2754 dprintf("rejected in rule %d due to name " 2755 "mismatch.\n", i); 2756 continue; 2757 } 2758 } 2759 dprintf("accepted in rule %d.\n", i); 2760 return (1); /* hooray! */ 2761 } 2762 return (0); 2763 } 2764 2765 /* 2766 * Fairly similar to popen(3), but returns an open descriptor, as 2767 * opposed to a FILE *. 2768 */ 2769 static int 2770 p_open(const char *prog, pid_t *rpid) 2771 { 2772 int pfd[2], nulldesc; 2773 pid_t pid; 2774 char *argv[4]; /* sh -c cmd NULL */ 2775 char errmsg[200]; 2776 2777 if (pipe(pfd) == -1) 2778 return (-1); 2779 if ((nulldesc = open(_PATH_DEVNULL, O_RDWR)) == -1) 2780 /* we are royally screwed anyway */ 2781 return (-1); 2782 2783 switch ((pid = fork())) { 2784 case -1: 2785 close(nulldesc); 2786 return (-1); 2787 2788 case 0: 2789 (void)setsid(); /* Avoid catching SIGHUPs. */ 2790 argv[0] = strdup("sh"); 2791 argv[1] = strdup("-c"); 2792 argv[2] = strdup(prog); 2793 argv[3] = NULL; 2794 if (argv[0] == NULL || argv[1] == NULL || argv[2] == NULL) { 2795 logerror("strdup"); 2796 exit(1); 2797 } 2798 2799 alarm(0); 2800 2801 /* Restore signals marked as SIG_IGN. */ 2802 (void)signal(SIGINT, SIG_DFL); 2803 (void)signal(SIGQUIT, SIG_DFL); 2804 (void)signal(SIGPIPE, SIG_DFL); 2805 2806 dup2(pfd[0], STDIN_FILENO); 2807 dup2(nulldesc, STDOUT_FILENO); 2808 dup2(nulldesc, STDERR_FILENO); 2809 closefrom(STDERR_FILENO + 1); 2810 2811 (void)execvp(_PATH_BSHELL, argv); 2812 _exit(255); 2813 } 2814 close(nulldesc); 2815 close(pfd[0]); 2816 /* 2817 * Avoid blocking on a hung pipe. With O_NONBLOCK, we are 2818 * supposed to get an EWOULDBLOCK on writev(2), which is 2819 * caught by the logic above anyway, which will in turn close 2820 * the pipe, and fork a new logging subprocess if necessary. 2821 * The stale subprocess will be killed some time later unless 2822 * it terminated itself due to closing its input pipe (so we 2823 * get rid of really dead puppies). 2824 */ 2825 if (fcntl(pfd[1], F_SETFL, O_NONBLOCK) == -1) { 2826 /* This is bad. */ 2827 (void)snprintf(errmsg, sizeof errmsg, 2828 "Warning: cannot change pipe to PID %d to " 2829 "non-blocking behaviour.", 2830 (int)pid); 2831 logerror(errmsg); 2832 } 2833 *rpid = pid; 2834 return (pfd[1]); 2835 } 2836 2837 static void 2838 deadq_enter(pid_t pid, const char *name) 2839 { 2840 struct deadq_entry *dq; 2841 int status; 2842 2843 if (pid == 0) 2844 return; 2845 /* 2846 * Be paranoid, if we can't signal the process, don't enter it 2847 * into the dead queue (perhaps it's already dead). If possible, 2848 * we try to fetch and log the child's status. 2849 */ 2850 if (kill(pid, 0) != 0) { 2851 if (waitpid(pid, &status, WNOHANG) > 0) 2852 log_deadchild(pid, status, name); 2853 return; 2854 } 2855 2856 dq = malloc(sizeof(*dq)); 2857 if (dq == NULL) { 2858 logerror("malloc"); 2859 exit(1); 2860 } 2861 *dq = (struct deadq_entry){ 2862 .dq_pid = pid, 2863 .dq_timeout = DQ_TIMO_INIT 2864 }; 2865 TAILQ_INSERT_TAIL(&deadq_head, dq, dq_entries); 2866 } 2867 2868 static int 2869 deadq_remove(struct deadq_entry *dq) 2870 { 2871 if (dq != NULL) { 2872 TAILQ_REMOVE(&deadq_head, dq, dq_entries); 2873 free(dq); 2874 return (1); 2875 } 2876 2877 return (0); 2878 } 2879 2880 static int 2881 deadq_removebypid(pid_t pid) 2882 { 2883 struct deadq_entry *dq; 2884 2885 TAILQ_FOREACH(dq, &deadq_head, dq_entries) { 2886 if (dq->dq_pid == pid) 2887 break; 2888 } 2889 return (deadq_remove(dq)); 2890 } 2891 2892 static void 2893 log_deadchild(pid_t pid, int status, const char *name) 2894 { 2895 int code; 2896 char buf[256]; 2897 const char *reason; 2898 2899 errno = 0; /* Keep strerror() stuff out of logerror messages. */ 2900 if (WIFSIGNALED(status)) { 2901 reason = "due to signal"; 2902 code = WTERMSIG(status); 2903 } else { 2904 reason = "with status"; 2905 code = WEXITSTATUS(status); 2906 if (code == 0) 2907 return; 2908 } 2909 (void)snprintf(buf, sizeof buf, 2910 "Logging subprocess %d (%s) exited %s %d.", 2911 pid, name, reason, code); 2912 logerror(buf); 2913 } 2914 2915 static int 2916 socksetup(struct peer *pe) 2917 { 2918 struct addrinfo hints, *res, *res0; 2919 int error; 2920 char *cp; 2921 int (*sl_recv)(struct socklist *); 2922 /* 2923 * We have to handle this case for backwards compatibility: 2924 * If there are two (or more) colons but no '[' and ']', 2925 * assume this is an inet6 address without a service. 2926 */ 2927 if (pe->pe_name != NULL) { 2928 #ifdef INET6 2929 if (pe->pe_name[0] == '[' && 2930 (cp = strchr(pe->pe_name + 1, ']')) != NULL) { 2931 pe->pe_name = &pe->pe_name[1]; 2932 *cp = '\0'; 2933 if (cp[1] == ':' && cp[2] != '\0') 2934 pe->pe_serv = cp + 2; 2935 } else { 2936 #endif 2937 cp = strchr(pe->pe_name, ':'); 2938 if (cp != NULL && strchr(cp + 1, ':') == NULL) { 2939 *cp = '\0'; 2940 if (cp[1] != '\0') 2941 pe->pe_serv = cp + 1; 2942 if (cp == pe->pe_name) 2943 pe->pe_name = NULL; 2944 } 2945 #ifdef INET6 2946 } 2947 #endif 2948 } 2949 hints = (struct addrinfo){ 2950 .ai_family = AF_UNSPEC, 2951 .ai_socktype = SOCK_DGRAM, 2952 .ai_flags = AI_PASSIVE 2953 }; 2954 if (pe->pe_name != NULL) 2955 dprintf("Trying peer: %s\n", pe->pe_name); 2956 if (pe->pe_serv == NULL) 2957 pe->pe_serv = "syslog"; 2958 error = getaddrinfo(pe->pe_name, pe->pe_serv, &hints, &res0); 2959 if (error) { 2960 char *msgbuf; 2961 2962 asprintf(&msgbuf, "getaddrinfo failed for %s%s: %s", 2963 pe->pe_name == NULL ? "" : pe->pe_name, pe->pe_serv, 2964 gai_strerror(error)); 2965 errno = 0; 2966 if (msgbuf == NULL) 2967 logerror(gai_strerror(error)); 2968 else 2969 logerror(msgbuf); 2970 free(msgbuf); 2971 die(0); 2972 } 2973 for (res = res0; res != NULL; res = res->ai_next) { 2974 int s; 2975 2976 if (res->ai_family != AF_LOCAL && 2977 SecureMode > 1) { 2978 /* Only AF_LOCAL in secure mode. */ 2979 continue; 2980 } 2981 if (family != AF_UNSPEC && 2982 res->ai_family != AF_LOCAL && res->ai_family != family) 2983 continue; 2984 2985 s = socket(res->ai_family, res->ai_socktype, 2986 res->ai_protocol); 2987 if (s < 0) { 2988 logerror("socket"); 2989 error++; 2990 continue; 2991 } 2992 #ifdef INET6 2993 if (res->ai_family == AF_INET6) { 2994 if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, 2995 &(int){1}, sizeof(int)) < 0) { 2996 logerror("setsockopt(IPV6_V6ONLY)"); 2997 close(s); 2998 error++; 2999 continue; 3000 } 3001 } 3002 #endif 3003 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 3004 &(int){1}, sizeof(int)) < 0) { 3005 logerror("setsockopt(SO_REUSEADDR)"); 3006 close(s); 3007 error++; 3008 continue; 3009 } 3010 3011 /* 3012 * Bind INET and UNIX-domain sockets. 3013 * 3014 * A UNIX-domain socket is always bound to a pathname 3015 * regardless of -N flag. 3016 * 3017 * For INET sockets, RFC 3164 recommends that client 3018 * side message should come from the privileged syslogd port. 3019 * 3020 * If the system administrator chooses not to obey 3021 * this, we can skip the bind() step so that the 3022 * system will choose a port for us. 3023 */ 3024 if (res->ai_family == AF_LOCAL) 3025 unlink(pe->pe_name); 3026 if (res->ai_family == AF_LOCAL || 3027 NoBind == 0 || pe->pe_name != NULL) { 3028 if (bind(s, res->ai_addr, res->ai_addrlen) < 0) { 3029 logerror("bind"); 3030 close(s); 3031 error++; 3032 continue; 3033 } 3034 if (res->ai_family == AF_LOCAL || 3035 SecureMode == 0) 3036 increase_rcvbuf(s); 3037 } 3038 if (res->ai_family == AF_LOCAL && 3039 chmod(pe->pe_name, pe->pe_mode) < 0) { 3040 dprintf("chmod %s: %s\n", pe->pe_name, 3041 strerror(errno)); 3042 close(s); 3043 error++; 3044 continue; 3045 } 3046 dprintf("new socket fd is %d\n", s); 3047 if (res->ai_socktype != SOCK_DGRAM) { 3048 listen(s, 5); 3049 } 3050 sl_recv = socklist_recv_sock; 3051 #if defined(INET) || defined(INET6) 3052 if (SecureMode && (res->ai_family == AF_INET || 3053 res->ai_family == AF_INET6)) { 3054 dprintf("shutdown\n"); 3055 /* Forbid communication in secure mode. */ 3056 if (shutdown(s, SHUT_RD) < 0 && 3057 errno != ENOTCONN) { 3058 logerror("shutdown"); 3059 if (!Debug) 3060 die(0); 3061 } 3062 sl_recv = NULL; 3063 } else 3064 #endif 3065 dprintf("listening on socket\n"); 3066 dprintf("sending on socket\n"); 3067 addsock(res->ai_addr, res->ai_addrlen, 3068 &(struct socklist){ 3069 .sl_socket = s, 3070 .sl_peer = pe, 3071 .sl_recv = sl_recv 3072 }); 3073 } 3074 freeaddrinfo(res0); 3075 3076 return(error); 3077 } 3078 3079 static void 3080 increase_rcvbuf(int fd) 3081 { 3082 socklen_t len; 3083 3084 if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, 3085 &(socklen_t){sizeof(len)}) == 0) { 3086 if (len < RCVBUF_MINSIZE) { 3087 len = RCVBUF_MINSIZE; 3088 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len)); 3089 } 3090 } 3091 } 3092