xref: /NextBSD/contrib/ofed/libsdp/src/log.c (revision eb1a5f8de9f7ea602c373a710f531abbf81141c4)
1 /*
2   This software is available to you under a choice of one of two
3   licenses.  You may choose to be licensed under the terms of the GNU
4   General Public License (GPL) Version 2, available at
5   <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6   license, available in the LICENSE.TXT file accompanying this
7   software.  These details are also available at
8   <http://openib.org/license.html>.
9 
10   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   SOFTWARE.
18 
19   Copyright (c) 2004 Topspin Communications.  All rights reserved.
20   Copyright (c) 2006 Mellanox Technologies Ltd. All rights reserved.
21 
22   $Id$
23 */
24 
25 /*
26  * system includes
27  */
28 #if HAVE_CONFIG_H
29 #  include <config.h>
30 #endif /* HAVE_CONFIG_H */
31 #include <unistd.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <errno.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdarg.h>
38 #include <string.h>
39 #include <syslog.h>
40 #include <time.h>
41 #include <limits.h>
42 
43 /*
44  * SDP specific includes
45  */
46 #include "libsdp.h"
47 
48 extern char *program_invocation_short_name;
49 
50 typedef enum
51 {
52 	SDP_LOG_FILE,
53 	SDP_LOG_SYSLOG,
54 } __sdp_log_type_t;
55 
56 /* --------------------------------------------------------------------- */
57 /* library static and global variables                                   */
58 /* --------------------------------------------------------------------- */
59 int __sdp_min_level = 9;
60 static __sdp_log_type_t __sdp_log_type = SDP_LOG_FILE;
61 static FILE *__sdp_log_file = NULL;
62 
63 void
__sdp_log(int level,char * format,...)64 __sdp_log(
65 	int level,
66 	char *format,
67 	... )
68 {
69 	va_list ap;
70 	char extra_format[512];
71 	time_t timeval;
72 	char timestr[32];
73 
74 	if ( level < __sdp_min_level ) {
75 		return;
76 	}
77 
78 	va_start( ap, format );
79 	switch ( __sdp_log_type ) {
80 	case SDP_LOG_SYSLOG:
81 		sprintf( extra_format, "%s[%d] libsdp %s ",
82 					program_invocation_short_name, getpid(  ), format );
83 		vsyslog( LOG_USER | LOG_NOTICE, extra_format, ap );
84 		break;
85 	case SDP_LOG_FILE:
86 		timeval = time(NULL);
87 #ifdef SOLARIS_BUILD
88 		ctime_r(&timeval, timestr, sizeof timestr);
89 #else
90                 ctime_r(&timeval, timestr);
91 #endif
92 		timestr[strlen(timestr)-1] = '\0';
93 		sprintf( extra_format, "%s %s[%d] libsdp %s ",
94 					timestr, program_invocation_short_name,
95 					getpid(  ), format );
96 		if ( __sdp_log_file == NULL ) {
97 			vfprintf( stderr, extra_format, ap );
98 #if 0									  /* might slow everything too much? */
99 			( void )fflush( stderr );
100 #endif
101 		} else {
102 			vfprintf( __sdp_log_file, extra_format, ap );
103 #if 0									  /* might slow everything too much? */
104 			( void )fflush( __sdp_log_file );
105 #endif
106 		}
107 		break;
108 	}
109 	va_end( ap );
110 }
111 
112 int
__sdp_log_get_level(void)113 __sdp_log_get_level(
114 	void )
115 {
116 	return ( __sdp_min_level );
117 }
118 
119 void
__sdp_log_set_min_level(int level)120 __sdp_log_set_min_level(
121 	int level )
122 {
123 	__sdp_min_level = level;
124 }
125 
126 static void
__sdp_log_set_log_type(__sdp_log_type_t type)127 __sdp_log_set_log_type(
128 	__sdp_log_type_t type )
129 {
130 	if ( __sdp_log_file != NULL ) {
131 		fclose( __sdp_log_file );
132 		__sdp_log_file = NULL;
133 	}
134 
135 	__sdp_log_type = type;
136 }
137 
138 int
__sdp_log_set_log_stderr(void)139 __sdp_log_set_log_stderr(
140 	void )
141 {
142 	__sdp_log_set_log_type( SDP_LOG_FILE );
143 	/* NULL means stderr */
144 
145 	return 1;
146 }
147 
148 int
__sdp_log_set_log_syslog(void)149 __sdp_log_set_log_syslog(
150 	void )
151 {
152 	__sdp_log_set_log_type( SDP_LOG_SYSLOG );
153 
154 	return 1;
155 }
156 
157 int
__sdp_log_set_log_file(char * filename)158 __sdp_log_set_log_file(
159 	char *filename )
160 {
161 	FILE *f;
162 	uid_t uid;
163 	struct stat lstat_res;
164 	int status;
165 
166 	char *p, tfilename[PATH_MAX + 1];
167 
168 	/* Strip off any paths from the filename */
169 	p = strrchr( filename, '/' );
170 
171 	/*
172 		base on the active user ID we either use /var/log for root or
173 		append the uid to the name
174 	*/
175 	uid = geteuid();
176 	if (uid == 0) {
177 		if ( p )
178 			filename = p + 1;
179 		snprintf( tfilename, sizeof(tfilename), "/var/log/%s", filename );
180 	} else {
181 		char tdir[PATH_MAX + 1];
182 		/*
183 			for regular user, allow log file to be placed in a user
184 			requested path. If no path is requested the log file is
185 			placed in /tmp/
186 		*/
187 		if ( p )
188 			snprintf(tdir, sizeof(tdir), "%s.%d", filename, uid );
189 		else
190 			snprintf(tdir, sizeof(tdir ), "/tmp/%s.%d", filename, uid );
191 
192 		if (mkdir(tdir, 0700)) {
193 			struct stat stat;
194 
195 			if (errno != EEXIST) {
196 				__sdp_log( 9, "Couldn't create directory '%s' for logging (%m)\n", tdir );
197 				return 0;
198 			}
199 
200 			if (lstat(tdir, &stat)) {
201 				__sdp_log(9, "Couldn't lstat directory %s\n", tdir);
202 				return 0;
203 			}
204 
205 			if (!S_ISDIR(stat.st_mode) || stat.st_uid != uid ||
206 					(stat.st_mode & ~(S_IFMT | S_IRWXU))) {
207 				__sdp_log( 9, "Cowardly refusing to log into directory:'%s'. "
208 					  "Make sure it is not: (1) link, (2) other uid, (3) bad permissions."
209 					  "thus is a security issue.\n", tdir );
210 				return 0;
211 			}
212 		}
213 
214 		snprintf(tfilename, sizeof(tfilename), "%s/log", tdir);
215 		printf("dir: %s file: %s\n", tdir, tfilename);
216 	}
217 
218 	/* double check the file is not a link */
219 	status = lstat(tfilename, &lstat_res);
220 	if ( (status == 0) && S_ISLNK(lstat_res.st_mode) ) {
221 		__sdp_log( 9, "Cowardly refusing to log into:'%s'. "
222 					  "It is a link - thus is a security issue.\n", tfilename );
223 		return 0;
224 	}
225 
226 	f = fopen( tfilename, "a" );
227 	if ( !f ) {
228 		__sdp_log( 9, "Couldn't open '%s' for logging (%m)\n", tfilename );
229 		return 0;
230 	}
231 
232 	__sdp_log_set_log_type( SDP_LOG_FILE );
233 	__sdp_log_file = f;
234 
235 	return 1;
236 }
237