1/* 2 * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Portions Copyright (c) 2009 Apple Inc. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#include "kdc_locl.h" 37#ifdef HAVE_UTIL_H 38#include <util.h> 39#endif 40 41#ifdef __APPLE__ 42#include <sandbox.h> 43 44int sandbox_flag = 1; 45#endif 46 47#ifdef HAVE_CAPNG 48#include <cap-ng.h> 49#endif 50 51static void terminated(void *ctx) __attribute__((noreturn)); 52 53 54#ifdef SUPPORT_DETACH 55int detach_from_console = -1; 56#endif 57 58/* 59 * Allow dropping root bit, since heimdal reopens the database all the 60 * time the database needs to be owned by the user you are switched 61 * too. A better solution is to split the kdc in to more processes and 62 * run the network facing part with very low privilege. 63 */ 64 65static void 66switch_environment(void) 67{ 68#ifdef HAVE_GETEUID 69 if ((runas_string || chroot_string) && geteuid() != 0) 70 errx(1, "no running as root, can't switch user/chroot"); 71 72 if (chroot_string && chroot(chroot_string) != 0) 73 errx(1, "chroot(%s)", "chroot_string failed"); 74 75 if (runas_string) { 76 struct passwd *pw; 77 78 pw = getpwnam(runas_string); 79 if (pw == NULL) 80 errx(1, "unknown user %s", runas_string); 81 82 if (initgroups(pw->pw_name, pw->pw_gid) < 0) 83 err(1, "initgroups failed"); 84 85#ifndef HAVE_CAPNG 86 if (setgid(pw->pw_gid) < 0) 87 err(1, "setgid(%s) failed", runas_string); 88 89 if (setuid(pw->pw_uid) < 0) 90 err(1, "setuid(%s)", runas_string); 91#else 92 capng_clear (CAPNG_EFFECTIVE | CAPNG_PERMITTED); 93 if (capng_updatev (CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, 94 CAP_NET_BIND_SERVICE, CAP_SETPCAP, -1) < 0) 95 err(1, "capng_updateev"); 96 97 if (capng_change_id(pw->pw_uid, pw->pw_gid, 98 CAPNG_CLEAR_BOUNDING) < 0) 99 err(1, "capng_change_id(%s)", runas_string); 100#endif 101 } 102#endif 103} 104 105static krb5_context context; 106static krb5_kdc_configuration *config; 107 108static heim_array_t 109get_realms(void) 110{ 111 heim_array_t array; 112 char **realms, **r; 113 unsigned int i; 114 int ret; 115 116 array = heim_array_create(); 117 118 for(i = 0; i < config->num_db; i++) { 119 120 if (config->db[i]->hdb_get_realms == NULL) 121 continue; 122 123 ret = (config->db[i]->hdb_get_realms)(context, config->db[i], &realms); 124 if (ret == 0) { 125 for (r = realms; r && *r; r++) { 126 heim_string_t s = heim_string_create(*r); 127 if (s) 128 heim_array_append_value(array, s); 129 heim_release(s); 130 } 131 krb5_free_host_realm(context, realms); 132 } 133 } 134 135 return array; 136} 137 138static void 139terminated(void *ctx) 140{ 141 kdc_log(context, config, 0, "Terminated: %s", (char *)ctx); 142 exit(1); 143} 144 145int 146main(int argc, char **argv) 147{ 148 krb5_error_code ret; 149 150 setprogname(argv[0]); 151 152 ret = krb5_init_context(&context); 153 if (ret == KRB5_CONFIG_BADFORMAT) 154 errx (1, "krb5_init_context failed to parse configuration file"); 155 else if (ret) 156 errx (1, "krb5_init_context failed: %d", ret); 157 158 ret = krb5_kt_register(context, &hdb_kt_ops); 159 if (ret) 160 errx (1, "krb5_kt_register(HDB) failed: %d", ret); 161 162 config = configure(context, argc, argv); 163 164#ifdef SIGPIPE 165#ifdef HAVE_SIGACTION 166 { 167 struct sigaction sa; 168 169 sa.sa_flags = 0; 170 sigemptyset(&sa.sa_mask); 171 172 sa.sa_handler = SIG_IGN; 173 sigaction(SIGPIPE, &sa, NULL); 174 } 175#else 176 signal(SIGPIPE, SIG_IGN); 177#endif 178#endif /* SIGPIPE */ 179 180 181 182#ifdef SUPPORT_DETACH 183 if (detach_from_console) 184 daemon(0, 0); 185#endif 186#ifdef __APPLE__ 187 if (sandbox_flag) { 188 char *errorstring; 189 ret = sandbox_init("kdc", SANDBOX_NAMED, &errorstring); 190 if (ret) 191 errx(1, "sandbox_init failed: %d: %s", ret, errorstring); 192 } 193 bonjour_announce(get_realms); 194#endif /* __APPLE__ */ 195 pidfile(NULL); 196 197 switch_environment(); 198 199 setup_listeners(context, config, listen_on_ipc, listen_on_network); 200 201 heim_sipc_signal_handler(SIGINT, terminated, "SIGINT"); 202 heim_sipc_signal_handler(SIGTERM, terminated, "SIGTERM"); 203#ifdef SIGXCPU 204 heim_sipc_signal_handler(SIGXCPU, terminated, "CPU time limit exceeded"); 205#endif 206 207 heim_ipc_main(); 208} 209