2 * Copyright (c) 1997 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. 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
39 #include "krb5_locl.h"
44 krb5_kt_resolve(krb5_context context
,
50 if (strncmp (name
, "FILE:", 5) != 0)
51 return KRB5_KT_UNKNOWN_TYPE
;
56 k
->filename
= strdup(name
+ 5);
57 if (k
->filename
== NULL
) {
65 #define KEYTAB_DEFAULT "FILE:/etc/v5srvtab"
68 krb5_kt_default_name(krb5_context context
,
72 strncpy (name
, KEYTAB_DEFAULT
, namesize
);
77 krb5_kt_default(krb5_context context
,
80 return krb5_kt_resolve (context
, KEYTAB_DEFAULT
, id
);
84 krb5_kt_read_service_key(krb5_context context
,
85 krb5_pointer keyprocarg
,
86 krb5_principal principal
,
92 krb5_keytab_entry entry
;
96 r
= krb5_kt_resolve (context
, keyprocarg
, &keytab
);
98 r
= krb5_kt_default (context
, &keytab
);
103 r
= krb5_kt_get_entry (context
, keytab
, principal
, vno
, keytype
, &entry
);
106 *key
= malloc(sizeof(**key
));
107 (*key
)->keytype
= entry
.keyblock
.keytype
;
108 (*key
)->keyvalue
.length
= 0;
109 (*key
)->keyvalue
.data
= NULL
;
110 krb5_data_copy(&(*key
)->keyvalue
, entry
.keyblock
.keyvalue
.data
,
111 entry
.keyblock
.keyvalue
.length
);
113 krb5_kt_close (context
, keytab
);
117 #if 0 /* not implemented */
119 krb5_kt_remove_entry(krb5_context context
,
121 krb5_keytab_entry
*entry
)
128 krb5_kt_get_name(krb5_context context
,
133 strncpy (name
, keytab
->filename
, namesize
);
138 krb5_kt_close(krb5_context context
,
147 krb5_kt_get_entry(krb5_context context
,
149 krb5_const_principal principal
,
151 krb5_keytype keytype
,
152 krb5_keytab_entry
*entry
)
154 krb5_keytab_entry tmp
;
156 krb5_kt_cursor cursor
;
158 r
= krb5_kt_start_seq_get (context
, id
, &cursor
);
160 return KRB5_KT_NOTFOUND
; /* XXX i.e. file not found */
163 while (krb5_kt_next_entry(context
, id
, &tmp
, &cursor
) == 0) {
164 if ((principal
== NULL
165 || krb5_principal_compare(context
,
168 && (keytype
== 0 || keytype
== tmp
.keyblock
.keytype
)) {
169 if (kvno
== tmp
.vno
) {
170 krb5_kt_copy_entry_contents (context
, &tmp
, entry
);
171 krb5_kt_free_entry (context
, &tmp
);
172 krb5_kt_end_seq_get(context
, id
, &cursor
);
174 } else if (kvno
== 0 && tmp
.vno
> entry
->vno
) {
176 krb5_kt_free_entry (context
, entry
);
177 krb5_kt_copy_entry_contents (context
, &tmp
, entry
);
180 krb5_kt_free_entry(context
, &tmp
);
182 krb5_kt_end_seq_get (context
, id
, &cursor
);
186 return KRB5_KT_NOTFOUND
;
190 krb5_kt_copy_entry_contents(krb5_context context
,
191 const krb5_keytab_entry
*in
,
192 krb5_keytab_entry
*out
)
196 memset(out
, 0, sizeof(*out
));
199 ret
= krb5_copy_principal (context
, in
->principal
, &out
->principal
);
202 ret
= krb5_copy_keyblock_contents (context
,
209 krb5_kt_free_entry (context
, out
);
214 krb5_kt_free_entry(krb5_context context
,
215 krb5_keytab_entry
*entry
)
217 krb5_free_principal (context
, entry
->principal
);
218 krb5_free_keyblock_contents (context
, &entry
->keyblock
);
223 krb5_kt_start_seq_get(krb5_context context
,
225 krb5_kt_cursor
*cursor
)
230 cursor
->fd
= open (id
->filename
, O_RDONLY
);
233 cursor
->sp
= krb5_storage_from_fd(cursor
->fd
);
234 ret
= krb5_ret_int16(cursor
->sp
, &tag
);
238 return KRB5_KT_UNKNOWN_TYPE
;
242 static krb5_error_code
243 krb5_kt_ret_data(krb5_storage
*sp
,
248 ret
= krb5_ret_int16(sp
, &size
);
252 data
->data
= malloc(size
);
253 if (data
->data
== NULL
)
255 ret
= sp
->fetch(sp
, data
->data
, size
);
257 return (ret
< 0)? errno
: KRB5_KT_END
;
261 static krb5_error_code
262 krb5_kt_ret_string(krb5_storage
*sp
,
263 general_string
*data
)
267 ret
= krb5_ret_int16(sp
, &size
);
270 *data
= malloc(size
+ 1);
273 ret
= sp
->fetch(sp
, *data
, size
);
274 (*data
)[size
] = '\0';
276 return (ret
< 0)? errno
: KRB5_KT_END
;
280 static krb5_error_code
281 krb5_kt_ret_principal(krb5_storage
*sp
,
282 krb5_principal
*princ
)
293 ret
= krb5_ret_int16(sp
, &tmp
);
296 p
->name
.name_type
= KRB5_NT_SRV_HST
;
297 p
->name
.name_string
.len
= tmp
;
298 ret
= krb5_kt_ret_string(sp
, &p
->realm
);
300 p
->name
.name_string
.val
= calloc(p
->name
.name_string
.len
,
301 sizeof(*p
->name
.name_string
.val
));
302 if(p
->name
.name_string
.val
== NULL
)
304 for(i
= 0; i
< p
->name
.name_string
.len
; i
++){
305 ret
= krb5_kt_ret_string(sp
, p
->name
.name_string
.val
+ i
);
312 static krb5_error_code
313 krb5_kt_ret_keyblock(krb5_storage
*sp
, krb5_keyblock
*p
)
318 ret
= krb5_ret_int16(sp
, &tmp
); /* keytype + etype */
321 ret
= krb5_kt_ret_data(sp
, &p
->keyvalue
);
325 static krb5_error_code
326 krb5_kt_store_data(krb5_storage
*sp
,
330 ret
= krb5_store_int16(sp
, data
.length
);
333 ret
= sp
->store(sp
, data
.data
, data
.length
);
334 if(ret
!= data
.length
){
342 static krb5_error_code
343 krb5_kt_store_string(krb5_storage
*sp
,
347 size_t len
= strlen(data
);
348 ret
= krb5_store_int16(sp
, len
);
351 ret
= sp
->store(sp
, data
, len
);
360 static krb5_error_code
361 krb5_kt_store_keyblock(krb5_storage
*sp
,
366 ret
= krb5_store_int16(sp
, p
->keytype
); /* keytype + etype */
368 ret
= krb5_kt_store_data(sp
, p
->keyvalue
);
373 static krb5_error_code
374 krb5_kt_store_principal(krb5_storage
*sp
,
380 ret
= krb5_store_int16(sp
, p
->name
.name_string
.len
);
382 ret
= krb5_kt_store_string(sp
, p
->realm
);
384 for(i
= 0; i
< p
->name
.name_string
.len
; i
++){
385 ret
= krb5_kt_store_string(sp
, p
->name
.name_string
.val
[i
]);
393 krb5_kt_add_entry(krb5_context context
,
395 krb5_keytab_entry
*entry
)
401 fd
= open (id
->filename
, O_WRONLY
| O_APPEND
);
403 fd
= open (id
->filename
, O_WRONLY
| O_CREAT
, 0600);
406 sp
= krb5_storage_from_fd(fd
);
407 ret
= krb5_store_int16 (sp
, 0x0502);
410 sp
= krb5_storage_from_fd(fd
);
413 ret
= krb5_store_int32 (sp
, 4711); /* XXX */
415 ret
= krb5_kt_store_principal (sp
, entry
->principal
);
417 ret
= krb5_store_int32 (sp
, entry
->principal
->name
.name_type
);
419 ret
= krb5_store_int32 (sp
, time(NULL
));
421 ret
= krb5_store_int8 (sp
, entry
->vno
);
423 ret
= krb5_kt_store_keyblock (sp
, &entry
->keyblock
);
425 krb5_storage_free (sp
);
431 krb5_kt_next_entry(krb5_context context
,
433 krb5_keytab_entry
*entry
,
434 krb5_kt_cursor
*cursor
)
442 ret
= krb5_ret_int32(cursor
->sp
, &tmp32
);
446 ret
= krb5_kt_ret_principal (cursor
->sp
, &entry
->principal
);
449 ret
= krb5_ret_int32(cursor
->sp
, &tmp32
);
450 entry
->principal
->name
.name_type
= tmp32
;
453 ret
= krb5_ret_int32(cursor
->sp
, &tmp32
);
457 ret
= krb5_ret_int8(cursor
->sp
, &tmp8
);
461 ret
= krb5_kt_ret_keyblock (cursor
->sp
, &entry
->keyblock
);
468 krb5_kt_end_seq_get(krb5_context context
,
470 krb5_kt_cursor
*cursor
)
472 krb5_storage_free(cursor
->sp
);