1 /*
2 * (c) Copyright 1992 by Panagiotis Tsirigotis
3 * (c) Sections Copyright 1998-2001 by Rob Braun
4 * All rights reserved. The file named COPYRIGHT specifies the terms
5 * and conditions for redistribution.
6 */
7
8 #include "config.h"
9 #include <stdlib.h>
10 #include <sys/types.h>
11 #include <sys/socket.h>
12 #include <sys/wait.h>
13 #include <syslog.h>
14 #include <time.h>
15 #include <stdio.h>
16 #include <stdarg.h>
17 #ifdef HAVE_NETDB_H
18 #include <netdb.h>
19 #endif
20
21 #include "str.h"
22 #include "log.h"
23 #include "sconf.h"
24 #include "sconst.h"
25 #include "msg.h"
26
27
28 #define LOGBUF_SIZE 1024
29
30 static char ipv6_ret[NI_MAXHOST];
31
xaddrname(const union xsockaddr * inaddr)32 const char *xaddrname(const union xsockaddr *inaddr)
33 {
34 unsigned int len = 0;
35 if( inaddr->sa.sa_family == AF_INET ) len = sizeof(struct sockaddr_in);
36 if( inaddr->sa.sa_family == AF_INET6 ) len = sizeof(struct sockaddr_in6);
37 memset(ipv6_ret, 0, sizeof(ipv6_ret));
38 if( getnameinfo(&inaddr->sa, len, ipv6_ret, sizeof(ipv6_ret), NULL,
39 0, NI_NUMERICHOST) )
40 strncpy(ipv6_ret, "<unknown>", NI_MAXHOST);
41 return ipv6_ret;
42 }
43
xaddrport(const union xsockaddr * inaddr)44 uint16_t xaddrport(const union xsockaddr *inaddr)
45 {
46 if( inaddr->sa.sa_family == AF_INET ) return inaddr->sa_in.sin_port;
47 if( inaddr->sa.sa_family == AF_INET6 ) return inaddr->sa_in6.sin6_port;
48 return 0;
49 }
50
51 static int log_common(mask_t *, char *, int, const connection_s *) ;
52
53 /*
54 * This function writes log records of the form:
55 *
56 * START: service [pid] [from_address]
57 */
svc_log_success(struct service * sp,const connection_s * cp,pid_t pid)58 void svc_log_success( struct service *sp, const connection_s *cp, pid_t pid )
59 {
60 char buf[ LOGBUF_SIZE ] ;
61 int bufsize ;
62 struct service_config *scp = SVC_CONF( sp ) ;
63 int len ;
64 int cc ;
65
66 if ( ! SVC_LOGS_ON_SUCCESS( sp ) )
67 return ;
68
69 bufsize = sizeof( buf ) ;
70 len = 0 ;
71
72 cc = strx_nprint( buf, bufsize, "%s: %s", START_ENTRY, SC_ID( scp ) ) ;
73 len += cc ;
74 bufsize -= cc ;
75
76 if ( SC_LOGS_PID( scp ) )
77 {
78 cc = strx_nprint( &buf[ len ], bufsize, " pid=%d", pid ) ;
79 len += cc ;
80 bufsize -= cc ;
81 }
82
83 cc = log_common( &SC_LOG_ON_SUCCESS( scp ), &buf[len], bufsize, cp ) ;
84 len += cc ;
85 bufsize -= cc ;
86
87 xlog_write( SVC_LOG(sp), buf, len, XLOG_NO_ERRNO ) ;
88 }
89
90
91 /*
92 * This function writes log records of the form:
93 *
94 * FAIL: service failure-type [from_address]
95 *
96 */
svc_log_failure(struct service * sp,const connection_s * cp,access_e access_failure)97 void svc_log_failure( struct service *sp,
98 const connection_s *cp,
99 access_e access_failure )
100 {
101 char buf[ LOGBUF_SIZE ] ;
102 int bufsize ;
103 struct service_config *scp = SVC_CONF( sp ) ;
104 int len = 0 ;
105 int cc ;
106
107 if ( ! SVC_LOGS_ON_FAILURE( sp ) )
108 return ;
109
110 bufsize = sizeof( buf ) ;
111 cc = strx_nprint( buf, bufsize, "%s: %s", FAIL_ENTRY, SC_ID( scp ) ) ;
112 len += cc ;
113 bufsize -= cc ;
114
115 cc = strx_nprint( &buf[ len ], bufsize,
116 " %s", ACCESS_EXPLAIN( access_failure ) ) ;
117 len += cc ;
118 bufsize -= cc ;
119
120 cc = log_common( &SC_LOG_ON_FAILURE( scp ), &buf[ len ], bufsize, cp ) ;
121 len += cc ;
122 bufsize -= cc ;
123
124 xlog_write( SVC_LOG(sp), buf, len, XLOG_NO_ERRNO ) ;
125 }
126
127
128
log_common(mask_t * logmask,char * buf,int bufsize,const connection_s * cp)129 static int log_common( mask_t *logmask,
130 char *buf,
131 int bufsize,
132 const connection_s *cp )
133 {
134 int len = 0 ;
135
136 if ( M_IS_SET( *logmask, LO_HOST ) )
137 len = strx_nprint( buf, bufsize, " from=%s", conn_addrstr( cp ) ) ;
138 return( len ) ;
139 }
140
141
svc_log_exit(struct service * sp,const struct server * serp)142 void svc_log_exit( struct service *sp, const struct server *serp )
143 {
144 char buf[ LOGBUF_SIZE ] ;
145 int bufsize ;
146 int cc ;
147 int len ;
148 int exit_status = SERVER_EXITSTATUS( serp ) ;
149 struct service_config *scp = SVC_CONF( sp ) ;
150 const char *func = "log_exit" ;
151
152 if ( ! SVC_LOGS_ON_EXIT( sp ) )
153 return ;
154
155 bufsize = sizeof( buf ) ;
156 len = 0 ;
157
158 cc = strx_nprint( buf, bufsize, "%s: %s", EXIT_ENTRY, SC_ID( scp ) ) ;
159 bufsize -= cc ;
160 len += cc ;
161
162 /*
163 * If the EXIT flag was used, log the exit status or the signal that
164 * killed the process. We assume that these are the only reasons
165 * for process termination.
166 */
167 if ( SC_LOGS_EXITS( scp ) )
168 {
169 int num = 0;
170 const char *s ;
171
172 if ( PROC_EXITED( exit_status ) )
173 {
174 s = "status" ;
175 num = PROC_EXITSTATUS( exit_status ) ;
176 }
177 else if ( PROC_SIGNALED( exit_status ) )
178 {
179 s = "signal" ;
180 num = PROC_TERMSIG( exit_status ) ;
181 }
182 else
183 {
184 msg( LOG_ERR, func, "Bad exit status" ) ;
185 s = NULL ;
186 }
187
188 if ( s )
189 {
190 cc = strx_nprint( &buf[ len ], bufsize, " %s=%d", s, num ) ;
191 len += cc ;
192 bufsize -= cc ;
193 }
194 }
195
196 if ( SC_LOGS_PID( scp ) )
197 {
198 cc = strx_nprint( &buf[ len ], bufsize, " pid=%d", SERVER_PID( serp ) ) ;
199 len += cc ;
200 bufsize -= cc ;
201 }
202
203 if ( SC_LOGS_DURATION( scp ) )
204 {
205 time_t current_time ;
206
207 (void) time( ¤t_time ) ;
208 cc = strx_nprint( &buf[ len ], bufsize, " duration=%ld(sec)",
209 (long)(current_time - SERVER_STARTTIME( serp )) ) ;
210 len += cc ;
211 bufsize -= cc ;
212 }
213 xlog_write( SVC_LOG(sp), buf, len, XLOG_NO_ERRNO ) ;
214 }
215
216
217
218 /*
219 * Used by other parts of xinetd that want to log something without
220 * going through the proper channels (i.e. log_{success,failure} and log_exit)
221 */
222 /* VARARGS3 */
svc_logprint(struct service * sp,const char * line_id,const char * fmt,...)223 void svc_logprint( struct service *sp, const char *line_id,
224 const char *fmt, ...)
225 {
226 char buf[ LOGBUF_SIZE ] ;
227 int bufsize = sizeof( buf ) ;
228 int len ;
229 int cc ;
230 va_list ap ;
231
232 if ( ! SVC_IS_LOGGING( sp ) )
233 return ;
234
235 len = strx_nprint( buf, bufsize, "%s: %s ", line_id, SVC_ID( sp ) ) ;
236 va_start( ap, fmt ) ;
237 cc = strx_nprintv( &buf[ len ], bufsize-len, fmt, ap ) ;
238 va_end( ap ) ;
239 xlog_write( SVC_LOG(sp), buf, len+cc, XLOG_NO_ERRNO | XLOG_NO_SIZECHECK ) ;
240 }
241
242