]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/ofed/libsdp/src/log.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / ofed / libsdp / src / log.c
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
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
113 __sdp_log_get_level(
114         void )
115 {
116         return ( __sdp_min_level );
117 }
118
119 void
120 __sdp_log_set_min_level(
121         int level )
122 {
123         __sdp_min_level = level;
124 }
125
126 static void
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
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
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
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 }