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 51#ifdef SUPPORT_DETACH 52int detach_from_console = -1; 53#endif 54 55/* 56 * Allow dropping root bit, since heimdal reopens the database all the 57 * time the database needs to be owned by the user you are switched 58 * too. A better solution is to split the kdc in to more processes and 59 * run the network facing part with very low privilege. 60 */ 61 62static void 63switch_environment(void) 64{ 65#ifdef HAVE_GETEUID 66 if ((runas_string || chroot_string) && geteuid() != 0) 67 errx(1, "no running as root, can't switch user/chroot"); 68 69 if (chroot_string && chroot(chroot_string) != 0) 70 errx(1, "chroot(%s)", "chroot_string failed"); 71 72 if (runas_string) { 73 struct passwd *pw; 74 75 pw = getpwnam(runas_string); 76 if (pw == NULL) 77 errx(1, "unknown user %s", runas_string); 78 79 if (initgroups(pw->pw_name, pw->pw_gid) < 0) 80 err(1, "initgroups failed"); 81 82#ifndef HAVE_CAPNG 83 if (setgid(pw->pw_gid) < 0) 84 err(1, "setgid(%s) failed", runas_string); 85 86 if (setuid(pw->pw_uid) < 0) 87 err(1, "setuid(%s)", runas_string); 88#else 89 capng_clear (CAPNG_EFFECTIVE | CAPNG_PERMITTED); 90 if (capng_updatev (CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, 91 CAP_NET_BIND_SERVICE, CAP_SETPCAP, -1) < 0) 92 err(1, "capng_updateev"); 93 94 if (capng_change_id(pw->pw_uid, pw->pw_gid, 95 CAPNG_CLEAR_BOUNDING) < 0) 96 err(1, "capng_change_id(%s)", runas_string); 97#endif 98 } 99#endif 100} 101 102static krb5_context context; 103static krb5_kdc_configuration *config; 104 105static heim_array_t 106get_realms(void) 107{ 108 heim_array_t array; 109 char **realms, **r; 110 unsigned int i; 111 int ret; 112 113 array = heim_array_create(); 114 115 for(i = 0; i < config->num_db; i++) { 116 117 if (config->db[i]->hdb_get_realms == NULL) 118 continue; 119 120 ret = (config->db[i]->hdb_get_realms)(context, config->db[i], &realms); 121 if (ret == 0) { 122 for (r = realms; r && *r; r++) { 123 heim_string_t s = heim_string_create(*r); 124 if (s) 125 heim_array_append_value(array, s); 126 heim_release(s); 127 } 128 krb5_free_host_realm(context, realms); 129 } 130 } 131 132 return array; 133} 134 135static void 136terminated(void *ctx) 137{ 138 kdc_log(context, config, 0, "Terminated: %s", (char *)ctx); 139 exit(1); 140} 141 142int 143main(int argc, char **argv) 144{ 145 krb5_error_code ret; 146 147 setprogname(argv[0]); 148 149 ret = krb5_init_context(&context); 150 if (ret == KRB5_CONFIG_BADFORMAT) 151 errx (1, "krb5_init_context failed to parse configuration file"); 152 else if (ret) 153 errx (1, "krb5_init_context failed: %d", ret); 154 155 ret = krb5_kt_register(context, &hdb_kt_ops); 156 if (ret) 157 errx (1, "krb5_kt_register(HDB) failed: %d", ret); 158 159 config = configure(context, argc, argv); 160 161#ifdef SIGPIPE 162#ifdef HAVE_SIGACTION 163 { 164 struct sigaction sa; 165 166 sa.sa_flags = 0; 167 sigemptyset(&sa.sa_mask); 168 169 sa.sa_handler = SIG_IGN; 170 sigaction(SIGPIPE, &sa, NULL); 171 } 172#else 173 signal(SIGPIPE, SIG_IGN); 174#endif 175#endif /* SIGPIPE */ 176 177 178 179#ifdef SUPPORT_DETACH 180 if (detach_from_console) 181 daemon(0, 0); 182#endif 183#ifdef __APPLE__ 184 if (sandbox_flag) { 185 char *errorstring; 186 ret = sandbox_init("kdc", SANDBOX_NAMED, &errorstring); 187 if (ret) 188 errx(1, "sandbox_init failed: %d: %s", ret, errorstring); 189 } 190 bonjour_announce(get_realms); 191#endif /* __APPLE__ */ 192 pidfile(NULL); 193 194 switch_environment(); 195 196 setup_listeners(context, config, listen_on_ipc, listen_on_network); 197 198 heim_sipc_signal_handler(SIGINT, terminated, "SIGINT"); 199 heim_sipc_signal_handler(SIGTERM, terminated, "SIGTERM"); 200#ifdef SIGXCPU 201 heim_sipc_signal_handler(SIGXCPU, terminated, "CPU time limit exceeded"); 202#endif 203 204 heim_ipc_main(); 205 206 krb5_free_context(context); 207 return 0; 208} 209