106a99fe3SHajimu UMEMOTO /*- 2*d915a14eSPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*d915a14eSPedro 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 <sys/cdefs.h> 3106a99fe3SHajimu UMEMOTO __FBSDID("$FreeBSD$"); 3206a99fe3SHajimu UMEMOTO 3306a99fe3SHajimu UMEMOTO #include "namespace.h" 34ae274020SCraig Rodrigues #define _NS_PRIVATE 3506a99fe3SHajimu UMEMOTO #include <nsswitch.h> 3606a99fe3SHajimu UMEMOTO #include <stdlib.h> 3706a99fe3SHajimu UMEMOTO #include <string.h> 3806a99fe3SHajimu UMEMOTO #include "un-namespace.h" 3906a99fe3SHajimu UMEMOTO #include "nscachedcli.h" 4006a99fe3SHajimu UMEMOTO #include "nscache.h" 4106a99fe3SHajimu UMEMOTO 4206a99fe3SHajimu UMEMOTO #define NSS_CACHE_KEY_INITIAL_SIZE (256) 4306a99fe3SHajimu UMEMOTO #define NSS_CACHE_KEY_SIZE_LIMIT (NSS_CACHE_KEY_INITIAL_SIZE << 4) 4406a99fe3SHajimu UMEMOTO 4506a99fe3SHajimu UMEMOTO #define NSS_CACHE_BUFFER_INITIAL_SIZE (1024) 4606a99fe3SHajimu UMEMOTO #define NSS_CACHE_BUFFER_SIZE_LIMIT (NSS_CACHE_BUFFER_INITIAL_SIZE << 8) 4706a99fe3SHajimu UMEMOTO 4890855671STom McLaughlin #define CACHED_SOCKET_PATH "/var/run/nscd" 4906a99fe3SHajimu UMEMOTO 5006a99fe3SHajimu UMEMOTO int 5106a99fe3SHajimu UMEMOTO __nss_cache_handler(void *retval, void *mdata, va_list ap) 5206a99fe3SHajimu UMEMOTO { 5306a99fe3SHajimu UMEMOTO return (NS_UNAVAIL); 5406a99fe3SHajimu UMEMOTO } 5506a99fe3SHajimu UMEMOTO 5606a99fe3SHajimu UMEMOTO int 5706a99fe3SHajimu UMEMOTO __nss_common_cache_read(void *retval, void *mdata, va_list ap) 5806a99fe3SHajimu UMEMOTO { 5906a99fe3SHajimu UMEMOTO struct cached_connection_params params; 6006a99fe3SHajimu UMEMOTO cached_connection connection; 6106a99fe3SHajimu UMEMOTO 6206a99fe3SHajimu UMEMOTO char *buffer; 6306a99fe3SHajimu UMEMOTO size_t buffer_size, size; 6406a99fe3SHajimu UMEMOTO 6506a99fe3SHajimu UMEMOTO nss_cache_info const *cache_info; 6606a99fe3SHajimu UMEMOTO nss_cache_data *cache_data; 6706a99fe3SHajimu UMEMOTO va_list ap_new; 6806a99fe3SHajimu UMEMOTO int res; 6906a99fe3SHajimu UMEMOTO 7006a99fe3SHajimu UMEMOTO cache_data = (nss_cache_data *)mdata; 7106a99fe3SHajimu UMEMOTO cache_info = cache_data->info; 7206a99fe3SHajimu UMEMOTO 7306a99fe3SHajimu UMEMOTO memset(¶ms, 0, sizeof(struct cached_connection_params)); 7406a99fe3SHajimu UMEMOTO params.socket_path = CACHED_SOCKET_PATH; 7506a99fe3SHajimu UMEMOTO 7606a99fe3SHajimu UMEMOTO cache_data->key = (char *)malloc(NSS_CACHE_KEY_INITIAL_SIZE); 7706a99fe3SHajimu UMEMOTO memset(cache_data->key, 0, NSS_CACHE_KEY_INITIAL_SIZE); 7806a99fe3SHajimu UMEMOTO cache_data->key_size = NSS_CACHE_KEY_INITIAL_SIZE; 7906a99fe3SHajimu UMEMOTO va_copy(ap_new, ap); 8006a99fe3SHajimu UMEMOTO 8106a99fe3SHajimu UMEMOTO do { 8206a99fe3SHajimu UMEMOTO size = cache_data->key_size; 8306a99fe3SHajimu UMEMOTO res = cache_info->id_func(cache_data->key, &size, ap_new, 8406a99fe3SHajimu UMEMOTO cache_info->mdata); 8506a99fe3SHajimu UMEMOTO va_end(ap_new); 8606a99fe3SHajimu UMEMOTO if (res == NS_RETURN) { 8706a99fe3SHajimu UMEMOTO if (cache_data->key_size > NSS_CACHE_KEY_SIZE_LIMIT) 8806a99fe3SHajimu UMEMOTO break; 8906a99fe3SHajimu UMEMOTO 9006a99fe3SHajimu UMEMOTO cache_data->key_size <<= 1; 9106a99fe3SHajimu UMEMOTO cache_data->key = realloc(cache_data->key, 9206a99fe3SHajimu UMEMOTO cache_data->key_size); 9306a99fe3SHajimu UMEMOTO memset(cache_data->key, 0, cache_data->key_size); 9406a99fe3SHajimu UMEMOTO va_copy(ap_new, ap); 9506a99fe3SHajimu UMEMOTO } 9606a99fe3SHajimu UMEMOTO } while (res == NS_RETURN); 9706a99fe3SHajimu UMEMOTO 9806a99fe3SHajimu UMEMOTO if (res != NS_SUCCESS) { 9906a99fe3SHajimu UMEMOTO free(cache_data->key); 10006a99fe3SHajimu UMEMOTO cache_data->key = NULL; 10106a99fe3SHajimu UMEMOTO cache_data->key_size = 0; 10206a99fe3SHajimu UMEMOTO return (res); 10306a99fe3SHajimu UMEMOTO } else 10406a99fe3SHajimu UMEMOTO cache_data->key_size = size; 10506a99fe3SHajimu UMEMOTO 10606a99fe3SHajimu UMEMOTO buffer_size = NSS_CACHE_BUFFER_INITIAL_SIZE; 10706a99fe3SHajimu UMEMOTO buffer = (char *)malloc(NSS_CACHE_BUFFER_INITIAL_SIZE); 10806a99fe3SHajimu UMEMOTO memset(buffer, 0, NSS_CACHE_BUFFER_INITIAL_SIZE); 10906a99fe3SHajimu UMEMOTO 11006a99fe3SHajimu UMEMOTO do { 11106a99fe3SHajimu UMEMOTO connection = __open_cached_connection(¶ms); 11206a99fe3SHajimu UMEMOTO if (connection == NULL) { 11306a99fe3SHajimu UMEMOTO res = -1; 11406a99fe3SHajimu UMEMOTO break; 11506a99fe3SHajimu UMEMOTO } 11606a99fe3SHajimu UMEMOTO res = __cached_read(connection, cache_info->entry_name, 11706a99fe3SHajimu UMEMOTO cache_data->key, cache_data->key_size, buffer, 11806a99fe3SHajimu UMEMOTO &buffer_size); 11906a99fe3SHajimu UMEMOTO __close_cached_connection(connection); 12006a99fe3SHajimu UMEMOTO if (res == -2 && buffer_size < NSS_CACHE_BUFFER_SIZE_LIMIT) { 12106a99fe3SHajimu UMEMOTO buffer = (char *)realloc(buffer, buffer_size); 12206a99fe3SHajimu UMEMOTO memset(buffer, 0, buffer_size); 12306a99fe3SHajimu UMEMOTO } 12406a99fe3SHajimu UMEMOTO } while (res == -2); 12506a99fe3SHajimu UMEMOTO 12606a99fe3SHajimu UMEMOTO if (res == 0) { 12706a99fe3SHajimu UMEMOTO if (buffer_size == 0) { 12806a99fe3SHajimu UMEMOTO free(buffer); 12906a99fe3SHajimu UMEMOTO free(cache_data->key); 13006a99fe3SHajimu UMEMOTO cache_data->key = NULL; 13106a99fe3SHajimu UMEMOTO cache_data->key_size = 0; 13206a99fe3SHajimu UMEMOTO return (NS_RETURN); 13306a99fe3SHajimu UMEMOTO } 13406a99fe3SHajimu UMEMOTO 13506a99fe3SHajimu UMEMOTO va_copy(ap_new, ap); 13606a99fe3SHajimu UMEMOTO res = cache_info->unmarshal_func(buffer, buffer_size, retval, 13706a99fe3SHajimu UMEMOTO ap_new, cache_info->mdata); 13806a99fe3SHajimu UMEMOTO va_end(ap_new); 13906a99fe3SHajimu UMEMOTO 14006a99fe3SHajimu UMEMOTO if (res != NS_SUCCESS) { 14106a99fe3SHajimu UMEMOTO free(buffer); 14206a99fe3SHajimu UMEMOTO free(cache_data->key); 14306a99fe3SHajimu UMEMOTO cache_data->key = NULL; 14406a99fe3SHajimu UMEMOTO cache_data->key_size = 0; 14506a99fe3SHajimu UMEMOTO return (res); 14606a99fe3SHajimu UMEMOTO } else 14706a99fe3SHajimu UMEMOTO res = 0; 14806a99fe3SHajimu UMEMOTO } 14906a99fe3SHajimu UMEMOTO 15006a99fe3SHajimu UMEMOTO if (res == 0) { 15106a99fe3SHajimu UMEMOTO free(cache_data->key); 15206a99fe3SHajimu UMEMOTO cache_data->key = NULL; 15306a99fe3SHajimu UMEMOTO cache_data->key_size = 0; 15406a99fe3SHajimu UMEMOTO } 15506a99fe3SHajimu UMEMOTO 15606a99fe3SHajimu UMEMOTO free(buffer); 15706a99fe3SHajimu UMEMOTO return (res == 0 ? NS_SUCCESS : NS_NOTFOUND); 15806a99fe3SHajimu UMEMOTO } 15906a99fe3SHajimu UMEMOTO 16006a99fe3SHajimu UMEMOTO int 16106a99fe3SHajimu UMEMOTO __nss_common_cache_write(void *retval, void *mdata, va_list ap) 16206a99fe3SHajimu UMEMOTO { 16306a99fe3SHajimu UMEMOTO struct cached_connection_params params; 16406a99fe3SHajimu UMEMOTO cached_connection connection; 16506a99fe3SHajimu UMEMOTO 16606a99fe3SHajimu UMEMOTO char *buffer; 16706a99fe3SHajimu UMEMOTO size_t buffer_size; 16806a99fe3SHajimu UMEMOTO 16906a99fe3SHajimu UMEMOTO nss_cache_info const *cache_info; 17006a99fe3SHajimu UMEMOTO nss_cache_data *cache_data; 17106a99fe3SHajimu UMEMOTO va_list ap_new; 17206a99fe3SHajimu UMEMOTO int res; 17306a99fe3SHajimu UMEMOTO 17406a99fe3SHajimu UMEMOTO cache_data = (nss_cache_data *)mdata; 17506a99fe3SHajimu UMEMOTO cache_info = cache_data->info; 17606a99fe3SHajimu UMEMOTO 17706a99fe3SHajimu UMEMOTO if (cache_data->key == NULL) 17806a99fe3SHajimu UMEMOTO return (NS_UNAVAIL); 17906a99fe3SHajimu UMEMOTO 18006a99fe3SHajimu UMEMOTO memset(¶ms, 0, sizeof(struct cached_connection_params)); 18106a99fe3SHajimu UMEMOTO params.socket_path = CACHED_SOCKET_PATH; 18206a99fe3SHajimu UMEMOTO 18306a99fe3SHajimu UMEMOTO connection = __open_cached_connection(¶ms); 18406a99fe3SHajimu UMEMOTO if (connection == NULL) { 18506a99fe3SHajimu UMEMOTO free(cache_data->key); 18606a99fe3SHajimu UMEMOTO return (NS_UNAVAIL); 18706a99fe3SHajimu UMEMOTO } 18806a99fe3SHajimu UMEMOTO 18906a99fe3SHajimu UMEMOTO buffer_size = NSS_CACHE_BUFFER_INITIAL_SIZE; 19006a99fe3SHajimu UMEMOTO buffer = (char *)malloc(NSS_CACHE_BUFFER_INITIAL_SIZE); 19106a99fe3SHajimu UMEMOTO memset(buffer, 0, NSS_CACHE_BUFFER_INITIAL_SIZE); 19206a99fe3SHajimu UMEMOTO 19306a99fe3SHajimu UMEMOTO do { 19406a99fe3SHajimu UMEMOTO size_t size; 19506a99fe3SHajimu UMEMOTO 19606a99fe3SHajimu UMEMOTO size = buffer_size; 19706a99fe3SHajimu UMEMOTO va_copy(ap_new, ap); 19806a99fe3SHajimu UMEMOTO res = cache_info->marshal_func(buffer, &size, retval, ap_new, 19906a99fe3SHajimu UMEMOTO cache_info->mdata); 20006a99fe3SHajimu UMEMOTO va_end(ap_new); 20106a99fe3SHajimu UMEMOTO 20206a99fe3SHajimu UMEMOTO if (res == NS_RETURN) { 20306a99fe3SHajimu UMEMOTO if (buffer_size > NSS_CACHE_BUFFER_SIZE_LIMIT) 20406a99fe3SHajimu UMEMOTO break; 20506a99fe3SHajimu UMEMOTO 20606a99fe3SHajimu UMEMOTO buffer_size <<= 1; 20706a99fe3SHajimu UMEMOTO buffer = (char *)realloc(buffer, buffer_size); 20806a99fe3SHajimu UMEMOTO memset(buffer, 0, buffer_size); 20906a99fe3SHajimu UMEMOTO } 21006a99fe3SHajimu UMEMOTO } while (res == NS_RETURN); 21106a99fe3SHajimu UMEMOTO 21206a99fe3SHajimu UMEMOTO if (res != NS_SUCCESS) { 21306a99fe3SHajimu UMEMOTO __close_cached_connection(connection); 21406a99fe3SHajimu UMEMOTO free(cache_data->key); 21506a99fe3SHajimu UMEMOTO free(buffer); 21606a99fe3SHajimu UMEMOTO return (res); 21706a99fe3SHajimu UMEMOTO } 21806a99fe3SHajimu UMEMOTO 21906a99fe3SHajimu UMEMOTO res = __cached_write(connection, cache_info->entry_name, 22006a99fe3SHajimu UMEMOTO cache_data->key, cache_data->key_size, buffer, buffer_size); 22106a99fe3SHajimu UMEMOTO __close_cached_connection(connection); 22206a99fe3SHajimu UMEMOTO 22306a99fe3SHajimu UMEMOTO free(cache_data->key); 22406a99fe3SHajimu UMEMOTO free(buffer); 22506a99fe3SHajimu UMEMOTO 22606a99fe3SHajimu UMEMOTO return (res == 0 ? NS_SUCCESS : NS_UNAVAIL); 22706a99fe3SHajimu UMEMOTO } 22806a99fe3SHajimu UMEMOTO 22906a99fe3SHajimu UMEMOTO int 23006a99fe3SHajimu UMEMOTO __nss_common_cache_write_negative(void *mdata) 23106a99fe3SHajimu UMEMOTO { 23206a99fe3SHajimu UMEMOTO struct cached_connection_params params; 23306a99fe3SHajimu UMEMOTO cached_connection connection; 23406a99fe3SHajimu UMEMOTO int res; 23506a99fe3SHajimu UMEMOTO 23606a99fe3SHajimu UMEMOTO nss_cache_info const *cache_info; 23706a99fe3SHajimu UMEMOTO nss_cache_data *cache_data; 23806a99fe3SHajimu UMEMOTO 23906a99fe3SHajimu UMEMOTO cache_data = (nss_cache_data *)mdata; 24006a99fe3SHajimu UMEMOTO cache_info = cache_data->info; 24106a99fe3SHajimu UMEMOTO 24206a99fe3SHajimu UMEMOTO if (cache_data->key == NULL) 24306a99fe3SHajimu UMEMOTO return (NS_UNAVAIL); 24406a99fe3SHajimu UMEMOTO 24506a99fe3SHajimu UMEMOTO memset(¶ms, 0, sizeof(struct cached_connection_params)); 24606a99fe3SHajimu UMEMOTO params.socket_path = CACHED_SOCKET_PATH; 24706a99fe3SHajimu UMEMOTO 24806a99fe3SHajimu UMEMOTO connection = __open_cached_connection(¶ms); 24906a99fe3SHajimu UMEMOTO if (connection == NULL) { 25006a99fe3SHajimu UMEMOTO free(cache_data->key); 25106a99fe3SHajimu UMEMOTO return (NS_UNAVAIL); 25206a99fe3SHajimu UMEMOTO } 25306a99fe3SHajimu UMEMOTO 25406a99fe3SHajimu UMEMOTO res = __cached_write(connection, cache_info->entry_name, 25506a99fe3SHajimu UMEMOTO cache_data->key, cache_data->key_size, NULL, 0); 25606a99fe3SHajimu UMEMOTO __close_cached_connection(connection); 25706a99fe3SHajimu UMEMOTO 25806a99fe3SHajimu UMEMOTO free(cache_data->key); 25906a99fe3SHajimu UMEMOTO return (res == 0 ? NS_SUCCESS : NS_UNAVAIL); 26006a99fe3SHajimu UMEMOTO } 26106a99fe3SHajimu UMEMOTO 26206a99fe3SHajimu UMEMOTO int 26306a99fe3SHajimu UMEMOTO __nss_mp_cache_read(void *retval, void *mdata, va_list ap) 26406a99fe3SHajimu UMEMOTO { 26506a99fe3SHajimu UMEMOTO struct cached_connection_params params; 26606a99fe3SHajimu UMEMOTO cached_mp_read_session rs; 26706a99fe3SHajimu UMEMOTO 26806a99fe3SHajimu UMEMOTO char *buffer; 26906a99fe3SHajimu UMEMOTO size_t buffer_size; 27006a99fe3SHajimu UMEMOTO 27106a99fe3SHajimu UMEMOTO nss_cache_info const *cache_info; 27206a99fe3SHajimu UMEMOTO nss_cache_data *cache_data; 27306a99fe3SHajimu UMEMOTO va_list ap_new; 27406a99fe3SHajimu UMEMOTO int res; 27506a99fe3SHajimu UMEMOTO 27606a99fe3SHajimu UMEMOTO cache_data = (nss_cache_data *)mdata; 27706a99fe3SHajimu UMEMOTO cache_info = cache_data->info; 27806a99fe3SHajimu UMEMOTO 27906a99fe3SHajimu UMEMOTO if (cache_info->get_mp_ws_func() != INVALID_CACHED_MP_WRITE_SESSION) 28006a99fe3SHajimu UMEMOTO return (NS_UNAVAIL); 28106a99fe3SHajimu UMEMOTO 28206a99fe3SHajimu UMEMOTO rs = cache_info->get_mp_rs_func(); 28306a99fe3SHajimu UMEMOTO if (rs == INVALID_CACHED_MP_READ_SESSION) { 28406a99fe3SHajimu UMEMOTO memset(¶ms, 0, sizeof(struct cached_connection_params)); 28506a99fe3SHajimu UMEMOTO params.socket_path = CACHED_SOCKET_PATH; 28606a99fe3SHajimu UMEMOTO 28706a99fe3SHajimu UMEMOTO rs = __open_cached_mp_read_session(¶ms, 28806a99fe3SHajimu UMEMOTO cache_info->entry_name); 28906a99fe3SHajimu UMEMOTO if (rs == INVALID_CACHED_MP_READ_SESSION) 29006a99fe3SHajimu UMEMOTO return (NS_UNAVAIL); 29106a99fe3SHajimu UMEMOTO 29206a99fe3SHajimu UMEMOTO cache_info->set_mp_rs_func(rs); 29306a99fe3SHajimu UMEMOTO } 29406a99fe3SHajimu UMEMOTO 29506a99fe3SHajimu UMEMOTO buffer_size = NSS_CACHE_BUFFER_INITIAL_SIZE; 29606a99fe3SHajimu UMEMOTO buffer = (char *)malloc(NSS_CACHE_BUFFER_INITIAL_SIZE); 29706a99fe3SHajimu UMEMOTO memset(buffer, 0, NSS_CACHE_BUFFER_INITIAL_SIZE); 29806a99fe3SHajimu UMEMOTO 29906a99fe3SHajimu UMEMOTO do { 30006a99fe3SHajimu UMEMOTO res = __cached_mp_read(rs, buffer, &buffer_size); 30106a99fe3SHajimu UMEMOTO if (res == -2 && buffer_size < NSS_CACHE_BUFFER_SIZE_LIMIT) { 30206a99fe3SHajimu UMEMOTO buffer = (char *)realloc(buffer, buffer_size); 30306a99fe3SHajimu UMEMOTO memset(buffer, 0, buffer_size); 30406a99fe3SHajimu UMEMOTO } 30506a99fe3SHajimu UMEMOTO } while (res == -2); 30606a99fe3SHajimu UMEMOTO 30706a99fe3SHajimu UMEMOTO if (res == 0) { 30806a99fe3SHajimu UMEMOTO va_copy(ap_new, ap); 30906a99fe3SHajimu UMEMOTO res = cache_info->unmarshal_func(buffer, buffer_size, retval, 31006a99fe3SHajimu UMEMOTO ap_new, cache_info->mdata); 31106a99fe3SHajimu UMEMOTO va_end(ap_new); 31206a99fe3SHajimu UMEMOTO 31306a99fe3SHajimu UMEMOTO if (res != NS_SUCCESS) { 31406a99fe3SHajimu UMEMOTO free(buffer); 31506a99fe3SHajimu UMEMOTO return (res); 31606a99fe3SHajimu UMEMOTO } else 31706a99fe3SHajimu UMEMOTO res = 0; 31806a99fe3SHajimu UMEMOTO } else { 31906a99fe3SHajimu UMEMOTO free(buffer); 32006a99fe3SHajimu UMEMOTO __close_cached_mp_read_session(rs); 32106a99fe3SHajimu UMEMOTO rs = INVALID_CACHED_MP_READ_SESSION; 32206a99fe3SHajimu UMEMOTO cache_info->set_mp_rs_func(rs); 32306a99fe3SHajimu UMEMOTO return (res == -1 ? NS_RETURN : NS_UNAVAIL); 32406a99fe3SHajimu UMEMOTO } 32506a99fe3SHajimu UMEMOTO 32606a99fe3SHajimu UMEMOTO free(buffer); 32706a99fe3SHajimu UMEMOTO return (res == 0 ? NS_SUCCESS : NS_NOTFOUND); 32806a99fe3SHajimu UMEMOTO } 32906a99fe3SHajimu UMEMOTO 33006a99fe3SHajimu UMEMOTO int 33106a99fe3SHajimu UMEMOTO __nss_mp_cache_write(void *retval, void *mdata, va_list ap) 33206a99fe3SHajimu UMEMOTO { 33306a99fe3SHajimu UMEMOTO struct cached_connection_params params; 33406a99fe3SHajimu UMEMOTO cached_mp_write_session ws; 33506a99fe3SHajimu UMEMOTO 33606a99fe3SHajimu UMEMOTO char *buffer; 33706a99fe3SHajimu UMEMOTO size_t buffer_size; 33806a99fe3SHajimu UMEMOTO 33906a99fe3SHajimu UMEMOTO nss_cache_info const *cache_info; 34006a99fe3SHajimu UMEMOTO nss_cache_data *cache_data; 34106a99fe3SHajimu UMEMOTO va_list ap_new; 34206a99fe3SHajimu UMEMOTO int res; 34306a99fe3SHajimu UMEMOTO 34406a99fe3SHajimu UMEMOTO cache_data = (nss_cache_data *)mdata; 34506a99fe3SHajimu UMEMOTO cache_info = cache_data->info; 34606a99fe3SHajimu UMEMOTO 34706a99fe3SHajimu UMEMOTO ws = cache_info->get_mp_ws_func(); 34806a99fe3SHajimu UMEMOTO if (ws == INVALID_CACHED_MP_WRITE_SESSION) { 34906a99fe3SHajimu UMEMOTO memset(¶ms, 0, sizeof(struct cached_connection_params)); 35006a99fe3SHajimu UMEMOTO params.socket_path = CACHED_SOCKET_PATH; 35106a99fe3SHajimu UMEMOTO 35206a99fe3SHajimu UMEMOTO ws = __open_cached_mp_write_session(¶ms, 35306a99fe3SHajimu UMEMOTO cache_info->entry_name); 35406a99fe3SHajimu UMEMOTO if (ws == INVALID_CACHED_MP_WRITE_SESSION) 35506a99fe3SHajimu UMEMOTO return (NS_UNAVAIL); 35606a99fe3SHajimu UMEMOTO 35706a99fe3SHajimu UMEMOTO cache_info->set_mp_ws_func(ws); 35806a99fe3SHajimu UMEMOTO } 35906a99fe3SHajimu UMEMOTO 36006a99fe3SHajimu UMEMOTO buffer_size = NSS_CACHE_BUFFER_INITIAL_SIZE; 36106a99fe3SHajimu UMEMOTO buffer = (char *)malloc(NSS_CACHE_BUFFER_INITIAL_SIZE); 36206a99fe3SHajimu UMEMOTO memset(buffer, 0, NSS_CACHE_BUFFER_INITIAL_SIZE); 36306a99fe3SHajimu UMEMOTO 36406a99fe3SHajimu UMEMOTO do { 36506a99fe3SHajimu UMEMOTO size_t size; 36606a99fe3SHajimu UMEMOTO 36706a99fe3SHajimu UMEMOTO size = buffer_size; 36806a99fe3SHajimu UMEMOTO va_copy(ap_new, ap); 36906a99fe3SHajimu UMEMOTO res = cache_info->marshal_func(buffer, &size, retval, ap_new, 37006a99fe3SHajimu UMEMOTO cache_info->mdata); 37106a99fe3SHajimu UMEMOTO va_end(ap_new); 37206a99fe3SHajimu UMEMOTO 37306a99fe3SHajimu UMEMOTO if (res == NS_RETURN) { 37406a99fe3SHajimu UMEMOTO if (buffer_size > NSS_CACHE_BUFFER_SIZE_LIMIT) 37506a99fe3SHajimu UMEMOTO break; 37606a99fe3SHajimu UMEMOTO 37706a99fe3SHajimu UMEMOTO buffer_size <<= 1; 37806a99fe3SHajimu UMEMOTO buffer = (char *)realloc(buffer, buffer_size); 37906a99fe3SHajimu UMEMOTO memset(buffer, 0, buffer_size); 38006a99fe3SHajimu UMEMOTO } 38106a99fe3SHajimu UMEMOTO } while (res == NS_RETURN); 38206a99fe3SHajimu UMEMOTO 38306a99fe3SHajimu UMEMOTO if (res != NS_SUCCESS) { 38406a99fe3SHajimu UMEMOTO free(buffer); 38506a99fe3SHajimu UMEMOTO return (res); 38606a99fe3SHajimu UMEMOTO } 38706a99fe3SHajimu UMEMOTO 38806a99fe3SHajimu UMEMOTO res = __cached_mp_write(ws, buffer, buffer_size); 38906a99fe3SHajimu UMEMOTO 39006a99fe3SHajimu UMEMOTO free(buffer); 39106a99fe3SHajimu UMEMOTO return (res == 0 ? NS_SUCCESS : NS_UNAVAIL); 39206a99fe3SHajimu UMEMOTO } 39306a99fe3SHajimu UMEMOTO 39406a99fe3SHajimu UMEMOTO int 39506a99fe3SHajimu UMEMOTO __nss_mp_cache_write_submit(void *retval, void *mdata, va_list ap) 39606a99fe3SHajimu UMEMOTO { 39706a99fe3SHajimu UMEMOTO cached_mp_write_session ws; 39806a99fe3SHajimu UMEMOTO 39906a99fe3SHajimu UMEMOTO nss_cache_info const *cache_info; 40006a99fe3SHajimu UMEMOTO nss_cache_data *cache_data; 40106a99fe3SHajimu UMEMOTO 40206a99fe3SHajimu UMEMOTO cache_data = (nss_cache_data *)mdata; 40306a99fe3SHajimu UMEMOTO cache_info = cache_data->info; 40406a99fe3SHajimu UMEMOTO 40506a99fe3SHajimu UMEMOTO ws = cache_info->get_mp_ws_func(); 40606a99fe3SHajimu UMEMOTO if (ws != INVALID_CACHED_MP_WRITE_SESSION) { 40706a99fe3SHajimu UMEMOTO __close_cached_mp_write_session(ws); 40806a99fe3SHajimu UMEMOTO ws = INVALID_CACHED_MP_WRITE_SESSION; 40906a99fe3SHajimu UMEMOTO cache_info->set_mp_ws_func(ws); 41006a99fe3SHajimu UMEMOTO } 41106a99fe3SHajimu UMEMOTO return (NS_UNAVAIL); 41206a99fe3SHajimu UMEMOTO } 41306a99fe3SHajimu UMEMOTO 41406a99fe3SHajimu UMEMOTO int 41506a99fe3SHajimu UMEMOTO __nss_mp_cache_end(void *retval, void *mdata, va_list ap) 41606a99fe3SHajimu UMEMOTO { 41706a99fe3SHajimu UMEMOTO cached_mp_write_session ws; 41806a99fe3SHajimu UMEMOTO cached_mp_read_session rs; 41906a99fe3SHajimu UMEMOTO 42006a99fe3SHajimu UMEMOTO nss_cache_info const *cache_info; 42106a99fe3SHajimu UMEMOTO nss_cache_data *cache_data; 42206a99fe3SHajimu UMEMOTO 42306a99fe3SHajimu UMEMOTO cache_data = (nss_cache_data *)mdata; 42406a99fe3SHajimu UMEMOTO cache_info = cache_data->info; 42506a99fe3SHajimu UMEMOTO 42606a99fe3SHajimu UMEMOTO ws = cache_info->get_mp_ws_func(); 42706a99fe3SHajimu UMEMOTO if (ws != INVALID_CACHED_MP_WRITE_SESSION) { 42806a99fe3SHajimu UMEMOTO __abandon_cached_mp_write_session(ws); 42906a99fe3SHajimu UMEMOTO ws = INVALID_CACHED_MP_WRITE_SESSION; 43006a99fe3SHajimu UMEMOTO cache_info->set_mp_ws_func(ws); 43106a99fe3SHajimu UMEMOTO } 43206a99fe3SHajimu UMEMOTO 43306a99fe3SHajimu UMEMOTO rs = cache_info->get_mp_rs_func(); 43406a99fe3SHajimu UMEMOTO if (rs != INVALID_CACHED_MP_READ_SESSION) { 43506a99fe3SHajimu UMEMOTO __close_cached_mp_read_session(rs); 43606a99fe3SHajimu UMEMOTO rs = INVALID_CACHED_MP_READ_SESSION; 43706a99fe3SHajimu UMEMOTO cache_info->set_mp_rs_func(rs); 43806a99fe3SHajimu UMEMOTO } 43906a99fe3SHajimu UMEMOTO 44006a99fe3SHajimu UMEMOTO return (NS_UNAVAIL); 44106a99fe3SHajimu UMEMOTO } 442