Add des3 string-to-key. Add ktype argument to krb5_string_to_key().
[heimdal.git] / admin / srvconvert.c
blob91cd14e641a6e29d92d4cfe787f0d056af5f43a9
1 /*
2 * Copyright (c) 1997 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
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. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Kungliga Tekniska
20 * Högskolan and its contributors.
22 * 4. Neither the name of the Institute nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
39 #include "ktutil_locl.h"
41 RCSID("$Id$");
43 /* convert a version 4 srvtab to a version 5 keytab */
45 #ifndef KEYFILE
46 #define KEYFILE "/etc/srvtab"
47 #endif
49 static char *srvtab = KEYFILE;
50 static char *keytab;
51 static int help_flag;
52 static int verbose;
54 static struct getargs args[] = {
55 { "srvtab", 's', arg_string, &srvtab, "Srvtab to convert", "file" },
56 { "keytab", 'k', arg_string, &keytab, "Keytab to put result in", "keytab" },
57 { "help", 'h', arg_flag, &help_flag },
58 { "verbose", 'v', arg_flag, &verbose },
61 static int num_args = sizeof(args) / sizeof(args[0]);
63 int
64 srvconv(int argc, char **argv)
66 krb5_error_code ret;
67 int optind = 0;
68 char keytab_name[256];
69 int fd;
70 krb5_storage *sp;
71 krb5_keytab id;
73 if(getarg(args, num_args, argc, argv, &optind)){
74 arg_printusage(args, num_args, "");
75 return 1;
77 if(help_flag){
78 arg_printusage(args, num_args, "");
79 return 0;
82 argc -= optind;
83 argv += optind;
85 if (argc != 0) {
86 arg_printusage(args, num_args, "");
87 return 1;
90 if(keytab == NULL){
91 ret = krb5_kt_default_name(context, keytab_name, sizeof(keytab_name));
92 if(ret) {
93 krb5_warn(context, ret, "krb5_kt_default_name");
94 return 1;
96 keytab = keytab_name;
98 ret = krb5_kt_resolve(context, keytab, &id);
99 if(ret) {
100 krb5_warn(context, ret, "krb5_kt_resolve");
101 return 1;
103 fd = open(srvtab, O_RDONLY);
104 if(fd < 0){
105 krb5_warn(context, errno, "%s", srvtab);
106 krb5_kt_close(context, id);
107 return 1;
109 sp = krb5_storage_from_fd(fd);
110 if(sp == NULL){
111 close(fd);
112 krb5_kt_close(context, id);
113 return 1;
115 while(1){
116 char *service, *instance, *realm;
117 int8_t kvno;
118 des_cblock key;
119 krb5_keytab_entry entry;
121 ret = krb5_ret_stringz(sp, &service);
122 if(ret == KRB5_CC_END)
123 break;
124 if(ret) {
125 krb5_warn(context, ret, "reading service");
126 break;
128 ret = krb5_ret_stringz(sp, &instance);
129 if(ret) {
130 krb5_warn(context, ret, "reading instance");
131 free(service);
132 break;
134 ret = krb5_ret_stringz(sp, &realm);
135 if(ret) {
136 krb5_warn(context, ret, "reading realm");
137 free(service);
138 free(instance);
139 break;
141 ret = krb5_425_conv_principal(context, service, instance, realm,
142 &entry.principal);
143 free(service);
144 free(instance);
145 free(realm);
147 if(ret) {
148 krb5_warn(context, ret, "krb5_425_conv_principal");
149 break;
152 ret = krb5_ret_int8(sp, &kvno);
153 if(ret) {
154 krb5_warn(context, ret, "reading kvno");
155 krb5_free_principal(context, entry.principal);
156 break;
158 ret = sp->fetch(sp, key, 8);
159 if(ret < 0){
160 krb5_warn(context, errno, "reading key");
161 krb5_free_principal(context, entry.principal);
162 break;
164 if(ret < 8) {
165 krb5_warn(context, errno, "end of file while reading key");
166 krb5_free_principal(context, entry.principal);
167 break;
170 entry.vno = kvno;
171 entry.keyblock.keytype = KEYTYPE_DES;
172 entry.keyblock.keyvalue.data = key;
173 entry.keyblock.keyvalue.length = 8;
175 if(verbose){
176 char *p;
177 ret = krb5_unparse_name(context, entry.principal, &p);
178 if(ret){
179 krb5_warn(context, ret, "krb5_unparse_name");
180 krb5_free_principal(context, entry.principal);
181 break;
182 } else{
183 fprintf(stderr, "Storing keytab for %s\n", p);
184 free(p);
188 ret = krb5_kt_add_entry(context, id, &entry);
189 krb5_free_principal(context, entry.principal);
190 if(ret) {
191 krb5_warn(context, ret, "krb5_kt_add_entry");
192 break;
195 krb5_storage_free(sp);
196 close(fd);
197 krb5_kt_close(context, id);
198 return ret;