155682Smarkm/* 2233294Sstas * Copyright (c) 1997-2005 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 555682Smarkm * 6233294Sstas * Portions Copyright (c) 2009 Apple Inc. All rights reserved. 755682Smarkm * 8233294Sstas * Redistribution and use in source and binary forms, with or without 9233294Sstas * modification, are permitted provided that the following conditions 10233294Sstas * are met: 1155682Smarkm * 12233294Sstas * 1. Redistributions of source code must retain the above copyright 13233294Sstas * notice, this list of conditions and the following disclaimer. 1455682Smarkm * 15233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 16233294Sstas * notice, this list of conditions and the following disclaimer in the 17233294Sstas * documentation and/or other materials provided with the distribution. 1855682Smarkm * 19233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 20233294Sstas * may be used to endorse or promote products derived from this software 21233294Sstas * without specific prior written permission. 22233294Sstas * 23233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33233294Sstas * SUCH DAMAGE. 3455682Smarkm */ 3555682Smarkm 3655682Smarkm#include "kdc_locl.h" 37102644Snectar#ifdef HAVE_UTIL_H 38102644Snectar#include <util.h> 39102644Snectar#endif 4055682Smarkm 41233294Sstas#ifdef HAVE_CAPNG 42233294Sstas#include <cap-ng.h> 43233294Sstas#endif 4455682Smarkm 4555682Smarkmsig_atomic_t exit_flag = 0; 4655682Smarkm 47233294Sstas#ifdef SUPPORT_DETACH 48178825Sdfrint detach_from_console = -1; 49233294Sstas#endif 50102644Snectar 5155682Smarkmstatic RETSIGTYPE 5255682Smarkmsigterm(int sig) 5355682Smarkm{ 54178825Sdfr exit_flag = sig; 5555682Smarkm} 5655682Smarkm 57233294Sstas/* 58233294Sstas * Allow dropping root bit, since heimdal reopens the database all the 59233294Sstas * time the database needs to be owned by the user you are switched 60233294Sstas * too. A better solution is to split the kdc in to more processes and 61233294Sstas * run the network facing part with very low privilege. 62233294Sstas */ 63233294Sstas 64233294Sstasstatic void 65233294Sstasswitch_environment(void) 66233294Sstas{ 67233294Sstas#ifdef HAVE_GETEUID 68233294Sstas if ((runas_string || chroot_string) && geteuid() != 0) 69233294Sstas errx(1, "no running as root, can't switch user/chroot"); 70233294Sstas 71233294Sstas if (chroot_string && chroot(chroot_string) != 0) 72233294Sstas errx(1, "chroot(%s)", "chroot_string failed"); 73233294Sstas 74233294Sstas if (runas_string) { 75233294Sstas struct passwd *pw; 76233294Sstas 77233294Sstas pw = getpwnam(runas_string); 78233294Sstas if (pw == NULL) 79233294Sstas errx(1, "unknown user %s", runas_string); 80233294Sstas 81233294Sstas if (initgroups(pw->pw_name, pw->pw_gid) < 0) 82233294Sstas err(1, "initgroups failed"); 83233294Sstas 84233294Sstas#ifndef HAVE_CAPNG 85233294Sstas if (setgid(pw->pw_gid) < 0) 86233294Sstas err(1, "setgid(%s) failed", runas_string); 87233294Sstas 88233294Sstas if (setuid(pw->pw_uid) < 0) 89233294Sstas err(1, "setuid(%s)", runas_string); 90233294Sstas#else 91233294Sstas capng_clear (CAPNG_EFFECTIVE | CAPNG_PERMITTED); 92233294Sstas if (capng_updatev (CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, 93233294Sstas CAP_NET_BIND_SERVICE, CAP_SETPCAP, -1) < 0) 94233294Sstas err(1, "capng_updateev"); 95233294Sstas 96233294Sstas if (capng_change_id(pw->pw_uid, pw->pw_gid, 97233294Sstas CAPNG_CLEAR_BOUNDING) < 0) 98233294Sstas err(1, "capng_change_id(%s)", runas_string); 99233294Sstas#endif 100233294Sstas } 101233294Sstas#endif 102233294Sstas} 103233294Sstas 104233294Sstas 10555682Smarkmint 10655682Smarkmmain(int argc, char **argv) 10755682Smarkm{ 10855682Smarkm krb5_error_code ret; 109178825Sdfr krb5_context context; 110178825Sdfr krb5_kdc_configuration *config; 111178825Sdfr 11278527Sassar setprogname(argv[0]); 113233294Sstas 11472445Sassar ret = krb5_init_context(&context); 115178825Sdfr if (ret == KRB5_CONFIG_BADFORMAT) 116178825Sdfr errx (1, "krb5_init_context failed to parse configuration file"); 117178825Sdfr else if (ret) 11872445Sassar errx (1, "krb5_init_context failed: %d", ret); 11955682Smarkm 120178825Sdfr ret = krb5_kt_register(context, &hdb_kt_ops); 121178825Sdfr if (ret) 122178825Sdfr errx (1, "krb5_kt_register(HDB) failed: %d", ret); 12355682Smarkm 124178825Sdfr config = configure(context, argc, argv); 12555682Smarkm 12655682Smarkm#ifdef HAVE_SIGACTION 12755682Smarkm { 12855682Smarkm struct sigaction sa; 12955682Smarkm 13055682Smarkm sa.sa_flags = 0; 13155682Smarkm sa.sa_handler = sigterm; 13255682Smarkm sigemptyset(&sa.sa_mask); 13355682Smarkm 13455682Smarkm sigaction(SIGINT, &sa, NULL); 13572445Sassar sigaction(SIGTERM, &sa, NULL); 136233294Sstas#ifdef SIGXCPU 137178825Sdfr sigaction(SIGXCPU, &sa, NULL); 138233294Sstas#endif 139178825Sdfr 140178825Sdfr sa.sa_handler = SIG_IGN; 141233294Sstas#ifdef SIGPIPE 142178825Sdfr sigaction(SIGPIPE, &sa, NULL); 143233294Sstas#endif 14455682Smarkm } 14555682Smarkm#else 14655682Smarkm signal(SIGINT, sigterm); 14772445Sassar signal(SIGTERM, sigterm); 148233294Sstas#ifdef SIGXCPU 149178825Sdfr signal(SIGXCPU, sigterm); 150233294Sstas#endif 151233294Sstas#ifdef SIGPIPE 152178825Sdfr signal(SIGPIPE, SIG_IGN); 15355682Smarkm#endif 154233294Sstas#endif 155233294Sstas#ifdef SUPPORT_DETACH 156102644Snectar if (detach_from_console) 157102644Snectar daemon(0, 0); 158233294Sstas#endif 159233294Sstas#ifdef __APPLE__ 160233294Sstas bonjour_announce(context, config); 161233294Sstas#endif 16272445Sassar pidfile(NULL); 163233294Sstas 164233294Sstas switch_environment(); 165233294Sstas 166178825Sdfr loop(context, config); 16755682Smarkm krb5_free_context(context); 16855682Smarkm return 0; 16955682Smarkm} 170