Fix KRB-FX-CF2 for enctypes with non-dense keyspaces
[heimdal.git] / kdc / mit_dump.c
bloba584e8fc57f1e2ec9f8673a4e58001d41d186b81
1 /*
2 * Copyright (c) 2000 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #include "hprop.h"
36 extern krb5_error_code _hdb_mdb_value2entry(krb5_context context,
37 krb5_data *data,
38 krb5_kvno target_kvno,
39 hdb_entry *entry);
41 extern int _hdb_mit_dump2mitdb_entry(krb5_context context,
42 char *line,
43 krb5_storage *sp);
48 can have any number of princ stanzas.
49 format is as follows (only \n indicates newlines)
50 princ\t%d\t (%d is KRB5_KDB_V1_BASE_LENGTH, always 38)
51 %d\t (strlen of principal e.g. shadow/foo@ANDREW.CMU.EDU)
52 %d\t (number of tl_data)
53 %d\t (number of key data, e.g. how many keys for this user)
54 %d\t (extra data length)
55 %s\t (principal name)
56 %d\t (attributes)
57 %d\t (max lifetime, seconds)
58 %d\t (max renewable life, seconds)
59 %d\t (expiration, seconds since epoch or 2145830400 for never)
60 %d\t (password expiration, seconds, 0 for never)
61 %d\t (last successful auth, seconds since epoch)
62 %d\t (last failed auth, per above)
63 %d\t (failed auth count)
64 foreach tl_data 0 to number of tl_data - 1 as above
65 %d\t%d\t (data type, data length)
66 foreach tl_data 0 to length-1
67 %02x (tl data contents[element n])
68 except if tl_data length is 0
69 %d (always -1)
71 foreach key 0 to number of keys - 1 as above
72 %d\t%d\t (key data version, kvno)
73 foreach version 0 to key data version - 1 (a key or a salt)
74 %d\t%d\t(data type for this key, data length for this key)
75 foreach key data length 0 to length-1
76 %02x (key data contents[element n])
77 except if key_data length is 0
78 %d (always -1)
80 foreach extra data length 0 to length - 1
81 %02x (extra data part)
82 unless no extra data
83 %d (always -1)
84 ;\n
88 static char *
89 nexttoken(char **p)
91 char *q;
92 do {
93 q = strsep(p, " \t");
94 } while(q && *q == '\0');
95 return q;
98 #include <kadm5/admin.h>
100 /* XXX This is broken: what if the princ name has a \n?! */
101 static int
102 my_fgetln(FILE *f, char **buf, size_t *sz, size_t *len)
104 char *p, *n;
106 if (!*buf) {
107 *buf = malloc(*sz ? *sz : 2048);
108 if (!*buf)
109 return ENOMEM;
110 if (!*sz)
111 *sz = 2048;
113 *len = 0;
114 while ((p = fgets(&(*buf)[*len], *sz - *len, f))) {
115 *len = strlen(*buf);
116 if (feof(f))
117 return 0;
118 if (strchr(*buf, '\n'))
119 return 0;
120 n = realloc(*buf, *sz + (*sz >> 1));
121 if (!n) {
122 free(*buf);
123 *buf = NULL;
124 *sz = 0;
125 *len = 0;
126 return ENOMEM;
128 *buf = n;
129 *sz += *sz >> 1;
131 return 0; /* *len == 0 || no EOL -> EOF */
135 mit_prop_dump(void *arg, const char *file)
137 krb5_error_code ret;
138 size_t line_bufsz = 0;
139 size_t line_len = 0;
140 char *line = NULL;
141 int lineno = 0;
142 FILE *f;
143 struct hdb_entry_ex ent;
144 struct prop_data *pd = arg;
145 krb5_storage *sp = NULL;
146 krb5_data kdb_ent;
148 memset(&ent, 0, sizeof (ent));
149 f = fopen(file, "r");
150 if (f == NULL)
151 return errno;
153 ret = ENOMEM;
154 sp = krb5_storage_emem();
155 if (!sp)
156 goto out;
157 while ((ret = my_fgetln(f, &line, &line_bufsz, &line_len)) == 0 &&
158 !feof(f)) {
159 char *p = line;
160 char *q;
161 lineno++;
163 if(strncmp(line, "kdb5_util", strlen("kdb5_util")) == 0) {
164 int major;
165 q = nexttoken(&p);
166 if (strcmp(q, "kdb5_util"))
167 errx(1, "line %d: unknown version", lineno);
168 q = nexttoken(&p); /* load_dump */
169 if (strcmp(q, "load_dump"))
170 errx(1, "line %d: unknown version", lineno);
171 q = nexttoken(&p); /* load_dump */
172 if (strcmp(q, "version"))
173 errx(1, "line %d: unknown version", lineno);
174 q = nexttoken(&p); /* x.0 */
175 if (sscanf(q, "%d", &major) != 1)
176 errx(1, "line %d: unknown version", lineno);
177 if (major != 4 && major != 5 && major != 6)
178 errx(1, "unknown dump file format, got %d, expected 4-6",
179 major);
180 continue;
181 } else if(strncmp(p, "policy", strlen("policy")) == 0) {
182 warnx("line: %d: ignoring policy (not supported)", lineno);
183 continue;
184 } else if(strncmp(p, "princ", strlen("princ")) != 0) {
185 warnx("line %d: not a principal", lineno);
186 continue;
188 krb5_storage_truncate(sp, 0);
189 ret = _hdb_mit_dump2mitdb_entry(pd->context, line, sp);
190 if (ret) {
191 if (ret > 0)
192 warn("line: %d: failed to parse; ignoring", lineno);
193 else
194 warnx("line: %d: failed to parse; ignoring", lineno);
195 continue;
197 ret = krb5_storage_to_data(sp, &kdb_ent);
198 if (ret) break;
199 ret = _hdb_mdb_value2entry(pd->context, &kdb_ent, 0, &ent.entry);
200 krb5_data_free(&kdb_ent);
201 if (ret) {
202 warnx("line: %d: failed to store; ignoring", lineno);
203 continue;
205 ret = v5_prop(pd->context, NULL, &ent, arg);
206 hdb_free_entry(pd->context, &ent);
207 if (ret) break;
210 out:
211 fclose(f);
212 free(line);
213 if (sp)
214 krb5_storage_free(sp);
215 if (ret && ret == ENOMEM)
216 errx(1, "out of memory");
217 if (ret)
218 errx(1, "line %d: problem parsing dump line", lineno);
219 return ret;