2 * Copyright (c) 1997 - 2001 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
34 #include "krb5_locl.h"
36 __RCSID("$Heimdal: keytab_memory.c 16352 2005-12-05 18:39:46Z lha $"
39 /* memory operations -------------------------------------------- */
42 krb5_keytab_entry
*entries
;
46 struct mkt_data
*next
;
49 /* this mutex protects mkt_head, ->refcount, and ->next
50 * content is not protected (name is static and need no protection)
52 static HEIMDAL_MUTEX mkt_mutex
= HEIMDAL_MUTEX_INITIALIZER
;
53 static struct mkt_data
*mkt_head
;
56 static krb5_error_code
57 mkt_resolve(krb5_context context
, const char *name
, krb5_keytab id
)
61 HEIMDAL_MUTEX_lock(&mkt_mutex
);
63 for (d
= mkt_head
; d
!= NULL
; d
= d
->next
)
64 if (strcmp(d
->name
, name
) == 0)
68 krb5_abortx(context
, "Double close on memory keytab, "
69 "refcount < 1 %d", d
->refcount
);
72 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
76 d
= calloc(1, sizeof(*d
));
78 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
79 krb5_set_error_string (context
, "malloc: out of memory");
82 d
->name
= strdup(name
);
83 if (d
->name
== NULL
) {
84 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
86 krb5_set_error_string (context
, "malloc: out of memory");
94 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
99 static krb5_error_code
100 mkt_close(krb5_context context
, krb5_keytab id
)
102 struct mkt_data
*d
= id
->data
, **dp
;
105 HEIMDAL_MUTEX_lock(&mkt_mutex
);
108 "krb5 internal error, memory keytab refcount < 1 on close");
110 if (--d
->refcount
> 0) {
111 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
114 for (dp
= &mkt_head
; *dp
!= NULL
; dp
= &(*dp
)->next
) {
120 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
123 for(i
= 0; i
< d
->num_entries
; i
++)
124 krb5_kt_free_entry(context
, &d
->entries
[i
]);
130 static krb5_error_code
131 mkt_get_name(krb5_context context
,
136 struct mkt_data
*d
= id
->data
;
137 strlcpy(name
, d
->name
, namesize
);
141 static krb5_error_code
142 mkt_start_seq_get(krb5_context context
,
151 static krb5_error_code
152 mkt_next_entry(krb5_context context
,
154 krb5_keytab_entry
*entry
,
157 struct mkt_data
*d
= id
->data
;
158 if(c
->fd
>= d
->num_entries
)
160 return krb5_kt_copy_entry_contents(context
, &d
->entries
[c
->fd
++], entry
);
163 static krb5_error_code
164 mkt_end_seq_get(krb5_context context
,
166 krb5_kt_cursor
*cursor
)
171 static krb5_error_code
172 mkt_add_entry(krb5_context context
,
174 krb5_keytab_entry
*entry
)
176 struct mkt_data
*d
= id
->data
;
177 krb5_keytab_entry
*tmp
;
178 tmp
= realloc(d
->entries
, (d
->num_entries
+ 1) * sizeof(*d
->entries
));
180 krb5_set_error_string (context
, "malloc: out of memory");
184 return krb5_kt_copy_entry_contents(context
, entry
,
185 &d
->entries
[d
->num_entries
++]);
188 static krb5_error_code
189 mkt_remove_entry(krb5_context context
,
191 krb5_keytab_entry
*entry
)
193 struct mkt_data
*d
= id
->data
;
194 krb5_keytab_entry
*e
, *end
;
197 if (d
->num_entries
== 0) {
198 krb5_clear_error_string(context
);
199 return KRB5_KT_NOTFOUND
;
202 /* do this backwards to minimize copying */
203 for(end
= d
->entries
+ d
->num_entries
, e
= end
- 1; e
>= d
->entries
; e
--) {
204 if(krb5_kt_compare(context
, e
, entry
->principal
,
205 entry
->vno
, entry
->keyblock
.keytype
)) {
206 krb5_kt_free_entry(context
, e
);
207 memmove(e
, e
+ 1, (end
- e
- 1) * sizeof(*e
));
208 memset(end
- 1, 0, sizeof(*end
));
215 krb5_clear_error_string (context
);
216 return KRB5_KT_NOTFOUND
;
218 e
= realloc(d
->entries
, d
->num_entries
* sizeof(*d
->entries
));
219 if(e
!= NULL
|| d
->num_entries
== 0)
224 const krb5_kt_ops krb5_mkt_ops
= {