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>
58 while(*p
&& !isspace((unsigned char)*p
))
61 while(*p
&& isspace((unsigned char)*p
))
67 * Parse the time in `s', returning:
74 parse_time_string(time_t *t
, const char *s
)
76 int year
, month
, date
, hour
, minute
, second
;
79 if(strcmp(s
, "-") == 0)
81 if(sscanf(s
, "%04d%02d%02d%02d%02d%02d",
82 &year
, &month
, &date
, &hour
, &minute
, &second
) != 6)
84 tm
.tm_year
= year
- 1900;
85 tm
.tm_mon
= month
- 1;
96 * parse time, allocating space in *t if it's there
100 parse_time_string_alloc (time_t **t
, const char *s
)
106 ret
= parse_time_string (&tmp
, s
);
108 *t
= malloc (sizeof (**t
));
110 krb5_errx (context
, 1, "malloc: out of memory");
117 * see parse_time_string for calling convention
121 parse_integer(unsigned int *u
, const char *s
)
123 if(strcmp(s
, "-") == 0)
125 if (sscanf(s
, "%u", u
) != 1)
131 parse_integer_alloc (unsigned int **u
, const char *s
)
137 ret
= parse_integer (&tmp
, s
);
139 *u
= malloc (sizeof (**u
));
141 krb5_errx (context
, 1, "malloc: out of memory");
148 * Parse dumped keys in `str' and store them in `ent'
149 * return -1 if parsing failed
153 parse_keys(hdb_entry
*ent
, char *str
)
160 p
= strsep(&str
, ":");
161 if (sscanf(p
, "%d", &tmp
) != 1)
164 p
= strsep(&str
, ":");
167 key
= realloc(ent
->keys
.val
,
168 (ent
->keys
.len
+ 1) * sizeof(*ent
->keys
.val
));
170 krb5_errx (context
, 1, "realloc: out of memory");
172 key
= ent
->keys
.val
+ ent
->keys
.len
;
174 memset(key
, 0, sizeof(*key
));
175 if(sscanf(p
, "%d", &tmp
) == 1) {
176 key
->mkvno
= malloc(sizeof(*key
->mkvno
));
180 p
= strsep(&str
, ":");
181 if (sscanf(p
, "%d", &tmp
) != 1)
183 key
->key
.keytype
= tmp
;
184 p
= strsep(&str
, ":");
185 ret
= krb5_data_alloc(&key
->key
.keyvalue
, (strlen(p
) - 1) / 2 + 1);
187 krb5_err (context
, 1, ret
, "krb5_data_alloc");
188 for(i
= 0; i
< strlen(p
); i
+= 2) {
189 if(sscanf(p
+ i
, "%02x", &tmp
) != 1)
191 ((u_char
*)key
->key
.keyvalue
.data
)[i
/ 2] = tmp
;
193 p
= strsep(&str
, ":");
194 if(strcmp(p
, "-") != 0){
198 if(sscanf(p
, "%u/", &type
) != 1)
206 key
->salt
= calloc(1, sizeof(*key
->salt
));
207 if (key
->salt
== NULL
)
208 krb5_errx (context
, 1, "malloc: out of memory");
209 key
->salt
->type
= type
;
213 ret
= krb5_data_copy(&key
->salt
->salt
, p
+ 1, p_len
- 2);
215 krb5_err (context
, 1, ret
, "krb5_data_copy");
217 ret
= krb5_data_alloc(&key
->salt
->salt
,
218 (p_len
- 1) / 2 + 1);
220 krb5_err (context
, 1, ret
, "krb5_data_alloc");
221 for(i
= 0; i
< p_len
; i
+= 2){
222 if (sscanf(p
+ i
, "%02x", &tmp
) != 1)
224 ((u_char
*)key
->salt
->salt
.data
)[i
/ 2] = tmp
;
228 krb5_data_zero (&key
->salt
->salt
);
230 p
= strsep(&str
, ":");
236 * see parse_time_string for calling convention
240 parse_event(Event
*ev
, char *s
)
245 if(strcmp(s
, "-") == 0)
247 memset(ev
, 0, sizeof(*ev
));
249 if(parse_time_string(&ev
->time
, p
) != 1)
252 ret
= krb5_parse_name(context
, p
, &ev
->principal
);
259 parse_event_alloc (Event
**ev
, char *s
)
265 ret
= parse_event (&tmp
, s
);
267 *ev
= malloc (sizeof (**ev
));
269 krb5_errx (context
, 1, "malloc: out of memory");
276 parse_hdbflags2int(HDBFlags
*f
, const char *s
)
281 ret
= parse_integer (&tmp
, s
);
283 *f
= int2HDBFlags (tmp
);
288 parse_generation(char *str
, GENERATION
**gen
)
293 if(strcmp(str
, "-") == 0 || *str
== '\0') {
297 *gen
= calloc(1, sizeof(**gen
));
299 p
= strsep(&str
, ":");
300 if(parse_time_string(&(*gen
)->time
, p
) != 1)
302 p
= strsep(&str
, ":");
303 if(sscanf(p
, "%d", &v
) != 1)
306 p
= strsep(&str
, ":");
307 if(sscanf(p
, "%d", &v
) != 1)
309 (*gen
)->gen
= v
- 1; /* XXX gets bumped in _hdb_store */
314 parse_extensions(char *str
, HDB_extensions
**e
)
319 if(strcmp(str
, "-") == 0 || *str
== '\0') {
323 *e
= calloc(1, sizeof(**e
));
325 p
= strsep(&str
, ":");
335 len
= hex_decode(p
, d
, len
);
341 ret
= decode_HDB_extension(d
, len
, &ext
, NULL
);
345 d
= realloc((*e
)->val
, ((*e
)->len
+ 1) * sizeof((*e
)->val
[0]));
349 (*e
)->val
[(*e
)->len
] = ext
;
352 p
= strsep(&str
, ":");
360 * Parse the dump file in `filename' and create the database (merging
365 doit(const char *filename
, int mergep
)
369 char s
[8192]; /* XXX should fix this properly */
375 HDB
*db
= _kadm5_s_get_db(kadm_handle
);
377 f
= fopen(filename
, "r");
379 krb5_warn(context
, errno
, "fopen(%s)", filename
);
382 ret
= kadm5_log_truncate (kadm_handle
);
385 krb5_warn(context
, ret
, "kadm5_log_truncate");
390 flags
|= O_CREAT
| O_TRUNC
;
391 ret
= db
->hdb_open(context
, db
, flags
, 0600);
393 krb5_warn(context
, ret
, "hdb_open");
399 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 const char *msg
= krb5_get_error_message(context
, ret
);
454 fprintf(stderr
, "%s:%d:%s (%s)\n",
455 filename
, line
, msg
, e
.principal
);
456 krb5_free_error_message(context
, msg
);
460 if (parse_keys(&ent
.entry
, e
.key
)) {
461 fprintf (stderr
, "%s:%d:error parsing keys (%s)\n",
462 filename
, line
, e
.key
);
463 hdb_free_entry (context
, &ent
);
467 if (parse_event(&ent
.entry
.created_by
, e
.created
) == -1) {
468 fprintf (stderr
, "%s:%d:error parsing created event (%s)\n",
469 filename
, line
, e
.created
);
470 hdb_free_entry (context
, &ent
);
473 if (parse_event_alloc (&ent
.entry
.modified_by
, e
.modified
) == -1) {
474 fprintf (stderr
, "%s:%d:error parsing event (%s)\n",
475 filename
, line
, e
.modified
);
476 hdb_free_entry (context
, &ent
);
479 if (parse_time_string_alloc (&ent
.entry
.valid_start
, e
.valid_start
) == -1) {
480 fprintf (stderr
, "%s:%d:error parsing time (%s)\n",
481 filename
, line
, e
.valid_start
);
482 hdb_free_entry (context
, &ent
);
485 if (parse_time_string_alloc (&ent
.entry
.valid_end
, e
.valid_end
) == -1) {
486 fprintf (stderr
, "%s:%d:error parsing time (%s)\n",
487 filename
, line
, e
.valid_end
);
488 hdb_free_entry (context
, &ent
);
491 if (parse_time_string_alloc (&ent
.entry
.pw_end
, e
.pw_end
) == -1) {
492 fprintf (stderr
, "%s:%d:error parsing time (%s)\n",
493 filename
, line
, e
.pw_end
);
494 hdb_free_entry (context
, &ent
);
498 if (parse_integer_alloc (&ent
.entry
.max_life
, e
.max_life
) == -1) {
499 fprintf (stderr
, "%s:%d:error parsing lifetime (%s)\n",
500 filename
, line
, e
.max_life
);
501 hdb_free_entry (context
, &ent
);
505 if (parse_integer_alloc (&ent
.entry
.max_renew
, e
.max_renew
) == -1) {
506 fprintf (stderr
, "%s:%d:error parsing lifetime (%s)\n",
507 filename
, line
, e
.max_renew
);
508 hdb_free_entry (context
, &ent
);
512 if (parse_hdbflags2int (&ent
.entry
.flags
, e
.flags
) != 1) {
513 fprintf (stderr
, "%s:%d:error parsing flags (%s)\n",
514 filename
, line
, e
.flags
);
515 hdb_free_entry (context
, &ent
);
519 if(parse_generation(e
.generation
, &ent
.entry
.generation
) == -1) {
520 fprintf (stderr
, "%s:%d:error parsing generation (%s)\n",
521 filename
, line
, e
.generation
);
522 hdb_free_entry (context
, &ent
);
526 if(parse_extensions(e
.extensions
, &ent
.entry
.extensions
) == -1) {
527 fprintf (stderr
, "%s:%d:error parsing extension (%s)\n",
528 filename
, line
, e
.extensions
);
529 hdb_free_entry (context
, &ent
);
533 ret
= db
->hdb_store(context
, db
, HDB_F_REPLACE
, &ent
);
534 hdb_free_entry (context
, &ent
);
536 krb5_warn(context
, ret
, "db_store");
540 db
->hdb_close(context
, db
);
546 extern int local_flag
;
549 loadit(int mergep
, const char *name
, int argc
, char **argv
)
552 krb5_warnx(context
, "%s is only available in local (-l) mode", name
);
556 return doit(argv
[0], mergep
);
560 load(void *opt
, int argc
, char **argv
)
562 return loadit(0, "load", argc
, argv
);
566 merge(void *opt
, int argc
, char **argv
)
568 return loadit(1, "merge", argc
, argv
);