2 * Copyright (c) 1997 - 2004 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
38 static int version_flag
;
40 static const char *ktname
= HPROP_KEYTAB
;
41 static const char *database
;
42 static char *mkeyfile
;
44 static int verbose_flag
;
45 static int encrypt_flag
;
46 static int decrypt_flag
;
47 static hdb_master_key mkey5
;
49 static char *source_type
;
51 static char *afs_cell
;
52 static char *v4_realm
;
54 static int kaspecials_flag
;
55 static int ka_use_null_salt
;
57 static char *local_realm
=NULL
;
60 open_socket(krb5_context context
, const char *hostname
, const char *port
)
62 struct addrinfo
*ai
, *a
;
63 struct addrinfo hints
;
66 memset (&hints
, 0, sizeof(hints
));
67 hints
.ai_socktype
= SOCK_STREAM
;
68 hints
.ai_protocol
= IPPROTO_TCP
;
70 error
= getaddrinfo (hostname
, port
, &hints
, &ai
);
72 warnx ("%s: %s", hostname
, gai_strerror(error
));
76 for (a
= ai
; a
!= NULL
; a
= a
->ai_next
) {
79 s
= socket (a
->ai_family
, a
->ai_socktype
, a
->ai_protocol
);
82 if (connect (s
, a
->ai_addr
, a
->ai_addrlen
) < 0) {
83 warn ("connect(%s)", hostname
);
90 warnx ("failed to contact %s", hostname
);
96 v5_prop(krb5_context context
, HDB
*db
, hdb_entry
*entry
, void *appdata
)
99 struct prop_data
*pd
= appdata
;
103 ret
= hdb_seal_keys_mkey(context
, entry
, mkey5
);
105 krb5_warn(context
, ret
, "hdb_seal_keys_mkey");
110 ret
= hdb_unseal_keys_mkey(context
, entry
, mkey5
);
112 krb5_warn(context
, ret
, "hdb_unseal_keys_mkey");
117 ret
= hdb_entry2value(context
, entry
, &data
);
119 krb5_warn(context
, ret
, "hdb_entry2value");
124 ret
= krb5_write_message(context
, &pd
->sock
, &data
);
126 ret
= krb5_write_priv_message(context
, pd
->auth_context
,
128 krb5_data_free(&data
);
134 static char realm_buf
[REALM_SZ
];
137 kdb_prop(void *arg
, Principal
*p
)
140 struct v4_principal pr
;
142 memset(&pr
, 0, sizeof(pr
));
144 if(p
->attributes
!= 0) {
145 warnx("%s.%s has non-zero attributes - skipping",
146 p
->name
, p
->instance
);
149 strlcpy(pr
.name
, p
->name
, sizeof(pr
.name
));
150 strlcpy(pr
.instance
, p
->instance
, sizeof(pr
.instance
));
152 copy_to_key(&p
->key_low
, &p
->key_high
, pr
.key
);
153 pr
.exp_date
= p
->exp_date
;
154 pr
.mod_date
= p
->mod_date
;
155 strlcpy(pr
.mod_name
, p
->mod_name
, sizeof(pr
.mod_name
));
156 strlcpy(pr
.mod_instance
, p
->mod_instance
, sizeof(pr
.mod_instance
));
157 pr
.max_life
= p
->max_life
;
158 pr
.mkvno
= p
->kdc_key_ver
;
159 pr
.kvno
= p
->key_version
;
161 ret
= v4_prop(arg
, &pr
);
162 memset(&pr
, 0, sizeof(pr
));
170 krb_life_to_time(time_t start
, int life
)
172 static int lifetimes
[] = {
173 38400, 41055, 43894, 46929, 50174, 53643, 57352, 61318,
174 65558, 70091, 74937, 80119, 85658, 91581, 97914, 104684,
175 111922, 119661, 127935, 136781, 146239, 156350, 167161, 178720,
176 191077, 204289, 218415, 233517, 249664, 266926, 285383, 305116,
177 326213, 348769, 372885, 398668, 426234, 455705, 487215, 520904,
178 556921, 595430, 636601, 680618, 727680, 777995, 831789, 889303,
179 950794, 1016537, 1086825, 1161973, 1242318, 1328218, 1420057, 1518247,
180 1623226, 1735464, 1855462, 1983758, 2120925, 2267576, 2424367, 2592000
185 double q
= exp((log(2592000.0) - log(38400.0)) / 63);
187 for(i
= 0; i
< 64; i
++) {
188 lifetimes
[i
] = (int)x
;
196 return start
+ life
* 5 * 60;
199 return start
+ lifetimes
[life
- 0x80];
204 v4_prop(void *arg
, struct v4_principal
*p
)
206 struct prop_data
*pd
= arg
;
210 memset(&ent
, 0, sizeof(ent
));
212 ret
= krb5_425_conv_principal(pd
->context
, p
->name
, p
->instance
, v4_realm
,
215 krb5_warn(pd
->context
, ret
,
216 "krb5_425_conv_principal %s.%s@%s",
217 p
->name
, p
->instance
, v4_realm
);
223 krb5_unparse_name_short(pd
->context
, ent
.principal
, &s
);
224 krb5_warnx(pd
->context
, "%s.%s -> %s", p
->name
, p
->instance
, s
);
230 ent
.keys
.val
= malloc(ent
.keys
.len
* sizeof(*ent
.keys
.val
));
232 ent
.keys
.val
[0].mkvno
= malloc (sizeof(*ent
.keys
.val
[0].mkvno
));
233 *(ent
.keys
.val
[0].mkvno
) = p
->mkvno
;
235 ent
.keys
.val
[0].mkvno
= NULL
;
236 ent
.keys
.val
[0].salt
= calloc(1, sizeof(*ent
.keys
.val
[0].salt
));
237 ent
.keys
.val
[0].salt
->type
= KRB5_PADATA_PW_SALT
;
238 ent
.keys
.val
[0].key
.keytype
= ETYPE_DES_CBC_MD5
;
239 krb5_data_alloc(&ent
.keys
.val
[0].key
.keyvalue
, DES_KEY_SZ
);
240 memcpy(ent
.keys
.val
[0].key
.keyvalue
.data
, p
->key
, 8);
242 copy_Key(&ent
.keys
.val
[0], &ent
.keys
.val
[1]);
243 ent
.keys
.val
[1].key
.keytype
= ETYPE_DES_CBC_MD4
;
244 copy_Key(&ent
.keys
.val
[0], &ent
.keys
.val
[2]);
245 ent
.keys
.val
[2].key
.keytype
= ETYPE_DES_CBC_CRC
;
248 int life
= krb_life_to_time(0, p
->max_life
);
249 if(life
== NEVERDATE
){
252 /* clean up lifetime a bit */
254 life
= (life
+ 86399) / 86400 * 86400;
256 life
= (life
+ 3599) / 3600 * 3600;
258 *ent
.max_life
= life
;
262 ALLOC(ent
.valid_end
);
263 *ent
.valid_end
= p
->exp_date
;
265 ret
= krb5_make_principal(pd
->context
, &ent
.created_by
.principal
,
271 krb5_warn(pd
->context
, ret
, "krb5_make_principal");
275 ent
.created_by
.time
= time(NULL
);
276 ALLOC(ent
.modified_by
);
277 ret
= krb5_425_conv_principal(pd
->context
, p
->mod_name
, p
->mod_instance
,
278 v4_realm
, &ent
.modified_by
->principal
);
280 krb5_warn(pd
->context
, ret
, "%s.%s@%s", p
->name
, p
->instance
, v4_realm
);
281 ent
.modified_by
->principal
= NULL
;
285 ent
.modified_by
->time
= p
->mod_date
;
287 ent
.flags
.forwardable
= 1;
288 ent
.flags
.renewable
= 1;
289 ent
.flags
.proxiable
= 1;
290 ent
.flags
.postdate
= 1;
291 ent
.flags
.client
= 1;
292 ent
.flags
.server
= 1;
294 /* special case password changing service */
295 if(strcmp(p
->name
, "changepw") == 0 &&
296 strcmp(p
->instance
, "kerberos") == 0) {
297 ent
.flags
.forwardable
= 0;
298 ent
.flags
.renewable
= 0;
299 ent
.flags
.proxiable
= 0;
300 ent
.flags
.postdate
= 0;
301 ent
.flags
.initial
= 1;
302 ent
.flags
.change_pw
= 1;
305 ret
= v5_prop(pd
->context
, NULL
, &ent
, pd
);
307 if (strcmp (p
->name
, "krbtgt") == 0
308 && strcmp (v4_realm
, p
->instance
) != 0) {
309 krb5_free_principal (pd
->context
, ent
.principal
);
310 ret
= krb5_425_conv_principal (pd
->context
, p
->name
,
311 v4_realm
, p
->instance
,
314 ret
= v5_prop (pd
->context
, NULL
, &ent
, pd
);
318 hdb_free_entry(pd
->context
, &ent
);
324 /* read a `ka_entry' from `fd' at offset `pos' */
326 read_block(krb5_context context
, int fd
, int32_t pos
, void *buf
, size_t len
)
330 if((ret
= pread(fd
, buf
, len
, 64 + pos
)) < 0)
331 krb5_err(context
, 1, errno
, "pread(%u)", 64 + pos
);
333 if(lseek(fd
, 64 + pos
, SEEK_SET
) == (off_t
)-1)
334 krb5_err(context
, 1, errno
, "lseek(%u)", 64 + pos
);
335 ret
= read(fd
, buf
, len
);
337 krb5_err(context
, 1, errno
, "read(%lu)", (unsigned long)len
);
340 krb5_errx(context
, 1, "read(%lu) = %u", (unsigned long)len
, ret
);
344 ka_convert(struct prop_data
*pd
, int fd
, struct ka_entry
*ent
)
346 int32_t flags
= ntohl(ent
->flags
);
351 && (flags
& KAFNORMAL
) == 0) /* remove special entries */
353 memset(&hdb
, 0, sizeof(hdb
));
354 ret
= krb5_425_conv_principal(pd
->context
, ent
->name
, ent
->instance
,
355 v4_realm
, &hdb
.principal
);
357 krb5_warn(pd
->context
, ret
,
358 "krb5_425_conv_principal (%s.%s@%s)",
359 ent
->name
, ent
->instance
, v4_realm
);
362 hdb
.kvno
= ntohl(ent
->kvno
);
364 hdb
.keys
.val
= malloc(hdb
.keys
.len
* sizeof(*hdb
.keys
.val
));
365 hdb
.keys
.val
[0].mkvno
= NULL
;
366 hdb
.keys
.val
[0].salt
= calloc(1, sizeof(*hdb
.keys
.val
[0].salt
));
367 if (ka_use_null_salt
) {
368 hdb
.keys
.val
[0].salt
->type
= hdb_pw_salt
;
369 hdb
.keys
.val
[0].salt
->salt
.data
= NULL
;
370 hdb
.keys
.val
[0].salt
->salt
.length
= 0;
372 hdb
.keys
.val
[0].salt
->type
= hdb_afs3_salt
;
373 hdb
.keys
.val
[0].salt
->salt
.data
= strdup(afs_cell
);
374 hdb
.keys
.val
[0].salt
->salt
.length
= strlen(afs_cell
);
377 hdb
.keys
.val
[0].key
.keytype
= ETYPE_DES_CBC_MD5
;
378 krb5_data_copy(&hdb
.keys
.val
[0].key
.keyvalue
, ent
->key
, sizeof(ent
->key
));
379 copy_Key(&hdb
.keys
.val
[0], &hdb
.keys
.val
[1]);
380 hdb
.keys
.val
[1].key
.keytype
= ETYPE_DES_CBC_MD4
;
381 copy_Key(&hdb
.keys
.val
[0], &hdb
.keys
.val
[2]);
382 hdb
.keys
.val
[2].key
.keytype
= ETYPE_DES_CBC_CRC
;
385 *hdb
.max_life
= ntohl(ent
->max_life
);
387 if(ntohl(ent
->valid_end
) != NEVERDATE
&& ntohl(ent
->valid_end
) != 0xffffffff) {
388 ALLOC(hdb
.valid_end
);
389 *hdb
.valid_end
= ntohl(ent
->valid_end
);
392 if (ntohl(ent
->pw_change
) != NEVERDATE
&&
393 ent
->pw_expire
!= 255 &&
394 ent
->pw_expire
!= 0) {
396 *hdb
.pw_end
= ntohl(ent
->pw_change
)
397 + 24 * 60 * 60 * ent
->pw_expire
;
400 ret
= krb5_make_principal(pd
->context
, &hdb
.created_by
.principal
,
405 hdb
.created_by
.time
= time(NULL
);
409 ALLOC(hdb
.modified_by
);
410 read_block(pd
->context
, fd
, ntohl(ent
->mod_ptr
), &mod
, sizeof(mod
));
412 krb5_425_conv_principal(pd
->context
, mod
.name
, mod
.instance
, v4_realm
,
413 &hdb
.modified_by
->principal
);
414 hdb
.modified_by
->time
= ntohl(ent
->mod_time
);
415 memset(&mod
, 0, sizeof(mod
));
418 hdb
.flags
.forwardable
= 1;
419 hdb
.flags
.renewable
= 1;
420 hdb
.flags
.proxiable
= 1;
421 hdb
.flags
.postdate
= 1;
422 /* XXX - AFS 3.4a creates krbtgt.REALMOFCELL as NOTGS+NOSEAL */
423 if (strcmp(ent
->name
, "krbtgt") == 0 &&
424 (flags
& (KAFNOTGS
|KAFNOSEAL
)) == (KAFNOTGS
|KAFNOSEAL
))
425 flags
&= ~(KAFNOTGS
|KAFNOSEAL
);
427 hdb
.flags
.client
= (flags
& KAFNOTGS
) == 0;
428 hdb
.flags
.server
= (flags
& KAFNOSEAL
) == 0;
430 ret
= v5_prop(pd
->context
, NULL
, &hdb
, pd
);
431 hdb_free_entry(pd
->context
, &hdb
);
436 ka_dump(struct prop_data
*pd
, const char *file
)
438 struct ka_header header
;
440 int fd
= open(file
, O_RDONLY
);
443 krb5_err(pd
->context
, 1, errno
, "open(%s)", file
);
444 read_block(pd
->context
, fd
, 0, &header
, sizeof(header
));
445 if(header
.version1
!= header
.version2
)
446 krb5_errx(pd
->context
, 1, "Version mismatch in header: %ld/%ld",
447 (long)ntohl(header
.version1
), (long)ntohl(header
.version2
));
448 if(ntohl(header
.version1
) != 5)
449 krb5_errx(pd
->context
, 1, "Unknown database version %ld (expected 5)",
450 (long)ntohl(header
.version1
));
451 for(i
= 0; i
< ntohl(header
.hashsize
); i
++){
452 int32_t pos
= ntohl(header
.hash
[i
]);
455 read_block(pd
->context
, fd
, pos
, &ent
, sizeof(ent
));
456 ka_convert(pd
, fd
, &ent
);
457 pos
= ntohl(ent
.next
);
465 struct getargs args
[] = {
466 { "master-key", 'm', arg_string
, &mkeyfile
, "v5 master key file", "file" },
467 { "database", 'd', arg_string
, &database
, "database", "file" },
468 { "source", 0, arg_string
, &source_type
, "type of database to read",
478 { "v4-realm", 'r', arg_string
, &v4_realm
, "v4 realm to use" },
479 { "cell", 'c', arg_string
, &afs_cell
, "name of AFS cell" },
480 { "kaspecials", 'S', arg_flag
, &kaspecials_flag
, "dump KASPECIAL keys"},
481 { "keytab", 'k', arg_string
, &ktname
, "keytab to use for authentication", "keytab" },
482 { "v5-realm", 'R', arg_string
, &local_realm
, "v5 realm to use" },
483 { "decrypt", 'D', arg_flag
, &decrypt_flag
, "decrypt keys" },
484 { "encrypt", 'E', arg_flag
, &encrypt_flag
, "encrypt keys" },
485 { "stdout", 'n', arg_flag
, &to_stdout
, "dump to stdout" },
486 { "verbose", 'v', arg_flag
, &verbose_flag
},
487 { "version", 0, arg_flag
, &version_flag
},
488 { "help", 'h', arg_flag
, &help_flag
}
491 static int num_args
= sizeof(args
) / sizeof(args
[0]);
496 arg_printusage (args
, num_args
, NULL
, "[host[:port]] ...");
501 get_creds(krb5_context context
, krb5_ccache
*cache
)
504 krb5_principal client
;
506 krb5_get_init_creds_opt
*init_opts
;
507 krb5_preauthtype preauth
= KRB5_PADATA_ENC_TIMESTAMP
;
510 ret
= krb5_kt_register(context
, &hdb_kt_ops
);
511 if(ret
) krb5_err(context
, 1, ret
, "krb5_kt_register");
513 ret
= krb5_kt_resolve(context
, ktname
, &keytab
);
514 if(ret
) krb5_err(context
, 1, ret
, "krb5_kt_resolve");
516 ret
= krb5_make_principal(context
, &client
, NULL
,
517 "kadmin", HPROP_NAME
, NULL
);
518 if(ret
) krb5_err(context
, 1, ret
, "krb5_make_principal");
520 ret
= krb5_get_init_creds_opt_alloc(context
, &init_opts
);
521 if(ret
) krb5_err(context
, 1, ret
, "krb5_get_init_creds_opt_alloc");
522 krb5_get_init_creds_opt_set_preauth_list(init_opts
, &preauth
, 1);
524 ret
= krb5_get_init_creds_keytab(context
, &creds
, client
, keytab
, 0, NULL
, init_opts
);
525 if(ret
) krb5_err(context
, 1, ret
, "krb5_get_init_creds");
527 krb5_get_init_creds_opt_free(init_opts
);
529 ret
= krb5_kt_close(context
, keytab
);
530 if(ret
) krb5_err(context
, 1, ret
, "krb5_kt_close");
532 ret
= krb5_cc_gen_new(context
, &krb5_mcc_ops
, cache
);
533 if(ret
) krb5_err(context
, 1, ret
, "krb5_cc_gen_new");
535 ret
= krb5_cc_initialize(context
, *cache
, client
);
536 if(ret
) krb5_err(context
, 1, ret
, "krb5_cc_initialize");
538 krb5_free_principal(context
, client
);
540 ret
= krb5_cc_store_cred(context
, *cache
, &creds
);
541 if(ret
) krb5_err(context
, 1, ret
, "krb5_cc_store_cred");
543 krb5_free_cred_contents(context
, &creds
);
554 #define IS_TYPE_V4(X) ((X) == HPROP_KRB4_DB || (X) == HPROP_KRB4_DUMP || (X) == HPROP_KASERVER)
560 { HPROP_HEIMDAL
, "heimdal" },
561 { HPROP_KRB4_DUMP
, "krb4-dump" },
563 { HPROP_KRB4_DB
, "krb4-db" },
565 { HPROP_KASERVER
, "kaserver" },
566 { HPROP_MIT_DUMP
, "mit-dump" }
570 parse_source_type(const char *s
)
573 for(i
= 0; i
< sizeof(types
) / sizeof(types
[0]); i
++) {
574 if(strstr(types
[i
].name
, s
) == types
[i
].name
)
575 return types
[i
].type
;
581 iterate (krb5_context context
,
582 const char *database
,
585 struct prop_data
*pd
)
590 case HPROP_KRB4_DUMP
:
591 ret
= v4_prop_dump(pd
, database
);
595 ret
= kerb_db_iterate ((k_iter_proc_t
)kdb_prop
, pd
);
597 krb5_errx(context
, 1, "kerb_db_iterate: %s",
598 krb_get_err_text(ret
));
602 ret
= ka_dump(pd
, database
);
604 krb5_err(context
, 1, ret
, "ka_dump");
607 ret
= mit_prop_dump(pd
, database
);
609 krb5_errx(context
, 1, "mit_prop_dump: %s",
610 krb5_get_err_text(context
, ret
));
613 ret
= hdb_foreach(context
, db
, HDB_F_DECRYPT
, v5_prop
, pd
);
615 krb5_err(context
, 1, ret
, "hdb_foreach");
621 dump_database (krb5_context context
, int type
,
622 const char *database
, HDB
*db
)
628 pd
.context
= context
;
629 pd
.auth_context
= NULL
;
630 pd
.sock
= STDOUT_FILENO
;
632 iterate (context
, database
, db
, type
, &pd
);
633 krb5_data_zero (&data
);
634 ret
= krb5_write_message (context
, &pd
.sock
, &data
);
636 krb5_err(context
, 1, ret
, "krb5_write_message");
642 propagate_database (krb5_context context
, int type
,
643 const char *database
,
644 HDB
*db
, krb5_ccache ccache
,
645 int optind
, int argc
, char **argv
)
647 krb5_principal server
;
651 for(i
= optind
; i
< argc
; i
++){
652 krb5_auth_context auth_context
;
657 char *port
, portstr
[NI_MAXSERV
];
659 port
= strchr(argv
[i
], ':');
661 snprintf(portstr
, sizeof(portstr
), "%u",
662 ntohs(krb5_getportbyname (context
, "hprop", "tcp",
668 fd
= open_socket(context
, argv
[i
], port
);
670 krb5_warn (context
, errno
, "connect %s", argv
[i
]);
674 ret
= krb5_sname_to_principal(context
, argv
[i
],
675 HPROP_NAME
, KRB5_NT_SRV_HST
, &server
);
677 krb5_warn(context
, ret
, "krb5_sname_to_principal(%s)", argv
[i
]);
684 krb5_get_default_realm(context
,&my_realm
);
686 free (*krb5_princ_realm(context
, server
));
687 krb5_princ_set_realm(context
,server
,&my_realm
);
691 ret
= krb5_sendauth(context
,
697 AP_OPTS_MUTUAL_REQUIRED
| AP_OPTS_USE_SUBKEY
,
705 krb5_free_principal(context
, server
);
708 krb5_warn(context
, ret
, "krb5_sendauth");
713 pd
.context
= context
;
714 pd
.auth_context
= auth_context
;
717 iterate (context
, database
, db
, type
, &pd
);
719 krb5_data_zero (&data
);
720 ret
= krb5_write_priv_message(context
, auth_context
, &fd
, &data
);
722 krb5_warn(context
, ret
, "krb5_write_priv_message");
724 ret
= krb5_read_priv_message(context
, auth_context
, &fd
, &data
);
726 krb5_warn(context
, ret
, "krb5_read_priv_message");
728 krb5_data_free (&data
);
730 krb5_auth_con_free(context
, auth_context
);
737 main(int argc
, char **argv
)
740 krb5_context context
;
741 krb5_ccache ccache
= NULL
;
747 setprogname(argv
[0]);
749 if(getarg(args
, num_args
, argc
, argv
, &optind
))
760 ret
= krb5_init_context(&context
);
765 krb5_set_default_realm(context
, local_realm
);
767 if(v4_realm
== NULL
) {
768 ret
= krb5_get_default_realm(context
, &v4_realm
);
770 krb5_err(context
, 1, ret
, "krb5_get_default_realm");
773 if(afs_cell
== NULL
) {
774 afs_cell
= strdup(v4_realm
);
776 krb5_errx(context
, 1, "out of memory");
781 if(encrypt_flag
&& decrypt_flag
)
782 krb5_errx(context
, 1,
783 "only one of `--encrypt' and `--decrypt' is meaningful");
785 if(source_type
!= NULL
) {
787 krb5_errx(context
, 1, "more than one database type specified");
788 type
= parse_source_type(source_type
);
790 krb5_errx(context
, 1, "unknown source type `%s'", source_type
);
792 type
= HPROP_HEIMDAL
;
795 get_creds(context
, &ccache
);
797 if(decrypt_flag
|| encrypt_flag
) {
798 ret
= hdb_read_master_key(context
, mkeyfile
, &mkey5
);
799 if(ret
&& ret
!= ENOENT
)
800 krb5_err(context
, 1, ret
, "hdb_read_master_key");
802 krb5_errx(context
, 1, "No master key file found");
806 if (IS_TYPE_V4(type
)) {
809 if (v4_realm
== NULL
) {
810 e
= krb_get_lrealm(realm_buf
, 1);
812 krb5_errx(context
, 1, "krb_get_lrealm: %s",
813 krb_get_err_text(e
));
814 v4_realm
= realm_buf
;
822 if (database
== NULL
)
823 krb5_errx(context
, 1, "no database specified");
827 if (database
== NULL
)
828 database
= DEFAULT_DATABASE
;
829 ka_use_null_salt
= krb5_config_get_bool_default(context
, NULL
, FALSE
,
831 "afs_uses_null_salt",
835 case HPROP_KRB4_DUMP
:
836 if (database
== NULL
)
837 krb5_errx(context
, 1, "no dump file specified");
841 if (database
== NULL
)
842 krb5_errx(context
, 1, "no dump file specified");
845 ret
= hdb_create (context
, &db
, database
);
847 krb5_err(context
, 1, ret
, "hdb_create: %s", database
);
848 ret
= db
->hdb_open(context
, db
, O_RDONLY
, 0);
850 krb5_err(context
, 1, ret
, "db->hdb_open");
853 krb5_errx(context
, 1, "unknown dump type `%d'", type
);
858 dump_database (context
, type
, database
, db
);
860 propagate_database (context
, type
, database
,
861 db
, ccache
, optind
, argc
, argv
);
864 krb5_cc_destroy(context
, ccache
);
867 (*db
->hdb_destroy
)(context
, db
);
869 krb5_free_context(context
);