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(krb5_context context
, HDB
*db
, krb5_const_principal principal
,
103 unsigned flags
, hdb_entry_ex
*entry
)
105 krb5_principal enterprise_principal
= NULL
;
106 krb5_data key
, value
;
109 if (principal
->name
.name_type
== KRB5_NT_ENTERPRISE_PRINCIPAL
) {
110 if (principal
->name
.name_string
.len
!= 1) {
111 ret
= KRB5_PARSE_MALFORMED
;
112 krb5_set_error_message(context
, ret
, "malformed principal: "
113 "enterprise name with %d name components",
114 principal
->name
.name_string
.len
);
117 ret
= krb5_parse_name(context
, principal
->name
.name_string
.val
[0],
118 &enterprise_principal
);
121 principal
= enterprise_principal
;
124 hdb_principal2key(context
, principal
, &key
);
125 if (enterprise_principal
)
126 krb5_free_principal(context
, principal
);
127 code
= db
->hdb__get(context
, db
, key
, &value
);
128 krb5_data_free(&key
);
131 code
= hdb_value2entry(context
, &value
, &entry
->entry
);
132 if (code
== ASN1_BAD_ID
&& (flags
& HDB_F_CANON
) == 0) {
133 krb5_data_free(&value
);
134 return HDB_ERR_NOENTRY
;
135 } else if (code
== ASN1_BAD_ID
) {
136 hdb_entry_alias alias
;
138 code
= hdb_value2entry_alias(context
, &value
, &alias
);
140 krb5_data_free(&value
);
143 hdb_principal2key(context
, alias
.principal
, &key
);
144 krb5_data_free(&value
);
145 free_hdb_entry_alias(&alias
);
147 code
= db
->hdb__get(context
, db
, key
, &value
);
148 krb5_data_free(&key
);
151 code
= hdb_value2entry(context
, &value
, &entry
->entry
);
153 krb5_data_free(&value
);
157 krb5_data_free(&value
);
158 if (db
->hdb_master_key_set
&& (flags
& HDB_F_DECRYPT
)) {
159 code
= hdb_unseal_keys (context
, db
, &entry
->entry
);
161 hdb_free_entry(context
, entry
);
166 static krb5_error_code
167 hdb_remove_aliases(krb5_context context
, HDB
*db
, krb5_data
*key
)
169 const HDB_Ext_Aliases
*aliases
;
170 krb5_error_code code
;
175 code
= db
->hdb__get(context
, db
, *key
, &value
);
176 if (code
== HDB_ERR_NOENTRY
)
181 code
= hdb_value2entry(context
, &value
, &oldentry
);
182 krb5_data_free(&value
);
186 code
= hdb_entry_get_aliases(&oldentry
, &aliases
);
187 if (code
|| aliases
== NULL
) {
188 free_hdb_entry(&oldentry
);
191 for (i
= 0; i
< aliases
->aliases
.len
; i
++) {
194 hdb_principal2key(context
, &aliases
->aliases
.val
[i
], &akey
);
195 code
= db
->hdb__del(context
, db
, akey
);
196 krb5_data_free(&akey
);
198 free_hdb_entry(&oldentry
);
202 free_hdb_entry(&oldentry
);
206 static krb5_error_code
207 hdb_add_aliases(krb5_context context
, HDB
*db
,
208 unsigned flags
, hdb_entry_ex
*entry
)
210 const HDB_Ext_Aliases
*aliases
;
211 krb5_error_code code
;
212 krb5_data key
, value
;
215 code
= hdb_entry_get_aliases(&entry
->entry
, &aliases
);
216 if (code
|| aliases
== NULL
)
219 for (i
= 0; i
< aliases
->aliases
.len
; i
++) {
220 hdb_entry_alias entryalias
;
221 entryalias
.principal
= entry
->entry
.principal
;
223 hdb_principal2key(context
, &aliases
->aliases
.val
[i
], &key
);
224 code
= hdb_entry_alias2value(context
, &entryalias
, &value
);
226 krb5_data_free(&key
);
229 code
= db
->hdb__put(context
, db
, flags
, key
, value
);
230 krb5_data_free(&key
);
231 krb5_data_free(&value
);
238 static krb5_error_code
239 hdb_check_aliases(krb5_context context
, HDB
*db
, hdb_entry_ex
*entry
)
241 const HDB_Ext_Aliases
*aliases
;
244 /* check if new aliases already is used */
246 code
= hdb_entry_get_aliases(&entry
->entry
, &aliases
);
250 for (i
= 0; aliases
&& i
< aliases
->aliases
.len
; i
++) {
251 hdb_entry_alias alias
;
252 krb5_data akey
, value
;
254 hdb_principal2key(context
, &aliases
->aliases
.val
[i
], &akey
);
255 code
= db
->hdb__get(context
, db
, akey
, &value
);
256 krb5_data_free(&akey
);
257 if (code
== HDB_ERR_NOENTRY
)
262 code
= hdb_value2entry_alias(context
, &value
, &alias
);
263 krb5_data_free(&value
);
265 if (code
== ASN1_BAD_ID
)
266 return HDB_ERR_EXISTS
;
270 code
= krb5_principal_compare(context
, alias
.principal
,
271 entry
->entry
.principal
);
272 free_hdb_entry_alias(&alias
);
274 return HDB_ERR_EXISTS
;
280 _hdb_store(krb5_context context
, HDB
*db
, unsigned flags
, hdb_entry_ex
*entry
)
282 krb5_data key
, value
;
285 /* check if new aliases already is used */
286 code
= hdb_check_aliases(context
, db
, entry
);
290 if(entry
->entry
.generation
== NULL
) {
292 entry
->entry
.generation
= malloc(sizeof(*entry
->entry
.generation
));
293 if(entry
->entry
.generation
== NULL
) {
294 krb5_set_error_message(context
, ENOMEM
, "malloc: out of memory");
297 gettimeofday(&t
, NULL
);
298 entry
->entry
.generation
->time
= t
.tv_sec
;
299 entry
->entry
.generation
->usec
= t
.tv_usec
;
300 entry
->entry
.generation
->gen
= 0;
302 entry
->entry
.generation
->gen
++;
304 code
= hdb_seal_keys(context
, db
, &entry
->entry
);
308 hdb_principal2key(context
, entry
->entry
.principal
, &key
);
311 code
= hdb_remove_aliases(context
, db
, &key
);
313 krb5_data_free(&key
);
316 hdb_entry2value(context
, &entry
->entry
, &value
);
317 code
= db
->hdb__put(context
, db
, flags
& HDB_F_REPLACE
, key
, value
);
318 krb5_data_free(&value
);
319 krb5_data_free(&key
);
323 code
= hdb_add_aliases(context
, db
, flags
, entry
);
329 _hdb_remove(krb5_context context
, HDB
*db
, krb5_const_principal principal
)
334 hdb_principal2key(context
, principal
, &key
);
336 code
= hdb_remove_aliases(context
, db
, &key
);
338 krb5_data_free(&key
);
341 code
= db
->hdb__del(context
, db
, key
);
342 krb5_data_free(&key
);