2 * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
34 #include "kadmin_locl.h"
35 #include "kadmin-commands.h"
36 #include <kadm5/private.h>
38 __RCSID("$Heimdal: load.c 16658 2006-01-25 12:29:46Z lha $"
59 while(*p
&& !isspace((unsigned char)*p
))
62 while(*p
&& isspace((unsigned char)*p
))
68 * Parse the time in `s', returning:
75 parse_time_string(time_t *t
, const char *s
)
77 int year
, month
, date
, hour
, minute
, second
;
80 if(strcmp(s
, "-") == 0)
82 if(sscanf(s
, "%04d%02d%02d%02d%02d%02d",
83 &year
, &month
, &date
, &hour
, &minute
, &second
) != 6)
85 tm
.tm_year
= year
- 1900;
86 tm
.tm_mon
= month
- 1;
97 * parse time, allocating space in *t if it's there
101 parse_time_string_alloc (time_t **t
, const char *s
)
107 ret
= parse_time_string (&tmp
, s
);
109 *t
= malloc (sizeof (**t
));
111 krb5_errx (context
, 1, "malloc: out of memory");
118 * see parse_time_string for calling convention
122 parse_integer(unsigned int *u
, const char *s
)
124 if(strcmp(s
, "-") == 0)
126 if (sscanf(s
, "%u", u
) != 1)
132 parse_integer_alloc (unsigned int **u
, const char *s
)
138 ret
= parse_integer (&tmp
, s
);
140 *u
= malloc (sizeof (**u
));
142 krb5_errx (context
, 1, "malloc: out of memory");
149 * Parse dumped keys in `str' and store them in `ent'
150 * return -1 if parsing failed
154 parse_keys(hdb_entry
*ent
, char *str
)
161 p
= strsep(&str
, ":");
162 if (sscanf(p
, "%d", &tmp
) != 1)
165 p
= strsep(&str
, ":");
168 key
= realloc(ent
->keys
.val
,
169 (ent
->keys
.len
+ 1) * sizeof(*ent
->keys
.val
));
171 krb5_errx (context
, 1, "realloc: out of memory");
173 key
= ent
->keys
.val
+ ent
->keys
.len
;
175 memset(key
, 0, sizeof(*key
));
176 if(sscanf(p
, "%d", &tmp
) == 1) {
177 key
->mkvno
= malloc(sizeof(*key
->mkvno
));
181 p
= strsep(&str
, ":");
182 if (sscanf(p
, "%d", &tmp
) != 1)
184 key
->key
.keytype
= tmp
;
185 p
= strsep(&str
, ":");
186 ret
= krb5_data_alloc(&key
->key
.keyvalue
, (strlen(p
) - 1) / 2 + 1);
188 krb5_err (context
, 1, ret
, "krb5_data_alloc");
189 for(i
= 0; i
< strlen(p
); i
+= 2) {
190 if(sscanf(p
+ i
, "%02x", &tmp
) != 1)
192 ((u_char
*)key
->key
.keyvalue
.data
)[i
/ 2] = tmp
;
194 p
= strsep(&str
, ":");
195 if(strcmp(p
, "-") != 0){
199 if(sscanf(p
, "%u/", &type
) != 1)
207 key
->salt
= malloc(sizeof(*key
->salt
));
208 if (key
->salt
== NULL
)
209 krb5_errx (context
, 1, "malloc: out of memory");
210 key
->salt
->type
= type
;
214 ret
= krb5_data_copy(&key
->salt
->salt
, p
+ 1, p_len
- 2);
216 krb5_err (context
, 1, ret
, "krb5_data_copy");
218 ret
= krb5_data_alloc(&key
->salt
->salt
,
219 (p_len
- 1) / 2 + 1);
221 krb5_err (context
, 1, ret
, "krb5_data_alloc");
222 for(i
= 0; i
< p_len
; i
+= 2){
223 if (sscanf(p
+ i
, "%02x", &tmp
) != 1)
225 ((u_char
*)key
->salt
->salt
.data
)[i
/ 2] = tmp
;
229 krb5_data_zero (&key
->salt
->salt
);
231 p
= strsep(&str
, ":");
237 * see parse_time_string for calling convention
241 parse_event(Event
*ev
, char *s
)
246 if(strcmp(s
, "-") == 0)
248 memset(ev
, 0, sizeof(*ev
));
250 if(parse_time_string(&ev
->time
, p
) != 1)
253 ret
= krb5_parse_name(context
, p
, &ev
->principal
);
260 parse_event_alloc (Event
**ev
, char *s
)
266 ret
= parse_event (&tmp
, s
);
268 *ev
= malloc (sizeof (**ev
));
270 krb5_errx (context
, 1, "malloc: out of memory");
277 parse_hdbflags2int(HDBFlags
*f
, const char *s
)
282 ret
= parse_integer (&tmp
, s
);
284 *f
= int2HDBFlags (tmp
);
289 parse_generation(char *str
, GENERATION
**gen
)
294 if(strcmp(str
, "-") == 0 || *str
== '\0') {
298 *gen
= calloc(1, sizeof(**gen
));
300 p
= strsep(&str
, ":");
301 if(parse_time_string(&(*gen
)->time
, p
) != 1)
303 p
= strsep(&str
, ":");
304 if(sscanf(p
, "%d", &v
) != 1)
307 p
= strsep(&str
, ":");
308 if(sscanf(p
, "%d", &v
) != 1)
310 (*gen
)->gen
= v
- 1; /* XXX gets bumped in _hdb_store */
315 parse_extensions(char *str
, HDB_extensions
**e
)
320 if(strcmp(str
, "-") == 0 || *str
== '\0') {
324 *e
= calloc(1, sizeof(**e
));
326 p
= strsep(&str
, ":");
336 len
= hex_decode(p
, d
, len
);
340 ret
= decode_HDB_extension(d
, len
, &ext
, NULL
);
344 d
= realloc((*e
)->val
, ((*e
)->len
+ 1) * sizeof((*e
)->val
[0]));
348 (*e
)->val
[(*e
)->len
] = ext
;
351 p
= strsep(&str
, ":");
359 * Parse the dump file in `filename' and create the database (merging
364 doit(const char *filename
, int mergep
)
368 char s
[8192]; /* XXX should fix this properly */
374 HDB
*db
= _kadm5_s_get_db(kadm_handle
);
376 f
= fopen(filename
, "r");
378 krb5_warn(context
, errno
, "fopen(%s)", filename
);
381 ret
= kadm5_log_truncate (kadm_handle
);
384 krb5_warn(context
, ret
, "kadm5_log_truncate");
389 flags
|= O_CREAT
| O_TRUNC
;
390 ret
= db
->hdb_open(context
, db
, flags
, 0600);
392 krb5_warn(context
, ret
, "hdb_open");
398 while(fgets(s
, sizeof(s
), f
) != NULL
) {
403 while (isspace((unsigned char)*p
))
410 else if(isspace((unsigned char)*p
)) {
450 memset(&ent
, 0, sizeof(ent
));
451 ret
= krb5_parse_name(context
, e
.principal
, &ent
.entry
.principal
);
453 fprintf(stderr
, "%s:%d:%s (%s)\n",
456 krb5_get_err_text(context
, ret
),
461 if (parse_keys(&ent
.entry
, e
.key
)) {
462 fprintf (stderr
, "%s:%d:error parsing keys (%s)\n",
463 filename
, line
, e
.key
);
464 hdb_free_entry (context
, &ent
);
468 if (parse_event(&ent
.entry
.created_by
, e
.created
) == -1) {
469 fprintf (stderr
, "%s:%d:error parsing created event (%s)\n",
470 filename
, line
, e
.created
);
471 hdb_free_entry (context
, &ent
);
474 if (parse_event_alloc (&ent
.entry
.modified_by
, e
.modified
) == -1) {
475 fprintf (stderr
, "%s:%d:error parsing event (%s)\n",
476 filename
, line
, e
.modified
);
477 hdb_free_entry (context
, &ent
);
480 if (parse_time_string_alloc (&ent
.entry
.valid_start
, e
.valid_start
) == -1) {
481 fprintf (stderr
, "%s:%d:error parsing time (%s)\n",
482 filename
, line
, e
.valid_start
);
483 hdb_free_entry (context
, &ent
);
486 if (parse_time_string_alloc (&ent
.entry
.valid_end
, e
.valid_end
) == -1) {
487 fprintf (stderr
, "%s:%d:error parsing time (%s)\n",
488 filename
, line
, e
.valid_end
);
489 hdb_free_entry (context
, &ent
);
492 if (parse_time_string_alloc (&ent
.entry
.pw_end
, e
.pw_end
) == -1) {
493 fprintf (stderr
, "%s:%d:error parsing time (%s)\n",
494 filename
, line
, e
.pw_end
);
495 hdb_free_entry (context
, &ent
);
499 if (parse_integer_alloc (&ent
.entry
.max_life
, e
.max_life
) == -1) {
500 fprintf (stderr
, "%s:%d:error parsing lifetime (%s)\n",
501 filename
, line
, e
.max_life
);
502 hdb_free_entry (context
, &ent
);
506 if (parse_integer_alloc (&ent
.entry
.max_renew
, e
.max_renew
) == -1) {
507 fprintf (stderr
, "%s:%d:error parsing lifetime (%s)\n",
508 filename
, line
, e
.max_renew
);
509 hdb_free_entry (context
, &ent
);
513 if (parse_hdbflags2int (&ent
.entry
.flags
, e
.flags
) != 1) {
514 fprintf (stderr
, "%s:%d:error parsing flags (%s)\n",
515 filename
, line
, e
.flags
);
516 hdb_free_entry (context
, &ent
);
520 if(parse_generation(e
.generation
, &ent
.entry
.generation
) == -1) {
521 fprintf (stderr
, "%s:%d:error parsing generation (%s)\n",
522 filename
, line
, e
.generation
);
523 hdb_free_entry (context
, &ent
);
527 if(parse_extensions(e
.extensions
, &ent
.entry
.extensions
) == -1) {
528 fprintf (stderr
, "%s:%d:error parsing extension (%s)\n",
529 filename
, line
, e
.extensions
);
530 hdb_free_entry (context
, &ent
);
534 ret
= db
->hdb_store(context
, db
, HDB_F_REPLACE
, &ent
);
535 hdb_free_entry (context
, &ent
);
537 krb5_warn(context
, ret
, "db_store");
541 db
->hdb_close(context
, db
);
547 extern int local_flag
;
550 loadit(int mergep
, const char *name
, int argc
, char **argv
)
553 krb5_warnx(context
, "%s is only available in local (-l) mode", name
);
557 return doit(argv
[0], mergep
);
561 load(void *opt
, int argc
, char **argv
)
563 return loadit(0, "load", argc
, argv
);
567 merge(void *opt
, int argc
, char **argv
)
569 return loadit(1, "merge", argc
, argv
);