hx509: For times before 2050 use UTCTime (fix pasto)
[heimdal.git] / kadmin / init.c
blob8b025e112f8a45344c4f61c1a26516931a076f66
1 /*
2 * Copyright (c) 1997-2004 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
36 #include "kadmin_locl.h"
37 #include "kadmin-commands.h"
38 #include <kadm5/private.h>
40 #define CRE_DUP_OK 1
42 static kadm5_ret_t
43 create_random_entry(krb5_principal princ,
44 unsigned max_life,
45 unsigned max_rlife,
46 uint32_t attributes,
47 unsigned flags)
49 kadm5_principal_ent_rec ent;
50 kadm5_ret_t ret;
51 int mask = 0;
52 krb5_keyblock *keys;
53 int n_keys, i;
54 char *name;
56 ret = krb5_unparse_name(context, princ, &name);
57 if (ret) {
58 krb5_warn(context, ret, "failed to unparse principal name");
59 return ret;
62 memset(&ent, 0, sizeof(ent));
63 ent.principal = princ;
64 mask |= KADM5_PRINCIPAL;
65 if (max_life) {
66 ent.max_life = max_life;
67 mask |= KADM5_MAX_LIFE;
69 if (max_rlife) {
70 ent.max_renewable_life = max_rlife;
71 mask |= KADM5_MAX_RLIFE;
73 ent.attributes |= attributes | KRB5_KDB_DISALLOW_ALL_TIX;
74 mask |= KADM5_ATTRIBUTES | KADM5_KEY_DATA;
76 /* Create the entry with no keys or password */
77 ret = kadm5_s_create_principal_with_key(kadm_handle, &ent, mask);
78 if(ret) {
79 if (ret == KADM5_DUP && (flags & CRE_DUP_OK))
80 goto out;
81 krb5_warn(context, ret, "create_random_entry(%s): create failed",
82 name);
83 goto out;
86 /* Replace the string2key based keys with real random bytes */
87 ret = kadm5_randkey_principal(kadm_handle, princ, &keys, &n_keys);
88 if(ret) {
89 krb5_warn(context, ret, "create_random_entry(%s): randkey failed",
90 name);
91 goto out;
93 for(i = 0; i < n_keys; i++)
94 krb5_free_keyblock_contents(context, &keys[i]);
95 free(keys);
96 ret = kadm5_get_principal(kadm_handle, princ, &ent,
97 KADM5_PRINCIPAL | KADM5_ATTRIBUTES);
98 if(ret) {
99 krb5_warn(context, ret, "create_random_entry(%s): "
100 "unable to get principal", name);
101 goto out;
103 ent.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX);
104 ent.kvno = 1;
105 ret = kadm5_modify_principal(kadm_handle, &ent,
106 KADM5_ATTRIBUTES|KADM5_KVNO);
107 kadm5_free_principal_ent (kadm_handle, &ent);
108 if(ret) {
109 krb5_warn(context, ret, "create_random_entry(%s): "
110 "unable to modify principal", name);
111 goto out;
113 out:
114 free(name);
115 return ret;
118 extern int local_flag;
121 init(struct init_options *opt, int argc, char **argv)
123 kadm5_ret_t ret;
124 int i;
125 HDB *db;
126 krb5_deltat max_life = 0, max_rlife = 0;
128 if (!local_flag) {
129 krb5_warnx(context, "init is only available in local (-l) mode");
130 return 0;
133 if (opt->realm_max_ticket_life_string) {
134 if (str2deltat (opt->realm_max_ticket_life_string, &max_life) != 0) {
135 krb5_warnx (context, "unable to parse \"%s\"",
136 opt->realm_max_ticket_life_string);
137 return 0;
140 if (opt->realm_max_renewable_life_string) {
141 if (str2deltat (opt->realm_max_renewable_life_string, &max_rlife) != 0) {
142 krb5_warnx (context, "unable to parse \"%s\"",
143 opt->realm_max_renewable_life_string);
144 return 0;
148 db = _kadm5_s_get_db(kadm_handle);
150 ret = db->hdb_open(context, db, O_RDWR | O_CREAT, 0600);
151 if(ret){
152 krb5_warn(context, ret, "hdb_open");
153 return 0;
155 ret = kadm5_log_reinit(kadm_handle, 0);
156 if (ret)
157 krb5_err(context, 1, ret, "Failed iprop log initialization");
158 kadm5_log_end(kadm_handle);
159 db->hdb_close(context, db);
160 for(i = 0; i < argc; i++){
161 krb5_principal princ;
162 const char *realm = argv[i];
164 if (opt->realm_max_ticket_life_string == NULL) {
165 max_life = 0;
166 if(edit_deltat ("Realm max ticket life", &max_life, NULL, 0)) {
167 return 0;
170 if (opt->realm_max_renewable_life_string == NULL) {
171 max_rlife = 0;
172 if(edit_deltat("Realm max renewable ticket life", &max_rlife,
173 NULL, 0)) {
174 return 0;
178 /* Create `krbtgt/REALM' */
179 ret = krb5_make_principal(context, &princ, realm,
180 KRB5_TGS_NAME, realm, NULL);
181 if(ret)
182 return 0;
184 create_random_entry(princ, max_life, max_rlife, 0, 0);
185 krb5_free_principal(context, princ);
187 if (opt->bare_flag)
188 continue;
190 /* Create `kadmin/changepw' */
191 krb5_make_principal(context, &princ, realm,
192 "kadmin", "changepw", NULL);
194 * The Windows XP (at least) password changing protocol
195 * request the `kadmin/changepw' ticket with `renewable_ok,
196 * renewable, forwardable' and so fails if we disallow
197 * forwardable here.
199 create_random_entry(princ, 5*60, 5*60,
200 KRB5_KDB_DISALLOW_TGT_BASED|
201 KRB5_KDB_PWCHANGE_SERVICE|
202 KRB5_KDB_DISALLOW_POSTDATED|
203 KRB5_KDB_DISALLOW_RENEWABLE|
204 KRB5_KDB_DISALLOW_PROXIABLE|
205 KRB5_KDB_REQUIRES_PRE_AUTH,
207 krb5_free_principal(context, princ);
209 /* Create `kadmin/admin' */
210 krb5_make_principal(context, &princ, realm,
211 "kadmin", "admin", NULL);
212 create_random_entry(princ, 60*60, 60*60, KRB5_KDB_REQUIRES_PRE_AUTH, 0);
213 krb5_free_principal(context, princ);
215 /* Create `changepw/kerberos' (for v4 compat) */
216 krb5_make_principal(context, &princ, realm,
217 "changepw", "kerberos", NULL);
218 create_random_entry(princ, 60*60, 60*60,
219 KRB5_KDB_DISALLOW_TGT_BASED|
220 KRB5_KDB_PWCHANGE_SERVICE, 0);
222 krb5_free_principal(context, princ);
224 /* Create `kadmin/hprop' for database propagation */
225 krb5_make_principal(context, &princ, realm,
226 "kadmin", "hprop", NULL);
227 create_random_entry(princ, 60*60, 60*60,
228 KRB5_KDB_REQUIRES_PRE_AUTH|
229 KRB5_KDB_DISALLOW_TGT_BASED, 0);
230 krb5_free_principal(context, princ);
232 /* Create `WELLKNOWN/ANONYMOUS' for anonymous as-req */
233 krb5_make_principal(context, &princ, realm,
234 KRB5_WELLKNOWN_NAME, KRB5_ANON_NAME, NULL);
235 create_random_entry(princ, 60*60, 60*60,
236 KRB5_KDB_REQUIRES_PRE_AUTH, 0);
237 krb5_free_principal(context, princ);
239 /* Create `WELLKNOWN/FEDERATED' for GSS preauth */
240 krb5_make_principal(context, &princ, realm,
241 KRB5_WELLKNOWN_NAME, KRB5_FEDERATED_NAME, NULL);
242 create_random_entry(princ, 60*60, 60*60,
243 KRB5_KDB_REQUIRES_PRE_AUTH, 0);
244 krb5_free_principal(context, princ);
246 /* Create `WELLKNONW/org.h5l.fast-cookie@WELLKNOWN:ORG.H5L' for FAST cookie */
247 krb5_make_principal(context, &princ, KRB5_WELLKNOWN_ORG_H5L_REALM,
248 KRB5_WELLKNOWN_NAME, "org.h5l.fast-cookie", NULL);
249 create_random_entry(princ, 60*60, 60*60,
250 KRB5_KDB_REQUIRES_PRE_AUTH|
251 KRB5_KDB_DISALLOW_TGT_BASED|
252 KRB5_KDB_DISALLOW_ALL_TIX, CRE_DUP_OK);
253 krb5_free_principal(context, princ);
255 /* Create `default' */
257 kadm5_principal_ent_rec ent;
258 int mask = 0;
260 memset (&ent, 0, sizeof(ent));
261 mask |= KADM5_PRINCIPAL;
262 krb5_make_principal(context, &ent.principal, realm,
263 "default", NULL);
264 mask |= KADM5_MAX_LIFE;
265 ent.max_life = 24 * 60 * 60;
266 mask |= KADM5_MAX_RLIFE;
267 ent.max_renewable_life = 7 * ent.max_life;
268 ent.attributes = KRB5_KDB_DISALLOW_ALL_TIX;
269 mask |= KADM5_ATTRIBUTES;
271 ret = kadm5_create_principal(kadm_handle, &ent, mask, "");
272 if (ret)
273 krb5_err (context, 1, ret, "kadm5_create_principal");
275 krb5_free_principal(context, ent.principal);
278 return 0;