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 #define KRB5_DEPRECATED /* uses v4 functions that will die */
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_ex
*entry
, void *appdata
)
99 struct prop_data
*pd
= appdata
;
103 ret
= hdb_seal_keys_mkey(context
, &entry
->entry
, mkey5
);
105 krb5_warn(context
, ret
, "hdb_seal_keys_mkey");
110 ret
= hdb_unseal_keys_mkey(context
, &entry
->entry
, mkey5
);
112 krb5_warn(context
, ret
, "hdb_unseal_keys_mkey");
117 ret
= hdb_entry2value(context
, &entry
->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 v4_prop(void *arg
, struct v4_principal
*p
)
136 struct prop_data
*pd
= arg
;
140 memset(&ent
, 0, sizeof(ent
));
142 ret
= krb5_425_conv_principal(pd
->context
, p
->name
, p
->instance
, v4_realm
,
143 &ent
.entry
.principal
);
145 krb5_warn(pd
->context
, ret
,
146 "krb5_425_conv_principal %s.%s@%s",
147 p
->name
, p
->instance
, v4_realm
);
153 krb5_unparse_name_short(pd
->context
, ent
.entry
.principal
, &s
);
154 krb5_warnx(pd
->context
, "%s.%s -> %s", p
->name
, p
->instance
, s
);
158 ent
.entry
.kvno
= p
->kvno
;
159 ent
.entry
.keys
.len
= 3;
160 ent
.entry
.keys
.val
= malloc(ent
.entry
.keys
.len
* sizeof(*ent
.entry
.keys
.val
));
161 if (ent
.entry
.keys
.val
== NULL
)
162 krb5_errx(pd
->context
, ENOMEM
, "malloc");
164 ent
.entry
.keys
.val
[0].mkvno
= malloc (sizeof(*ent
.entry
.keys
.val
[0].mkvno
));
165 if (ent
.entry
.keys
.val
[0].mkvno
== NULL
)
166 krb5_errx(pd
->context
, ENOMEM
, "malloc");
167 *(ent
.entry
.keys
.val
[0].mkvno
) = p
->mkvno
;
169 ent
.entry
.keys
.val
[0].mkvno
= NULL
;
170 ent
.entry
.keys
.val
[0].salt
= calloc(1, sizeof(*ent
.entry
.keys
.val
[0].salt
));
171 if (ent
.entry
.keys
.val
[0].salt
== NULL
)
172 krb5_errx(pd
->context
, ENOMEM
, "calloc");
173 ent
.entry
.keys
.val
[0].salt
->type
= KRB5_PADATA_PW_SALT
;
174 ent
.entry
.keys
.val
[0].key
.keytype
= ETYPE_DES_CBC_MD5
;
175 krb5_data_alloc(&ent
.entry
.keys
.val
[0].key
.keyvalue
, DES_KEY_SZ
);
176 memcpy(ent
.entry
.keys
.val
[0].key
.keyvalue
.data
, p
->key
, 8);
178 copy_Key(&ent
.entry
.keys
.val
[0], &ent
.entry
.keys
.val
[1]);
179 ent
.entry
.keys
.val
[1].key
.keytype
= ETYPE_DES_CBC_MD4
;
180 copy_Key(&ent
.entry
.keys
.val
[0], &ent
.entry
.keys
.val
[2]);
181 ent
.entry
.keys
.val
[2].key
.keytype
= ETYPE_DES_CBC_CRC
;
184 int life
= _krb5_krb_life_to_time(0, p
->max_life
);
185 if(life
== NEVERDATE
){
186 ent
.entry
.max_life
= NULL
;
188 /* clean up lifetime a bit */
190 life
= (life
+ 86399) / 86400 * 86400;
192 life
= (life
+ 3599) / 3600 * 3600;
193 ALLOC(ent
.entry
.max_life
);
194 *ent
.entry
.max_life
= life
;
198 ALLOC(ent
.entry
.valid_end
);
199 *ent
.entry
.valid_end
= p
->exp_date
;
201 ret
= krb5_make_principal(pd
->context
, &ent
.entry
.created_by
.principal
,
207 krb5_warn(pd
->context
, ret
, "krb5_make_principal");
211 ent
.entry
.created_by
.time
= time(NULL
);
212 ALLOC(ent
.entry
.modified_by
);
213 ret
= krb5_425_conv_principal(pd
->context
, p
->mod_name
, p
->mod_instance
,
214 v4_realm
, &ent
.entry
.modified_by
->principal
);
216 krb5_warn(pd
->context
, ret
, "%s.%s@%s", p
->name
, p
->instance
, v4_realm
);
217 ent
.entry
.modified_by
->principal
= NULL
;
221 ent
.entry
.modified_by
->time
= p
->mod_date
;
223 ent
.entry
.flags
.forwardable
= 1;
224 ent
.entry
.flags
.renewable
= 1;
225 ent
.entry
.flags
.proxiable
= 1;
226 ent
.entry
.flags
.postdate
= 1;
227 ent
.entry
.flags
.client
= 1;
228 ent
.entry
.flags
.server
= 1;
230 /* special case password changing service */
231 if(strcmp(p
->name
, "changepw") == 0 &&
232 strcmp(p
->instance
, "kerberos") == 0) {
233 ent
.entry
.flags
.forwardable
= 0;
234 ent
.entry
.flags
.renewable
= 0;
235 ent
.entry
.flags
.proxiable
= 0;
236 ent
.entry
.flags
.postdate
= 0;
237 ent
.entry
.flags
.initial
= 1;
238 ent
.entry
.flags
.change_pw
= 1;
241 ret
= v5_prop(pd
->context
, NULL
, &ent
, pd
);
243 if (strcmp (p
->name
, "krbtgt") == 0
244 && strcmp (v4_realm
, p
->instance
) != 0) {
245 krb5_free_principal (pd
->context
, ent
.entry
.principal
);
246 ret
= krb5_425_conv_principal (pd
->context
, p
->name
,
247 v4_realm
, p
->instance
,
248 &ent
.entry
.principal
);
250 ret
= v5_prop (pd
->context
, NULL
, &ent
, pd
);
254 hdb_free_entry(pd
->context
, &ent
);
261 /* read a `ka_entry' from `fd' at offset `pos' */
263 read_block(krb5_context context
, int fd
, int32_t pos
, void *buf
, size_t len
)
267 if((ret
= pread(fd
, buf
, len
, 64 + pos
)) < 0)
268 krb5_err(context
, 1, errno
, "pread(%u)", 64 + pos
);
270 if(lseek(fd
, 64 + pos
, SEEK_SET
) == (off_t
)-1)
271 krb5_err(context
, 1, errno
, "lseek(%u)", 64 + pos
);
272 ret
= read(fd
, buf
, len
);
274 krb5_err(context
, 1, errno
, "read(%lu)", (unsigned long)len
);
277 krb5_errx(context
, 1, "read(%lu) = %u", (unsigned long)len
, ret
);
283 ka_convert(struct prop_data
*pd
, int fd
, struct ka_entry
*ent
)
285 int32_t flags
= ntohl(ent
->flags
);
290 && (flags
& KAFNORMAL
) == 0) /* remove special entries */
292 memset(&hdb
, 0, sizeof(hdb
));
293 ret
= krb5_425_conv_principal(pd
->context
, ent
->name
, ent
->instance
,
294 v4_realm
, &hdb
.entry
.principal
);
296 krb5_warn(pd
->context
, ret
,
297 "krb5_425_conv_principal (%s.%s@%s)",
298 ent
->name
, ent
->instance
, v4_realm
);
301 hdb
.entry
.kvno
= ntohl(ent
->kvno
);
302 hdb
.entry
.keys
.len
= 3;
304 malloc(hdb
.entry
.keys
.len
* sizeof(*hdb
.entry
.keys
.val
));
305 if (hdb
.entry
.keys
.val
== NULL
)
306 krb5_errx(pd
->context
, ENOMEM
, "malloc");
307 hdb
.entry
.keys
.val
[0].mkvno
= NULL
;
308 hdb
.entry
.keys
.val
[0].salt
= calloc(1, sizeof(*hdb
.entry
.keys
.val
[0].salt
));
309 if (hdb
.entry
.keys
.val
[0].salt
== NULL
)
310 krb5_errx(pd
->context
, ENOMEM
, "calloc");
311 if (ka_use_null_salt
) {
312 hdb
.entry
.keys
.val
[0].salt
->type
= hdb_pw_salt
;
313 hdb
.entry
.keys
.val
[0].salt
->salt
.data
= NULL
;
314 hdb
.entry
.keys
.val
[0].salt
->salt
.length
= 0;
316 hdb
.entry
.keys
.val
[0].salt
->type
= hdb_afs3_salt
;
317 hdb
.entry
.keys
.val
[0].salt
->salt
.data
= strdup(afs_cell
);
318 if (hdb
.entry
.keys
.val
[0].salt
->salt
.data
== NULL
)
319 krb5_errx(pd
->context
, ENOMEM
, "strdup");
320 hdb
.entry
.keys
.val
[0].salt
->salt
.length
= strlen(afs_cell
);
323 hdb
.entry
.keys
.val
[0].key
.keytype
= ETYPE_DES_CBC_MD5
;
324 krb5_data_copy(&hdb
.entry
.keys
.val
[0].key
.keyvalue
,
327 copy_Key(&hdb
.entry
.keys
.val
[0], &hdb
.entry
.keys
.val
[1]);
328 hdb
.entry
.keys
.val
[1].key
.keytype
= ETYPE_DES_CBC_MD4
;
329 copy_Key(&hdb
.entry
.keys
.val
[0], &hdb
.entry
.keys
.val
[2]);
330 hdb
.entry
.keys
.val
[2].key
.keytype
= ETYPE_DES_CBC_CRC
;
332 ALLOC(hdb
.entry
.max_life
);
333 *hdb
.entry
.max_life
= ntohl(ent
->max_life
);
335 if(ntohl(ent
->valid_end
) != NEVERDATE
&& ntohl(ent
->valid_end
) != 0xffffffff) {
336 ALLOC(hdb
.entry
.valid_end
);
337 *hdb
.entry
.valid_end
= ntohl(ent
->valid_end
);
340 if (ntohl(ent
->pw_change
) != NEVERDATE
&&
341 ent
->pw_expire
!= 255 &&
342 ent
->pw_expire
!= 0) {
343 ALLOC(hdb
.entry
.pw_end
);
344 *hdb
.entry
.pw_end
= ntohl(ent
->pw_change
)
345 + 24 * 60 * 60 * ent
->pw_expire
;
348 ret
= krb5_make_principal(pd
->context
, &hdb
.entry
.created_by
.principal
,
353 hdb
.entry
.created_by
.time
= time(NULL
);
357 ALLOC(hdb
.entry
.modified_by
);
358 read_block(pd
->context
, fd
, ntohl(ent
->mod_ptr
), &mod
, sizeof(mod
));
360 krb5_425_conv_principal(pd
->context
, mod
.name
, mod
.instance
, v4_realm
,
361 &hdb
.entry
.modified_by
->principal
);
362 hdb
.entry
.modified_by
->time
= ntohl(ent
->mod_time
);
363 memset(&mod
, 0, sizeof(mod
));
366 hdb
.entry
.flags
.forwardable
= 1;
367 hdb
.entry
.flags
.renewable
= 1;
368 hdb
.entry
.flags
.proxiable
= 1;
369 hdb
.entry
.flags
.postdate
= 1;
370 /* XXX - AFS 3.4a creates krbtgt.REALMOFCELL as NOTGS+NOSEAL */
371 if (strcmp(ent
->name
, "krbtgt") == 0 &&
372 (flags
& (KAFNOTGS
|KAFNOSEAL
)) == (KAFNOTGS
|KAFNOSEAL
))
373 flags
&= ~(KAFNOTGS
|KAFNOSEAL
);
375 hdb
.entry
.flags
.client
= (flags
& KAFNOTGS
) == 0;
376 hdb
.entry
.flags
.server
= (flags
& KAFNOSEAL
) == 0;
378 ret
= v5_prop(pd
->context
, NULL
, &hdb
, pd
);
379 hdb_free_entry(pd
->context
, &hdb
);
384 ka_dump(struct prop_data
*pd
, const char *file
)
386 struct ka_header header
;
388 int fd
= open(file
, O_RDONLY
);
391 krb5_err(pd
->context
, 1, errno
, "open(%s)", file
);
392 read_block(pd
->context
, fd
, 0, &header
, sizeof(header
));
393 if(header
.version1
!= header
.version2
)
394 krb5_errx(pd
->context
, 1, "Version mismatch in header: %ld/%ld",
395 (long)ntohl(header
.version1
), (long)ntohl(header
.version2
));
396 if(ntohl(header
.version1
) != 5)
397 krb5_errx(pd
->context
, 1, "Unknown database version %ld (expected 5)",
398 (long)ntohl(header
.version1
));
399 for(i
= 0; i
< ntohl(header
.hashsize
); i
++){
400 int32_t pos
= ntohl(header
.hash
[i
]);
403 read_block(pd
->context
, fd
, pos
, &ent
, sizeof(ent
));
404 ka_convert(pd
, fd
, &ent
);
405 pos
= ntohl(ent
.next
);
413 struct getargs args
[] = {
414 { "master-key", 'm', arg_string
, &mkeyfile
, "v5 master key file", "file" },
415 { "database", 'd', arg_string
, &database
, "database", "file" },
416 { "source", 0, arg_string
, &source_type
, "type of database to read",
426 { "v4-realm", 'r', arg_string
, &v4_realm
, "v4 realm to use" },
428 { "cell", 'c', arg_string
, &afs_cell
, "name of AFS cell" },
430 { "kaspecials", 'S', arg_flag
, &kaspecials_flag
, "dump KASPECIAL keys"},
432 { "keytab", 'k', arg_string
, &ktname
, "keytab to use for authentication", "keytab" },
433 { "v5-realm", 'R', arg_string
, &local_realm
, "v5 realm to use" },
434 { "decrypt", 'D', arg_flag
, &decrypt_flag
, "decrypt keys" },
435 { "encrypt", 'E', arg_flag
, &encrypt_flag
, "encrypt keys" },
436 { "stdout", 'n', arg_flag
, &to_stdout
, "dump to stdout" },
437 { "verbose", 'v', arg_flag
, &verbose_flag
},
438 { "version", 0, arg_flag
, &version_flag
},
439 { "help", 'h', arg_flag
, &help_flag
}
442 static int num_args
= sizeof(args
) / sizeof(args
[0]);
447 arg_printusage (args
, num_args
, NULL
, "[host[:port]] ...");
452 get_creds(krb5_context context
, krb5_ccache
*cache
)
455 krb5_principal client
;
457 krb5_get_init_creds_opt
*init_opts
;
458 krb5_preauthtype preauth
= KRB5_PADATA_ENC_TIMESTAMP
;
461 ret
= krb5_kt_register(context
, &hdb_kt_ops
);
462 if(ret
) krb5_err(context
, 1, ret
, "krb5_kt_register");
464 ret
= krb5_kt_resolve(context
, ktname
, &keytab
);
465 if(ret
) krb5_err(context
, 1, ret
, "krb5_kt_resolve");
467 ret
= krb5_make_principal(context
, &client
, NULL
,
468 "kadmin", HPROP_NAME
, NULL
);
469 if(ret
) krb5_err(context
, 1, ret
, "krb5_make_principal");
471 ret
= krb5_get_init_creds_opt_alloc(context
, &init_opts
);
472 if(ret
) krb5_err(context
, 1, ret
, "krb5_get_init_creds_opt_alloc");
473 krb5_get_init_creds_opt_set_preauth_list(init_opts
, &preauth
, 1);
475 ret
= krb5_get_init_creds_keytab(context
, &creds
, client
, keytab
, 0, NULL
, init_opts
);
476 if(ret
) krb5_err(context
, 1, ret
, "krb5_get_init_creds");
478 krb5_get_init_creds_opt_free(context
, init_opts
);
480 ret
= krb5_kt_close(context
, keytab
);
481 if(ret
) krb5_err(context
, 1, ret
, "krb5_kt_close");
483 ret
= krb5_cc_new_unique(context
, krb5_cc_type_memory
, NULL
, cache
);
484 if(ret
) krb5_err(context
, 1, ret
, "krb5_cc_new_unique");
486 ret
= krb5_cc_initialize(context
, *cache
, client
);
487 if(ret
) krb5_err(context
, 1, ret
, "krb5_cc_initialize");
489 krb5_free_principal(context
, client
);
491 ret
= krb5_cc_store_cred(context
, *cache
, &creds
);
492 if(ret
) krb5_err(context
, 1, ret
, "krb5_cc_store_cred");
494 krb5_free_cred_contents(context
, &creds
);
504 #define IS_TYPE_V4(X) ((X) == HPROP_KRB4_DUMP || (X) == HPROP_KASERVER)
510 { HPROP_HEIMDAL
, "heimdal" },
511 { HPROP_KRB4_DUMP
, "krb4-dump" },
512 { HPROP_KASERVER
, "kaserver" },
513 { HPROP_MIT_DUMP
, "mit-dump" }
517 parse_source_type(const char *s
)
520 for(i
= 0; i
< sizeof(types
) / sizeof(types
[0]); i
++) {
521 if(strstr(types
[i
].name
, s
) == types
[i
].name
)
522 return types
[i
].type
;
528 iterate (krb5_context context
,
529 const char *database_name
,
532 struct prop_data
*pd
)
538 case HPROP_KRB4_DUMP
:
539 ret
= v4_prop_dump(pd
, database_name
);
541 krb5_warn(context
, ret
, "v4_prop_dump");
544 ret
= ka_dump(pd
, database_name
);
546 krb5_warn(context
, ret
, "ka_dump");
550 ret
= mit_prop_dump(pd
, database_name
);
552 krb5_warn(context
, ret
, "mit_prop_dump");
555 ret
= hdb_foreach(context
, db
, HDB_F_DECRYPT
, v5_prop
, pd
);
557 krb5_warn(context
, ret
, "hdb_foreach");
560 krb5_errx(context
, 1, "unknown prop type: %d", type
);
566 dump_database (krb5_context context
, int type
,
567 const char *database_name
, HDB
*db
)
573 pd
.context
= context
;
574 pd
.auth_context
= NULL
;
575 pd
.sock
= STDOUT_FILENO
;
577 ret
= iterate (context
, database_name
, db
, type
, &pd
);
579 krb5_errx(context
, 1, "iterate failure");
580 krb5_data_zero (&data
);
581 ret
= krb5_write_message (context
, &pd
.sock
, &data
);
583 krb5_err(context
, 1, ret
, "krb5_write_message");
589 propagate_database (krb5_context context
, int type
,
590 const char *database_name
,
591 HDB
*db
, krb5_ccache ccache
,
592 int optidx
, int argc
, char **argv
)
594 krb5_principal server
;
598 for(i
= optidx
; i
< argc
; i
++){
599 krb5_auth_context auth_context
;
604 char *port
, portstr
[NI_MAXSERV
];
605 char *host
= argv
[i
];
607 port
= strchr(host
, ':');
609 snprintf(portstr
, sizeof(portstr
), "%u",
610 ntohs(krb5_getportbyname (context
, "hprop", "tcp",
616 fd
= open_socket(context
, host
, port
);
619 krb5_warn (context
, errno
, "connect %s", host
);
623 ret
= krb5_sname_to_principal(context
, argv
[i
],
624 HPROP_NAME
, KRB5_NT_SRV_HST
, &server
);
627 krb5_warn(context
, ret
, "krb5_sname_to_principal(%s)", host
);
634 krb5_get_default_realm(context
,&my_realm
);
635 krb5_principal_set_realm(context
,server
,my_realm
);
636 krb5_xfree(my_realm
);
640 ret
= krb5_sendauth(context
,
646 AP_OPTS_MUTUAL_REQUIRED
| AP_OPTS_USE_SUBKEY
,
654 krb5_free_principal(context
, server
);
658 krb5_warn(context
, ret
, "krb5_sendauth (%s)", host
);
663 pd
.context
= context
;
664 pd
.auth_context
= auth_context
;
667 ret
= iterate (context
, database_name
, db
, type
, &pd
);
669 krb5_warnx(context
, "iterate to host %s failed", host
);
674 krb5_data_zero (&data
);
675 ret
= krb5_write_priv_message(context
, auth_context
, &fd
, &data
);
677 krb5_warn(context
, ret
, "krb5_write_priv_message");
682 ret
= krb5_read_priv_message(context
, auth_context
, &fd
, &data
);
684 krb5_warn(context
, ret
, "krb5_read_priv_message: %s", host
);
688 krb5_data_free (&data
);
691 krb5_auth_con_free(context
, auth_context
);
700 main(int argc
, char **argv
)
703 krb5_context context
;
704 krb5_ccache ccache
= NULL
;
710 setprogname(argv
[0]);
712 if(getarg(args
, num_args
, argc
, argv
, &optidx
))
723 ret
= krb5_init_context(&context
);
727 /* We may be reading an old database encrypted with a DES master key. */
728 ret
= krb5_allow_weak_crypto(context
, 1);
730 krb5_err(context
, 1, ret
, "krb5_allow_weak_crypto");
733 krb5_set_default_realm(context
, local_realm
);
735 if(v4_realm
== NULL
) {
736 ret
= krb5_get_default_realm(context
, &v4_realm
);
738 krb5_err(context
, 1, ret
, "krb5_get_default_realm");
741 if(afs_cell
== NULL
) {
742 afs_cell
= strdup(v4_realm
);
744 krb5_errx(context
, 1, "out of memory");
749 if(encrypt_flag
&& decrypt_flag
)
750 krb5_errx(context
, 1,
751 "only one of `--encrypt' and `--decrypt' is meaningful");
753 if(source_type
!= NULL
) {
754 type
= parse_source_type(source_type
);
756 krb5_errx(context
, 1, "unknown source type `%s'", source_type
);
758 type
= HPROP_HEIMDAL
;
761 get_creds(context
, &ccache
);
763 if(decrypt_flag
|| encrypt_flag
) {
764 ret
= hdb_read_master_key(context
, mkeyfile
, &mkey5
);
765 if(ret
&& ret
!= ENOENT
)
766 krb5_err(context
, 1, ret
, "hdb_read_master_key");
768 krb5_errx(context
, 1, "No master key file found");
771 if (IS_TYPE_V4(type
) && v4_realm
== NULL
)
772 krb5_errx(context
, 1, "Its a Kerberos 4 database "
773 "but no realm configured");
777 if (database
== NULL
)
778 database
= DEFAULT_DATABASE
;
779 ka_use_null_salt
= krb5_config_get_bool_default(context
, NULL
, FALSE
,
781 "afs_uses_null_salt",
785 case HPROP_KRB4_DUMP
:
786 if (database
== NULL
)
787 krb5_errx(context
, 1, "no dump file specified");
791 if (database
== NULL
)
792 krb5_errx(context
, 1, "no dump file specified");
795 ret
= hdb_create (context
, &db
, database
);
797 krb5_err(context
, 1, ret
, "hdb_create: %s", database
);
798 ret
= db
->hdb_open(context
, db
, O_RDONLY
, 0);
800 krb5_err(context
, 1, ret
, "db->hdb_open");
803 krb5_errx(context
, 1, "unknown dump type `%d'", type
);
808 exit_code
= dump_database (context
, type
, database
, db
);
810 exit_code
= propagate_database (context
, type
, database
,
811 db
, ccache
, optidx
, argc
, argv
);
814 krb5_cc_destroy(context
, ccache
);
817 (*db
->hdb_destroy
)(context
, db
);
819 krb5_free_context(context
);