1 /* $NetBSD: keytab_memory.c,v 1.1.1.1 2011/04/13 18:15:34 elric Exp $ */
4 * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include "krb5_locl.h"
38 /* memory operations -------------------------------------------- */
41 krb5_keytab_entry
*entries
;
45 struct mkt_data
*next
;
48 /* this mutex protects mkt_head, ->refcount, and ->next
49 * content is not protected (name is static and need no protection)
51 static HEIMDAL_MUTEX mkt_mutex
= HEIMDAL_MUTEX_INITIALIZER
;
52 static struct mkt_data
*mkt_head
;
55 static krb5_error_code KRB5_CALLCONV
56 mkt_resolve(krb5_context context
, const char *name
, krb5_keytab id
)
60 HEIMDAL_MUTEX_lock(&mkt_mutex
);
62 for (d
= mkt_head
; d
!= NULL
; d
= d
->next
)
63 if (strcmp(d
->name
, name
) == 0)
67 krb5_abortx(context
, "Double close on memory keytab, "
68 "refcount < 1 %d", d
->refcount
);
71 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
75 d
= calloc(1, sizeof(*d
));
77 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
78 krb5_set_error_message(context
, ENOMEM
,
79 N_("malloc: out of memory", ""));
82 d
->name
= strdup(name
);
83 if (d
->name
== NULL
) {
84 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
86 krb5_set_error_message(context
, ENOMEM
,
87 N_("malloc: out of memory", ""));
95 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
100 static krb5_error_code KRB5_CALLCONV
101 mkt_close(krb5_context context
, krb5_keytab id
)
103 struct mkt_data
*d
= id
->data
, **dp
;
106 HEIMDAL_MUTEX_lock(&mkt_mutex
);
109 "krb5 internal error, memory keytab refcount < 1 on close");
111 if (--d
->refcount
> 0) {
112 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
115 for (dp
= &mkt_head
; *dp
!= NULL
; dp
= &(*dp
)->next
) {
121 HEIMDAL_MUTEX_unlock(&mkt_mutex
);
124 for(i
= 0; i
< d
->num_entries
; i
++)
125 krb5_kt_free_entry(context
, &d
->entries
[i
]);
131 static krb5_error_code KRB5_CALLCONV
132 mkt_get_name(krb5_context context
,
137 struct mkt_data
*d
= id
->data
;
138 strlcpy(name
, d
->name
, namesize
);
142 static krb5_error_code KRB5_CALLCONV
143 mkt_start_seq_get(krb5_context context
,
152 static krb5_error_code KRB5_CALLCONV
153 mkt_next_entry(krb5_context context
,
155 krb5_keytab_entry
*entry
,
158 struct mkt_data
*d
= id
->data
;
159 if(c
->fd
>= d
->num_entries
)
161 return krb5_kt_copy_entry_contents(context
, &d
->entries
[c
->fd
++], entry
);
164 static krb5_error_code KRB5_CALLCONV
165 mkt_end_seq_get(krb5_context context
,
167 krb5_kt_cursor
*cursor
)
172 static krb5_error_code KRB5_CALLCONV
173 mkt_add_entry(krb5_context context
,
175 krb5_keytab_entry
*entry
)
177 struct mkt_data
*d
= id
->data
;
178 krb5_keytab_entry
*tmp
;
179 tmp
= realloc(d
->entries
, (d
->num_entries
+ 1) * sizeof(*d
->entries
));
181 krb5_set_error_message(context
, ENOMEM
,
182 N_("malloc: out of memory", ""));
186 return krb5_kt_copy_entry_contents(context
, entry
,
187 &d
->entries
[d
->num_entries
++]);
190 static krb5_error_code KRB5_CALLCONV
191 mkt_remove_entry(krb5_context context
,
193 krb5_keytab_entry
*entry
)
195 struct mkt_data
*d
= id
->data
;
196 krb5_keytab_entry
*e
, *end
;
199 if (d
->num_entries
== 0) {
200 krb5_clear_error_message(context
);
201 return KRB5_KT_NOTFOUND
;
204 /* do this backwards to minimize copying */
205 for(end
= d
->entries
+ d
->num_entries
, e
= end
- 1; e
>= d
->entries
; e
--) {
206 if(krb5_kt_compare(context
, e
, entry
->principal
,
207 entry
->vno
, entry
->keyblock
.keytype
)) {
208 krb5_kt_free_entry(context
, e
);
209 memmove(e
, e
+ 1, (end
- e
- 1) * sizeof(*e
));
210 memset(end
- 1, 0, sizeof(*end
));
217 krb5_clear_error_message (context
);
218 return KRB5_KT_NOTFOUND
;
220 e
= realloc(d
->entries
, d
->num_entries
* sizeof(*d
->entries
));
221 if(e
!= NULL
|| d
->num_entries
== 0)
226 const krb5_kt_ops krb5_mkt_ops
= {