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 KRB5_CALLCONV
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 return krb5_enomem(context
);
78 d
->name
= strdup(name
);
79 if (d
->name
== NULL
) {
80 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
82 return krb5_enomem(context
);
89 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
94 static krb5_error_code KRB5_CALLCONV
95 mkt_close(krb5_context context
, krb5_keytab id
)
97 struct mkt_data
*d
= id
->data
, **dp
;
100 HEIMDAL_MUTEX_lock(&mkt_mutex
);
103 "krb5 internal error, memory keytab refcount < 1 on close");
105 if (--d
->refcount
> 0) {
106 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
109 for (dp
= &mkt_head
; *dp
!= NULL
; dp
= &(*dp
)->next
) {
115 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
118 for(i
= 0; i
< d
->num_entries
; i
++)
119 krb5_kt_free_entry(context
, &d
->entries
[i
]);
125 static krb5_error_code KRB5_CALLCONV
126 mkt_get_name(krb5_context context
,
131 struct mkt_data
*d
= id
->data
;
132 strlcpy(name
, d
->name
, namesize
);
136 static krb5_error_code KRB5_CALLCONV
137 mkt_start_seq_get(krb5_context context
,
146 static krb5_error_code KRB5_CALLCONV
147 mkt_next_entry(krb5_context context
,
149 krb5_keytab_entry
*entry
,
152 struct mkt_data
*d
= id
->data
;
153 if(c
->fd
>= d
->num_entries
)
155 return krb5_kt_copy_entry_contents(context
, &d
->entries
[c
->fd
++], entry
);
158 static krb5_error_code KRB5_CALLCONV
159 mkt_end_seq_get(krb5_context context
,
161 krb5_kt_cursor
*cursor
)
166 static krb5_error_code KRB5_CALLCONV
167 mkt_add_entry(krb5_context context
,
169 krb5_keytab_entry
*entry
)
171 struct mkt_data
*d
= id
->data
;
172 krb5_keytab_entry
*tmp
;
173 tmp
= realloc(d
->entries
, (d
->num_entries
+ 1) * sizeof(*d
->entries
));
175 return krb5_enomem(context
);
177 return krb5_kt_copy_entry_contents(context
, entry
,
178 &d
->entries
[d
->num_entries
++]);
181 static krb5_error_code KRB5_CALLCONV
182 mkt_remove_entry(krb5_context context
,
184 krb5_keytab_entry
*entry
)
186 struct mkt_data
*d
= id
->data
;
187 krb5_keytab_entry
*e
, *end
;
190 if (d
->num_entries
== 0) {
191 krb5_clear_error_message(context
);
192 return KRB5_KT_NOTFOUND
;
195 /* do this backwards to minimize copying */
196 for(end
= d
->entries
+ d
->num_entries
, e
= end
- 1; e
>= d
->entries
; e
--) {
197 if(krb5_kt_compare(context
, e
, entry
->principal
,
198 entry
->vno
, entry
->keyblock
.keytype
)) {
199 krb5_kt_free_entry(context
, e
);
200 memmove(e
, e
+ 1, (end
- e
- 1) * sizeof(*e
));
201 memset(end
- 1, 0, sizeof(*end
));
208 krb5_clear_error_message (context
);
209 return KRB5_KT_NOTFOUND
;
211 e
= realloc(d
->entries
, d
->num_entries
* sizeof(*d
->entries
));
212 if(e
!= NULL
|| d
->num_entries
== 0)
217 const krb5_kt_ops krb5_mkt_ops
= {