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 HAVE_CAPNG 42 #include <cap-ng.h> 43 #endif 44 45 sig_atomic_t exit_flag = 0; 46 47 #ifdef SUPPORT_DETACH 48 int detach_from_console = -1; 49 #endif 50 51 static RETSIGTYPE 52 sigterm(int sig) 53 { 54 exit_flag = sig; 55 } 56 57 /* 58 * Allow dropping root bit, since heimdal reopens the database all the 59 * time the database needs to be owned by the user you are switched 60 * too. A better solution is to split the kdc in to more processes and 61 * run the network facing part with very low privilege. 62 */ 63 64 static void 65 switch_environment(void) 66 { 67 #ifdef HAVE_GETEUID 68 if ((runas_string || chroot_string) && geteuid() != 0) 69 errx(1, "no running as root, can't switch user/chroot"); 70 71 if (chroot_string && chroot(chroot_string) != 0) 72 errx(1, "chroot(%s)", "chroot_string failed"); 73 74 if (runas_string) { 75 struct passwd *pw; 76 77 pw = getpwnam(runas_string); 78 if (pw == NULL) 79 errx(1, "unknown user %s", runas_string); 80 81 if (initgroups(pw->pw_name, pw->pw_gid) < 0) 82 err(1, "initgroups failed"); 83 84 #ifndef HAVE_CAPNG 85 if (setgid(pw->pw_gid) < 0) 86 err(1, "setgid(%s) failed", runas_string); 87 88 if (setuid(pw->pw_uid) < 0) 89 err(1, "setuid(%s)", runas_string); 90 #else 91 capng_clear (CAPNG_EFFECTIVE | CAPNG_PERMITTED); 92 if (capng_updatev (CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, 93 CAP_NET_BIND_SERVICE, CAP_SETPCAP, -1) < 0) 94 err(1, "capng_updateev"); 95 96 if (capng_change_id(pw->pw_uid, pw->pw_gid, 97 CAPNG_CLEAR_BOUNDING) < 0) 98 err(1, "capng_change_id(%s)", runas_string); 99 #endif 100 } 101 #endif 102 } 103 104 105 int 106 main(int argc, char **argv) 107 { 108 krb5_error_code ret; 109 krb5_context context; 110 krb5_kdc_configuration *config; 111 112 setprogname(argv[0]); 113 114 ret = krb5_init_context(&context); 115 if (ret == KRB5_CONFIG_BADFORMAT) 116 errx (1, "krb5_init_context failed to parse configuration file"); 117 else if (ret) 118 errx (1, "krb5_init_context failed: %d", ret); 119 120 ret = krb5_kt_register(context, &hdb_kt_ops); 121 if (ret) 122 errx (1, "krb5_kt_register(HDB) failed: %d", ret); 123 124 config = configure(context, argc, argv); 125 126 #ifdef HAVE_SIGACTION 127 { 128 struct sigaction sa; 129 130 sa.sa_flags = 0; 131 sa.sa_handler = sigterm; 132 sigemptyset(&sa.sa_mask); 133 134 sigaction(SIGINT, &sa, NULL); 135 sigaction(SIGTERM, &sa, NULL); 136 #ifdef SIGXCPU 137 sigaction(SIGXCPU, &sa, NULL); 138 #endif 139 140 sa.sa_handler = SIG_IGN; 141 #ifdef SIGPIPE 142 sigaction(SIGPIPE, &sa, NULL); 143 #endif 144 } 145 #else 146 signal(SIGINT, sigterm); 147 signal(SIGTERM, sigterm); 148 #ifdef SIGXCPU 149 signal(SIGXCPU, sigterm); 150 #endif 151 #ifdef SIGPIPE 152 signal(SIGPIPE, SIG_IGN); 153 #endif 154 #endif 155 #ifdef SUPPORT_DETACH 156 if (detach_from_console) 157 daemon(0, 0); 158 #endif 159 #ifdef __APPLE__ 160 bonjour_announce(context, config); 161 #endif 162 pidfile(NULL); 163 164 switch_environment(); 165 166 loop(context, config); 167 krb5_free_context(context); 168 return 0; 169 } 170