/* * Copyright (C) 1989 TGV, Incorporated * * This is a template user-audit shareable image. This allows a * user to do customized logging/auditing upon connection accepts * and rejects. * * THIS INTERFACE IS SUBJECT TO CHANGE WITHOUT NOTICE * * Compile and link: * $ CC USER_AUDITOR * $ LINK/SHARE USER_AUDITOR/OPT * * Install by placing in the MULTINET: directory and restarting the * MultiNet Server process. * * WARNING: User written auditors which work incorrectly can affect * the operation of MultiNet by killing the MULTINET_SERVER * process. If you are having problems with MultiNet disable * your auditor BEFORE calling for support. * */ #include #include #include "MultiNet_Root:[MultiNet.Include.Sys]Types.h" #include "MultiNet_Root:[MultiNet.Include.Sys]Socket.h" #include "MultiNet_Root:[MultiNet.Include.NetInet]In.h" #include "MultiNet_Root:[MultiNet.Include]NetDB.h" /* * Static pointers to calls back to the MULTINET_SERVER process * which are set up during initialization and used when auditing * occurs. */ static FILE *(*Log_Open)(); /* Address of routine to OPEN files */ static void (*Log_Write)(); /* Address of routine to WRITE files */ static void (*Dprintf)(); /* Printf which prints to console */ static FILE *fp; /* File-pointer returned by Log_Open */ /* * This routine is called once by the MULTINET_SERVER at image startup. * It is used to pass us the address of the Open, Write, and Dprintf * routines and we pass back: * * 1) The address to call when a connection occurs with information * about the connection. * * 2) A status of 1 meaning success. If we return a zero, the Audit * routine will never be called and an error will be logged on * the console saying we refused to start. * * The symbol MULTINET_AUDIT_INIT_V21 must be made UNIVERSAL through * a linker .OPT file!!! */ int multinet_audit_init_v21(Log_Open_Vector, Log_Write_Vector, Dprintf_Vector, Audit_Routine_Vector) FILE *(*Log_Open_Vector)(); void (*Log_Write_Vector)(); void (*Dprintf_Vector)(); int (**Audit_Routine_Vector)(); { int Audit(); /* * Tell the MULTINET_SERVER who to call when a connection is received */ *Audit_Routine_Vector = Audit; /* * Store these for later use */ Log_Open = Log_Open_Vector; Log_Write = Log_Write_Vector; Dprintf = Dprintf_Vector; /* * Open a log file for later use. */ /* fp = (*Log_Open) ("MULTINET:FOO.LOG");*/ fp = (*Log_Open) ("ip_manager:user_auditor.log"); return(1); } /* * This is an example of a user-written auditing routine which is * called when a connection is accepted or rejected. * * Warnings: * * hp may be NULL indicating that the gethostbyaddr() failed. * Don't assume that the socket type is AF_INET. It could be * AF_CHAOS or AF_PUP if the user has either enabled. */ Audit(Service_Name, Socket_Type, Local_SockAddr, Remote_SockAddr, hp, h_errno, Accepted) char *Service_Name; /* eg, "TELNET" */ int Socket_Type; /* eg, SOCK_DGRAM, SOCK_STREAM */ struct sockaddr *Local_SockAddr; /* to get the numeric port from */ struct sockaddr *Remote_SockAddr; /* Address of the person who connected */ struct hostent *hp; /* Result from gethostbyaddr() or NULL */ int h_errno; /* ... if gethostbyaddr() used DNS */ int Accepted; /* BOOLEAN: FALSE if connection refused */ { register struct sockaddr_in *sin = (struct sockaddr_in *) Remote_SockAddr; char Buf[128]; static char usernam[] = "ip_manager:user_auditor." ; static char dnsnam[] = "ip_manager:dns_auditor." ; char outbuf[128] ; char strng[128] ; int status ; /* * Don't assume AF_INET. Check! */ if (sin->sin_family != AF_INET) return; /* * First, print a notice of the connection on the console */ #ifdef SYSLOG if (hp) { Dprintf("Auditor called on service %s host %s\n", Service_Name, hp->h_name); } else { Dprintf("Auditor called on service %s host %s\n", Service_Name, inet_ntoa(sin->sin_addr)); } #endif /* * Next, write an entry to a log file */ /* sprintf(Buf, "Service %s was called by %s",Service_Name, inet_ntoa(sin->sin_addr));*/ if (hp) { sprintf(Buf, "Service %s was called by %s",Service_Name, hp->h_name); } else { sprintf(Buf, "Service %s was called by %s",Service_Name, inet_ntoa(sin->sin_addr)); } pdate(&strng) ; if (strcmp(Service_Name, "DOMAINNAME") == 0) { sprintf(outbuf, "%s%s", dnsnam, strng) ; } else { sprintf(outbuf, "%s%s", usernam, strng) ; } /* Dprintf("Auditor opening file: '%s'\n", outbuf);*/ fp = (*Log_Open) (outbuf); (*Log_Write) (fp, Buf); /* Note: no trailing \n */ } /* * Some important comments on how to use this: * * The auditing routine is called by the MULTINET_SERVER process following * the connection being made. There is a delay while the MULTINET_SERVER * process attempts to resolve the IP address into a host name. * * When the auditing routine is called, all non-AST based code in the * MULTINET_SERVER is halted until you return. Do not do anything here * which will take a long time or potentially block. * * Two routines are provided for you to optionally use when writing * files: * * fp = FILE *Log_Open(Filename) * Log_Write((FILE *) fp, Message); * * These do not work the way you might think! * * Log_Open only validates that Filename is ok, but does not open the * file. It returns you a context for later use. Two Log_Open's of the * same file will return you the same pointer. The file is created if * it does not already exist. * * Log_Write writes a message to a file and: * * $OPENs the file if it is not already open. * * Sets a 30 second timer to $FLUSH the file. * * Resets the 10 minute idle timer which causes the file to $CLOSE. * * If Log_Write files to open or write the file for any reason, the message * is sent to OPCOM instead. * * These are the same routines that the MULTINET_SERVER uses to implement * SET LOG-FILE output. * */ pdate(str) char * str ; { long t ; int rtn_sts ; struct tm *ltm ; static char * months[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" } ; rtn_sts = time(&t) ; ltm = localtime(&t) ; sprintf(str, "%02d-%s-19%02d", ltm->tm_mday, months[ltm->tm_mon], ltm->tm_year) ; }