1cb5caa98Sdjl /* 2cb5caa98Sdjl * CDDL HEADER START 3cb5caa98Sdjl * 4cb5caa98Sdjl * The contents of this file are subject to the terms of the 5cb5caa98Sdjl * Common Development and Distribution License (the "License"). 6cb5caa98Sdjl * You may not use this file except in compliance with the License. 7cb5caa98Sdjl * 8cb5caa98Sdjl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9cb5caa98Sdjl * or http://www.opensolaris.org/os/licensing. 10cb5caa98Sdjl * See the License for the specific language governing permissions 11cb5caa98Sdjl * and limitations under the License. 12cb5caa98Sdjl * 13cb5caa98Sdjl * When distributing Covered Code, include this CDDL HEADER in each 14cb5caa98Sdjl * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15cb5caa98Sdjl * If applicable, add the following below this CDDL HEADER, with the 16cb5caa98Sdjl * fields enclosed by brackets "[]" replaced with your own identifying 17cb5caa98Sdjl * information: Portions Copyright [yyyy] [name of copyright owner] 18cb5caa98Sdjl * 19cb5caa98Sdjl * CDDL HEADER END 20cb5caa98Sdjl */ 21cb5caa98Sdjl /* 22cb5caa98Sdjl * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23cb5caa98Sdjl * Use is subject to license terms. 24cb5caa98Sdjl */ 25cb5caa98Sdjl 26cb5caa98Sdjl #pragma ident "%Z%%M% %I% %E% SMI" 27cb5caa98Sdjl 28cb5caa98Sdjl #include <stdlib.h> 29cb5caa98Sdjl #include <locale.h> 30cb5caa98Sdjl #include <string.h> 31cb5caa98Sdjl #include "nscd_config.h" 32cb5caa98Sdjl #include "nscd_log.h" 33cb5caa98Sdjl #include "nscd_switch.h" 34cb5caa98Sdjl 35cb5caa98Sdjl /* 36cb5caa98Sdjl * Configuration data for the nscd switch functions. 37cb5caa98Sdjl */ 38cb5caa98Sdjl nscd_cfg_global_switch_t nscd_switch_cfg_g; 39cb5caa98Sdjl nscd_cfg_switch_t *nscd_switch_cfg; 40cb5caa98Sdjl 41cb5caa98Sdjl /* 42cb5caa98Sdjl * statistics of the nscd switch functions. 43cb5caa98Sdjl */ 44cb5caa98Sdjl nscd_cfg_stat_global_switch_t nscd_switch_stats_g; 45cb5caa98Sdjl nscd_cfg_stat_switch_t *nscd_switch_stats; 46cb5caa98Sdjl 47cb5caa98Sdjl /* 48cb5caa98Sdjl * cookie is set up by the verify function for passing to 49cb5caa98Sdjl * the notify function 50cb5caa98Sdjl */ 51cb5caa98Sdjl typedef struct { 52cb5caa98Sdjl struct __nsw_switchconfig_v1 *cfg; 53cb5caa98Sdjl char *cfgstr; 54cb5caa98Sdjl } nsw_cfg_cookie_t; 55cb5caa98Sdjl 56cb5caa98Sdjl nscd_rc_t 57cb5caa98Sdjl _nscd_alloc_switch_cfg() 58cb5caa98Sdjl { 59cb5caa98Sdjl nscd_switch_cfg = calloc(NSCD_NUM_DB, sizeof (nscd_cfg_switch_t)); 60cb5caa98Sdjl if (nscd_switch_cfg == NULL) 61cb5caa98Sdjl return (NSCD_NO_MEMORY); 62cb5caa98Sdjl 63cb5caa98Sdjl return (NSCD_SUCCESS); 64cb5caa98Sdjl } 65cb5caa98Sdjl 66cb5caa98Sdjl nscd_rc_t 67cb5caa98Sdjl _nscd_alloc_switch_stats() 68cb5caa98Sdjl { 69cb5caa98Sdjl 70cb5caa98Sdjl nscd_switch_stats = calloc(NSCD_NUM_DB, 71cb5caa98Sdjl sizeof (nscd_cfg_stat_switch_t)); 72cb5caa98Sdjl if (nscd_switch_stats == NULL) 73cb5caa98Sdjl return (NSCD_NO_MEMORY); 74cb5caa98Sdjl 75cb5caa98Sdjl return (NSCD_SUCCESS); 76cb5caa98Sdjl } 77cb5caa98Sdjl 78cb5caa98Sdjl /* ARGSUSED */ 79cb5caa98Sdjl nscd_rc_t 80cb5caa98Sdjl _nscd_cfg_switch_notify( 81cb5caa98Sdjl void *data, 82cb5caa98Sdjl struct nscd_cfg_param_desc *pdesc, 83cb5caa98Sdjl nscd_cfg_id_t *nswdb, 84cb5caa98Sdjl nscd_cfg_flag_t dflag, 85cb5caa98Sdjl nscd_cfg_error_t **errorp, 86cb5caa98Sdjl void *cookie) 87cb5caa98Sdjl { 88cb5caa98Sdjl 89cb5caa98Sdjl void *dp; 90cb5caa98Sdjl nscd_rc_t rc; 91cb5caa98Sdjl nsw_cfg_cookie_t *ck = (nsw_cfg_cookie_t *)cookie; 92cb5caa98Sdjl 93cb5caa98Sdjl if (_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_INIT) || 94cb5caa98Sdjl _nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_GROUP)) { 95cb5caa98Sdjl /* 96cb5caa98Sdjl * group data is received, copy in the 97cb5caa98Sdjl * entire strcture 98cb5caa98Sdjl */ 99cb5caa98Sdjl if (_nscd_cfg_flag_is_set(pdesc->pflag, 100cb5caa98Sdjl NSCD_CFG_PFLAG_GLOBAL)) { 101cb5caa98Sdjl nscd_switch_cfg_g = *(nscd_cfg_global_switch_t *)data; 102cb5caa98Sdjl } else { 103cb5caa98Sdjl nscd_switch_cfg[nswdb->index] = 104cb5caa98Sdjl *(nscd_cfg_switch_t *)data; 105cb5caa98Sdjl 106cb5caa98Sdjl } 107cb5caa98Sdjl } else { 108cb5caa98Sdjl /* 109cb5caa98Sdjl * individual paramater is received: copy in the 110cb5caa98Sdjl * parameter value except for nsw-config-string. 111cb5caa98Sdjl */ 112cb5caa98Sdjl if (_nscd_cfg_flag_is_set(pdesc->pflag, 113cb5caa98Sdjl NSCD_CFG_PFLAG_GLOBAL)) { 114cb5caa98Sdjl dp = (char *)&nscd_switch_cfg_g + pdesc->p_offset; 115cb5caa98Sdjl (void) memcpy(dp, data, pdesc->p_size); 116cb5caa98Sdjl } else { 117cb5caa98Sdjl dp = (char *)&nscd_switch_cfg[nswdb->index] + 118cb5caa98Sdjl pdesc->p_offset; 119cb5caa98Sdjl if (pdesc->p_offset != 120cb5caa98Sdjl offsetof(nscd_cfg_switch_t, nsw_config_string)) 121cb5caa98Sdjl (void) memcpy(dp, data, pdesc->p_size); 122cb5caa98Sdjl } 123cb5caa98Sdjl } 124cb5caa98Sdjl 125cb5caa98Sdjl /* 126cb5caa98Sdjl * cookie contains data for the switch policy config 127cb5caa98Sdjl */ 128cb5caa98Sdjl if (cookie != NULL) { 129*ad0e80f7Smichen rc = _nscd_create_sw_struct(nswdb->index, -1, nswdb->name, 130cb5caa98Sdjl ck->cfgstr, ck->cfg, NULL); 131cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 132cb5caa98Sdjl (void) __nsw_freeconfig_v1(ck->cfg); 133cb5caa98Sdjl free(ck); 134cb5caa98Sdjl return (rc); 135cb5caa98Sdjl } 136cb5caa98Sdjl free(ck); 137cb5caa98Sdjl } 138cb5caa98Sdjl 139cb5caa98Sdjl if (_nscd_cfg_flag_is_not_set(dflag, NSCD_CFG_DFLAG_STATIC_DATA)) 140cb5caa98Sdjl free(data); 141cb5caa98Sdjl 142cb5caa98Sdjl return (NSCD_SUCCESS); 143cb5caa98Sdjl } 144cb5caa98Sdjl 145cb5caa98Sdjl /* ARGSUSED */ 146cb5caa98Sdjl nscd_rc_t 147cb5caa98Sdjl _nscd_cfg_switch_verify( 148cb5caa98Sdjl void *data, 149cb5caa98Sdjl struct nscd_cfg_param_desc *pdesc, 150cb5caa98Sdjl nscd_cfg_id_t *nswdb, 151cb5caa98Sdjl nscd_cfg_flag_t dflag, 152cb5caa98Sdjl nscd_cfg_error_t **errorp, 153cb5caa98Sdjl void **cookie) 154cb5caa98Sdjl { 155cb5caa98Sdjl char *me = "_nscd_cfg_switch_verify"; 156cb5caa98Sdjl nscd_cfg_switch_t *cfg; 157cb5caa98Sdjl char *nswcfgstr; 158cb5caa98Sdjl int size; 159cb5caa98Sdjl struct __nsw_switchconfig_v1 *switchcfg = NULL; 160cb5caa98Sdjl enum __nsw_parse_err err; 161cb5caa98Sdjl nsw_cfg_cookie_t *ck; 162cb5caa98Sdjl char buf[MAX_NSSWITCH_CONFIG_STRING_SZ]; 163cb5caa98Sdjl char msg[NSCD_CFG_MAX_ERR_MSG_LEN]; 164cb5caa98Sdjl 165cb5caa98Sdjl /* 166cb5caa98Sdjl * global config data has nothing special to verify 167cb5caa98Sdjl */ 168cb5caa98Sdjl if (_nscd_cfg_flag_is_set(pdesc->pflag, NSCD_CFG_PFLAG_GLOBAL)) 169cb5caa98Sdjl return (NSCD_SUCCESS); 170cb5caa98Sdjl 171cb5caa98Sdjl *cookie = NULL; 172cb5caa98Sdjl 173cb5caa98Sdjl /* 174cb5caa98Sdjl * switch policy string is the one to parse and verify 175cb5caa98Sdjl */ 176cb5caa98Sdjl 177cb5caa98Sdjl if (_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_INIT) || 178cb5caa98Sdjl _nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_GROUP)) { 179cb5caa98Sdjl 180cb5caa98Sdjl /* get it from the group data */ 181cb5caa98Sdjl cfg = (nscd_cfg_switch_t *)data; 182cb5caa98Sdjl nswcfgstr = cfg->nsw_config_string; 183cb5caa98Sdjl } else { 184cb5caa98Sdjl /* not group, and not the switch policy string, return */ 185cb5caa98Sdjl if (pdesc->p_offset != offsetof(nscd_cfg_switch_t, 186cb5caa98Sdjl nsw_config_string)) 187cb5caa98Sdjl return (NSCD_SUCCESS); 188cb5caa98Sdjl 189cb5caa98Sdjl /* the data itself is the string */ 190cb5caa98Sdjl nswcfgstr = (char *)data; 191cb5caa98Sdjl } 192cb5caa98Sdjl 193cb5caa98Sdjl /* 194cb5caa98Sdjl * convert the string into struct __nsw_switchconfig_v1 195cb5caa98Sdjl */ 196cb5caa98Sdjl size = MAX_NSSWITCH_CONFIG_STRING_SZ; 197cb5caa98Sdjl if (strlcpy(buf, nswcfgstr, size) >= size) { 198cb5caa98Sdjl 199cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 200cb5caa98Sdjl gettext("switch policy string too long (\"%s : %s\" > %d)"), 201cb5caa98Sdjl nswdb->name, nswcfgstr, size); 202cb5caa98Sdjl 203cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 204cb5caa98Sdjl (me, "%s\n", msg); 205cb5caa98Sdjl 206cb5caa98Sdjl if (*errorp) 207cb5caa98Sdjl *errorp = _nscd_cfg_make_error( 208cb5caa98Sdjl NSCD_CFG_SYNTAX_ERROR, msg); 209cb5caa98Sdjl 210cb5caa98Sdjl return (NSCD_CFG_SYNTAX_ERROR); 211cb5caa98Sdjl } 212cb5caa98Sdjl switchcfg = _nsw_getoneconfig_v1(nswdb->name, buf, &err); 213cb5caa98Sdjl if (switchcfg == NULL) { 214cb5caa98Sdjl 215cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 216cb5caa98Sdjl gettext("syntax error: switch policy string (%s : %s) rc = %d"), 217cb5caa98Sdjl nswdb->name, nswcfgstr, err); 218cb5caa98Sdjl 219cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 220cb5caa98Sdjl (me, "%s\n", msg); 221cb5caa98Sdjl 222cb5caa98Sdjl if (*errorp) 223cb5caa98Sdjl *errorp = _nscd_cfg_make_error( 224cb5caa98Sdjl NSCD_CFG_SYNTAX_ERROR, msg); 225cb5caa98Sdjl 226cb5caa98Sdjl return (NSCD_CFG_SYNTAX_ERROR); 227cb5caa98Sdjl } 228cb5caa98Sdjl 229cb5caa98Sdjl /* save the __nsw_switchconfig_v1 for the notify function */ 230cb5caa98Sdjl ck = calloc(1, sizeof (nsw_cfg_cookie_t)); 231cb5caa98Sdjl if (ck == NULL) { 232cb5caa98Sdjl (void) __nsw_freeconfig_v1(switchcfg); 233cb5caa98Sdjl return (NSCD_CFG_SYNTAX_ERROR); 234cb5caa98Sdjl } 235cb5caa98Sdjl ck->cfg = switchcfg; 236cb5caa98Sdjl ck->cfgstr = nswcfgstr; 237cb5caa98Sdjl *cookie = ck; 238cb5caa98Sdjl 239cb5caa98Sdjl return (NSCD_SUCCESS); 240cb5caa98Sdjl } 241cb5caa98Sdjl 242cb5caa98Sdjl /* ARGSUSED */ 243cb5caa98Sdjl nscd_rc_t 244cb5caa98Sdjl _nscd_cfg_switch_get_stat( 245cb5caa98Sdjl void **stat, 246cb5caa98Sdjl struct nscd_cfg_stat_desc *sdesc, 247cb5caa98Sdjl nscd_cfg_id_t *nswdb, 248cb5caa98Sdjl nscd_cfg_flag_t *dflag, 249cb5caa98Sdjl void (**free_stat)(void *stat), 250cb5caa98Sdjl nscd_cfg_error_t **errorp) 251cb5caa98Sdjl { 252cb5caa98Sdjl 253cb5caa98Sdjl if (_nscd_cfg_flag_is_set(sdesc->sflag, NSCD_CFG_SFLAG_GLOBAL)) { 254cb5caa98Sdjl *stat = &NSCD_SW_STATS_G; 255cb5caa98Sdjl } else 256cb5caa98Sdjl *stat = &NSCD_SW_STATS(nswdb->index); 257cb5caa98Sdjl 258cb5caa98Sdjl /* indicate the statistics are static, i.e., do not free */ 259cb5caa98Sdjl *dflag = _nscd_cfg_flag_set(*dflag, NSCD_CFG_DFLAG_STATIC_DATA); 260cb5caa98Sdjl 261cb5caa98Sdjl return (NSCD_SUCCESS); 262cb5caa98Sdjl } 263