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 /* memory operations -------------------------------------------- */
39 krb5_keytab_entry
*entries
;
43 struct mkt_data
*next
;
46 /* this mutex protects mkt_head, ->refcount, and ->next
47 * content is not protected (name is static and need no protection)
49 static HEIMDAL_MUTEX mkt_mutex
= HEIMDAL_MUTEX_INITIALIZER
;
50 static struct mkt_data
*mkt_head
;
53 static krb5_error_code
54 mkt_resolve(krb5_context context
, const char *name
, krb5_keytab id
)
58 HEIMDAL_MUTEX_lock(&mkt_mutex
);
60 for (d
= mkt_head
; d
!= NULL
; d
= d
->next
)
61 if (strcmp(d
->name
, name
) == 0)
65 krb5_abortx(context
, "Double close on memory keytab, "
66 "refcount < 1 %d", d
->refcount
);
69 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
73 d
= calloc(1, sizeof(*d
));
75 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
76 krb5_set_error_message(context
, ENOMEM
,
77 N_("malloc: out of memory", ""));
80 d
->name
= strdup(name
);
81 if (d
->name
== NULL
) {
82 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
84 krb5_set_error_message(context
, ENOMEM
,
85 N_("malloc: out of memory", ""));
93 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
98 static krb5_error_code
99 mkt_close(krb5_context context
, krb5_keytab id
)
101 struct mkt_data
*d
= id
->data
, **dp
;
104 HEIMDAL_MUTEX_lock(&mkt_mutex
);
107 "krb5 internal error, memory keytab refcount < 1 on close");
109 if (--d
->refcount
> 0) {
110 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
113 for (dp
= &mkt_head
; *dp
!= NULL
; dp
= &(*dp
)->next
) {
119 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
122 for(i
= 0; i
< d
->num_entries
; i
++)
123 krb5_kt_free_entry(context
, &d
->entries
[i
]);
129 static krb5_error_code
130 mkt_get_name(krb5_context context
,
135 struct mkt_data
*d
= id
->data
;
136 strlcpy(name
, d
->name
, namesize
);
140 static krb5_error_code
141 mkt_start_seq_get(krb5_context context
,
150 static krb5_error_code
151 mkt_next_entry(krb5_context context
,
153 krb5_keytab_entry
*entry
,
156 struct mkt_data
*d
= id
->data
;
157 if(c
->fd
>= d
->num_entries
)
159 return krb5_kt_copy_entry_contents(context
, &d
->entries
[c
->fd
++], entry
);
162 static krb5_error_code
163 mkt_end_seq_get(krb5_context context
,
165 krb5_kt_cursor
*cursor
)
170 static krb5_error_code
171 mkt_add_entry(krb5_context context
,
173 krb5_keytab_entry
*entry
)
175 struct mkt_data
*d
= id
->data
;
176 krb5_keytab_entry
*tmp
;
177 tmp
= realloc(d
->entries
, (d
->num_entries
+ 1) * sizeof(*d
->entries
));
179 krb5_set_error_message(context
, ENOMEM
,
180 N_("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_message(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_message (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
= {