From 0 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Mon, 15 Oct 2007 19:54:35 +0000 Subject: [PATCH 01] Apply dhcp-3.0.5-alt-warnings.patch diff --git a/dhcp/common/parse.c b/dhcp/common/parse.c index defaced..defaced 100644 --- a/dhcp/common/parse.c +++ b/dhcp/common/parse.c @@ -5562,6 +5562,25 @@ int parse_X (cfile, buf, max) return len; } +static ssize_t +write_loop (int fd, const char *buffer, size_t count) +{ + ssize_t offset = 0; + + while (count > 0) + { + ssize_t block = write (fd, &buffer[offset], count); + + if (block < 0 && errno == EINTR) + continue; + if (block <= 0) + return offset ? : block; + offset += block; + count -= block; + } + return offset; +} + int parse_warn (struct parse *cfile, const char *fmt, ...) { va_list list; @@ -5601,14 +5620,14 @@ int parse_warn (struct parse *cfile, const char *fmt, ...) #endif if (log_perror) { - IGNORE_RET (write (STDERR_FILENO, mbuf, strlen (mbuf))); - IGNORE_RET (write (STDERR_FILENO, "\n", 1)); - IGNORE_RET (write (STDERR_FILENO, cfile -> token_line, + IGNORE_RET (write_loop (STDERR_FILENO, mbuf, strlen (mbuf))); + IGNORE_RET (write_loop (STDERR_FILENO, "\n", 1)); + IGNORE_RET (write_loop (STDERR_FILENO, cfile -> token_line, strlen (cfile -> token_line))); - IGNORE_RET (write (STDERR_FILENO, "\n", 1)); + IGNORE_RET (write_loop (STDERR_FILENO, "\n", 1)); if (cfile -> lexchar < 81) - IGNORE_RET (write (STDERR_FILENO, lexbuf, lix)); - IGNORE_RET (write (STDERR_FILENO, "^\n", 2)); + IGNORE_RET (write_loop (STDERR_FILENO, lexbuf, lix)); + IGNORE_RET (write_loop (STDERR_FILENO, "^\n", 2)); } cfile -> warnings_occurred = 1; diff --git a/dhcp/omapip/errwarn.c b/dhcp/omapip/errwarn.c index defaced..defaced 100644 --- a/dhcp/omapip/errwarn.c +++ b/dhcp/omapip/errwarn.c @@ -48,6 +48,25 @@ void (*log_cleanup) (void); static char mbuf [CVT_BUF_MAX + 1]; static char fbuf [CVT_BUF_MAX + 1]; +static ssize_t +write_loop (int fd, const char *buffer, size_t count) +{ + ssize_t offset = 0; + + while (count > 0) + { + ssize_t block = write (fd, &buffer[offset], count); + + if (block < 0 && errno == EINTR) + continue; + if (block <= 0) + return offset ? : block; + offset += block; + count -= block; + } + return offset; +} + /* Log an error message, then exit... */ void log_fatal (const char * fmt, ... ) @@ -64,23 +83,30 @@ void log_fatal (const char * fmt, ... ) va_end (list); #ifndef DEBUG - syslog (LOG_ERR, "%s", mbuf); + if (*mbuf) + syslog (LOG_ERR, "%s", mbuf); #endif /* Also log it to stderr? */ - if (log_perror) { - IGNORE_RET (write (STDERR_FILENO, mbuf, strlen (mbuf))); - IGNORE_RET (write (STDERR_FILENO, "\n", 1)); + if (log_perror && *mbuf) { + IGNORE_RET (write_loop (STDERR_FILENO, mbuf, strlen (mbuf))); + IGNORE_RET (write_loop (STDERR_FILENO, "\n", 1)); } + log_error ("%s", "Please note the following before requesting help:"); + log_error ("%s", ""); + log_error ("%s", "This software is a part of the Internet Software Consortium's DHCP suite"); + log_error ("%s", "with modifications for ALT Linux."); + log_error ("%s", "The ISC folks quite reasonably require that you do not bother them with"); + log_error ("%s", "questions on software that includes third-party modifications and might"); + log_error ("%s", "not be based off their latest code. Hence, please direct any questions"); + log_error ("%s", "to the community@ mailing list instead; the subscription instructions"); + log_error ("%s", "are given at http://lists.altlinux.org/mailman/listinfo/community ."); log_error ("%s", ""); - log_error ("If you think you have received this message due to a bug rather"); - log_error ("than a configuration issue please read the section on submitting"); - log_error ("bugs on either our web page at www.isc.org or in the README file"); - log_error ("before submitting a bug. These pages explain the proper"); - log_error ("process and the information we find helpful for debugging."); + log_error ("%s", "Please also read the SUPPORT section on the README about"); + log_error ("%s", "submitting bug reports and requests for help."); log_error ("%s", ""); - log_error ("exiting."); + log_error ("%s", "exiting."); if (log_cleanup) (*log_cleanup) (); @@ -103,12 +129,13 @@ int log_error (const char * fmt, ...) va_end (list); #ifndef DEBUG - syslog (LOG_ERR, "%s", mbuf); + if (*mbuf) + syslog (LOG_ERR, "%s", mbuf); #endif - if (log_perror) { - IGNORE_RET (write (STDERR_FILENO, mbuf, strlen (mbuf))); - IGNORE_RET (write (STDERR_FILENO, "\n", 1)); + if (log_perror && *mbuf) { + IGNORE_RET (write_loop (STDERR_FILENO, mbuf, strlen (mbuf))); + IGNORE_RET (write_loop (STDERR_FILENO, "\n", 1)); } return 0; @@ -130,12 +157,13 @@ int log_info (const char *fmt, ...) va_end (list); #ifndef DEBUG - syslog (LOG_INFO, "%s", mbuf); + if (*mbuf) + syslog (LOG_INFO, "%s", mbuf); #endif - if (log_perror) { - IGNORE_RET (write (STDERR_FILENO, mbuf, strlen (mbuf))); - IGNORE_RET (write (STDERR_FILENO, "\n", 1)); + if (log_perror && *mbuf) { + IGNORE_RET (write_loop (STDERR_FILENO, mbuf, strlen (mbuf))); + IGNORE_RET (write_loop (STDERR_FILENO, "\n", 1)); } return 0; @@ -157,12 +185,13 @@ int log_debug (const char *fmt, ...) va_end (list); #ifndef DEBUG - syslog (LOG_DEBUG, "%s", mbuf); + if (*mbuf) + syslog (LOG_DEBUG, "%s", mbuf); #endif - if (log_perror) { - IGNORE_RET (write (STDERR_FILENO, mbuf, strlen (mbuf))); - IGNORE_RET (write (STDERR_FILENO, "\n", 1)); + if (log_perror && *mbuf) { + IGNORE_RET (write_loop (STDERR_FILENO, mbuf, strlen (mbuf))); + IGNORE_RET (write_loop (STDERR_FILENO, "\n", 1)); } return 0; @@ -223,7 +252,7 @@ char *strerror (err) static char errbuf [128]; if (err < 0 || err >= sys_nerr) { - sprintf (errbuf, "Error %d", err); + snprintf (errbuf, sizeof(errbuf), "Error %d", err); return errbuf; } return sys_errlist [err]; diff --git a/dhcp/server/dhcpd.c b/dhcp/server/dhcpd.c index defaced..defaced 100644 --- a/dhcp/server/dhcpd.c +++ b/dhcp/server/dhcpd.c @@ -165,7 +165,8 @@ static void omapi_listener_start (void *foo) #define DHCPD_USAGE1 \ " [-cf config-file] [-lf lease-file]\n" #endif /* DHCPv6 */ - +#define DHCPD_USAGE_ALT_CHROOT \ +" [-u user] [-j chroot-dir]\n" #if defined (PARANOIA) #define DHCPD_USAGEP \ " [-user user] [-group group] [-chroot dir]\n" @@ -207,9 +208,9 @@ static char use_noarg[] = "No argument for command: %s "; static void usage(const char *sfmt, const char *sarg) { log_info("%s %s", message, PACKAGE_VERSION); - log_info(copyright); - log_info(arr); - log_info(url); + log_info("%s", copyright); + log_info("%s", arr); + log_info("%s", url); /* If desired print out the specific error message */ #ifdef PRINT_SPECIFIC_CL_ERRORS @@ -217,10 +218,11 @@ usage(const char *sfmt, const char *sarg) { log_error(sfmt, sarg); #endif - log_fatal("Usage: %s %s%s%s%s%s\n %s %s", + log_fatal("Usage: %s %s%s%s%s%s%s\n %s %s", isc_file_basename(progname), DHCPD_USAGE0, DHCPD_USAGE1, + DHCPD_USAGE_ALT_CHROOT, DHCPD_USAGEP, DHCPD_USAGET, DHCPD_USAGEC, @@ -284,6 +286,8 @@ main(int argc, char **argv) { char *traceinfile = (char *)0; char *traceoutfile = (char *)0; #endif + char *server_user = "dhcpd"; + char *server_jail = "/var/lib/dhcp/dhcpd"; #if defined (PARANOIA) char *set_user = 0; @@ -305,10 +309,12 @@ main(int argc, char **argv) { fd = open("/dev/null", O_RDWR); if (fd == 1) fd = open("/dev/null", O_RDWR); - if (fd == 2) + if (fd == 2) { + fd = open("/dev/null", O_RDWR); log_perror = 0; /* No sense logging to /dev/null. */ - else if (fd != -1) - close(fd); + } + if (fd < 0) + log_fatal ("Can't open %s: %m", "/dev/null"); /* Parse arguments changing daemon */ for (i = 1; i < argc; i++) { @@ -522,6 +528,14 @@ main(int argc, char **argv) { dhcpv4_over_dhcpv6 = 1; #endif /* DHCP4o6 */ #endif /* DHCPv6 */ + } else if (!strcmp (argv [i], "-u")) { + if (++i == argc) + usage(use_noarg, argv[i-1]); + server_user = argv[i]; + } else if (!strcmp (argv [i], "-j")) { + if (++i == argc) + usage(use_noarg, argv[i-1]); + server_jail = argv[i]; #if defined (TRACING) } else if (!strcmp (argv [i], "-tf")) { if (++i == argc) @@ -612,9 +626,9 @@ main(int argc, char **argv) { if (!quiet) { log_info("%s %s", message, PACKAGE_VERSION); - log_info (copyright); - log_info (arr); - log_info (url); + log_info ("%s", copyright); + log_info ("%s", arr); + log_info ("%s", url); } else { log_perror = 0; } @@ -886,12 +900,6 @@ main(int argc, char **argv) { group_write_hook = group_writer; - /* Start up the database... */ - db_startup (lftest); - - if (lftest) - exit (0); - /* Discover all the network interfaces and initialize them. */ #if defined(DHCPv6) && defined(DHCP4o6) if (dhcpv4_over_dhcpv6) { @@ -909,23 +917,6 @@ main(int argc, char **argv) { #endif /* DHCPv6 && DHCP4o6 */ discover_interfaces(DISCOVER_SERVER); -#ifdef DHCPv6 - /* - * Remove addresses from our pools that we should not issue - * to clients. - * - * We currently have no support for this in IPv4. It is not - * as important in IPv4, as making pools with ranges that - * leave out interfaces and hosts is fairly straightforward - * using range notation, but not so handy with CIDR notation. - */ - if (local_family == AF_INET6) { - mark_hosts_unavailable(); - mark_phosts_unavailable(); - mark_interfaces_unavailable(); - } -#endif /* DHCPv6 */ - /* Make up a seed for the random number generator from current time plus the sum of the last four bytes of each interface's hardware address interpreted as an integer. @@ -943,30 +934,6 @@ main(int argc, char **argv) { #if defined (TRACING) trace_seed_stash (trace_srandom, seed + cur_time); #endif - postdb_startup (); - -#ifdef DHCPv6 - /* - * Set server DHCPv6 identifier - we go in order: - * dhcp6.server-id in the config file - * server-duid from the lease file - * server-duid from the config file (the config file is read first - * and the lease file overwrites the config file information) - * generate a new one from the interface hardware addresses. - * In all cases we write it out to the lease file. - * See dhcpv6.c for discussion of setting DUID. - */ - if ((set_server_duid_from_option() != ISC_R_SUCCESS) && - (!server_duid_isset()) && - (generate_new_server_duid() != ISC_R_SUCCESS)) { - log_fatal("Unable to set server identifier."); - } - write_server_duid(); -#ifdef DHCP4o6 - if (dhcpv4_over_dhcpv6) - dhcp4o6_setup(dhcp4o6_port); -#endif /* DHCP4o6 */ -#endif /* DHCPv6 */ #ifndef DEBUG /* @@ -977,8 +944,10 @@ main(int argc, char **argv) { if (no_pid_file == ISC_FALSE) { i = open(path_dhcpd_pid, O_WRONLY|O_CREAT|O_TRUNC, 0644); if (i >= 0) { - sprintf(pbuf, "%d\n", (int) getpid()); - IGNORE_RET(write(i, pbuf, strlen(pbuf))); + snprintf(pbuf, sizeof(pbuf), "%d\n", (int) getpid()); + if (write (i, pbuf, strlen (pbuf)) != strlen (pbuf)) + log_fatal ("Error writing pid file: %s: %m", + path_dhcpd_pid); close(i); } else { log_error("Can't create PID file %s: %m.", @@ -986,6 +955,8 @@ main(int argc, char **argv) { } } + dhcpd_priv_minimize (server_user, server_jail); + #if defined (PARANOIA) /* change uid to the specified one */ @@ -1023,18 +994,65 @@ main(int argc, char **argv) { (void) setsid(); /* Close standard I/O descriptors. */ - (void) close(0); - (void) close(1); - (void) close(2); - - /* Reopen them on /dev/null. */ - (void) open("/dev/null", O_RDWR); - (void) open("/dev/null", O_RDWR); - (void) open("/dev/null", O_RDWR); + if (dup2 (fd, 0) != 0 || + dup2 (fd, 1) != 1 || + dup2 (fd, 2) != 2) + log_fatal("Can't daemonize: %m"); + (void) close (fd); + fd = -1; log_perror = 0; /* No sense logging to /dev/null. */ IGNORE_RET (chdir("/")); } + + /* Start up the database... */ + db_startup (lftest); + + if (lftest) + exit (0); + +#ifdef DHCPv6 + /* + * Remove addresses from our pools that we should not issue + * to clients. + * + * We currently have no support for this in IPv4. It is not + * as important in IPv4, as making pools with ranges that + * leave out interfaces and hosts is fairly straightforward + * using range notation, but not so handy with CIDR notation. + */ + if (local_family == AF_INET6) { + mark_hosts_unavailable(); + mark_phosts_unavailable(); + mark_interfaces_unavailable(); + } + + /* + * Set server DHCPv6 identifier - we go in order: + * dhcp6.server-id in the config file + * server-duid from the lease file + * server-duid from the config file (the config file is read first + * and the lease file overwrites the config file information) + * generate a new one from the interface hardware addresses. + * In all cases we write it out to the lease file. + * See dhcpv6.c for discussion of setting DUID. + */ + if ((set_server_duid_from_option() != ISC_R_SUCCESS) && + (!server_duid_isset()) && + (generate_new_server_duid() != ISC_R_SUCCESS)) { + log_fatal("Unable to set server identifier."); + } + write_server_duid(); +#ifdef DHCP4o6 + if (dhcpv4_over_dhcpv6) + dhcp4o6_setup(dhcp4o6_port); +#endif /* DHCP4o6 */ +#endif /* DHCPv6 */ + + postdb_startup (); + + dhcpd_priv_drop (server_user, server_jail); + #endif /* !DEBUG */ #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \ @@ -1333,9 +1351,9 @@ void postconf_initialization (int quiet) tmp = log_perror; log_perror = 0; log_info("%s %s", message, PACKAGE_VERSION); - log_info(copyright); - log_info(arr); - log_info(url); + log_info("%s", copyright); + log_info("%s", arr); + log_info("%s", url); log_perror = tmp; } else log_fatal("invalid log facility");