2 #require_once("{$GLOBALS['srcdir']}/sql.inc");
3 require_once(dirname(__FILE__). "/sql.inc");
5 function newEvent($event, $user, $groupname, $success, $comments="") {
6 $adodb = $GLOBALS['adodb']['db'];
7 $crt_user=isset($_SERVER['SSL_CLIENT_S_DN_CN']) ? $_SERVER['SSL_CLIENT_S_DN_CN'] : null;
8 /* More details added to the log */
9 $sql = "insert into log ( date, event, user, groupname, success, comments, crt_user) " .
10 "values ( NOW(), " . $adodb->qstr($event) . "," . $adodb->qstr($user) .
11 "," . $adodb->qstr($groupname) . "," . $adodb->qstr($success) . "," .
12 $adodb->qstr($comments) ."," .
13 $adodb->qstr($crt_user) . ")";
14 //$ret = sqlInsertClean($sql);
15 // Call the new function created for audit log
16 $ret = sqlInsertClean_audit($sql);
17 send_atna_audit_msg($user, $groupname, $event, 0, $success, $comments);
20 function getEventByDate($date, $user="", $cols="DISTINCT date, event, user, groupname, patient_id, success, comments, checksum")
22 $sql = "SELECT $cols FROM log WHERE date >= '$date 00:00:00' AND date <= '$date 23:59:59'";
23 if ($user) $sql .= " AND user LIKE '$user'";
24 $sql .= " ORDER BY date DESC LIMIT 5000";
25 $res = sqlStatement($sql);
26 for($iter=0; $row=sqlFetchArray($res); $iter++) {
33 * Get records from the LOG and Extended_Log table
34 * using the optional parameters:
35 * date : a specific date (defaults to today)
36 * user : a specific user (defaults to none)
37 * cols : gather specific columns (defaults to date,event,user,groupname,comments)
38 * sortby : sort the results by (defaults to none)
42 function getEvents($params)
44 // parse the parameters
45 $cols = "DISTINCT date, event, user, groupname, patient_id, success, comments,checksum,crt_user";
46 if (isset($params['cols']) && $params['cols'] != "") $cols = $params['cols'];
48 $date1 = date("Y-m-d", time());
49 if (isset($params['sdate']) && $params['sdate'] != "") $date1= $params['sdate'];
51 $date2 = date("Y-m-d", time());
52 if (isset($params['edate']) && $params['edate'] != "") $date2= $params['edate'];
55 if (isset($params['user']) && $params['user'] != "") $user= $params['user'];
57 //VicarePlus :: For Generating log with patient id.
59 if (isset($params['patient']) && $params['patient'] != "") $patient= $params['patient'];
62 if (isset($params['sortby']) && $params['sortby'] != "") $sortby = $params['sortby'];
65 if (isset($params['levent']) && $params['levent'] != "") $levent = $params['levent'];
68 if (isset($params['tevent']) && $params['tevent'] != "") $tevent = $params['tevent'];
71 if (isset($params['event']) && $params['event'] != "") $event = $params['event'];
73 if ($sortby == "comments") $sortby = "description";
74 if ($sortby == "groupname") $sortby = ""; //VicarePlus :: since there is no groupname in extended_log
75 if ($sortby == "success") $sortby = ""; //VicarePlus :: since there is no success field in extended_log
76 if ($sortby == "checksum") $sortby = ""; //VicarePlus :: since there is no checksum field in extended_log
77 $columns = "DISTINCT date, event, user, recipient,patient_id,description";
78 $sql = "SELECT $columns FROM extended_log WHERE date >= '$date1 00:00:00' AND date <= '$date2 23:59:59'";
79 if ($user != "") $sql .= " AND user LIKE '$user'";
80 if ($patient != "") $sql .= " AND patient_id LIKE '$patient'";
81 if ($levent != "") $sql .= " AND event LIKE '$levent%'";
82 if ($sortby != "") $sql .= " ORDER BY ".$sortby." DESC "; // descending order
83 $sql .= " LIMIT 5000";
88 $sql = "SELECT $cols FROM log WHERE date >= '$date1 00:00:00' AND date <= '$date2 23:59:59'";
89 if ($user != "") $sql .= " AND user LIKE '$user'";
90 if ($patient != "") $sql .= " AND patient_id LIKE '$patient'";
91 if ($levent != "") $sql .= " AND event LIKE '$levent%'";
92 if ($tevent != "") $sql .= " AND event LIKE '%$tevent'";
93 if ($sortby != "") $sql .= " ORDER BY ".$sortby." DESC "; // descending order
94 $sql .= " LIMIT 5000";
96 $res = sqlStatement($sql);
97 for($iter=0; $row=sqlFetchArray($res); $iter++) {
103 /* Given an SQL insert/update that was just performeds:
104 * - Find the table and primary id of the row that was created/modified
105 * - Calculate the SHA1 checksum of that row (with all the
106 * column values concatenated together).
107 * - Return the SHA1 checksum as a 40 char hex string.
108 * If this is not an insert/update query, return "".
109 * If multiple rows were modified, return "".
110 * If we're unable to determine the row modified, return "".
112 function sql_checksum_of_modified_row($statement)
117 $tokens = preg_split("/[\s,(\'\"]+/", $statement);
118 /* Identifying the id for insert/replace statements for calculating the checksum */
119 if((strcasecmp($tokens[0],"INSERT")==0) || (strcasecmp($tokens[0],"REPLACE")==0)){
121 $rid = mysql_insert_id($GLOBALS['dbh']);
122 /* For handling the table that doesn't have auto-increment column */
123 if ($rid === 0 || $rid === FALSE) {
124 if($table == "gacl_aco_map" || $table == "gacl_aro_groups_map" || $table == "gacl_aro_map" || $table == "gacl_axo_groups_map" || $table == "gacl_axo_map")
126 else if($table == "gacl_groups_aro_map" || $table == "gacl_groups_axo_map")
130 /* To handle insert statements */
131 if($tokens[3] == $id){
132 for($i=4;$i<count($tokens);$i++){
133 if(strcasecmp($tokens[$i],"VALUES")==0){
139 /* To handle replace statements */
140 else if(strcasecmp($tokens[3],"SET")==0){
141 if((strcasecmp($tokens[4],"ID")==0) || (strcasecmp($tokens[4],"`ID`")==0)){
151 /* Identifying the id for update statements for calculating the checksum */
152 else if(strcasecmp($tokens[0],"UPDATE")==0){
156 $total = count($tokens);
158 /* Identifying the primary key column for the updated record */
159 if ($table == "form_physical_exam") {
162 else if ($table == "claims"){
165 else if ($table == "openemr_postcalendar_events") {
168 else if ($table == "lang_languages"){
171 else if ($table == "openemr_postcalendar_categories" || $table == "openemr_postcalendar_topics"){
174 else if ($table == "openemr_postcalendar_limits"){
177 else if($table == "gacl_aco_map" || $table == "gacl_aro_groups_map" || $table == "gacl_aro_map" || $table == "gacl_axo_groups_map" || $table == "gacl_axo_map"){
180 else if($table == "gacl_groups_aro_map" || $table == "gacl_groups_axo_map"){
187 /* Identifying the primary key value for the updated record */
188 while ($offset < $total) {
189 /* There are 4 possible ways that the id=123 can be parsed:
197 if (($tokens[$offset] == "$id=") && ($offset + 1 < $total)) {
198 $rid = $tokens[$offset+1];
201 /* 'id', '=', '123' */
202 else if ($tokens[$offset] == "$id" && $tokens[$offset+1] == "=" && ($offset+2 < $total)) {
203 $rid = $tokens[$offset+2];
207 else if (strpos($tokens[$offset], "$id=") === 0) {
208 $tid = substr($tokens[$offset], strlen($id)+1);
214 else if($tokens[$offset] == "$id") {
215 $tid = substr($tokens[$offset+1],1);
221 }//while ($offset < $total)
222 }// else if ($tokens[0] == 'update' || $tokens[0] == 'UPDATE' )
224 if ($table == "" || $rid == "") {
227 /* Framing sql statements for calculating checksum */
228 if ($table == "form_physical_exam") {
229 $sql = "select * from $table where forms_id = $rid";
231 else if ($table == "claims"){
232 $sql = "select * from $table where patient_id = $rid";
234 else if ($table == "openemr_postcalendar_events") {
235 $sql = "select * from $table where pc_eid = $rid";
237 else if ($table == "lang_languages") {
238 $sql = "select * from $table where lang_id = $rid";
240 else if ($table == "openemr_postcalendar_categories" || $table == "openemr_postcalendar_topics"){
241 $sql = "select * from $table where pc_catid = $rid";
243 else if ($table == "openemr_postcalendar_limits"){
244 $sql = "select * from $table where pc_limitid = $rid";
246 else if ($table == "gacl_aco_map" || $table == "gacl_aro_groups_map" || $table == "gacl_aro_map" || $table == "gacl_axo_groups_map" || $table == "gacl_axo_map"){
247 $sql = "select * from $table where acl_id = $rid";
249 else if($table == "gacl_groups_aro_map" || $table == "gacl_groups_axo_map"){
250 $sql = "select * from $table where group_id = $rid";
253 $sql = "select * from $table where id = $rid";
255 $results = sqlQuery($sql,'true');
257 /* Concatenating the column values for the row inserted/updated */
258 if (is_array($results)) {
259 foreach ($results as $field_name => $field) {
260 $column_values .= $field;
263 // ViCarePlus: As per NIST standard, the encryption algorithm SHA1 is used
264 return sha1($column_values);
267 /* Create an XML audit record corresponding to RFC 3881.
268 * The parameters passed are the column values (from table 'log')
269 * for a single audit record.
271 function create_rfc3881_msg($user, $group, $event, $patient_id, $outcome, $comments)
274 /* Event action codes indicate whether the event is read/write.
275 * C = create, R = read, U = update, D = delete, E = execute
277 $eventActionCode = 'E';
278 if (substr($event, -7) == "-create") {
279 $eventActionCode = 'C';
281 else if (substr($event, -7) == "-insert") {
282 $eventActionCode = 'C';
284 else if (substr($event, -7) == "-select") {
285 $eventActionCode = 'R';
287 else if (substr($event, -7) == "-update") {
288 $eventActionCode = 'U';
290 else if (substr($event, -7) == "-delete") {
291 $eventActionCode = 'D';
294 $date_obj = new DateTime();
295 $eventDateTime = $date_obj->format(DATE_ATOM);
297 /* For EventOutcomeIndicator, 0 = success and 4 = minor error */
298 $eventOutcome = ($outcome === 1) ? 0 : 4;
300 /* The choice of event codes is up to OpenEMR.
301 * We're using the same event codes as
302 * https://iheprofiles.projects.openhealthtools.org/
304 $eventIDcodeSystemName = "DCM";
306 $eventIDdisplayName = $event;
308 if (strpos($event, 'patient-record') !== FALSE) {
309 $eventIDcode = 110110;
310 $eventIDdisplayName = 'Patient Record';
312 else if (strpos($event, 'view') !== FALSE) {
313 $eventIDCode = 110110;
314 $eventIDdisplayName = 'Patient Record';
316 else if (strpos($event, 'login') !== FALSE) {
317 $eventIDcode = 110122;
318 $eventIDdisplayName = 'Login';
320 else if (strpos($event, 'logout') !== FALSE) {
321 $eventIDcode = 110123;
322 $eventIDdisplayName = 'Logout';
324 else if (strpos($event, 'scheduling') !== FALSE) {
325 $eventIDcode = 110111;
326 $eventIDdisplayName = 'Patient Care Assignment';
328 else if (strpos($event, 'security-administration') !== FALSE) {
329 $eventIDcode = 110129;
330 $eventIDdisplayName = 'Security Administration';
336 /* Variables used in ActiveParticipant section, which identifies
337 * the IP address and application of the source and destination.
339 $srcUserID = $_SERVER['SERVER_NAME'] . '|OpenEMR';
340 $srcNetwork = $_SERVER['SERVER_ADDR'];
341 $destUserID = $GLOBALS['atna_audit_host'];
342 $destNetwork = $GLOBALS['atna_audit_host'];
348 $userDisplayName = 'User Identifier';
351 $patientTypeCode = "";
354 $patientDisplayName = "";
356 if ($eventIdDisplayName == 'Patient Record') {
357 $patientID = $patient_id;
358 $pattientTypeCode = 1;
361 $patientDisplayName = 'Patient Number';
364 /* Construct the XML audit message, and save to $msg */
365 $msg = '<?xml version="1.0" encoding="ASCII"?>';
366 $msg .= '<AuditMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ';
367 $msg .= 'xsi:noNamespaceSchemaLocation="healthcare-security-audit.xsd">';
369 /* Indicate the event code, text name, read/write type, and date/time */
370 $msg .= "<EventIdentification EventActionCode=\"$eventActionCode\" ";
371 $msg .= "EventDateTime=\"$eventDateTime\" ";
372 $msg .= "EventOutcomeIndicator=\"$eventOutcome\">";
373 $msg .= "<EventID code=\"eventIDcode\" displayName=\"$eventIDdisplayName\" ";
374 $msg .= "codeSystemName=\"DCM\" />";
375 $msg .= "</EventIdentification>";
377 /* Indicate the IP address and application of the source and destination */
378 $msg .= "<ActiveParticipant UserID=\"$srcUserID\" UserIsRequestor=\"true\" ";
379 $msg .= "NetworkAccessPointID=\"$srcNetwork\" NetworkAccessPointTypeCode=\"2\" >";
380 $msg .= "<RoleIDCode code=\"110153\" displayName=\"Source\" codeSystemName=\"DCM\" />";
381 $msg .= "</ActiveParticipant>";
382 $msg .= "<ActiveParticipant UserID=\"$destUserID\" UserIsRequestor=\"false\" ";
383 $msg .= "NetworkAccessPointID=\"$destNetwork\" NetworkAccessPointTypeCode=\"2\" >";
384 $msg .= "<RoleIDCode code=\"110152\" displayName=\"Destination\" codeSystemName=\"DCM\" />";
385 $msg .= "</ActiveParticipant>";
387 $msg .= "<AuditSourceIdentification AuditSourceID=\"$srcUserID\" />";
389 /* Indicate the username who generated this audit record */
390 $msg .= "<ParticipantObjectIdentification ParticipantObjectID=\"$user\" ";
391 $msg .= "ParticipantObjectTypeCode=\"1\" ";
392 $msg .= "ParticipantObjectTypeCodeRole=\"6\" >";
393 $msg .= "<ParticipantObjectIDTypeCode code=\"11\" ";
394 $msg .= "displayName=\"User Identifier\" ";
395 $msg .= "codeSystemName=\"RFC-3881\" /></ParticipantObjectIdentification>";
397 if ($eventIDdisplayName == 'Patient Record' && $patient_id != 0) {
398 $msg .= "<ParticipantObjectIdentification ParticipantObjectID=\"$patient_id\" ";
399 $msg .= "ParticipantObjectTypeCode=\"1\" ";
400 $msg .= "ParticipantObjectTypeCodeRole=\"1\" >";
401 $msg .= "<ParticipantObjectIDTypeCode code=\"2\" ";
402 $msg .= "displayName=\"Patient Number\" ";
403 $msg .= "codeSystemName=\"RFC-3881\" /></ParticipantObjectIdentification>";
405 $msg .= "</AuditMessage>";
407 /* Add the syslog header */
408 $date_obj = new DateTime($date);
409 $datestr= $date_obj->format(DATE_ATOM);
410 $msg = "<13> " . $datestr . " " . $_SERVER['SERVER_NAME'] . " " . $msg;
415 /* Create a TLS (SSLv3) connection to the given host/port.
416 * $localcert is the path to a PEM file with a client certificate and private key.
417 * $cafile is the path to the CA certificate file, for
418 * authenticating the remote machine's certificate.
419 * If $cafile is "", the remote machine's certificate is not verified.
420 * If $localcert is "", we don't pass a client certificate in the connection.
422 * Return a stream resource that can be used with fwrite(), fread(), etc.
423 * Returns FALSE on error.
425 function create_tls_conn($host, $port, $localcert, $cafile) {
427 if ($cafile !== null && $cafile != "") {
428 $sslopts['cafile'] = $cafile;
429 $sslopts['verify_peer'] = TRUE;
430 $sslopts['verify_depth'] = 10;
432 if ($localcert !== null && $localcert != "") {
433 $sslopts['local_cert'] = $localcert;
435 $opts = array('tls' => $sslopts, 'ssl' => $sslopts);
436 $ctx = stream_context_create($opts);
438 $flags = STREAM_CLIENT_CONNECT;
440 $olderr = error_reporting(0);
441 $conn = stream_socket_client('tls://' . $host . ":" . $port, $errno, $errstr,
442 $timeout, $flags, $ctx);
443 error_reporting($olderr);
448 /* This function is used to send audit records to an Audit Repository Server,
449 * as described in the Audit Trail and Node Authentication (ATNA) standard.
450 * Given the fields in a single audit record:
451 * - Create an XML audit message according to RFC 3881, including the RFC5425 syslog header.
452 * - Create a TLS connection that performs bi-directions certificate authentication,
453 * according to RFC 5425.
454 * - Send the XML message on the TLS connection.
456 function send_atna_audit_msg($user, $group, $event, $patient_id, $outcome, $comments)
458 /* If no ATNA repository server is configured, return */
459 if ($GLOBALS['atna_audit_host'] === null || $GLOBALS['atna_audit_host'] == "" || !($GLOBALS['enable_atna_audit'])) {
462 $host = $GLOBALS['atna_audit_host'];
463 $port = $GLOBALS['atna_audit_port'];
464 $localcert = $GLOBALS['atna_audit_localcert'];
465 $cacert = $GLOBALS['atna_audit_cacert'];
466 $conn = create_tls_conn($host, $port, $localcert, $cacert);
467 if ($conn !== FALSE) {
468 $msg = create_rfc3881_msg($user, $group, $event, $patient_id, $outcome, $comments);
476 /* Add an entry into the audit log table, indicating that an
477 * SQL query was performed. $outcome is true if the statement
478 * successfully completed. Determine the event type based on
479 * the tables present in the SQL query.
481 function auditSQLEvent($statement, $outcome)
483 $user = isset($_SESSION['authUser']) ? $_SESSION['authUser'] : "";
484 /* Don't log anything if the audit logging is not enabled. Exception for "emergency" users */
485 if (!isset($GLOBALS['enable_auditlog']) || !($GLOBALS['enable_auditlog']))
487 if ((soundex($user) != soundex("emergency")) && (soundex($user) != soundex("breakglass")))
490 // ViCarePlus : Fix for Audit Issue :: Sep 24, 2010
492 // Issue: When the audit logging is enabled and when SELECT QUERY (query=1 in globals.php) is enabled to log,
493 // the issue of LAST_INSERT_ID arises.
494 // This is because, the function sql_checksum_of_modified_row() is triggered more than
495 // once for SELECT Queries and thus the expected value (LAST_INSERT_ID) in the $GLOBALS['lastidado'] is getting altered.
496 // Since, the $GLOBALS['lastidado'] is manipulated by the other function calls(sql_checksum_of_modified_row),
497 // this issue is arised.
500 // The task of assigning LAST_INSERT_ID to a global variable $GLOBALS['lastidado'] is moved from sql.inc to this file.
501 // Following code will get executed, when (a) when audit is enabled (b) When break glass is invoked.
502 // Retrieve LAST_INSERT_ID and assign it to a global variable and eventually it can be used by other functions.
503 $lastid=mysql_insert_id($GLOBALS['dbh']);
504 $GLOBALS['lastidado']=$lastid;
505 // ViCarePlus : Audit fix - ends here :: Sep 24,2010
507 $statement = trim($statement);
509 /* Don't audit SQL statements done to the audit log,
510 * or we'll have an infinite loop.
512 if ((stripos($statement, "insert into log") !== FALSE) ||
513 (stripos($statement, "FROM log ") !== FALSE) ) {
517 $group = isset($_SESSION['authGroup']) ? $_SESSION['authGroup'] : "";
518 $comments = $statement;
521 if ($outcome === FALSE) {
524 if ($outcome !== FALSE) {
525 $checksum = sql_checksum_of_modified_row($statement);
527 /* Determine the query type (select, update, insert, delete) */
528 $querytype = "select";
529 $querytypes = array("select", "update", "insert", "delete","replace");
530 foreach ($querytypes as $qtype) {
531 if (stripos($statement, $qtype) === 0) {
536 /* Determine the audit event based on the database tables */
538 $tables = array("billing" => "patient-record",
539 "claims" => "patient-record",
540 "employer_data" => "patient-record",
541 "forms" => "patient-record",
542 "form_encounter" => "patient-record",
543 "form_dictation" => "patient-record",
544 "form_misc_billing_options" => "patient-record",
545 "form_reviewofs" => "patient-record",
546 "form_ros" => "patient-record",
547 "form_soap" => "patient-record",
548 "form_vitals" => "patient-record",
549 "history_data" => "patient-record",
550 "immunizations" => "patient-record",
551 "insurance_data" => "patient-record",
552 "issue_encounter" => "patient-record",
553 "lists" => "patient-record",
554 "patient_data" => "patient-record",
555 "payments" => "patient-record",
556 "pnotes" => "patient-record",
557 "onotes" => "patient-record",
558 "prescriptions" => "order",
559 "transactions" => "patient-record",
560 "facility" => "security-administration",
561 "pharmacies" => "security-administration",
562 "addresses" => "security-administration",
563 "phone_numbers" => "security-administration",
564 "x12_partners" => "security-administration",
565 "insurance_companies" => "security-administration",
566 "codes" => "security-administration",
567 "registry" => "security-administration",
568 "users" => "security-administration",
569 "groups" => "security-administration",
570 "openemr_postcalendar_events" => "scheduling",
571 "openemr_postcalendar_categories" => "security-administration",
572 "openemr_postcalendar_limits" => "security-administration",
573 "openemr_postcalendar_topics" => "security-administration",
574 "gacl_acl" => "security-administration",
575 "gacl_acl_sections" => "security-administration",
576 "gacl_acl_seq" => "security-administration",
577 "gacl_aco" => "security-administration",
578 "gacl_aco_map" => "security-administration",
579 "gacl_aco_sections" => "security-administration",
580 "gacl_aco_sections_seq" => "security-administration",
581 "gacl_aco_seq" => "security-administration",
582 "gacl_aro" => "security-administration",
583 "gacl_aro_groups" => "security-administration",
584 "gacl_aro_groups_id_seq" => "security-administration",
585 "gacl_aro_groups_map" => "security-administration",
586 "gacl_aro_map" => "security-administration",
587 "gacl_aro_sections" => "security-administration",
588 "gacl_aro_sections_seq" => "security-administration",
589 "gacl_aro_seq" => "security-administration",
590 "gacl_axo" => "security-administration",
591 "gacl_axo_groups" => "security-administration",
592 "gacl_axo_groups_map" => "security-administration",
593 "gacl_axo_map" => "security-administration",
594 "gacl_axo_sections" => "security-administration",
595 "gacl_groups_aro_map" => "security-administration",
596 "gacl_groups_axo_map" => "security-administration",
597 "gacl_phpgacl" => "security-administration"
600 /* When searching for table names, truncate the SQL statement,
601 * removing any WHERE, SET, or VALUE clauses.
603 $truncated_sql = $statement;
604 $truncated_sql = str_replace("\n", " ", $truncated_sql);
605 if ($querytype == "select") {
606 $startwhere = stripos($truncated_sql, " where ");
607 if ($startwhere > 0) {
608 $truncated_sql = substr($truncated_sql, 0, $startwhere);
612 $startparen = stripos($truncated_sql, "(" );
613 $startset = stripos($truncated_sql, " set ");
614 $startvalues = stripos($truncated_sql, " values ");
616 if ($startparen > 0) {
617 $truncated_sql = substr($truncated_sql, 0, $startparen);
619 if ($startvalues > 0) {
620 $truncated_sql = substr($truncated_sql, 0, $startvalues);
623 $truncated_sql = substr($truncated_sql, 0, $startset);
626 foreach ($tables as $table => $value) {
627 if (strpos($truncated_sql, $table) !== FALSE) {
631 else if (strpos($truncated_sql, "form_") !== FALSE) {
632 $event = "patient-record";
637 /* Avoid filling the audit log with trivial SELECT statements.
638 * Skip SELECTs from unknown tables.
639 * Skip SELECT count() statements.
640 * Skip the SELECT made by the authCheckSession() function.
642 if ($querytype == "select") {
643 if ($event == "other")
645 if (stripos($statement, "SELECT count(" ) === 0)
647 if (stripos($statement, "select username, password from users") === 0)
652 /* If the event is a patient-record, then note the patient id */
654 if ($event == "patient-record") {
655 if (array_key_exists('pid', $_SESSION) && $_SESSION['pid'] != '') {
656 $pid = $_SESSION['pid'];
660 /* If query events are not enabled, don't log them */
661 if (($querytype == "select") && !($GLOBALS['audit_events_query']))
663 if ((soundex($user) != soundex("emergency")) && (soundex($user) != soundex("breakglass")))
667 if (!($GLOBALS["audit_events_${event}"]))
669 if ((soundex($user) != soundex("emergency")) && (soundex($user) != soundex("breakglass")))
674 $event = $event . "-" . $querytype;
676 $adodb = $GLOBALS['adodb']['db'];
678 // ViSolve : Don't log sequences - to avoid the affect due to GenID calls
679 if (strpos($comments, "sequences") !== FALSE) return;
681 $sql = "insert into log (date, event, user, groupname, comments, patient_id, success, checksum,crt_user) " .
683 $adodb->qstr($event) . ", " .
684 $adodb->qstr($user) . "," .
685 $adodb->qstr($group) . "," .
686 $adodb->qstr($comments) . "," .
687 $adodb->qstr($pid) . "," .
688 $adodb->qstr($success) . "," .
689 $adodb->qstr($checksum) . "," .
690 $adodb->qstr($_SERVER['SSL_CLIENT_S_DN_CN']) .")";
692 //$ret = sqlInsertClean($sql);
693 //ViSolve: Call the new function created for audit logs
694 sqlInsertClean_audit($sql);
695 send_atna_audit_msg($user, $group, $event, $pid, $success, $comments);
699 * Record the patient disclosures.
700 * @param $dates - The date when the disclosures are sent to the thrid party.
701 * @param $event - The type of the disclosure.
702 * @param $pid - The id of the patient for whom the disclosures are recorded.
703 * @param $comment - The recipient name and description of the disclosure.
704 * @uname - The username who is recording the disclosure.
706 function recordDisclosure($dates,$event,$pid,$recipient,$description,$user)
708 $adodb = $GLOBALS['adodb']['db'];
709 $crt_user= $_SERVER['SSL_CLIENT_S_DN_CN'];
710 $groupname=$_SESSION['authProvider'];
712 $sql = "insert into extended_log ( date, event, user, recipient, patient_id, description) " .
713 "values (" . $adodb->qstr($dates) . "," . $adodb->qstr($event) . "," . $adodb->qstr($user) .
714 "," . $adodb->qstr($recipient) . ",".
715 $adodb->qstr($pid) ."," .
716 $adodb->qstr($description) .")";
717 $ret = sqlInsertClean_audit($sql);
720 * Edit the disclosures that is recorded.
721 * @param $dates - The date when the disclosures are sent to the thrid party.
722 * @param $event - The type of the disclosure.
723 * param $comment - The recipient and the description of the disclosure are appended.
724 * $logeventid - The id of the record which is to be edited.
726 function updateRecordedDisclosure($dates,$event,$recipient,$description,$disclosure_id)
728 $adodb = $GLOBALS['adodb']['db'];
729 $sql="update extended_log set
730 event=" . $adodb->qstr($event) . ",
731 date=" . $adodb->qstr($dates) . ",
732 recipient=" . $adodb->qstr($recipient) . ",
733 description=" . $adodb->qstr($description) . "
734 where id=" . $adodb->qstr($disclosure_id) . "";
735 $ret = sqlInsertClean_audit($sql);
738 * Delete the disclosures that is recorded.
739 * $deleteid - The id of the record which is to be deleted.
741 function deleteDisclosure($deletelid)
743 $sql="delete from extended_log where id='$deletelid'";
744 $ret = sqlInsertClean_audit($sql);