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