# $Header: usradt.tcl 06-jun-00.10:55:57 jmansur Exp $
#
# copyright (c) 1999 by the Oracle Corporation
#
# NAME:
#
#  usradt.tcl : Event tcl file that checks if a specified user(s) 
#               logs on to the database.
#
# ARGUMENTS:
#           argv(0) == connect string
#           argv(1) == filter of the user names to be monitored, or *
#                      for all users. Examples of filters are
#                      "= 'SYSTEM'" 
#
# RETURN:
#           $SCRIPT_FAIL or
#           $NO_EVENT or
#           $ALERT_EVENT
#
# OUTPUT:
#           A list of username, count of sessions, workstation for 
#           all restricted users currently logged in.
#


# Event definition
oradefine event /oracle/rdbms/audit/usradt description=VOC-01344 \
report=VOC-01345 frequency=300
oraarguments connect_str user_name
oravardesc connect_str oracle_signon
oravardesc user_name string default=='SYS' message=VOC-01346
oraresults username session_count machine
oravardesc username string
oravardesc session_count string
oravardesc machine string
oradefine end
#


# Initialize global variables
set output ""
oraeventpersist last_users {} 
oraeventpersist last_counts {} 
oraeventpersist last_workstations {} 


# The main event checking functions
proc EvalEvent {} {


    # Declare globals we will use

    global argv last_report output  
    global SCRIPT_FAIL NO_EVENT ALERT_EVENT CLEAR_EVENT
    global oramsg
    global last_users last_counts last_workstations

    # initialize the return code and output
    set ret_code $CLEAR_EVENT
    set output ""
    set err ""
    set user {}
    set count {}
    set workstation {}

    # connect to the database and open a cursor
    set connect [format "%s@%s" [lindex $argv 0] $oramsg(oraobject)]
    if {[catch {oralogon $connect} lda]} {
        lappend output [msgtxt [RDBMS] ora $oramsg(rc)] ""
        if {$last_report == $SCRIPT_FAIL} {
            return $NO_EVENT
        } else {
            set last_report $SCRIPT_FAIL
            return $SCRIPT_FAIL
        }
    }

    if {[catch {set cur [oraopen $lda]} err]} {
        lappend output $err
        catch {oralogoff $lda} err
        if {$last_report == $SCRIPT_FAIL} {		
            return $NO_EVENT
        } else {
            set last_report $SCRIPT_FAIL
            return $SCRIPT_FAIL
        }
    }

    #construct the SQL statement..
    set sql {select username,count(username),machine
             from v$session 
             where type <> 'BACKGROUND' and username is not null }
    if {[string compare [lindex $argv 1] *] != 0} {
        lappend sql and username 
        set tmp [convertin $oramsg(db_characterset) [lindex $argv 1]]
        set sql [concat $sql $tmp]
    }
    lappend sql group by username,machine 

    if {[catch {orasql $cur $sql}] == 1} {
        lappend output [convertout $oramsg(db_characterset) \
            $oramsg(errortxt)] $sql
        catch {oraclose $cur} err
        catch {oralogoff $lda} err
	lappend output $err
        if {$last_report == $SCRIPT_FAIL} {
            return $NO_EVENT
        } else {
            set last_report $SCRIPT_FAIL
            return $SCRIPT_FAIL
        }
    }

    if {[catch {set row [orafetch $cur]} err]} {
	lappend output $err
        catch {oraclose $cur} err
        catch {oralogoff $lda} err
        if {$last_report == $SCRIPT_FAIL} {
            return $NO_EVENT
        } else {
            set last_report $SCRIPT_FAIL
            return $SCRIPT_FAIL
        }
    }

    if {$oramsg(rows) != 0} {
      # check for user sessions
      while {$oramsg(rc) == 0} {
        if {[lindex $row 2] > 0} {
            set ret_code $ALERT_EVENT
            set tmp [convertout $oramsg(db_characterset) [lindex $row 0]]
            lappend user $tmp
            lappend count [lindex $row 1]
            lappend workstation [lindex $row 2]
        
        }
        if {[catch {set row [orafetch $cur]} err]} {
            lappend output $err
            catch {oraclose $cur} err
	    catch {oralogoff $lda} err
            if {$last_report == $SCRIPT_FAIL} {
            	return $NO_EVENT
            } else {
    	        set last_report $SCRIPT_FAIL
                return $SCRIPT_FAIL
            }
        }
      }
      lappend output $user $count $workstation
    }

    # log off
    catch {oraclose $cur} err
    catch {oralogoff $lda} err

    if { $ret_code == $last_report &&
         [string compare $last_users $user] == 0 &&
         [string compare $last_counts $count] == 0 &&
         [string compare $last_workstations $workstation] == 0 } {
        return $NO_EVENT
    } else {
        ORATCL_DEBUG "usradt : $oramsg(oraobject) : [oratime] : MESSAGE - $ret_code, $output"
        set last_report $ret_code
        set last_users $user
        set last_counts $count
        set last_workstations $workstation
        return $ret_code 
    }
}
    
