Run shell script on a command

I want to run a shell script when date -s <string> command is used. For example i want to log the command to the file /tmp/user.log by executing the following command in the shell script

logger -p user.notice "date -s command executed" -f /tmp/user.log

How can run a shell script when date -s <string> is executed on the shell?

To make it more general, I want to run my shell script when someone else issues a particular linux command on my system. How to do this?


Solution 1:

Rephrasing the question, you want to know when someone attempts to set the system time. This is exactly what the audit subsystem is for...it allows you to audit the execution of specific system calls. In this case, you want to know whenever someone calls any of the various system calls that can change the system time. By using the audit subsystem, you have a solution that works regardless of whether someone is calling /bin/date or their own locally built version of the command.

See auditd(8) and audit.rules(7) for a complete description of the rules syntax, and for examples of auditing time-change operations, you can look for "time-change" in the example nispom.rules file. You may find this on your local system, or you can find it here:

  • https://fedorahosted.org/audit/browser/trunk/contrib/nispom.rules

For more information about the audit subsystem (and documentation is a little hard to come by):

  • http://www.novell.com/documentation/sled10/pdfdoc/auditqs_sp2/auditqs_sp2.pdf
  • http://doc.opensuse.org/products/draft/SLES/SLES-security/cha.audit.setup.html
  • http://www.cyberciti.biz/tips/linux-audit-files-to-see-who-made-changes-to-a-file.html

Solution 2:

You can't easily prevent a user from running his own version of program, but if you assume that the user is not malicious it is easy:

  1. Create a wrapper script that logs the program and then runs it (using the original parameters)
  2. Make sure the wrapper replaces the original program in the user path.

You can either use alias to make the users use the wrapper, or you can simply move/rename the original program and put the wrapper in the original location.

If you only want to log some of the executions use a regexp in the wrapper script.

Solution 3:

Thanks a ton my serverfault friends for the answers.

I think i have come up with an answer for my question with all your help. But you all kinldy help me out if there is any error associated with it or any improvements to be done? Here i go.

These are the things i did.

i). created a script , datewrapper.sh in /etc with the following code

#! /bin/bash

# wrapper script for the date command.
# whenever the date -s command is issued, it will be logged.

# executing the date command first with parameter list if any
date $@

# check whether the date command executed successfully
if [ "$?" == "0" ] ; then
   for param in $@ ; do
      # if "-s" option is used, log it
      if [ "$param" == "-s" ] ; then
         # user.notice logs the message to /tmp/log/user.log
         # as per the commands in /etc/syslog-ng/syslog-ng.conf
         logger -p user.notice "New date set"
         break
      fi
   done
fi

exit 0

ii). chmod a+x /etc/datewrapper.sh ; alias date='/etc/datewrapper.sh'

iii). date

Tue Dec 21 21:51:01 UTC 2010

iv). date -s "21:53:05"

Tue Dec 21 21:53:05 UTC 2010

v). I checked the /tmp/log/user.log. It shows the message

Dec 21 21:53:05 localhost root: New date set

So the result is that whenever the user gives date command, my script will be executed and whenever he issues the command with -s option, it will logged into /tmp/log/user.log