init.c revision 1.2
1/* $NetBSD: init.c,v 1.2 2017/01/28 21:31:44 christos Exp $ */ 2 3/* 4 * Copyright (c) 1997-2004 Kungliga Tekniska H��gskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Portions Copyright (c) 2009 Apple Inc. All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * 3. Neither the name of the Institute nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 38#include "kadmin_locl.h" 39#include "kadmin-commands.h" 40#include <kadm5/private.h> 41 42#define CRE_DUP_OK 1 43 44static kadm5_ret_t 45create_random_entry(krb5_principal princ, 46 unsigned max_life, 47 unsigned max_rlife, 48 uint32_t attributes, 49 unsigned flags) 50{ 51 kadm5_principal_ent_rec ent; 52 kadm5_ret_t ret; 53 int mask = 0; 54 krb5_keyblock *keys; 55 int n_keys, i; 56 char *name; 57 const char *password; 58 char pwbuf[512]; 59 60 random_password(pwbuf, sizeof(pwbuf)); 61 password = pwbuf; 62 63 ret = krb5_unparse_name(context, princ, &name); 64 if (ret) { 65 krb5_warn(context, ret, "failed to unparse principal name"); 66 return ret; 67 } 68 69 memset(&ent, 0, sizeof(ent)); 70 ent.principal = princ; 71 mask |= KADM5_PRINCIPAL; 72 if (max_life) { 73 ent.max_life = max_life; 74 mask |= KADM5_MAX_LIFE; 75 } 76 if (max_rlife) { 77 ent.max_renewable_life = max_rlife; 78 mask |= KADM5_MAX_RLIFE; 79 } 80 ent.attributes |= attributes | KRB5_KDB_DISALLOW_ALL_TIX; 81 mask |= KADM5_ATTRIBUTES; 82 83 /* Create the entry with a random password */ 84 ret = kadm5_create_principal(kadm_handle, &ent, mask, password); 85 if(ret) { 86 if (ret == KADM5_DUP && (flags & CRE_DUP_OK)) 87 goto out; 88 krb5_warn(context, ret, "create_random_entry(%s): randkey failed", 89 name); 90 goto out; 91 } 92 93 /* Replace the string2key based keys with real random bytes */ 94 ret = kadm5_randkey_principal(kadm_handle, princ, &keys, &n_keys); 95 if(ret) { 96 krb5_warn(context, ret, "create_random_entry(%s): randkey failed", 97 name); 98 goto out; 99 } 100 for(i = 0; i < n_keys; i++) 101 krb5_free_keyblock_contents(context, &keys[i]); 102 free(keys); 103 ret = kadm5_get_principal(kadm_handle, princ, &ent, 104 KADM5_PRINCIPAL | KADM5_ATTRIBUTES); 105 if(ret) { 106 krb5_warn(context, ret, "create_random_entry(%s): " 107 "unable to get principal", name); 108 goto out; 109 } 110 ent.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX); 111 ent.kvno = 1; 112 ret = kadm5_modify_principal(kadm_handle, &ent, 113 KADM5_ATTRIBUTES|KADM5_KVNO); 114 kadm5_free_principal_ent (kadm_handle, &ent); 115 if(ret) { 116 krb5_warn(context, ret, "create_random_entry(%s): " 117 "unable to modify principal", name); 118 goto out; 119 } 120 out: 121 free(name); 122 return ret; 123} 124 125extern int local_flag; 126 127int 128init(struct init_options *opt, int argc, char **argv) 129{ 130 kadm5_ret_t ret; 131 int i; 132 HDB *db; 133 krb5_deltat max_life = 0, max_rlife = 0; 134 135 if (!local_flag) { 136 krb5_warnx(context, "init is only available in local (-l) mode"); 137 return 0; 138 } 139 140 if (opt->realm_max_ticket_life_string) { 141 if (str2deltat (opt->realm_max_ticket_life_string, &max_life) != 0) { 142 krb5_warnx (context, "unable to parse \"%s\"", 143 opt->realm_max_ticket_life_string); 144 return 0; 145 } 146 } 147 if (opt->realm_max_renewable_life_string) { 148 if (str2deltat (opt->realm_max_renewable_life_string, &max_rlife) != 0) { 149 krb5_warnx (context, "unable to parse \"%s\"", 150 opt->realm_max_renewable_life_string); 151 return 0; 152 } 153 } 154 155 db = _kadm5_s_get_db(kadm_handle); 156 157 ret = db->hdb_open(context, db, O_RDWR | O_CREAT, 0600); 158 if(ret){ 159 krb5_warn(context, ret, "hdb_open"); 160 return 0; 161 } 162 ret = kadm5_log_reinit(kadm_handle, 0); 163 if (ret) 164 krb5_err(context, 1, ret, "Failed iprop log initialization"); 165 kadm5_log_end(kadm_handle); 166 db->hdb_close(context, db); 167 for(i = 0; i < argc; i++){ 168 krb5_principal princ; 169 const char *realm = argv[i]; 170 171 if (opt->realm_max_ticket_life_string == NULL) { 172 max_life = 0; 173 if(edit_deltat ("Realm max ticket life", &max_life, NULL, 0)) { 174 return 0; 175 } 176 } 177 if (opt->realm_max_renewable_life_string == NULL) { 178 max_rlife = 0; 179 if(edit_deltat("Realm max renewable ticket life", &max_rlife, 180 NULL, 0)) { 181 return 0; 182 } 183 } 184 185 /* Create `krbtgt/REALM' */ 186 ret = krb5_make_principal(context, &princ, realm, 187 KRB5_TGS_NAME, realm, NULL); 188 if(ret) 189 return 0; 190 191 create_random_entry(princ, max_life, max_rlife, 0, 0); 192 krb5_free_principal(context, princ); 193 194 if (opt->bare_flag) 195 continue; 196 197 /* Create `kadmin/changepw' */ 198 krb5_make_principal(context, &princ, realm, 199 "kadmin", "changepw", NULL); 200 /* 201 * The Windows XP (at least) password changing protocol 202 * request the `kadmin/changepw' ticket with `renewable_ok, 203 * renewable, forwardable' and so fails if we disallow 204 * forwardable here. 205 */ 206 create_random_entry(princ, 5*60, 5*60, 207 KRB5_KDB_DISALLOW_TGT_BASED| 208 KRB5_KDB_PWCHANGE_SERVICE| 209 KRB5_KDB_DISALLOW_POSTDATED| 210 KRB5_KDB_DISALLOW_RENEWABLE| 211 KRB5_KDB_DISALLOW_PROXIABLE| 212 KRB5_KDB_REQUIRES_PRE_AUTH, 213 0); 214 krb5_free_principal(context, princ); 215 216 /* Create `kadmin/admin' */ 217 krb5_make_principal(context, &princ, realm, 218 "kadmin", "admin", NULL); 219 create_random_entry(princ, 60*60, 60*60, KRB5_KDB_REQUIRES_PRE_AUTH, 0); 220 krb5_free_principal(context, princ); 221 222 /* Create `changepw/kerberos' (for v4 compat) */ 223 krb5_make_principal(context, &princ, realm, 224 "changepw", "kerberos", NULL); 225 create_random_entry(princ, 60*60, 60*60, 226 KRB5_KDB_DISALLOW_TGT_BASED| 227 KRB5_KDB_PWCHANGE_SERVICE, 0); 228 229 krb5_free_principal(context, princ); 230 231 /* Create `kadmin/hprop' for database propagation */ 232 krb5_make_principal(context, &princ, realm, 233 "kadmin", "hprop", NULL); 234 create_random_entry(princ, 60*60, 60*60, 235 KRB5_KDB_REQUIRES_PRE_AUTH| 236 KRB5_KDB_DISALLOW_TGT_BASED, 0); 237 krb5_free_principal(context, princ); 238 239 /* Create `WELLKNOWN/ANONYMOUS' for anonymous as-req */ 240 krb5_make_principal(context, &princ, realm, 241 KRB5_WELLKNOWN_NAME, KRB5_ANON_NAME, NULL); 242 create_random_entry(princ, 60*60, 60*60, 243 KRB5_KDB_REQUIRES_PRE_AUTH, 0); 244 krb5_free_principal(context, princ); 245 246 247 /* Create `WELLKNONW/org.h5l.fast-cookie@WELLKNOWN:ORG.H5L' for FAST cookie */ 248 krb5_make_principal(context, &princ, KRB5_WELLKNOWN_ORG_H5L_REALM, 249 KRB5_WELLKNOWN_NAME, "org.h5l.fast-cookie", NULL); 250 create_random_entry(princ, 60*60, 60*60, 251 KRB5_KDB_REQUIRES_PRE_AUTH| 252 KRB5_KDB_DISALLOW_TGT_BASED| 253 KRB5_KDB_DISALLOW_ALL_TIX, CRE_DUP_OK); 254 krb5_free_principal(context, princ); 255 256 /* Create `default' */ 257 { 258 kadm5_principal_ent_rec ent; 259 int mask = 0; 260 261 memset (&ent, 0, sizeof(ent)); 262 mask |= KADM5_PRINCIPAL; 263 krb5_make_principal(context, &ent.principal, realm, 264 "default", NULL); 265 mask |= KADM5_MAX_LIFE; 266 ent.max_life = 24 * 60 * 60; 267 mask |= KADM5_MAX_RLIFE; 268 ent.max_renewable_life = 7 * ent.max_life; 269 ent.attributes = KRB5_KDB_DISALLOW_ALL_TIX; 270 mask |= KADM5_ATTRIBUTES; 271 272 ret = kadm5_create_principal(kadm_handle, &ent, mask, ""); 273 if (ret) 274 krb5_err (context, 1, ret, "kadm5_create_principal"); 275 276 krb5_free_principal(context, ent.principal); 277 } 278 } 279 return 0; 280} 281