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 <limits.h> 31*cb5caa98Sdjl #include <fcntl.h> 32*cb5caa98Sdjl #include <sys/stat.h> 33*cb5caa98Sdjl #include <sys/varargs.h> 34*cb5caa98Sdjl #include <synch.h> 35*cb5caa98Sdjl #include <thread.h> 36*cb5caa98Sdjl #include <string.h> 37*cb5caa98Sdjl #include <unistd.h> 38*cb5caa98Sdjl #include "nscd_log.h" 39*cb5caa98Sdjl #include "nscd_config.h" 40*cb5caa98Sdjl #include "nscd_switch.h" 41*cb5caa98Sdjl #include "cache.h" 42*cb5caa98Sdjl 43*cb5caa98Sdjl /* 44*cb5caa98Sdjl * old nscd debug levels 45*cb5caa98Sdjl */ 46*cb5caa98Sdjl #define DBG_OFF 0 47*cb5caa98Sdjl #define DBG_CANT_FIND 2 48*cb5caa98Sdjl #define DBG_NETLOOKUPS 4 49*cb5caa98Sdjl #define DBG_ALL 6 50*cb5caa98Sdjl 51*cb5caa98Sdjl /* max. chars in a nscd log entry */ 52*cb5caa98Sdjl #define LOGBUFLEN 1024 53*cb5caa98Sdjl 54*cb5caa98Sdjl /* configuration for the nscd log component */ 55*cb5caa98Sdjl int _nscd_log_comp = 0x0; 56*cb5caa98Sdjl int _nscd_log_level = 0x0; 57*cb5caa98Sdjl static char logfile[PATH_MAX]; 58*cb5caa98Sdjl 59*cb5caa98Sdjl /* statistics data */ 60*cb5caa98Sdjl static nscd_cfg_stat_global_log_t logstats = { 61*cb5caa98Sdjl NSCD_CFG_STAT_GROUP_INFO_GLOBAL_LOG, 0 }; 62*cb5caa98Sdjl 63*cb5caa98Sdjl /* if no log file specified, log entry goes to stderr */ 64*cb5caa98Sdjl int _logfd = 2; 65*cb5caa98Sdjl 66*cb5caa98Sdjl /* close old log file and open a new one */ 67*cb5caa98Sdjl static nscd_rc_t 68*cb5caa98Sdjl _nscd_set_lf( 69*cb5caa98Sdjl char *lf) 70*cb5caa98Sdjl { 71*cb5caa98Sdjl int newlogfd; 72*cb5caa98Sdjl char *me = "_nscd_set_lf"; 73*cb5caa98Sdjl 74*cb5caa98Sdjl /* 75*cb5caa98Sdjl * don't try and open the log file /dev/null 76*cb5caa98Sdjl */ 77*cb5caa98Sdjl if (lf == NULL || *lf == 0) { 78*cb5caa98Sdjl /* ignore empty log file specs */ 79*cb5caa98Sdjl return (NSCD_SUCCESS); 80*cb5caa98Sdjl } else if (strcmp(lf, "/dev/null") == 0) { 81*cb5caa98Sdjl (void) strlcpy(logfile, lf, PATH_MAX); 82*cb5caa98Sdjl if (_logfd >= 0) 83*cb5caa98Sdjl (void) close(_logfd); 84*cb5caa98Sdjl _logfd = -1; 85*cb5caa98Sdjl return (NSCD_SUCCESS); 86*cb5caa98Sdjl } else if (strcmp(lf, "stderr") == 0) { 87*cb5caa98Sdjl (void) strlcpy(logfile, lf, PATH_MAX); 88*cb5caa98Sdjl if (_logfd != -1 && _logfd != 2) 89*cb5caa98Sdjl (void) close(_logfd); 90*cb5caa98Sdjl _logfd = 2; 91*cb5caa98Sdjl return (NSCD_SUCCESS); 92*cb5caa98Sdjl } else { 93*cb5caa98Sdjl 94*cb5caa98Sdjl /* 95*cb5caa98Sdjl * In order to open this file securely, we'll try a few tricks 96*cb5caa98Sdjl */ 97*cb5caa98Sdjl 98*cb5caa98Sdjl if ((newlogfd = open(lf, O_EXCL|O_WRONLY|O_CREAT, 0644)) < 0) { 99*cb5caa98Sdjl /* 100*cb5caa98Sdjl * File already exists... now we need to get cute 101*cb5caa98Sdjl * since opening a file in a world-writeable directory 102*cb5caa98Sdjl * safely is hard = it could be a hard link or a 103*cb5caa98Sdjl * symbolic link to a system file. 104*cb5caa98Sdjl */ 105*cb5caa98Sdjl struct stat before; 106*cb5caa98Sdjl 107*cb5caa98Sdjl if (lstat(lf, &before) < 0) { 108*cb5caa98Sdjl _nscd_logit(me, "Cannot open new " 109*cb5caa98Sdjl "logfile \"%s\": %sn", lf, strerror(errno)); 110*cb5caa98Sdjl return (NSCD_CFG_FILE_OPEN_ERROR); 111*cb5caa98Sdjl } 112*cb5caa98Sdjl 113*cb5caa98Sdjl if (S_ISREG(before.st_mode) && /* no symbolic links */ 114*cb5caa98Sdjl (before.st_nlink == 1) && /* no hard links */ 115*cb5caa98Sdjl (before.st_uid == 0)) { /* owned by root */ 116*cb5caa98Sdjl if ((newlogfd = 117*cb5caa98Sdjl open(lf, O_APPEND|O_WRONLY, 0644)) < 0) { 118*cb5caa98Sdjl _nscd_logit(me, "Cannot open new "\ 119*cb5caa98Sdjl "logfile \"%s\": %s\n", lf, 120*cb5caa98Sdjl strerror(errno)); 121*cb5caa98Sdjl return (NSCD_CFG_FILE_OPEN_ERROR); 122*cb5caa98Sdjl } 123*cb5caa98Sdjl } else { 124*cb5caa98Sdjl _nscd_logit(me, "Cannot use specified " 125*cb5caa98Sdjl "logfile \"%s\": "\ 126*cb5caa98Sdjl "file is/has links or isn't owned by "\ 127*cb5caa98Sdjl "root\n", lf); 128*cb5caa98Sdjl return (NSCD_CFG_FILE_OPEN_ERROR); 129*cb5caa98Sdjl } 130*cb5caa98Sdjl } 131*cb5caa98Sdjl 132*cb5caa98Sdjl (void) close(_logfd); 133*cb5caa98Sdjl (void) strlcpy(logfile, lf, PATH_MAX); 134*cb5caa98Sdjl _logfd = newlogfd; 135*cb5caa98Sdjl _nscd_logit(me, "Start of new logfile %s\n", lf); 136*cb5caa98Sdjl } 137*cb5caa98Sdjl return (NSCD_SUCCESS); 138*cb5caa98Sdjl } 139*cb5caa98Sdjl 140*cb5caa98Sdjl 141*cb5caa98Sdjl /* log an entry to the configured nscd log file */ 142*cb5caa98Sdjl void 143*cb5caa98Sdjl _nscd_logit( 144*cb5caa98Sdjl char *funcname, 145*cb5caa98Sdjl char *format, 146*cb5caa98Sdjl ...) 147*cb5caa98Sdjl { 148*cb5caa98Sdjl static mutex_t loglock = DEFAULTMUTEX; 149*cb5caa98Sdjl struct timeval tv; 150*cb5caa98Sdjl char tid_buf[32]; 151*cb5caa98Sdjl char pid_buf[32]; 152*cb5caa98Sdjl char buffer[LOGBUFLEN]; 153*cb5caa98Sdjl int safechars, offset; 154*cb5caa98Sdjl va_list ap; 155*cb5caa98Sdjl 156*cb5caa98Sdjl if (_logfd < 0) 157*cb5caa98Sdjl return; 158*cb5caa98Sdjl 159*cb5caa98Sdjl va_start(ap, format); 160*cb5caa98Sdjl 161*cb5caa98Sdjl if (gettimeofday(&tv, NULL) != 0 || 162*cb5caa98Sdjl ctime_r(&tv.tv_sec, buffer, LOGBUFLEN) == NULL) { 163*cb5caa98Sdjl (void) snprintf(buffer, LOGBUFLEN, 164*cb5caa98Sdjl "<time conversion failed>\t"); 165*cb5caa98Sdjl } else { 166*cb5caa98Sdjl (void) sprintf(tid_buf, "--%d", thr_self()); 167*cb5caa98Sdjl (void) sprintf(pid_buf, "--%ld", getpid()); 168*cb5caa98Sdjl /* 169*cb5caa98Sdjl * ctime_r() includes some stuff we don't want; 170*cb5caa98Sdjl * adjust length to overwrite " YYYY\n" and 171*cb5caa98Sdjl * include tid string length. 172*cb5caa98Sdjl */ 173*cb5caa98Sdjl offset = strlen(buffer) - 6; 174*cb5caa98Sdjl safechars = LOGBUFLEN - (offset - 1); 175*cb5caa98Sdjl (void) snprintf(buffer + offset, 176*cb5caa98Sdjl safechars, ".%.4ld%s%s\t%s:\n\t\t", 177*cb5caa98Sdjl tv.tv_usec/100, tid_buf, pid_buf, 178*cb5caa98Sdjl funcname); 179*cb5caa98Sdjl } 180*cb5caa98Sdjl offset = strlen(buffer); 181*cb5caa98Sdjl safechars = LOGBUFLEN - (offset - 1); 182*cb5caa98Sdjl /*LINTED: E_SEC_PRINTF_VAR_FMT*/ 183*cb5caa98Sdjl if (vsnprintf(buffer + offset, safechars, format, ap) > 184*cb5caa98Sdjl safechars) { 185*cb5caa98Sdjl (void) strncat(buffer, "...\n", LOGBUFLEN); 186*cb5caa98Sdjl } 187*cb5caa98Sdjl 188*cb5caa98Sdjl (void) mutex_lock(&loglock); 189*cb5caa98Sdjl (void) write(_logfd, buffer, strlen(buffer)); 190*cb5caa98Sdjl logstats.entries_logged++; 191*cb5caa98Sdjl (void) mutex_unlock(&loglock); 192*cb5caa98Sdjl 193*cb5caa98Sdjl va_end(ap); 194*cb5caa98Sdjl } 195*cb5caa98Sdjl 196*cb5caa98Sdjl 197*cb5caa98Sdjl /* ARGSUSED */ 198*cb5caa98Sdjl nscd_rc_t 199*cb5caa98Sdjl _nscd_cfg_log_notify( 200*cb5caa98Sdjl void *data, 201*cb5caa98Sdjl struct nscd_cfg_param_desc *pdesc, 202*cb5caa98Sdjl nscd_cfg_id_t *nswdb, 203*cb5caa98Sdjl nscd_cfg_flag_t dflag, 204*cb5caa98Sdjl nscd_cfg_error_t **errorp, 205*cb5caa98Sdjl void *cookie) 206*cb5caa98Sdjl { 207*cb5caa98Sdjl 208*cb5caa98Sdjl nscd_cfg_global_log_t *logcfg; 209*cb5caa98Sdjl int off; 210*cb5caa98Sdjl 211*cb5caa98Sdjl /* 212*cb5caa98Sdjl * At init time, the whole group of config params are received. 213*cb5caa98Sdjl * At update time, group or individual parameter value could 214*cb5caa98Sdjl * be received. 215*cb5caa98Sdjl */ 216*cb5caa98Sdjl 217*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_GROUP)) { 218*cb5caa98Sdjl 219*cb5caa98Sdjl logcfg = (nscd_cfg_global_log_t *)data; 220*cb5caa98Sdjl 221*cb5caa98Sdjl _nscd_log_comp = logcfg->debug_comp; 222*cb5caa98Sdjl _nscd_log_level = logcfg->debug_level; 223*cb5caa98Sdjl 224*cb5caa98Sdjl /* 225*cb5caa98Sdjl * logcfg->logfile should have been opened 226*cb5caa98Sdjl * by _nscd_cfg_log_verify() 227*cb5caa98Sdjl */ 228*cb5caa98Sdjl 229*cb5caa98Sdjl return (NSCD_SUCCESS); 230*cb5caa98Sdjl } 231*cb5caa98Sdjl 232*cb5caa98Sdjl /* 233*cb5caa98Sdjl * individual config parameter 234*cb5caa98Sdjl */ 235*cb5caa98Sdjl off = offsetof(nscd_cfg_global_log_t, debug_comp); 236*cb5caa98Sdjl if (pdesc->p_offset == off) { 237*cb5caa98Sdjl _nscd_log_comp = *(nscd_cfg_bitmap_t *)data; 238*cb5caa98Sdjl return (NSCD_SUCCESS); 239*cb5caa98Sdjl } 240*cb5caa98Sdjl 241*cb5caa98Sdjl off = offsetof(nscd_cfg_global_log_t, debug_level); 242*cb5caa98Sdjl if (pdesc->p_offset == off) 243*cb5caa98Sdjl _nscd_log_level = *(nscd_cfg_bitmap_t *)data; 244*cb5caa98Sdjl 245*cb5caa98Sdjl /* 246*cb5caa98Sdjl * logcfg->logfile should have been opened 247*cb5caa98Sdjl * by _nscd_cfg_log_verify() 248*cb5caa98Sdjl */ 249*cb5caa98Sdjl 250*cb5caa98Sdjl return (NSCD_SUCCESS); 251*cb5caa98Sdjl } 252*cb5caa98Sdjl 253*cb5caa98Sdjl /* ARGSUSED */ 254*cb5caa98Sdjl nscd_rc_t 255*cb5caa98Sdjl _nscd_cfg_log_verify( 256*cb5caa98Sdjl void *data, 257*cb5caa98Sdjl struct nscd_cfg_param_desc *pdesc, 258*cb5caa98Sdjl nscd_cfg_id_t *nswdb, 259*cb5caa98Sdjl nscd_cfg_flag_t dflag, 260*cb5caa98Sdjl nscd_cfg_error_t **errorp, 261*cb5caa98Sdjl void **cookie) 262*cb5caa98Sdjl { 263*cb5caa98Sdjl nscd_cfg_global_log_t *logcfg; 264*cb5caa98Sdjl nscd_cfg_bitmap_t bt; 265*cb5caa98Sdjl int off; 266*cb5caa98Sdjl 267*cb5caa98Sdjl /* 268*cb5caa98Sdjl * There is no switch db specific config params 269*cb5caa98Sdjl * for the nscd log component. It is a bug if 270*cb5caa98Sdjl * the input param description is global. 271*cb5caa98Sdjl */ 272*cb5caa98Sdjl if (_nscd_cfg_flag_is_not_set(pdesc->pflag, NSCD_CFG_PFLAG_GLOBAL)) 273*cb5caa98Sdjl return (NSCD_CFG_PARAM_DESC_ERROR); 274*cb5caa98Sdjl 275*cb5caa98Sdjl /* 276*cb5caa98Sdjl * At init time, the whole group of config params are received. 277*cb5caa98Sdjl * At update time, group or individual parameter value could 278*cb5caa98Sdjl * be received. 279*cb5caa98Sdjl */ 280*cb5caa98Sdjl 281*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_GROUP)) { 282*cb5caa98Sdjl 283*cb5caa98Sdjl logcfg = (nscd_cfg_global_log_t *)data; 284*cb5caa98Sdjl 285*cb5caa98Sdjl if (_nscd_cfg_bitmap_valid(logcfg->debug_comp, 286*cb5caa98Sdjl NSCD_LOG_ALL) == 0) 287*cb5caa98Sdjl return (NSCD_CFG_SYNTAX_ERROR); 288*cb5caa98Sdjl 289*cb5caa98Sdjl if (_nscd_cfg_bitmap_valid(logcfg->debug_level, 290*cb5caa98Sdjl NSCD_LOG_LEVEL_ALL) == 0) 291*cb5caa98Sdjl return (NSCD_CFG_SYNTAX_ERROR); 292*cb5caa98Sdjl 293*cb5caa98Sdjl if (logcfg->logfile != NULL) 294*cb5caa98Sdjl return (_nscd_set_lf(logcfg->logfile)); 295*cb5caa98Sdjl 296*cb5caa98Sdjl return (NSCD_SUCCESS); 297*cb5caa98Sdjl } 298*cb5caa98Sdjl 299*cb5caa98Sdjl /* 300*cb5caa98Sdjl * individual config parameter 301*cb5caa98Sdjl */ 302*cb5caa98Sdjl 303*cb5caa98Sdjl off = offsetof(nscd_cfg_global_log_t, debug_comp); 304*cb5caa98Sdjl if (pdesc->p_offset == off) { 305*cb5caa98Sdjl 306*cb5caa98Sdjl bt = *(nscd_cfg_bitmap_t *)data; 307*cb5caa98Sdjl if (_nscd_cfg_bitmap_valid(bt, NSCD_LOG_ALL) == 0) 308*cb5caa98Sdjl return (NSCD_CFG_SYNTAX_ERROR); 309*cb5caa98Sdjl 310*cb5caa98Sdjl return (NSCD_SUCCESS); 311*cb5caa98Sdjl } 312*cb5caa98Sdjl 313*cb5caa98Sdjl off = offsetof(nscd_cfg_global_log_t, debug_level); 314*cb5caa98Sdjl if (pdesc->p_offset == off) { 315*cb5caa98Sdjl 316*cb5caa98Sdjl bt = *(nscd_cfg_bitmap_t *)data; 317*cb5caa98Sdjl if (_nscd_cfg_bitmap_valid(bt, NSCD_LOG_LEVEL_ALL) == 0) 318*cb5caa98Sdjl return (NSCD_CFG_SYNTAX_ERROR); 319*cb5caa98Sdjl 320*cb5caa98Sdjl return (NSCD_SUCCESS); 321*cb5caa98Sdjl } 322*cb5caa98Sdjl 323*cb5caa98Sdjl off = offsetof(nscd_cfg_global_log_t, logfile); 324*cb5caa98Sdjl if (pdesc->p_offset == off) { 325*cb5caa98Sdjl if (data != NULL) 326*cb5caa98Sdjl return (_nscd_set_lf((char *)data)); 327*cb5caa98Sdjl else 328*cb5caa98Sdjl return (NSCD_SUCCESS); 329*cb5caa98Sdjl } 330*cb5caa98Sdjl 331*cb5caa98Sdjl return (NSCD_CFG_PARAM_DESC_ERROR); 332*cb5caa98Sdjl } 333*cb5caa98Sdjl 334*cb5caa98Sdjl /* ARGSUSED */ 335*cb5caa98Sdjl nscd_rc_t 336*cb5caa98Sdjl _nscd_cfg_log_get_stat( 337*cb5caa98Sdjl void **stat, 338*cb5caa98Sdjl struct nscd_cfg_stat_desc *sdesc, 339*cb5caa98Sdjl nscd_cfg_id_t *nswdb, 340*cb5caa98Sdjl nscd_cfg_flag_t *dflag, 341*cb5caa98Sdjl void (**free_stat)(void *stat), 342*cb5caa98Sdjl nscd_cfg_error_t **errorp) 343*cb5caa98Sdjl { 344*cb5caa98Sdjl 345*cb5caa98Sdjl *(nscd_cfg_stat_global_log_t **)stat = &logstats; 346*cb5caa98Sdjl 347*cb5caa98Sdjl /* indicate the statistics are static, i.e., do not free */ 348*cb5caa98Sdjl *dflag = _nscd_cfg_flag_set(*dflag, NSCD_CFG_DFLAG_STATIC_DATA); 349*cb5caa98Sdjl 350*cb5caa98Sdjl return (NSCD_SUCCESS); 351*cb5caa98Sdjl } 352*cb5caa98Sdjl 353*cb5caa98Sdjl /* 354*cb5caa98Sdjl * set the name of the current log file and make it current. 355*cb5caa98Sdjl */ 356*cb5caa98Sdjl nscd_rc_t 357*cb5caa98Sdjl _nscd_set_log_file( 358*cb5caa98Sdjl char *name) 359*cb5caa98Sdjl { 360*cb5caa98Sdjl nscd_rc_t rc; 361*cb5caa98Sdjl nscd_cfg_handle_t *h; 362*cb5caa98Sdjl 363*cb5caa98Sdjl rc = _nscd_cfg_get_handle("logfile", NULL, &h, NULL); 364*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 365*cb5caa98Sdjl return (rc); 366*cb5caa98Sdjl 367*cb5caa98Sdjl rc = _nscd_cfg_set(h, name, NULL); 368*cb5caa98Sdjl _nscd_cfg_free_handle(h); 369*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 370*cb5caa98Sdjl exit(rc); 371*cb5caa98Sdjl 372*cb5caa98Sdjl return (NSCD_SUCCESS); 373*cb5caa98Sdjl } 374*cb5caa98Sdjl 375*cb5caa98Sdjl /* 376*cb5caa98Sdjl * Map old nscd debug level to new one and make it current. 377*cb5caa98Sdjl * -- debug component: NSCD_LOG_CACHE 378*cb5caa98Sdjl * -- debug level: 379*cb5caa98Sdjl * -- DBG_OFF --> NSCD_LOG_LEVEL_NONE 380*cb5caa98Sdjl * -- DBG_CANT_FIND --> NSCD_LOG_LEVEL_ERROR 381*cb5caa98Sdjl * -- DBG_DBG_NETLOOKUPS --> NSCD_LOG_LEVEL_ERROR 382*cb5caa98Sdjl * -- DBG_ALL --> NSCD_LOG_LEVEL_ALL 383*cb5caa98Sdjl */ 384*cb5caa98Sdjl nscd_rc_t 385*cb5caa98Sdjl _nscd_set_debug_level( 386*cb5caa98Sdjl int level) 387*cb5caa98Sdjl { 388*cb5caa98Sdjl nscd_rc_t rc; 389*cb5caa98Sdjl nscd_cfg_handle_t *h; 390*cb5caa98Sdjl int l; 391*cb5caa98Sdjl int c; 392*cb5caa98Sdjl 393*cb5caa98Sdjl rc = _nscd_cfg_get_handle("debug-components", NULL, &h, NULL); 394*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 395*cb5caa98Sdjl return (rc); 396*cb5caa98Sdjl c = NSCD_LOG_CACHE; 397*cb5caa98Sdjl 398*cb5caa98Sdjl if (level < 0) 399*cb5caa98Sdjl c = -1 * level / 10000; 400*cb5caa98Sdjl rc = _nscd_cfg_set(h, &c, NULL); 401*cb5caa98Sdjl _nscd_cfg_free_handle(h); 402*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 403*cb5caa98Sdjl exit(rc); 404*cb5caa98Sdjl 405*cb5caa98Sdjl rc = _nscd_cfg_get_handle("debug-level", NULL, &h, NULL); 406*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 407*cb5caa98Sdjl return (rc); 408*cb5caa98Sdjl 409*cb5caa98Sdjl if (level == DBG_OFF) 410*cb5caa98Sdjl l = NSCD_LOG_LEVEL_NONE; 411*cb5caa98Sdjl else if (level >= DBG_CANT_FIND) 412*cb5caa98Sdjl l = NSCD_LOG_LEVEL_ERROR; 413*cb5caa98Sdjl else if (level >= DBG_NETLOOKUPS) 414*cb5caa98Sdjl l = NSCD_LOG_LEVEL_ERROR; 415*cb5caa98Sdjl else if (level >= DBG_ALL) 416*cb5caa98Sdjl l = NSCD_LOG_LEVEL_ALL; 417*cb5caa98Sdjl 418*cb5caa98Sdjl if (level < 0) 419*cb5caa98Sdjl l = -1 * level % 10000; 420*cb5caa98Sdjl 421*cb5caa98Sdjl rc = _nscd_cfg_set(h, &l, NULL); 422*cb5caa98Sdjl _nscd_cfg_free_handle(h); 423*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 424*cb5caa98Sdjl exit(rc); 425*cb5caa98Sdjl 426*cb5caa98Sdjl return (NSCD_SUCCESS); 427*cb5caa98Sdjl } 428