diff options
author | Internet Software Consortium, Inc <@isc.org> | 2007-09-07 14:14:23 -0600 |
---|---|---|
committer | LaMont Jones <lamont@debian.org> | 2007-09-07 14:14:23 -0600 |
commit | c286cfb7479fcaf7cd55917b19e68d127a04f90e (patch) | |
tree | cdcec6b08d348bd68ba073578bf45500474c6cda /bin/named/unix/os.c | |
parent | c37e760642189d2b245b58879c4a7683488b52e4 (diff) | |
download | bind9-c286cfb7479fcaf7cd55917b19e68d127a04f90e.tar.gz |
9.2.2rc1
Diffstat (limited to 'bin/named/unix/os.c')
-rw-r--r-- | bin/named/unix/os.c | 109 |
1 files changed, 63 insertions, 46 deletions
diff --git a/bin/named/unix/os.c b/bin/named/unix/os.c index ab7652fe..bde3edf3 100644 --- a/bin/named/unix/os.c +++ b/bin/named/unix/os.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1999-2001 Internet Software Consortium. + * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: os.c,v 1.46.2.1 2001/10/22 23:28:12 gson Exp $ */ +/* $Id: os.c,v 1.46.2.4 2002/08/05 06:57:03 marka Exp $ */ #include <config.h> #include <stdarg.h> @@ -53,36 +53,36 @@ static char *pidfile = NULL; /* * Linux defines: - * (T) HAVE_LINUXTHREADS - * (C) HAVE_LINUX_CAPABILITY_H - * (P) HAVE_SYS_PRCTL_H + * (T) HAVE_LINUXTHREADS + * (C) HAVE_LINUX_CAPABILITY_H + * (P) HAVE_SYS_PRCTL_H * The possible cases are: - * none: setuid() normally - * T: no setuid() - * C: setuid() normally, drop caps (keep CAP_SETUID) - * T+C: no setuid(), drop caps (don't keep CAP_SETUID) - * T+C+P: setuid() early, drop caps (keep CAP_SETUID) - * C+P: setuid() normally, drop caps (keep CAP_SETUID) + * none: setuid() normally + * T: no setuid() + * C: setuid() normally, drop caps (keep CAP_SETUID) + * T+C: no setuid(), drop caps (don't keep CAP_SETUID) + * T+C+P: setuid() early, drop caps (keep CAP_SETUID) + * C+P: setuid() normally, drop caps (keep CAP_SETUID) * P: not possible * T+P: not possible * * if (C) - * caps = BIND_SERVICE + CHROOT + SETGID - * if ((T && C && P) || !T) - * caps += SETUID - * endif - * capset(caps) + * caps = BIND_SERVICE + CHROOT + SETGID + * if ((T && C && P) || !T) + * caps += SETUID + * endif + * capset(caps) * endif * if (T && C && P && -u) - * setuid() + * setuid() * else if (T && -u) - * fail + * fail * --> start threads * if (!T && -u) - * setuid() + * setuid() * if (C && (P || !-u)) - * caps = BIND_SERVICE - * capset(caps) + * caps = BIND_SERVICE + * capset(caps) * endif * * It will be nice when Linux threads work properly with setuid(). @@ -127,6 +127,9 @@ static isc_boolean_t non_root_caps = ISC_FALSE; #endif /* HAVE_SYS_PRCTL_H */ #ifndef SYS_capset +#ifndef __NR_capset +#include <asm/unistd.h> /* Slackware 4.0 needs this. */ +#endif #define SYS_capset __NR_capset #endif @@ -304,7 +307,7 @@ ns_os_daemonize(void) { mainpid = getpid(); #endif - if (setsid() == -1) { + if (setsid() == -1) { isc__strerror(errno, strbuf, sizeof(strbuf)); ns_main_earlyfatal("setsid(): %s", strbuf); } @@ -435,23 +438,23 @@ ns_os_minprivs(void) { static int safe_open(const char *filename, isc_boolean_t append) { int fd; - struct stat sb; + struct stat sb; - if (stat(filename, &sb) == -1) { - if (errno != ENOENT) + if (stat(filename, &sb) == -1) { + if (errno != ENOENT) return (-1); - } else if ((sb.st_mode & S_IFREG) == 0) { + } else if ((sb.st_mode & S_IFREG) == 0) { errno = EOPNOTSUPP; return (-1); } if (append) fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); else { (void)unlink(filename); fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); } return (fd); } @@ -466,52 +469,66 @@ cleanup_pidfile(void) { } void -ns_os_writepidfile(const char *filename) { - int fd; +ns_os_writepidfile(const char *filename, isc_boolean_t first_time) { + int fd; FILE *lockfile; size_t len; pid_t pid; char strbuf[ISC_STRERRORSIZE]; + void (*report)(const char *, ...); /* * The caller must ensure any required synchronization. */ + report = first_time ? ns_main_earlyfatal : ns_main_earlywarning; + cleanup_pidfile(); len = strlen(filename); pidfile = malloc(len + 1); if (pidfile == NULL) { isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("couldn't malloc '%s': %s", - filename, strbuf); + (*report)("couldn't malloc '%s': %s", filename, strbuf); + return; } /* This is safe. */ strcpy(pidfile, filename); - fd = safe_open(filename, ISC_FALSE); - if (fd < 0) { + fd = safe_open(filename, ISC_FALSE); + if (fd < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("couldn't open pid file '%s': %s", - filename, strbuf); + (*report)("couldn't open pid file '%s': %s", filename, strbuf); + free(pidfile); + pidfile = NULL; + return; } - lockfile = fdopen(fd, "w"); - if (lockfile == NULL) { + lockfile = fdopen(fd, "w"); + if (lockfile == NULL) { isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("could not fdopen() pid file '%s': %s", - filename, strbuf); + (*report)("could not fdopen() pid file '%s': %s", + filename, strbuf); + (void)close(fd); + cleanup_pidfile(); + return; } #ifdef HAVE_LINUXTHREADS pid = mainpid; #else pid = getpid(); #endif - if (fprintf(lockfile, "%ld\n", (long)pid) < 0) - ns_main_earlyfatal("fprintf() to pid file '%s' failed", - filename); - if (fflush(lockfile) == EOF) - ns_main_earlyfatal("fflush() to pid file '%s' failed", - filename); + if (fprintf(lockfile, "%ld\n", (long)pid) < 0) { + (*report)("fprintf() to pid file '%s' failed", filename); + (void)fclose(lockfile); + cleanup_pidfile(); + return; + } + if (fflush(lockfile) == EOF) { + (*report)("fflush() to pid file '%s' failed", filename); + (void)fclose(lockfile); + cleanup_pidfile(); + return; + } (void)fclose(lockfile); } |