1ed5d5720SPeter Avalos /*-
2ed5d5720SPeter Avalos * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru>
3ed5d5720SPeter Avalos * All rights reserved.
4ed5d5720SPeter Avalos *
5ed5d5720SPeter Avalos * Redistribution and use in source and binary forms, with or without
6ed5d5720SPeter Avalos * modification, are permitted provided that the following conditions
7ed5d5720SPeter Avalos * are met:
8ed5d5720SPeter Avalos * 1. Redistributions of source code must retain the above copyright
9ed5d5720SPeter Avalos * notice, this list of conditions and the following disclaimer.
10ed5d5720SPeter Avalos * 2. Redistributions in binary form must reproduce the above copyright
11ed5d5720SPeter Avalos * notice, this list of conditions and the following disclaimer in the
12ed5d5720SPeter Avalos * documentation and/or other materials provided with the distribution.
13ed5d5720SPeter Avalos *
14ed5d5720SPeter Avalos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15ed5d5720SPeter Avalos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16ed5d5720SPeter Avalos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17ed5d5720SPeter Avalos * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18ed5d5720SPeter Avalos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19ed5d5720SPeter Avalos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20ed5d5720SPeter Avalos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21ed5d5720SPeter Avalos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22ed5d5720SPeter Avalos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23ed5d5720SPeter Avalos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24ed5d5720SPeter Avalos * SUCH DAMAGE.
25ed5d5720SPeter Avalos *
26ed5d5720SPeter Avalos * $FreeBSD: src/lib/libc/net/nscache.c,v 1.2 2007/10/17 23:20:49 tmclaugh Exp $
27ed5d5720SPeter Avalos */
28ed5d5720SPeter Avalos
29ed5d5720SPeter Avalos #include "namespace.h"
30*a1ff66cbSSascha Wildner #define _NS_PRIVATE
31ed5d5720SPeter Avalos #include <nsswitch.h>
32ed5d5720SPeter Avalos #include <stdlib.h>
33ed5d5720SPeter Avalos #include <string.h>
34ed5d5720SPeter Avalos #include "un-namespace.h"
35ed5d5720SPeter Avalos #include "nscachedcli.h"
36ed5d5720SPeter Avalos #include "nscache.h"
37ed5d5720SPeter Avalos
38ed5d5720SPeter Avalos #define NSS_CACHE_KEY_INITIAL_SIZE (256)
39ed5d5720SPeter Avalos #define NSS_CACHE_KEY_SIZE_LIMIT (NSS_CACHE_KEY_INITIAL_SIZE << 4)
40ed5d5720SPeter Avalos
41ed5d5720SPeter Avalos #define NSS_CACHE_BUFFER_INITIAL_SIZE (1024)
42ed5d5720SPeter Avalos #define NSS_CACHE_BUFFER_SIZE_LIMIT (NSS_CACHE_BUFFER_INITIAL_SIZE << 8)
43ed5d5720SPeter Avalos
44ed5d5720SPeter Avalos #define CACHED_SOCKET_PATH "/var/run/nscd"
45ed5d5720SPeter Avalos
46ed5d5720SPeter Avalos int
__nss_cache_handler(void * retval __unused,void * mdata __unused,va_list ap __unused)476d7019e6SSascha Wildner __nss_cache_handler(void *retval __unused, void *mdata __unused,
486d7019e6SSascha Wildner va_list ap __unused)
49ed5d5720SPeter Avalos {
50ed5d5720SPeter Avalos return (NS_UNAVAIL);
51ed5d5720SPeter Avalos }
52ed5d5720SPeter Avalos
53ed5d5720SPeter Avalos int
__nss_common_cache_read(void * retval,void * mdata,va_list ap)54ed5d5720SPeter Avalos __nss_common_cache_read(void *retval, void *mdata, va_list ap)
55ed5d5720SPeter Avalos {
56ed5d5720SPeter Avalos struct cached_connection_params params;
57ed5d5720SPeter Avalos cached_connection connection;
58ed5d5720SPeter Avalos
59ed5d5720SPeter Avalos char *buffer;
60ed5d5720SPeter Avalos size_t buffer_size, size;
61ed5d5720SPeter Avalos
62ed5d5720SPeter Avalos nss_cache_info const *cache_info;
63ed5d5720SPeter Avalos nss_cache_data *cache_data;
64ed5d5720SPeter Avalos va_list ap_new;
65ed5d5720SPeter Avalos int res;
66ed5d5720SPeter Avalos
67ed5d5720SPeter Avalos cache_data = (nss_cache_data *)mdata;
68ed5d5720SPeter Avalos cache_info = cache_data->info;
69ed5d5720SPeter Avalos
70ed5d5720SPeter Avalos memset(¶ms, 0, sizeof(struct cached_connection_params));
71ed5d5720SPeter Avalos params.socket_path = CACHED_SOCKET_PATH;
72ed5d5720SPeter Avalos
73ed5d5720SPeter Avalos cache_data->key = (char *)malloc(NSS_CACHE_KEY_INITIAL_SIZE);
74ed5d5720SPeter Avalos memset(cache_data->key, 0, NSS_CACHE_KEY_INITIAL_SIZE);
75ed5d5720SPeter Avalos cache_data->key_size = NSS_CACHE_KEY_INITIAL_SIZE;
76ed5d5720SPeter Avalos va_copy(ap_new, ap);
77ed5d5720SPeter Avalos
78ed5d5720SPeter Avalos do {
79ed5d5720SPeter Avalos size = cache_data->key_size;
80ed5d5720SPeter Avalos res = cache_info->id_func(cache_data->key, &size, ap_new,
81ed5d5720SPeter Avalos cache_info->mdata);
82ed5d5720SPeter Avalos va_end(ap_new);
83ed5d5720SPeter Avalos if (res == NS_RETURN) {
84ed5d5720SPeter Avalos if (cache_data->key_size > NSS_CACHE_KEY_SIZE_LIMIT)
85ed5d5720SPeter Avalos break;
86ed5d5720SPeter Avalos
87ed5d5720SPeter Avalos cache_data->key_size <<= 1;
88ed5d5720SPeter Avalos cache_data->key = realloc(cache_data->key,
89ed5d5720SPeter Avalos cache_data->key_size);
90ed5d5720SPeter Avalos memset(cache_data->key, 0, cache_data->key_size);
91ed5d5720SPeter Avalos va_copy(ap_new, ap);
92ed5d5720SPeter Avalos }
93ed5d5720SPeter Avalos } while (res == NS_RETURN);
94ed5d5720SPeter Avalos
95ed5d5720SPeter Avalos if (res != NS_SUCCESS) {
96ed5d5720SPeter Avalos free(cache_data->key);
97ed5d5720SPeter Avalos cache_data->key = NULL;
98ed5d5720SPeter Avalos cache_data->key_size = 0;
99ed5d5720SPeter Avalos return (res);
100ed5d5720SPeter Avalos } else
101ed5d5720SPeter Avalos cache_data->key_size = size;
102ed5d5720SPeter Avalos
103ed5d5720SPeter Avalos buffer_size = NSS_CACHE_BUFFER_INITIAL_SIZE;
104ed5d5720SPeter Avalos buffer = (char *)malloc(NSS_CACHE_BUFFER_INITIAL_SIZE);
105ed5d5720SPeter Avalos memset(buffer, 0, NSS_CACHE_BUFFER_INITIAL_SIZE);
106ed5d5720SPeter Avalos
107ed5d5720SPeter Avalos do {
108ed5d5720SPeter Avalos connection = __open_cached_connection(¶ms);
109ed5d5720SPeter Avalos if (connection == NULL) {
110ed5d5720SPeter Avalos res = -1;
111ed5d5720SPeter Avalos break;
112ed5d5720SPeter Avalos }
113ed5d5720SPeter Avalos res = __cached_read(connection, cache_info->entry_name,
114ed5d5720SPeter Avalos cache_data->key, cache_data->key_size, buffer,
115ed5d5720SPeter Avalos &buffer_size);
116ed5d5720SPeter Avalos __close_cached_connection(connection);
117ed5d5720SPeter Avalos if (res == -2 && buffer_size < NSS_CACHE_BUFFER_SIZE_LIMIT) {
118ed5d5720SPeter Avalos buffer = (char *)realloc(buffer, buffer_size);
119ed5d5720SPeter Avalos memset(buffer, 0, buffer_size);
120ed5d5720SPeter Avalos }
121ed5d5720SPeter Avalos } while (res == -2);
122ed5d5720SPeter Avalos
123ed5d5720SPeter Avalos if (res == 0) {
124ed5d5720SPeter Avalos if (buffer_size == 0) {
125ed5d5720SPeter Avalos free(buffer);
126ed5d5720SPeter Avalos free(cache_data->key);
127ed5d5720SPeter Avalos cache_data->key = NULL;
128ed5d5720SPeter Avalos cache_data->key_size = 0;
129ed5d5720SPeter Avalos return (NS_RETURN);
130ed5d5720SPeter Avalos }
131ed5d5720SPeter Avalos
132ed5d5720SPeter Avalos va_copy(ap_new, ap);
133ed5d5720SPeter Avalos res = cache_info->unmarshal_func(buffer, buffer_size, retval,
134ed5d5720SPeter Avalos ap_new, cache_info->mdata);
135ed5d5720SPeter Avalos va_end(ap_new);
136ed5d5720SPeter Avalos
137ed5d5720SPeter Avalos if (res != NS_SUCCESS) {
138ed5d5720SPeter Avalos free(buffer);
139ed5d5720SPeter Avalos free(cache_data->key);
140ed5d5720SPeter Avalos cache_data->key = NULL;
141ed5d5720SPeter Avalos cache_data->key_size = 0;
142ed5d5720SPeter Avalos return (res);
143ed5d5720SPeter Avalos } else
144ed5d5720SPeter Avalos res = 0;
145ed5d5720SPeter Avalos }
146ed5d5720SPeter Avalos
147ed5d5720SPeter Avalos if (res == 0) {
148ed5d5720SPeter Avalos free(cache_data->key);
149ed5d5720SPeter Avalos cache_data->key = NULL;
150ed5d5720SPeter Avalos cache_data->key_size = 0;
151ed5d5720SPeter Avalos }
152ed5d5720SPeter Avalos
153ed5d5720SPeter Avalos free(buffer);
154ed5d5720SPeter Avalos return (res == 0 ? NS_SUCCESS : NS_NOTFOUND);
155ed5d5720SPeter Avalos }
156ed5d5720SPeter Avalos
157ed5d5720SPeter Avalos int
__nss_common_cache_write(void * retval,void * mdata,va_list ap)158ed5d5720SPeter Avalos __nss_common_cache_write(void *retval, void *mdata, va_list ap)
159ed5d5720SPeter Avalos {
160ed5d5720SPeter Avalos struct cached_connection_params params;
161ed5d5720SPeter Avalos cached_connection connection;
162ed5d5720SPeter Avalos
163ed5d5720SPeter Avalos char *buffer;
164ed5d5720SPeter Avalos size_t buffer_size;
165ed5d5720SPeter Avalos
166ed5d5720SPeter Avalos nss_cache_info const *cache_info;
167ed5d5720SPeter Avalos nss_cache_data *cache_data;
168ed5d5720SPeter Avalos va_list ap_new;
169ed5d5720SPeter Avalos int res;
170ed5d5720SPeter Avalos
171ed5d5720SPeter Avalos cache_data = (nss_cache_data *)mdata;
172ed5d5720SPeter Avalos cache_info = cache_data->info;
173ed5d5720SPeter Avalos
174ed5d5720SPeter Avalos if (cache_data->key == NULL)
175ed5d5720SPeter Avalos return (NS_UNAVAIL);
176ed5d5720SPeter Avalos
177ed5d5720SPeter Avalos memset(¶ms, 0, sizeof(struct cached_connection_params));
178ed5d5720SPeter Avalos params.socket_path = CACHED_SOCKET_PATH;
179ed5d5720SPeter Avalos
180ed5d5720SPeter Avalos connection = __open_cached_connection(¶ms);
181ed5d5720SPeter Avalos if (connection == NULL) {
182ed5d5720SPeter Avalos free(cache_data->key);
183ed5d5720SPeter Avalos return (NS_UNAVAIL);
184ed5d5720SPeter Avalos }
185ed5d5720SPeter Avalos
186ed5d5720SPeter Avalos buffer_size = NSS_CACHE_BUFFER_INITIAL_SIZE;
187ed5d5720SPeter Avalos buffer = (char *)malloc(NSS_CACHE_BUFFER_INITIAL_SIZE);
188ed5d5720SPeter Avalos memset(buffer, 0, NSS_CACHE_BUFFER_INITIAL_SIZE);
189ed5d5720SPeter Avalos
190ed5d5720SPeter Avalos do {
191ed5d5720SPeter Avalos size_t size;
192ed5d5720SPeter Avalos
193ed5d5720SPeter Avalos size = buffer_size;
194ed5d5720SPeter Avalos va_copy(ap_new, ap);
195ed5d5720SPeter Avalos res = cache_info->marshal_func(buffer, &size, retval, ap_new,
196ed5d5720SPeter Avalos cache_info->mdata);
197ed5d5720SPeter Avalos va_end(ap_new);
198ed5d5720SPeter Avalos
199ed5d5720SPeter Avalos if (res == NS_RETURN) {
200ed5d5720SPeter Avalos if (buffer_size > NSS_CACHE_BUFFER_SIZE_LIMIT)
201ed5d5720SPeter Avalos break;
202ed5d5720SPeter Avalos
203ed5d5720SPeter Avalos buffer_size <<= 1;
204ed5d5720SPeter Avalos buffer = (char *)realloc(buffer, buffer_size);
205ed5d5720SPeter Avalos memset(buffer, 0, buffer_size);
206ed5d5720SPeter Avalos }
207ed5d5720SPeter Avalos } while (res == NS_RETURN);
208ed5d5720SPeter Avalos
209ed5d5720SPeter Avalos if (res != NS_SUCCESS) {
210ed5d5720SPeter Avalos __close_cached_connection(connection);
211ed5d5720SPeter Avalos free(cache_data->key);
212ed5d5720SPeter Avalos free(buffer);
213ed5d5720SPeter Avalos return (res);
214ed5d5720SPeter Avalos }
215ed5d5720SPeter Avalos
216ed5d5720SPeter Avalos res = __cached_write(connection, cache_info->entry_name,
217ed5d5720SPeter Avalos cache_data->key, cache_data->key_size, buffer, buffer_size);
218ed5d5720SPeter Avalos __close_cached_connection(connection);
219ed5d5720SPeter Avalos
220ed5d5720SPeter Avalos free(cache_data->key);
221ed5d5720SPeter Avalos free(buffer);
222ed5d5720SPeter Avalos
223ed5d5720SPeter Avalos return (res == 0 ? NS_SUCCESS : NS_UNAVAIL);
224ed5d5720SPeter Avalos }
225ed5d5720SPeter Avalos
226ed5d5720SPeter Avalos int
__nss_common_cache_write_negative(void * mdata)227ed5d5720SPeter Avalos __nss_common_cache_write_negative(void *mdata)
228ed5d5720SPeter Avalos {
229ed5d5720SPeter Avalos struct cached_connection_params params;
230ed5d5720SPeter Avalos cached_connection connection;
231ed5d5720SPeter Avalos int res;
232ed5d5720SPeter Avalos
233ed5d5720SPeter Avalos nss_cache_info const *cache_info;
234ed5d5720SPeter Avalos nss_cache_data *cache_data;
235ed5d5720SPeter Avalos
236ed5d5720SPeter Avalos cache_data = (nss_cache_data *)mdata;
237ed5d5720SPeter Avalos cache_info = cache_data->info;
238ed5d5720SPeter Avalos
239ed5d5720SPeter Avalos if (cache_data->key == NULL)
240ed5d5720SPeter Avalos return (NS_UNAVAIL);
241ed5d5720SPeter Avalos
242ed5d5720SPeter Avalos memset(¶ms, 0, sizeof(struct cached_connection_params));
243ed5d5720SPeter Avalos params.socket_path = CACHED_SOCKET_PATH;
244ed5d5720SPeter Avalos
245ed5d5720SPeter Avalos connection = __open_cached_connection(¶ms);
246ed5d5720SPeter Avalos if (connection == NULL) {
247ed5d5720SPeter Avalos free(cache_data->key);
248ed5d5720SPeter Avalos return (NS_UNAVAIL);
249ed5d5720SPeter Avalos }
250ed5d5720SPeter Avalos
251ed5d5720SPeter Avalos res = __cached_write(connection, cache_info->entry_name,
252ed5d5720SPeter Avalos cache_data->key, cache_data->key_size, NULL, 0);
253ed5d5720SPeter Avalos __close_cached_connection(connection);
254ed5d5720SPeter Avalos
255ed5d5720SPeter Avalos free(cache_data->key);
256ed5d5720SPeter Avalos return (res == 0 ? NS_SUCCESS : NS_UNAVAIL);
257ed5d5720SPeter Avalos }
258ed5d5720SPeter Avalos
259ed5d5720SPeter Avalos int
__nss_mp_cache_read(void * retval,void * mdata,va_list ap)260ed5d5720SPeter Avalos __nss_mp_cache_read(void *retval, void *mdata, va_list ap)
261ed5d5720SPeter Avalos {
262ed5d5720SPeter Avalos struct cached_connection_params params;
263ed5d5720SPeter Avalos cached_mp_read_session rs;
264ed5d5720SPeter Avalos
265ed5d5720SPeter Avalos char *buffer;
266ed5d5720SPeter Avalos size_t buffer_size;
267ed5d5720SPeter Avalos
268ed5d5720SPeter Avalos nss_cache_info const *cache_info;
269ed5d5720SPeter Avalos nss_cache_data *cache_data;
270ed5d5720SPeter Avalos va_list ap_new;
271ed5d5720SPeter Avalos int res;
272ed5d5720SPeter Avalos
273ed5d5720SPeter Avalos cache_data = (nss_cache_data *)mdata;
274ed5d5720SPeter Avalos cache_info = cache_data->info;
275ed5d5720SPeter Avalos
276ed5d5720SPeter Avalos if (cache_info->get_mp_ws_func() != INVALID_CACHED_MP_WRITE_SESSION)
277ed5d5720SPeter Avalos return (NS_UNAVAIL);
278ed5d5720SPeter Avalos
279ed5d5720SPeter Avalos rs = cache_info->get_mp_rs_func();
280ed5d5720SPeter Avalos if (rs == INVALID_CACHED_MP_READ_SESSION) {
281ed5d5720SPeter Avalos memset(¶ms, 0, sizeof(struct cached_connection_params));
282ed5d5720SPeter Avalos params.socket_path = CACHED_SOCKET_PATH;
283ed5d5720SPeter Avalos
284ed5d5720SPeter Avalos rs = __open_cached_mp_read_session(¶ms,
285ed5d5720SPeter Avalos cache_info->entry_name);
286ed5d5720SPeter Avalos if (rs == INVALID_CACHED_MP_READ_SESSION)
287ed5d5720SPeter Avalos return (NS_UNAVAIL);
288ed5d5720SPeter Avalos
289ed5d5720SPeter Avalos cache_info->set_mp_rs_func(rs);
290ed5d5720SPeter Avalos }
291ed5d5720SPeter Avalos
292ed5d5720SPeter Avalos buffer_size = NSS_CACHE_BUFFER_INITIAL_SIZE;
293ed5d5720SPeter Avalos buffer = (char *)malloc(NSS_CACHE_BUFFER_INITIAL_SIZE);
294ed5d5720SPeter Avalos memset(buffer, 0, NSS_CACHE_BUFFER_INITIAL_SIZE);
295ed5d5720SPeter Avalos
296ed5d5720SPeter Avalos do {
297ed5d5720SPeter Avalos res = __cached_mp_read(rs, buffer, &buffer_size);
298ed5d5720SPeter Avalos if (res == -2 && buffer_size < NSS_CACHE_BUFFER_SIZE_LIMIT) {
299ed5d5720SPeter Avalos buffer = (char *)realloc(buffer, buffer_size);
300ed5d5720SPeter Avalos memset(buffer, 0, buffer_size);
301ed5d5720SPeter Avalos }
302ed5d5720SPeter Avalos } while (res == -2);
303ed5d5720SPeter Avalos
304ed5d5720SPeter Avalos if (res == 0) {
305ed5d5720SPeter Avalos va_copy(ap_new, ap);
306ed5d5720SPeter Avalos res = cache_info->unmarshal_func(buffer, buffer_size, retval,
307ed5d5720SPeter Avalos ap_new, cache_info->mdata);
308ed5d5720SPeter Avalos va_end(ap_new);
309ed5d5720SPeter Avalos
310ed5d5720SPeter Avalos if (res != NS_SUCCESS) {
311ed5d5720SPeter Avalos free(buffer);
312ed5d5720SPeter Avalos return (res);
313ed5d5720SPeter Avalos } else
314ed5d5720SPeter Avalos res = 0;
315ed5d5720SPeter Avalos } else {
316ed5d5720SPeter Avalos free(buffer);
317ed5d5720SPeter Avalos __close_cached_mp_read_session(rs);
318ed5d5720SPeter Avalos rs = INVALID_CACHED_MP_READ_SESSION;
319ed5d5720SPeter Avalos cache_info->set_mp_rs_func(rs);
320ed5d5720SPeter Avalos return (res == -1 ? NS_RETURN : NS_UNAVAIL);
321ed5d5720SPeter Avalos }
322ed5d5720SPeter Avalos
323ed5d5720SPeter Avalos free(buffer);
324ed5d5720SPeter Avalos return (res == 0 ? NS_SUCCESS : NS_NOTFOUND);
325ed5d5720SPeter Avalos }
326ed5d5720SPeter Avalos
327ed5d5720SPeter Avalos int
__nss_mp_cache_write(void * retval,void * mdata,va_list ap)328ed5d5720SPeter Avalos __nss_mp_cache_write(void *retval, void *mdata, va_list ap)
329ed5d5720SPeter Avalos {
330ed5d5720SPeter Avalos struct cached_connection_params params;
331ed5d5720SPeter Avalos cached_mp_write_session ws;
332ed5d5720SPeter Avalos
333ed5d5720SPeter Avalos char *buffer;
334ed5d5720SPeter Avalos size_t buffer_size;
335ed5d5720SPeter Avalos
336ed5d5720SPeter Avalos nss_cache_info const *cache_info;
337ed5d5720SPeter Avalos nss_cache_data *cache_data;
338ed5d5720SPeter Avalos va_list ap_new;
339ed5d5720SPeter Avalos int res;
340ed5d5720SPeter Avalos
341ed5d5720SPeter Avalos cache_data = (nss_cache_data *)mdata;
342ed5d5720SPeter Avalos cache_info = cache_data->info;
343ed5d5720SPeter Avalos
344ed5d5720SPeter Avalos ws = cache_info->get_mp_ws_func();
345ed5d5720SPeter Avalos if (ws == INVALID_CACHED_MP_WRITE_SESSION) {
346ed5d5720SPeter Avalos memset(¶ms, 0, sizeof(struct cached_connection_params));
347ed5d5720SPeter Avalos params.socket_path = CACHED_SOCKET_PATH;
348ed5d5720SPeter Avalos
349ed5d5720SPeter Avalos ws = __open_cached_mp_write_session(¶ms,
350ed5d5720SPeter Avalos cache_info->entry_name);
351ed5d5720SPeter Avalos if (ws == INVALID_CACHED_MP_WRITE_SESSION)
352ed5d5720SPeter Avalos return (NS_UNAVAIL);
353ed5d5720SPeter Avalos
354ed5d5720SPeter Avalos cache_info->set_mp_ws_func(ws);
355ed5d5720SPeter Avalos }
356ed5d5720SPeter Avalos
357ed5d5720SPeter Avalos buffer_size = NSS_CACHE_BUFFER_INITIAL_SIZE;
358ed5d5720SPeter Avalos buffer = (char *)malloc(NSS_CACHE_BUFFER_INITIAL_SIZE);
359ed5d5720SPeter Avalos memset(buffer, 0, NSS_CACHE_BUFFER_INITIAL_SIZE);
360ed5d5720SPeter Avalos
361ed5d5720SPeter Avalos do {
362ed5d5720SPeter Avalos size_t size;
363ed5d5720SPeter Avalos
364ed5d5720SPeter Avalos size = buffer_size;
365ed5d5720SPeter Avalos va_copy(ap_new, ap);
366ed5d5720SPeter Avalos res = cache_info->marshal_func(buffer, &size, retval, ap_new,
367ed5d5720SPeter Avalos cache_info->mdata);
368ed5d5720SPeter Avalos va_end(ap_new);
369ed5d5720SPeter Avalos
370ed5d5720SPeter Avalos if (res == NS_RETURN) {
371ed5d5720SPeter Avalos if (buffer_size > NSS_CACHE_BUFFER_SIZE_LIMIT)
372ed5d5720SPeter Avalos break;
373ed5d5720SPeter Avalos
374ed5d5720SPeter Avalos buffer_size <<= 1;
375ed5d5720SPeter Avalos buffer = (char *)realloc(buffer, buffer_size);
376ed5d5720SPeter Avalos memset(buffer, 0, buffer_size);
377ed5d5720SPeter Avalos }
378ed5d5720SPeter Avalos } while (res == NS_RETURN);
379ed5d5720SPeter Avalos
380ed5d5720SPeter Avalos if (res != NS_SUCCESS) {
381ed5d5720SPeter Avalos free(buffer);
382ed5d5720SPeter Avalos return (res);
383ed5d5720SPeter Avalos }
384ed5d5720SPeter Avalos
385ed5d5720SPeter Avalos res = __cached_mp_write(ws, buffer, buffer_size);
386ed5d5720SPeter Avalos
387ed5d5720SPeter Avalos free(buffer);
388ed5d5720SPeter Avalos return (res == 0 ? NS_SUCCESS : NS_UNAVAIL);
389ed5d5720SPeter Avalos }
390ed5d5720SPeter Avalos
391ed5d5720SPeter Avalos int
__nss_mp_cache_write_submit(void * retval __unused,void * mdata,va_list ap __unused)3926d7019e6SSascha Wildner __nss_mp_cache_write_submit(void *retval __unused, void *mdata,
3936d7019e6SSascha Wildner va_list ap __unused)
394ed5d5720SPeter Avalos {
395ed5d5720SPeter Avalos cached_mp_write_session ws;
396ed5d5720SPeter Avalos
397ed5d5720SPeter Avalos nss_cache_info const *cache_info;
398ed5d5720SPeter Avalos nss_cache_data *cache_data;
399ed5d5720SPeter Avalos
400ed5d5720SPeter Avalos cache_data = (nss_cache_data *)mdata;
401ed5d5720SPeter Avalos cache_info = cache_data->info;
402ed5d5720SPeter Avalos
403ed5d5720SPeter Avalos ws = cache_info->get_mp_ws_func();
404ed5d5720SPeter Avalos if (ws != INVALID_CACHED_MP_WRITE_SESSION) {
405ed5d5720SPeter Avalos __close_cached_mp_write_session(ws);
406ed5d5720SPeter Avalos ws = INVALID_CACHED_MP_WRITE_SESSION;
407ed5d5720SPeter Avalos cache_info->set_mp_ws_func(ws);
408ed5d5720SPeter Avalos }
409ed5d5720SPeter Avalos return (NS_UNAVAIL);
410ed5d5720SPeter Avalos }
411ed5d5720SPeter Avalos
412ed5d5720SPeter Avalos int
__nss_mp_cache_end(void * retval __unused,void * mdata,va_list ap __unused)4136d7019e6SSascha Wildner __nss_mp_cache_end(void *retval __unused, void *mdata, va_list ap __unused)
414ed5d5720SPeter Avalos {
415ed5d5720SPeter Avalos cached_mp_write_session ws;
416ed5d5720SPeter Avalos cached_mp_read_session rs;
417ed5d5720SPeter Avalos
418ed5d5720SPeter Avalos nss_cache_info const *cache_info;
419ed5d5720SPeter Avalos nss_cache_data *cache_data;
420ed5d5720SPeter Avalos
421ed5d5720SPeter Avalos cache_data = (nss_cache_data *)mdata;
422ed5d5720SPeter Avalos cache_info = cache_data->info;
423ed5d5720SPeter Avalos
424ed5d5720SPeter Avalos ws = cache_info->get_mp_ws_func();
425ed5d5720SPeter Avalos if (ws != INVALID_CACHED_MP_WRITE_SESSION) {
426ed5d5720SPeter Avalos __abandon_cached_mp_write_session(ws);
427ed5d5720SPeter Avalos ws = INVALID_CACHED_MP_WRITE_SESSION;
428ed5d5720SPeter Avalos cache_info->set_mp_ws_func(ws);
429ed5d5720SPeter Avalos }
430ed5d5720SPeter Avalos
431ed5d5720SPeter Avalos rs = cache_info->get_mp_rs_func();
432ed5d5720SPeter Avalos if (rs != INVALID_CACHED_MP_READ_SESSION) {
433ed5d5720SPeter Avalos __close_cached_mp_read_session(rs);
434ed5d5720SPeter Avalos rs = INVALID_CACHED_MP_READ_SESSION;
435ed5d5720SPeter Avalos cache_info->set_mp_rs_func(rs);
436ed5d5720SPeter Avalos }
437ed5d5720SPeter Avalos
438ed5d5720SPeter Avalos return (NS_UNAVAIL);
439ed5d5720SPeter Avalos }
440