xref: /illumos-gate/usr/src/cmd/nscd/nscd_log.c (revision cb5caa98562cf06753163f558cbcfe30b8f4673a)
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