How to enforce user to Enter text when login to a UNIX / Linux system?

Hi.

I inject my tracklogin.sh script in the profile of each user.

$ more .profile
./tracklogin.sh
#       This is the default standard profile provided to a user.
MAIL=/usr/mail/${LOGNAME:?}
bash-3.2$ more tracklogin.sh
#!/bin/bash
tdate=$(date +"%d%m%y")
mkdir -p /tmp/root_log 2>/dev/null
chmod -R 775 /tmp/root_log
echo User `id` logged in at:`date`>>/tmp/root_log/logs_$tdate
 
read -p "Enter Reason for Login:" reason
while [[ $reason == '' ]] # While string is different or empty...
do
    echo "Enter a valid string" # Ask the user to enter a valid string
    read -p "Enter Reason for Login: " reason # Ask the user to enter a string
done
echo "Reason for Login:$reason">>/tmp/root_log/logs_$tdate

This script reads and enforce the user to enter the reason he/she is login to the system.

However, if the user issues "Ctrl+C" my tracklogin.sh script terminates and the user is able to login to the system which i don't want.

Can you tell me how can i enforce the user to be able to login only after giving some justification ?

How about using a "restricted shell"? man bash :

Or, in your above "injection", did you consider trap ping the relevant signals?

I m unaware of these suggestions.

While i try to study them and how to use them... more insight on how they can help :eek:would be appreciated :slight_smile:

You realize, of course, anyone can go and trash /tmp/root_log/logs_$tdate ?

1 Like

Yes, i m testing this out. once good with the scripts i will change the log location.

Thank you for your attention though.

---------- Post updated at 02:45 PM ---------- Previous update was at 02:40 PM ----------

Based on your suggestions, I tried the below in tracklogin.sh

trap "echo Bye Bye ...; exit; exit" 2

But when i login i get the below error for tracklogin.sh

bash: ./tracklogin.sh: restricted: cannot specify `/' in command names

Can you tell me how i can overcome this error?

i then decided to run tracklogin.sh in debug mode i see the below output:

bash -x tracklogin.sh
++ date +%d%m%y
+ tdate=110817
+ mkdir -p /tmp/root_log
+ chmod -R 777 /tmp/root_log
++ id
++ date
+ echo User 'uid=51371(user1)' 'gid=24(webuser)' logged in at:Fri Aug 11 14:36:28 CDT 2017
+ trap 'echo Bye Bye...; exit; exit' 2
+ read -p 'Enter Reason for Login:' reason
Enter Reason for Login:^C++ echo Bye Bye...
Bye Bye...
++ exit

It seems to catch the trap but how do i force the user out of the system ?

Well, the exit should do exactly that.

No it does not. Please see the below observation.

I put this trap code in tracklogin.sh

trap "exit;" 2

and inject the tracklogin.sh in my .profile as shown in the OP.

When I login to the server it prompts me for Reason.

But when I press Crtl+C it Does Not log me out.

Instead I can continue without being enforced or killed out of the server.

Please see the output below.

IF YOU DO NOT CONSENT, LOG OFF NOW.
 
##################################################################
# *** This Server is using Centrify                          *** #
# *** Remember to use your Active Directory account          *** #
# ***    password when logging in                            *** #
##################################################################
 
Using keyboard-interactive authentication.
(AD: corp.bank.int) Password:
Password will expire in 6 days
Last login: Fri Aug 11 15:54:29 2017 from uggs00811
Sun Microsystems Inc.   SunOS 5.10      Generic January 2005
Enter Reason for Login:^C$ hostname
Mymac1
$ id
uid=51371(user1) gid=24(webuser)

Can you please suggest ??

Try sourcing your tracklogin.sh. Executing it will do so in a sub shell, and this in turn is exit ed, not the main shell.

i tried the below line of code in my .profile

source ~/tracklogin.sh

then i tried logging in and got this error

.profile: source: not found

I do have the tracklogin.sh in my home directory for sure.

$ ls -ltr ~/tracklogin.sh
-rwxrwxr-x   1 user1 webuser       921 Aug 11 15:53 /home/webuser/user1/tracklogin.sh

When i fired the command on the command-line manually i got the below:

$ source ~/tracklogin.sh
ksh: : source: not found

Can you please comment.

As always, if you don't tell us what shell and operating system you're using, you're likely to get suggestions that won't work in your environment...

For ksh (and other POSIX conforming shells), change:

source ~/tracklogin.sh

to:

. ~/tracklogin.sh

Hmmm - are you running the bash or the ksh shell? I'm not sure ksh has the source buitlin command - try . instead.

I tried this but then it is going in INFINITE loop. See below output:

more .profile
. ~/tracklogin.sh

Output showing infinite loop as soon as i enter my credentials for login.

Enter a valid string
.profile[3]: read: no query process
Enter a valid string
.profile[3]: read: no query process
Enter a valid string
.....
....

Please suggest.

---------- Post updated at 05:23 PM ---------- Previous update was at 05:20 PM ----------

Well i dont know. i am simply login in so i believe it got to be the default shell. One thing i can see is that it does execute the .profile file as i first login.

This is not the point Corona688 has raised: your script, when called from the login routine of a user, runs with the credentials of this user. To append the text the user enters to the log file the user has to be allowed to write to this file.

But because he is allowed to write the file he is also free to remove any content from the file - he could reduce it to zero length. So your whole mechanism is flawed from the beginning.

Since shell scripts cannot run as SUID (that is, run with the effective privileges of another user, not the one executing it) you will need to write a C- (or any other programming language you can compile to an object deck) program which takes the text and then writes it to a log file not writable by the user itself.

I hope this helps.

bakunin

By definition, where they can create files, they can delete files. Your scheme is flawed.

I may have the root user crontab copy the contents of the files the user logs to a file owned and controlled by root. However, on this thread i m still seeking help to get the script to work as desired i.e. Enforce explanation for login or kick the user out of the system.

No. It is not the system default shell. It is the login shell for whatever user's login ID you're using when you login. Since it is executing .profile , we know that it is not csh nor one of its derivatives. And, #! lines in a sourced file are just comments, they have absolutely no effect on the shell that will be used to evaluate the commands in that script. The code in that script will be executed by the login shell of the user who is logging in. You need to be sure that you're only using commands in your script that can be recognized by any shell on your system that will be used as a login shell for the users running that script. (I.e., you'll need one script for users logging in with a shell that uses Bourne shell syntax (and it can't use [[...]] or $(...) or source ) and a different script for users logging in with a shell that uses csh syntax.)

And you're going to build enough intelligence into this script so it won't accept any of the following as a reason for logging in:

?
I want to
Who cares
Stop bothering me and get out of my way so I can do my job!

or even just a line containing a <space> character?

And, anything you put in the user's .profile or .cshrc can be removed by that user as soon as they have suffered through your attempt to micromanage them once.

If your code doesn't log the user's login data directly to a safe repository that the user logging in can't write to, the user can easily remove that data before any cron job you set up has a chance to capture it and copy it to its final resting place.

1 Like

@Don Cragun Thank you for your reply.

First of all let me explain what i did to resolve the ticket based upon the suggestions received.

  1. sourced the tracklogin.sh in the .profile or for that matter in all the files containing "profile" or "rc" in their filenames.
. ~/tracklogin.sh
  1. used trap to exit on Ctrl+C and Ctrl+D
trap "exit;" 2
  1. To resolve the recursive infinite error msg: .profile[3]: read: no query process I changed
read -p "Enter Reason for Login:" reason

To

echo "Enter Reason for Login:"
read  reason

Now coming back to the concerns shared by Corona, Don Cragun and others.

Firstly i do not know what would be the correct / professional way to achieve what i want to achieve. Enforce every user to log an explanation for Login else kick them out of the server. If you have any document / steps to follow. Kindly share.

Now, that i m able to achieve the above my way, I will see if i could trigger a backup of the logs by root user by continuously monitoring the cksum of the /tmp/root_log folder. Incase the cksum changes; then the root takes a backup. I will also insert a 3 seconds sleep in the tracklogin.sh script so that the crontab can take a backup before the user gets control. I think this will be done by setting the crontab to run say every 3 secs which will be too short a time for anyone to modify the logs.

tail -3 tracklogin.sh
echo " Freezing while the root takes your log Backup...."
sleep 3
echo "You can Begin WORK now !!!"

Do you appreciate my ideas :(?

Do you appreciate that if I fire up a cron job every day shortly after midnight that invokes the following script with the pathname of that day's log file as an operand:

#!/bin/ksh
test -f "$1" || touch "$1"
ls -l "$1" | read -r _ _ _ _ size _
tail -0 -f junk | while read line
do	dd if=/dev/null of="$1" bs=1 seek="$size" count=0
done

then the script that you're running every 3 seconds to capture updates will have much less than a 1% chance of capturing anything written to that log file before my script obliterates it? And, if I didn't care about preserving what had already been put in that file, the following script run every second would have a 66% chance of wiping out any updates before your script running every 3 seconds would capture it:

> "$1"

Are we having fun yet?

Your scheme is fundamentally flawed. Any file that the user who is logging in can write to can be truncated by that user before you can reliably capture it!

Anything that you are writing into one of my personal startup files can be removed, commented out, or disabled the first time I login after you install it.

Not enough fun yet: A system with a race condition between several jobs tends to have recources bound to doing these jobs. In other words: at some point in time the system will be so busy executing the logging-job, the anti-logging-job, the anti-anti-logging-job, the anti-anti-anti-logging-job, etc., so that little to no system resources will be left to do whatever the system was designed to do in first place.

Ultimately one won't need all the anti-anti-....scripts any more because nobody would want to log in to such a sluggish system.

There is only two things to do to resolve such a ticket: first write a log comment that this is an <derogatory adjective of your choice> idea and you don't have time to waste on nonsense and then, second, close it. That is the sensible thing to do and in fact "best practice".

bakunin

1 Like

Well, wouldn't it be time to become acquainted with the environment you're working in? Here, you are using a bash ism in a ksh shell:

man ksh :

Joining the general chorus questioning the goal you are pursueing: On a production system, any user with a valid account should have reason to log in, shouldn't s/he? Why, then, question it? And, would making him/her wait additional seconds improve the acceptance of the system?