106a99fe3SHajimu UMEMOTO /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3d915a14eSPedro F. Giffuni *
406a99fe3SHajimu UMEMOTO * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru>
506a99fe3SHajimu UMEMOTO * All rights reserved.
606a99fe3SHajimu UMEMOTO *
706a99fe3SHajimu UMEMOTO * Redistribution and use in source and binary forms, with or without
806a99fe3SHajimu UMEMOTO * modification, are permitted provided that the following conditions
906a99fe3SHajimu UMEMOTO * are met:
1006a99fe3SHajimu UMEMOTO * 1. Redistributions of source code must retain the above copyright
1106a99fe3SHajimu UMEMOTO * notice, this list of conditions and the following disclaimer.
1206a99fe3SHajimu UMEMOTO * 2. Redistributions in binary form must reproduce the above copyright
1306a99fe3SHajimu UMEMOTO * notice, this list of conditions and the following disclaimer in the
1406a99fe3SHajimu UMEMOTO * documentation and/or other materials provided with the distribution.
1506a99fe3SHajimu UMEMOTO *
1606a99fe3SHajimu UMEMOTO * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1706a99fe3SHajimu UMEMOTO * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1806a99fe3SHajimu UMEMOTO * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1906a99fe3SHajimu UMEMOTO * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2006a99fe3SHajimu UMEMOTO * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2106a99fe3SHajimu UMEMOTO * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2206a99fe3SHajimu UMEMOTO * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2306a99fe3SHajimu UMEMOTO * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2406a99fe3SHajimu UMEMOTO * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2506a99fe3SHajimu UMEMOTO * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2606a99fe3SHajimu UMEMOTO * SUCH DAMAGE.
2706a99fe3SHajimu UMEMOTO *
2806a99fe3SHajimu UMEMOTO */
2906a99fe3SHajimu UMEMOTO
3006a99fe3SHajimu UMEMOTO #include "namespace.h"
31ae274020SCraig Rodrigues #define _NS_PRIVATE
3206a99fe3SHajimu UMEMOTO #include <nsswitch.h>
3306a99fe3SHajimu UMEMOTO #include <stdlib.h>
3406a99fe3SHajimu UMEMOTO #include <string.h>
3506a99fe3SHajimu UMEMOTO #include "un-namespace.h"
3606a99fe3SHajimu UMEMOTO #include "nscachedcli.h"
3706a99fe3SHajimu UMEMOTO #include "nscache.h"
3806a99fe3SHajimu UMEMOTO
3906a99fe3SHajimu UMEMOTO #define NSS_CACHE_KEY_INITIAL_SIZE (256)
4006a99fe3SHajimu UMEMOTO #define NSS_CACHE_KEY_SIZE_LIMIT (NSS_CACHE_KEY_INITIAL_SIZE << 4)
4106a99fe3SHajimu UMEMOTO
4206a99fe3SHajimu UMEMOTO #define NSS_CACHE_BUFFER_INITIAL_SIZE (1024)
4306a99fe3SHajimu UMEMOTO #define NSS_CACHE_BUFFER_SIZE_LIMIT (NSS_CACHE_BUFFER_INITIAL_SIZE << 8)
4406a99fe3SHajimu UMEMOTO
4590855671STom McLaughlin #define CACHED_SOCKET_PATH "/var/run/nscd"
4606a99fe3SHajimu UMEMOTO
4706a99fe3SHajimu UMEMOTO int
__nss_cache_handler(void * retval,void * mdata,va_list ap)4806a99fe3SHajimu UMEMOTO __nss_cache_handler(void *retval, void *mdata, va_list ap)
4906a99fe3SHajimu UMEMOTO {
5006a99fe3SHajimu UMEMOTO return (NS_UNAVAIL);
5106a99fe3SHajimu UMEMOTO }
5206a99fe3SHajimu UMEMOTO
5306a99fe3SHajimu UMEMOTO int
__nss_common_cache_read(void * retval,void * mdata,va_list ap)5406a99fe3SHajimu UMEMOTO __nss_common_cache_read(void *retval, void *mdata, va_list ap)
5506a99fe3SHajimu UMEMOTO {
5606a99fe3SHajimu UMEMOTO struct cached_connection_params params;
5706a99fe3SHajimu UMEMOTO cached_connection connection;
5806a99fe3SHajimu UMEMOTO
5906a99fe3SHajimu UMEMOTO char *buffer;
6006a99fe3SHajimu UMEMOTO size_t buffer_size, size;
6106a99fe3SHajimu UMEMOTO
6206a99fe3SHajimu UMEMOTO nss_cache_info const *cache_info;
6306a99fe3SHajimu UMEMOTO nss_cache_data *cache_data;
6406a99fe3SHajimu UMEMOTO va_list ap_new;
6506a99fe3SHajimu UMEMOTO int res;
6606a99fe3SHajimu UMEMOTO
6706a99fe3SHajimu UMEMOTO cache_data = (nss_cache_data *)mdata;
6806a99fe3SHajimu UMEMOTO cache_info = cache_data->info;
6906a99fe3SHajimu UMEMOTO
7006a99fe3SHajimu UMEMOTO memset(¶ms, 0, sizeof(struct cached_connection_params));
7106a99fe3SHajimu UMEMOTO params.socket_path = CACHED_SOCKET_PATH;
7206a99fe3SHajimu UMEMOTO
7306a99fe3SHajimu UMEMOTO cache_data->key = (char *)malloc(NSS_CACHE_KEY_INITIAL_SIZE);
7406a99fe3SHajimu UMEMOTO memset(cache_data->key, 0, NSS_CACHE_KEY_INITIAL_SIZE);
7506a99fe3SHajimu UMEMOTO cache_data->key_size = NSS_CACHE_KEY_INITIAL_SIZE;
7606a99fe3SHajimu UMEMOTO va_copy(ap_new, ap);
7706a99fe3SHajimu UMEMOTO
7806a99fe3SHajimu UMEMOTO do {
7906a99fe3SHajimu UMEMOTO size = cache_data->key_size;
8006a99fe3SHajimu UMEMOTO res = cache_info->id_func(cache_data->key, &size, ap_new,
8106a99fe3SHajimu UMEMOTO cache_info->mdata);
8206a99fe3SHajimu UMEMOTO va_end(ap_new);
8306a99fe3SHajimu UMEMOTO if (res == NS_RETURN) {
8406a99fe3SHajimu UMEMOTO if (cache_data->key_size > NSS_CACHE_KEY_SIZE_LIMIT)
8506a99fe3SHajimu UMEMOTO break;
8606a99fe3SHajimu UMEMOTO
8706a99fe3SHajimu UMEMOTO cache_data->key_size <<= 1;
8806a99fe3SHajimu UMEMOTO cache_data->key = realloc(cache_data->key,
8906a99fe3SHajimu UMEMOTO cache_data->key_size);
9006a99fe3SHajimu UMEMOTO memset(cache_data->key, 0, cache_data->key_size);
9106a99fe3SHajimu UMEMOTO va_copy(ap_new, ap);
9206a99fe3SHajimu UMEMOTO }
9306a99fe3SHajimu UMEMOTO } while (res == NS_RETURN);
9406a99fe3SHajimu UMEMOTO
9506a99fe3SHajimu UMEMOTO if (res != NS_SUCCESS) {
9606a99fe3SHajimu UMEMOTO free(cache_data->key);
9706a99fe3SHajimu UMEMOTO cache_data->key = NULL;
9806a99fe3SHajimu UMEMOTO cache_data->key_size = 0;
9906a99fe3SHajimu UMEMOTO return (res);
10006a99fe3SHajimu UMEMOTO } else
10106a99fe3SHajimu UMEMOTO cache_data->key_size = size;
10206a99fe3SHajimu UMEMOTO
10306a99fe3SHajimu UMEMOTO buffer_size = NSS_CACHE_BUFFER_INITIAL_SIZE;
10406a99fe3SHajimu UMEMOTO buffer = (char *)malloc(NSS_CACHE_BUFFER_INITIAL_SIZE);
10506a99fe3SHajimu UMEMOTO memset(buffer, 0, NSS_CACHE_BUFFER_INITIAL_SIZE);
10606a99fe3SHajimu UMEMOTO
10706a99fe3SHajimu UMEMOTO do {
10806a99fe3SHajimu UMEMOTO connection = __open_cached_connection(¶ms);
10906a99fe3SHajimu UMEMOTO if (connection == NULL) {
11006a99fe3SHajimu UMEMOTO res = -1;
11106a99fe3SHajimu UMEMOTO break;
11206a99fe3SHajimu UMEMOTO }
11306a99fe3SHajimu UMEMOTO res = __cached_read(connection, cache_info->entry_name,
11406a99fe3SHajimu UMEMOTO cache_data->key, cache_data->key_size, buffer,
11506a99fe3SHajimu UMEMOTO &buffer_size);
11606a99fe3SHajimu UMEMOTO __close_cached_connection(connection);
11706a99fe3SHajimu UMEMOTO if (res == -2 && buffer_size < NSS_CACHE_BUFFER_SIZE_LIMIT) {
11806a99fe3SHajimu UMEMOTO buffer = (char *)realloc(buffer, buffer_size);
11906a99fe3SHajimu UMEMOTO memset(buffer, 0, buffer_size);
12006a99fe3SHajimu UMEMOTO }
12106a99fe3SHajimu UMEMOTO } while (res == -2);
12206a99fe3SHajimu UMEMOTO
12306a99fe3SHajimu UMEMOTO if (res == 0) {
12406a99fe3SHajimu UMEMOTO if (buffer_size == 0) {
12506a99fe3SHajimu UMEMOTO free(buffer);
12606a99fe3SHajimu UMEMOTO free(cache_data->key);
12706a99fe3SHajimu UMEMOTO cache_data->key = NULL;
12806a99fe3SHajimu UMEMOTO cache_data->key_size = 0;
12906a99fe3SHajimu UMEMOTO return (NS_RETURN);
13006a99fe3SHajimu UMEMOTO }
13106a99fe3SHajimu UMEMOTO
13206a99fe3SHajimu UMEMOTO va_copy(ap_new, ap);
13306a99fe3SHajimu UMEMOTO res = cache_info->unmarshal_func(buffer, buffer_size, retval,
13406a99fe3SHajimu UMEMOTO ap_new, cache_info->mdata);
13506a99fe3SHajimu UMEMOTO va_end(ap_new);
13606a99fe3SHajimu UMEMOTO
13706a99fe3SHajimu UMEMOTO if (res != NS_SUCCESS) {
13806a99fe3SHajimu UMEMOTO free(buffer);
13906a99fe3SHajimu UMEMOTO free(cache_data->key);
14006a99fe3SHajimu UMEMOTO cache_data->key = NULL;
14106a99fe3SHajimu UMEMOTO cache_data->key_size = 0;
14206a99fe3SHajimu UMEMOTO return (res);
14306a99fe3SHajimu UMEMOTO } else
14406a99fe3SHajimu UMEMOTO res = 0;
14506a99fe3SHajimu UMEMOTO }
14606a99fe3SHajimu UMEMOTO
14706a99fe3SHajimu UMEMOTO if (res == 0) {
14806a99fe3SHajimu UMEMOTO free(cache_data->key);
14906a99fe3SHajimu UMEMOTO cache_data->key = NULL;
15006a99fe3SHajimu UMEMOTO cache_data->key_size = 0;
15106a99fe3SHajimu UMEMOTO }
15206a99fe3SHajimu UMEMOTO
15306a99fe3SHajimu UMEMOTO free(buffer);
15406a99fe3SHajimu UMEMOTO return (res == 0 ? NS_SUCCESS : NS_NOTFOUND);
15506a99fe3SHajimu UMEMOTO }
15606a99fe3SHajimu UMEMOTO
15706a99fe3SHajimu UMEMOTO int
__nss_common_cache_write(void * retval,void * mdata,va_list ap)15806a99fe3SHajimu UMEMOTO __nss_common_cache_write(void *retval, void *mdata, va_list ap)
15906a99fe3SHajimu UMEMOTO {
16006a99fe3SHajimu UMEMOTO struct cached_connection_params params;
16106a99fe3SHajimu UMEMOTO cached_connection connection;
16206a99fe3SHajimu UMEMOTO
16306a99fe3SHajimu UMEMOTO char *buffer;
16406a99fe3SHajimu UMEMOTO size_t buffer_size;
16506a99fe3SHajimu UMEMOTO
16606a99fe3SHajimu UMEMOTO nss_cache_info const *cache_info;
16706a99fe3SHajimu UMEMOTO nss_cache_data *cache_data;
16806a99fe3SHajimu UMEMOTO va_list ap_new;
16906a99fe3SHajimu UMEMOTO int res;
17006a99fe3SHajimu UMEMOTO
17106a99fe3SHajimu UMEMOTO cache_data = (nss_cache_data *)mdata;
17206a99fe3SHajimu UMEMOTO cache_info = cache_data->info;
17306a99fe3SHajimu UMEMOTO
17406a99fe3SHajimu UMEMOTO if (cache_data->key == NULL)
17506a99fe3SHajimu UMEMOTO return (NS_UNAVAIL);
17606a99fe3SHajimu UMEMOTO
17706a99fe3SHajimu UMEMOTO memset(¶ms, 0, sizeof(struct cached_connection_params));
17806a99fe3SHajimu UMEMOTO params.socket_path = CACHED_SOCKET_PATH;
17906a99fe3SHajimu UMEMOTO
18006a99fe3SHajimu UMEMOTO connection = __open_cached_connection(¶ms);
18106a99fe3SHajimu UMEMOTO if (connection == NULL) {
18206a99fe3SHajimu UMEMOTO free(cache_data->key);
18306a99fe3SHajimu UMEMOTO return (NS_UNAVAIL);
18406a99fe3SHajimu UMEMOTO }
18506a99fe3SHajimu UMEMOTO
18606a99fe3SHajimu UMEMOTO buffer_size = NSS_CACHE_BUFFER_INITIAL_SIZE;
18706a99fe3SHajimu UMEMOTO buffer = (char *)malloc(NSS_CACHE_BUFFER_INITIAL_SIZE);
18806a99fe3SHajimu UMEMOTO memset(buffer, 0, NSS_CACHE_BUFFER_INITIAL_SIZE);
18906a99fe3SHajimu UMEMOTO
19006a99fe3SHajimu UMEMOTO do {
19106a99fe3SHajimu UMEMOTO size_t size;
19206a99fe3SHajimu UMEMOTO
19306a99fe3SHajimu UMEMOTO size = buffer_size;
19406a99fe3SHajimu UMEMOTO va_copy(ap_new, ap);
19506a99fe3SHajimu UMEMOTO res = cache_info->marshal_func(buffer, &size, retval, ap_new,
19606a99fe3SHajimu UMEMOTO cache_info->mdata);
19706a99fe3SHajimu UMEMOTO va_end(ap_new);
19806a99fe3SHajimu UMEMOTO
19906a99fe3SHajimu UMEMOTO if (res == NS_RETURN) {
20006a99fe3SHajimu UMEMOTO if (buffer_size > NSS_CACHE_BUFFER_SIZE_LIMIT)
20106a99fe3SHajimu UMEMOTO break;
20206a99fe3SHajimu UMEMOTO
20306a99fe3SHajimu UMEMOTO buffer_size <<= 1;
20406a99fe3SHajimu UMEMOTO buffer = (char *)realloc(buffer, buffer_size);
20506a99fe3SHajimu UMEMOTO memset(buffer, 0, buffer_size);
20606a99fe3SHajimu UMEMOTO }
20706a99fe3SHajimu UMEMOTO } while (res == NS_RETURN);
20806a99fe3SHajimu UMEMOTO
20906a99fe3SHajimu UMEMOTO if (res != NS_SUCCESS) {
21006a99fe3SHajimu UMEMOTO __close_cached_connection(connection);
21106a99fe3SHajimu UMEMOTO free(cache_data->key);
21206a99fe3SHajimu UMEMOTO free(buffer);
21306a99fe3SHajimu UMEMOTO return (res);
21406a99fe3SHajimu UMEMOTO }
21506a99fe3SHajimu UMEMOTO
21606a99fe3SHajimu UMEMOTO res = __cached_write(connection, cache_info->entry_name,
21706a99fe3SHajimu UMEMOTO cache_data->key, cache_data->key_size, buffer, buffer_size);
21806a99fe3SHajimu UMEMOTO __close_cached_connection(connection);
21906a99fe3SHajimu UMEMOTO
22006a99fe3SHajimu UMEMOTO free(cache_data->key);
22106a99fe3SHajimu UMEMOTO free(buffer);
22206a99fe3SHajimu UMEMOTO
22306a99fe3SHajimu UMEMOTO return (res == 0 ? NS_SUCCESS : NS_UNAVAIL);
22406a99fe3SHajimu UMEMOTO }
22506a99fe3SHajimu UMEMOTO
22606a99fe3SHajimu UMEMOTO int
__nss_common_cache_write_negative(void * mdata)22706a99fe3SHajimu UMEMOTO __nss_common_cache_write_negative(void *mdata)
22806a99fe3SHajimu UMEMOTO {
22906a99fe3SHajimu UMEMOTO struct cached_connection_params params;
23006a99fe3SHajimu UMEMOTO cached_connection connection;
23106a99fe3SHajimu UMEMOTO int res;
23206a99fe3SHajimu UMEMOTO
23306a99fe3SHajimu UMEMOTO nss_cache_info const *cache_info;
23406a99fe3SHajimu UMEMOTO nss_cache_data *cache_data;
23506a99fe3SHajimu UMEMOTO
23606a99fe3SHajimu UMEMOTO cache_data = (nss_cache_data *)mdata;
23706a99fe3SHajimu UMEMOTO cache_info = cache_data->info;
23806a99fe3SHajimu UMEMOTO
23906a99fe3SHajimu UMEMOTO if (cache_data->key == NULL)
24006a99fe3SHajimu UMEMOTO return (NS_UNAVAIL);
24106a99fe3SHajimu UMEMOTO
24206a99fe3SHajimu UMEMOTO memset(¶ms, 0, sizeof(struct cached_connection_params));
24306a99fe3SHajimu UMEMOTO params.socket_path = CACHED_SOCKET_PATH;
24406a99fe3SHajimu UMEMOTO
24506a99fe3SHajimu UMEMOTO connection = __open_cached_connection(¶ms);
24606a99fe3SHajimu UMEMOTO if (connection == NULL) {
24706a99fe3SHajimu UMEMOTO free(cache_data->key);
24806a99fe3SHajimu UMEMOTO return (NS_UNAVAIL);
24906a99fe3SHajimu UMEMOTO }
25006a99fe3SHajimu UMEMOTO
25106a99fe3SHajimu UMEMOTO res = __cached_write(connection, cache_info->entry_name,
25206a99fe3SHajimu UMEMOTO cache_data->key, cache_data->key_size, NULL, 0);
25306a99fe3SHajimu UMEMOTO __close_cached_connection(connection);
25406a99fe3SHajimu UMEMOTO
25506a99fe3SHajimu UMEMOTO free(cache_data->key);
25606a99fe3SHajimu UMEMOTO return (res == 0 ? NS_SUCCESS : NS_UNAVAIL);
25706a99fe3SHajimu UMEMOTO }
25806a99fe3SHajimu UMEMOTO
25906a99fe3SHajimu UMEMOTO int
__nss_mp_cache_read(void * retval,void * mdata,va_list ap)26006a99fe3SHajimu UMEMOTO __nss_mp_cache_read(void *retval, void *mdata, va_list ap)
26106a99fe3SHajimu UMEMOTO {
26206a99fe3SHajimu UMEMOTO struct cached_connection_params params;
26306a99fe3SHajimu UMEMOTO cached_mp_read_session rs;
26406a99fe3SHajimu UMEMOTO
26506a99fe3SHajimu UMEMOTO char *buffer;
26606a99fe3SHajimu UMEMOTO size_t buffer_size;
26706a99fe3SHajimu UMEMOTO
26806a99fe3SHajimu UMEMOTO nss_cache_info const *cache_info;
26906a99fe3SHajimu UMEMOTO nss_cache_data *cache_data;
27006a99fe3SHajimu UMEMOTO va_list ap_new;
27106a99fe3SHajimu UMEMOTO int res;
27206a99fe3SHajimu UMEMOTO
27306a99fe3SHajimu UMEMOTO cache_data = (nss_cache_data *)mdata;
27406a99fe3SHajimu UMEMOTO cache_info = cache_data->info;
27506a99fe3SHajimu UMEMOTO
27606a99fe3SHajimu UMEMOTO if (cache_info->get_mp_ws_func() != INVALID_CACHED_MP_WRITE_SESSION)
27706a99fe3SHajimu UMEMOTO return (NS_UNAVAIL);
27806a99fe3SHajimu UMEMOTO
27906a99fe3SHajimu UMEMOTO rs = cache_info->get_mp_rs_func();
28006a99fe3SHajimu UMEMOTO if (rs == INVALID_CACHED_MP_READ_SESSION) {
28106a99fe3SHajimu UMEMOTO memset(¶ms, 0, sizeof(struct cached_connection_params));
28206a99fe3SHajimu UMEMOTO params.socket_path = CACHED_SOCKET_PATH;
28306a99fe3SHajimu UMEMOTO
28406a99fe3SHajimu UMEMOTO rs = __open_cached_mp_read_session(¶ms,
28506a99fe3SHajimu UMEMOTO cache_info->entry_name);
28606a99fe3SHajimu UMEMOTO if (rs == INVALID_CACHED_MP_READ_SESSION)
28706a99fe3SHajimu UMEMOTO return (NS_UNAVAIL);
28806a99fe3SHajimu UMEMOTO
28906a99fe3SHajimu UMEMOTO cache_info->set_mp_rs_func(rs);
29006a99fe3SHajimu UMEMOTO }
29106a99fe3SHajimu UMEMOTO
29206a99fe3SHajimu UMEMOTO buffer_size = NSS_CACHE_BUFFER_INITIAL_SIZE;
29306a99fe3SHajimu UMEMOTO buffer = (char *)malloc(NSS_CACHE_BUFFER_INITIAL_SIZE);
29406a99fe3SHajimu UMEMOTO memset(buffer, 0, NSS_CACHE_BUFFER_INITIAL_SIZE);
29506a99fe3SHajimu UMEMOTO
29606a99fe3SHajimu UMEMOTO do {
29706a99fe3SHajimu UMEMOTO res = __cached_mp_read(rs, buffer, &buffer_size);
29806a99fe3SHajimu UMEMOTO if (res == -2 && buffer_size < NSS_CACHE_BUFFER_SIZE_LIMIT) {
29906a99fe3SHajimu UMEMOTO buffer = (char *)realloc(buffer, buffer_size);
30006a99fe3SHajimu UMEMOTO memset(buffer, 0, buffer_size);
30106a99fe3SHajimu UMEMOTO }
30206a99fe3SHajimu UMEMOTO } while (res == -2);
30306a99fe3SHajimu UMEMOTO
30406a99fe3SHajimu UMEMOTO if (res == 0) {
30506a99fe3SHajimu UMEMOTO va_copy(ap_new, ap);
30606a99fe3SHajimu UMEMOTO res = cache_info->unmarshal_func(buffer, buffer_size, retval,
30706a99fe3SHajimu UMEMOTO ap_new, cache_info->mdata);
30806a99fe3SHajimu UMEMOTO va_end(ap_new);
30906a99fe3SHajimu UMEMOTO
31006a99fe3SHajimu UMEMOTO if (res != NS_SUCCESS) {
31106a99fe3SHajimu UMEMOTO free(buffer);
31206a99fe3SHajimu UMEMOTO return (res);
31306a99fe3SHajimu UMEMOTO } else
31406a99fe3SHajimu UMEMOTO res = 0;
31506a99fe3SHajimu UMEMOTO } else {
31606a99fe3SHajimu UMEMOTO free(buffer);
31706a99fe3SHajimu UMEMOTO __close_cached_mp_read_session(rs);
31806a99fe3SHajimu UMEMOTO rs = INVALID_CACHED_MP_READ_SESSION;
31906a99fe3SHajimu UMEMOTO cache_info->set_mp_rs_func(rs);
32006a99fe3SHajimu UMEMOTO return (res == -1 ? NS_RETURN : NS_UNAVAIL);
32106a99fe3SHajimu UMEMOTO }
32206a99fe3SHajimu UMEMOTO
32306a99fe3SHajimu UMEMOTO free(buffer);
32406a99fe3SHajimu UMEMOTO return (res == 0 ? NS_SUCCESS : NS_NOTFOUND);
32506a99fe3SHajimu UMEMOTO }
32606a99fe3SHajimu UMEMOTO
32706a99fe3SHajimu UMEMOTO int
__nss_mp_cache_write(void * retval,void * mdata,va_list ap)32806a99fe3SHajimu UMEMOTO __nss_mp_cache_write(void *retval, void *mdata, va_list ap)
32906a99fe3SHajimu UMEMOTO {
33006a99fe3SHajimu UMEMOTO struct cached_connection_params params;
33106a99fe3SHajimu UMEMOTO cached_mp_write_session ws;
33206a99fe3SHajimu UMEMOTO
33306a99fe3SHajimu UMEMOTO char *buffer;
33406a99fe3SHajimu UMEMOTO size_t buffer_size;
33506a99fe3SHajimu UMEMOTO
33606a99fe3SHajimu UMEMOTO nss_cache_info const *cache_info;
33706a99fe3SHajimu UMEMOTO nss_cache_data *cache_data;
33806a99fe3SHajimu UMEMOTO va_list ap_new;
33906a99fe3SHajimu UMEMOTO int res;
34006a99fe3SHajimu UMEMOTO
34106a99fe3SHajimu UMEMOTO cache_data = (nss_cache_data *)mdata;
34206a99fe3SHajimu UMEMOTO cache_info = cache_data->info;
34306a99fe3SHajimu UMEMOTO
34406a99fe3SHajimu UMEMOTO ws = cache_info->get_mp_ws_func();
34506a99fe3SHajimu UMEMOTO if (ws == INVALID_CACHED_MP_WRITE_SESSION) {
34606a99fe3SHajimu UMEMOTO memset(¶ms, 0, sizeof(struct cached_connection_params));
34706a99fe3SHajimu UMEMOTO params.socket_path = CACHED_SOCKET_PATH;
34806a99fe3SHajimu UMEMOTO
34906a99fe3SHajimu UMEMOTO ws = __open_cached_mp_write_session(¶ms,
35006a99fe3SHajimu UMEMOTO cache_info->entry_name);
35106a99fe3SHajimu UMEMOTO if (ws == INVALID_CACHED_MP_WRITE_SESSION)
35206a99fe3SHajimu UMEMOTO return (NS_UNAVAIL);
35306a99fe3SHajimu UMEMOTO
35406a99fe3SHajimu UMEMOTO cache_info->set_mp_ws_func(ws);
35506a99fe3SHajimu UMEMOTO }
35606a99fe3SHajimu UMEMOTO
35706a99fe3SHajimu UMEMOTO buffer_size = NSS_CACHE_BUFFER_INITIAL_SIZE;
35806a99fe3SHajimu UMEMOTO buffer = (char *)malloc(NSS_CACHE_BUFFER_INITIAL_SIZE);
35906a99fe3SHajimu UMEMOTO memset(buffer, 0, NSS_CACHE_BUFFER_INITIAL_SIZE);
36006a99fe3SHajimu UMEMOTO
36106a99fe3SHajimu UMEMOTO do {
36206a99fe3SHajimu UMEMOTO size_t size;
36306a99fe3SHajimu UMEMOTO
36406a99fe3SHajimu UMEMOTO size = buffer_size;
36506a99fe3SHajimu UMEMOTO va_copy(ap_new, ap);
36606a99fe3SHajimu UMEMOTO res = cache_info->marshal_func(buffer, &size, retval, ap_new,
36706a99fe3SHajimu UMEMOTO cache_info->mdata);
36806a99fe3SHajimu UMEMOTO va_end(ap_new);
36906a99fe3SHajimu UMEMOTO
37006a99fe3SHajimu UMEMOTO if (res == NS_RETURN) {
37106a99fe3SHajimu UMEMOTO if (buffer_size > NSS_CACHE_BUFFER_SIZE_LIMIT)
37206a99fe3SHajimu UMEMOTO break;
37306a99fe3SHajimu UMEMOTO
37406a99fe3SHajimu UMEMOTO buffer_size <<= 1;
37506a99fe3SHajimu UMEMOTO buffer = (char *)realloc(buffer, buffer_size);
37606a99fe3SHajimu UMEMOTO memset(buffer, 0, buffer_size);
37706a99fe3SHajimu UMEMOTO }
37806a99fe3SHajimu UMEMOTO } while (res == NS_RETURN);
37906a99fe3SHajimu UMEMOTO
38006a99fe3SHajimu UMEMOTO if (res != NS_SUCCESS) {
38106a99fe3SHajimu UMEMOTO free(buffer);
38206a99fe3SHajimu UMEMOTO return (res);
38306a99fe3SHajimu UMEMOTO }
38406a99fe3SHajimu UMEMOTO
38506a99fe3SHajimu UMEMOTO res = __cached_mp_write(ws, buffer, buffer_size);
38606a99fe3SHajimu UMEMOTO
38706a99fe3SHajimu UMEMOTO free(buffer);
38806a99fe3SHajimu UMEMOTO return (res == 0 ? NS_SUCCESS : NS_UNAVAIL);
38906a99fe3SHajimu UMEMOTO }
39006a99fe3SHajimu UMEMOTO
39106a99fe3SHajimu UMEMOTO int
__nss_mp_cache_write_submit(void * retval,void * mdata,va_list ap)39206a99fe3SHajimu UMEMOTO __nss_mp_cache_write_submit(void *retval, void *mdata, va_list ap)
39306a99fe3SHajimu UMEMOTO {
39406a99fe3SHajimu UMEMOTO cached_mp_write_session ws;
39506a99fe3SHajimu UMEMOTO
39606a99fe3SHajimu UMEMOTO nss_cache_info const *cache_info;
39706a99fe3SHajimu UMEMOTO nss_cache_data *cache_data;
39806a99fe3SHajimu UMEMOTO
39906a99fe3SHajimu UMEMOTO cache_data = (nss_cache_data *)mdata;
40006a99fe3SHajimu UMEMOTO cache_info = cache_data->info;
40106a99fe3SHajimu UMEMOTO
40206a99fe3SHajimu UMEMOTO ws = cache_info->get_mp_ws_func();
40306a99fe3SHajimu UMEMOTO if (ws != INVALID_CACHED_MP_WRITE_SESSION) {
40406a99fe3SHajimu UMEMOTO __close_cached_mp_write_session(ws);
40506a99fe3SHajimu UMEMOTO ws = INVALID_CACHED_MP_WRITE_SESSION;
40606a99fe3SHajimu UMEMOTO cache_info->set_mp_ws_func(ws);
40706a99fe3SHajimu UMEMOTO }
40806a99fe3SHajimu UMEMOTO return (NS_UNAVAIL);
40906a99fe3SHajimu UMEMOTO }
41006a99fe3SHajimu UMEMOTO
41106a99fe3SHajimu UMEMOTO int
__nss_mp_cache_end(void * retval,void * mdata,va_list ap)41206a99fe3SHajimu UMEMOTO __nss_mp_cache_end(void *retval, void *mdata, va_list ap)
41306a99fe3SHajimu UMEMOTO {
41406a99fe3SHajimu UMEMOTO cached_mp_write_session ws;
41506a99fe3SHajimu UMEMOTO cached_mp_read_session rs;
41606a99fe3SHajimu UMEMOTO
41706a99fe3SHajimu UMEMOTO nss_cache_info const *cache_info;
41806a99fe3SHajimu UMEMOTO nss_cache_data *cache_data;
41906a99fe3SHajimu UMEMOTO
42006a99fe3SHajimu UMEMOTO cache_data = (nss_cache_data *)mdata;
42106a99fe3SHajimu UMEMOTO cache_info = cache_data->info;
42206a99fe3SHajimu UMEMOTO
42306a99fe3SHajimu UMEMOTO ws = cache_info->get_mp_ws_func();
42406a99fe3SHajimu UMEMOTO if (ws != INVALID_CACHED_MP_WRITE_SESSION) {
42506a99fe3SHajimu UMEMOTO __abandon_cached_mp_write_session(ws);
42606a99fe3SHajimu UMEMOTO ws = INVALID_CACHED_MP_WRITE_SESSION;
42706a99fe3SHajimu UMEMOTO cache_info->set_mp_ws_func(ws);
42806a99fe3SHajimu UMEMOTO }
42906a99fe3SHajimu UMEMOTO
43006a99fe3SHajimu UMEMOTO rs = cache_info->get_mp_rs_func();
43106a99fe3SHajimu UMEMOTO if (rs != INVALID_CACHED_MP_READ_SESSION) {
43206a99fe3SHajimu UMEMOTO __close_cached_mp_read_session(rs);
43306a99fe3SHajimu UMEMOTO rs = INVALID_CACHED_MP_READ_SESSION;
43406a99fe3SHajimu UMEMOTO cache_info->set_mp_rs_func(rs);
43506a99fe3SHajimu UMEMOTO }
43606a99fe3SHajimu UMEMOTO
43706a99fe3SHajimu UMEMOTO return (NS_UNAVAIL);
43806a99fe3SHajimu UMEMOTO }
439