xref: /freebsd/crypto/heimdal/kdc/mit_dump.c (revision 5000d023a446b81f6d45ed59aa379607ec814f01)
1 /*
2  * Copyright (c) 2000 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
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.
16  *
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.
20  *
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.
32  */
33 
34 #include "hprop.h"
35 
36 extern krb5_error_code _hdb_mdb_value2entry(krb5_context context,
37                                             krb5_data *data,
38                                             krb5_kvno target_kvno,
39                                             hdb_entry *entry);
40 
41 extern int _hdb_mit_dump2mitdb_entry(krb5_context context,
42                                      char *line,
43                                      krb5_storage *sp);
44 
45 
46 
47 /*
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)
70   \t
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)
79     \t
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
85 
86 */
87 
88 static char *
nexttoken(char ** p)89 nexttoken(char **p)
90 {
91     char *q;
92     do {
93 	q = strsep(p, " \t");
94     } while(q && *q == '\0');
95     return q;
96 }
97 
98 #include <kadm5/admin.h>
99 
100 static int
my_fgetln(FILE * f,char ** buf,size_t * sz,size_t * len)101 my_fgetln(FILE *f, char **buf, size_t *sz, size_t *len)
102 {
103     char *p, *n;
104 
105     if (!*buf) {
106         *buf = malloc(*sz ? *sz : 2048);
107         if (!*buf)
108             return ENOMEM;
109         if (!*sz)
110             *sz = 2048;
111     }
112     *len = 0;
113     while ((p = fgets(&(*buf)[*len], *sz, f))) {
114         if (strcspn(*buf, "\r\n") || feof(f)) {
115             *len = strlen(*buf);
116             return 0;
117         }
118         *len += strlen(&(*buf)[*len]); /* *len should be == *sz */
119         n = realloc(buf, *sz + (*sz >> 1));
120         if (!n) {
121             free(*buf);
122             *buf = NULL;
123             *sz = 0;
124             *len = 0;
125             return ENOMEM;
126         }
127         *buf = n;
128         *sz += *sz >> 1;
129     }
130     return 0; /* *len == 0 || no EOL -> EOF */
131 }
132 
133 int
mit_prop_dump(void * arg,const char * file)134 mit_prop_dump(void *arg, const char *file)
135 {
136     krb5_error_code ret;
137     size_t line_bufsz = 0;
138     size_t line_len = 0;
139     char *line = NULL;
140     int lineno = 0;
141     FILE *f;
142     struct hdb_entry_ex ent;
143     struct prop_data *pd = arg;
144     krb5_storage *sp = NULL;
145     krb5_data kdb_ent;
146 
147     memset(&ent, 0, sizeof (ent));
148     f = fopen(file, "r");
149     if (f == NULL)
150 	return errno;
151 
152     ret = ENOMEM;
153     sp = krb5_storage_emem();
154     if (!sp)
155         goto out;
156     while ((ret = my_fgetln(f, &line, &line_bufsz, &line_len)) == 0) {
157         char *p = line;
158         char *q;
159         lineno++;
160 
161 	if(strncmp(line, "kdb5_util", strlen("kdb5_util")) == 0) {
162 	    int major;
163             q = nexttoken(&p);
164             if (strcmp(q, "kdb5_util"))
165                 errx(1, "line %d: unknown version", lineno);
166 	    q = nexttoken(&p); /* load_dump */
167 	    if (strcmp(q, "load_dump"))
168 		errx(1, "line %d: unknown version", lineno);
169 	    q = nexttoken(&p); /* load_dump */
170 	    if (strcmp(q, "version"))
171 		errx(1, "line %d: unknown version", lineno);
172 	    q = nexttoken(&p); /* x.0 */
173 	    if (sscanf(q, "%d", &major) != 1)
174 		errx(1, "line %d: unknown version", lineno);
175 	    if (major != 4 && major != 5 && major != 6)
176 		errx(1, "unknown dump file format, got %d, expected 4-6",
177 		     major);
178 	    continue;
179 	} else if(strncmp(p, "policy", strlen("policy")) == 0) {
180             warnx("line: %d: ignoring policy (not supported)", lineno);
181 	    continue;
182 	} else if(strncmp(p, "princ", strlen("princ")) != 0) {
183 	    warnx("line %d: not a principal", lineno);
184 	    continue;
185 	}
186         krb5_storage_truncate(sp, 0);
187         ret = _hdb_mit_dump2mitdb_entry(pd->context, line, sp);
188         if (ret) break;
189         ret = krb5_storage_to_data(sp, &kdb_ent);
190         if (ret) break;
191         ret = _hdb_mdb_value2entry(pd->context, &kdb_ent, 0, &ent.entry);
192         krb5_data_free(&kdb_ent);
193         if (ret) break;
194 	ret = v5_prop(pd->context, NULL, &ent, arg);
195         hdb_free_entry(pd->context, &ent);
196         if (ret) break;
197     }
198 
199 out:
200     fclose(f);
201     free(line);
202     if (sp)
203         krb5_storage_free(sp);
204     if (ret && ret == ENOMEM)
205         errx(1, "out of memory");
206     if (ret)
207         errx(1, "line %d: problem parsing dump line", lineno);
208     return ret;
209 }
210 
211