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 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 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 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 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 * 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 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 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 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