os.c revision fe6b7ccc8de18264107a96602fefe7be772e9d4f
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews/*
7d32c065c7bb56f281651ae3dd2888f32ce4f1d9Bob Halley * Copyright (C) 1999-2001 Internet Software Consortium.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Permission to use, copy, modify, and distribute this software for any
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * purpose with or without fee is hereby granted, provided that the above
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * copyright notice and this permission notice appear in all copies.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
ce8b84ce64a7f1b3b7b558a4aa14be946846080aJames Brister/* $Id: os.c,v 1.7 2001/09/07 00:37:00 marka Exp $ */
ce8b84ce64a7f1b3b7b558a4aa14be946846080aJames Brister
ce8b84ce64a7f1b3b7b558a4aa14be946846080aJames Brister#include <config.h>
3761c433912beabe43abeed2c3513b6201c59f64Mark Andrews#include <stdarg.h>
854d0238dbc2908490197984b3b9d558008a53dfMark Andrews
854d0238dbc2908490197984b3b9d558008a53dfMark Andrews#include <sys/stat.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff#include <ctype.h>
d981ca645597116d227a48bf37cc5edc061c854dBob Halley#include <errno.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <io.h>
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews#include <process.h>
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews#include <fcntl.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <stdio.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <stdlib.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <syslog.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews#include <isc/print.h>
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews#include <isc/result.h>
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Brister#include <isc/string.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <isc/ntpaths.h>
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <named/main.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <named/os.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <named/globals.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <named/ntservice.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
ce8b84ce64a7f1b3b7b558a4aa14be946846080aJames Brister
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic char *pidfile = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffstatic BOOL Initialized = FALSE;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonvoid
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonns_paths_init() {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (!Initialized)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_ntpaths_init();
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ns_g_conffile = isc_ntpaths_get(NAMED_CONF_PATH);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews lwresd_g_conffile = isc_ntpaths_get(LWRES_CONF_PATH);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews lwresd_g_resolvconffile = isc_ntpaths_get(RESOLV_CONF_PATH);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ns_g_conffile = isc_ntpaths_get(NAMED_CONF_PATH);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ns_g_defaultpidfile = isc_ntpaths_get(NAMED_PID_PATH);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson lwresd_g_defaultpidfile = isc_ntpaths_get(LWRESD_PID_PATH);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ns_g_keyfile = isc_ntpaths_get(RNDC_KEY_PATH);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews Initialized = TRUE;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
ce8b84ce64a7f1b3b7b558a4aa14be946846080aJames Bristerstatic void
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewssetup_syslog(const char *progname) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews int options;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff
d981ca645597116d227a48bf37cc5edc061c854dBob Halley options = LOG_PID;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#ifdef LOG_NDELAY
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews options |= LOG_NDELAY;
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews#endif
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews openlog(progname, options, LOG_DAEMON);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews}
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Bristervoid
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrewsns_os_init(const char *progname) {
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews ns_paths_init();
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews setup_syslog(progname);
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews ntservice_init();
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsvoid
ce8b84ce64a7f1b3b7b558a4aa14be946846080aJames Bristerns_os_daemonize(void) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews int fd;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff /*
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Brister * Try to set stdin, stdout, and stderr to /dev/null, but press
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Brister * on even if it fails.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * XXXMLG The close() calls here are unneeded on all but NetBSD, but
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * are harmless to include everywhere. dup2() is supposed to close
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews * the FD if it is in use, but unproven-pthreads-0.16 is broken
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * and will end up closing the wrong FD. This will be fixed eventually,
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews * and these calls will be removed.
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews */
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews fd = open("NUL", O_RDWR, 0);
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews if (fd != -1) {
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews close(_fileno(stdin));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews (void)_dup2(fd, _fileno(stdin));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews close(_fileno(stdout));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews (void)_dup2(fd, _fileno(stdout));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews close(_fileno(stderr));
ce8b84ce64a7f1b3b7b558a4aa14be946846080aJames Brister (void)_dup2(fd, _fileno(stderr));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (fd != _fileno(stdin) &&
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews fd != _fileno(stdout) &&
4529cdaedaf1a0a5f8ff89aeca510b7a4475446cBob Halley fd != _fileno(stderr))
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Brister (void)close(fd);
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Brister }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsvoid
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsns_os_chroot(const char *root) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
d981ca645597116d227a48bf37cc5edc061c854dBob Halleyvoid
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrewsns_os_inituserinfo(const char *username) {
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsvoid
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsns_os_changeuser(void) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsvoid
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsns_os_minprivs(void) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
ce8b84ce64a7f1b3b7b558a4aa14be946846080aJames Bristerstatic int
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewssafe_open(const char *filename, isc_boolean_t append) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews int fd;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff struct stat sb;
d981ca645597116d227a48bf37cc5edc061c854dBob Halley
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews if (stat(filename, &sb) == -1) {
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews if (errno != ENOENT)
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews return (-1);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews } else if ((sb.st_mode & S_IFREG) == 0)
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews return (-1);
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Brister
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews if (append)
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Brister fd = open(filename, O_WRONLY|O_CREAT|O_APPEND,
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Brister S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews else {
ce8b84ce64a7f1b3b7b558a4aa14be946846080aJames Brister (void)unlink(filename);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews fd = open(filename, O_WRONLY|O_CREAT|O_EXCL,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff }
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Brister return (fd);
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Brister}
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrewsstatic void
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrewscleanup_pidfile(void) {
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Brister if (pidfile != NULL) {
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Brister (void)unlink(pidfile);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews free(pidfile);
ce8b84ce64a7f1b3b7b558a4aa14be946846080aJames Brister }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews pidfile = NULL;
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews}
4529cdaedaf1a0a5f8ff89aeca510b7a4475446cBob Halley
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Bristervoid
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Bristerns_os_writepidfile(const char *filename) {
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews int fd;
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews FILE *lockfile;
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews size_t len;
d981ca645597116d227a48bf37cc5edc061c854dBob Halley pid_t pid;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff
d981ca645597116d227a48bf37cc5edc061c854dBob Halley /*
d981ca645597116d227a48bf37cc5edc061c854dBob Halley * The caller must ensure any required synchronization.
d981ca645597116d227a48bf37cc5edc061c854dBob Halley */
b1bc194f94c0b3cbc5999582f08e8d7a20b91e2eBob Halley
b1bc194f94c0b3cbc5999582f08e8d7a20b91e2eBob Halley cleanup_pidfile();
b1bc194f94c0b3cbc5999582f08e8d7a20b91e2eBob Halley
d981ca645597116d227a48bf37cc5edc061c854dBob Halley len = strlen(filename);
d981ca645597116d227a48bf37cc5edc061c854dBob Halley pidfile = malloc(len + 1);
b1bc194f94c0b3cbc5999582f08e8d7a20b91e2eBob Halley if (pidfile == NULL)
b1bc194f94c0b3cbc5999582f08e8d7a20b91e2eBob Halley ns_main_earlyfatal("couldn't malloc '%s': %s",
b1bc194f94c0b3cbc5999582f08e8d7a20b91e2eBob Halley filename, strerror(errno));
d981ca645597116d227a48bf37cc5edc061c854dBob Halley /* This is safe. */
ce8b84ce64a7f1b3b7b558a4aa14be946846080aJames Brister strcpy(pidfile, filename);
d981ca645597116d227a48bf37cc5edc061c854dBob Halley
d981ca645597116d227a48bf37cc5edc061c854dBob Halley fd = safe_open(filename, ISC_FALSE);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff if (fd < 0)
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Brister ns_main_earlyfatal("couldn't open pid file '%s': %s",
ee7cac1c6e1e0b36a7fa622b8c109169f1093b63James Brister filename, strerror(errno));
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley lockfile = fdopen(fd, "w");
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley if (lockfile == NULL)
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley ns_main_earlyfatal("could not fdopen() pid file '%s': %s",
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley filename, strerror(errno));
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley pid = getpid();
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley if (fprintf(lockfile, "%ld\n", (long)pid) < 0)
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley ns_main_earlyfatal("fprintf() to pid file '%s' failed",
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley filename);
ce8b84ce64a7f1b3b7b558a4aa14be946846080aJames Brister if (fflush(lockfile) == EOF)
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley ns_main_earlyfatal("fflush() to pid file '%s' failed",
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley filename);
854d0238dbc2908490197984b3b9d558008a53dfMark Andrews (void)fclose(lockfile);
}
void
ns_os_shutdown(void) {
closelog();
cleanup_pidfile();
ntservice_shutdown(); /* This MUST be the last thing done */
}