1004388ebScasper /*
2159d09a2SMark Phalan * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3004388ebScasper * Use is subject to license terms.
4004388ebScasper */
5505d05c7Sgtb
6505d05c7Sgtb /*
7505d05c7Sgtb * lib/krb5/keytab/srvtab/kts_resolv.c
8505d05c7Sgtb *
9505d05c7Sgtb * Copyright 1990,1991,2002 by the Massachusetts Institute of Technology.
10505d05c7Sgtb * All Rights Reserved.
11505d05c7Sgtb *
12505d05c7Sgtb * Export of this software from the United States of America may
13505d05c7Sgtb * require a specific license from the United States Government.
14505d05c7Sgtb * It is the responsibility of any person or organization contemplating
15505d05c7Sgtb * export to obtain such a license before exporting.
16*55fea89dSDan Cross *
17505d05c7Sgtb * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
18505d05c7Sgtb * distribute this software and its documentation for any purpose and
19505d05c7Sgtb * without fee is hereby granted, provided that the above copyright
20505d05c7Sgtb * notice appear in all copies and that both that copyright notice and
21505d05c7Sgtb * this permission notice appear in supporting documentation, and that
22505d05c7Sgtb * the name of M.I.T. not be used in advertising or publicity pertaining
23505d05c7Sgtb * to distribution of the software without specific, written prior
24505d05c7Sgtb * permission. Furthermore if you modify this software you must label
25505d05c7Sgtb * your software as modified software and not distribute it in such a
26505d05c7Sgtb * fashion that it might be confused with the original M.I.T. software.
27505d05c7Sgtb * M.I.T. makes no representations about the suitability of
28505d05c7Sgtb * this software for any purpose. It is provided "as is" without express
29505d05c7Sgtb * or implied warranty.
30505d05c7Sgtb */
31505d05c7Sgtb
32505d05c7Sgtb #include "k5-int.h"
33505d05c7Sgtb #include <stdio.h>
34505d05c7Sgtb
35505d05c7Sgtb /*
36505d05c7Sgtb * Constants
37505d05c7Sgtb */
38505d05c7Sgtb #define IGNORE_VNO 0
39505d05c7Sgtb #define IGNORE_ENCTYPE 0
40505d05c7Sgtb
41505d05c7Sgtb #define KRB5_KT_VNO_1 0x0501 /* krb v5, keytab version 1 (DCE compat) */
42505d05c7Sgtb #define KRB5_KT_VNO 0x0502 /* krb v5, keytab version 2 (standard) */
43505d05c7Sgtb
44505d05c7Sgtb #define KRB5_KT_DEFAULT_VNO KRB5_KT_VNO
45505d05c7Sgtb
46*55fea89dSDan Cross /*
47505d05c7Sgtb * Types
48505d05c7Sgtb */
49505d05c7Sgtb typedef struct _krb5_ktsrvtab_data {
50505d05c7Sgtb char *name; /* Name of the file */
51505d05c7Sgtb FILE *openf; /* open file, if any. */
52505d05c7Sgtb } krb5_ktsrvtab_data;
53505d05c7Sgtb
54505d05c7Sgtb /*
55505d05c7Sgtb * Macros
56505d05c7Sgtb */
57505d05c7Sgtb #define KTPRIVATE(id) ((krb5_ktsrvtab_data *)(id)->data)
58505d05c7Sgtb #define KTFILENAME(id) (((krb5_ktsrvtab_data *)(id)->data)->name)
59505d05c7Sgtb #define KTFILEP(id) (((krb5_ktsrvtab_data *)(id)->data)->openf)
60505d05c7Sgtb
61505d05c7Sgtb extern const struct _krb5_kt_ops krb5_kts_ops;
62505d05c7Sgtb
63505d05c7Sgtb static krb5_error_code KRB5_CALLCONV krb5_ktsrvtab_resolve
64505d05c7Sgtb (krb5_context,
65505d05c7Sgtb const char *,
66505d05c7Sgtb krb5_keytab *);
67505d05c7Sgtb
68505d05c7Sgtb static krb5_error_code KRB5_CALLCONV krb5_ktsrvtab_get_name
69505d05c7Sgtb (krb5_context,
70505d05c7Sgtb krb5_keytab,
71505d05c7Sgtb char *,
72505d05c7Sgtb unsigned int);
73505d05c7Sgtb
74505d05c7Sgtb static krb5_error_code KRB5_CALLCONV krb5_ktsrvtab_close
75505d05c7Sgtb (krb5_context,
76505d05c7Sgtb krb5_keytab);
77505d05c7Sgtb
78505d05c7Sgtb static krb5_error_code KRB5_CALLCONV krb5_ktsrvtab_get_entry
79505d05c7Sgtb (krb5_context,
80505d05c7Sgtb krb5_keytab,
81505d05c7Sgtb krb5_const_principal,
82505d05c7Sgtb krb5_kvno,
83505d05c7Sgtb krb5_enctype,
84505d05c7Sgtb krb5_keytab_entry *);
85505d05c7Sgtb
86505d05c7Sgtb static krb5_error_code KRB5_CALLCONV krb5_ktsrvtab_start_seq_get
87505d05c7Sgtb (krb5_context,
88505d05c7Sgtb krb5_keytab,
89505d05c7Sgtb krb5_kt_cursor *);
90505d05c7Sgtb
91505d05c7Sgtb static krb5_error_code KRB5_CALLCONV krb5_ktsrvtab_get_next
92505d05c7Sgtb (krb5_context,
93505d05c7Sgtb krb5_keytab,
94505d05c7Sgtb krb5_keytab_entry *,
95505d05c7Sgtb krb5_kt_cursor *);
96505d05c7Sgtb
97505d05c7Sgtb static krb5_error_code KRB5_CALLCONV krb5_ktsrvtab_end_get
98505d05c7Sgtb (krb5_context,
99505d05c7Sgtb krb5_keytab,
100505d05c7Sgtb krb5_kt_cursor *);
101505d05c7Sgtb
102505d05c7Sgtb static krb5_error_code krb5_ktsrvint_open
103505d05c7Sgtb (krb5_context,
104505d05c7Sgtb krb5_keytab);
105505d05c7Sgtb
106505d05c7Sgtb static krb5_error_code krb5_ktsrvint_close
107505d05c7Sgtb (krb5_context,
108505d05c7Sgtb krb5_keytab);
109505d05c7Sgtb
110*55fea89dSDan Cross static krb5_error_code krb5_ktsrvint_read_entry
111505d05c7Sgtb (krb5_context,
112505d05c7Sgtb krb5_keytab,
113505d05c7Sgtb krb5_keytab_entry *);
114505d05c7Sgtb
115505d05c7Sgtb /*
116*55fea89dSDan Cross * This is an implementation specific resolver. It returns a keytab id
117505d05c7Sgtb * initialized with srvtab keytab routines.
118505d05c7Sgtb */
119505d05c7Sgtb
120505d05c7Sgtb static krb5_error_code KRB5_CALLCONV
krb5_ktsrvtab_resolve(krb5_context context,const char * name,krb5_keytab * id)121505d05c7Sgtb krb5_ktsrvtab_resolve(krb5_context context, const char *name, krb5_keytab *id)
122505d05c7Sgtb {
123505d05c7Sgtb krb5_ktsrvtab_data *data;
124505d05c7Sgtb FILE *fp;
125505d05c7Sgtb
126505d05c7Sgtb /* Make sure we can open the srvtab file for reading. */
127159d09a2SMark Phalan /* Solaris Kerberos */
128004388ebScasper fp = fopen(name, "rF");
129505d05c7Sgtb if (!fp)
130505d05c7Sgtb return(errno);
131505d05c7Sgtb fclose(fp);
132505d05c7Sgtb
133505d05c7Sgtb if ((*id = (krb5_keytab) malloc(sizeof(**id))) == NULL)
134505d05c7Sgtb return(ENOMEM);
135*55fea89dSDan Cross
136505d05c7Sgtb (*id)->ops = &krb5_kts_ops;
137505d05c7Sgtb data = (krb5_ktsrvtab_data *)malloc(sizeof(krb5_ktsrvtab_data));
138505d05c7Sgtb if (data == NULL) {
139505d05c7Sgtb krb5_xfree(*id);
140505d05c7Sgtb return(ENOMEM);
141505d05c7Sgtb }
142505d05c7Sgtb
143505d05c7Sgtb data->name = (char *)malloc(strlen(name) + 1);
144505d05c7Sgtb if (data->name == NULL) {
145505d05c7Sgtb krb5_xfree(data);
146505d05c7Sgtb krb5_xfree(*id);
147505d05c7Sgtb return(ENOMEM);
148505d05c7Sgtb }
149505d05c7Sgtb
150505d05c7Sgtb (void) strcpy(data->name, name);
151505d05c7Sgtb data->openf = 0;
152505d05c7Sgtb
153505d05c7Sgtb (*id)->data = (krb5_pointer)data;
154505d05c7Sgtb (*id)->magic = KV5M_KEYTAB;
155505d05c7Sgtb return(0);
156505d05c7Sgtb }
157505d05c7Sgtb
158505d05c7Sgtb /*
159505d05c7Sgtb * "Close" a file-based keytab and invalidate the id. This means
160505d05c7Sgtb * free memory hidden in the structures.
161505d05c7Sgtb */
162505d05c7Sgtb
163505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_ktsrvtab_close(krb5_context context,krb5_keytab id)164505d05c7Sgtb krb5_ktsrvtab_close(krb5_context context, krb5_keytab id)
165505d05c7Sgtb /*
166*55fea89dSDan Cross * This routine is responsible for freeing all memory allocated
167505d05c7Sgtb * for this keytab. There are no system resources that need
168505d05c7Sgtb * to be freed nor are there any open files.
169505d05c7Sgtb *
170505d05c7Sgtb * This routine should undo anything done by krb5_ktsrvtab_resolve().
171505d05c7Sgtb */
172505d05c7Sgtb {
173505d05c7Sgtb krb5_xfree(KTFILENAME(id));
174505d05c7Sgtb krb5_xfree(id->data);
175505d05c7Sgtb id->ops = 0;
176505d05c7Sgtb krb5_xfree(id);
177505d05c7Sgtb return (0);
178505d05c7Sgtb }
179505d05c7Sgtb
180505d05c7Sgtb /*
181505d05c7Sgtb * This is the get_entry routine for the file based keytab implementation.
182505d05c7Sgtb * It opens the keytab file, and either retrieves the entry or returns
183505d05c7Sgtb * an error.
184505d05c7Sgtb */
185505d05c7Sgtb
186505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_ktsrvtab_get_entry(krb5_context context,krb5_keytab id,krb5_const_principal principal,krb5_kvno kvno,krb5_enctype enctype,krb5_keytab_entry * entry)187505d05c7Sgtb krb5_ktsrvtab_get_entry(krb5_context context, krb5_keytab id, krb5_const_principal principal, krb5_kvno kvno, krb5_enctype enctype, krb5_keytab_entry *entry)
188505d05c7Sgtb {
189505d05c7Sgtb krb5_keytab_entry best_entry, ent;
190505d05c7Sgtb krb5_error_code kerror = 0;
191505d05c7Sgtb int found_wrong_kvno = 0;
192505d05c7Sgtb
193505d05c7Sgtb /* Open the srvtab. */
194505d05c7Sgtb if ((kerror = krb5_ktsrvint_open(context, id)))
195505d05c7Sgtb return(kerror);
196505d05c7Sgtb
197505d05c7Sgtb /* srvtab files only have DES_CBC_CRC keys. */
198505d05c7Sgtb switch (enctype) {
199505d05c7Sgtb case ENCTYPE_DES_CBC_CRC:
200505d05c7Sgtb case ENCTYPE_DES_CBC_MD5:
201505d05c7Sgtb case ENCTYPE_DES_CBC_MD4:
202505d05c7Sgtb case ENCTYPE_DES_CBC_RAW:
203505d05c7Sgtb case IGNORE_ENCTYPE:
204505d05c7Sgtb break;
205505d05c7Sgtb default:
206505d05c7Sgtb return KRB5_KT_NOTFOUND;
207505d05c7Sgtb }
208505d05c7Sgtb
209505d05c7Sgtb best_entry.principal = 0;
210505d05c7Sgtb best_entry.vno = 0;
211505d05c7Sgtb best_entry.key.contents = 0;
212505d05c7Sgtb while ((kerror = krb5_ktsrvint_read_entry(context, id, &ent)) == 0) {
213505d05c7Sgtb ent.key.enctype = enctype;
214505d05c7Sgtb if (krb5_principal_compare(context, principal, ent.principal)) {
215505d05c7Sgtb if (kvno == IGNORE_VNO) {
216505d05c7Sgtb if (!best_entry.principal || (best_entry.vno < ent.vno)) {
217505d05c7Sgtb krb5_kt_free_entry(context, &best_entry);
218505d05c7Sgtb best_entry = ent;
219505d05c7Sgtb }
220505d05c7Sgtb } else {
221505d05c7Sgtb if (ent.vno == kvno) {
222505d05c7Sgtb best_entry = ent;
223505d05c7Sgtb break;
224505d05c7Sgtb } else {
225505d05c7Sgtb found_wrong_kvno = 1;
226505d05c7Sgtb }
227505d05c7Sgtb }
228505d05c7Sgtb } else {
229505d05c7Sgtb krb5_kt_free_entry(context, &ent);
230505d05c7Sgtb }
231505d05c7Sgtb }
232505d05c7Sgtb if (kerror == KRB5_KT_END) {
233505d05c7Sgtb if (best_entry.principal)
234505d05c7Sgtb kerror = 0;
235505d05c7Sgtb else if (found_wrong_kvno)
236505d05c7Sgtb kerror = KRB5_KT_KVNONOTFOUND;
237505d05c7Sgtb else
238505d05c7Sgtb kerror = KRB5_KT_NOTFOUND;
239505d05c7Sgtb }
240505d05c7Sgtb if (kerror) {
241505d05c7Sgtb (void) krb5_ktsrvint_close(context, id);
242505d05c7Sgtb krb5_kt_free_entry(context, &best_entry);
243505d05c7Sgtb return kerror;
244505d05c7Sgtb }
245505d05c7Sgtb if ((kerror = krb5_ktsrvint_close(context, id)) != 0) {
246505d05c7Sgtb krb5_kt_free_entry(context, &best_entry);
247505d05c7Sgtb return kerror;
248505d05c7Sgtb }
249505d05c7Sgtb *entry = best_entry;
250505d05c7Sgtb return 0;
251505d05c7Sgtb }
252505d05c7Sgtb
253505d05c7Sgtb /*
254505d05c7Sgtb * Get the name of the file containing a srvtab-based keytab.
255505d05c7Sgtb */
256505d05c7Sgtb
257505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_ktsrvtab_get_name(krb5_context context,krb5_keytab id,char * name,unsigned int len)258505d05c7Sgtb krb5_ktsrvtab_get_name(krb5_context context, krb5_keytab id, char *name, unsigned int len)
259*55fea89dSDan Cross /*
260505d05c7Sgtb * This routine returns the name of the name of the file associated with
261505d05c7Sgtb * this srvtab-based keytab. The name is prefixed with PREFIX:, so that
262505d05c7Sgtb * trt will happen if the name is passed back to resolve.
263505d05c7Sgtb */
264505d05c7Sgtb {
265505d05c7Sgtb memset(name, 0, len);
266505d05c7Sgtb
267505d05c7Sgtb if (len < strlen(id->ops->prefix)+2)
268505d05c7Sgtb return(KRB5_KT_NAME_TOOLONG);
269505d05c7Sgtb strcpy(name, id->ops->prefix);
270505d05c7Sgtb name += strlen(id->ops->prefix);
271505d05c7Sgtb name[0] = ':';
272505d05c7Sgtb name++;
273505d05c7Sgtb len -= strlen(id->ops->prefix)+1;
274505d05c7Sgtb
275159d09a2SMark Phalan /* Solaris Kerberos */
27654925bf6Swillf if (len < strlen(KTFILENAME(id))+1)
277505d05c7Sgtb return(KRB5_KT_NAME_TOOLONG);
278505d05c7Sgtb strcpy(name, KTFILENAME(id));
279505d05c7Sgtb /* strcpy will NUL-terminate the destination */
280505d05c7Sgtb
281505d05c7Sgtb return(0);
282505d05c7Sgtb }
283505d05c7Sgtb
284505d05c7Sgtb /*
285505d05c7Sgtb * krb5_ktsrvtab_start_seq_get()
286505d05c7Sgtb */
287505d05c7Sgtb
288505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_ktsrvtab_start_seq_get(krb5_context context,krb5_keytab id,krb5_kt_cursor * cursorp)289505d05c7Sgtb krb5_ktsrvtab_start_seq_get(krb5_context context, krb5_keytab id, krb5_kt_cursor *cursorp)
290505d05c7Sgtb {
291505d05c7Sgtb krb5_error_code retval;
292505d05c7Sgtb long *fileoff;
293505d05c7Sgtb
294505d05c7Sgtb if ((retval = krb5_ktsrvint_open(context, id)))
295505d05c7Sgtb return retval;
296505d05c7Sgtb
297505d05c7Sgtb if (!(fileoff = (long *)malloc(sizeof(*fileoff)))) {
298505d05c7Sgtb krb5_ktsrvint_close(context, id);
299505d05c7Sgtb return ENOMEM;
300505d05c7Sgtb }
301505d05c7Sgtb *fileoff = ftell(KTFILEP(id));
302505d05c7Sgtb *cursorp = (krb5_kt_cursor)fileoff;
303505d05c7Sgtb
304505d05c7Sgtb return 0;
305505d05c7Sgtb }
306505d05c7Sgtb
307505d05c7Sgtb /*
308505d05c7Sgtb * krb5_ktsrvtab_get_next()
309505d05c7Sgtb */
310505d05c7Sgtb
311505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_ktsrvtab_get_next(krb5_context context,krb5_keytab id,krb5_keytab_entry * entry,krb5_kt_cursor * cursor)312505d05c7Sgtb krb5_ktsrvtab_get_next(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry, krb5_kt_cursor *cursor)
313505d05c7Sgtb {
314505d05c7Sgtb long *fileoff = (long *)*cursor;
315505d05c7Sgtb krb5_keytab_entry cur_entry;
316505d05c7Sgtb krb5_error_code kerror;
317505d05c7Sgtb
318505d05c7Sgtb if (fseek(KTFILEP(id), *fileoff, 0) == -1)
319505d05c7Sgtb return KRB5_KT_END;
320505d05c7Sgtb if ((kerror = krb5_ktsrvint_read_entry(context, id, &cur_entry)))
321505d05c7Sgtb return kerror;
322505d05c7Sgtb *fileoff = ftell(KTFILEP(id));
323505d05c7Sgtb *entry = cur_entry;
324505d05c7Sgtb return 0;
325505d05c7Sgtb }
326505d05c7Sgtb
327505d05c7Sgtb /*
328505d05c7Sgtb * krb5_ktsrvtab_end_get()
329505d05c7Sgtb */
330505d05c7Sgtb
331505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_ktsrvtab_end_get(krb5_context context,krb5_keytab id,krb5_kt_cursor * cursor)332505d05c7Sgtb krb5_ktsrvtab_end_get(krb5_context context, krb5_keytab id, krb5_kt_cursor *cursor)
333505d05c7Sgtb {
334505d05c7Sgtb krb5_xfree(*cursor);
335505d05c7Sgtb return krb5_ktsrvint_close(context, id);
336505d05c7Sgtb }
337505d05c7Sgtb
338505d05c7Sgtb /*
339505d05c7Sgtb * krb5_kts_ops
340505d05c7Sgtb */
341505d05c7Sgtb
342505d05c7Sgtb const struct _krb5_kt_ops krb5_kts_ops = {
343505d05c7Sgtb 0,
344505d05c7Sgtb "SRVTAB", /* Prefix -- this string should not appear anywhere else! */
345505d05c7Sgtb krb5_ktsrvtab_resolve,
346*55fea89dSDan Cross krb5_ktsrvtab_get_name,
347505d05c7Sgtb krb5_ktsrvtab_close,
348505d05c7Sgtb krb5_ktsrvtab_get_entry,
349505d05c7Sgtb krb5_ktsrvtab_start_seq_get,
350505d05c7Sgtb krb5_ktsrvtab_get_next,
351505d05c7Sgtb krb5_ktsrvtab_end_get,
352505d05c7Sgtb 0,
353505d05c7Sgtb 0,
354505d05c7Sgtb 0
355505d05c7Sgtb };
356505d05c7Sgtb
357505d05c7Sgtb /*
358505d05c7Sgtb * formerly: lib/krb5/keytab/srvtab/kts_util.c
359505d05c7Sgtb *
360505d05c7Sgtb * Copyright (c) Hewlett-Packard Company 1991
361505d05c7Sgtb * Released to the Massachusetts Institute of Technology for inclusion
362505d05c7Sgtb * in the Kerberos source code distribution.
363505d05c7Sgtb *
364505d05c7Sgtb * Copyright 1990,1991 by the Massachusetts Institute of Technology.
365505d05c7Sgtb * All Rights Reserved.
366505d05c7Sgtb *
367505d05c7Sgtb * Export of this software from the United States of America may
368505d05c7Sgtb * require a specific license from the United States Government.
369505d05c7Sgtb * It is the responsibility of any person or organization contemplating
370505d05c7Sgtb * export to obtain such a license before exporting.
371*55fea89dSDan Cross *
372505d05c7Sgtb * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
373505d05c7Sgtb * distribute this software and its documentation for any purpose and
374505d05c7Sgtb * without fee is hereby granted, provided that the above copyright
375505d05c7Sgtb * notice appear in all copies and that both that copyright notice and
376505d05c7Sgtb * this permission notice appear in supporting documentation, and that
377505d05c7Sgtb * the name of M.I.T. not be used in advertising or publicity pertaining
378505d05c7Sgtb * to distribution of the software without specific, written prior
379505d05c7Sgtb * permission. Furthermore if you modify this software you must label
380505d05c7Sgtb * your software as modified software and not distribute it in such a
381505d05c7Sgtb * fashion that it might be confused with the original M.I.T. software.
382505d05c7Sgtb * M.I.T. makes no representations about the suitability of
383505d05c7Sgtb * this software for any purpose. It is provided "as is" without express
384505d05c7Sgtb * or implied warranty.
385*55fea89dSDan Cross *
386505d05c7Sgtb *
387505d05c7Sgtb * This function contains utilities for the srvtab based implementation
388505d05c7Sgtb * of the keytab. There are no public functions in this file.
389505d05c7Sgtb */
390505d05c7Sgtb
391505d05c7Sgtb #include <stdio.h>
392505d05c7Sgtb
393505d05c7Sgtb #ifdef ANSI_STDIO
394159d09a2SMark Phalan /* Solaris Kerberos */
395004388ebScasper #define READ_MODE "rbF"
396505d05c7Sgtb #else
397159d09a2SMark Phalan /* Solaris Kerberos */
398004388ebScasper #define READ_MODE "rF"
399505d05c7Sgtb #endif
400505d05c7Sgtb
401505d05c7Sgtb /* The maximum sizes for V4 aname, realm, sname, and instance +1 */
402505d05c7Sgtb /* Taken from krb.h */
403505d05c7Sgtb #define ANAME_SZ 40
404505d05c7Sgtb #define REALM_SZ 40
405505d05c7Sgtb #define SNAME_SZ 40
406505d05c7Sgtb #define INST_SZ 40
407505d05c7Sgtb
408505d05c7Sgtb static krb5_error_code
read_field(FILE * fp,char * s,int len)409505d05c7Sgtb read_field(FILE *fp, char *s, int len)
410505d05c7Sgtb {
411505d05c7Sgtb int c;
412505d05c7Sgtb
413505d05c7Sgtb while ((c = getc(fp)) != 0) {
414505d05c7Sgtb if (c == EOF || len <= 1)
415505d05c7Sgtb return KRB5_KT_END;
416505d05c7Sgtb *s = c;
417505d05c7Sgtb s++;
418505d05c7Sgtb len--;
419505d05c7Sgtb }
420505d05c7Sgtb *s = 0;
421505d05c7Sgtb return 0;
422505d05c7Sgtb }
423505d05c7Sgtb
424505d05c7Sgtb krb5_error_code
krb5_ktsrvint_open(krb5_context context,krb5_keytab id)425505d05c7Sgtb krb5_ktsrvint_open(krb5_context context, krb5_keytab id)
426505d05c7Sgtb {
427505d05c7Sgtb KTFILEP(id) = fopen(KTFILENAME(id), READ_MODE);
428505d05c7Sgtb if (!KTFILEP(id))
429505d05c7Sgtb return errno;
430505d05c7Sgtb return 0;
431505d05c7Sgtb }
432505d05c7Sgtb
433505d05c7Sgtb krb5_error_code
krb5_ktsrvint_close(krb5_context context,krb5_keytab id)434505d05c7Sgtb krb5_ktsrvint_close(krb5_context context, krb5_keytab id)
435505d05c7Sgtb {
436505d05c7Sgtb if (!KTFILEP(id))
437505d05c7Sgtb return 0;
438505d05c7Sgtb (void) fclose(KTFILEP(id));
439505d05c7Sgtb KTFILEP(id) = 0;
440505d05c7Sgtb return 0;
441505d05c7Sgtb }
442505d05c7Sgtb
443505d05c7Sgtb krb5_error_code
krb5_ktsrvint_read_entry(krb5_context context,krb5_keytab id,krb5_keytab_entry * ret_entry)444505d05c7Sgtb krb5_ktsrvint_read_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *ret_entry)
445505d05c7Sgtb {
446505d05c7Sgtb FILE *fp;
447505d05c7Sgtb char name[SNAME_SZ], instance[INST_SZ], realm[REALM_SZ];
448505d05c7Sgtb unsigned char key[8];
449505d05c7Sgtb int vno;
450505d05c7Sgtb krb5_error_code kerror;
451505d05c7Sgtb
452505d05c7Sgtb /* Read in an entry from the srvtab file. */
453505d05c7Sgtb fp = KTFILEP(id);
454505d05c7Sgtb kerror = read_field(fp, name, sizeof(name));
455505d05c7Sgtb if (kerror != 0)
456505d05c7Sgtb return kerror;
457505d05c7Sgtb kerror = read_field(fp, instance, sizeof(instance));
458505d05c7Sgtb if (kerror != 0)
459505d05c7Sgtb return kerror;
460505d05c7Sgtb kerror = read_field(fp, realm, sizeof(realm));
461505d05c7Sgtb if (kerror != 0)
462505d05c7Sgtb return kerror;
463505d05c7Sgtb vno = getc(fp);
464505d05c7Sgtb if (vno == EOF)
465505d05c7Sgtb return KRB5_KT_END;
466505d05c7Sgtb if (fread(key, 1, sizeof(key), fp) != sizeof(key))
467505d05c7Sgtb return KRB5_KT_END;
468505d05c7Sgtb
469505d05c7Sgtb /* Fill in ret_entry with the data we read. Everything maps well
470505d05c7Sgtb * except for the timestamp, which we don't have a value for. For
471505d05c7Sgtb * now we just set it to 0. */
472505d05c7Sgtb memset(ret_entry, 0, sizeof(*ret_entry));
473505d05c7Sgtb ret_entry->magic = KV5M_KEYTAB_ENTRY;
474505d05c7Sgtb kerror = krb5_425_conv_principal(context, name, instance, realm,
475505d05c7Sgtb &ret_entry->principal);
476505d05c7Sgtb if (kerror != 0)
477505d05c7Sgtb return kerror;
478505d05c7Sgtb ret_entry->vno = vno;
479505d05c7Sgtb ret_entry->timestamp = 0;
480505d05c7Sgtb ret_entry->key.enctype = ENCTYPE_DES_CBC_CRC;
481505d05c7Sgtb ret_entry->key.magic = KV5M_KEYBLOCK;
482505d05c7Sgtb ret_entry->key.length = sizeof(key);
483505d05c7Sgtb ret_entry->key.contents = malloc(sizeof(key));
484505d05c7Sgtb if (!ret_entry->key.contents) {
485505d05c7Sgtb krb5_free_principal(context, ret_entry->principal);
486505d05c7Sgtb return ENOMEM;
487505d05c7Sgtb }
488505d05c7Sgtb memcpy(ret_entry->key.contents, key, sizeof(key));
489505d05c7Sgtb
490505d05c7Sgtb return 0;
491505d05c7Sgtb }
492