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