2 * Copyright (c) 1997 - 2002 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
36 RCSID("$Id: hprop.c,v 1.70 2002/09/04 18:19:41 joda Exp $");
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
, sizeof(des_cblock
));
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
) != -1){
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 krb5_get_init_creds_opt_init(&init_opts
);
521 krb5_get_init_creds_opt_set_preauth_list(&init_opts
, &preauth
, 1);
523 ret
= krb5_get_init_creds_keytab(context
, &creds
, client
, keytab
, 0, NULL
, &init_opts
);
524 if(ret
) krb5_err(context
, 1, ret
, "krb5_get_init_creds");
526 ret
= krb5_kt_close(context
, keytab
);
527 if(ret
) krb5_err(context
, 1, ret
, "krb5_kt_close");
529 ret
= krb5_cc_gen_new(context
, &krb5_mcc_ops
, cache
);
530 if(ret
) krb5_err(context
, 1, ret
, "krb5_cc_gen_new");
532 ret
= krb5_cc_initialize(context
, *cache
, client
);
533 if(ret
) krb5_err(context
, 1, ret
, "krb5_cc_initialize");
535 krb5_free_principal(context
, client
);
537 ret
= krb5_cc_store_cred(context
, *cache
, &creds
);
538 if(ret
) krb5_err(context
, 1, ret
, "krb5_cc_store_cred");
540 krb5_free_creds_contents(context
, &creds
);
551 #define IS_TYPE_V4(X) ((X) == HPROP_KRB4_DB || (X) == HPROP_KRB4_DUMP || (X) == HPROP_KASERVER)
557 { HPROP_HEIMDAL
, "heimdal" },
558 { HPROP_KRB4_DUMP
, "krb4-dump" },
560 { HPROP_KRB4_DB
, "krb4-db" },
562 { HPROP_KASERVER
, "kaserver" },
563 { HPROP_MIT_DUMP
, "mit-dump" }
567 parse_source_type(const char *s
)
570 for(i
= 0; i
< sizeof(types
) / sizeof(types
[0]); i
++) {
571 if(strstr(types
[i
].name
, s
) == types
[i
].name
)
572 return types
[i
].type
;
578 iterate (krb5_context context
,
579 const char *database
,
582 struct prop_data
*pd
)
587 case HPROP_KRB4_DUMP
:
588 ret
= v4_prop_dump(pd
, database
);
592 ret
= kerb_db_iterate ((k_iter_proc_t
)kdb_prop
, pd
);
594 krb5_errx(context
, 1, "kerb_db_iterate: %s",
595 krb_get_err_text(ret
));
599 ret
= ka_dump(pd
, database
);
601 krb5_err(context
, 1, ret
, "ka_dump");
604 ret
= mit_prop_dump(pd
, database
);
606 krb5_errx(context
, 1, "mit_prop_dump: %s",
607 krb5_get_err_text(context
, ret
));
610 ret
= hdb_foreach(context
, db
, HDB_F_DECRYPT
, v5_prop
, pd
);
612 krb5_err(context
, 1, ret
, "hdb_foreach");
618 dump_database (krb5_context context
, int type
,
619 const char *database
, HDB
*db
)
625 pd
.context
= context
;
626 pd
.auth_context
= NULL
;
627 pd
.sock
= STDOUT_FILENO
;
629 iterate (context
, database
, db
, type
, &pd
);
630 krb5_data_zero (&data
);
631 ret
= krb5_write_message (context
, &pd
.sock
, &data
);
633 krb5_err(context
, 1, ret
, "krb5_write_message");
639 propagate_database (krb5_context context
, int type
,
640 const char *database
,
641 HDB
*db
, krb5_ccache ccache
,
642 int optind
, int argc
, char **argv
)
644 krb5_principal server
;
648 for(i
= optind
; i
< argc
; i
++){
649 krb5_auth_context auth_context
;
654 char *port
, portstr
[NI_MAXSERV
];
656 port
= strchr(argv
[i
], ':');
658 snprintf(portstr
, sizeof(portstr
), "%u",
659 ntohs(krb5_getportbyname (context
, "hprop", "tcp",
665 fd
= open_socket(context
, argv
[i
], port
);
667 krb5_warn (context
, errno
, "connect %s", argv
[i
]);
671 ret
= krb5_sname_to_principal(context
, argv
[i
],
672 HPROP_NAME
, KRB5_NT_SRV_HST
, &server
);
674 krb5_warn(context
, ret
, "krb5_sname_to_principal(%s)", argv
[i
]);
681 krb5_get_default_realm(context
,&my_realm
);
683 free (*krb5_princ_realm(context
, server
));
684 krb5_princ_set_realm(context
,server
,&my_realm
);
688 ret
= krb5_sendauth(context
,
694 AP_OPTS_MUTUAL_REQUIRED
| AP_OPTS_USE_SUBKEY
,
702 krb5_free_principal(context
, server
);
705 krb5_warn(context
, ret
, "krb5_sendauth");
710 pd
.context
= context
;
711 pd
.auth_context
= auth_context
;
714 iterate (context
, database
, db
, type
, &pd
);
716 krb5_data_zero (&data
);
717 ret
= krb5_write_priv_message(context
, auth_context
, &fd
, &data
);
719 krb5_warn(context
, ret
, "krb5_write_priv_message");
721 ret
= krb5_read_priv_message(context
, auth_context
, &fd
, &data
);
723 krb5_warn(context
, ret
, "krb5_read_priv_message");
725 krb5_data_free (&data
);
727 krb5_auth_con_free(context
, auth_context
);
734 main(int argc
, char **argv
)
737 krb5_context context
;
738 krb5_ccache ccache
= NULL
;
744 setprogname(argv
[0]);
746 if(getarg(args
, num_args
, argc
, argv
, &optind
))
757 ret
= krb5_init_context(&context
);
762 krb5_set_default_realm(context
, local_realm
);
764 if(v4_realm
== NULL
) {
765 ret
= krb5_get_default_realm(context
, &v4_realm
);
767 krb5_err(context
, 1, ret
, "krb5_get_default_realm");
770 if(afs_cell
== NULL
) {
771 afs_cell
= strdup(v4_realm
);
773 krb5_errx(context
, 1, "out of memory");
778 if(encrypt_flag
&& decrypt_flag
)
779 krb5_errx(context
, 1,
780 "only one of `--encrypt' and `--decrypt' is meaningful");
782 if(source_type
!= NULL
) {
784 krb5_errx(context
, 1, "more than one database type specified");
785 type
= parse_source_type(source_type
);
787 krb5_errx(context
, 1, "unknown source type `%s'", source_type
);
789 type
= HPROP_HEIMDAL
;
792 get_creds(context
, &ccache
);
794 if(decrypt_flag
|| encrypt_flag
) {
795 ret
= hdb_read_master_key(context
, mkeyfile
, &mkey5
);
796 if(ret
&& ret
!= ENOENT
)
797 krb5_err(context
, 1, ret
, "hdb_read_master_key");
799 krb5_errx(context
, 1, "No master key file found");
803 if (IS_TYPE_V4(type
)) {
806 if (v4_realm
== NULL
) {
807 e
= krb_get_lrealm(realm_buf
, 1);
809 krb5_errx(context
, 1, "krb_get_lrealm: %s",
810 krb_get_err_text(e
));
811 v4_realm
= realm_buf
;
819 if (database
== NULL
)
820 krb5_errx(context
, 1, "no database specified");
824 if (database
== NULL
)
825 database
= DEFAULT_DATABASE
;
826 ka_use_null_salt
= krb5_config_get_bool_default(context
, NULL
, FALSE
,
828 "afs_uses_null_salt",
832 case HPROP_KRB4_DUMP
:
833 if (database
== NULL
)
834 krb5_errx(context
, 1, "no dump file specified");
838 if (database
== NULL
)
839 krb5_errx(context
, 1, "no dump file specified");
842 ret
= hdb_create (context
, &db
, database
);
844 krb5_err(context
, 1, ret
, "hdb_create: %s", database
);
845 ret
= db
->open(context
, db
, O_RDONLY
, 0);
847 krb5_err(context
, 1, ret
, "db->open");
850 krb5_errx(context
, 1, "unknown dump type `%d'", type
);
855 dump_database (context
, type
, database
, db
);
857 propagate_database (context
, type
, database
,
858 db
, ccache
, optind
, argc
, argv
);
861 krb5_cc_destroy(context
, ccache
);
864 (*db
->destroy
)(context
, db
);
866 krb5_free_context(context
);