--- embedaddon/dnsmasq/src/log.c 2013/07/29 19:37:40 1.1.1.1 +++ embedaddon/dnsmasq/src/log.c 2023/09/27 11:02:07 1.1.1.5 @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2013 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2022 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -100,10 +100,23 @@ int log_start(struct passwd *ent_pw, int errfd) /* If we're running as root and going to change uid later, change the ownership here so that the file is always owned by the dnsmasq user. Then logrotate can just copy the owner. - Failure of the chown call is OK, (for instance when started as non-root) */ - if (log_to_file && !log_stderr && ent_pw && ent_pw->pw_uid != 0 && - fchown(log_fd, ent_pw->pw_uid, -1) != 0) - ret = errno; + Failure of the chown call is OK, (for instance when started as non-root). + + If we've created a file with group-id root, we also make + the file group-writable. This gives processes in the root group + write access to the file and avoids the problem that on some systems, + once the file is owned by the dnsmasq user, it can't be written + whilst dnsmasq is running as root during startup. + */ + if (log_to_file && !log_stderr && ent_pw && ent_pw->pw_uid != 0) + { + struct stat ls; + if (getgid() == 0 && fstat(log_fd, &ls) == 0 && ls.st_gid == 0 && + (ls.st_mode & S_IWGRP) == 0) + (void)fchmod(log_fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP); + if (fchown(log_fd, ent_pw->pw_uid, -1) != 0) + ret = errno; + } return ret; } @@ -118,7 +131,7 @@ int log_reopen(char *log_file) /* NOTE: umask is set to 022 by the time this gets called */ if (log_file) - log_fd = open(log_file, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP); + log_fd = open(log_file, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP); else { #if defined(HAVE_SOLARIS_NETWORK) || defined(__ANDROID__) @@ -154,7 +167,7 @@ static void log_write(void) while (entries) { - /* The data in the payoad is written with a terminating zero character + /* The data in the payload is written with a terminating zero character and the length reflects this. For a stream connection we need to send the zero as a record terminator, but this isn't done for a datagram connection, so treat the length as one less than reality @@ -232,7 +245,7 @@ static void log_write(void) logaddr.sun_len = sizeof(logaddr) - sizeof(logaddr.sun_path) + strlen(_PATH_LOG) + 1; #endif logaddr.sun_family = AF_UNIX; - strncpy(logaddr.sun_path, _PATH_LOG, sizeof(logaddr.sun_path)); + safe_strncpy(logaddr.sun_path, _PATH_LOG, sizeof(logaddr.sun_path)); /* Got connection back? try again. */ if (connect(log_fd, (struct sockaddr *)&logaddr, sizeof(logaddr)) != -1) @@ -273,7 +286,7 @@ static void log_write(void) /* priority is one of LOG_DEBUG, LOG_INFO, LOG_NOTICE, etc. See sys/syslog.h. OR'd to priority can be MS_TFTP, MS_DHCP, ... to be able to do log separation between DNS, DHCP and TFTP services. -*/ + If OR'd with MS_DEBUG, the messages are suppressed unless --log-debug is set. */ void my_syslog(int priority, const char *format, ...) { va_list ap; @@ -288,7 +301,15 @@ void my_syslog(int priority, const char *format, ...) func = "-tftp"; else if ((LOG_FACMASK & priority) == MS_DHCP) func = "-dhcp"; - + else if ((LOG_FACMASK & priority) == MS_SCRIPT) + func = "-script"; + else if ((LOG_FACMASK & priority) == MS_DEBUG) + { + if (!option_bool(OPT_LOG_DEBUG)) + return; + func = "-debug"; + } + #ifdef LOG_PRI priority = LOG_PRI(priority); #else @@ -421,25 +442,22 @@ void my_syslog(int priority, const char *format, ...) } } -void set_log_writer(fd_set *set, int *maxfdp) +void set_log_writer(void) { if (entries && log_fd != -1 && connection_good) - { - FD_SET(log_fd, set); - bump_maxfd(log_fd, maxfdp); - } + poll_listen(log_fd, POLLOUT); } -void check_log_writer(fd_set *set) +void check_log_writer(int force) { - if (log_fd != -1 && (!set || FD_ISSET(log_fd, set))) + if (log_fd != -1 && (force || poll_check(log_fd, POLLOUT))) log_write(); } void flush_log(void) { /* write until queue empty, but don't loop forever if there's - no connection to the syslog in existance */ + no connection to the syslog in existence */ while (log_fd != -1) { struct timespec waiter;