106a99fe3SHajimu UMEMOTO /*- 206a99fe3SHajimu UMEMOTO * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru> 306a99fe3SHajimu UMEMOTO * All rights reserved. 406a99fe3SHajimu UMEMOTO * 506a99fe3SHajimu UMEMOTO * Redistribution and use in source and binary forms, with or without 606a99fe3SHajimu UMEMOTO * modification, are permitted provided that the following conditions 706a99fe3SHajimu UMEMOTO * are met: 806a99fe3SHajimu UMEMOTO * 1. Redistributions of source code must retain the above copyright 906a99fe3SHajimu UMEMOTO * notice, this list of conditions and the following disclaimer. 1006a99fe3SHajimu UMEMOTO * 2. Redistributions in binary form must reproduce the above copyright 1106a99fe3SHajimu UMEMOTO * notice, this list of conditions and the following disclaimer in the 1206a99fe3SHajimu UMEMOTO * documentation and/or other materials provided with the distribution. 1306a99fe3SHajimu UMEMOTO * 1406a99fe3SHajimu UMEMOTO * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1506a99fe3SHajimu UMEMOTO * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1606a99fe3SHajimu UMEMOTO * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1706a99fe3SHajimu UMEMOTO * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1806a99fe3SHajimu UMEMOTO * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1906a99fe3SHajimu UMEMOTO * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2006a99fe3SHajimu UMEMOTO * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2106a99fe3SHajimu UMEMOTO * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2206a99fe3SHajimu UMEMOTO * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2306a99fe3SHajimu UMEMOTO * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2406a99fe3SHajimu UMEMOTO * SUCH DAMAGE. 2506a99fe3SHajimu UMEMOTO * 2606a99fe3SHajimu UMEMOTO */ 2706a99fe3SHajimu UMEMOTO 2806a99fe3SHajimu UMEMOTO #include <sys/cdefs.h> 2906a99fe3SHajimu UMEMOTO __FBSDID("$FreeBSD$"); 3006a99fe3SHajimu UMEMOTO 3106a99fe3SHajimu UMEMOTO #include "namespace.h" 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 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 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 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 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 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 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 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 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