/* * util.c - routeup/tlsdated utility functions * Copyright (c) 2012 The Chromium Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "config.h" #include <grp.h> #include <pwd.h> #include <stdarg.h> #include <stdio.h> #include <sys/types.h> #if !_PLAN9_SOURCE #include <syslog.h> #endif #include <unistd.h> #include "src/util.h" /** helper function to print message and die */ void die (const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); exit(1); } /** helper function for 'verbose' output */ void verb (const char *fmt, ...) { va_list ap; if (! verbose) return; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } #if !_PLAN9_SOURCE void API logat(int isverbose, const char *fmt, ...) { if (isverbose && !verbose) return; va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); va_end(ap); va_start(ap, fmt); vsyslog(LOG_INFO, fmt, ap); va_end(ap); } #endif void drop_privs_to (const char *user, const char *group, const char **supp_groups) { #if !_PLAN9_SOURCE uid_t uid; gid_t gid; struct passwd *pw; struct group *gr; /* TODO(garnold) Implement supplementary group support. */ if (supp_groups) die ("Supplementary groups not supported\n"); if (0 != getuid ()) return; /* not running as root to begin with; should (!) be harmless to continue without dropping to 'nobody' (setting time will fail in the end) */ pw = getpwnam(user); gr = getgrnam(group); if (NULL == pw) die ("Failed to obtain UID for `%s'\n", user); if (NULL == gr) die ("Failed to obtain GID for `%s'\n", group); uid = pw->pw_uid; if (0 == uid) die ("UID for `%s' is 0, refusing to run SSL\n", user); gid = pw->pw_gid; if (0 == gid || 0 == gr->gr_gid) die ("GID for `%s' is 0, refusing to run SSL\n", user); if (pw->pw_gid != gr->gr_gid) die ("GID for `%s' is not `%s' as expected, refusing to run SSL\n", user, group); if (0 != initgroups((const char *)user, gr->gr_gid)) die ("Unable to initgroups for `%s' in group `%s' as expected\n", user, group); #ifdef HAVE_SETRESGID if (0 != setresgid (gid, gid, gid)) die ("Failed to setresgid: %s\n", strerror (errno)); #else if (0 != (setgid (gid) | setegid (gid))) die ("Failed to setgid: %s\n", strerror (errno)); #endif #ifdef HAVE_SETRESUID if (0 != setresuid (uid, uid, uid)) die ("Failed to setresuid: %s\n", strerror (errno)); #else if (0 != (setuid (uid) | seteuid (uid))) die ("Failed to setuid: %s\n", strerror (errno)); #endif #endif /* !_PLAN9_SOURCE */ }