1911106dfSjm199354 /*
2911106dfSjm199354 * CDDL HEADER START
3911106dfSjm199354 *
4911106dfSjm199354 * The contents of this file are subject to the terms of the
5911106dfSjm199354 * Common Development and Distribution License (the "License").
6911106dfSjm199354 * You may not use this file except in compliance with the License.
7911106dfSjm199354 *
8911106dfSjm199354 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9911106dfSjm199354 * or http://www.opensolaris.org/os/licensing.
10911106dfSjm199354 * See the License for the specific language governing permissions
11911106dfSjm199354 * and limitations under the License.
12911106dfSjm199354 *
13911106dfSjm199354 * When distributing Covered Code, include this CDDL HEADER in each
14911106dfSjm199354 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15911106dfSjm199354 * If applicable, add the following below this CDDL HEADER, with the
16911106dfSjm199354 * fields enclosed by brackets "[]" replaced with your own identifying
17911106dfSjm199354 * information: Portions Copyright [yyyy] [name of copyright owner]
18911106dfSjm199354 *
19911106dfSjm199354 * CDDL HEADER END
20911106dfSjm199354 */
21911106dfSjm199354 /*
2253c11029Sjm199354 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23911106dfSjm199354 * Use is subject to license terms.
24911106dfSjm199354 */
25911106dfSjm199354
26911106dfSjm199354 #pragma ident "%Z%%M% %I% %E% SMI"
27911106dfSjm199354
28911106dfSjm199354 /*
29911106dfSjm199354 * Implementation of the "scan file" interface
30911106dfSjm199354 */
31911106dfSjm199354
32911106dfSjm199354 #include <stdio.h>
33911106dfSjm199354 #include <stdlib.h>
34911106dfSjm199354 #include <unistd.h>
35911106dfSjm199354 #include <string.h>
36911106dfSjm199354 #include <errno.h>
37911106dfSjm199354 #include <syslog.h>
38911106dfSjm199354 #include <sys/types.h>
39911106dfSjm199354 #include <fcntl.h>
40911106dfSjm199354 #include <bsm/adt.h>
41911106dfSjm199354 #include <bsm/adt_event.h>
42bfc848c6Sjm199354 #include <pthread.h>
43911106dfSjm199354
44911106dfSjm199354 #include "vs_incl.h"
45911106dfSjm199354
46bfc848c6Sjm199354 /*
47bfc848c6Sjm199354 * vs_svc_nodes - table of scan requests and their thread id and
48bfc848c6Sjm199354 * scan engine context.
49bfc848c6Sjm199354 * The table is sized by the value passed to vs_svc_init. This
50bfc848c6Sjm199354 * value is obtained from the kernel and represents the maximum
51bfc848c6Sjm199354 * request idx that the kernel will request vscand to process.
52bfc848c6Sjm199354 * The table is indexed by the vsr_idx value passed in
53bfc848c6Sjm199354 * the scan request - always non-zero. This value is also the index
54bfc848c6Sjm199354 * into the kernel scan request table and identifies the instance of
55bfc848c6Sjm199354 * the driver being used to access file data for the scan. Although
56bfc848c6Sjm199354 * this is of no consequence here, it is useful information for debug.
57bfc848c6Sjm199354 *
58bfc848c6Sjm199354 * When a scan request is received a response is sent indicating
59bfc848c6Sjm199354 * one of the following:
60bfc848c6Sjm199354 * VS_STATUS_ERROR - an error occurred
61bfc848c6Sjm199354 * VS_STATUS_NO_SCAN - no scan is required
62bfc848c6Sjm199354 * VS_STATUS_SCANNING - request has been queued for async processing
63bfc848c6Sjm199354 *
64bfc848c6Sjm199354 * If the scan is required (VS_STATUS_SCANNING) a thread is created
65bfc848c6Sjm199354 * to perform the scan. It's tid is saved in vs_svc_nodes.
66bfc848c6Sjm199354 *
67bfc848c6Sjm199354 * In the case of SHUTDOWN, vs_terminate requests that all scan
68bfc848c6Sjm199354 * engine connections be closed, thus termintaing any in-progress
69bfc848c6Sjm199354 * scans, then awaits completion of all scanning threads as identified
70bfc848c6Sjm199354 * in vs_svc_nodes.
71bfc848c6Sjm199354 */
72bfc848c6Sjm199354
73bfc848c6Sjm199354 typedef struct vs_svc_node {
74bfc848c6Sjm199354 pthread_t vsn_tid;
75bfc848c6Sjm199354 vs_scan_req_t vsn_req;
76bfc848c6Sjm199354 vs_eng_ctx_t vsn_eng;
77bfc848c6Sjm199354 } vs_svc_node_t;
78bfc848c6Sjm199354
79bfc848c6Sjm199354 static vs_svc_node_t *vs_svc_nodes;
80bfc848c6Sjm199354 static uint32_t vs_svc_max_node; /* max idx into vs_svc_nodes */
81bfc848c6Sjm199354 static pthread_mutex_t vs_svc_mutex = PTHREAD_MUTEX_INITIALIZER;
82bfc848c6Sjm199354
83bfc848c6Sjm199354
84911106dfSjm199354 /* local functions */
85bfc848c6Sjm199354 static void *vs_svc_async_scan(void *);
86bfc848c6Sjm199354 static int vs_svc_scan_file(vs_svc_node_t *, vs_scanstamp_t *);
87911106dfSjm199354 static void vs_svc_vlog(char *, vs_result_t *);
88911106dfSjm199354 static void vs_svc_audit(char *, vs_result_t *);
89911106dfSjm199354
90bfc848c6Sjm199354
91911106dfSjm199354 /*
92911106dfSjm199354 * vs_svc_init, vs_svc_fini
93911106dfSjm199354 *
94911106dfSjm199354 * Invoked on daemon load and unload
95911106dfSjm199354 */
96bfc848c6Sjm199354 int
vs_svc_init(uint32_t max_req)97bfc848c6Sjm199354 vs_svc_init(uint32_t max_req)
98911106dfSjm199354 {
99bfc848c6Sjm199354 vs_svc_max_node = max_req;
100bfc848c6Sjm199354 vs_svc_nodes = (vs_svc_node_t *)
101bfc848c6Sjm199354 calloc(max_req + 1, sizeof (vs_svc_node_t));
102bfc848c6Sjm199354
103bfc848c6Sjm199354 return (vs_svc_nodes == NULL ? -1 : 0);
104911106dfSjm199354 }
105911106dfSjm199354
106911106dfSjm199354 void
vs_svc_fini()107911106dfSjm199354 vs_svc_fini()
108911106dfSjm199354 {
109bfc848c6Sjm199354 if (vs_svc_nodes)
110bfc848c6Sjm199354 free(vs_svc_nodes);
111bfc848c6Sjm199354 }
112bfc848c6Sjm199354
113bfc848c6Sjm199354
114bfc848c6Sjm199354 /*
115bfc848c6Sjm199354 * vs_svc_terminate
116bfc848c6Sjm199354 *
117bfc848c6Sjm199354 * Close all scan engine connections to terminate in-progress scan
118bfc848c6Sjm199354 * requests, and wait for all threads in vs_svc_nodes to complete
119bfc848c6Sjm199354 */
120bfc848c6Sjm199354 void
vs_svc_terminate()121bfc848c6Sjm199354 vs_svc_terminate()
122bfc848c6Sjm199354 {
123bfc848c6Sjm199354 int i;
124bfc848c6Sjm199354 pthread_t tid;
125bfc848c6Sjm199354
126bfc848c6Sjm199354 /* close connections to abort requests */
127bfc848c6Sjm199354 vs_eng_close_connections();
128bfc848c6Sjm199354
129bfc848c6Sjm199354 /* wait for threads */
130bfc848c6Sjm199354 for (i = 1; i <= vs_svc_max_node; i++) {
131bfc848c6Sjm199354
132bfc848c6Sjm199354 (void) pthread_mutex_lock(&vs_svc_mutex);
133bfc848c6Sjm199354 tid = vs_svc_nodes[i].vsn_tid;
134bfc848c6Sjm199354 (void) pthread_mutex_unlock(&vs_svc_mutex);
135bfc848c6Sjm199354
136bfc848c6Sjm199354 if (tid != 0)
137bfc848c6Sjm199354 (void) pthread_join(tid, NULL);
138bfc848c6Sjm199354 }
139bfc848c6Sjm199354 }
140bfc848c6Sjm199354
141bfc848c6Sjm199354
142bfc848c6Sjm199354 /*
143bfc848c6Sjm199354 * vs_svc_queue_scan_req
144bfc848c6Sjm199354 *
145bfc848c6Sjm199354 * Determine if the file needs to be scanned - either it has
146bfc848c6Sjm199354 * been modified or its scanstamp is not current.
147bfc848c6Sjm199354 * Initiate a thread to process the request, saving the tid
148bfc848c6Sjm199354 * in vs_svc_nodes[idx].vsn_tid, where idx is the vsr_idx passed in
149bfc848c6Sjm199354 * the scan request.
150bfc848c6Sjm199354 *
151bfc848c6Sjm199354 * Returns: VS_STATUS_ERROR - error
152bfc848c6Sjm199354 * VS_STATUS_NO_SCAN - no scan required
153bfc848c6Sjm199354 * VS_STATUS_SCANNING - async scan initiated
154bfc848c6Sjm199354 */
155bfc848c6Sjm199354 int
vs_svc_queue_scan_req(vs_scan_req_t * req)156bfc848c6Sjm199354 vs_svc_queue_scan_req(vs_scan_req_t *req)
157bfc848c6Sjm199354 {
158bfc848c6Sjm199354 pthread_t tid;
159bfc848c6Sjm199354 vs_svc_node_t *node;
160bfc848c6Sjm199354
161bfc848c6Sjm199354 /* No scan if file quarantined */
162bfc848c6Sjm199354 if (req->vsr_quarantined)
163bfc848c6Sjm199354 return (VS_STATUS_NO_SCAN);
164bfc848c6Sjm199354
165bfc848c6Sjm199354 /* No scan if file not modified AND scanstamp is current */
166bfc848c6Sjm199354 if ((req->vsr_modified == 0) &&
167bfc848c6Sjm199354 vs_eng_scanstamp_current(req->vsr_scanstamp)) {
168bfc848c6Sjm199354 return (VS_STATUS_NO_SCAN);
169bfc848c6Sjm199354 }
170bfc848c6Sjm199354
171bfc848c6Sjm199354 /* scan required */
172bfc848c6Sjm199354 node = &(vs_svc_nodes[req->vsr_idx]);
173bfc848c6Sjm199354
174bfc848c6Sjm199354 (void) pthread_mutex_lock(&vs_svc_mutex);
175bfc848c6Sjm199354 if ((node->vsn_tid != 0) || (req->vsr_idx > vs_svc_max_node)) {
176bfc848c6Sjm199354 (void) pthread_mutex_unlock(&vs_svc_mutex);
177bfc848c6Sjm199354 return (VS_STATUS_ERROR);
178bfc848c6Sjm199354 }
179bfc848c6Sjm199354
180bfc848c6Sjm199354 node->vsn_req = *req;
181bfc848c6Sjm199354
182bfc848c6Sjm199354 if (pthread_create(&tid, NULL, vs_svc_async_scan, (void *)node) != 0) {
183bfc848c6Sjm199354 (void) pthread_mutex_unlock(&vs_svc_mutex);
184bfc848c6Sjm199354 return (VS_STATUS_ERROR);
185bfc848c6Sjm199354 }
186bfc848c6Sjm199354
187bfc848c6Sjm199354 node->vsn_tid = tid;
188bfc848c6Sjm199354 (void) pthread_mutex_unlock(&vs_svc_mutex);
189bfc848c6Sjm199354
190bfc848c6Sjm199354 return (VS_STATUS_SCANNING);
191bfc848c6Sjm199354 }
192bfc848c6Sjm199354
193bfc848c6Sjm199354
194bfc848c6Sjm199354 /*
195bfc848c6Sjm199354 * vs_svc_async_scan
196bfc848c6Sjm199354 *
197bfc848c6Sjm199354 * Initialize response structure, invoke vs_svc_scan_file to
198bfc848c6Sjm199354 * perform the scan, then send the result to the kernel.
199bfc848c6Sjm199354 */
200bfc848c6Sjm199354 static void *
vs_svc_async_scan(void * arg)201bfc848c6Sjm199354 vs_svc_async_scan(void *arg)
202bfc848c6Sjm199354 {
203bfc848c6Sjm199354 vs_svc_node_t *node = (vs_svc_node_t *)arg;
204bfc848c6Sjm199354 vs_scan_req_t *scan_req = &(node->vsn_req);
205bfc848c6Sjm199354 vs_scan_rsp_t scan_rsp;
206bfc848c6Sjm199354
207bfc848c6Sjm199354 scan_rsp.vsr_idx = scan_req->vsr_idx;
208bfc848c6Sjm199354 scan_rsp.vsr_seqnum = scan_req->vsr_seqnum;
209bfc848c6Sjm199354 scan_rsp.vsr_result = vs_svc_scan_file(node, &scan_rsp.vsr_scanstamp);
210bfc848c6Sjm199354
211bfc848c6Sjm199354 /* clear node and send async response to kernel */
212bfc848c6Sjm199354 (void) pthread_mutex_lock(&vs_svc_mutex);
213bfc848c6Sjm199354 (void) memset(node, 0, sizeof (vs_svc_node_t));
214bfc848c6Sjm199354 (void) pthread_mutex_unlock(&vs_svc_mutex);
215bfc848c6Sjm199354
216bfc848c6Sjm199354 (void) vscand_kernel_result(&scan_rsp);
217bfc848c6Sjm199354
218bfc848c6Sjm199354 return (NULL);
219911106dfSjm199354 }
220911106dfSjm199354
221911106dfSjm199354
222911106dfSjm199354 /*
223911106dfSjm199354 * vs_svc_scan_file
224911106dfSjm199354 *
225911106dfSjm199354 * vs_svc_scan_file is responsible for:
226911106dfSjm199354 * - obtaining & releasing a scan engine connection
227911106dfSjm199354 * - invoking the scan engine interface code to do the scan
228911106dfSjm199354 * - retrying a failed scan (up to VS_MAX_RETRY times)
229911106dfSjm199354 * - updating scan statistics
230911106dfSjm199354 * - logging virus information
231911106dfSjm199354 *
23253c11029Sjm199354 *
233911106dfSjm199354 * Returns:
234bfc848c6Sjm199354 * VS_STATUS_NO_SCAN - scan not reqd; daemon shutting down
23553c11029Sjm199354 * VS_STATUS_CLEAN - scan success. File clean.
23653c11029Sjm199354 * new scanstamp returned in scanstamp param.
23753c11029Sjm199354 * VS_STATUS_INFECTED - scan success. File infected.
23853c11029Sjm199354 * VS_STATUS_ERROR - scan failure either in vscand or scan engine.
239911106dfSjm199354 */
240bfc848c6Sjm199354 static int
vs_svc_scan_file(vs_svc_node_t * node,vs_scanstamp_t * scanstamp)241bfc848c6Sjm199354 vs_svc_scan_file(vs_svc_node_t *node, vs_scanstamp_t *scanstamp)
242911106dfSjm199354 {
243bfc848c6Sjm199354 char devname[MAXPATHLEN];
244bfc848c6Sjm199354 int flags = 0;
24553c11029Sjm199354 int retries;
246911106dfSjm199354 vs_result_t result;
247bfc848c6Sjm199354 vs_scan_req_t *req = &(node->vsn_req);
248bfc848c6Sjm199354 vs_eng_ctx_t *eng = &(node->vsn_eng);
249bfc848c6Sjm199354
250bfc848c6Sjm199354 (void) snprintf(devname, MAXPATHLEN, "%s%d", VS_DRV_PATH, req->vsr_idx);
251911106dfSjm199354
25253c11029Sjm199354 /* initialize response scanstamp to current scanstamp value */
253bfc848c6Sjm199354 (void) strlcpy(*scanstamp, req->vsr_scanstamp, sizeof (vs_scanstamp_t));
254911106dfSjm199354
255911106dfSjm199354 (void) memset(&result, 0, sizeof (vs_result_t));
256911106dfSjm199354 result.vsr_rc = VS_RESULT_UNDEFINED;
257911106dfSjm199354
258911106dfSjm199354 for (retries = 0; retries <= VS_MAX_RETRY; retries++) {
259bfc848c6Sjm199354 /* get engine connection */
260bfc848c6Sjm199354 if (vs_eng_get(eng, (retries != 0)) != 0) {
26153c11029Sjm199354 result.vsr_rc = VS_RESULT_ERROR;
262911106dfSjm199354 continue;
263911106dfSjm199354 }
264911106dfSjm199354
265bfc848c6Sjm199354 /* shutdown could occur while waiting for engine connection */
266911106dfSjm199354 if (vscand_get_state() == VS_STATE_SHUTDOWN) {
267bfc848c6Sjm199354 vs_eng_release(eng);
26853c11029Sjm199354 return (VS_STATUS_NO_SCAN);
269911106dfSjm199354 }
270911106dfSjm199354
271bfc848c6Sjm199354 /* scan file */
272bfc848c6Sjm199354 (void) vs_icap_scan_file(eng, devname, req->vsr_path,
273bfc848c6Sjm199354 req->vsr_size, flags, &result);
274911106dfSjm199354
275911106dfSjm199354 /* if no error, clear error state on engine and break */
27653c11029Sjm199354 if ((result.vsr_rc != VS_RESULT_SE_ERROR) &&
27753c11029Sjm199354 (result.vsr_rc != VS_RESULT_ERROR)) {
278bfc848c6Sjm199354 vs_eng_set_error(eng, 0);
279bfc848c6Sjm199354 vs_eng_release(eng);
280911106dfSjm199354 break;
281911106dfSjm199354 }
282911106dfSjm199354
28353c11029Sjm199354 /* treat error on shutdown as scan not required */
284911106dfSjm199354 if (vscand_get_state() == VS_STATE_SHUTDOWN) {
285bfc848c6Sjm199354 vs_eng_release(eng);
28653c11029Sjm199354 return (VS_STATUS_NO_SCAN);
287911106dfSjm199354 }
288911106dfSjm199354
289911106dfSjm199354 /* set engine's error state and update engine stats */
290bfc848c6Sjm199354 if (result.vsr_rc == VS_RESULT_SE_ERROR)
291bfc848c6Sjm199354 vs_eng_set_error(eng, 1);
292bfc848c6Sjm199354
293bfc848c6Sjm199354 vs_eng_release(eng);
294911106dfSjm199354 }
295911106dfSjm199354
29653c11029Sjm199354 vs_stats_set(result.vsr_rc);
297911106dfSjm199354
29853c11029Sjm199354 /*
29953c11029Sjm199354 * VS_RESULT_CLEANED - file infected, cleaned data available
30053c11029Sjm199354 * VS_RESULT_FORBIDDEN - file infected, no cleaned data
30153c11029Sjm199354 * Log virus, write audit record and return INFECTED status
30253c11029Sjm199354 */
303911106dfSjm199354 if (result.vsr_rc == VS_RESULT_CLEANED ||
304911106dfSjm199354 result.vsr_rc == VS_RESULT_FORBIDDEN) {
305bfc848c6Sjm199354 vs_svc_vlog(req->vsr_path, &result);
306bfc848c6Sjm199354 vs_svc_audit(req->vsr_path, &result);
30753c11029Sjm199354 return (VS_STATUS_INFECTED);
308911106dfSjm199354 }
309911106dfSjm199354
31053c11029Sjm199354 /* VS_RESULT_CLEAN - Set the scanstamp and return CLEAN status */
31153c11029Sjm199354 if (result.vsr_rc == VS_RESULT_CLEAN) {
31253c11029Sjm199354 (void) strlcpy(*scanstamp, result.vsr_scanstamp,
313911106dfSjm199354 sizeof (vs_scanstamp_t));
31453c11029Sjm199354 return (VS_STATUS_CLEAN);
315911106dfSjm199354 }
316911106dfSjm199354
31753c11029Sjm199354 return (VS_STATUS_ERROR);
318911106dfSjm199354 }
319911106dfSjm199354
320911106dfSjm199354
321911106dfSjm199354 /*
322911106dfSjm199354 * vs_svc_vlog
323911106dfSjm199354 *
324bfc848c6Sjm199354 * log details of infections detected in syslig
325bfc848c6Sjm199354 * If virus log is configured log details there too
326911106dfSjm199354 */
327911106dfSjm199354 static void
vs_svc_vlog(char * filepath,vs_result_t * result)328911106dfSjm199354 vs_svc_vlog(char *filepath, vs_result_t *result)
329911106dfSjm199354 {
330911106dfSjm199354 FILE *fp = NULL;
331911106dfSjm199354 time_t sec;
332911106dfSjm199354 struct tm *timestamp;
333911106dfSjm199354 char timebuf[18]; /* MM/DD/YY hh:mm:ss */
334911106dfSjm199354 int i;
335911106dfSjm199354 char *log;
336911106dfSjm199354
337bfc848c6Sjm199354 /* syslog */
338911106dfSjm199354 if (result->vsr_nviolations == 0) {
339*c8dbf746Sjm199354 syslog(LOG_NOTICE, "quarantine %s\n", filepath);
340911106dfSjm199354 } else {
341911106dfSjm199354 for (i = 0; i < result->vsr_nviolations; i++) {
342*c8dbf746Sjm199354 syslog(LOG_NOTICE, "quarantine %s %d - %s\n",
343911106dfSjm199354 filepath,
344911106dfSjm199354 result->vsr_vrec[i].vr_id,
345911106dfSjm199354 result->vsr_vrec[i].vr_desc);
346911106dfSjm199354 }
347911106dfSjm199354 }
348bfc848c6Sjm199354
349bfc848c6Sjm199354 /* log file */
350bfc848c6Sjm199354 if (((log = vscand_viruslog()) == NULL) ||
351bfc848c6Sjm199354 ((fp = fopen(log, "a")) == NULL)) {
352bfc848c6Sjm199354 return;
353911106dfSjm199354 }
354911106dfSjm199354
355bfc848c6Sjm199354 (void) time(&sec);
356bfc848c6Sjm199354 timestamp = localtime(&sec);
357bfc848c6Sjm199354 (void) strftime(timebuf, sizeof (timebuf), "%D %T", timestamp);
358bfc848c6Sjm199354
359bfc848c6Sjm199354 if (result->vsr_nviolations == 0) {
360bfc848c6Sjm199354 (void) fprintf(fp, "%s quarantine %d[%s]\n",
361bfc848c6Sjm199354 timebuf, strlen(filepath), filepath);
362bfc848c6Sjm199354 } else {
363bfc848c6Sjm199354 for (i = 0; i < result->vsr_nviolations; i++) {
364bfc848c6Sjm199354 (void) fprintf(fp, "%s quarantine %d[%s] %d - %d[%s]\n",
365bfc848c6Sjm199354 timebuf, strlen(filepath), filepath,
366bfc848c6Sjm199354 result->vsr_vrec[i].vr_id,
367bfc848c6Sjm199354 strlen(result->vsr_vrec[i].vr_desc),
368bfc848c6Sjm199354 result->vsr_vrec[i].vr_desc);
369bfc848c6Sjm199354 }
370bfc848c6Sjm199354 }
371bfc848c6Sjm199354
372911106dfSjm199354 (void) fclose(fp);
373911106dfSjm199354 }
374911106dfSjm199354
375911106dfSjm199354
376911106dfSjm199354 /*
377911106dfSjm199354 * vs_svc_audit
378911106dfSjm199354 *
379911106dfSjm199354 * Generate AUE_vscan_quarantine audit record containing name
380911106dfSjm199354 * of infected file, and violation details if available.
381911106dfSjm199354 */
382911106dfSjm199354 static void
vs_svc_audit(char * filepath,vs_result_t * result)383911106dfSjm199354 vs_svc_audit(char *filepath, vs_result_t *result)
384911106dfSjm199354 {
385911106dfSjm199354 int i;
386911106dfSjm199354 char *violations[VS_MAX_VIOLATIONS];
387911106dfSjm199354 char data[VS_MAX_VIOLATIONS][VS_DESCRIPTION_MAX];
388911106dfSjm199354 adt_session_data_t *ah;
389911106dfSjm199354 adt_termid_t *p_tid;
390911106dfSjm199354 adt_event_data_t *event;
391911106dfSjm199354
392911106dfSjm199354 if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA)) {
393911106dfSjm199354 syslog(LOG_AUTH | LOG_ALERT, "adt_start_session: %m");
394911106dfSjm199354 return;
395911106dfSjm199354 }
396911106dfSjm199354
397911106dfSjm199354 if (adt_load_ttyname("/dev/console", &p_tid) != 0) {
398911106dfSjm199354 syslog(LOG_AUTH | LOG_ALERT,
399911106dfSjm199354 "adt_load_ttyname(/dev/console): %m");
400911106dfSjm199354 return;
401911106dfSjm199354 }
402911106dfSjm199354
403911106dfSjm199354 if (adt_set_user(ah, ADT_NO_ATTRIB, ADT_NO_ATTRIB, ADT_NO_ATTRIB,
404911106dfSjm199354 ADT_NO_ATTRIB, p_tid, ADT_NEW) != 0) {
405911106dfSjm199354 syslog(LOG_AUTH | LOG_ALERT, "adt_set_user(ADT_NO_ATTRIB): %m");
406911106dfSjm199354 (void) adt_end_session(ah);
407911106dfSjm199354 return;
408911106dfSjm199354 }
409911106dfSjm199354
410911106dfSjm199354 if ((event = adt_alloc_event(ah, ADT_vscan_quarantine)) == NULL) {
411911106dfSjm199354 syslog(LOG_AUTH | LOG_ALERT,
412911106dfSjm199354 "adt_alloc_event(ADT_vscan_quarantine)): %m");
413911106dfSjm199354 (void) adt_end_session(ah);
414911106dfSjm199354 return;
415911106dfSjm199354 }
416911106dfSjm199354
417911106dfSjm199354 /* populate vscan audit event */
418911106dfSjm199354 event->adt_vscan_quarantine.file = filepath;
419911106dfSjm199354 for (i = 0; i < result->vsr_nviolations; i++) {
420911106dfSjm199354 (void) snprintf(data[i], VS_DESCRIPTION_MAX, "%d - %s",
421911106dfSjm199354 result->vsr_vrec[i].vr_id, result->vsr_vrec[i].vr_desc);
422911106dfSjm199354 violations[i] = data[i];
423911106dfSjm199354 }
424911106dfSjm199354
425911106dfSjm199354 event->adt_vscan_quarantine.violations = (char **)violations;
426911106dfSjm199354 event->adt_vscan_quarantine.nviolations = result->vsr_nviolations;
427911106dfSjm199354
428911106dfSjm199354 if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS))
429911106dfSjm199354 syslog(LOG_AUTH | LOG_ALERT, "adt_put_event: %m");
430911106dfSjm199354
431911106dfSjm199354 adt_free_event(event);
432911106dfSjm199354 (void) adt_end_session(ah);
433911106dfSjm199354 }
434