#!/usr/local/bin/tclsh8.6

# 
# This script is called from syslogd daemon, with a line such as:
# 
#     local2.*       |exec /usr/local/sbin/detectconfmod
# 
# This script reads informations on a line by line basis, detects
# configuration modification events and sends them to the DNS database.
# It looks for these patterns:
# - Cisco
#	Sep 30 10:56:33 crc-cg1 373: Sep 30 10:56:31: %SYS-5-CONFIG_I: Configured from console by jean on vty0 (172.16.202.1)
# - Juniper :
#	Sep 30 10:57:55 espla-rc1 mgd[91730]: UI_COMMIT: User 'jean' requested 'commit' operation (comment: none)
#	- Cisco ASA :
#	Nov 18 07:29:34 vpn %ASA-5-111008: User 'bcollet' executed the 'write' command
#
#
# History:
#   2010/10/14 : pda/jean : design
#   2010/12/20 : pda      : reworked installation
#   2015/11/18 : bcollet  : adding support for Cisco ASA
#

source /usr/local/lib/netmagis/libnetmagis.tcl

proc main {argv0 argv} {

    #
    # Initialization
    #

    set msg [d init-script dbfd $argv0 true tabcor]
    if {$msg ne ""} then {
	puts stderr "$msg"
	puts stderr "Aborted."
	return 1
    }

    set defdomain [dnsconfig get "defdomain"]

    #
    # Main loop
    #

    while {[gets stdin line] >= 0} {
	#
	# Extract host name
	#

	if {[regexp {^\S+\s+\d+\s+\d+:\d+:\d+\s+(\S+)} $line dummy host]} then {

	    set found 0

	    if {[regexp {.*Configured from \S+ by (\S+)} $line dummy login]} then {
		#
		# Cisco
		#

		set found 1
	    } elseif {[regexp {.*User '(\S+)' requested 'commit'} $line dummy login]} then {
		#
		# Juniper
		#

		set found 1
	    } elseif {[regexp {.*ASA-5-111008: User '(\S+)' executed the 'write' command} $line dummy login]} then {
    #
    # Cisco ASA
    #
    set found 1
    }

	    if {$found} then {
		#
		# If host name is not fully qualified, qualify it.
		# The case of a not fully qualified host name occurs if
		# - either the originating syslog do not send a FQDN 
		#	(not a best practice according to RFC 5424)
		# - or the originating syslog do not send a hostname
		#	and the local syslog daemon performs a reverse-lookup
		#	and strips the domain part.
		#

		if {! [regexp {\.} $host]} then {
		    #
		    # Append the default domain
		    #
		    append host ".$defdomain"
		}


		#
		# Insert this entry in the database
		#

		set qhost [::pgsql::quote $host]
		set qlogin [::pgsql::quote $login]
		set sql "INSERT INTO topo.modeq (eq, login) VALUES ('$qhost', '$qlogin')"
		if {! [::pgsql::execsql $dbfd $sql msg]} then {
		    puts stderr "$argv0: cannot write '$eq/$login' to database ($msg)"
		    return 1
		}
	    }
	}
    }
}

exit [main $argv0 $argv]
