6431922cb25fb3d9815677cfbfba83db95b4e401Tinderbox User * Copyright (C) 1999-2002, 2004-2011, 2013-2017 Internet Systems Consortium, Inc. ("ISC")
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
de8661e517ed679cfaa12e47eb9a8e23829ed320David Lawrence#include <grp.h> /* Required for initgroups() on IRIX. */
1d8cbe855fc355b80802dcf29f4ac24bebdd1193Brian Wellington * If there's no <linux/capability.h>, we don't care about <sys/prctl.h>
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellington * Linux defines:
5d98cf67b32d785aca1a72ea1dc4d559fab39208Mark Andrews * (T) HAVE_LINUXTHREADS
0415ca35ada2cac6a86127eaca64f3a997aea121Evan Hunt * (C) HAVE_SYS_CAPABILITY_H (or HAVE_LINUX_CAPABILITY_H)
5d98cf67b32d785aca1a72ea1dc4d559fab39208Mark Andrews * (P) HAVE_SYS_PRCTL_H
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellington * The possible cases are:
5d98cf67b32d785aca1a72ea1dc4d559fab39208Mark Andrews * none: setuid() normally
5d98cf67b32d785aca1a72ea1dc4d559fab39208Mark Andrews * T: no setuid()
5d98cf67b32d785aca1a72ea1dc4d559fab39208Mark Andrews * C: setuid() normally, drop caps (keep CAP_SETUID)
5d98cf67b32d785aca1a72ea1dc4d559fab39208Mark Andrews * T+C: no setuid(), drop caps (don't keep CAP_SETUID)
5d98cf67b32d785aca1a72ea1dc4d559fab39208Mark Andrews * T+C+P: setuid() early, drop caps (keep CAP_SETUID)
5d98cf67b32d785aca1a72ea1dc4d559fab39208Mark Andrews * C+P: setuid() normally, drop caps (keep CAP_SETUID)
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellington * P: not possible
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellington * T+P: not possible
5d98cf67b32d785aca1a72ea1dc4d559fab39208Mark Andrews * caps = BIND_SERVICE + CHROOT + SETGID
5d98cf67b32d785aca1a72ea1dc4d559fab39208Mark Andrews * if ((T && C && P) || !T)
5d98cf67b32d785aca1a72ea1dc4d559fab39208Mark Andrews * caps += SETUID
5d98cf67b32d785aca1a72ea1dc4d559fab39208Mark Andrews * capset(caps)
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellington * if (T && C && P && -u)
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellington * else if (T && -u)
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellington * --> start threads
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellington * if (!T && -u)
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellington * if (C && (P || !-u))
5d98cf67b32d785aca1a72ea1dc4d559fab39208Mark Andrews * caps = BIND_SERVICE
5d98cf67b32d785aca1a72ea1dc4d559fab39208Mark Andrews * capset(caps)
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellington * It will be nice when Linux threads work properly with setuid().
c336121fb5a5c1b9cb9b2cd4cea50f0788270505Brian Wellingtonstatic isc_boolean_t done_setuid = ISC_FALSE;
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellingtonstatic isc_boolean_t non_root_caps = ISC_FALSE;
077daa21229ffaedda79588fa70fbaeae19ae998Bob Halley * We define _LINUX_FS_H to prevent it from being included. We don't need
077daa21229ffaedda79588fa70fbaeae19ae998Bob Halley * anything from it, and the files it includes cause warnings with 2.2
077daa21229ffaedda79588fa70fbaeae19ae998Bob Halley * kernels, and compilation failures (due to conflicts between <linux/string.h>
077daa21229ffaedda79588fa70fbaeae19ae998Bob Halley * and <string.h>) on 2.3 kernels.
0415ca35ada2cac6a86127eaca64f3a997aea121Evan Hunt#include <asm/unistd.h> /* Slackware 4.0 needs this. */
0415ca35ada2cac6a86127eaca64f3a997aea121Evan Hunt#endif /* __NR_capset */
0415ca35ada2cac6a86127eaca64f3a997aea121Evan Hunt#endif /* SYS_capset */
0415ca35ada2cac6a86127eaca64f3a997aea121Evan Hunt#endif /* HAVE_SYS_CAPABILITY_H */
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <sys/prctl.h> /* Required for prctl(). */
1d8cbe855fc355b80802dcf29f4ac24bebdd1193Brian Wellington * If the value of PR_SET_KEEPCAPS is not in <sys/prctl.h>, define it
d1e4b08844175357a925ddd6dcfa750cccd2b116Brian Wellington * here. This allows setuid() to work on systems running a new enough
d1e4b08844175357a925ddd6dcfa750cccd2b116Brian Wellington * kernel but with /usr/include/linux pointing to "standard" kernel
f8727bd90366af835f551da1b5e1fdfcd2d3d01fBrian Wellington#endif /* HAVE_SYS_PRCTL_H */
0415ca35ada2cac6a86127eaca64f3a997aea121Evan Hunt#endif /* HAVE_LIBCAP */
77771185071bf74d53378f1a3099a04d2af5153eBrian Wellington if ((getuid() != 0 && !non_root_caps) || non_root)
dc2a0aa7aaa8b85398ae183c7274c0eeec5009afMark Andrews " please ensure that the capset kernel"
dc2a0aa7aaa8b85398ae183c7274c0eeec5009afMark Andrews " module is loaded. see insmod(8)",
ef4eed2a2a8897bd4e5b19dd94f638e0861ebda5Mark Andrews err = cap_get_flag(curcaps, capval, CAP_PERMITTED, &curval); \
88674be66567d3c7db91e717cd5972655e2e2488Mark Andrews err = cap_set_flag(caps, CAP_EFFECTIVE, 1, &capval, CAP_SET); \
88674be66567d3c7db91e717cd5972655e2e2488Mark Andrews isc__strerror(errno, strbuf, sizeof(strbuf)); \
88674be66567d3c7db91e717cd5972655e2e2488Mark Andrews ns_main_earlyfatal("cap_set_proc failed: %s", strbuf); \
88674be66567d3c7db91e717cd5972655e2e2488Mark Andrews err = cap_set_flag(caps, CAP_PERMITTED, 1, &capval, CAP_SET); \
88674be66567d3c7db91e717cd5972655e2e2488Mark Andrews isc__strerror(errno, strbuf, sizeof(strbuf)); \
88674be66567d3c7db91e717cd5972655e2e2488Mark Andrews ns_main_earlyfatal("cap_set_proc failed: %s", strbuf); \
0415ca35ada2cac6a86127eaca64f3a997aea121Evan Hunt ns_main_earlyfatal("cap_init failed: %s", strbuf); \
ef4eed2a2a8897bd4e5b19dd94f638e0861ebda5Mark Andrews isc__strerror(errno, strbuf, sizeof(strbuf)); \
ef4eed2a2a8897bd4e5b19dd94f638e0861ebda5Mark Andrews ns_main_earlyfatal("cap_get_proc failed: %s", strbuf); \
ef4eed2a2a8897bd4e5b19dd94f638e0861ebda5Mark Andrews#define SET_CAP(flag) do { caps |= (1 << (flag)); } while (0)
0415ca35ada2cac6a86127eaca64f3a997aea121Evan Hunt#endif /* HAVE_LIBCAP */
134ba0e08a0ae9a564a8d8628fc633377d3fc239Bob Halley * We don't need most privileges, so we drop them right away.
134ba0e08a0ae9a564a8d8628fc633377d3fc239Bob Halley * Later on linux_minprivs() will be called, which will drop our
134ba0e08a0ae9a564a8d8628fc633377d3fc239Bob Halley * capabilities to the minimum needed to run the server.
134ba0e08a0ae9a564a8d8628fc633377d3fc239Bob Halley * We need to be able to bind() to privileged ports, notably port 53!
134ba0e08a0ae9a564a8d8628fc633377d3fc239Bob Halley * We need chroot() initially too.
f8727bd90366af835f551da1b5e1fdfcd2d3d01fBrian Wellington#if defined(HAVE_SYS_PRCTL_H) || !defined(HAVE_LINUXTHREADS)
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellington * We can setuid() only if either the kernel supports keeping
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellington * capabilities after setuid() (which we don't know until we've
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellington * tried) or we're not using threads. If either of these is
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellington * true, we want the setuid capability.
71954c957132c35ddf5f9e4dcc98c057b265b6d8Brian Wellington * Since we call initgroups, we need this.
d119051ef75d5a88d28c13fb0a7c6d6757a4e9b5Brian Wellington * Without this, we run into problems reading a configuration file
d119051ef75d5a88d28c13fb0a7c6d6757a4e9b5Brian Wellington * owned by a non-root user and non-world-readable on startup.
5e4b7294d88ab58371d8c98e05ea80086dcb67cdBob Halley * XXX We might want to add CAP_SYS_RESOURCE, though it's not
5e4b7294d88ab58371d8c98e05ea80086dcb67cdBob Halley * clear it would work right given the way linuxthreads work.
108490a7f8529aff50a0ac7897580b59a73d9845David Lawrence * XXXDCL But since we need to be able to set the maximum number
108490a7f8529aff50a0ac7897580b59a73d9845David Lawrence * of files, the stack size, data size, and core dump size to
108490a7f8529aff50a0ac7897580b59a73d9845David Lawrence * support named.conf options, this is now being added to test.
a4463732ad7935992a101b3d19f0a41120b85458Mark Andrews * We need to be able to set the ownership of the containing
a4463732ad7935992a101b3d19f0a41120b85458Mark Andrews * directory of the pid file when we create it.
134ba0e08a0ae9a564a8d8628fc633377d3fc239Bob Halley * Drop all privileges except the ability to bind() to privileged
134ba0e08a0ae9a564a8d8628fc633377d3fc239Bob Halley * It's important that we drop CAP_SYS_CHROOT. If we didn't, it
134ba0e08a0ae9a564a8d8628fc633377d3fc239Bob Halley * chroot() could be used to escape from the chrooted area.
8fd925169f3d690f6c50c17d711adc9695407528Mark Andrews * XXX We might want to add CAP_SYS_RESOURCE, though it's not
8fd925169f3d690f6c50c17d711adc9695407528Mark Andrews * clear it would work right given the way linuxthreads work.
8fd925169f3d690f6c50c17d711adc9695407528Mark Andrews * XXXDCL But since we need to be able to set the maximum number
8fd925169f3d690f6c50c17d711adc9695407528Mark Andrews * of files, the stack size, data size, and core dump size to
8fd925169f3d690f6c50c17d711adc9695407528Mark Andrews * support named.conf options, this is now being added to test.
134ba0e08a0ae9a564a8d8628fc633377d3fc239Bob Halley * Ask the kernel to allow us to keep our capabilities after we
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews ns_main_earlyfatal("prctl() failed: %s", strbuf);
2dfd6bca9aa6d9279b4278d6fa18ea5f63ba0ec9Bob Halley#endif /* HAVE_LINUX_CAPABILITY_H */
ee80f4506479e189ca1320eb87ac89188c5a7848Mark Andrews openlog(isc_file_basename(progname), options, ISC_FACILITY);
2c329da87c5c886e7f4468c69a9e6323121068cbMark Andrews * Wait for the child to finish loading for the first time.
2c329da87c5c886e7f4468c69a9e6323121068cbMark Andrews * This would be so much simpler if fork() worked once we
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater * were multi-threaded.
2aa67e804d85f4d88153368ce65ce4df7b5390e6Bob Halley * We're the child.
2aa67e804d85f4d88153368ce65ce4df7b5390e6Bob Halley * Try to set stdin, stdout, and stderr to /dev/null, but press
2aa67e804d85f4d88153368ce65ce4df7b5390e6Bob Halley * on even if it fails.
15197aefa1659e98ea1c48e2cbae631136a072b7Michael Graff * XXXMLG The close() calls here are unneeded on all but NetBSD, but
15197aefa1659e98ea1c48e2cbae631136a072b7Michael Graff * are harmless to include everywhere. dup2() is supposed to close
15197aefa1659e98ea1c48e2cbae631136a072b7Michael Graff * the FD if it is in use, but unproven-pthreads-0.16 is broken
15197aefa1659e98ea1c48e2cbae631136a072b7Michael Graff * and will end up closing the wrong FD. This will be fixed eventually,
15197aefa1659e98ea1c48e2cbae631136a072b7Michael Graff * and these calls will be removed.
52254f75267c734acf1f1fb982b6a3be05e93507Mark Andrews if (devnullfd != STDERR_FILENO && !ns_g_keepstderr) {
dfa3ca995c99e66ab56e98da79e386bcdb23c43aMark Andrews * Signal to the parent that we started successfully.
dfa3ca995c99e66ab56e98da79e386bcdb23c43aMark Andrews ns_main_earlyfatal("unable to signal parent that we "
dfa3ca995c99e66ab56e98da79e386bcdb23c43aMark Andrews "otherwise started successfully.");
2dfd6bca9aa6d9279b4278d6fa18ea5f63ba0ec9Bob Halley if (*s == '\0')
2dfd6bca9aa6d9279b4278d6fa18ea5f63ba0ec9Bob Halley while (*s != '\0') {
f754fa97bc698cc251d227173a95e4d39a88ac01Mark Andrews /* Set ns_smf_chroot flag on successful chroot. */
4e5388b45908ce8b8b35825ca6f16c1d236643baBrian Wellington runas_pw = getpwuid((uid_t)atoi(username));
2dfd6bca9aa6d9279b4278d6fa18ea5f63ba0ec9Bob Halley ns_main_earlyfatal("user '%s' unknown", username);
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews if (initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0) {
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews ns_main_earlyfatal("initgroups(): %s", strbuf);
31a71adf14d106260127079f6ea26bea600163e9Mark Andrews ns_main_earlyfatal("-u with Linux threads not supported: "
31a71adf14d106260127079f6ea26bea600163e9Mark Andrews "requires kernel support for "
31a71adf14d106260127079f6ea26bea600163e9Mark Andrews "prctl(PR_SET_KEEPCAPS)");
31a71adf14d106260127079f6ea26bea600163e9Mark Andrews ns_main_earlyfatal("-u with Linux threads not supported: "
31a71adf14d106260127079f6ea26bea600163e9Mark Andrews "no capabilities support or capabilities "
31a71adf14d106260127079f6ea26bea600163e9Mark Andrews "disabled at build time");
d53520b78d4a8726396efdbaa71f86f687a6f308Mark Andrews#if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_DUMPABLE)
d53520b78d4a8726396efdbaa71f86f687a6f308Mark Andrews * Restore the ability of named to drop core after the setuid()
d53520b78d4a8726396efdbaa71f86f687a6f308Mark Andrews * call has disabled it.
f61a7c87bf36b189d8f04ea4c8ab3ec55778355cMark Andrews ns_main_earlywarning("prctl(PR_SET_DUMPABLE) failed: %s",
f61a7c87bf36b189d8f04ea4c8ab3ec55778355cMark Andrews#if defined(HAVE_LINUX_CAPABILITY_H) && !defined(HAVE_LINUXTHREADS)
6d54a6fc180acaf8772c9447cb925b31f39c7158Mark Andrews * Linux: max number of open files specified by one thread doesn't seem
6d54a6fc180acaf8772c9447cb925b31f39c7158Mark Andrews * to apply to other threads on Linux.
6d54a6fc180acaf8772c9447cb925b31f39c7158Mark Andrews result = isc_resource_setlimit(isc_resource_openfiles, newvalue);
6d54a6fc180acaf8772c9447cb925b31f39c7158Mark Andrews ns_main_earlywarning("couldn't adjust limit on open files");
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellington ns_os_changeuser(); /* Call setuid() before threads are started */
51e0ad287f1b345f0c3316f0633aab14d0e8bb65Brian Wellington#if defined(HAVE_LINUX_CAPABILITY_H) && defined(HAVE_LINUXTHREADS)
3a875400473e5c06199272a1292ed84646990e2fEvan Huntsafe_open(const char *filename, mode_t mode, isc_boolean_t append) {
9ee5efde7df57cbe70fb9b32c9d898e8ef7eca1eBob Halley return (-1);
9ee5efde7df57cbe70fb9b32c9d898e8ef7eca1eBob Halley return (-1);
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, mode);
e502b133d630bda0ee64c1e2ce6729d96750d8abMark Andrews return (-1);
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode);
e502b133d630bda0ee64c1e2ce6729d96750d8abMark Andrews ns_main_earlywarning("unlink '%s': failed", pidfile);
7ae96d882326357448f8f440c52f47ac1b1fa455Evan Hunt ns_main_earlywarning("unlink '%s': failed", lockfile);
7ae96d882326357448f8f440c52f47ac1b1fa455Evan Hunt * Ensure that a directory exists.
7ae96d882326357448f8f440c52f47ac1b1fa455Evan Hunt * NOTE: This function overwrites the '/' characters in 'filename' with
7ae96d882326357448f8f440c52f47ac1b1fa455Evan Hunt * nulls. The caller should copy the filename to a fresh buffer first.
598da901aba066208ab57ef5a44661f00f6c7dc6Mark Andrewsmkdirpath(char *filename, void (*report)(const char *, ...)) {
fb8db7fc3f3ea597a959e4c8ac42247fd78ca887Mark Andrews * Handle "//", "/./" and "/../" in path.
598da901aba066208ab57ef5a44661f00f6c7dc6Mark Andrews mode = S_IRUSR | S_IWUSR | S_IXUSR; /* u=rwx */
598da901aba066208ab57ef5a44661f00f6c7dc6Mark Andrews return (-1);
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt#if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID)
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt#if !defined(HAVE_SETEUID) && defined(HAVE_SETRESUID)
3e12c54de2238dc90bae06a2e083e4976120bad5Automatic Updater isc__strerror(errno, strbuf, sizeof(strbuf));
de3200acf43b23858f19f9f45b71a745fb3728c0Mark Andrews ns_main_earlywarning("unable to set effective gid to %ld: %s",
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt if (getresgid(&tmpg, &oldgid, &tmpg) == -1 || oldgid != gid) {
3e12c54de2238dc90bae06a2e083e4976120bad5Automatic Updater isc__strerror(errno, strbuf, sizeof(strbuf));
de3200acf43b23858f19f9f45b71a745fb3728c0Mark Andrews ns_main_earlywarning("unable to set effective uid to %ld: %s",
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt if (getresuid(&tmpu, &olduid, &tmpu) == -1 || olduid != uid) {
3a875400473e5c06199272a1292ed84646990e2fEvan Huntns_os_openfile(const char *filename, mode_t mode, isc_boolean_t switch_user) {
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt * Make the containing directory if it doesn't exist.
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt ns_main_earlywarning("couldn't strdup() '%s': %s",
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt /* Set UID/GID to the one we'll be running with eventually */
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt /* Restore UID/GID to root */
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt#endif /* HAVE_LINUXTHREADS */
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt "permissions to open "
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt "directory permissions "
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt "or reconfigure the filename.");
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt#else /* HAVE_LINUXTHREADS */
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt "directory permissions "
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt "or reconfigure the filename.");
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt#endif /* HAVE_LINUXTHREADS */
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt ns_main_earlywarning("could not open file '%s': %s",
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt ns_main_earlywarning("could not fdopen() file '%s': %s",
93e6ebcd0a0f044ba2add424c265b5e0bb4c8afdMark Andrewsns_os_writepidfile(const char *filename, isc_boolean_t first_time) {
93e6ebcd0a0f044ba2add424c265b5e0bb4c8afdMark Andrews void (*report)(const char *, ...);
9ee5efde7df57cbe70fb9b32c9d898e8ef7eca1eBob Halley * The caller must ensure any required synchronization.
93e6ebcd0a0f044ba2add424c265b5e0bb4c8afdMark Andrews report = first_time ? ns_main_earlyfatal : ns_main_earlywarning;
3a875400473e5c06199272a1292ed84646990e2fEvan Hunt (*report)("couldn't strdup() '%s': %s", filename, strbuf);
d869bc7685f47ba0c18f6343d3eee414aac1ebb5Mark Andrews fh = ns_os_openfile(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH,
5d98cf67b32d785aca1a72ea1dc4d559fab39208Mark Andrews (*report)("fprintf() to pid file '%s' failed", filename);
5d98cf67b32d785aca1a72ea1dc4d559fab39208Mark Andrews (*report)("fflush() to pid file '%s' failed", filename);
7ae96d882326357448f8f440c52f47ac1b1fa455Evan Hunt * Make the containing directory if it doesn't exist.
7ae96d882326357448f8f440c52f47ac1b1fa455Evan Hunt ns_main_earlyfatal("couldn't allocate memory for '%s': %s",
7ae96d882326357448f8f440c52f47ac1b1fa455Evan Hunt int ret = mkdirpath(lockfile, ns_main_earlywarning);
7ae96d882326357448f8f440c52f47ac1b1fa455Evan Hunt ns_main_earlywarning("couldn't create '%s'", filename);
47d837a49967a6a1b290024f5efb0669276013b1Mukund Sivaraman * ns_os_openfile() uses safeopen() which removes any existing
47d837a49967a6a1b290024f5efb0669276013b1Mukund Sivaraman * files. We can't use that here.
47d837a49967a6a1b290024f5efb0669276013b1Mukund Sivaraman singletonfd = open(filename, O_WRONLY | O_CREAT,
47d837a49967a6a1b290024f5efb0669276013b1Mukund Sivaraman /* Non-blocking (does not wait for lock) */
47d837a49967a6a1b290024f5efb0669276013b1Mukund Sivaraman if (fcntl(singletonfd, F_SETLK, &lock) == -1) {
df7596a03eea7f1c2df89bd63d3bd4b73f274565Mark Andrews return ((n == 0) ? ISC_R_SUCCESS : ISC_R_FAILURE);
cf300e03de3df3ff422db922520bf07c686c86daMark Andrewsstatic char *
cf300e03de3df3ff422db922520bf07c686c86daMark Andrewsns_os_shutdownmsg(char *command, isc_buffer_t *text) {
cf300e03de3df3ff422db922520bf07c686c86daMark Andrews unsigned int n;
cf300e03de3df3ff422db922520bf07c686c86daMark Andrews /* Skip the command name. */
cf300e03de3df3ff422db922520bf07c686c86daMark Andrews /* Only send a message if it is complete. */
a360461b34c8cff31c66ef18d872fc2f04be395bMark Andrews if (n > 0 && n < isc_buffer_availablelength(text))
7cd594b8427fe742d44295790ba367e1de22a47dEvan Hunt snprintf(unamebuf, sizeof(unamebuf), "unknown architecture");
f02c22d58ac88777655e0b407b22b07864d39184Evan Hunt "%s %s %s %s",
f02c22d58ac88777655e0b407b22b07864d39184Evan Hunt uts.sysname, uts.machine, uts.release, uts.version);
7cd594b8427fe742d44295790ba367e1de22a47dEvan Hunt snprintf(unamebuf, sizeof(unamebuf), "unknown architecture");