1*1c9681d1Schristos /*	$NetBSD: hdb-keytab.c,v 1.2 2017/01/28 21:31:48 christos Exp $	*/
2f59d82ffSelric 
3f59d82ffSelric /*
4f59d82ffSelric  * Copyright (c) 2009 Kungliga Tekniska H�gskolan
5f59d82ffSelric  * (Royal Institute of Technology, Stockholm, Sweden).
6f59d82ffSelric  * All rights reserved.
7f59d82ffSelric  *
8f59d82ffSelric  * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
9f59d82ffSelric  *
10f59d82ffSelric  * Redistribution and use in source and binary forms, with or without
11f59d82ffSelric  * modification, are permitted provided that the following conditions
12f59d82ffSelric  * are met:
13f59d82ffSelric  *
14f59d82ffSelric  * 1. Redistributions of source code must retain the above copyright
15f59d82ffSelric  *    notice, this list of conditions and the following disclaimer.
16f59d82ffSelric  *
17f59d82ffSelric  * 2. Redistributions in binary form must reproduce the above copyright
18f59d82ffSelric  *    notice, this list of conditions and the following disclaimer in the
19f59d82ffSelric  *    documentation and/or other materials provided with the distribution.
20f59d82ffSelric  *
21f59d82ffSelric  * 3. Neither the name of the Institute nor the names of its contributors
22f59d82ffSelric  *    may be used to endorse or promote products derived from this software
23f59d82ffSelric  *    without specific prior written permission.
24f59d82ffSelric  *
25f59d82ffSelric  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
26f59d82ffSelric  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27f59d82ffSelric  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28f59d82ffSelric  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
29f59d82ffSelric  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30f59d82ffSelric  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31f59d82ffSelric  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32f59d82ffSelric  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33f59d82ffSelric  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34f59d82ffSelric  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35f59d82ffSelric  * SUCH DAMAGE.
36f59d82ffSelric  */
37f59d82ffSelric 
38f59d82ffSelric #include "hdb_locl.h"
39f59d82ffSelric #include <assert.h>
40f59d82ffSelric 
41f59d82ffSelric typedef struct {
42f59d82ffSelric     char *path;
43f59d82ffSelric     krb5_keytab keytab;
44f59d82ffSelric } *hdb_keytab;
45f59d82ffSelric 
46f59d82ffSelric /*
47f59d82ffSelric  *
48f59d82ffSelric  */
49f59d82ffSelric 
50f59d82ffSelric static krb5_error_code
hkt_close(krb5_context context,HDB * db)51f59d82ffSelric hkt_close(krb5_context context, HDB *db)
52f59d82ffSelric {
53f59d82ffSelric     hdb_keytab k = (hdb_keytab)db->hdb_db;
54f59d82ffSelric     krb5_error_code ret;
55f59d82ffSelric 
56f59d82ffSelric     assert(k->keytab);
57f59d82ffSelric 
58f59d82ffSelric     ret = krb5_kt_close(context, k->keytab);
59f59d82ffSelric     k->keytab = NULL;
60f59d82ffSelric 
61f59d82ffSelric     return ret;
62f59d82ffSelric }
63f59d82ffSelric 
64f59d82ffSelric static krb5_error_code
hkt_destroy(krb5_context context,HDB * db)65f59d82ffSelric hkt_destroy(krb5_context context, HDB *db)
66f59d82ffSelric {
67f59d82ffSelric     hdb_keytab k = (hdb_keytab)db->hdb_db;
68f59d82ffSelric     krb5_error_code ret;
69f59d82ffSelric 
70f59d82ffSelric     ret = hdb_clear_master_key (context, db);
71f59d82ffSelric 
72f59d82ffSelric     free(k->path);
73f59d82ffSelric     free(k);
74f59d82ffSelric 
75f59d82ffSelric     free(db->hdb_name);
76f59d82ffSelric     free(db);
77f59d82ffSelric     return ret;
78f59d82ffSelric }
79f59d82ffSelric 
80f59d82ffSelric static krb5_error_code
hkt_lock(krb5_context context,HDB * db,int operation)81f59d82ffSelric hkt_lock(krb5_context context, HDB *db, int operation)
82f59d82ffSelric {
83f59d82ffSelric     return 0;
84f59d82ffSelric }
85f59d82ffSelric 
86f59d82ffSelric static krb5_error_code
hkt_unlock(krb5_context context,HDB * db)87f59d82ffSelric hkt_unlock(krb5_context context, HDB *db)
88f59d82ffSelric {
89f59d82ffSelric     return 0;
90f59d82ffSelric }
91f59d82ffSelric 
92f59d82ffSelric static krb5_error_code
hkt_firstkey(krb5_context context,HDB * db,unsigned flags,hdb_entry_ex * entry)93f59d82ffSelric hkt_firstkey(krb5_context context, HDB *db,
94f59d82ffSelric 	     unsigned flags, hdb_entry_ex *entry)
95f59d82ffSelric {
96f59d82ffSelric     return HDB_ERR_DB_INUSE;
97f59d82ffSelric }
98f59d82ffSelric 
99f59d82ffSelric static krb5_error_code
hkt_nextkey(krb5_context context,HDB * db,unsigned flags,hdb_entry_ex * entry)100f59d82ffSelric hkt_nextkey(krb5_context context, HDB * db, unsigned flags,
101f59d82ffSelric 	     hdb_entry_ex * entry)
102f59d82ffSelric {
103f59d82ffSelric     return HDB_ERR_DB_INUSE;
104f59d82ffSelric }
105f59d82ffSelric 
106f59d82ffSelric static krb5_error_code
hkt_open(krb5_context context,HDB * db,int flags,mode_t mode)107f59d82ffSelric hkt_open(krb5_context context, HDB * db, int flags, mode_t mode)
108f59d82ffSelric {
109f59d82ffSelric     hdb_keytab k = (hdb_keytab)db->hdb_db;
110f59d82ffSelric     krb5_error_code ret;
111f59d82ffSelric 
112f59d82ffSelric     assert(k->keytab == NULL);
113f59d82ffSelric 
114f59d82ffSelric     ret = krb5_kt_resolve(context, k->path, &k->keytab);
115f59d82ffSelric     if (ret)
116f59d82ffSelric 	return ret;
117f59d82ffSelric 
118f59d82ffSelric     return 0;
119f59d82ffSelric }
120f59d82ffSelric 
121f59d82ffSelric static krb5_error_code
hkt_fetch_kvno(krb5_context context,HDB * db,krb5_const_principal principal,unsigned flags,krb5_kvno kvno,hdb_entry_ex * entry)122f59d82ffSelric hkt_fetch_kvno(krb5_context context, HDB * db, krb5_const_principal principal,
123f59d82ffSelric 	       unsigned flags, krb5_kvno kvno, hdb_entry_ex * entry)
124f59d82ffSelric {
125f59d82ffSelric     hdb_keytab k = (hdb_keytab)db->hdb_db;
126f59d82ffSelric     krb5_error_code ret;
127f59d82ffSelric     krb5_keytab_entry ktentry;
128f59d82ffSelric 
129f59d82ffSelric     if (!(flags & HDB_F_KVNO_SPECIFIED)) {
130f59d82ffSelric 	    /* Preserve previous behaviour if no kvno specified */
131f59d82ffSelric 	    kvno = 0;
132f59d82ffSelric     }
133f59d82ffSelric 
134f59d82ffSelric     memset(&ktentry, 0, sizeof(ktentry));
135f59d82ffSelric 
136f59d82ffSelric     entry->entry.flags.server = 1;
137f59d82ffSelric     entry->entry.flags.forwardable = 1;
138f59d82ffSelric     entry->entry.flags.renewable = 1;
139f59d82ffSelric 
140f59d82ffSelric     /* Not recorded in the OD backend, make something up */
141f59d82ffSelric     ret = krb5_parse_name(context, "hdb/keytab@WELL-KNOWN:KEYTAB-BACKEND",
142f59d82ffSelric 			  &entry->entry.created_by.principal);
143f59d82ffSelric     if (ret)
144f59d82ffSelric 	goto out;
145f59d82ffSelric 
146f59d82ffSelric     /*
147f59d82ffSelric      * XXX really needs to try all enctypes and just not pick the
148f59d82ffSelric      * first one, even if that happens to be des3-cbc-sha1 (ie best
149f59d82ffSelric      * enctype) in the Apple case. A while loop over all known
150f59d82ffSelric      * enctypes should work.
151f59d82ffSelric      */
152f59d82ffSelric 
153f59d82ffSelric     ret = krb5_kt_get_entry(context, k->keytab, principal, kvno, 0, &ktentry);
154f59d82ffSelric     if (ret) {
155f59d82ffSelric 	ret = HDB_ERR_NOENTRY;
156f59d82ffSelric 	goto out;
157f59d82ffSelric     }
158f59d82ffSelric 
159f59d82ffSelric     ret = krb5_copy_principal(context, principal, &entry->entry.principal);
160f59d82ffSelric     if (ret)
161f59d82ffSelric 	goto out;
162f59d82ffSelric 
163f59d82ffSelric     ret = _hdb_keytab2hdb_entry(context, &ktentry, entry);
164f59d82ffSelric 
165f59d82ffSelric  out:
166f59d82ffSelric     if (ret) {
167f59d82ffSelric 	free_hdb_entry(&entry->entry);
168f59d82ffSelric 	memset(&entry->entry, 0, sizeof(entry->entry));
169f59d82ffSelric     }
170f59d82ffSelric     krb5_kt_free_entry(context, &ktentry);
171f59d82ffSelric 
172f59d82ffSelric     return ret;
173f59d82ffSelric }
174f59d82ffSelric 
175f59d82ffSelric static krb5_error_code
hkt_store(krb5_context context,HDB * db,unsigned flags,hdb_entry_ex * entry)176f59d82ffSelric hkt_store(krb5_context context, HDB * db, unsigned flags,
177f59d82ffSelric 	  hdb_entry_ex * entry)
178f59d82ffSelric {
179f59d82ffSelric     return HDB_ERR_DB_INUSE;
180f59d82ffSelric }
181f59d82ffSelric 
182f59d82ffSelric 
183f59d82ffSelric krb5_error_code
hdb_keytab_create(krb5_context context,HDB ** db,const char * arg)184f59d82ffSelric hdb_keytab_create(krb5_context context, HDB ** db, const char *arg)
185f59d82ffSelric {
186f59d82ffSelric     hdb_keytab k;
187f59d82ffSelric 
188f59d82ffSelric     *db = calloc(1, sizeof(**db));
189f59d82ffSelric     if (*db == NULL) {
190f59d82ffSelric 	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
191f59d82ffSelric 	return ENOMEM;
192f59d82ffSelric     }
193f59d82ffSelric     memset(*db, 0, sizeof(**db));
194f59d82ffSelric 
195f59d82ffSelric     k = calloc(1, sizeof(*k));
196f59d82ffSelric     if (k == NULL) {
197f59d82ffSelric 	free(*db);
198f59d82ffSelric 	*db = NULL;
199f59d82ffSelric 	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
200f59d82ffSelric 	return ENOMEM;
201f59d82ffSelric     }
202f59d82ffSelric 
203f59d82ffSelric     k->path = strdup(arg);
204f59d82ffSelric     if (k->path == NULL) {
205f59d82ffSelric 	free(k);
206f59d82ffSelric 	free(*db);
207f59d82ffSelric 	*db = NULL;
208f59d82ffSelric 	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
209f59d82ffSelric 	return ENOMEM;
210f59d82ffSelric     }
211f59d82ffSelric 
212f59d82ffSelric 
213f59d82ffSelric     (*db)->hdb_db = k;
214f59d82ffSelric 
215f59d82ffSelric     (*db)->hdb_master_key_set = 0;
216f59d82ffSelric     (*db)->hdb_openp = 0;
217f59d82ffSelric     (*db)->hdb_open = hkt_open;
218f59d82ffSelric     (*db)->hdb_close = hkt_close;
219f59d82ffSelric     (*db)->hdb_fetch_kvno = hkt_fetch_kvno;
220f59d82ffSelric     (*db)->hdb_store = hkt_store;
221f59d82ffSelric     (*db)->hdb_remove = NULL;
222f59d82ffSelric     (*db)->hdb_firstkey = hkt_firstkey;
223f59d82ffSelric     (*db)->hdb_nextkey = hkt_nextkey;
224f59d82ffSelric     (*db)->hdb_lock = hkt_lock;
225f59d82ffSelric     (*db)->hdb_unlock = hkt_unlock;
226f59d82ffSelric     (*db)->hdb_rename = NULL;
227f59d82ffSelric     (*db)->hdb__get = NULL;
228f59d82ffSelric     (*db)->hdb__put = NULL;
229f59d82ffSelric     (*db)->hdb__del = NULL;
230f59d82ffSelric     (*db)->hdb_destroy = hkt_destroy;
231f59d82ffSelric 
232f59d82ffSelric     return 0;
233f59d82ffSelric }
234