2 * Copyright (c) 1997-2002 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. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 hdb_principal2key(krb5_context context
, krb5_const_principal p
, krb5_data
*key
)
43 ret
= copy_Principal(p
, &new);
46 new.name
.name_type
= 0;
48 ASN1_MALLOC_ENCODE(Principal
, key
->data
, key
->length
, &new, &len
, ret
);
49 if (ret
== 0 && key
->length
!= len
)
50 krb5_abortx(context
, "internal asn.1 encoder error");
56 hdb_key2principal(krb5_context context
, krb5_data
*key
, krb5_principal p
)
58 return decode_Principal(key
->data
, key
->length
, p
, NULL
);
62 hdb_entry2value(krb5_context context
, const hdb_entry
*ent
, krb5_data
*value
)
67 ASN1_MALLOC_ENCODE(hdb_entry
, value
->data
, value
->length
, ent
, &len
, ret
);
68 if (ret
== 0 && value
->length
!= len
)
69 krb5_abortx(context
, "internal asn.1 encoder error");
74 hdb_value2entry(krb5_context context
, krb5_data
*value
, hdb_entry
*ent
)
76 return decode_hdb_entry(value
->data
, value
->length
, ent
, NULL
);
80 hdb_entry_alias2value(krb5_context context
,
81 const hdb_entry_alias
*alias
,
87 ASN1_MALLOC_ENCODE(hdb_entry_alias
, value
->data
, value
->length
,
89 if (ret
== 0 && value
->length
!= len
)
90 krb5_abortx(context
, "internal asn.1 encoder error");
95 hdb_value2entry_alias(krb5_context context
, krb5_data
*value
,
98 return decode_hdb_entry_alias(value
->data
, value
->length
, ent
, NULL
);
102 _hdb_fetch_kvno(krb5_context context
, HDB
*db
, krb5_const_principal principal
,
103 unsigned flags
, krb5_kvno kvno
, hdb_entry_ex
*entry
)
105 krb5_principal enterprise_principal
= NULL
;
106 krb5_data key
, value
;
110 if (principal
->name
.name_type
== KRB5_NT_ENTERPRISE_PRINCIPAL
) {
111 if (principal
->name
.name_string
.len
!= 1) {
112 ret
= KRB5_PARSE_MALFORMED
;
113 krb5_set_error_message(context
, ret
, "malformed principal: "
114 "enterprise name with %d name components",
115 principal
->name
.name_string
.len
);
118 ret
= krb5_parse_name(context
, principal
->name
.name_string
.val
[0],
119 &enterprise_principal
);
122 principal
= enterprise_principal
;
125 hdb_principal2key(context
, principal
, &key
);
126 if (enterprise_principal
)
127 krb5_free_principal(context
, enterprise_principal
);
128 code
= db
->hdb__get(context
, db
, key
, &value
);
129 krb5_data_free(&key
);
132 code
= hdb_value2entry(context
, &value
, &entry
->entry
);
133 if (code
== ASN1_BAD_ID
&& (flags
& HDB_F_CANON
) == 0) {
134 krb5_data_free(&value
);
135 return HDB_ERR_NOENTRY
;
136 } else if (code
== ASN1_BAD_ID
) {
137 hdb_entry_alias alias
;
139 code
= hdb_value2entry_alias(context
, &value
, &alias
);
141 krb5_data_free(&value
);
144 hdb_principal2key(context
, alias
.principal
, &key
);
145 krb5_data_free(&value
);
146 free_hdb_entry_alias(&alias
);
148 code
= db
->hdb__get(context
, db
, key
, &value
);
149 krb5_data_free(&key
);
152 code
= hdb_value2entry(context
, &value
, &entry
->entry
);
154 krb5_data_free(&value
);
158 krb5_data_free(&value
);
159 if (db
->hdb_master_key_set
&& (flags
& HDB_F_DECRYPT
)) {
160 code
= hdb_unseal_keys (context
, db
, &entry
->entry
);
162 hdb_free_entry(context
, entry
);
167 static krb5_error_code
168 hdb_remove_aliases(krb5_context context
, HDB
*db
, krb5_data
*key
)
170 const HDB_Ext_Aliases
*aliases
;
171 krb5_error_code code
;
176 code
= db
->hdb__get(context
, db
, *key
, &value
);
177 if (code
== HDB_ERR_NOENTRY
)
182 code
= hdb_value2entry(context
, &value
, &oldentry
);
183 krb5_data_free(&value
);
187 code
= hdb_entry_get_aliases(&oldentry
, &aliases
);
188 if (code
|| aliases
== NULL
) {
189 free_hdb_entry(&oldentry
);
192 for (i
= 0; i
< aliases
->aliases
.len
; i
++) {
195 hdb_principal2key(context
, &aliases
->aliases
.val
[i
], &akey
);
196 code
= db
->hdb__del(context
, db
, akey
);
197 krb5_data_free(&akey
);
199 free_hdb_entry(&oldentry
);
203 free_hdb_entry(&oldentry
);
207 static krb5_error_code
208 hdb_add_aliases(krb5_context context
, HDB
*db
,
209 unsigned flags
, hdb_entry_ex
*entry
)
211 const HDB_Ext_Aliases
*aliases
;
212 krb5_error_code code
;
213 krb5_data key
, value
;
216 code
= hdb_entry_get_aliases(&entry
->entry
, &aliases
);
217 if (code
|| aliases
== NULL
)
220 for (i
= 0; i
< aliases
->aliases
.len
; i
++) {
221 hdb_entry_alias entryalias
;
222 entryalias
.principal
= entry
->entry
.principal
;
224 hdb_principal2key(context
, &aliases
->aliases
.val
[i
], &key
);
225 code
= hdb_entry_alias2value(context
, &entryalias
, &value
);
227 krb5_data_free(&key
);
230 code
= db
->hdb__put(context
, db
, flags
, key
, value
);
231 krb5_data_free(&key
);
232 krb5_data_free(&value
);
239 static krb5_error_code
240 hdb_check_aliases(krb5_context context
, HDB
*db
, hdb_entry_ex
*entry
)
242 const HDB_Ext_Aliases
*aliases
;
246 /* check if new aliases already is used */
248 code
= hdb_entry_get_aliases(&entry
->entry
, &aliases
);
252 for (i
= 0; aliases
&& i
< aliases
->aliases
.len
; i
++) {
253 hdb_entry_alias alias
;
254 krb5_data akey
, value
;
256 hdb_principal2key(context
, &aliases
->aliases
.val
[i
], &akey
);
257 code
= db
->hdb__get(context
, db
, akey
, &value
);
258 krb5_data_free(&akey
);
259 if (code
== HDB_ERR_NOENTRY
)
264 code
= hdb_value2entry_alias(context
, &value
, &alias
);
265 krb5_data_free(&value
);
267 if (code
== ASN1_BAD_ID
)
268 return HDB_ERR_EXISTS
;
272 code
= krb5_principal_compare(context
, alias
.principal
,
273 entry
->entry
.principal
);
274 free_hdb_entry_alias(&alias
);
276 return HDB_ERR_EXISTS
;
282 _hdb_store(krb5_context context
, HDB
*db
, unsigned flags
, hdb_entry_ex
*entry
)
284 krb5_data key
, value
;
287 /* check if new aliases already is used */
288 code
= hdb_check_aliases(context
, db
, entry
);
292 if(entry
->entry
.generation
== NULL
) {
294 entry
->entry
.generation
= malloc(sizeof(*entry
->entry
.generation
));
295 if(entry
->entry
.generation
== NULL
) {
296 krb5_set_error_message(context
, ENOMEM
, "malloc: out of memory");
299 gettimeofday(&t
, NULL
);
300 entry
->entry
.generation
->time
= t
.tv_sec
;
301 entry
->entry
.generation
->usec
= t
.tv_usec
;
302 entry
->entry
.generation
->gen
= 0;
304 entry
->entry
.generation
->gen
++;
306 code
= hdb_seal_keys(context
, db
, &entry
->entry
);
310 hdb_principal2key(context
, entry
->entry
.principal
, &key
);
313 code
= hdb_remove_aliases(context
, db
, &key
);
315 krb5_data_free(&key
);
318 hdb_entry2value(context
, &entry
->entry
, &value
);
319 code
= db
->hdb__put(context
, db
, flags
& HDB_F_REPLACE
, key
, value
);
320 krb5_data_free(&value
);
321 krb5_data_free(&key
);
325 code
= hdb_add_aliases(context
, db
, flags
, entry
);
331 _hdb_remove(krb5_context context
, HDB
*db
, krb5_const_principal principal
)
336 hdb_principal2key(context
, principal
, &key
);
338 code
= hdb_remove_aliases(context
, db
, &key
);
340 krb5_data_free(&key
);
343 code
= db
->hdb__del(context
, db
, key
);
344 krb5_data_free(&key
);