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